├── .eslintignore ├── .eslintrc.json ├── .github ├── FUNDING.yml └── workflows │ ├── ci.yml │ └── require-labels.yml ├── .gitignore ├── .husky ├── .gitignore └── pre-commit ├── .idea └── workspace.xml ├── .npmignore ├── .prettierignore ├── .prettierrc ├── LICENSE ├── README.md ├── bin └── scripts.js ├── index.js ├── package-lock.json ├── package.json ├── scripts ├── config │ ├── babelJestTransform.js │ ├── createJestConfig.js │ └── paths.js └── test.js ├── src ├── config.js ├── eslintrc.json ├── ts.eslintrc.json └── webpack.config.js └── tests ├── aliases-false ├── aliases-false.test.js ├── handler.js ├── package-lock.json ├── package.json └── serverless.yml ├── aliases-jest ├── .eslintrc.json ├── aliases-jest.test.js ├── handler.js ├── libs │ └── sum.js ├── package-lock.json ├── package.json ├── serverless.yml └── tests │ └── index.test.js ├── aliases ├── aliases.test.js ├── custom-lib │ └── src │ │ └── some-lib │ │ └── index.js ├── handler.js ├── package-lock.json ├── package.json └── serverless.yml ├── base ├── .gitignore ├── base.test.js ├── handler.js ├── package-lock.json ├── package.json └── serverless.yml ├── class-properties ├── .gitignore ├── class-properties.test.js ├── handler.js ├── package-lock.json ├── package.json └── serverless.yml ├── copy-files-individually-packaged ├── .gitignore ├── bin │ └── echo.sh ├── copy-files-individually-packaged.test.js ├── handler.js ├── package-lock.json ├── package.json ├── public │ └── test.txt ├── serverless.yml └── world.js ├── copy-files ├── .gitignore ├── bin │ └── echo.sh ├── copy-files.test.js ├── handler.js ├── package-lock.json ├── package.json ├── public │ └── test.txt ├── serverless.yml └── world.js ├── disable-eslint ├── .gitignore ├── disable-eslint.test.js ├── handler.js ├── package-lock.json ├── package.json └── serverless.yml ├── esbuild ├── .gitignore ├── esbuild.test.js ├── handler.js ├── package-lock.json ├── package.json └── serverless.yml ├── externals-all ├── externals-all.test.js ├── handler.js ├── package-lock.json ├── package.json └── serverless.yml ├── externals ├── .gitignore ├── externals.test.js ├── handler.js ├── package-lock.json ├── package.json └── serverless.yml ├── failed-eslint ├── .gitignore ├── include.js └── service │ ├── failed-eslint.test.js │ ├── handler.js │ ├── package-lock.json │ ├── package.json │ └── serverless.yml ├── fixpackages-formidable ├── fixpackages-formidable.test.js ├── handler.js ├── package-lock.json ├── package.json └── serverless.yml ├── force-exclude ├── force-exclude.test.js ├── handler.js ├── package-lock.json ├── package.json ├── serverless.node18.yml └── serverless.yml ├── generate-stats-files ├── generate-stats-file.test.js ├── handler.js ├── package-lock.json ├── package.json └── serverless.yml ├── helpers ├── clear-npm-cache.js ├── index.js ├── npm-install.js ├── remove-node-modules.js ├── run-jest-command.js ├── run-sls-command.js └── setup-tests.js ├── ignore-packages ├── handler.js ├── ignore-packages.test.js ├── package-lock.json ├── package.json └── serverless.yml ├── invalid-runtime ├── handler.js ├── invalid-runtime.test.js └── serverless.yml ├── isomorphic-loaders ├── .gitignore ├── assets │ ├── react.png │ ├── style.css │ └── style.scss ├── handler.js ├── isomorphic-loaders.test.js ├── package-lock.json ├── package.json └── serverless.yml ├── load-gql-files ├── .gitignore ├── load-gql-files.test.js ├── package-lock.json ├── package.json ├── serverless.yml └── src │ ├── global.d.ts │ ├── handler.ts │ ├── resolvers │ ├── ExampleResolver.ts │ └── index.ts │ └── schema │ ├── exampleSchema.gql │ ├── index.ts │ └── linkSchema.gql ├── minify-options ├── .gitignore ├── handler.js ├── minify-options.test.js ├── package-lock.json ├── package.json └── serverless.yml ├── nested-lambda ├── .gitignore ├── nested-lambda.test.js ├── package-lock.json ├── package.json ├── serverless.yml └── services │ └── main │ └── handler.js ├── nested-services ├── nested-services.test.js ├── package.json └── services │ └── service1 │ ├── handler.js │ └── serverless.yml ├── node-env ├── .gitignore ├── handler.js ├── node-env.test.js ├── package-lock.json ├── package.json └── serverless.yml ├── nullish-coalescing ├── .gitignore ├── handler.js ├── nullish-coalescing.test.js ├── package-lock.json ├── package.json └── serverless.yml ├── optional-chaining ├── .gitignore ├── handler.js ├── optional-chaining.test.js ├── package-lock.json ├── package.json └── serverless.yml ├── override-eslint ├── .eslintrc.json ├── .gitignore ├── handler.js ├── override-eslint.test.js ├── package-lock.json ├── package.json └── serverless.yml ├── raw-loader ├── .gitignore ├── assets │ ├── csv.csv │ ├── pem.pem │ └── text.txt ├── handler.js ├── package-lock.json ├── package.json ├── raw-loader.test.js └── serverless.yml ├── scripts ├── .env ├── asyncSum.js ├── package-lock.json ├── package.json ├── scripts.test.js ├── setup-tests.js └── tests │ └── index.test.js ├── typescript-config-path ├── handler.ts ├── package-lock.json ├── package.json ├── serverless.yml ├── tsconfig.special.json └── typescript-config-path.test.js ├── typescript-esbuild ├── custom-lib │ └── src │ │ └── some-lib │ │ └── index.ts ├── decorated-class.ts ├── handler.ts ├── package-lock.json ├── package.json ├── serverless.yml ├── tsconfig.json ├── tsx │ └── import.tsx └── typescript-esbuild.test.js ├── typescript-exclude-files ├── handler.spec.ts ├── handler.ts ├── package-lock.json ├── package.json ├── serverless.yml ├── tsconfig.json └── typescript-exclude-files.test.js ├── typescript-forkts-disabled ├── handler.ts ├── package-lock.json ├── package.json ├── serverless.yml ├── tsconfig.json └── typescript-forkts-disabled.test.js ├── typescript-invalid-module ├── handler.ts ├── package-lock.json ├── package.json ├── serverless.yml ├── tsconfig.json └── typescript-invalid-module.test.js ├── typescript-jest ├── handler.ts ├── package-lock.json ├── package.json ├── serverless.yml ├── tests │ └── index.test.ts ├── tsconfig.json └── typescript-jest.test.js ├── typescript-no-baseUrl ├── handler.ts ├── package-lock.json ├── package.json ├── serverless.yml ├── tsconfig.json └── typescript-no-baseUrl.test.js ├── typescript ├── custom-lib │ └── src │ │ └── some-lib │ │ └── index.ts ├── decorated-class.ts ├── handler.ts ├── package-lock.json ├── package.json ├── serverless.yml ├── tsconfig.json ├── tsx │ └── import.tsx └── typescript.test.js ├── with-eslintignore ├── .eslintignore ├── .gitignore ├── handler.js ├── package-lock.json ├── package.json ├── serverless.yml └── with-eslintignore.test.js ├── with-node14 ├── .gitignore ├── handler.js ├── serverless.yml └── with-node14.test.js ├── with-node16 ├── .gitignore ├── handler.js ├── serverless.yml └── with-node16.test.js ├── with-node18 ├── .gitignore ├── handler.js ├── serverless.yml └── with-node18.test.js └── with-node20 ├── .gitignore ├── handler.js ├── serverless.yml └── with-node20.test.js /.eslintignore: -------------------------------------------------------------------------------- 1 | # Ignore user's code that'll be transpiled 2 | tests/nullish-coalescing/** 3 | tests/failed-eslint/** 4 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "commonjs": true, 4 | "es6": true, 5 | "node": true, 6 | "jest": true 7 | }, 8 | "extends": "eslint:recommended", 9 | "globals": { 10 | "Atomics": "readonly", 11 | "SharedArrayBuffer": "readonly" 12 | }, 13 | "parserOptions": { 14 | "ecmaVersion": 2018, 15 | "sourceType": "module" 16 | }, 17 | "rules": {} 18 | } 19 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | # github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | github: jayair 5 | patreon: serverless_stack 6 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: CI 5 | 6 | on: 7 | workflow_dispatch: {} 8 | push: 9 | branches: [ master ] 10 | pull_request: 11 | branches: [ master ] 12 | 13 | jobs: 14 | build: 15 | 16 | strategy: 17 | matrix: 18 | os: [ubuntu-latest] 19 | node-version: [18.x, 20.x] 20 | 21 | runs-on: ${{ matrix.os }} 22 | 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Use Node.js ${{ matrix.node-version }} 26 | uses: actions/setup-node@v4 27 | with: 28 | node-version: ${{ matrix.node-version }} 29 | - name: Install dependencies 30 | run: npm install 31 | - name: Install Serverless 32 | run: npm install -g serverless@3.39.0 33 | - name: Test 34 | run: npm run test 35 | -------------------------------------------------------------------------------- /.github/workflows/require-labels.yml: -------------------------------------------------------------------------------- 1 | name: Label 2 | on: 3 | pull_request: 4 | types: [opened, labeled, unlabeled, synchronize] 5 | jobs: 6 | required: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: mheap/github-action-required-labels@v5 10 | with: 11 | mode: exactly 12 | count: 1 13 | labels: "breaking, enhancement, bug, documentation, internal, skip changelog" 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # TypeScript incremental build products 43 | dist/ 44 | tsconfig.tsbuildinfo 45 | 46 | # Optional npm cache directory 47 | .npm 48 | 49 | # Optional eslint cache 50 | .eslintcache 51 | 52 | # Optional REPL history 53 | .node_repl_history 54 | 55 | # Output of 'npm pack' 56 | *.tgz 57 | 58 | # Yarn Integrity file 59 | .yarn-integrity 60 | 61 | # next.js build output 62 | .next 63 | 64 | # Serverless build output 65 | .serverless 66 | .webpack 67 | .cache-loader 68 | .idea/* -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | npx lint-staged -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | tests 3 | *.test.js 4 | yarn.lock 5 | yarn-error.log 6 | .travis.yml 7 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | README.md 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Anomaly Innovations 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bin/scripts.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /** 3 | * Based on https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/bin/react-scripts.js 4 | */ 5 | 6 | 'use strict'; 7 | 8 | // Makes the script crash on unhandled rejections instead of silently 9 | // ignoring them. In the future, promise rejections that are not handled will 10 | // terminate the Node.js process with a non-zero exit code. 11 | process.on('unhandledRejection', err => { 12 | throw err; 13 | }); 14 | 15 | const spawn = require('cross-spawn'); 16 | const args = process.argv.slice(2); 17 | 18 | const scriptIndex = args.findIndex( 19 | x => x === 'test' 20 | ); 21 | const script = scriptIndex === -1 ? args[0] : args[scriptIndex]; 22 | const nodeArgs = scriptIndex > 0 ? args.slice(0, scriptIndex) : []; 23 | 24 | switch (script) { 25 | case 'test': { 26 | const result = spawn.sync( 27 | 'node', 28 | nodeArgs 29 | .concat(require.resolve('../scripts/' + script)) 30 | .concat(args.slice(scriptIndex + 1)), 31 | { stdio: 'inherit' } 32 | ); 33 | if (result.signal) { 34 | if (result.signal === 'SIGKILL') { 35 | console.log( 36 | 'The build failed because the process exited too early. ' + 37 | 'This probably means the system ran out of memory or someone called ' + 38 | '`kill -9` on the process.' 39 | ); 40 | } else if (result.signal === 'SIGTERM') { 41 | console.log( 42 | 'The build failed because the process exited too early. ' + 43 | 'Someone might have called `kill` or `killall`, or the system could ' + 44 | 'be shutting down.' 45 | ); 46 | } 47 | process.exit(1); 48 | } 49 | process.exit(result.status); 50 | break; 51 | } 52 | default: 53 | console.log('Unknown script "' + script + '".'); 54 | break; 55 | } 56 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const path = require("path"); 4 | const pkgUp = require("pkg-up"); 5 | const ServerlessWebpack = require("serverless-webpack"); 6 | 7 | const config = require("./src/config"); 8 | 9 | function getWebpackConfigPath(servicePath) { 10 | return path.relative(servicePath, __dirname) + "/src/webpack.config.js"; 11 | } 12 | 13 | function applyWebpackOptions(custom, config) { 14 | if (custom.webpack) { 15 | throw "serverless-webpack config detected in serverless.yml. serverless-bundle is not compatible with serverless-webpack."; 16 | } 17 | 18 | custom.webpack = { 19 | packager: config.options.packager, 20 | concurrency: config.options.concurrency, 21 | packagerOptions: config.options.packagerOptions, 22 | webpackConfig: getWebpackConfigPath(config.servicePath), 23 | includeModules: { 24 | forceExclude: config.options.forceExclude, 25 | forceInclude: config.options.forceInclude, 26 | nodeModulesRelativeDir: 27 | config.options.nodeModulesRelativeDir != null 28 | ? config.options.nodeModulesRelativeDir 29 | : "./", 30 | // Generate relative path for the package.json 31 | // For cases where the services are nested and don't have their own package.json 32 | // Traverse up the tree to find the path to the nearest package.json 33 | // 34 | // Certain plugins like serverless-plugin-typescript change the cwd, so when 35 | // searching, reset the cwd to the service path 36 | packagePath: path.relative( 37 | config.servicePath, 38 | pkgUp.sync({ cwd: config.servicePath }) 39 | ), 40 | }, 41 | excludeFiles: config.options.excludeFiles, 42 | excludeRegex: /bundle_stats\.(html|json)$/, 43 | keepOutputDirectory: config.options.generateStatsFiles, 44 | }; 45 | } 46 | 47 | function applyUserConfig(config, userConfig, servicePath, runtime) { 48 | config.servicePath = servicePath; 49 | 50 | // Default to Node 12 if no runtime found 51 | const runtimeVersion = 52 | Number.parseInt((runtime || "").replace("nodejs", ""), 10) || 12; 53 | 54 | // Force exclude aws-sdk for versions below Node 18 55 | if (runtimeVersion < 18) { 56 | config.options.forceExclude.push("aws-sdk"); 57 | } 58 | 59 | // Concat forceExclude if provided 60 | if (userConfig.forceExclude) { 61 | userConfig.forceExclude = config.options.forceExclude.concat( 62 | userConfig.forceExclude 63 | ); 64 | } 65 | 66 | // Concat externals if a list of packages are provided 67 | if (userConfig.externals && Array.isArray(userConfig.externals)) { 68 | userConfig.externals = config.options.externals.concat( 69 | userConfig.externals 70 | ); 71 | } 72 | 73 | // Concat rawFileExtensions if provided 74 | if (userConfig.rawFileExtensions) { 75 | userConfig.rawFileExtensions = config.options.rawFileExtensions.concat( 76 | userConfig.rawFileExtensions 77 | ); 78 | } 79 | 80 | Object.assign(config.options, userConfig); 81 | 82 | config.nodeVersion = runtimeVersion; 83 | } 84 | 85 | class ServerlessPlugin extends ServerlessWebpack { 86 | constructor(serverless, options) { 87 | super(serverless, options); 88 | 89 | this.serverless = serverless; 90 | this.options = options; 91 | 92 | this.hooks["before:webpack:validate:validate"] = function () { 93 | const service = this.serverless.service; 94 | const servicePath = this.serverless.config.servicePath; 95 | 96 | service.custom = service.custom || {}; 97 | 98 | applyUserConfig( 99 | config, 100 | service.custom.bundle || {}, 101 | servicePath, 102 | service.provider.runtime 103 | ); 104 | applyWebpackOptions(service.custom, config); 105 | }.bind(this); 106 | } 107 | } 108 | 109 | module.exports = ServerlessPlugin; 110 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "serverless-bundle", 3 | "version": "6.3.0", 4 | "description": "An extension of the serverless-webpack plugin that bundles your ES6 + TypeScript Node.js Lambda functions.", 5 | "main": "index.js", 6 | "scripts": { 7 | "changelog": "lerna-changelog", 8 | "jest-clear-cache": "jest --clearCache", 9 | "test": "jest --no-watchman", 10 | "prepare": "is-ci || husky install" 11 | }, 12 | "bin": { 13 | "serverless-bundle": "bin/scripts.js" 14 | }, 15 | "jest": { 16 | "setupFilesAfterEnv": [ 17 | "/tests/helpers/setup-tests.js" 18 | ], 19 | "testPathIgnorePatterns": [ 20 | "/scripts", 21 | "/tests/scripts/tests", 22 | "/tests/aliases-jest/tests", 23 | "/tests/typescript-jest/tests", 24 | "/tests/typescript-exclude-files/handler.spec.ts" 25 | ] 26 | }, 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/AnomalyInnovations/serverless-bundle.git" 30 | }, 31 | "author": "Jay V ", 32 | "license": "MIT", 33 | "dependencies": { 34 | "@babel/core": "^7.17.2", 35 | "@babel/plugin-proposal-class-properties": "^7.16.7", 36 | "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", 37 | "@babel/plugin-proposal-optional-chaining": "^7.16.7", 38 | "@babel/plugin-transform-runtime": "^7.17.0", 39 | "@babel/preset-env": "^7.16.11", 40 | "@babel/runtime": "^7.17.2", 41 | "@typescript-eslint/eslint-plugin": "^4.33.0", 42 | "@typescript-eslint/parser": "^4.33.0", 43 | "babel-eslint": "^10.0.2", 44 | "babel-jest": "^29.7.0", 45 | "babel-loader": "^8.2.3", 46 | "babel-plugin-source-map-support": "^2.1.3", 47 | "chalk": "^4.1.2", 48 | "copy-webpack-plugin": "^8.1.1", 49 | "core-js": "^3.21.0", 50 | "cross-spawn": "^7.0.3", 51 | "css-loader": "^5.2.7", 52 | "dotenv": "^8.6.0", 53 | "esbuild-loader": "^2.18.0", 54 | "eslint": "^7.32.0", 55 | "eslint-config-strongloop": "^2.1.0", 56 | "eslint-webpack-plugin": "^2.6.0", 57 | "fast-glob": "^3.2.11", 58 | "fork-ts-checker-webpack-plugin": "^6.5.0", 59 | "graphql": "^15.8.0", 60 | "graphql-tag": "^2.12.6", 61 | "ignore-loader": "^0.1.2", 62 | "import-fresh": "^3.3.0", 63 | "isomorphic-style-loader": "^5.3.2", 64 | "jest": "^29.7.0", 65 | "pkg-up": "^3.1.0", 66 | "raw-loader": "^4.0.2", 67 | "regenerator-runtime": "^0.13.9", 68 | "resolve": "^1.22.0", 69 | "sass": "^1.49.7", 70 | "sass-loader": "^11.1.1", 71 | "serverless-webpack": "^5.14.2", 72 | "source-map-support": "^0.5.21", 73 | "ts-jest": "^29.2.5", 74 | "ts-loader": "^8.3.0", 75 | "tsconfig-paths-webpack-plugin": "^3.5.2", 76 | "typescript": "^4.5.5", 77 | "webpack": "^5.68.0", 78 | "webpack-bundle-analyzer": "^4.5.0", 79 | "webpack-node-externals": "^2.5.2", 80 | "webpack-permissions-plugin": "^1.0.8" 81 | }, 82 | "devDependencies": { 83 | "@types/jest": "^29.5.12", 84 | "husky": "^6.0.0", 85 | "is-ci": "^3.0.1", 86 | "lerna-changelog": "^2.2.0", 87 | "lint-staged": "^10.5.4", 88 | "prettier": "^2.5.1", 89 | "reflect-metadata": "^0.1.13", 90 | "serverless": "^3.39.0" 91 | }, 92 | "peerDependencies": { 93 | "serverless": "1 || 2 || 3" 94 | }, 95 | "lint-staged": { 96 | "*.{js,css,json,md}": [ 97 | "prettier --write", 98 | "git add" 99 | ], 100 | "*.js": [ 101 | "eslint --fix", 102 | "git add" 103 | ] 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /scripts/config/babelJestTransform.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const babelJest = require("babel-jest"); 4 | 5 | module.exports = babelJest.createTransformer({ 6 | presets: ["@babel/preset-env"], 7 | plugins: [ 8 | "@babel/plugin-proposal-class-properties", 9 | "@babel/plugin-proposal-optional-chaining", 10 | "@babel/plugin-proposal-nullish-coalescing-operator" 11 | ], 12 | babelrc: false, 13 | configFile: false 14 | }); 15 | -------------------------------------------------------------------------------- /scripts/config/createJestConfig.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /** 3 | * Based on https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/scripts/utils/createJestConfig.js 4 | */ 5 | "use strict"; 6 | 7 | const fs = require("fs"); 8 | const chalk = require("chalk"); 9 | const paths = require("./paths"); 10 | 11 | module.exports = (resolve, rootDir) => { 12 | const config = { 13 | collectCoverageFrom: ["./**/*.{js,jsx,ts,tsx}"], 14 | 15 | preset: "ts-jest", 16 | globals: { 17 | "ts-jest": { 18 | babelConfig: { 19 | presets: [require.resolve("@babel/preset-env")] 20 | } 21 | } 22 | }, 23 | 24 | setupFiles: [ 25 | require.resolve("core-js/stable"), 26 | require.resolve("regenerator-runtime/runtime") 27 | ], 28 | 29 | testMatch: [ 30 | "/**/__tests__/**/*.{js,jsx,ts,tsx}", 31 | "/**/*.{spec,test}.{js,jsx,ts,tsx}" 32 | ], 33 | transform: { 34 | "^.+\\.(js|jsx)$": resolve("scripts/config/babelJestTransform.js") 35 | }, 36 | transformIgnorePatterns: [ 37 | "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$" 38 | ], 39 | testEnvironment: "node" 40 | }; 41 | if (rootDir) { 42 | config.rootDir = rootDir; 43 | } 44 | const overrides = Object.assign({}, require(paths.appPackageJson).jest); 45 | const supportedKeys = [ 46 | "clearMocks", 47 | "collectCoverageFrom", 48 | "coveragePathIgnorePatterns", 49 | "coverageReporters", 50 | "coverageThreshold", 51 | "displayName", 52 | "extraGlobals", 53 | "globalSetup", 54 | "globalTeardown", 55 | "reporters", 56 | "resetMocks", 57 | "resetModules", 58 | "restoreMocks", 59 | "setupFilesAfterEnv", 60 | "snapshotSerializers", 61 | "testMatch", 62 | "testResultsProcessor", 63 | "transform", 64 | "transformIgnorePatterns", 65 | "watchPathIgnorePatterns", 66 | "moduleNameMapper", 67 | "testSequencer", 68 | ]; 69 | if (overrides) { 70 | supportedKeys.forEach(key => { 71 | if (overrides.hasOwnProperty(key)) { 72 | if (Array.isArray(config[key]) || typeof config[key] !== "object") { 73 | // for arrays or primitive types, directly override the config key 74 | config[key] = overrides[key]; 75 | } else { 76 | // for object types, extend gracefully 77 | config[key] = Object.assign({}, config[key], overrides[key]); 78 | } 79 | 80 | delete overrides[key]; 81 | } 82 | }); 83 | const unsupportedKeys = Object.keys(overrides); 84 | if (unsupportedKeys.length) { 85 | const isOverridingSetupFile = 86 | unsupportedKeys.indexOf("setupFilesAfterEnv") > -1; 87 | 88 | console.error( 89 | chalk.red( 90 | "\nOut of the box, serverless-bundle only supports overriding " + 91 | "these Jest options:\n\n" + 92 | supportedKeys.map(key => chalk.bold(" \u2022 " + key)).join("\n") + 93 | ".\n\n" + 94 | "These options in your package.json Jest configuration " + 95 | "are not currently supported by serverless-bundle:\n\n" + 96 | unsupportedKeys 97 | .map(key => chalk.bold(" \u2022 " + key)) 98 | .join("\n") + 99 | "\n\nIf you wish to override other Jest options, " + 100 | "consider using serverless-webpack directly instead.\n" 101 | ) 102 | ); 103 | 104 | process.exit(1); 105 | } 106 | } 107 | // Include dotenv env variables 108 | require("dotenv").config({ 109 | path: "./.env" 110 | }); 111 | return config; 112 | }; 113 | -------------------------------------------------------------------------------- /scripts/config/paths.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Based on https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/paths.js 3 | */ 4 | 'use strict'; 5 | 6 | const path = require('path'); 7 | const fs = require('fs'); 8 | 9 | // Make sure any symlinks in the project folder are resolved: 10 | // https://github.com/facebook/create-react-app/issues/637 11 | const appDirectory = fs.realpathSync(process.cwd()); 12 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath); 13 | 14 | const moduleFileExtensions = [ 15 | 'js', 16 | 'jsx', 17 | ]; 18 | 19 | // Resolve file paths in the same order as webpack 20 | const resolveModule = (resolveFn, filePath) => { 21 | const extension = moduleFileExtensions.find(extension => 22 | fs.existsSync(resolveFn(`${filePath}.${extension}`)) 23 | ); 24 | 25 | if (extension) { 26 | return resolveFn(`${filePath}.${extension}`); 27 | } 28 | 29 | return resolveFn(`${filePath}.js`); 30 | }; 31 | 32 | const resolveOwn = relativePath => path.resolve(__dirname, '..', relativePath); 33 | 34 | module.exports = { 35 | appPath: resolveApp('.'), 36 | appPackageJson: resolveApp('package.json'), 37 | yarnLockFile: resolveApp('yarn.lock'), 38 | appNodeModules: resolveApp('node_modules'), 39 | ownPath: resolveOwn('.'), 40 | ownNodeModules: resolveOwn('node_modules'), 41 | }; 42 | -------------------------------------------------------------------------------- /scripts/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Based on https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/scripts/test.js 3 | */ 4 | "use strict"; 5 | 6 | // Do this as the first thing so that any code reading it knows the right env. 7 | process.env.BABEL_ENV = "test"; 8 | process.env.NODE_ENV = "test"; 9 | 10 | // Makes the script crash on unhandled rejections instead of silently 11 | // ignoring them. In the future, promise rejections that are not handled will 12 | // terminate the Node.js process with a non-zero exit code. 13 | process.on("unhandledRejection", err => { 14 | throw err; 15 | }); 16 | 17 | const jest = require("jest"); 18 | let argv = process.argv.slice(2); 19 | 20 | // Disable watchman 21 | argv.push("--no-watchman"); 22 | 23 | const createJestConfig = require("./config/createJestConfig"); 24 | const path = require("path"); 25 | const paths = require("./config/paths"); 26 | argv.push( 27 | "--config", 28 | JSON.stringify( 29 | createJestConfig( 30 | relativePath => path.resolve(__dirname, "..", relativePath), 31 | path.resolve(paths.appPath) 32 | ) 33 | ) 34 | ); 35 | 36 | // This is a very dirty workaround for https://github.com/facebook/jest/issues/5913. 37 | // We're trying to resolve the environment ourselves because Jest does it incorrectly. 38 | // TODO: remove this as soon as it's fixed in Jest. 39 | const resolve = require("resolve"); 40 | function resolveJestDefaultEnvironment(name) { 41 | const jestDir = path.dirname( 42 | resolve.sync("jest", { 43 | basedir: __dirname 44 | }) 45 | ); 46 | const jestCLIDir = path.dirname( 47 | resolve.sync("jest-cli", { 48 | basedir: jestDir 49 | }) 50 | ); 51 | const jestConfigDir = path.dirname( 52 | resolve.sync("jest-config", { 53 | basedir: jestCLIDir 54 | }) 55 | ); 56 | return resolve.sync(name, { 57 | basedir: jestConfigDir 58 | }); 59 | } 60 | let cleanArgv = []; 61 | let env = "node"; 62 | let next; 63 | do { 64 | next = argv.shift(); 65 | if (next === "--env") { 66 | env = argv.shift(); 67 | } else if (next.indexOf("--env=") === 0) { 68 | env = next.substring("--env=".length); 69 | } else { 70 | cleanArgv.push(next); 71 | } 72 | } while (argv.length > 0); 73 | argv = cleanArgv; 74 | let resolvedEnv; 75 | try { 76 | resolvedEnv = resolveJestDefaultEnvironment(`jest-environment-${env}`); 77 | } catch (e) { 78 | // ignore 79 | } 80 | if (!resolvedEnv) { 81 | try { 82 | resolvedEnv = resolveJestDefaultEnvironment(env); 83 | } catch (e) { 84 | // ignore 85 | } 86 | } 87 | const testEnvironment = resolvedEnv || env; 88 | argv.push("--env", testEnvironment); 89 | 90 | jest.run(argv); 91 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | servicePath: "", 5 | nodeVersion: null, 6 | options: { 7 | aliases: [], 8 | stats: false, 9 | caching: true, 10 | linting: true, 11 | esbuild: false, 12 | fixPackages: [], 13 | packager: "npm", 14 | copyFiles: null, 15 | concatText: null, 16 | sourcemaps: true, 17 | forceInclude: null, 18 | excludeFiles: null, 19 | ignorePackages: [], 20 | packagerOptions: {}, 21 | generateStatsFiles: false, 22 | tsConfig: "tsconfig.json", 23 | forceExclude: [], 24 | disableForkTsChecker: false, 25 | // Set non Webpack compatible packages as externals 26 | // Or if we want to exclude all packages in the node_modules: 27 | // externals: "all" 28 | externals: ["knex", "sharp"], 29 | // Set default file extensions to use the raw-loader with 30 | rawFileExtensions: ["pem", "txt"], 31 | minifyOptions: {}, 32 | experiments: {}, 33 | }, 34 | }; 35 | -------------------------------------------------------------------------------- /src/eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "es6": true 4 | }, 5 | "parser": "babel-eslint", 6 | "parserOptions": { 7 | "ecmaVersion": 2017, 8 | "sourceType": "module" 9 | }, 10 | "extends": "strongloop", 11 | "rules": { 12 | "eol-last": "off", 13 | "brace-style": "off", 14 | "comma-dangle": "off", 15 | "comma-spacing": "off", 16 | "eqeqeq": "off", 17 | "indent": "off", 18 | "key-spacing": "off", 19 | "keyword-spacing": "off", 20 | "max-len": "off", 21 | "no-ex-assign": "off", 22 | "no-extra-boolean-cast": "off", 23 | "no-multi-spaces": "off", 24 | "no-throw-literal": "off", 25 | "no-unreachable": "off", 26 | "radix": "off", 27 | "quote-props": "off", 28 | "quotes": "off", 29 | "space-before-function-paren": "off", 30 | "space-in-parens": "off", 31 | "space-infix-ops": "off", 32 | "space-unary-ops": "off", 33 | "spaced-comment": "off" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/ts.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "plugins": ["@typescript-eslint"], 4 | "parserOptions": { 5 | "ecmaVersion": 2017, 6 | "sourceType": "module" 7 | }, 8 | "extends": [ 9 | "eslint:recommended", 10 | "plugin:@typescript-eslint/eslint-recommended", 11 | "plugin:@typescript-eslint/recommended" 12 | ], 13 | "rules": {} 14 | } 15 | -------------------------------------------------------------------------------- /src/webpack.config.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | const ts = require("typescript"); 4 | const webpack = require("webpack"); 5 | const fastGlob = require("fast-glob"); 6 | const slsw = require("serverless-webpack"); 7 | const importFresh = require("import-fresh"); 8 | const ESLintPlugin = require("eslint-webpack-plugin"); 9 | const nodeExternals = require("webpack-node-externals"); 10 | const CopyWebpackPlugin = require("copy-webpack-plugin"); 11 | const { ESBuildMinifyPlugin } = require("esbuild-loader"); 12 | const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); 13 | const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); 14 | const PermissionsOutputPlugin = require("webpack-permissions-plugin"); 15 | const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); 16 | 17 | const config = require("./config"); 18 | 19 | const jsEslintConfig = require("./eslintrc.json"); 20 | const tsEslintConfig = require("./ts.eslintrc.json"); 21 | 22 | // Load the default config for reference 23 | // Note: This import potentially clears our the dynamically loaded config. So any other 24 | // imports of the config after this, load the default config as well. Make sure to 25 | // use this after importing the config. 26 | const defaultConfig = importFresh("./config"); 27 | 28 | const isLocal = slsw.lib.webpack.isLocal; 29 | 30 | const aliases = config.options.aliases; 31 | const servicePath = config.servicePath; 32 | const nodeVersion = config.nodeVersion; 33 | const externals = config.options.externals; 34 | const copyFiles = config.options.copyFiles; 35 | const experiments = config.options.experiments; 36 | const esbuildNodeVersion = "node" + nodeVersion; 37 | const forceExclude = config.options.forceExclude; 38 | const ignorePackages = config.options.ignorePackages; 39 | const rawFileExtensions = config.options.rawFileExtensions; 40 | const fixPackages = convertListToObject(config.options.fixPackages); 41 | const tsConfigPath = path.resolve(servicePath, config.options.tsConfig); 42 | const minifyOptions = config.options.minifyOptions; 43 | 44 | const ENABLE_ESBUILD = config.options.esbuild; 45 | const ENABLE_STATS = config.options.stats; 46 | const ENABLE_LINTING = config.options.linting; 47 | const ENABLE_SOURCE_MAPS = config.options.sourcemaps; 48 | const ENABLE_TYPESCRIPT = fs.existsSync(tsConfigPath); 49 | const ENABLE_TSCHECKER = !config.options.disableForkTsChecker; 50 | const GENERATE_STATS_FILES = config.options.generateStatsFiles; 51 | const ENABLE_CACHING = isLocal ? config.options.caching : false; 52 | 53 | // Handle the "all" option in externals 54 | // And add the forceExclude packages to it because they shouldn't be Webpacked 55 | const computedExternals = ( 56 | externals === "all" ? [nodeExternals()] : externals 57 | ).concat(forceExclude); 58 | 59 | const extensions = [ 60 | ".wasm", 61 | ".mjs", 62 | ".js", 63 | ".jsx", 64 | ".json", 65 | ".ts", 66 | ".tsx", 67 | ".graphql", 68 | ".gql", 69 | ]; 70 | 71 | // If tsConfig is specified and not found, throw an error 72 | if ( 73 | !ENABLE_TYPESCRIPT && 74 | config.options.tsConfig !== defaultConfig.options.tsConfig 75 | ) { 76 | throw `ERROR: ${config.options.tsConfig} not found.`; 77 | } 78 | 79 | const parsedTsConfig = parseTsConfig(); 80 | 81 | if (ENABLE_TYPESCRIPT && checkInvalidTsModule()) { 82 | console.log("serverless-bundle: CommonJS, ES3, or ES5 are not supported"); 83 | } 84 | 85 | function parseTsConfig() { 86 | // Borrowed from 87 | // https://github.com/formium/tsdx/blob/e84e8d654c8462b8db65a3d395e2a4ba79bf1bd2/src/createRollupConfig.ts#L49-L55 88 | const tsConfigJSON = ts.readConfigFile(tsConfigPath, ts.sys.readFile).config; 89 | return ts.parseJsonConfigFileContent(tsConfigJSON, ts.sys, "./"); 90 | } 91 | 92 | function checkInvalidTsModule() { 93 | const tsCompilerOptions = parsedTsConfig.options; 94 | 95 | const module = tsCompilerOptions.module; 96 | const target = tsCompilerOptions.target; 97 | 98 | return ( 99 | (module !== undefined && module === 1) || // commonjs 100 | (target !== undefined && (target === 0 || target === 1)) // es3 or es5 101 | ); 102 | } 103 | 104 | function convertListToObject(list) { 105 | var object = {}; 106 | 107 | for (var i = 0, l = list.length; i < l; i++) { 108 | object[list[i]] = true; 109 | } 110 | 111 | return object; 112 | } 113 | 114 | function resolveEntriesPath(entries) { 115 | for (let key in entries) { 116 | entries[key] = path.join(servicePath, entries[key]); 117 | } 118 | 119 | return entries; 120 | } 121 | 122 | function statModeToOctal(mode) { 123 | return (mode & parseInt("777", 8)).toString(8); 124 | } 125 | 126 | function babelLoader() { 127 | const plugins = [ 128 | "@babel/plugin-transform-runtime", 129 | "@babel/plugin-proposal-class-properties", 130 | "@babel/plugin-proposal-optional-chaining", 131 | "@babel/plugin-proposal-nullish-coalescing-operator", 132 | ]; 133 | 134 | if (ENABLE_SOURCE_MAPS) { 135 | plugins.push("babel-plugin-source-map-support"); 136 | } 137 | 138 | return { 139 | loader: "babel-loader", 140 | options: { 141 | // Enable caching 142 | cacheDirectory: ENABLE_CACHING, 143 | // Disable compresisng cache files to speed up caching 144 | cacheCompression: false, 145 | plugins: plugins.map(require.resolve), 146 | presets: [ 147 | [ 148 | require.resolve("@babel/preset-env"), 149 | { 150 | targets: { 151 | node: nodeVersion, 152 | }, 153 | }, 154 | ], 155 | ], 156 | }, 157 | }; 158 | } 159 | 160 | function esbuildLoader(loader) { 161 | const options = { 162 | loader, 163 | target: esbuildNodeVersion, 164 | }; 165 | 166 | if (ENABLE_TYPESCRIPT) { 167 | options.tsconfigRaw = fs.readFileSync(tsConfigPath); 168 | } 169 | 170 | return { 171 | loader: "esbuild-loader", 172 | options, 173 | }; 174 | } 175 | 176 | function tsLoader() { 177 | return { 178 | loader: "ts-loader", 179 | options: { 180 | projectReferences: true, 181 | configFile: tsConfigPath, 182 | experimentalWatchApi: true, 183 | // Don't check types if ForTsChecker is enabled 184 | transpileOnly: ENABLE_TSCHECKER, 185 | }, 186 | }; 187 | } 188 | 189 | function loaders() { 190 | const jsRule = { 191 | test: /\.js$/, 192 | exclude: /node_modules/, 193 | use: [ENABLE_ESBUILD ? esbuildLoader("jsx") : babelLoader()], 194 | }; 195 | 196 | const loaders = { 197 | rules: [ 198 | jsRule, 199 | { 200 | test: /\.mjs$/, 201 | include: /node_modules/, 202 | type: "javascript/auto", 203 | resolve: { 204 | fullySpecified: false, 205 | }, 206 | }, 207 | { 208 | test: /\.(graphql|gql)$/, 209 | exclude: /node_modules/, 210 | loader: "graphql-tag/loader", 211 | }, 212 | { 213 | test: /\.css$/, 214 | use: [ 215 | "isomorphic-style-loader", 216 | { 217 | loader: "css-loader", 218 | options: { 219 | importLoaders: 1, 220 | }, 221 | }, 222 | ], 223 | }, 224 | { 225 | test: /\.s[ac]ss$/i, 226 | use: [ 227 | "isomorphic-style-loader", 228 | { 229 | loader: "css-loader", 230 | options: { 231 | importLoaders: 1, 232 | }, 233 | }, 234 | { 235 | loader: "sass-loader", 236 | options: { 237 | implementation: require("sass"), 238 | }, 239 | }, 240 | ], 241 | }, 242 | { test: /\.gif|\.svg|\.png|\.jpg|\.jpeg$/, loader: "ignore-loader" }, 243 | ], 244 | }; 245 | 246 | if (ENABLE_TYPESCRIPT) { 247 | const tsRule = { 248 | test: /\.(ts|tsx)$/, 249 | use: [ENABLE_ESBUILD ? esbuildLoader("tsx") : tsLoader()], 250 | exclude: [ 251 | [ 252 | path.resolve(servicePath, "node_modules"), 253 | path.resolve(servicePath, ".serverless"), 254 | path.resolve(servicePath, ".webpack"), 255 | ], 256 | ], 257 | }; 258 | 259 | loaders.rules.push(tsRule); 260 | } 261 | 262 | if (rawFileExtensions && rawFileExtensions.length) { 263 | const rawFileRegex = `${rawFileExtensions 264 | .map((rawFileExt) => `\\.${rawFileExt}`) 265 | .join("|")}$`; 266 | 267 | loaders.rules.push({ 268 | test: new RegExp(rawFileRegex), 269 | loader: "raw-loader", 270 | }); 271 | } 272 | 273 | return loaders; 274 | } 275 | 276 | function plugins() { 277 | const plugins = []; 278 | 279 | if (GENERATE_STATS_FILES) { 280 | plugins.push( 281 | new BundleAnalyzerPlugin({ 282 | openAnalyzer: false, 283 | analyzerMode: "static", 284 | generateStatsFile: true, 285 | statsFilename: "bundle_stats.json", 286 | reportFilename: "bundle_stats.html", 287 | }) 288 | ); 289 | } 290 | 291 | if (ENABLE_TYPESCRIPT && ENABLE_TSCHECKER) { 292 | const forkTsCheckerWebpackOptions = { 293 | typescript: { 294 | configFile: tsConfigPath, 295 | build: true, 296 | }, 297 | }; 298 | 299 | if (ENABLE_LINTING) { 300 | if (parsedTsConfig.exclude) { 301 | tsEslintConfig.ignorePatterns = parsedTsConfig.exclude; 302 | } 303 | forkTsCheckerWebpackOptions.eslint = { 304 | files: path.join(servicePath, "**/*.ts"), 305 | options: { cwd: servicePath, baseConfig: tsEslintConfig }, 306 | }; 307 | } 308 | 309 | plugins.push(new ForkTsCheckerWebpackPlugin(forkTsCheckerWebpackOptions)); 310 | } 311 | 312 | if (ENABLE_LINTING) { 313 | plugins.push( 314 | new ESLintPlugin({ 315 | context: servicePath, 316 | baseConfig: jsEslintConfig, 317 | extensions: "js", 318 | }) 319 | ); 320 | 321 | // If the ForkTsChecker is disabled, then let Eslint do the linting 322 | if (ENABLE_TYPESCRIPT && !ENABLE_TSCHECKER) { 323 | plugins.push( 324 | new ESLintPlugin({ 325 | context: servicePath, 326 | baseConfig: tsEslintConfig, 327 | extensions: ["ts"], 328 | }) 329 | ); 330 | } 331 | } 332 | 333 | if (copyFiles) { 334 | plugins.push( 335 | new CopyWebpackPlugin({ 336 | patterns: copyFiles.map(function (data) { 337 | return { 338 | to: data.to, 339 | context: servicePath, 340 | from: path.join(servicePath, data.from), 341 | }; 342 | }), 343 | }) 344 | ); 345 | 346 | // Copy file permissions 347 | const buildFiles = []; 348 | copyFiles.forEach(function (data) { 349 | const entries = fastGlob.sync([data.from]); 350 | // loop through each file matched by fg 351 | entries.forEach(function (entry) { 352 | // get source file stat 353 | const stat = fs.statSync(path.resolve(servicePath, entry)); 354 | const { serverless } = slsw.lib; 355 | if ( 356 | serverless.service.package.individually && 357 | serverless.service.functions 358 | ) { 359 | for (let key in serverless.service.functions) { 360 | buildFiles.push({ 361 | fileMode: statModeToOctal(stat.mode), 362 | path: path.resolve(data.to, `.webpack/${key}`, entry), 363 | }); 364 | } 365 | } else { 366 | buildFiles.push({ 367 | fileMode: statModeToOctal(stat.mode), 368 | path: path.resolve(data.to, ".webpack/service", entry), 369 | }); 370 | } 371 | }); 372 | }); 373 | plugins.push(new PermissionsOutputPlugin({ buildFiles })); 374 | } 375 | 376 | // Ignore all locale files of moment.js 377 | plugins.push( 378 | new webpack.IgnorePlugin({ 379 | resourceRegExp: /^\.\/locale$/, 380 | contextRegExp: /moment$/, 381 | }) 382 | ); 383 | 384 | // Ignore any packages specified in the `ignorePackages` option 385 | for (let i = 0, l = ignorePackages.length; i < l; i++) { 386 | plugins.push( 387 | new webpack.IgnorePlugin({ 388 | resourceRegExp: new RegExp("^" + ignorePackages[i] + "$"), 389 | }) 390 | ); 391 | } 392 | 393 | if (fixPackages["formidable@1.x"]) { 394 | plugins.push(new webpack.DefinePlugin({ "global.GENTLY": false })); 395 | } 396 | 397 | return plugins; 398 | } 399 | 400 | function resolvePlugins() { 401 | const plugins = []; 402 | 403 | if (ENABLE_TYPESCRIPT && (parsedTsConfig.options || {}).baseUrl) { 404 | plugins.push( 405 | new TsconfigPathsPlugin({ 406 | configFile: tsConfigPath, 407 | extensions: extensions, 408 | }) 409 | ); 410 | } 411 | 412 | return plugins; 413 | } 414 | 415 | function alias() { 416 | return aliases.reduce((obj, item) => { 417 | const [key, value] = Object.entries(item)[0]; 418 | if (typeof value === "string") { 419 | obj[key] = path.join(servicePath, value); 420 | } else { 421 | obj[key] = value; 422 | } 423 | return obj; 424 | }, {}); 425 | } 426 | 427 | module.exports = { 428 | entry: resolveEntriesPath(slsw.lib.entries), 429 | target: "node", 430 | context: __dirname, 431 | // Disable verbose logs 432 | stats: ENABLE_STATS ? "normal" : "errors-only", 433 | devtool: ENABLE_SOURCE_MAPS ? "source-map" : false, 434 | externals: computedExternals, 435 | mode: isLocal ? "development" : "production", 436 | performance: { 437 | // Turn off size warnings for entry points 438 | hints: false, 439 | }, 440 | resolve: { 441 | // Performance 442 | symlinks: false, 443 | extensions: extensions, 444 | alias: alias(), 445 | // First start by looking for modules in the plugin's node_modules 446 | // before looking inside the project's node_modules. 447 | modules: [path.resolve(__dirname, "node_modules"), "node_modules"], 448 | plugins: resolvePlugins(), 449 | }, 450 | // Add loaders 451 | module: loaders(), 452 | // PERFORMANCE ONLY FOR DEVELOPMENT 453 | optimization: isLocal 454 | ? { 455 | nodeEnv: false, 456 | splitChunks: false, 457 | removeEmptyChunks: false, 458 | removeAvailableModules: false, 459 | } 460 | : { 461 | nodeEnv: false, 462 | minimizer: [ 463 | new ESBuildMinifyPlugin({ 464 | target: esbuildNodeVersion, 465 | ...minifyOptions, 466 | }), 467 | ], 468 | }, 469 | plugins: plugins(), 470 | experiments, 471 | node: { 472 | __dirname: false, 473 | }, 474 | }; 475 | -------------------------------------------------------------------------------- /tests/aliases-false/aliases-false.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("aliases-false", async () => { 12 | expect.assertions(1); 13 | 14 | const webpackErrorRegex = /"TypeError: is_sorted(.*)is not a function"/; 15 | 16 | try { 17 | await runSlsCommand(__dirname); 18 | } catch (err) { 19 | expect(err.stdout).toMatch(webpackErrorRegex); 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /tests/aliases-false/handler.js: -------------------------------------------------------------------------------- 1 | import sorted from "is-sorted"; 2 | 3 | export const hello = async (event) => { 4 | sorted([1, 2, 3]); 5 | return { 6 | statusCode: 200, 7 | body: JSON.stringify({ 8 | message: "Go Serverless v1.0! Your function executed successfully!", 9 | input: event, 10 | }), 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /tests/aliases-false/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliases-false", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "aliases-false", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "is-sorted": "^1.0.5" 13 | } 14 | }, 15 | "node_modules/is-sorted": { 16 | "version": "1.0.5", 17 | "resolved": "https://registry.npmjs.org/is-sorted/-/is-sorted-1.0.5.tgz", 18 | "integrity": "sha512-KZJvKDrI+Kg3ixeDaZQIt7RIwcGnm07+NSipyj1r9MtjDrLG678ETy4yO6dBJLUjejPdge9fLCGxsWkQO/3PJg==" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/aliases-false/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliases-false", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "is-sorted": "^1.0.5" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/aliases-false/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - "../../index" 5 | 6 | custom: 7 | bundle: 8 | aliases: 9 | - "is-sorted": false 10 | 11 | provider: 12 | name: aws 13 | runtime: nodejs20.x 14 | 15 | functions: 16 | hello: 17 | handler: handler.hello 18 | -------------------------------------------------------------------------------- /tests/aliases-jest/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "sourceType": "module" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/aliases-jest/aliases-jest.test.js: -------------------------------------------------------------------------------- 1 | const { runJestCommand, clearNpmCache } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("aliases-jest", async () => { 12 | const result = await runJestCommand(__dirname); 13 | 14 | // Ensure Jest ran the included tests successfully 15 | expect(result).not.toMatch(/failed/); 16 | }); 17 | -------------------------------------------------------------------------------- /tests/aliases-jest/handler.js: -------------------------------------------------------------------------------- 1 | import sum from "libs/sum"; 2 | 3 | const res = (body = {}) => ({ 4 | statusCode: 200, 5 | body: JSON.stringify(body, null, 2) 6 | }); 7 | 8 | export const hello = () => 9 | res({ 10 | sum: sum(1, 2, 3) 11 | }); 12 | -------------------------------------------------------------------------------- /tests/aliases-jest/libs/sum.js: -------------------------------------------------------------------------------- 1 | export default (...numbers) => numbers.reduce((acc, nbr) => acc + nbr); 2 | -------------------------------------------------------------------------------- /tests/aliases-jest/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliases-jest", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "aliases-jest", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/aliases-jest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliases-jest", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "../../bin/scripts.js test --testPathIgnorePatterns=\"./aliases-jest.test.js\"" 8 | }, 9 | "jest": { 10 | "moduleNameMapper": { 11 | "libs(.*)$": "/libs/$1" 12 | } 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC" 17 | } 18 | -------------------------------------------------------------------------------- /tests/aliases-jest/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/aliases-jest/tests/index.test.js: -------------------------------------------------------------------------------- 1 | import { hello } from "../handler"; 2 | 3 | test("hello returns sum equal 6 in body", () => { 4 | const expected = 6; 5 | const actual = JSON.parse(hello().body).sum; 6 | 7 | expect(actual).toBe(expected); 8 | }); 9 | -------------------------------------------------------------------------------- /tests/aliases/aliases.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("aliases", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/aliases/custom-lib/src/some-lib/index.js: -------------------------------------------------------------------------------- 1 | export function doSomething() { 2 | return "done"; 3 | } 4 | -------------------------------------------------------------------------------- /tests/aliases/handler.js: -------------------------------------------------------------------------------- 1 | import { doSomething } from "@my-org/some-lib"; 2 | 3 | export const hello = async (event, context) => { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify({ 7 | message: doSomething(), 8 | input: event 9 | }) 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /tests/aliases/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliases", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "aliases", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/aliases/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliases", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/aliases/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | custom: 4 | bundle: 5 | aliases: 6 | - "@my-org/some-lib": custom-lib/src/some-lib 7 | 8 | plugins: 9 | - '../../index' 10 | 11 | provider: 12 | name: aws 13 | runtime: nodejs20.x 14 | 15 | functions: 16 | hello: 17 | handler: handler.hello 18 | -------------------------------------------------------------------------------- /tests/base/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/base/base.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("base", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/base/handler.js: -------------------------------------------------------------------------------- 1 | export const hello = async (event, context) => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: 'Go Serverless v1.0! Your function executed successfully!', 6 | input: event, 7 | }), 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/base/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "base", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "base", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "base", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/base/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/class-properties/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/class-properties/class-properties.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("class-properties", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/class-properties/handler.js: -------------------------------------------------------------------------------- 1 | class TestClass { 2 | attribute1; 3 | 4 | constructor(data) { 5 | this.attribute1 = data.attribute1; 6 | } 7 | } 8 | 9 | export const hello = async (event, context) => { 10 | const a = new TestClass({ attribute1: "test" }); 11 | 12 | console.log(a); // eslint-disable-line 13 | 14 | return { 15 | statusCode: 200, 16 | body: JSON.stringify({ 17 | message: "Go Serverless v1.0! Your function executed successfully!", 18 | input: event 19 | }) 20 | }; 21 | }; 22 | -------------------------------------------------------------------------------- /tests/class-properties/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "class-properties", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "class-properties", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/class-properties/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "class-properties", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/class-properties/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/copy-files-individually-packaged/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/copy-files-individually-packaged/bin/echo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo $1 -------------------------------------------------------------------------------- /tests/copy-files-individually-packaged/copy-files-individually-packaged.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | const { existsSync, statSync } = require("fs"); 3 | 4 | beforeEach(async () => { 5 | await clearNpmCache(__dirname); 6 | }); 7 | 8 | afterAll(async () => { 9 | await clearNpmCache(__dirname); 10 | }); 11 | 12 | const TEST_DIR = "tests/copy-files-individually-packaged"; 13 | const WEBPACK_DIR = `${TEST_DIR}/.webpack`; 14 | 15 | test("copy files - hello", async () => { 16 | const result = await runSlsCommand(__dirname); 17 | 18 | expect(result).not.toMatch(errorRegex); 19 | expect(existsSync(`${WEBPACK_DIR}/hello/public/test.txt`)).toBe(true); 20 | expect(existsSync(`${WEBPACK_DIR}/hello/bin/echo.sh`)).toBe(true); 21 | 22 | let fromStat = statSync(`${TEST_DIR}/public/test.txt`); 23 | let toStat = statSync(`${WEBPACK_DIR}/hello/public/test.txt`); 24 | expect(toStat.mode).toBe(fromStat.mode); 25 | 26 | fromStat = statSync(`${TEST_DIR}/bin/echo.sh`); 27 | toStat = statSync(`${WEBPACK_DIR}/hello/bin/echo.sh`); 28 | expect(toStat.mode).toBe(fromStat.mode); 29 | }); 30 | 31 | test("copy files - world", async () => { 32 | const cmd = "invoke local -f world --data {}"; 33 | const result = await runSlsCommand(__dirname, cmd); 34 | 35 | expect(result).not.toMatch(errorRegex); 36 | expect(existsSync(`${WEBPACK_DIR}/world/public/test.txt`)).toBe(true); 37 | expect(existsSync(`${WEBPACK_DIR}/world/bin/echo.sh`)).toBe(true); 38 | 39 | let fromStat = statSync(`${TEST_DIR}/public/test.txt`); 40 | let toStat = statSync(`${WEBPACK_DIR}/world/public/test.txt`); 41 | expect(toStat.mode).toBe(fromStat.mode); 42 | 43 | fromStat = statSync(`${TEST_DIR}/bin/echo.sh`); 44 | toStat = statSync(`${WEBPACK_DIR}/world/bin/echo.sh`); 45 | expect(toStat.mode).toBe(fromStat.mode); 46 | }); 47 | -------------------------------------------------------------------------------- /tests/copy-files-individually-packaged/handler.js: -------------------------------------------------------------------------------- 1 | export const hello = async event => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: "Go Serverless v1.0! Your function executed successfully!", 6 | input: event 7 | }) 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/copy-files-individually-packaged/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "copy-files-individually-packaged", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "copy-files-individually-packaged", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/copy-files-individually-packaged/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "copy-files-individually-packaged", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/copy-files-individually-packaged/public/test.txt: -------------------------------------------------------------------------------- 1 | Testing file 2 | -------------------------------------------------------------------------------- /tests/copy-files-individually-packaged/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - "../../index" 5 | 6 | package: 7 | individually: true 8 | 9 | custom: 10 | bundle: 11 | stats: true 12 | copyFiles: 13 | - to: "./" 14 | from: "public/*" 15 | - to: "./" 16 | from: "bin/*" 17 | 18 | provider: 19 | name: aws 20 | runtime: nodejs20.x 21 | 22 | functions: 23 | hello: 24 | handler: handler.hello 25 | world: 26 | handler: world.hello 27 | -------------------------------------------------------------------------------- /tests/copy-files-individually-packaged/world.js: -------------------------------------------------------------------------------- 1 | export const hello = async event => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: "Go Serverless v1.0! Your function executed successfully!", 6 | input: event 7 | }) 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/copy-files/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/copy-files/bin/echo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo $1 -------------------------------------------------------------------------------- /tests/copy-files/copy-files.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | const { existsSync, statSync } = require("fs"); 3 | 4 | beforeEach(async () => { 5 | await clearNpmCache(__dirname); 6 | }); 7 | 8 | afterAll(async () => { 9 | await clearNpmCache(__dirname); 10 | }); 11 | 12 | const TEST_DIR = "tests/copy-files"; 13 | const WEBPACK_DIR = `${TEST_DIR}/.webpack`; 14 | 15 | test("copy files - hello", async () => { 16 | const result = await runSlsCommand(__dirname); 17 | 18 | expect(result).not.toMatch(errorRegex); 19 | expect(existsSync(`${WEBPACK_DIR}/service/public/test.txt`)).toBe(true); 20 | expect(existsSync(`${WEBPACK_DIR}/service/bin/echo.sh`)).toBe(true); 21 | 22 | let fromStat = statSync(`${TEST_DIR}/public/test.txt`); 23 | let toStat = statSync(`${WEBPACK_DIR}/service/public/test.txt`); 24 | expect(toStat.mode).toBe(fromStat.mode); 25 | 26 | fromStat = statSync(`${TEST_DIR}/bin/echo.sh`); 27 | toStat = statSync(`${WEBPACK_DIR}/service/bin/echo.sh`); 28 | expect(toStat.mode).toBe(fromStat.mode); 29 | }); 30 | 31 | test("copy files - world", async () => { 32 | const cmd = "invoke local -f world --data {}"; 33 | const result = await runSlsCommand(__dirname, cmd); 34 | 35 | expect(result).not.toMatch(errorRegex); 36 | expect(existsSync(`${WEBPACK_DIR}/service/public/test.txt`)).toBe(true); 37 | expect(existsSync(`${WEBPACK_DIR}/service/bin/echo.sh`)).toBe(true); 38 | 39 | let fromStat = statSync(`${TEST_DIR}/public/test.txt`); 40 | let toStat = statSync(`${WEBPACK_DIR}/service/public/test.txt`); 41 | expect(toStat.mode).toBe(fromStat.mode); 42 | 43 | fromStat = statSync(`${TEST_DIR}/bin/echo.sh`); 44 | toStat = statSync(`${WEBPACK_DIR}/service/bin/echo.sh`); 45 | expect(toStat.mode).toBe(fromStat.mode); 46 | }); 47 | -------------------------------------------------------------------------------- /tests/copy-files/handler.js: -------------------------------------------------------------------------------- 1 | export const hello = async event => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: "Go Serverless v1.0! Your function executed successfully!", 6 | input: event 7 | }) 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/copy-files/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "copy-files", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "copy-files", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/copy-files/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "copy-files", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/copy-files/public/test.txt: -------------------------------------------------------------------------------- 1 | Testing file 2 | -------------------------------------------------------------------------------- /tests/copy-files/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - "../../index" 5 | 6 | package: 7 | individually: false 8 | 9 | custom: 10 | bundle: 11 | stats: true 12 | copyFiles: 13 | - to: "./" 14 | from: "public/*" 15 | - to: "./" 16 | from: "bin/*" 17 | 18 | provider: 19 | name: aws 20 | runtime: nodejs20.x 21 | 22 | functions: 23 | hello: 24 | handler: handler.hello 25 | world: 26 | handler: world.hello 27 | -------------------------------------------------------------------------------- /tests/copy-files/world.js: -------------------------------------------------------------------------------- 1 | export const hello = async event => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: "Go Serverless v1.0! Your function executed successfully!", 6 | input: event 7 | }) 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/disable-eslint/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/disable-eslint/disable-eslint.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("disable eslint", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/disable-eslint/handler.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | 3 | export const hello = async (event, context) => { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify({ 7 | message: 'Go Serverless v1.0! Your function executed successfully!', 8 | input: event, 9 | }), 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /tests/disable-eslint/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "disable-eslint", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "disable-eslint", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/disable-eslint/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "disable-eslint", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/disable-eslint/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | custom: 4 | bundle: 5 | linting: false 6 | 7 | plugins: 8 | - '../../index' 9 | 10 | provider: 11 | name: aws 12 | runtime: nodejs20.x 13 | 14 | functions: 15 | hello: 16 | handler: handler.hello 17 | -------------------------------------------------------------------------------- /tests/esbuild/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/esbuild/esbuild.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("esbuild", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/esbuild/handler.js: -------------------------------------------------------------------------------- 1 | export const hello = async (event, context) => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: 'Go Serverless v1.0! Your function executed successfully!', 6 | input: event, 7 | }), 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/esbuild/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esbuild", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "esbuild", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "esbuild-loader": "^2.9.2", 13 | "reflect-metadata": "^0.1.13" 14 | } 15 | }, 16 | "node_modules/big.js": { 17 | "version": "5.2.2", 18 | "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", 19 | "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", 20 | "dev": true, 21 | "engines": { 22 | "node": "*" 23 | } 24 | }, 25 | "node_modules/emojis-list": { 26 | "version": "3.0.0", 27 | "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", 28 | "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", 29 | "dev": true, 30 | "engines": { 31 | "node": ">= 4" 32 | } 33 | }, 34 | "node_modules/esbuild": { 35 | "version": "0.8.55", 36 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.8.55.tgz", 37 | "integrity": "sha512-mM/s7hjYe5mQR+zAWOM5JVrCtYCke182E9l1Bbs6rG5EDP3b1gZF9sHZka53PD/iNt6OccymVZRWkTtBfcKW4w==", 38 | "dev": true, 39 | "hasInstallScript": true, 40 | "bin": { 41 | "esbuild": "bin/esbuild" 42 | } 43 | }, 44 | "node_modules/esbuild-loader": { 45 | "version": "2.9.2", 46 | "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.9.2.tgz", 47 | "integrity": "sha512-HpF+r/ES2aC40VDOIFsP8OIOM2y2vj8LyLwJ4G8DCMOi8Kov68TwCtxiMMTuSuxR/xKDu/ykgVyCEgps6BXpYw==", 48 | "dev": true, 49 | "dependencies": { 50 | "esbuild": "^0.8.42", 51 | "joycon": "^2.2.5", 52 | "json5": "^2.2.0", 53 | "loader-utils": "^2.0.0", 54 | "type-fest": "^0.20.2", 55 | "webpack-sources": "^2.2.0" 56 | } 57 | }, 58 | "node_modules/joycon": { 59 | "version": "2.2.5", 60 | "resolved": "https://registry.npmjs.org/joycon/-/joycon-2.2.5.tgz", 61 | "integrity": "sha512-YqvUxoOcVPnCp0VU1/56f+iKSdvIRJYPznH22BdXV3xMk75SFXhWeJkZ8C9XxUWt1b5x2X1SxuFygW1U0FmkEQ==", 62 | "dev": true, 63 | "engines": { 64 | "node": ">=6" 65 | } 66 | }, 67 | "node_modules/json5": { 68 | "version": "2.2.0", 69 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", 70 | "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", 71 | "dev": true, 72 | "dependencies": { 73 | "minimist": "^1.2.5" 74 | }, 75 | "bin": { 76 | "json5": "lib/cli.js" 77 | }, 78 | "engines": { 79 | "node": ">=6" 80 | } 81 | }, 82 | "node_modules/loader-utils": { 83 | "version": "2.0.0", 84 | "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", 85 | "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", 86 | "dev": true, 87 | "dependencies": { 88 | "big.js": "^5.2.2", 89 | "emojis-list": "^3.0.0", 90 | "json5": "^2.1.2" 91 | }, 92 | "engines": { 93 | "node": ">=8.9.0" 94 | } 95 | }, 96 | "node_modules/minimist": { 97 | "version": "1.2.5", 98 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 99 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 100 | "dev": true 101 | }, 102 | "node_modules/reflect-metadata": { 103 | "version": "0.1.13", 104 | "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", 105 | "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", 106 | "dev": true 107 | }, 108 | "node_modules/source-list-map": { 109 | "version": "2.0.1", 110 | "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", 111 | "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", 112 | "dev": true 113 | }, 114 | "node_modules/source-map": { 115 | "version": "0.6.1", 116 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 117 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 118 | "dev": true, 119 | "engines": { 120 | "node": ">=0.10.0" 121 | } 122 | }, 123 | "node_modules/type-fest": { 124 | "version": "0.20.2", 125 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 126 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 127 | "dev": true, 128 | "engines": { 129 | "node": ">=10" 130 | } 131 | }, 132 | "node_modules/webpack-sources": { 133 | "version": "2.2.0", 134 | "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", 135 | "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", 136 | "dev": true, 137 | "dependencies": { 138 | "source-list-map": "^2.0.1", 139 | "source-map": "^0.6.1" 140 | }, 141 | "engines": { 142 | "node": ">=10.13.0" 143 | } 144 | } 145 | }, 146 | "dependencies": { 147 | "big.js": { 148 | "version": "5.2.2", 149 | "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", 150 | "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", 151 | "dev": true 152 | }, 153 | "emojis-list": { 154 | "version": "3.0.0", 155 | "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", 156 | "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", 157 | "dev": true 158 | }, 159 | "esbuild": { 160 | "version": "0.8.55", 161 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.8.55.tgz", 162 | "integrity": "sha512-mM/s7hjYe5mQR+zAWOM5JVrCtYCke182E9l1Bbs6rG5EDP3b1gZF9sHZka53PD/iNt6OccymVZRWkTtBfcKW4w==", 163 | "dev": true 164 | }, 165 | "esbuild-loader": { 166 | "version": "2.9.2", 167 | "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.9.2.tgz", 168 | "integrity": "sha512-HpF+r/ES2aC40VDOIFsP8OIOM2y2vj8LyLwJ4G8DCMOi8Kov68TwCtxiMMTuSuxR/xKDu/ykgVyCEgps6BXpYw==", 169 | "dev": true, 170 | "requires": { 171 | "esbuild": "^0.8.42", 172 | "joycon": "^2.2.5", 173 | "json5": "^2.2.0", 174 | "loader-utils": "^2.0.0", 175 | "type-fest": "^0.20.2", 176 | "webpack-sources": "^2.2.0" 177 | } 178 | }, 179 | "joycon": { 180 | "version": "2.2.5", 181 | "resolved": "https://registry.npmjs.org/joycon/-/joycon-2.2.5.tgz", 182 | "integrity": "sha512-YqvUxoOcVPnCp0VU1/56f+iKSdvIRJYPznH22BdXV3xMk75SFXhWeJkZ8C9XxUWt1b5x2X1SxuFygW1U0FmkEQ==", 183 | "dev": true 184 | }, 185 | "json5": { 186 | "version": "2.2.0", 187 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", 188 | "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", 189 | "dev": true, 190 | "requires": { 191 | "minimist": "^1.2.5" 192 | } 193 | }, 194 | "loader-utils": { 195 | "version": "2.0.0", 196 | "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", 197 | "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", 198 | "dev": true, 199 | "requires": { 200 | "big.js": "^5.2.2", 201 | "emojis-list": "^3.0.0", 202 | "json5": "^2.1.2" 203 | } 204 | }, 205 | "minimist": { 206 | "version": "1.2.5", 207 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 208 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 209 | "dev": true 210 | }, 211 | "reflect-metadata": { 212 | "version": "0.1.13", 213 | "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", 214 | "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", 215 | "dev": true 216 | }, 217 | "source-list-map": { 218 | "version": "2.0.1", 219 | "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", 220 | "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", 221 | "dev": true 222 | }, 223 | "source-map": { 224 | "version": "0.6.1", 225 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 226 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 227 | "dev": true 228 | }, 229 | "type-fest": { 230 | "version": "0.20.2", 231 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 232 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 233 | "dev": true 234 | }, 235 | "webpack-sources": { 236 | "version": "2.2.0", 237 | "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", 238 | "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", 239 | "dev": true, 240 | "requires": { 241 | "source-list-map": "^2.0.1", 242 | "source-map": "^0.6.1" 243 | } 244 | } 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /tests/esbuild/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esbuild", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "esbuild-loader": "^2.9.2", 14 | "reflect-metadata": "^0.1.13" 15 | }, 16 | "dependencies": {} 17 | } 18 | -------------------------------------------------------------------------------- /tests/esbuild/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | esbuild: true 9 | 10 | provider: 11 | name: aws 12 | runtime: nodejs20.x 13 | 14 | functions: 15 | hello: 16 | handler: handler.hello 17 | -------------------------------------------------------------------------------- /tests/externals-all/externals-all.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("externals all option", async () => { 12 | const result = await runSlsCommand(__dirname, "package", true); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | 16 | /* 17 | Ensure that array-first is packaged as a part of the "all" externals option 18 | */ 19 | expect(result).toContain("Packing external modules: array-first@"); 20 | }); 21 | -------------------------------------------------------------------------------- /tests/externals-all/handler.js: -------------------------------------------------------------------------------- 1 | const first = require("array-first"); 2 | 3 | export const hello = async event => { 4 | const item = first(["a", "b", "c", "d", "e", "f"]); 5 | return { 6 | statusCode: 200, 7 | body: JSON.stringify({ 8 | message: `Go Serverless v1.0! Your function executed successfully! ${item}`, 9 | input: event 10 | }) 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /tests/externals-all/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "externals-all", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "externals-all", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "array-first": "^1.0.2" 13 | } 14 | }, 15 | "node_modules/array-first": { 16 | "version": "1.0.2", 17 | "resolved": "https://registry.npmjs.org/array-first/-/array-first-1.0.2.tgz", 18 | "integrity": "sha1-mGZxgQdKwlZrPCmT4Swx7/muJQY=", 19 | "dependencies": { 20 | "array-slice": "^0.2.3", 21 | "is-number": "^2.1.0" 22 | }, 23 | "engines": { 24 | "node": ">=0.10.0" 25 | } 26 | }, 27 | "node_modules/array-slice": { 28 | "version": "0.2.3", 29 | "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", 30 | "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", 31 | "engines": { 32 | "node": ">=0.10.0" 33 | } 34 | }, 35 | "node_modules/is-buffer": { 36 | "version": "1.1.6", 37 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 38 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 39 | }, 40 | "node_modules/is-number": { 41 | "version": "2.1.0", 42 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", 43 | "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", 44 | "dependencies": { 45 | "kind-of": "^3.0.2" 46 | }, 47 | "engines": { 48 | "node": ">=0.10.0" 49 | } 50 | }, 51 | "node_modules/kind-of": { 52 | "version": "3.2.2", 53 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 54 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 55 | "dependencies": { 56 | "is-buffer": "^1.1.5" 57 | }, 58 | "engines": { 59 | "node": ">=0.10.0" 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/externals-all/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "externals-all", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "array-first": "^1.0.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/externals-all/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | externals: all 9 | 10 | provider: 11 | name: aws 12 | runtime: nodejs20.x 13 | 14 | functions: 15 | hello: 16 | handler: handler.hello 17 | -------------------------------------------------------------------------------- /tests/externals/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/externals/externals.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("externals with forceInclude", async () => { 12 | const result = await runSlsCommand(__dirname, "package", true); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | 16 | /* 17 | Ensure that knex is packaged as an external by default 18 | And mysql is packaged because of forceInclude 19 | */ 20 | expect(result).toContain("Packing external modules: knex@^3.1.0, mysql"); 21 | }); 22 | -------------------------------------------------------------------------------- /tests/externals/handler.js: -------------------------------------------------------------------------------- 1 | import * as Knex from "knex"; 2 | 3 | function getConnection() { 4 | return Knex({ 5 | client: "pg", 6 | connection: "postgres://postgres:password1@localhost:5432/postgres", 7 | searchPath: ["knex", "public"] 8 | }); 9 | } 10 | 11 | export const hello = async (event, context) => { 12 | getConnection(); 13 | 14 | return { 15 | statusCode: 200, 16 | body: JSON.stringify({ 17 | message: "Go Serverless v1.0! Your function executed successfully!", 18 | input: event 19 | }) 20 | }; 21 | }; 22 | -------------------------------------------------------------------------------- /tests/externals/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "externals", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "knex": "^3.1.0", 14 | "pg": "^8.12.0", 15 | "pg-hstore": "^2.3.4", 16 | "sequelize": "^6.37.3", 17 | "sharp": "^0.33.5" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/externals/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | forceInclude: 9 | - mysql 10 | 11 | provider: 12 | name: aws 13 | runtime: nodejs20.x 14 | 15 | functions: 16 | hello: 17 | handler: handler.hello 18 | -------------------------------------------------------------------------------- /tests/failed-eslint/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/failed-eslint/include.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | 3 | export default function include() { 4 | console.log(1); 5 | } 6 | -------------------------------------------------------------------------------- /tests/failed-eslint/service/failed-eslint.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache } = require("../../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("check eslint", async () => { 12 | expect.assertions(1); 13 | 14 | const eslintErrorString = "no-unused-vars"; 15 | 16 | try { 17 | await runSlsCommand(__dirname); 18 | } catch (err) { 19 | expect(err.stdout).toContain(eslintErrorString); 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /tests/failed-eslint/service/handler.js: -------------------------------------------------------------------------------- 1 | import include from "../include"; 2 | 3 | const a = ""; 4 | 5 | export const hello = async (event, context) => { 6 | include(); 7 | return { 8 | statusCode: 200, 9 | body: JSON.stringify({ 10 | message: "Go Serverless v1.0! Your function executed successfully!", 11 | input: event, 12 | }), 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /tests/failed-eslint/service/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "service", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "service", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/failed-eslint/service/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "service", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/failed-eslint/service/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../../index' 5 | 6 | custom: 7 | bundle: 8 | caching: false 9 | 10 | provider: 11 | name: aws 12 | runtime: nodejs20.x 13 | 14 | functions: 15 | hello: 16 | handler: handler.hello 17 | -------------------------------------------------------------------------------- /tests/fixpackages-formidable/fixpackages-formidable.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("fixpackages-formidable", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/fixpackages-formidable/handler.js: -------------------------------------------------------------------------------- 1 | import formidable from "formidable"; // eslint-disable-line 2 | 3 | export const hello = (event, context) => { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify({ 7 | message: "Go Serverless v1.0! Your function executed successfully!", 8 | input: event 9 | }) 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /tests/fixpackages-formidable/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fixpackages-formidable", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "fixpackages-formidable", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "formidable": "^1.2.2" 13 | } 14 | }, 15 | "node_modules/formidable": { 16 | "version": "1.2.2", 17 | "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", 18 | "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==", 19 | "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", 20 | "funding": { 21 | "url": "https://ko-fi.com/tunnckoCore/commissions" 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/fixpackages-formidable/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fixpackages-formidable", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "formidable": "^1.2.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/fixpackages-formidable/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | fixPackages: 9 | - "formidable@1.x" 10 | 11 | provider: 12 | name: aws 13 | runtime: nodejs20.x 14 | 15 | functions: 16 | hello: 17 | handler: handler.hello 18 | -------------------------------------------------------------------------------- /tests/force-exclude/force-exclude.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("force-exclude", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | 17 | test("force-exclude package", async () => { 18 | const result = await runSlsCommand( 19 | __dirname, 20 | "package -c serverless.yml", 21 | true 22 | ); 23 | 24 | console.log(result); 25 | 26 | expect(result).not.toMatch(errorRegex); 27 | 28 | /* 29 | Ensure that is-sorted and aws-sdk is excluded 30 | */ 31 | expect(result).toContain("Excluding external modules: is-sorted@"); 32 | }); 33 | 34 | test("force-exclude package (node18)", async () => { 35 | const result = await runSlsCommand( 36 | __dirname, 37 | "package -c serverless.node18.yml", 38 | true 39 | ); 40 | 41 | expect(result).not.toMatch(errorRegex); 42 | 43 | /* 44 | Ensure that is-sorted is excluded 45 | */ 46 | expect(result).toContain("Excluding external modules: is-sorted@"); 47 | }); 48 | -------------------------------------------------------------------------------- /tests/force-exclude/handler.js: -------------------------------------------------------------------------------- 1 | import sorted from "is-sorted"; 2 | import AWS from "aws-sdk"; 3 | 4 | export const hello = async (event) => { 5 | // Include a dummy AWS SDK call to ensure webpack attempts to bundle it 6 | AWS.config.update({ 7 | region: "us-east-1", 8 | }); 9 | sorted([1, 2, 3]); 10 | return { 11 | statusCode: 200, 12 | body: JSON.stringify({ 13 | message: "Go Serverless v1.0! Your function executed successfully!", 14 | input: event 15 | }) 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /tests/force-exclude/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "force-exclude", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "force-exclude", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "aws-sdk": "^2.1502.0", 13 | "is-sorted": "^1.0.5" 14 | } 15 | }, 16 | "node_modules/available-typed-arrays": { 17 | "version": "1.0.7", 18 | "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", 19 | "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", 20 | "dependencies": { 21 | "possible-typed-array-names": "^1.0.0" 22 | }, 23 | "engines": { 24 | "node": ">= 0.4" 25 | }, 26 | "funding": { 27 | "url": "https://github.com/sponsors/ljharb" 28 | } 29 | }, 30 | "node_modules/aws-sdk": { 31 | "version": "2.1686.0", 32 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1686.0.tgz", 33 | "integrity": "sha512-N2VZPWKFtSPlHro+MJzxESNT8B8+3iX1TYg8m/lswGy9gHELY0PX3BGukMNbxhp5u0WKApzZR1fkNTajRGrFvw==", 34 | "hasInstallScript": true, 35 | "dependencies": { 36 | "buffer": "4.9.2", 37 | "events": "1.1.1", 38 | "ieee754": "1.1.13", 39 | "jmespath": "0.16.0", 40 | "querystring": "0.2.0", 41 | "sax": "1.2.1", 42 | "url": "0.10.3", 43 | "util": "^0.12.4", 44 | "uuid": "8.0.0", 45 | "xml2js": "0.6.2" 46 | }, 47 | "engines": { 48 | "node": ">= 10.0.0" 49 | } 50 | }, 51 | "node_modules/base64-js": { 52 | "version": "1.5.1", 53 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 54 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 55 | "funding": [ 56 | { 57 | "type": "github", 58 | "url": "https://github.com/sponsors/feross" 59 | }, 60 | { 61 | "type": "patreon", 62 | "url": "https://www.patreon.com/feross" 63 | }, 64 | { 65 | "type": "consulting", 66 | "url": "https://feross.org/support" 67 | } 68 | ] 69 | }, 70 | "node_modules/buffer": { 71 | "version": "4.9.2", 72 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", 73 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", 74 | "dependencies": { 75 | "base64-js": "^1.0.2", 76 | "ieee754": "^1.1.4", 77 | "isarray": "^1.0.0" 78 | } 79 | }, 80 | "node_modules/call-bind": { 81 | "version": "1.0.7", 82 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", 83 | "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", 84 | "dependencies": { 85 | "es-define-property": "^1.0.0", 86 | "es-errors": "^1.3.0", 87 | "function-bind": "^1.1.2", 88 | "get-intrinsic": "^1.2.4", 89 | "set-function-length": "^1.2.1" 90 | }, 91 | "engines": { 92 | "node": ">= 0.4" 93 | }, 94 | "funding": { 95 | "url": "https://github.com/sponsors/ljharb" 96 | } 97 | }, 98 | "node_modules/define-data-property": { 99 | "version": "1.1.4", 100 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", 101 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", 102 | "dependencies": { 103 | "es-define-property": "^1.0.0", 104 | "es-errors": "^1.3.0", 105 | "gopd": "^1.0.1" 106 | }, 107 | "engines": { 108 | "node": ">= 0.4" 109 | }, 110 | "funding": { 111 | "url": "https://github.com/sponsors/ljharb" 112 | } 113 | }, 114 | "node_modules/es-define-property": { 115 | "version": "1.0.0", 116 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", 117 | "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", 118 | "dependencies": { 119 | "get-intrinsic": "^1.2.4" 120 | }, 121 | "engines": { 122 | "node": ">= 0.4" 123 | } 124 | }, 125 | "node_modules/es-errors": { 126 | "version": "1.3.0", 127 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 128 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 129 | "engines": { 130 | "node": ">= 0.4" 131 | } 132 | }, 133 | "node_modules/events": { 134 | "version": "1.1.1", 135 | "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", 136 | "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", 137 | "engines": { 138 | "node": ">=0.4.x" 139 | } 140 | }, 141 | "node_modules/for-each": { 142 | "version": "0.3.3", 143 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", 144 | "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", 145 | "dependencies": { 146 | "is-callable": "^1.1.3" 147 | } 148 | }, 149 | "node_modules/function-bind": { 150 | "version": "1.1.2", 151 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 152 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 153 | "funding": { 154 | "url": "https://github.com/sponsors/ljharb" 155 | } 156 | }, 157 | "node_modules/get-intrinsic": { 158 | "version": "1.2.4", 159 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", 160 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", 161 | "dependencies": { 162 | "es-errors": "^1.3.0", 163 | "function-bind": "^1.1.2", 164 | "has-proto": "^1.0.1", 165 | "has-symbols": "^1.0.3", 166 | "hasown": "^2.0.0" 167 | }, 168 | "engines": { 169 | "node": ">= 0.4" 170 | }, 171 | "funding": { 172 | "url": "https://github.com/sponsors/ljharb" 173 | } 174 | }, 175 | "node_modules/gopd": { 176 | "version": "1.0.1", 177 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 178 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 179 | "dependencies": { 180 | "get-intrinsic": "^1.1.3" 181 | }, 182 | "funding": { 183 | "url": "https://github.com/sponsors/ljharb" 184 | } 185 | }, 186 | "node_modules/has-property-descriptors": { 187 | "version": "1.0.2", 188 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", 189 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", 190 | "dependencies": { 191 | "es-define-property": "^1.0.0" 192 | }, 193 | "funding": { 194 | "url": "https://github.com/sponsors/ljharb" 195 | } 196 | }, 197 | "node_modules/has-proto": { 198 | "version": "1.0.3", 199 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", 200 | "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", 201 | "engines": { 202 | "node": ">= 0.4" 203 | }, 204 | "funding": { 205 | "url": "https://github.com/sponsors/ljharb" 206 | } 207 | }, 208 | "node_modules/has-symbols": { 209 | "version": "1.0.3", 210 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 211 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 212 | "engines": { 213 | "node": ">= 0.4" 214 | }, 215 | "funding": { 216 | "url": "https://github.com/sponsors/ljharb" 217 | } 218 | }, 219 | "node_modules/has-tostringtag": { 220 | "version": "1.0.2", 221 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", 222 | "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", 223 | "dependencies": { 224 | "has-symbols": "^1.0.3" 225 | }, 226 | "engines": { 227 | "node": ">= 0.4" 228 | }, 229 | "funding": { 230 | "url": "https://github.com/sponsors/ljharb" 231 | } 232 | }, 233 | "node_modules/hasown": { 234 | "version": "2.0.2", 235 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 236 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 237 | "dependencies": { 238 | "function-bind": "^1.1.2" 239 | }, 240 | "engines": { 241 | "node": ">= 0.4" 242 | } 243 | }, 244 | "node_modules/ieee754": { 245 | "version": "1.1.13", 246 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", 247 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" 248 | }, 249 | "node_modules/inherits": { 250 | "version": "2.0.4", 251 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 252 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 253 | }, 254 | "node_modules/is-arguments": { 255 | "version": "1.1.1", 256 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", 257 | "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", 258 | "dependencies": { 259 | "call-bind": "^1.0.2", 260 | "has-tostringtag": "^1.0.0" 261 | }, 262 | "engines": { 263 | "node": ">= 0.4" 264 | }, 265 | "funding": { 266 | "url": "https://github.com/sponsors/ljharb" 267 | } 268 | }, 269 | "node_modules/is-callable": { 270 | "version": "1.2.7", 271 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", 272 | "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", 273 | "engines": { 274 | "node": ">= 0.4" 275 | }, 276 | "funding": { 277 | "url": "https://github.com/sponsors/ljharb" 278 | } 279 | }, 280 | "node_modules/is-generator-function": { 281 | "version": "1.0.10", 282 | "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", 283 | "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", 284 | "dependencies": { 285 | "has-tostringtag": "^1.0.0" 286 | }, 287 | "engines": { 288 | "node": ">= 0.4" 289 | }, 290 | "funding": { 291 | "url": "https://github.com/sponsors/ljharb" 292 | } 293 | }, 294 | "node_modules/is-sorted": { 295 | "version": "1.0.5", 296 | "resolved": "https://registry.npmjs.org/is-sorted/-/is-sorted-1.0.5.tgz", 297 | "integrity": "sha512-KZJvKDrI+Kg3ixeDaZQIt7RIwcGnm07+NSipyj1r9MtjDrLG678ETy4yO6dBJLUjejPdge9fLCGxsWkQO/3PJg==" 298 | }, 299 | "node_modules/is-typed-array": { 300 | "version": "1.1.13", 301 | "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", 302 | "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", 303 | "dependencies": { 304 | "which-typed-array": "^1.1.14" 305 | }, 306 | "engines": { 307 | "node": ">= 0.4" 308 | }, 309 | "funding": { 310 | "url": "https://github.com/sponsors/ljharb" 311 | } 312 | }, 313 | "node_modules/isarray": { 314 | "version": "1.0.0", 315 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 316 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" 317 | }, 318 | "node_modules/jmespath": { 319 | "version": "0.16.0", 320 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", 321 | "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", 322 | "engines": { 323 | "node": ">= 0.6.0" 324 | } 325 | }, 326 | "node_modules/possible-typed-array-names": { 327 | "version": "1.0.0", 328 | "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", 329 | "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", 330 | "engines": { 331 | "node": ">= 0.4" 332 | } 333 | }, 334 | "node_modules/punycode": { 335 | "version": "1.3.2", 336 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", 337 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" 338 | }, 339 | "node_modules/querystring": { 340 | "version": "0.2.0", 341 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", 342 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", 343 | "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", 344 | "engines": { 345 | "node": ">=0.4.x" 346 | } 347 | }, 348 | "node_modules/sax": { 349 | "version": "1.2.1", 350 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", 351 | "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" 352 | }, 353 | "node_modules/set-function-length": { 354 | "version": "1.2.2", 355 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", 356 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", 357 | "dependencies": { 358 | "define-data-property": "^1.1.4", 359 | "es-errors": "^1.3.0", 360 | "function-bind": "^1.1.2", 361 | "get-intrinsic": "^1.2.4", 362 | "gopd": "^1.0.1", 363 | "has-property-descriptors": "^1.0.2" 364 | }, 365 | "engines": { 366 | "node": ">= 0.4" 367 | } 368 | }, 369 | "node_modules/url": { 370 | "version": "0.10.3", 371 | "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", 372 | "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", 373 | "dependencies": { 374 | "punycode": "1.3.2", 375 | "querystring": "0.2.0" 376 | } 377 | }, 378 | "node_modules/util": { 379 | "version": "0.12.5", 380 | "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", 381 | "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", 382 | "dependencies": { 383 | "inherits": "^2.0.3", 384 | "is-arguments": "^1.0.4", 385 | "is-generator-function": "^1.0.7", 386 | "is-typed-array": "^1.1.3", 387 | "which-typed-array": "^1.1.2" 388 | } 389 | }, 390 | "node_modules/uuid": { 391 | "version": "8.0.0", 392 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", 393 | "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", 394 | "bin": { 395 | "uuid": "dist/bin/uuid" 396 | } 397 | }, 398 | "node_modules/which-typed-array": { 399 | "version": "1.1.15", 400 | "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", 401 | "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", 402 | "dependencies": { 403 | "available-typed-arrays": "^1.0.7", 404 | "call-bind": "^1.0.7", 405 | "for-each": "^0.3.3", 406 | "gopd": "^1.0.1", 407 | "has-tostringtag": "^1.0.2" 408 | }, 409 | "engines": { 410 | "node": ">= 0.4" 411 | }, 412 | "funding": { 413 | "url": "https://github.com/sponsors/ljharb" 414 | } 415 | }, 416 | "node_modules/xml2js": { 417 | "version": "0.6.2", 418 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", 419 | "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", 420 | "dependencies": { 421 | "sax": ">=0.6.0", 422 | "xmlbuilder": "~11.0.0" 423 | }, 424 | "engines": { 425 | "node": ">=4.0.0" 426 | } 427 | }, 428 | "node_modules/xmlbuilder": { 429 | "version": "11.0.1", 430 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", 431 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", 432 | "engines": { 433 | "node": ">=4.0" 434 | } 435 | } 436 | } 437 | } 438 | -------------------------------------------------------------------------------- /tests/force-exclude/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "force-exclude", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "aws-sdk": "^2.1502.0", 14 | "is-sorted": "^1.0.5" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/force-exclude/serverless.node18.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | forceExclude: 9 | - "is-sorted" 10 | 11 | provider: 12 | name: aws 13 | runtime: nodejs18.x 14 | 15 | functions: 16 | hello: 17 | handler: handler.hello 18 | -------------------------------------------------------------------------------- /tests/force-exclude/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | forceExclude: 9 | - "is-sorted" 10 | 11 | provider: 12 | name: aws 13 | runtime: nodejs20.x 14 | 15 | functions: 16 | hello: 17 | handler: handler.hello 18 | -------------------------------------------------------------------------------- /tests/generate-stats-files/generate-stats-file.test.js: -------------------------------------------------------------------------------- 1 | const { existsSync } = require("fs"); 2 | const path = require("path"); 3 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 4 | 5 | beforeEach(async () => { 6 | await clearNpmCache(__dirname); 7 | }); 8 | 9 | afterAll(async () => { 10 | await clearNpmCache(__dirname); 11 | }); 12 | 13 | test("generate-stats-files", async () => { 14 | const result = await runSlsCommand(__dirname); 15 | const statsFilePath = path.join( 16 | __dirname, 17 | ".webpack", 18 | "service", 19 | "bundle_stats.json" 20 | ); 21 | 22 | const htmlStatsFilePath = path.join( 23 | __dirname, 24 | ".webpack", 25 | "service", 26 | "bundle_stats.html" 27 | ); 28 | 29 | expect(result).not.toMatch(errorRegex); 30 | 31 | // Check if stats files have been generated 32 | expect(existsSync(statsFilePath)).toBe(true); 33 | expect(existsSync(htmlStatsFilePath)).toBe(true); 34 | }); 35 | -------------------------------------------------------------------------------- /tests/generate-stats-files/handler.js: -------------------------------------------------------------------------------- 1 | export const hello = async (event) => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: `Go Serverless v1.0! Your function executed successfully!`, 6 | input: event, 7 | }), 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/generate-stats-files/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generate-stats-files", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "generate-stats-files", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/generate-stats-files/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generate-stats-files", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/generate-stats-files/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | generateStatsFiles: true 9 | 10 | provider: 11 | name: aws 12 | runtime: nodejs20.x 13 | 14 | functions: 15 | hello: 16 | handler: handler.hello 17 | -------------------------------------------------------------------------------- /tests/helpers/clear-npm-cache.js: -------------------------------------------------------------------------------- 1 | const { promisify } = require("util"); 2 | const { exec } = require("child_process"); 3 | 4 | const execPromise = promisify(exec); 5 | const TIMEOUT = 30000; 6 | 7 | async function clearNpmCache(cwd) { 8 | await execPromise("rm -rf node_modules/.cache/", { 9 | cwd, 10 | TIMEOUT 11 | }); 12 | } 13 | 14 | module.exports = clearNpmCache; 15 | -------------------------------------------------------------------------------- /tests/helpers/index.js: -------------------------------------------------------------------------------- 1 | const npmInstall = require("./npm-install"); 2 | const clearNpmCache = require("./clear-npm-cache"); 3 | const runSlsCommand = require("./run-sls-command"); 4 | const runJestCommand = require("./run-jest-command"); 5 | const removeNodeModules = require("./remove-node-modules"); 6 | 7 | const errorRegex = /(Error|Exception) ---/; 8 | 9 | module.exports = { 10 | npmInstall, 11 | errorRegex, 12 | clearNpmCache, 13 | runSlsCommand, 14 | runJestCommand, 15 | removeNodeModules 16 | }; 17 | -------------------------------------------------------------------------------- /tests/helpers/npm-install.js: -------------------------------------------------------------------------------- 1 | const { promisify } = require("util"); 2 | const { exec } = require("child_process"); 3 | const { exists } = require("fs"); 4 | const removeNodeModules = require("./remove-node-modules"); 5 | 6 | const execPromise = promisify(exec); 7 | const existsPromise = promisify(exists); 8 | const TIMEOUT = 30000; 9 | 10 | async function npmInstall(cwd) { 11 | const hasPackageJson = await existsPromise(`${cwd}/package.json`); 12 | 13 | if (hasPackageJson) { 14 | await removeNodeModules(cwd); 15 | 16 | await execPromise("npm install", { 17 | cwd, 18 | TIMEOUT 19 | }); 20 | } 21 | } 22 | 23 | module.exports = npmInstall; 24 | -------------------------------------------------------------------------------- /tests/helpers/remove-node-modules.js: -------------------------------------------------------------------------------- 1 | const { promisify } = require("util"); 2 | const { exec } = require("child_process"); 3 | 4 | const execPromise = promisify(exec); 5 | const TIMEOUT = 30000; 6 | 7 | async function removeNodeModules(cwd) { 8 | await execPromise("rm -rf node_modules/", { 9 | cwd, 10 | TIMEOUT 11 | }); 12 | } 13 | 14 | module.exports = removeNodeModules; 15 | -------------------------------------------------------------------------------- /tests/helpers/run-jest-command.js: -------------------------------------------------------------------------------- 1 | const { promisify } = require("util"); 2 | const { exec } = require("child_process"); 3 | const npmInstall = require("./npm-install"); 4 | 5 | const execPromise = promisify(exec); 6 | const TIMEOUT = 30000; 7 | 8 | async function runJestCommand(cwd) { 9 | await npmInstall(cwd); 10 | 11 | const { stdout } = await execPromise("npm test", { 12 | cwd, 13 | TIMEOUT 14 | }); 15 | 16 | return stdout.toString("utf8"); 17 | } 18 | 19 | module.exports = runJestCommand; 20 | -------------------------------------------------------------------------------- /tests/helpers/run-sls-command.js: -------------------------------------------------------------------------------- 1 | const { promisify } = require("util"); 2 | const { exec } = require("child_process"); 3 | const npmInstall = require("./npm-install"); 4 | 5 | const execPromise = promisify(exec); 6 | const TIMEOUT = 30000; 7 | const INVOKE_CMD = "invoke local -f hello --data {}"; 8 | 9 | async function runSlsCommand(cwd, cmd = INVOKE_CMD, includeStderr = false) { 10 | await npmInstall(cwd); 11 | 12 | const { stdout, stderr } = await execPromise(`serverless ${cmd}`, { 13 | cwd, 14 | TIMEOUT, 15 | }); 16 | 17 | return includeStderr 18 | ? stdout.toString("utf8") + stderr.toString("utf8") 19 | : stdout.toString("utf8"); 20 | } 21 | 22 | module.exports = runSlsCommand; 23 | -------------------------------------------------------------------------------- /tests/helpers/setup-tests.js: -------------------------------------------------------------------------------- 1 | /* 2 | The default timeout is 5000ms on async tests. 3 | Because we npm install and remove directories, tests can take time to run. 4 | Setting to 1.5 minutes to support slow machines. 5 | */ 6 | jest.setTimeout(90000); 7 | -------------------------------------------------------------------------------- /tests/ignore-packages/handler.js: -------------------------------------------------------------------------------- 1 | import redis from "redis"; // eslint-disable-line no-unused-vars 2 | 3 | export const hello = async (event, context) => { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify({ 7 | message: "Go Serverless v1.0! Your function executed successfully!", 8 | input: event 9 | }) 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /tests/ignore-packages/ignore-packages.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("ignore-packages", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/ignore-packages/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ignore-packages", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "ignore-packages", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "redis": "^2.8.0" 13 | } 14 | }, 15 | "node_modules/double-ended-queue": { 16 | "version": "2.1.0-0", 17 | "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", 18 | "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" 19 | }, 20 | "node_modules/redis": { 21 | "version": "2.8.0", 22 | "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", 23 | "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", 24 | "dependencies": { 25 | "double-ended-queue": "^2.1.0-0", 26 | "redis-commands": "^1.2.0", 27 | "redis-parser": "^2.6.0" 28 | }, 29 | "engines": { 30 | "node": ">=0.10.0" 31 | } 32 | }, 33 | "node_modules/redis-commands": { 34 | "version": "1.5.0", 35 | "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.5.0.tgz", 36 | "integrity": "sha512-6KxamqpZ468MeQC3bkWmCB1fp56XL64D4Kf0zJSwDZbVLLm7KFkoIcHrgRvQ+sk8dnhySs7+yBg94yIkAK7aJg==" 37 | }, 38 | "node_modules/redis-parser": { 39 | "version": "2.6.0", 40 | "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", 41 | "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=", 42 | "engines": { 43 | "node": ">=0.10.0" 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/ignore-packages/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ignore-packages", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "redis": "^2.8.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/ignore-packages/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | ignorePackages: 9 | - hiredis 10 | 11 | provider: 12 | name: aws 13 | runtime: nodejs20.x 14 | 15 | functions: 16 | hello: 17 | handler: handler.hello 18 | -------------------------------------------------------------------------------- /tests/invalid-runtime/handler.js: -------------------------------------------------------------------------------- 1 | export const hello = async (event, context) => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: "Go Serverless v1.0! Your function executed successfully!", 6 | input: event 7 | }) 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/invalid-runtime/invalid-runtime.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("invalid runtime", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/invalid-runtime/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | 9 | functions: 10 | hello: 11 | handler: handler.hello 12 | -------------------------------------------------------------------------------- /tests/isomorphic-loaders/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/isomorphic-loaders/assets/react.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnomalyInnovations/serverless-bundle/b8c074a23e6465484b3d5cde6c81cb3e39b9cf46/tests/isomorphic-loaders/assets/react.png -------------------------------------------------------------------------------- /tests/isomorphic-loaders/assets/style.css: -------------------------------------------------------------------------------- 1 | html { 2 | background-color: blue; 3 | } 4 | -------------------------------------------------------------------------------- /tests/isomorphic-loaders/assets/style.scss: -------------------------------------------------------------------------------- 1 | html { 2 | color: red; 3 | } 4 | -------------------------------------------------------------------------------- /tests/isomorphic-loaders/handler.js: -------------------------------------------------------------------------------- 1 | import "./assets/style.css"; 2 | import "./assets/style.scss"; 3 | import "./assets/react.png"; 4 | 5 | export const hello = async (event, context) => { 6 | return { 7 | statusCode: 200, 8 | body: JSON.stringify({ 9 | message: "Go Serverless v1.0! Your function executed successfully!", 10 | input: event 11 | }) 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /tests/isomorphic-loaders/isomorphic-loaders.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("isomorphic loaders", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/isomorphic-loaders/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "isomorphic-loader", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "isomorphic-loader", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/isomorphic-loaders/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "isomorphic-loader", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/isomorphic-loaders/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/load-gql-files/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless 7 | .webpack -------------------------------------------------------------------------------- /tests/load-gql-files/load-gql-files.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("load-gql-files", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/load-gql-files/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "load-gql-files", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "start": "serverless offline start" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "apollo-server-lambda": "^2.10.1" 14 | }, 15 | "devDependencies": {} 16 | } 17 | -------------------------------------------------------------------------------- /tests/load-gql-files/serverless.yml: -------------------------------------------------------------------------------- 1 | service: load-gql-files 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: src/handler.graphqlHandler 13 | events: 14 | - http: 15 | path: graphql 16 | method: post 17 | cors: true 18 | - http: 19 | path: graphql 20 | method: get 21 | -------------------------------------------------------------------------------- /tests/load-gql-files/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.gql' { 2 | import { DocumentNode } from 'graphql'; 3 | 4 | const value: DocumentNode; 5 | export = value; 6 | } -------------------------------------------------------------------------------- /tests/load-gql-files/src/handler.ts: -------------------------------------------------------------------------------- 1 | import { ApolloServer } from 'apollo-server-lambda' 2 | import schema from './schema' 3 | import resolvers from './resolvers' 4 | 5 | const server = new ApolloServer({ 6 | typeDefs: schema, 7 | resolvers: resolvers, 8 | 9 | // By default, the GraphQL Playground interface and GraphQL introspection 10 | // is disabled in "production" (i.e. when `process.env.NODE_ENV` is `production`). 11 | // 12 | // If you'd like to have GraphQL Playground and introspection enabled in production, 13 | // the `playground` and `introspection` options must be set explicitly to `true`. 14 | playground: true, 15 | introspection: true 16 | }) 17 | 18 | export const graphqlHandler = server.createHandler({ 19 | cors: { 20 | origin: '*' 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /tests/load-gql-files/src/resolvers/ExampleResolver.ts: -------------------------------------------------------------------------------- 1 | export const exampleResolver = { 2 | Query: { 3 | examples: (parent, params, context) => [ 4 | { 5 | id: '1', 6 | name: 'This a test example' 7 | }, 8 | { 9 | id: '2', 10 | name: 'This another test example' 11 | } 12 | ], 13 | 14 | getExample: (parent, params, context) => ({ 15 | id: '1', 16 | name: 'This a test example' 17 | }) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/load-gql-files/src/resolvers/index.ts: -------------------------------------------------------------------------------- 1 | import { exampleResolver } from './ExampleResolver' 2 | 3 | export default [exampleResolver] 4 | -------------------------------------------------------------------------------- /tests/load-gql-files/src/schema/exampleSchema.gql: -------------------------------------------------------------------------------- 1 | extend type Query { 2 | examples: [Example!]! 3 | getExample(id: ID!): Example! 4 | } 5 | 6 | type Example { 7 | id: ID 8 | name: String 9 | } 10 | -------------------------------------------------------------------------------- /tests/load-gql-files/src/schema/index.ts: -------------------------------------------------------------------------------- 1 | import * as linkSchema from "./linkSchema.gql"; 2 | 3 | import * as exampleSchema from "./exampleSchema.gql"; 4 | 5 | export default [linkSchema, exampleSchema]; 6 | -------------------------------------------------------------------------------- /tests/load-gql-files/src/schema/linkSchema.gql: -------------------------------------------------------------------------------- 1 | type Query { 2 | _: Boolean 3 | } 4 | 5 | type Mutation { 6 | _: Boolean 7 | } 8 | 9 | type Subscription { 10 | _: Boolean 11 | } 12 | -------------------------------------------------------------------------------- /tests/minify-options/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/minify-options/handler.js: -------------------------------------------------------------------------------- 1 | function namedFunction() { 2 | return null; 3 | } 4 | 5 | class NamedClass {} 6 | 7 | export const hello = async () => { 8 | return { 9 | statusCode: 200, 10 | body: JSON.stringify({ 11 | functionName: namedFunction.name, 12 | className: NamedClass.name, 13 | }), 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /tests/minify-options/minify-options.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("minify-options", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/minify-options/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esbuild", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "esbuild", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "esbuild-loader": "^2.9.2", 13 | "reflect-metadata": "^0.1.13" 14 | } 15 | }, 16 | "node_modules/big.js": { 17 | "version": "5.2.2", 18 | "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", 19 | "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", 20 | "dev": true, 21 | "engines": { 22 | "node": "*" 23 | } 24 | }, 25 | "node_modules/emojis-list": { 26 | "version": "3.0.0", 27 | "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", 28 | "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", 29 | "dev": true, 30 | "engines": { 31 | "node": ">= 4" 32 | } 33 | }, 34 | "node_modules/esbuild": { 35 | "version": "0.8.55", 36 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.8.55.tgz", 37 | "integrity": "sha512-mM/s7hjYe5mQR+zAWOM5JVrCtYCke182E9l1Bbs6rG5EDP3b1gZF9sHZka53PD/iNt6OccymVZRWkTtBfcKW4w==", 38 | "dev": true, 39 | "hasInstallScript": true, 40 | "bin": { 41 | "esbuild": "bin/esbuild" 42 | } 43 | }, 44 | "node_modules/esbuild-loader": { 45 | "version": "2.9.2", 46 | "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.9.2.tgz", 47 | "integrity": "sha512-HpF+r/ES2aC40VDOIFsP8OIOM2y2vj8LyLwJ4G8DCMOi8Kov68TwCtxiMMTuSuxR/xKDu/ykgVyCEgps6BXpYw==", 48 | "dev": true, 49 | "dependencies": { 50 | "esbuild": "^0.8.42", 51 | "joycon": "^2.2.5", 52 | "json5": "^2.2.0", 53 | "loader-utils": "^2.0.0", 54 | "type-fest": "^0.20.2", 55 | "webpack-sources": "^2.2.0" 56 | } 57 | }, 58 | "node_modules/joycon": { 59 | "version": "2.2.5", 60 | "resolved": "https://registry.npmjs.org/joycon/-/joycon-2.2.5.tgz", 61 | "integrity": "sha512-YqvUxoOcVPnCp0VU1/56f+iKSdvIRJYPznH22BdXV3xMk75SFXhWeJkZ8C9XxUWt1b5x2X1SxuFygW1U0FmkEQ==", 62 | "dev": true, 63 | "engines": { 64 | "node": ">=6" 65 | } 66 | }, 67 | "node_modules/json5": { 68 | "version": "2.2.0", 69 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", 70 | "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", 71 | "dev": true, 72 | "dependencies": { 73 | "minimist": "^1.2.5" 74 | }, 75 | "bin": { 76 | "json5": "lib/cli.js" 77 | }, 78 | "engines": { 79 | "node": ">=6" 80 | } 81 | }, 82 | "node_modules/loader-utils": { 83 | "version": "2.0.0", 84 | "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", 85 | "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", 86 | "dev": true, 87 | "dependencies": { 88 | "big.js": "^5.2.2", 89 | "emojis-list": "^3.0.0", 90 | "json5": "^2.1.2" 91 | }, 92 | "engines": { 93 | "node": ">=8.9.0" 94 | } 95 | }, 96 | "node_modules/minimist": { 97 | "version": "1.2.5", 98 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 99 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 100 | "dev": true 101 | }, 102 | "node_modules/reflect-metadata": { 103 | "version": "0.1.13", 104 | "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", 105 | "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", 106 | "dev": true 107 | }, 108 | "node_modules/source-list-map": { 109 | "version": "2.0.1", 110 | "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", 111 | "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", 112 | "dev": true 113 | }, 114 | "node_modules/source-map": { 115 | "version": "0.6.1", 116 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 117 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 118 | "dev": true, 119 | "engines": { 120 | "node": ">=0.10.0" 121 | } 122 | }, 123 | "node_modules/type-fest": { 124 | "version": "0.20.2", 125 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 126 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 127 | "dev": true, 128 | "engines": { 129 | "node": ">=10" 130 | } 131 | }, 132 | "node_modules/webpack-sources": { 133 | "version": "2.2.0", 134 | "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", 135 | "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", 136 | "dev": true, 137 | "dependencies": { 138 | "source-list-map": "^2.0.1", 139 | "source-map": "^0.6.1" 140 | }, 141 | "engines": { 142 | "node": ">=10.13.0" 143 | } 144 | } 145 | }, 146 | "dependencies": { 147 | "big.js": { 148 | "version": "5.2.2", 149 | "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", 150 | "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", 151 | "dev": true 152 | }, 153 | "emojis-list": { 154 | "version": "3.0.0", 155 | "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", 156 | "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", 157 | "dev": true 158 | }, 159 | "esbuild": { 160 | "version": "0.8.55", 161 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.8.55.tgz", 162 | "integrity": "sha512-mM/s7hjYe5mQR+zAWOM5JVrCtYCke182E9l1Bbs6rG5EDP3b1gZF9sHZka53PD/iNt6OccymVZRWkTtBfcKW4w==", 163 | "dev": true 164 | }, 165 | "esbuild-loader": { 166 | "version": "2.9.2", 167 | "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.9.2.tgz", 168 | "integrity": "sha512-HpF+r/ES2aC40VDOIFsP8OIOM2y2vj8LyLwJ4G8DCMOi8Kov68TwCtxiMMTuSuxR/xKDu/ykgVyCEgps6BXpYw==", 169 | "dev": true, 170 | "requires": { 171 | "esbuild": "^0.8.42", 172 | "joycon": "^2.2.5", 173 | "json5": "^2.2.0", 174 | "loader-utils": "^2.0.0", 175 | "type-fest": "^0.20.2", 176 | "webpack-sources": "^2.2.0" 177 | } 178 | }, 179 | "joycon": { 180 | "version": "2.2.5", 181 | "resolved": "https://registry.npmjs.org/joycon/-/joycon-2.2.5.tgz", 182 | "integrity": "sha512-YqvUxoOcVPnCp0VU1/56f+iKSdvIRJYPznH22BdXV3xMk75SFXhWeJkZ8C9XxUWt1b5x2X1SxuFygW1U0FmkEQ==", 183 | "dev": true 184 | }, 185 | "json5": { 186 | "version": "2.2.0", 187 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", 188 | "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", 189 | "dev": true, 190 | "requires": { 191 | "minimist": "^1.2.5" 192 | } 193 | }, 194 | "loader-utils": { 195 | "version": "2.0.0", 196 | "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", 197 | "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", 198 | "dev": true, 199 | "requires": { 200 | "big.js": "^5.2.2", 201 | "emojis-list": "^3.0.0", 202 | "json5": "^2.1.2" 203 | } 204 | }, 205 | "minimist": { 206 | "version": "1.2.5", 207 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 208 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 209 | "dev": true 210 | }, 211 | "reflect-metadata": { 212 | "version": "0.1.13", 213 | "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", 214 | "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", 215 | "dev": true 216 | }, 217 | "source-list-map": { 218 | "version": "2.0.1", 219 | "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", 220 | "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", 221 | "dev": true 222 | }, 223 | "source-map": { 224 | "version": "0.6.1", 225 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 226 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 227 | "dev": true 228 | }, 229 | "type-fest": { 230 | "version": "0.20.2", 231 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 232 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 233 | "dev": true 234 | }, 235 | "webpack-sources": { 236 | "version": "2.2.0", 237 | "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", 238 | "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", 239 | "dev": true, 240 | "requires": { 241 | "source-list-map": "^2.0.1", 242 | "source-map": "^0.6.1" 243 | } 244 | } 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /tests/minify-options/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esbuild", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "esbuild-loader": "^2.9.2", 14 | "reflect-metadata": "^0.1.13" 15 | }, 16 | "dependencies": {} 17 | } 18 | -------------------------------------------------------------------------------- /tests/minify-options/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | minifyOptions: 9 | keepNames: true 10 | 11 | provider: 12 | name: aws 13 | runtime: nodejs20.x 14 | 15 | functions: 16 | hello: 17 | handler: handler.hello 18 | -------------------------------------------------------------------------------- /tests/nested-lambda/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/nested-lambda/nested-lambda.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("nested-lambda", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/nested-lambda/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nested-lambda", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "nested-lambda", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/nested-lambda/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nested-lambda", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/nested-lambda/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: services/main/handler.hello 13 | -------------------------------------------------------------------------------- /tests/nested-lambda/services/main/handler.js: -------------------------------------------------------------------------------- 1 | export const hello = async (event, context) => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: 'Go Serverless v1.0! Your function executed successfully!', 6 | input: event, 7 | }), 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/nested-services/nested-services.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("nested services", async () => { 12 | const pathToNestedService = `${__dirname}/services/service1`; 13 | 14 | const result = await runSlsCommand(pathToNestedService, "package"); 15 | 16 | expect(result).not.toMatch(errorRegex); 17 | }); 18 | -------------------------------------------------------------------------------- /tests/nested-services/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nested-services", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/nested-services/services/service1/handler.js: -------------------------------------------------------------------------------- 1 | export const hello = async (event, context) => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: "Go Serverless v1.0! Your function executed successfully!", 6 | input: event 7 | }) 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/nested-services/services/service1/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/node-env/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/node-env/handler.js: -------------------------------------------------------------------------------- 1 | export const hello = async (event) => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: "NODE_ENV=" + process.env.NODE_ENV, 6 | input: event, 7 | }), 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/node-env/node-env.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("node-env - production", async () => { 12 | const cmd = "invoke local -f hello --data {} --env NODE_ENV=production"; 13 | const result = await runSlsCommand(__dirname, cmd); 14 | 15 | expect(result).toContain("NODE_ENV=production"); 16 | }); 17 | 18 | test("node-env - development", async () => { 19 | const cmd = "invoke local -f hello --data {} --env NODE_ENV=development"; 20 | const result = await runSlsCommand(__dirname, cmd); 21 | 22 | expect(result).toContain("NODE_ENV=development"); 23 | }); 24 | -------------------------------------------------------------------------------- /tests/node-env/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-env", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "node-env", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/node-env/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-env", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/node-env/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/nullish-coalescing/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/nullish-coalescing/handler.js: -------------------------------------------------------------------------------- 1 | class TestClass { 2 | attribute1; 3 | 4 | constructor(data) { 5 | this.attribute1 = data.attribute1 ?? "default"; 6 | this.attribute2 = data.attribute2 ?? "default"; 7 | } 8 | } 9 | 10 | export const hello = async (event, context) => { 11 | const a = new TestClass({ attribute1: "test" }); 12 | 13 | console.log(a); // eslint-disable-line 14 | 15 | return { 16 | statusCode: 200, 17 | body: JSON.stringify({ 18 | message: "Go Serverless v1.0! Your function executed successfully!", 19 | input: event 20 | }) 21 | }; 22 | }; 23 | -------------------------------------------------------------------------------- /tests/nullish-coalescing/nullish-coalescing.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("nullish-coalescing", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/nullish-coalescing/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nullish-coalescing", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "nullish-coalescing", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/nullish-coalescing/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nullish-coalescing", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/nullish-coalescing/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/optional-chaining/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/optional-chaining/handler.js: -------------------------------------------------------------------------------- 1 | class TestClass { 2 | attribute1; 3 | 4 | constructor(data) { 5 | this.attribute1 = data?.attribute1; 6 | this.attribute2 = data?.attribute2; 7 | } 8 | } 9 | 10 | export const hello = async (event, context) => { 11 | const a = new TestClass({ attribute1: "test" }); 12 | 13 | console.log(a); // eslint-disable-line 14 | 15 | return { 16 | statusCode: 200, 17 | body: JSON.stringify({ 18 | message: "Go Serverless v1.0! Your function executed successfully!", 19 | input: event 20 | }) 21 | }; 22 | }; 23 | -------------------------------------------------------------------------------- /tests/optional-chaining/optional-chaining.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("optional-chaining", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/optional-chaining/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "optional-chaining", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "optional-chaining", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/optional-chaining/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "optional-chaining", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/optional-chaining/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/override-eslint/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-unused-vars": "off" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/override-eslint/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/override-eslint/handler.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | 3 | export const hello = async (event, context) => { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify({ 7 | message: 'Go Serverless v1.0! Your function executed successfully!', 8 | input: event, 9 | }), 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /tests/override-eslint/override-eslint.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("override-eslint", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/override-eslint/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "override-eslint", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "override-eslint", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/override-eslint/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "override-eslint", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/override-eslint/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/raw-loader/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless 7 | -------------------------------------------------------------------------------- /tests/raw-loader/assets/csv.csv: -------------------------------------------------------------------------------- 1 | John,Doe,120 jefferson st.,Riverside, NJ, 08075 2 | Jack,McGinnis,220 hobo Av.,Phila, PA,09119 3 | "John ""Da Man""",Repici,120 Jefferson St.,Riverside, NJ,08075 4 | Stephen,Tyler,"7452 Terrace ""At the Plaza"" road",SomeTown,SD, 91234 5 | ,Blankman,,SomeTown, SD, 00298 6 | "Joan ""the bone"", Anne",Jet,"9th, at Terrace plc",Desert City,CO,00123 7 | -------------------------------------------------------------------------------- /tests/raw-loader/assets/pem.pem: -------------------------------------------------------------------------------- 1 | Raw loader file 2 | -------------------------------------------------------------------------------- /tests/raw-loader/assets/text.txt: -------------------------------------------------------------------------------- 1 | Raw loader file 2 | -------------------------------------------------------------------------------- /tests/raw-loader/handler.js: -------------------------------------------------------------------------------- 1 | import "./assets/text.txt"; 2 | import "./assets/pem.pem"; 3 | 4 | export const hello = async event => { 5 | return { 6 | statusCode: 200, 7 | body: JSON.stringify({ 8 | message: "Go Serverless v1.0! Your function executed successfully!", 9 | input: event 10 | }) 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /tests/raw-loader/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "raw-loader", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "raw-loader", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/raw-loader/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "raw-loader", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/raw-loader/raw-loader.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("raw loader", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/raw-loader/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - "../../index" 5 | 6 | custom: 7 | bundle: 8 | rawFileExtensions: 9 | - csv 10 | 11 | provider: 12 | name: aws 13 | runtime: nodejs20.x 14 | 15 | functions: 16 | hello: 17 | handler: handler.hello 18 | -------------------------------------------------------------------------------- /tests/scripts/.env: -------------------------------------------------------------------------------- 1 | # We need to commit this file for the test 2 | TEST_VALUE=123 3 | -------------------------------------------------------------------------------- /tests/scripts/asyncSum.js: -------------------------------------------------------------------------------- 1 | export default (a, b) => new Promise(resolve => resolve(a + b)); 2 | -------------------------------------------------------------------------------- /tests/scripts/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jest", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "jest", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jest", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "../../bin/scripts.js test --testPathIgnorePatterns=\"./scripts.test.js\"" 8 | }, 9 | "jest": { 10 | "setupFilesAfterEnv": [ 11 | "/setup-tests.js" 12 | ] 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC" 17 | } 18 | -------------------------------------------------------------------------------- /tests/scripts/scripts.test.js: -------------------------------------------------------------------------------- 1 | const { runJestCommand, clearNpmCache } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("scripts", async () => { 12 | const result = await runJestCommand(__dirname); 13 | 14 | // Test Jest config in package.json is working 15 | expect(result).toContain("Running 'setupFilesAfterEnv'"); 16 | // Ensure Jest ran the included tests successfully 17 | expect(result).not.toMatch(/failed/); 18 | }); 19 | -------------------------------------------------------------------------------- /tests/scripts/setup-tests.js: -------------------------------------------------------------------------------- 1 | console.log("Running 'setupFilesAfterEnv'"); // eslint-disable-line 2 | -------------------------------------------------------------------------------- /tests/scripts/tests/index.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Test to make sure overriding Jest config works. 3 | * ./setupTests.js is set as `setupFilesAfterEnv` in 4 | * the package.json. It should be included before a 5 | * test is run. 6 | */ 7 | import asyncSum from "../asyncSum"; 8 | 9 | it("dotenv set", () => { 10 | expect(process.env.TEST_VALUE).toEqual("123"); 11 | }); 12 | 13 | it("sums numbers", async () => { 14 | const results = await asyncSum(1, 2); 15 | expect(results).toEqual(3); 16 | }); 17 | -------------------------------------------------------------------------------- /tests/typescript-config-path/handler.ts: -------------------------------------------------------------------------------- 1 | export const hello = async (event: any) => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: "Go Serverless v1.0! Your function executed successfully!", 6 | input: event, 7 | }), 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/typescript-config-path/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-config-path", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "typescript-config-path", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/typescript-config-path/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-config-path", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/typescript-config-path/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | tsConfig: 'tsconfig.special.json' 9 | 10 | provider: 11 | name: aws 12 | runtime: nodejs20.x 13 | 14 | functions: 15 | hello: 16 | handler: handler.hello 17 | -------------------------------------------------------------------------------- /tests/typescript-config-path/tsconfig.special.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "moduleResolution": "node", 5 | "baseUrl": "." 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/typescript-config-path/typescript-config-path.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("typescript-config-path", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/typescript-esbuild/custom-lib/src/some-lib/index.ts: -------------------------------------------------------------------------------- 1 | export function hi(name: string) { 2 | return `Imported successfully ${name}.`; 3 | } 4 | -------------------------------------------------------------------------------- /tests/typescript-esbuild/decorated-class.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-unused-vars 2 | function classDecorator( 3 | constructor: T 4 | ) { 5 | return class extends constructor { 6 | newProperty = "new property"; 7 | hello = "override"; 8 | }; 9 | } 10 | 11 | const myDecorator = (target: any, propertyKey: string, descriptor: PropertyDescriptor) => { 12 | console.log('decorator', descriptor); 13 | } 14 | 15 | @classDecorator 16 | export class Greeter { 17 | property = "property"; 18 | hello: string; 19 | constructor(m: string) { 20 | this.hello = m; 21 | } 22 | } 23 | 24 | @classDecorator 25 | export class Rocket { 26 | @myDecorator 27 | launch() { 28 | return true 29 | } 30 | } -------------------------------------------------------------------------------- /tests/typescript-esbuild/handler.ts: -------------------------------------------------------------------------------- 1 | import { hi } from "@my-org/some-lib/index"; 2 | import { merhaba } from "./tsx/import"; 3 | import { Greeter, Rocket } from './decorated-class' 4 | 5 | export const hello = async (event: any) => { 6 | new Greeter("world"); 7 | new Rocket().launch(); 8 | 9 | return { 10 | statusCode: 200, 11 | body: JSON.stringify({ 12 | message: `Go Serverless v1.0! ${hi("Sandy")} ${merhaba( 13 | "Andy" 14 | )} Your function executed successfully!`, 15 | input: event, 16 | }), 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /tests/typescript-esbuild/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-esbuild", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "typescript-esbuild", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/typescript-esbuild/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-esbuild", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/typescript-esbuild/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | linting: false 9 | stats: true 10 | disableForkTsChecker: true 11 | esbuild: true 12 | 13 | provider: 14 | name: aws 15 | runtime: nodejs20.x 16 | 17 | functions: 18 | hello: 19 | handler: handler.hello 20 | -------------------------------------------------------------------------------- /tests/typescript-esbuild/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "experimentalDecorators": true, 4 | "skipLibCheck": true, 5 | "target": "es6", 6 | "moduleResolution": "node", 7 | "emitDecoratorMetadata": true, 8 | "baseUrl": ".", 9 | "jsx": "preserve", 10 | "paths": { 11 | "@my-org/some-lib/*": ["custom-lib/src/some-lib/*"] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/typescript-esbuild/tsx/import.tsx: -------------------------------------------------------------------------------- 1 | export function merhaba(name: string) { 2 | return `Merhaba, ${name}`; 3 | } 4 | -------------------------------------------------------------------------------- /tests/typescript-esbuild/typescript-esbuild.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("typescript-esbuild", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).toContain("Imported successfully"); 15 | expect(result).toContain("Merhaba"); 16 | }); 17 | -------------------------------------------------------------------------------- /tests/typescript-exclude-files/handler.spec.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnomalyInnovations/serverless-bundle/b8c074a23e6465484b3d5cde6c81cb3e39b9cf46/tests/typescript-exclude-files/handler.spec.ts -------------------------------------------------------------------------------- /tests/typescript-exclude-files/handler.ts: -------------------------------------------------------------------------------- 1 | export const hello = async (event: any) => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: "Go Serverless v1.0! Your function executed successfully!", 6 | input: event, 7 | }), 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/typescript-exclude-files/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-exclude-files", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "typescript-exclude-files", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/typescript-exclude-files/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-exclude-files", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/typescript-exclude-files/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | excludeFiles: '*.spec.ts' 9 | 10 | provider: 11 | name: aws 12 | runtime: nodejs20.x 13 | 14 | functions: 15 | hello: 16 | handler: handler.hello 17 | -------------------------------------------------------------------------------- /tests/typescript-exclude-files/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "moduleResolution": "node", 5 | "baseUrl": "." 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/typescript-exclude-files/typescript-exclude-files.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("typescript-exclude-files", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch( 15 | "WARNING: More than one matching handlers found for 'handler'. Using 'handler.ts'." 16 | ); 17 | expect(result).not.toMatch(errorRegex); 18 | }); 19 | -------------------------------------------------------------------------------- /tests/typescript-forkts-disabled/handler.ts: -------------------------------------------------------------------------------- 1 | export const hello = async (event: any) => { 2 | const a = 1; 3 | return { 4 | statusCode: 200, 5 | body: JSON.stringify({ 6 | message: `Go Serverless v1.0! Your function executed successfully!`, 7 | input: event, 8 | }), 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /tests/typescript-forkts-disabled/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-forkts-disabled", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "typescript-forkts-disabled", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/typescript-forkts-disabled/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-forkts-disabled", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/typescript-forkts-disabled/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | bundle: 8 | disableForkTsChecker: true 9 | 10 | provider: 11 | name: aws 12 | runtime: nodejs20.x 13 | 14 | functions: 15 | hello: 16 | handler: handler.hello 17 | -------------------------------------------------------------------------------- /tests/typescript-forkts-disabled/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "moduleResolution": "node", 5 | "baseUrl": "." 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/typescript-forkts-disabled/typescript-forkts-disabled.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | // Test that we are running eslint even though ForkTsCheckerWebpackPlugin is disabled 12 | // Similar to the failed-eslint test 13 | test("typescript-forkts-disabled", async () => { 14 | expect.assertions(1); 15 | 16 | const eslintErrorString = "no-unused-vars"; 17 | 18 | try { 19 | await runSlsCommand(__dirname); 20 | } catch (err) { 21 | expect(err.stdout).toContain(eslintErrorString); 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /tests/typescript-invalid-module/handler.ts: -------------------------------------------------------------------------------- 1 | export const hello = async (event: any) => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: `Go Serverless v1.0! Your function executed successfully!`, 6 | input: event, 7 | }), 8 | }; 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /tests/typescript-invalid-module/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-invalid-module", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "typescript-invalid-module", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/typescript-invalid-module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-invalid-module", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/typescript-invalid-module/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | 14 | -------------------------------------------------------------------------------- /tests/typescript-invalid-module/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // should show warning for es3 or es5 4 | "target": "es3", 5 | // should show warning module: commonjs 6 | // "module": "commonjs", 7 | "moduleResolution": "node", 8 | "baseUrl": "." 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/typescript-invalid-module/typescript-invalid-module.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("typescript invalid module", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).toContain("CommonJS, ES3, or ES5 are not supported"); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/typescript-jest/handler.ts: -------------------------------------------------------------------------------- 1 | import { Context, APIGatewayEvent, APIGatewayProxyResult } from "aws-lambda"; 2 | 3 | export async function hello( 4 | event: APIGatewayEvent, 5 | context: Context 6 | ): Promise { 7 | return { 8 | statusCode: 200, 9 | body: JSON.stringify({ 10 | message: "Go Serverless v2.0! Your function executed successfully!", 11 | context, 12 | event, 13 | }), 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /tests/typescript-jest/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-jest", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "typescript-jest", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@types/aws-lambda": "^8.10.64" 13 | } 14 | }, 15 | "node_modules/@types/aws-lambda": { 16 | "version": "8.10.64", 17 | "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.64.tgz", 18 | "integrity": "sha512-LRKk2UQCSi7BsO5TlfSI8cTNpOGz+MH6+RXEWtuZmxJficQgxwEYJDiKVirzgyiHce0L0F4CqCVvKTwblAeOUw==", 19 | "dev": true 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/typescript-jest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-jest", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "../../bin/scripts.js test --testPathIgnorePatterns=\"./typescript-jest.test.js\"" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@types/aws-lambda": "^8.10.64" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/typescript-jest/serverless.yml: -------------------------------------------------------------------------------- 1 | service: typescript-jest 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/typescript-jest/tests/index.test.ts: -------------------------------------------------------------------------------- 1 | import {APIGatewayEvent, Context} from "aws-lambda"; 2 | import * as handler from "../handler"; 3 | 4 | test("hello", async () => { 5 | const event = { 6 | body: "Test Body" 7 | } as APIGatewayEvent; 8 | const context = {} as Context; 9 | 10 | const response = await handler.hello(event, context); 11 | 12 | expect(response.statusCode).toEqual(200); 13 | expect(typeof response.body).toBe("string"); 14 | }); 15 | -------------------------------------------------------------------------------- /tests/typescript-jest/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "moduleResolution": "node", 5 | "baseUrl": "." 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/typescript-jest/typescript-jest.test.js: -------------------------------------------------------------------------------- 1 | const { runJestCommand, clearNpmCache } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("typescript-jest", async () => { 12 | const result = await runJestCommand(__dirname); 13 | 14 | // Ensure Jest ran the included tests successfully 15 | expect(result).not.toMatch(/failed/); 16 | }); 17 | -------------------------------------------------------------------------------- /tests/typescript-no-baseUrl/handler.ts: -------------------------------------------------------------------------------- 1 | export const hello = async (event: any) => { 2 | return { 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | message: "No baseUrl", 6 | input: event, 7 | }), 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/typescript-no-baseUrl/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-no-baseUrl", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "typescript-no-baseUrl", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/typescript-no-baseUrl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-no-baseUrl", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/typescript-no-baseUrl/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | custom: 7 | 8 | provider: 9 | name: aws 10 | runtime: nodejs20.x 11 | 12 | functions: 13 | hello: 14 | handler: handler.hello 15 | -------------------------------------------------------------------------------- /tests/typescript-no-baseUrl/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "moduleResolution": "node" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tests/typescript-no-baseUrl/typescript-no-baseUrl.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("typescript-no-baseUrl", async () => { 12 | const result = await runSlsCommand(__dirname, "package", true); 13 | 14 | expect(result).not.toMatch(/Failed to load/); 15 | expect(result).not.toMatch(/Found no baseUrl/); 16 | }); 17 | -------------------------------------------------------------------------------- /tests/typescript/custom-lib/src/some-lib/index.ts: -------------------------------------------------------------------------------- 1 | export function hi(name: string) { 2 | return `Imported successfully ${name}.`; 3 | } 4 | -------------------------------------------------------------------------------- /tests/typescript/decorated-class.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-unused-vars 2 | function classDecorator( 3 | constructor: T 4 | ) { 5 | return class extends constructor { 6 | newProperty = "new property"; 7 | hello = "override"; 8 | }; 9 | } 10 | 11 | const myDecorator = (target: any, propertyKey: string, descriptor: PropertyDescriptor) => { 12 | console.log('decorator', descriptor); 13 | } 14 | 15 | @classDecorator 16 | export class Greeter { 17 | property = "property"; 18 | hello: string; 19 | constructor(m: string) { 20 | this.hello = m; 21 | } 22 | } 23 | 24 | @classDecorator 25 | export class Rocket { 26 | @myDecorator 27 | launch() { 28 | return true 29 | } 30 | } -------------------------------------------------------------------------------- /tests/typescript/handler.ts: -------------------------------------------------------------------------------- 1 | import { hi } from "@my-org/some-lib/index"; 2 | import { merhaba } from "./tsx/import"; 3 | import { Greeter, Rocket } from './decorated-class' 4 | 5 | /* eslint-disable no-unused-vars */ 6 | export const typescript4Inject = ( 7 | fn: (str: string, ...args: A) => any 8 | ) => (...a: A) => fn("test", ...a); 9 | /* eslint-enable no-unused-vars */ 10 | 11 | export const hello = async (event: any) => { 12 | new Greeter("world"); 13 | new Rocket().launch(); 14 | 15 | return { 16 | statusCode: 200, 17 | body: JSON.stringify({ 18 | message: `Go Serverless v1.0! ${hi("Sandy")} ${merhaba( 19 | "Andy" 20 | )} Your function executed successfully!`, 21 | input: event, 22 | }), 23 | }; 24 | }; 25 | -------------------------------------------------------------------------------- /tests/typescript/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "typescript", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/typescript/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "experimentalDecorators": true, 4 | "skipLibCheck": true, 5 | "target": "es6", 6 | "moduleResolution": "node", 7 | "emitDecoratorMetadata": true, 8 | "baseUrl": ".", 9 | "jsx": "preserve", 10 | "paths": { 11 | "@my-org/some-lib/*": ["custom-lib/src/some-lib/*"] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/typescript/tsx/import.tsx: -------------------------------------------------------------------------------- 1 | export function merhaba(name: string) { 2 | return `Merhaba, ${name}`; 3 | } 4 | -------------------------------------------------------------------------------- /tests/typescript/typescript.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("typescript", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).toContain("Imported successfully"); 15 | expect(result).toContain("Merhaba"); 16 | }); 17 | -------------------------------------------------------------------------------- /tests/with-eslintignore/.eslintignore: -------------------------------------------------------------------------------- 1 | handler.js 2 | -------------------------------------------------------------------------------- /tests/with-eslintignore/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/with-eslintignore/handler.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | 3 | export const hello = async (event, context) => { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify({ 7 | message: 'Go Serverless v1.0! Your function executed successfully!', 8 | input: event, 9 | }), 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /tests/with-eslintignore/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-eslintignore", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "with-eslintignore", 9 | "version": "1.0.0", 10 | "license": "ISC" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/with-eslintignore/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-eslintignore", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "handler.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /tests/with-eslintignore/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/with-eslintignore/with-eslintignore.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("test eslintignore", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/with-node14/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/with-node14/handler.js: -------------------------------------------------------------------------------- 1 | class User { 2 | constructor() { 3 | this.counter = 0; 4 | } 5 | 6 | increment() { 7 | this.counter++; 8 | } 9 | 10 | get count() { 11 | return this.counter; 12 | } 13 | } 14 | 15 | const user = new User(); 16 | 17 | export const hello = async (event) => { 18 | user.increment(); 19 | return { 20 | statusCode: 200, 21 | body: JSON.stringify({ 22 | message: `Go Serverless v1.0! Your function executed successfully! Count is ${user.count}`, 23 | input: event, 24 | }), 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /tests/with-node14/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs14.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/with-node14/with-node14.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("node 14", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/with-node16/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/with-node16/handler.js: -------------------------------------------------------------------------------- 1 | class User { 2 | constructor() { 3 | this.counter = 0; 4 | } 5 | 6 | increment() { 7 | this.counter++; 8 | } 9 | 10 | get count() { 11 | return this.counter; 12 | } 13 | } 14 | 15 | const user = new User(); 16 | 17 | export const hello = async (event) => { 18 | user.increment(); 19 | return { 20 | statusCode: 200, 21 | body: JSON.stringify({ 22 | message: `Go Serverless v1.0! Your function executed successfully! Count is ${user.count}`, 23 | input: event, 24 | }), 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /tests/with-node16/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs16.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/with-node16/with-node16.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("node 16", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/with-node18/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/with-node18/handler.js: -------------------------------------------------------------------------------- 1 | class User { 2 | constructor() { 3 | this.counter = 0; 4 | } 5 | 6 | increment() { 7 | this.counter++; 8 | } 9 | 10 | get count() { 11 | return this.counter; 12 | } 13 | } 14 | 15 | const user = new User(); 16 | 17 | export const hello = async (event) => { 18 | user.increment(); 19 | return { 20 | statusCode: 200, 21 | body: JSON.stringify({ 22 | message: `Go Serverless v1.0! Your function executed successfully! Count is ${user.count}`, 23 | input: event, 24 | }), 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /tests/with-node18/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/with-node18/with-node18.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("node 18", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/with-node20/.gitignore: -------------------------------------------------------------------------------- 1 | # package directories 2 | node_modules 3 | jspm_packages 4 | 5 | # Serverless directories 6 | .serverless -------------------------------------------------------------------------------- /tests/with-node20/handler.js: -------------------------------------------------------------------------------- 1 | class User { 2 | constructor() { 3 | this.counter = 0; 4 | } 5 | 6 | increment() { 7 | this.counter++; 8 | } 9 | 10 | get count() { 11 | return this.counter; 12 | } 13 | } 14 | 15 | const user = new User(); 16 | 17 | export const hello = async (event) => { 18 | user.increment(); 19 | return { 20 | statusCode: 200, 21 | body: JSON.stringify({ 22 | message: `Go Serverless v1.0! Your function executed successfully! Count is ${user.count}`, 23 | input: event, 24 | }), 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /tests/with-node20/serverless.yml: -------------------------------------------------------------------------------- 1 | service: my-service 2 | 3 | plugins: 4 | - '../../index' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs20.x 9 | 10 | functions: 11 | hello: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /tests/with-node20/with-node20.test.js: -------------------------------------------------------------------------------- 1 | const { runSlsCommand, clearNpmCache, errorRegex } = require("../helpers"); 2 | 3 | beforeEach(async () => { 4 | await clearNpmCache(__dirname); 5 | }); 6 | 7 | afterAll(async () => { 8 | await clearNpmCache(__dirname); 9 | }); 10 | 11 | test("node 20", async () => { 12 | const result = await runSlsCommand(__dirname); 13 | 14 | expect(result).not.toMatch(errorRegex); 15 | }); 16 | --------------------------------------------------------------------------------