├── .editorconfig ├── .github ├── prepare-canary.js └── workflows │ ├── integrate.yml │ ├── publish.yml │ └── validate.yml ├── .gitignore ├── .npmignore ├── .prettierignore ├── CODE_OF_CONDUCT.md ├── LICENSE.txt ├── README.md ├── RELEASE_PROCESS.md ├── bin └── serverless.js ├── commands ├── doctor.js ├── plugin-install.js └── plugin-uninstall.js ├── docs ├── README.md ├── cli-reference │ ├── config-credentials.md │ ├── create.md │ ├── deploy-function.md │ ├── deploy-list.md │ ├── deploy.md │ ├── generate-event.md │ ├── info.md │ ├── install.md │ ├── invoke-local.md │ ├── invoke.md │ ├── logs.md │ ├── metrics.md │ ├── package.md │ ├── plugin-install.md │ ├── plugin-list.md │ ├── plugin-search.md │ ├── plugin-uninstall.md │ ├── print.md │ ├── remove.md │ ├── rollback-function.md │ └── rollback.md ├── events │ ├── README.md │ ├── activemq.md │ ├── alb.md │ ├── alexa-skill.md │ ├── alexa-smart-home.md │ ├── apigateway.md │ ├── cloudfront.md │ ├── cloudwatch-event.md │ ├── cloudwatch-log.md │ ├── cognito-user-pool.md │ ├── event-bridge.md │ ├── http-api.md │ ├── iot-fleet-provisioning.md │ ├── iot.md │ ├── kafka.md │ ├── msk.md │ ├── rabbitmq.md │ ├── s3.md │ ├── schedule.md │ ├── sns.md │ ├── sqs.md │ ├── streams.md │ └── websocket.md ├── getting-started.md ├── guides │ ├── compose.md │ ├── configuration-validation.md │ ├── credentials.md │ ├── deploying.md │ ├── deprecations.md │ ├── environment-variables.md │ ├── events.md │ ├── functions.md │ ├── iam.md │ ├── intro.md │ ├── layers.md │ ├── packaging.md │ ├── parameters.md │ ├── plugins │ │ ├── README.md │ │ ├── cli-output.md │ │ ├── creating-plugins.md │ │ ├── custom-commands.md │ │ ├── custom-configuration.md │ │ ├── custom-variables.md │ │ └── extending-configuration.md │ ├── resources.md │ ├── serverless.yml.md │ ├── services.md │ ├── testing.md │ ├── upgrading-v3.md │ ├── variables.md │ └── workflow.md └── install-standalone.md ├── lib ├── aws │ ├── has-local-credentials.js │ ├── request.js │ ├── sdk-v2.js │ └── set-s3-upload-encryption-options.js ├── classes │ ├── cli.js │ ├── config-schema-handler │ │ ├── index.js │ │ ├── normalize-ajv-errors.js │ │ ├── regexp-keyword.js │ │ └── resolve-ajv-validate.js │ ├── config.js │ ├── plugin-manager.js │ ├── service.js │ ├── utils.js │ └── yaml-parser.js ├── cli │ ├── commands-schema │ │ ├── aws-service.js │ │ ├── common-options │ │ │ ├── aws-service.js │ │ │ ├── global.js │ │ │ └── service.js │ │ ├── index.js │ │ ├── no-service.js │ │ ├── resolve-final.js │ │ └── service.js │ ├── conditionally-load-dotenv.js │ ├── ensure-supported-command.js │ ├── filter-supported-options.js │ ├── handle-error.js │ ├── is-locally-installed.js │ ├── load-dotenv.js │ ├── local-serverless-path.js │ ├── param-reg-exp.js │ ├── parse-args.js │ ├── render-help │ │ ├── command.js │ │ ├── general.js │ │ ├── generate-command-usage.js │ │ ├── index.js │ │ └── options.js │ ├── render-version.js │ ├── resolve-configuration-path.js │ ├── resolve-input.js │ ├── run-compose.js │ ├── triage.js │ └── write-service-outputs.js ├── commands │ └── plugin-management.js ├── config-schema.js ├── configuration │ ├── read.js │ ├── resolve-provider-name.js │ └── variables │ │ ├── eventually-report-resolution-errors.js │ │ ├── humanize-property-path-keys.js │ │ ├── index.js │ │ ├── is-property-resolved.js │ │ ├── parse.js │ │ ├── resolve-meta.js │ │ ├── resolve-unresolved-source-types.js │ │ ├── resolve.js │ │ ├── source-resolution-error.js │ │ └── sources │ │ ├── env.js │ │ ├── file.js │ │ ├── instance-dependent │ │ ├── get-aws.js │ │ ├── get-cf.js │ │ ├── get-s3.js │ │ ├── get-sls.js │ │ ├── get-ssm.js │ │ └── param.js │ │ ├── opt.js │ │ ├── resolve-external-plugin-sources.js │ │ ├── self.js │ │ └── str-to-bool.js ├── plugins │ ├── aws │ │ ├── common │ │ │ ├── index.js │ │ │ └── lib │ │ │ │ ├── artifacts.js │ │ │ │ └── cleanup-temp-dir.js │ │ ├── config-credentials.js │ │ ├── custom-resources │ │ │ ├── generate-zip.js │ │ │ ├── index.js │ │ │ └── resources │ │ │ │ ├── README.md │ │ │ │ ├── api-gateway-cloud-watch-role │ │ │ │ └── handler.js │ │ │ │ ├── cognito-user-pool │ │ │ │ ├── handler.js │ │ │ │ └── lib │ │ │ │ │ ├── permissions.js │ │ │ │ │ └── user-pool.js │ │ │ │ ├── event-bridge │ │ │ │ ├── handler.js │ │ │ │ └── lib │ │ │ │ │ ├── event-bridge.js │ │ │ │ │ ├── permissions.js │ │ │ │ │ └── utils.js │ │ │ │ ├── s3 │ │ │ │ ├── handler.js │ │ │ │ └── lib │ │ │ │ │ ├── bucket.js │ │ │ │ │ └── permissions.js │ │ │ │ └── utils.js │ │ ├── deploy-function.js │ │ ├── deploy-list.js │ │ ├── deploy │ │ │ ├── index.js │ │ │ └── lib │ │ │ │ ├── check-for-changes.js │ │ │ │ ├── cleanup-s3-bucket.js │ │ │ │ ├── create-stack.js │ │ │ │ ├── ensure-valid-bucket-exists.js │ │ │ │ ├── extended-validate.js │ │ │ │ ├── upload-artifacts.js │ │ │ │ └── validate-template.js │ │ ├── info │ │ │ ├── display.js │ │ │ ├── get-api-key-values.js │ │ │ ├── get-resource-count.js │ │ │ ├── get-stack-info.js │ │ │ └── index.js │ │ ├── invoke-local │ │ │ ├── .gitignore │ │ │ ├── index.js │ │ │ └── runtime-wrappers │ │ │ │ ├── invoke.py │ │ │ │ ├── invoke.rb │ │ │ │ └── java │ │ │ │ ├── MANIFEST.mf │ │ │ │ ├── pom.xml │ │ │ │ └── src │ │ │ │ ├── main │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── serverless │ │ │ │ │ ├── Context.java │ │ │ │ │ ├── InvokeBridge.java │ │ │ │ │ ├── LambdaLogger.java │ │ │ │ │ └── mapper │ │ │ │ │ ├── AbstractMapper.java │ │ │ │ │ ├── DefaultEventMapper.java │ │ │ │ │ ├── DefaultMapper.java │ │ │ │ │ ├── HashMapWrapper.java │ │ │ │ │ ├── Mapper.java │ │ │ │ │ ├── MapperFactory.java │ │ │ │ │ └── S3EventMapper.java │ │ │ │ └── test │ │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── serverless │ │ │ │ │ ├── AbstractRequestHandler.java │ │ │ │ │ ├── ConcreteRequestHandler.java │ │ │ │ │ ├── InvokeBridgeInheritanceTest.java │ │ │ │ │ ├── InvokeBridgeTest.java │ │ │ │ │ ├── RequestHandler.java │ │ │ │ │ ├── RequestHandlerAPIGatewayProxyRequestEvent.java │ │ │ │ │ ├── RequestHandlerAPIGatewayV2HTTPEvent.java │ │ │ │ │ ├── RequestHandlerAPIGatewayV2WebSocketEvent.java │ │ │ │ │ ├── RequestHandlerApplicationLoadBalancerRequestEvent.java │ │ │ │ │ ├── RequestHandlerCloudFrontEvent.java │ │ │ │ │ ├── RequestHandlerCloudWatchLogsEvent.java │ │ │ │ │ ├── RequestHandlerCodeCommitEvent.java │ │ │ │ │ ├── RequestHandlerCognitoEvent.java │ │ │ │ │ ├── RequestHandlerConfigEvent.java │ │ │ │ │ ├── RequestHandlerDynamodbEvent.java │ │ │ │ │ ├── RequestHandlerIoTButtonEvent.java │ │ │ │ │ ├── RequestHandlerKinesisEvent.java │ │ │ │ │ ├── RequestHandlerKinesisFirehoseEvent.java │ │ │ │ │ ├── RequestHandlerLexEvent.java │ │ │ │ │ ├── RequestHandlerS3Event.java │ │ │ │ │ ├── RequestHandlerSNSEvent.java │ │ │ │ │ ├── RequestHandlerSQSEvent.java │ │ │ │ │ ├── RequestHandlerScheduledEvent.java │ │ │ │ │ └── RequestStreamHandler.java │ │ │ │ └── resources │ │ │ │ ├── api-gateway-proxy-request-event.json │ │ │ │ ├── api-gateway-v2-http-event.json │ │ │ │ ├── api-gateway-v2-websocket-event.json │ │ │ │ ├── application-load-balancer-request-event.json │ │ │ │ ├── cloud-front-event.json │ │ │ │ ├── cloud-watch-logs-event-decoded.json │ │ │ │ ├── cloud-watch-logs-event.json │ │ │ │ ├── code-commit-event.json │ │ │ │ ├── cognito-event.json │ │ │ │ ├── config-event.json │ │ │ │ ├── dynamo-event.json │ │ │ │ ├── iot-button-event.json │ │ │ │ ├── kinesis-event.json │ │ │ │ ├── kinesis-firehose-event.json │ │ │ │ ├── lex-event.json │ │ │ │ ├── s3-event.json │ │ │ │ ├── scheduled-event.json │ │ │ │ ├── sns-event.json │ │ │ │ ├── sqs-event.json │ │ │ │ └── test.json │ │ ├── invoke.js │ │ ├── lib │ │ │ ├── check-if-bucket-exists.js │ │ │ ├── check-if-ecr-repository-exists.js │ │ │ ├── get-create-change-set-params.js │ │ │ ├── get-create-stack-params.js │ │ │ ├── get-execute-change-set-params.js │ │ │ ├── get-service-state.js │ │ │ ├── get-shared-stack-action-params.js │ │ │ ├── get-update-stack-params.js │ │ │ ├── monitor-stack.js │ │ │ ├── naming.js │ │ │ ├── normalize-files.js │ │ │ ├── set-bucket-name.js │ │ │ ├── update-stack.js │ │ │ ├── upload-zip-file.js │ │ │ ├── validate.js │ │ │ └── wait-for-change-set-creation.js │ │ ├── logs.js │ │ ├── metrics.js │ │ ├── package │ │ │ ├── compile │ │ │ │ ├── events │ │ │ │ │ ├── activemq.js │ │ │ │ │ ├── alb │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── lib │ │ │ │ │ │ │ ├── listener-rules.js │ │ │ │ │ │ │ ├── permissions.js │ │ │ │ │ │ │ ├── target-groups.js │ │ │ │ │ │ │ └── validate.js │ │ │ │ │ ├── alexa-skill.js │ │ │ │ │ ├── alexa-smart-home.js │ │ │ │ │ ├── api-gateway │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── lib │ │ │ │ │ │ │ ├── api-keys.js │ │ │ │ │ │ │ ├── authorizers.js │ │ │ │ │ │ │ ├── cors.js │ │ │ │ │ │ │ ├── deployment.js │ │ │ │ │ │ │ ├── hack │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── disassociate-usage-plan.js │ │ │ │ │ │ │ └── update-stage.js │ │ │ │ │ │ │ ├── method │ │ │ │ │ │ │ ├── authorization.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── integration.js │ │ │ │ │ │ │ └── responses.js │ │ │ │ │ │ │ ├── permissions.js │ │ │ │ │ │ │ ├── request-validator.js │ │ │ │ │ │ │ ├── resources.js │ │ │ │ │ │ │ ├── rest-api.js │ │ │ │ │ │ │ ├── stage.js │ │ │ │ │ │ │ ├── usage-plan-keys.js │ │ │ │ │ │ │ ├── usage-plan.js │ │ │ │ │ │ │ └── validate.js │ │ │ │ │ ├── cloud-front.js │ │ │ │ │ ├── cloud-watch-event.js │ │ │ │ │ ├── cloud-watch-log.js │ │ │ │ │ ├── cognito-user-pool.js │ │ │ │ │ ├── event-bridge │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── utils.js │ │ │ │ │ ├── http-api.js │ │ │ │ │ ├── iot-fleet-provisioning.js │ │ │ │ │ ├── iot.js │ │ │ │ │ ├── kafka.js │ │ │ │ │ ├── lib │ │ │ │ │ │ └── ensure-api-gateway-cloud-watch-role.js │ │ │ │ │ ├── msk │ │ │ │ │ │ ├── get-msk-cluster-name-token.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── rabbitmq.js │ │ │ │ │ ├── s3 │ │ │ │ │ │ ├── config-schema.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── schedule.js │ │ │ │ │ ├── sns.js │ │ │ │ │ ├── sqs.js │ │ │ │ │ ├── stream.js │ │ │ │ │ └── websockets │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── lib │ │ │ │ │ │ ├── api.js │ │ │ │ │ │ ├── authorizers.js │ │ │ │ │ │ ├── deployment.js │ │ │ │ │ │ ├── integrations.js │ │ │ │ │ │ ├── permissions.js │ │ │ │ │ │ ├── pick-websockets-template-part.js │ │ │ │ │ │ ├── route-responses.js │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ ├── stage.js │ │ │ │ │ │ └── validate.js │ │ │ │ ├── functions.js │ │ │ │ └── layers.js │ │ │ ├── index.js │ │ │ └── lib │ │ │ │ ├── add-export-name-for-outputs.js │ │ │ │ ├── core-cloudformation-template.json │ │ │ │ ├── generate-artifact-directory-name.js │ │ │ │ ├── generate-core-template.js │ │ │ │ ├── get-hash-for-file-path.js │ │ │ │ ├── iam-role-lambda-execution-template.json │ │ │ │ ├── merge-custom-provider-resources.js │ │ │ │ ├── merge-iam-templates.js │ │ │ │ ├── save-compiled-template.js │ │ │ │ ├── save-service-state.js │ │ │ │ ├── strip-null-props-from-template-resources.js │ │ │ │ └── validate-template.js │ │ ├── provider.js │ │ ├── remove │ │ │ ├── index.js │ │ │ └── lib │ │ │ │ ├── bucket.js │ │ │ │ ├── ecr.js │ │ │ │ └── stack.js │ │ ├── rollback-function.js │ │ ├── rollback.js │ │ └── utils │ │ │ ├── arn-regular-expressions.js │ │ │ ├── credentials.js │ │ │ ├── find-and-group-deployments.js │ │ │ ├── format-lambda-log-event.js │ │ │ ├── get-lambda-layer-artifact-path.js │ │ │ ├── get-monitoring-frequency.js │ │ │ ├── get-s3-endpoint-for-region.js │ │ │ ├── get-s3-objects-from-stacks.js │ │ │ ├── is-change-set-without-changes.js │ │ │ ├── parse-s3-uri.js │ │ │ ├── resolve-cf-import-value.js │ │ │ ├── resolve-cf-ref-value.js │ │ │ └── resolve-lambda-target.js │ ├── config.js │ ├── create │ │ └── create.js │ ├── deploy.js │ ├── index.js │ ├── info.js │ ├── install.js │ ├── invoke.js │ ├── logs.js │ ├── metrics.js │ ├── package │ │ ├── lib │ │ │ ├── package-service.js │ │ │ └── zip-service.js │ │ └── package.js │ ├── plugin │ │ ├── lib │ │ │ └── utils.js │ │ ├── list.js │ │ ├── plugin.js │ │ └── search.js │ ├── print.js │ ├── remove.js │ ├── rollback.js │ └── standalone.js ├── serverless-error.js ├── serverless.js ├── templates │ └── recommended-list │ │ ├── human-readable.js │ │ └── index.js └── utils │ ├── aws-schema-get-cf-value.js │ ├── aws-sdk-patch.js │ ├── create-from-local-template.js │ ├── deep-sort-object-by-key.js │ ├── download-template-from-examples.js │ ├── download-template-from-repo.js │ ├── ensure-artifact.js │ ├── ensure-exists.js │ ├── filesize.js │ ├── fs │ ├── copy-dir-contents-sync.js │ ├── create-zip-file.js │ ├── dir-exists-sync.js │ ├── dir-exists.js │ ├── file-exists-sync.js │ ├── file-exists.js │ ├── get-tmp-dir-path.js │ ├── parse.js │ ├── read-file-sync.js │ ├── read-file.js │ ├── safe-move-file.js │ ├── walk-dir-sync.js │ ├── write-file-sync.js │ └── write-file.js │ ├── get-framework-id.js │ ├── get-require.js │ ├── get-serverless-dir.js │ ├── health-status-filename.js │ ├── import-esm.js │ ├── is-standalone-executable.js │ ├── log-deprecation.js │ ├── npm-command-deferred.js │ ├── npm-package │ ├── is-global.js │ └── is-writable.js │ ├── open-browser.js │ ├── rename-service.js │ ├── report-deprecated-properties.js │ ├── require-with-import-fallback.js │ ├── resolve-region.js │ ├── resolve-stage.js │ ├── standalone-patch.js │ ├── standalone.js │ ├── telemetry │ └── are-disabled.js │ ├── tokenize-exception.js │ └── yaml-ast-parser.js ├── package.json ├── prettier.config.js ├── scripts ├── pkg │ ├── build.js │ ├── config.js │ ├── install.sh │ └── upload │ │ ├── index.js │ │ └── world.js ├── serverless.js └── test │ ├── integration-setup │ ├── cloudformation.yml │ ├── index.js │ └── kafka.server.properties │ └── integration-teardown.js ├── test ├── .gitignore ├── README.md ├── fixtures │ ├── cli │ │ ├── config-syntax-error │ │ │ └── serverless.yml │ │ ├── config-type-js-deferred │ │ │ └── serverless.js │ │ ├── config-type-js │ │ │ └── serverless.js │ │ ├── config-type-json │ │ │ └── serverless.json │ │ ├── config-type-non-object │ │ │ └── serverless.json │ │ ├── config-type-yaml │ │ │ └── serverless.yaml │ │ ├── config-type-yml-and-json │ │ │ ├── serverless.json │ │ │ └── serverless.yml │ │ ├── config-type-yml │ │ │ └── serverless.yml │ │ ├── index.js │ │ ├── serverless-ts │ │ │ └── serverless.ts │ │ ├── uncaught-exception │ │ │ ├── plugin.js │ │ │ └── serverless.yml │ │ └── variables │ │ │ ├── config.json │ │ │ ├── serverless.yml │ │ │ └── terraform.tfstate │ └── programmatic │ │ ├── api-gateway-extended │ │ ├── core.js │ │ ├── helper.js │ │ └── serverless.yml │ │ ├── api-gateway │ │ ├── index.js │ │ └── serverless.yml │ │ ├── aws-loggedin-console-service │ │ ├── .serverlessrc │ │ └── serverless.yml │ │ ├── aws-loggedin-monitored-service │ │ ├── .serverlessrc │ │ └── serverless.yml │ │ ├── aws-loggedin-noapp-service │ │ ├── .serverlessrc │ │ └── serverless.yml │ │ ├── aws-loggedin-service │ │ ├── .serverlessrc │ │ ├── index.js │ │ └── serverless.yml │ │ ├── aws-loggedin-wrongapp-service │ │ ├── .serverlessrc │ │ └── serverless.yml │ │ ├── aws-loggedin-wrongorg-service │ │ ├── .serverlessrc │ │ └── serverless.yml │ │ ├── aws │ │ └── serverless.yml │ │ ├── blank │ │ └── serverless.yml │ │ ├── check-for-changes │ │ ├── artifact.zip │ │ ├── fn-individually.js │ │ ├── fn.js │ │ └── serverless.yml │ │ ├── cognito-user-pool │ │ ├── core.js │ │ ├── serverless.yml │ │ └── utils.js │ │ ├── config-invalid │ │ └── serverless.yml │ │ ├── config-schema-extensions-error │ │ ├── serverless.yml │ │ ├── test-plugin-with-colliding-custom-property.js │ │ ├── test-plugin-with-colliding-function-event-property.js │ │ ├── test-plugin-with-colliding-function-event.js │ │ ├── test-plugin-with-colliding-function-property.js │ │ ├── test-plugin-with-colliding-provider-property-in-function.js │ │ ├── test-plugin-with-colliding-provider-property-in-provider.js │ │ ├── test-plugin-with-colliding-top-level-property.js │ │ ├── test-plugin-with-complex-event-without-object-definition.js │ │ └── test-plugin-with-non-existing-event-error.js │ │ ├── config-schema-extensions │ │ ├── serverless.yml │ │ └── test-plugin.js │ │ ├── curated-plugins-python │ │ ├── _setup.js │ │ ├── handler.py │ │ ├── package.json │ │ ├── requirements.txt │ │ └── serverless.yml │ │ ├── curated-plugins │ │ ├── .env │ │ ├── _setup.js │ │ ├── index-ts.ts │ │ ├── index.js │ │ ├── package.json │ │ ├── serverless.yml │ │ └── webpack.config.js │ │ ├── custom-config-filename │ │ └── serverless.custom.yml │ │ ├── custom-provider │ │ ├── custom-provider.js │ │ └── serverless.yml │ │ ├── ecr │ │ ├── Dockerfile │ │ ├── Dockerfile.dev │ │ ├── app.js │ │ └── serverless.yml │ │ ├── event-bridge │ │ ├── core.js │ │ ├── serverless.yml │ │ └── utils.js │ │ ├── exception │ │ ├── plugin.js │ │ └── serverless.yml │ │ ├── function-active-mq │ │ ├── core.js │ │ ├── package.json │ │ └── serverless.yml │ │ ├── function-cloud-front │ │ ├── index.js │ │ └── serverless.yml │ │ ├── function-efs │ │ ├── core.js │ │ └── serverless.yml │ │ ├── function-layers │ │ ├── extra-layers │ │ │ └── test-layer-source-change │ │ │ │ └── index.js │ │ ├── index.js │ │ ├── serverless.yml │ │ └── test-layer │ │ │ └── index.js │ │ ├── function-msk │ │ ├── core.js │ │ ├── package.json │ │ └── serverless.yml │ │ ├── function-rabbit-mq │ │ ├── core.js │ │ ├── package.json │ │ └── serverless.yml │ │ ├── function │ │ ├── basic.js │ │ ├── other.js │ │ ├── serverless.yml │ │ ├── stream.js │ │ ├── target.js │ │ └── trigger.js │ │ ├── http-api-catch-all │ │ ├── index.js │ │ └── serverless.yml │ │ ├── http-api-export │ │ └── serverless.yml │ │ ├── http-api │ │ ├── authorizers.js │ │ ├── index.js │ │ └── serverless.yml │ │ ├── index.js │ │ ├── invocation │ │ ├── async-cjs.cjs │ │ ├── async.js │ │ ├── callback.js │ │ ├── class.rb │ │ ├── context-done.js │ │ ├── context-succeed.js │ │ ├── context.json │ │ ├── deadline_ms.rb │ │ ├── doubled-resolution-callback-first.js │ │ ├── doubled-resolution-promise-first.js │ │ ├── esm │ │ │ ├── async-esm.js │ │ │ └── package.json │ │ ├── handler.py │ │ ├── handler.rb │ │ ├── init-fail.js │ │ ├── invocation-fail.js │ │ ├── payload.js │ │ ├── payload.json │ │ ├── payload.yaml │ │ ├── remaining-time.js │ │ ├── remaining_time.py │ │ ├── remaining_time.rb │ │ └── serverless.yml │ │ ├── iot-fleet-provisioning │ │ ├── hook.js │ │ ├── package.json │ │ ├── register-device.js │ │ ├── serverless.yml │ │ └── template.json │ │ ├── iot │ │ ├── core.js │ │ ├── serverless.yml │ │ └── utils.js │ │ ├── layer │ │ ├── index.js │ │ ├── layer │ │ │ └── index.js │ │ └── serverless.yml │ │ ├── locally-installed-serverless │ │ ├── _setup.js │ │ ├── node_modules │ │ │ └── serverless │ │ │ │ ├── bin │ │ │ │ └── serverless.js │ │ │ │ ├── lib │ │ │ │ └── serverless.js │ │ │ │ └── package.json │ │ └── serverless.yml │ │ ├── multi-service │ │ ├── file.json │ │ └── service-a │ │ │ ├── index.js │ │ │ └── serverless.yml │ │ ├── package-artifact-in-serverless-dir │ │ ├── my-own.zip │ │ ├── package-artifact-plugin.js │ │ └── serverless.yml │ │ ├── package-artifact │ │ ├── absolute-artifact.zip │ │ ├── artifact-function.zip │ │ ├── artifact.zip │ │ ├── index.js │ │ └── serverless.yml │ │ ├── packaging │ │ ├── .env │ │ ├── .env.stage │ │ ├── .gitignore │ │ ├── .serverless_plugins │ │ │ └── index.js │ │ ├── artifact-function.zip │ │ ├── artifact.zip │ │ ├── custom-plugins │ │ │ ├── index.js │ │ │ ├── plugin-2 │ │ │ │ └── index.js │ │ │ ├── plugin-3 │ │ │ │ ├── package.json │ │ │ │ └── src │ │ │ │ │ └── main.js │ │ │ └── plugin-4 │ │ │ │ └── index.js │ │ ├── dir1 │ │ │ ├── index.js │ │ │ ├── subdir1 │ │ │ │ └── index.js │ │ │ ├── subdir2 │ │ │ │ ├── index.js │ │ │ │ ├── subsubdir1 │ │ │ │ │ └── index.js │ │ │ │ ├── subsubdir2 │ │ │ │ │ └── index.js │ │ │ │ └── subsubdir3 │ │ │ │ │ └── index.js │ │ │ ├── subdir3 │ │ │ │ └── index.js │ │ │ └── subdir4 │ │ │ │ └── index.js │ │ ├── dir2 │ │ │ └── index.js │ │ ├── dir3 │ │ │ └── index.js │ │ ├── index.js │ │ ├── layer │ │ │ ├── layer-module-1.js │ │ │ └── layer-module-2.js │ │ ├── main.go │ │ └── serverless.yml │ │ ├── plugin │ │ ├── broken-plugin │ │ │ └── index.js │ │ ├── custom-variable-source.js │ │ ├── extend-config-plugin │ │ │ └── index.js │ │ ├── local-esm-plugin │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── node_modules │ │ │ └── esm-plugin │ │ │ │ ├── index.js │ │ │ │ └── package.json │ │ ├── plugin.js │ │ └── serverless.yml │ │ ├── provisioned-concurrency │ │ ├── core.js │ │ └── serverless.yml │ │ ├── request-parameters │ │ ├── serverless.yml │ │ └── target.js │ │ ├── request-schema │ │ ├── dummy-schema.json │ │ ├── serverless.yml │ │ └── target.js │ │ ├── s3 │ │ ├── core.js │ │ ├── serverless.yml │ │ └── utils.js │ │ ├── schedule │ │ ├── core.js │ │ ├── serverless.yml │ │ └── utils.js │ │ ├── sns │ │ ├── core.js │ │ ├── serverless.yml │ │ └── utils.js │ │ ├── sqs │ │ ├── core.js │ │ ├── serverless.yml │ │ └── utils.js │ │ ├── stream │ │ ├── core.js │ │ ├── serverless.yml │ │ └── utils.js │ │ ├── variables-legacy │ │ ├── config.json │ │ ├── serverless.yml │ │ └── terraform.tfstate │ │ ├── websocket-external-auth │ │ ├── core.js │ │ └── serverless.yml │ │ └── websocket │ │ ├── core.js │ │ └── serverless.yml ├── integration-basic.test.js ├── integration-package │ ├── cloudformation.tests.js │ ├── fixtures │ │ ├── artifact │ │ │ ├── artifact.zip │ │ │ ├── handler.js │ │ │ └── serverless.yml │ │ ├── individually-function │ │ │ ├── handler.js │ │ │ ├── handler2.js │ │ │ └── serverless.yml │ │ ├── individually │ │ │ ├── handler.js │ │ │ ├── handler2.js │ │ │ └── serverless.yml │ │ └── regular │ │ │ ├── handler.js │ │ │ └── serverless.yml │ └── lambda-files.tests.js ├── integration │ ├── aws │ │ ├── api-gateway-external.test.js │ │ ├── api-gateway.test.js │ │ ├── cognito-user-pool.test.js │ │ ├── custom-deployment-bucket.test.js │ │ ├── event-bridge.test.js │ │ ├── function-url.test.js │ │ ├── function.test.js │ │ ├── http-api.test.js │ │ ├── infra-dependent │ │ │ ├── active-mq.test.js │ │ │ ├── file-system-config.test.js │ │ │ ├── msk.test.js │ │ │ └── rabbit-mq.test.js │ │ ├── iot-fleet-provisioning.test.js │ │ ├── iot.test.js │ │ ├── provisioned-concurrency.test.js │ │ ├── s3.test.js │ │ ├── schedule.test.js │ │ ├── sns.test.js │ │ ├── sqs.test.js │ │ ├── stream.test.js │ │ └── websocket.test.js │ ├── create.test.js │ ├── curated-plugins-python.test.js │ └── plugin-install.test.js ├── mocha-patch.js ├── serverless-binary.js ├── unit │ ├── commands │ │ ├── doctor.test.js │ │ ├── plugin-install.test.js │ │ └── plugin-uninstall.test.js │ ├── lib │ │ ├── aws │ │ │ ├── has-local-credentials.test.js │ │ │ └── request.test.js │ │ ├── classes │ │ │ ├── cli.test.js │ │ │ ├── config-schema-handler │ │ │ │ ├── index.test.js │ │ │ │ ├── normalize-ajv-errors.test.js │ │ │ │ └── resolve-ajv-validate.test.js │ │ │ ├── config.test.js │ │ │ ├── plugin-manager.test.js │ │ │ ├── service.test.js │ │ │ ├── utils.test.js │ │ │ └── yaml-parser.test.js │ │ ├── cli │ │ │ ├── commands-schema │ │ │ │ ├── aws-service.test.js │ │ │ │ ├── common-options │ │ │ │ │ ├── aws-service.test.js │ │ │ │ │ ├── global.test.js │ │ │ │ │ └── service.test.js │ │ │ │ ├── no-service.test.js │ │ │ │ ├── resolve-final.test.js │ │ │ │ └── service.test.js │ │ │ ├── conditionally-load-dotenv.test.js │ │ │ ├── ensure-supported-command.test.js │ │ │ ├── filter-supported-options.test.js │ │ │ ├── handle-error.test.js │ │ │ ├── load-dotenv.test.js │ │ │ ├── local-serverless-path.test.js │ │ │ ├── parse-args.test.js │ │ │ ├── render-help │ │ │ │ ├── command.test.js │ │ │ │ ├── general.test.js │ │ │ │ ├── generate-command-usage.test.js │ │ │ │ ├── index.test.js │ │ │ │ └── options.test.js │ │ │ ├── render-version.test.js │ │ │ ├── resolve-configuration-path.test.js │ │ │ ├── resolve-input.test.js │ │ │ └── triage │ │ │ │ ├── fixtures │ │ │ │ ├── @osls │ │ │ │ │ └── compose │ │ │ │ │ │ ├── js │ │ │ │ │ │ └── project │ │ │ │ │ │ │ └── serverless-compose.js │ │ │ │ │ │ ├── json │ │ │ │ │ │ └── project │ │ │ │ │ │ │ └── serverless-compose.json │ │ │ │ │ │ ├── ts │ │ │ │ │ │ └── project │ │ │ │ │ │ │ └── serverless-compose.ts │ │ │ │ │ │ ├── yaml │ │ │ │ │ │ └── project │ │ │ │ │ │ │ └── serverless-compose.yaml │ │ │ │ │ │ └── yml │ │ │ │ │ │ └── project │ │ │ │ │ │ └── serverless-compose.yml │ │ │ │ └── serverless │ │ │ │ │ ├── js │ │ │ │ │ ├── component-in-custom │ │ │ │ │ │ └── serverless.js │ │ │ │ │ └── projects │ │ │ │ │ │ ├── bar │ │ │ │ │ │ └── serverless.yml │ │ │ │ │ │ └── foo │ │ │ │ │ │ └── serverless.js │ │ │ │ │ ├── json │ │ │ │ │ ├── component-in-custom │ │ │ │ │ │ └── serverless.json │ │ │ │ │ └── projects │ │ │ │ │ │ ├── bar │ │ │ │ │ │ └── serverless.yml │ │ │ │ │ │ └── foo │ │ │ │ │ │ └── serverless.json │ │ │ │ │ ├── ts │ │ │ │ │ └── any │ │ │ │ │ │ └── serverless.ts │ │ │ │ │ └── yml │ │ │ │ │ ├── component-in-custom │ │ │ │ │ └── serverless.yml │ │ │ │ │ └── projects │ │ │ │ │ ├── bar │ │ │ │ │ └── serverless.yml │ │ │ │ │ └── foo │ │ │ │ │ └── serverless.yml │ │ │ │ └── index.test.js │ │ ├── config-schema.test.js │ │ ├── configuration │ │ │ ├── read.test.js │ │ │ ├── resolve-provider-name.test.js │ │ │ └── variables │ │ │ │ ├── eventually-report-resolution-errors.test.js │ │ │ │ ├── humanize-property-path-keys.test.js │ │ │ │ ├── index.test.js │ │ │ │ ├── is-property-path-resolved.test.js │ │ │ │ ├── parse.test.js │ │ │ │ ├── resolve-meta.test.js │ │ │ │ ├── resolve-unresolved-source-types.test.js │ │ │ │ ├── resolve.test.js │ │ │ │ ├── source-resolution-error.test.js │ │ │ │ └── sources │ │ │ │ ├── env.test.js │ │ │ │ ├── file.test.js │ │ │ │ ├── fixture │ │ │ │ ├── dir.yaml │ │ │ │ │ └── .gitkeep │ │ │ │ ├── file-ambiguous.json │ │ │ │ ├── file-function-access-unresolvable-property.js │ │ │ │ ├── file-function-errored-non-error.js │ │ │ │ ├── file-function-errored.js │ │ │ │ ├── file-function-many-variables.js │ │ │ │ ├── file-function-many-variables.yaml │ │ │ │ ├── file-function-variable-missing-source.js │ │ │ │ ├── file-function-variable.js │ │ │ │ ├── file-function.js │ │ │ │ ├── file-primitive.json │ │ │ │ ├── file-promise-rejected-non-error.js │ │ │ │ ├── file-promise-rejected.js │ │ │ │ ├── file-property-function-access-unresolvable-property.js │ │ │ │ ├── file-property-function-errored-non-error.js │ │ │ │ ├── file-property-function-errored.js │ │ │ │ ├── file-property-function-variable-missing-source.js │ │ │ │ ├── file-property-function-variable.js │ │ │ │ ├── file-property-function.js │ │ │ │ ├── file-property-promise.js │ │ │ │ ├── file-variables-nest-1.yaml │ │ │ │ ├── file-variables-nest-2.yaml │ │ │ │ ├── file-variables-nest-3.yaml │ │ │ │ ├── file.cjs │ │ │ │ ├── file.js │ │ │ │ ├── file.json │ │ │ │ ├── file.tfstate │ │ │ │ ├── file.yaml │ │ │ │ ├── file.yml │ │ │ │ ├── invalid.js │ │ │ │ ├── invalid.json │ │ │ │ ├── invalid.yml │ │ │ │ ├── invalid2.js │ │ │ │ └── non-standard.ext │ │ │ │ ├── instance-dependent │ │ │ │ ├── get-aws.test.js │ │ │ │ ├── get-cf.test.js │ │ │ │ ├── get-s3.test.js │ │ │ │ ├── get-sls.test.js │ │ │ │ ├── get-ssm.test.js │ │ │ │ └── param.test.js │ │ │ │ ├── opt.test.js │ │ │ │ ├── resolve-external-plugin-resources.test.js │ │ │ │ ├── self.test.js │ │ │ │ └── str-to-bool.test.js │ │ ├── plugins │ │ │ ├── aws │ │ │ │ ├── common │ │ │ │ │ ├── index.test.js │ │ │ │ │ └── lib │ │ │ │ │ │ ├── artifacts.test.js │ │ │ │ │ │ └── cleanup-temp-dir.test.js │ │ │ │ ├── config-credentials.test.js │ │ │ │ ├── custom-resources │ │ │ │ │ ├── generate-zip.test.js │ │ │ │ │ ├── index.test.js │ │ │ │ │ └── test │ │ │ │ │ │ ├── eventBridge.test.js │ │ │ │ │ │ └── utils.test.js │ │ │ │ ├── deploy-function.test.js │ │ │ │ ├── deploy-list.test.js │ │ │ │ ├── deploy │ │ │ │ │ ├── index.test.js │ │ │ │ │ └── lib │ │ │ │ │ │ ├── check-for-changes.test.js │ │ │ │ │ │ ├── cleanup-s3-bucket.test.js │ │ │ │ │ │ ├── extended-validate.test.js │ │ │ │ │ │ ├── upload-artifacts.test.js │ │ │ │ │ │ └── validate-template.test.js │ │ │ │ ├── info │ │ │ │ │ ├── display.test.js │ │ │ │ │ ├── get-api-key-values.test.js │ │ │ │ │ ├── get-resource-count.test.js │ │ │ │ │ ├── get-stack-info.test.js │ │ │ │ │ └── index.test.js │ │ │ │ ├── invoke-local │ │ │ │ │ └── index.test.js │ │ │ │ ├── invoke.test.js │ │ │ │ ├── lib │ │ │ │ │ ├── get-service-state.test.js │ │ │ │ │ ├── monitor-stack.test.js │ │ │ │ │ ├── naming.test.js │ │ │ │ │ ├── normalize-files.test.js │ │ │ │ │ └── set-bucket-name.test.js │ │ │ │ ├── logs.test.js │ │ │ │ ├── metrics.test.js │ │ │ │ ├── package │ │ │ │ │ ├── compile │ │ │ │ │ │ ├── events │ │ │ │ │ │ │ ├── activemq.test.js │ │ │ │ │ │ │ ├── alb │ │ │ │ │ │ │ │ ├── index.test.js │ │ │ │ │ │ │ │ └── lib │ │ │ │ │ │ │ │ │ ├── health-check.test.js │ │ │ │ │ │ │ │ │ ├── listener-rules.test.js │ │ │ │ │ │ │ │ │ ├── permissions.test.js │ │ │ │ │ │ │ │ │ ├── target-groups.test.js │ │ │ │ │ │ │ │ │ └── validate.test.js │ │ │ │ │ │ │ ├── alexa-skill.test.js │ │ │ │ │ │ │ ├── alexa-smart-home.test.js │ │ │ │ │ │ │ ├── alias.test.js │ │ │ │ │ │ │ ├── api-gateway │ │ │ │ │ │ │ │ ├── index.test.js │ │ │ │ │ │ │ │ └── lib │ │ │ │ │ │ │ │ │ ├── api-keys.test.js │ │ │ │ │ │ │ │ │ ├── authorizers.test.js │ │ │ │ │ │ │ │ │ ├── cors.test.js │ │ │ │ │ │ │ │ │ ├── deployment.test.js │ │ │ │ │ │ │ │ │ ├── hack │ │ │ │ │ │ │ │ │ ├── disassociate-usage-plan.test.js │ │ │ │ │ │ │ │ │ └── update-stage.test.js │ │ │ │ │ │ │ │ │ ├── method │ │ │ │ │ │ │ │ │ ├── index.test.js │ │ │ │ │ │ │ │ │ └── request-parameters.test.js │ │ │ │ │ │ │ │ │ ├── permissions.test.js │ │ │ │ │ │ │ │ │ ├── request-validator.test.js │ │ │ │ │ │ │ │ │ ├── resources.test.js │ │ │ │ │ │ │ │ │ ├── rest-api.test.js │ │ │ │ │ │ │ │ │ ├── stage │ │ │ │ │ │ │ │ │ └── index.test.js │ │ │ │ │ │ │ │ │ ├── usage-plan-keys.test.js │ │ │ │ │ │ │ │ │ ├── usage-plan.test.js │ │ │ │ │ │ │ │ │ └── validate.test.js │ │ │ │ │ │ │ ├── cloud-front.test.js │ │ │ │ │ │ │ ├── cloud-watch-event.test.js │ │ │ │ │ │ │ ├── cloud-watch-log.test.js │ │ │ │ │ │ │ ├── cognito-user-pool.test.js │ │ │ │ │ │ │ ├── event-bridge │ │ │ │ │ │ │ │ └── index.test.js │ │ │ │ │ │ │ ├── http-api.test.js │ │ │ │ │ │ │ ├── iot-fleet-provisioning │ │ │ │ │ │ │ │ └── index.test.js │ │ │ │ │ │ │ ├── iot.test.js │ │ │ │ │ │ │ ├── kafka.test.js │ │ │ │ │ │ │ ├── lib │ │ │ │ │ │ │ │ └── ensure-api-gateway-cloud-watch-role.test.js │ │ │ │ │ │ │ ├── msk │ │ │ │ │ │ │ │ ├── get-msk-cluster-name-token.test.js │ │ │ │ │ │ │ │ └── index.test.js │ │ │ │ │ │ │ ├── rabbitmq.test.js │ │ │ │ │ │ │ ├── s3 │ │ │ │ │ │ │ │ └── index.test.js │ │ │ │ │ │ │ ├── schedule.test.js │ │ │ │ │ │ │ ├── sns.test.js │ │ │ │ │ │ │ ├── sqs.test.js │ │ │ │ │ │ │ ├── stream.test.js │ │ │ │ │ │ │ └── websockets │ │ │ │ │ │ │ │ ├── index.test.js │ │ │ │ │ │ │ │ └── lib │ │ │ │ │ │ │ │ ├── authorizers.test.js │ │ │ │ │ │ │ │ ├── deployment.test.js │ │ │ │ │ │ │ │ ├── integrations.test.js │ │ │ │ │ │ │ │ ├── permissions.test.js │ │ │ │ │ │ │ │ ├── pick-websockets-template-part.test.js │ │ │ │ │ │ │ │ ├── route-responses.test.js │ │ │ │ │ │ │ │ ├── routes.test.js │ │ │ │ │ │ │ │ ├── stage.test.js │ │ │ │ │ │ │ │ └── validate.test.js │ │ │ │ │ │ ├── functions.test.js │ │ │ │ │ │ └── layers.test.js │ │ │ │ │ ├── index.test.js │ │ │ │ │ └── lib │ │ │ │ │ │ ├── add-export-name-for-outputs.test.js │ │ │ │ │ │ ├── generate-artifact-directory-name.test.js │ │ │ │ │ │ ├── generate-core-template.test.js │ │ │ │ │ │ ├── get-hash-for-file-path.test.js │ │ │ │ │ │ ├── merge-custom-provider-resources.test.js │ │ │ │ │ │ ├── merge-iam-templates.test.js │ │ │ │ │ │ ├── save-compiled-template.test.js │ │ │ │ │ │ ├── save-service-state.test.js │ │ │ │ │ │ └── strip-null-props-from-template-resources.test.js │ │ │ │ ├── provider.test.js │ │ │ │ ├── remove │ │ │ │ │ ├── index.test.js │ │ │ │ │ └── lib │ │ │ │ │ │ └── stack.test.js │ │ │ │ ├── rollback-function.test.js │ │ │ │ ├── rollback.test.js │ │ │ │ └── utils │ │ │ │ │ ├── credentials.test.js │ │ │ │ │ ├── find-and-group-deployments.test.js │ │ │ │ │ ├── format-lambda-log-event.test.js │ │ │ │ │ ├── get-s3-endpoint-for-region.test.js │ │ │ │ │ ├── get-s3-objects-from-stacks.test.js │ │ │ │ │ ├── parse-s3-uri.test.js │ │ │ │ │ ├── resolve-cf-import-value.test.js │ │ │ │ │ ├── resolve-cf-ref-value.test.js │ │ │ │ │ └── resolve-lambda-target.test.js │ │ │ ├── config.test.js │ │ │ ├── create │ │ │ │ └── create.test.js │ │ │ ├── deploy.test.js │ │ │ ├── info.test.js │ │ │ ├── install.test.js │ │ │ ├── invoke.test.js │ │ │ ├── metrics.test.js │ │ │ ├── package │ │ │ │ ├── lib │ │ │ │ │ ├── package-service.test.js │ │ │ │ │ └── zip-service.test.js │ │ │ │ └── package.test.js │ │ │ ├── plugin │ │ │ │ ├── lib │ │ │ │ │ └── utils.test.js │ │ │ │ ├── list.test.js │ │ │ │ └── search.test.js │ │ │ ├── print.test.js │ │ │ ├── remove.test.js │ │ │ └── rollback.test.js │ │ ├── serverless-error.test.js │ │ ├── serverless.test.js │ │ ├── templates │ │ │ └── recommended-list.test.js │ │ └── utils │ │ │ ├── create-from-local-template.test.js │ │ │ ├── deep-sort-object-by-key.test.js │ │ │ ├── download-template-from-repo.test.js │ │ │ ├── ensure-artifact.test.js │ │ │ ├── ensure-exists.test.js │ │ │ ├── filesize.test.js │ │ │ ├── fs │ │ │ ├── copy-dir-contents-sync.test.js │ │ │ ├── create-zip-file.test.js │ │ │ ├── file-exists-sync.test.js │ │ │ ├── file-exists.test.js │ │ │ ├── get-tmp-dir-path.test.js │ │ │ ├── parse.test.js │ │ │ ├── read-file-sync.test.js │ │ │ ├── read-file.test.js │ │ │ ├── safe-move-file.test.js │ │ │ ├── walk-dir-sync.test.js │ │ │ ├── write-file-sync.test.js │ │ │ └── write-file.test.js │ │ │ ├── log-deprecation.test.js │ │ │ ├── rename-service.test.js │ │ │ ├── resolve-region.test.js │ │ │ ├── resolve-stage.test.js │ │ │ ├── standalone.test.js │ │ │ ├── tokenize-exception.test.js │ │ │ └── yaml-ast-parser.test.js │ └── scripts │ │ └── serverless.test.js └── utils │ ├── api-gateway.js │ ├── aws-cleanup.js │ ├── child-process.js │ ├── cloudformation.js │ ├── cognito.js │ ├── dynamodb.js │ ├── event-bridge.js │ ├── fs.js │ ├── integration.js │ ├── iot.js │ ├── kinesis.js │ ├── misc.js │ ├── plugins.js │ ├── run-serverless.js │ ├── s3.js │ ├── sns.js │ ├── sqs.js │ └── websocket.js └── types └── index.d.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true ; top-most EditorConfig file 2 | 3 | ; Unix-style newlines with a newline ending every file 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.github/prepare-canary.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict'; 4 | 5 | const fs = require('fs'); 6 | const path = require('path'); 7 | 8 | const packageJsonPath = path.resolve(__dirname, '../package.json'); 9 | 10 | const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); 11 | 12 | packageJson.version = `${packageJson.version}-${process.env.GITHUB_SHA.slice(0, 8)}`; 13 | packageJson.dependencies['@serverless/dashboard-plugin'] = 'canary'; 14 | 15 | fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`); 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.eslintcache 2 | /dist 3 | /node_modules 4 | npm-debug.log 5 | /package-lock.json 6 | /yarn.lock 7 | **/.DS_Store 8 | bun.lockb 9 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /.github 2 | /.editorconfig 3 | /.prettierignore 4 | /CODE_OF_CONDUCT.md 5 | /CONTRIBUTING.md 6 | /docker-compose.yml 7 | /Dockerfile 8 | /prettier.config.js 9 | /RELEASE_PROCESS.md 10 | /scripts/pkg 11 | /scripts/test 12 | /test 13 | /VERSIONING.md 14 | !/lib/plugins/create/templates/**/.gitignore 15 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /test/fixtures/cli/config-syntax-error/serverless.yml 2 | /test/unit/lib/configuration/variables/sources/fixture/invalid.json 3 | /test/unit/lib/configuration/variables/sources/fixture/invalid.yml 4 | !/test/fixtures/programmatic/locallyInstalledServerless/node_modules/** 5 | -------------------------------------------------------------------------------- /RELEASE_PROCESS.md: -------------------------------------------------------------------------------- 1 | # Release process 2 | 3 | 1. Push to `main` 4 | 2. Tag a release in GitHub 5 | -------------------------------------------------------------------------------- /commands/doctor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fsp = require('fs').promises; 4 | const { writeText, log } = require('@serverless/utils/log'); 5 | const healthStatusFilename = require('../lib/utils/health-status-filename'); 6 | 7 | module.exports = async () => { 8 | const healthStatus = await (async () => { 9 | try { 10 | return await fsp.readFile(healthStatusFilename); 11 | } catch (error) { 12 | if (error.code === 'ENOENT') return null; 13 | throw error; 14 | } 15 | })(); 16 | 17 | if (healthStatus) writeText(healthStatus); 18 | else log.notice('No deprecations were reported in the last command'); 19 | }; 20 | -------------------------------------------------------------------------------- /docs/cli-reference/deploy-list.md: -------------------------------------------------------------------------------- 1 | # AWS - Deploy List 2 | 3 | The `sls deploy list [functions]` command will list information about your deployments. 4 | 5 | You can either see all available deployments in your S3 deployment bucket by running `serverless deploy list` or you can see the deployed functions by running `serverless deploy list functions`. 6 | 7 | The displayed information is useful when rolling back a deployment or function via `serverless rollback`. 8 | 9 | ## Options 10 | 11 | - `--stage` or `-s` The stage in your service that you want to deploy to. 12 | - `--region` or `-r` The region in that stage that you want to deploy to. 13 | 14 | ## Examples 15 | 16 | ### List existing deploys 17 | 18 | ```bash 19 | serverless deploy list 20 | ``` 21 | 22 | ### List deployed functions and their versions 23 | 24 | ```bash 25 | serverless deploy list functions 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/cli-reference/plugin-install.md: -------------------------------------------------------------------------------- 1 | # Plugin Install 2 | 3 | Install a Serverless plugin and add it to the services `plugins` array. By default, a latest version is installed. 4 | If you want a specific version, you can specify `@` as name option. 5 | 6 | **Note:** You might want to change the order of the plugin in the services `plugins` array. 7 | 8 | ```bash 9 | serverless plugin install --name pluginName 10 | ``` 11 | 12 | ## Options 13 | 14 | - `--name` or `-n` The plugins name. **Required**. 15 | 16 | ## Provided lifecycle events 17 | 18 | - `plugin:install:install` 19 | 20 | ## Examples 21 | 22 | ### Install the `serverless-webpack` plugin 23 | 24 | ```bash 25 | serverless plugin install --name serverless-webpack 26 | ``` 27 | 28 | ### Install a specific version 29 | 30 | ```bash 31 | serverless plugin install --name serverless-webpack@3.0.0-rc.2 32 | ``` 33 | -------------------------------------------------------------------------------- /docs/cli-reference/plugin-list.md: -------------------------------------------------------------------------------- 1 | # Plugin List 2 | 3 | List all available plugins on the terminal. Connected to the [Serverless plugin registry](https://github.com/serverless/plugins). 4 | 5 | ```bash 6 | serverless plugin list 7 | ``` 8 | 9 | ## Options 10 | 11 | - _None_ 12 | 13 | ## Provided lifecycle events 14 | 15 | - `plugin:list:list` 16 | -------------------------------------------------------------------------------- /docs/cli-reference/plugin-search.md: -------------------------------------------------------------------------------- 1 | # Plugin Search 2 | 3 | Search for a specific plugin based on a search query. Connected to the [Serverless plugin registry](https://github.com/serverless/plugins). 4 | 5 | ```bash 6 | serverless plugin search --query query 7 | ``` 8 | 9 | ## Options 10 | 11 | - `--query` or `-q` The query you want to use for your search. **Required**. 12 | 13 | ## Provided lifecycle events 14 | 15 | - `plugin:search:search` 16 | 17 | ## Examples 18 | 19 | ### Search for a `sqs` plugin 20 | 21 | ```bash 22 | serverless plugin search --query sqs 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/cli-reference/plugin-uninstall.md: -------------------------------------------------------------------------------- 1 | # Plugin Uninstall 2 | 3 | Uninstall a Serverless plugin and remove it from the services `plugins` array. 4 | 5 | ```bash 6 | serverless plugin uninstall --name pluginName 7 | ``` 8 | 9 | ## Options 10 | 11 | - `--name` or `-n` The plugins name. **Required**. 12 | 13 | ## Provided lifecycle events 14 | 15 | - `plugin:uninstall:uninstall` 16 | 17 | ## Examples 18 | 19 | ### Remove the `serverless-webpack` plugin 20 | 21 | ```bash 22 | serverless plugin uninstall --name serverless-webpack 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/cli-reference/remove.md: -------------------------------------------------------------------------------- 1 | # AWS - Remove 2 | 3 | The `sls remove` command will remove the deployed service, defined in your current working directory, from the provider. 4 | 5 | ```bash 6 | serverless remove 7 | ``` 8 | 9 | ## Options 10 | 11 | - `--stage` or `-s` The name of the stage in service. 12 | - `--region` or `-r` The name of the region in stage. 13 | - `--verbose` Shows all stack events during deployment. 14 | 15 | ## Provided lifecycle events 16 | 17 | - `remove:remove` 18 | 19 | ## Examples 20 | 21 | ### Removal of service in specific stage and region 22 | 23 | ```bash 24 | serverless remove --stage dev --region us-east-1 25 | ``` 26 | 27 | This example will remove the deployed service of your current working directory with the stage `dev` and the region `us-east-1`. 28 | -------------------------------------------------------------------------------- /docs/events/README.md: -------------------------------------------------------------------------------- 1 | # Serverless AWS Lambda Events 2 | 3 | Welcome to the AWS Serverless Events Glossary. 4 | 5 | Please select a section on the left to get started, or see the [user 6 | guide](../guides/events.md) for general information regarding Lambda Events in 7 | Serverless. 8 | -------------------------------------------------------------------------------- /lib/aws/has-local-credentials.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const AWS = require('./sdk-v2'); 4 | 5 | module.exports = () => { 6 | return Boolean(new AWS.S3().config.credentials); 7 | }; 8 | -------------------------------------------------------------------------------- /lib/aws/sdk-v2.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | process.env.AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE = 1; 4 | 5 | require('aws-sdk/lib/maintenance_mode_message').suppress = true; 6 | 7 | module.exports = require('aws-sdk'); 8 | -------------------------------------------------------------------------------- /lib/aws/set-s3-upload-encryption-options.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = (putParams, deploymentBucketOptions) => { 4 | const encryptionFields = [ 5 | ['serverSideEncryption', 'ServerSideEncryption'], 6 | ['sseCustomerAlgorithim', 'SSECustomerAlgorithm'], 7 | ['sseCustomerKey', 'SSECustomerKey'], 8 | ['sseCustomerKeyMD5', 'SSECustomerKeyMD5'], 9 | ['sseKMSKeyId', 'SSEKMSKeyId'], 10 | ]; 11 | 12 | const params = putParams; 13 | 14 | encryptionFields.forEach((element) => { 15 | if (deploymentBucketOptions[element[0]]) { 16 | params[element[1]] = deploymentBucketOptions[element[0]]; 17 | } 18 | }); 19 | 20 | return params; 21 | }; 22 | -------------------------------------------------------------------------------- /lib/classes/config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | const path = require('path'); 5 | 6 | class Config { 7 | constructor(serverless, config) { 8 | this.serverless = serverless; 9 | this.serverlessPath = path.join(__dirname, '..'); 10 | 11 | if (config) this.update(config); 12 | } 13 | 14 | update(config) { 15 | return _.merge(this, config); 16 | } 17 | 18 | get servicePath() { 19 | return this.serverless.serviceDir; 20 | } 21 | 22 | set servicePath(value) { 23 | this.serverless.serviceDir = value; 24 | } 25 | } 26 | 27 | module.exports = Config; 28 | -------------------------------------------------------------------------------- /lib/classes/yaml-parser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const yaml = require('js-yaml'); 4 | const resolve = require('json-refs').resolveRefs; 5 | 6 | class YamlParser { 7 | constructor(serverless) { 8 | this.serverless = serverless; 9 | } 10 | 11 | async parse(yamlFilePath) { 12 | const root = this.serverless.utils.readFileSync(yamlFilePath); 13 | const options = { 14 | filter: ['relative', 'remote'], 15 | loaderOptions: { 16 | processContent: (res, callback) => { 17 | callback(null, yaml.load(res.text)); 18 | }, 19 | }, 20 | location: yamlFilePath, 21 | }; 22 | return resolve(root, options).then((res) => res.resolved); 23 | } 24 | } 25 | 26 | module.exports = YamlParser; 27 | -------------------------------------------------------------------------------- /lib/cli/commands-schema/common-options/aws-service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | 'region': { 5 | usage: 'Region of the service', 6 | shortcut: 'r', 7 | }, 8 | 'aws-profile': { 9 | usage: 'AWS profile to use with the command', 10 | }, 11 | ...require('./service'), 12 | }; 13 | 14 | for (const optionSchema of Object.values(module.exports)) { 15 | if (!optionSchema.type) optionSchema.type = 'string'; 16 | } 17 | -------------------------------------------------------------------------------- /lib/cli/commands-schema/common-options/global.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | help: { usage: 'Show this message', shortcut: 'h', type: 'boolean' }, 5 | version: { usage: 'Show version info', shortcut: 'v', type: 'boolean' }, 6 | verbose: { usage: 'Show verbose logs', type: 'boolean' }, 7 | debug: { usage: 'Namespace of debug logs to expose (use "*" to display all)', type: 'string' }, 8 | }; 9 | 10 | for (const optionSchema of Object.values(module.exports)) { 11 | if (!optionSchema.type) optionSchema.type = 'string'; 12 | } 13 | -------------------------------------------------------------------------------- /lib/cli/commands-schema/common-options/service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | config: { 5 | usage: 'Path to serverless config file', 6 | shortcut: 'c', 7 | }, 8 | stage: { 9 | usage: 'Stage of the service', 10 | shortcut: 's', 11 | }, 12 | param: { 13 | usage: 'Pass custom parameter values for "param" variable source (usage: --param="key=value")', 14 | type: 'multiple', 15 | }, 16 | ...require('./global'), 17 | }; 18 | 19 | for (const optionSchema of Object.values(module.exports)) { 20 | if (!optionSchema.type) optionSchema.type = 'string'; 21 | } 22 | -------------------------------------------------------------------------------- /lib/cli/commands-schema/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('./aws-service'); 4 | -------------------------------------------------------------------------------- /lib/cli/conditionally-load-dotenv.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | 5 | module.exports = async (options, configuration) => { 6 | const stage = options.stage || _.get(configuration, 'provider.stage', 'dev'); 7 | if (!configuration.useDotenv) return false; 8 | require('./load-dotenv')(stage); 9 | return true; 10 | }; 11 | -------------------------------------------------------------------------------- /lib/cli/filter-supported-options.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const serviceOptionsNames = Object.keys(require('./commands-schema/common-options/service')); 4 | const awsServiceOptionsNames = Object.keys(require('./commands-schema/common-options/aws-service')); 5 | 6 | module.exports = (options, { commandSchema, providerName }) => { 7 | const supportedNames = (() => { 8 | if (commandSchema) return Object.keys(commandSchema.options); 9 | return providerName === 'aws' ? awsServiceOptionsNames : serviceOptionsNames; 10 | })(); 11 | const result = Object.create(null); 12 | for (const name of supportedNames) result[name] = options[name] == null ? null : options[name]; 13 | return result; 14 | }; 15 | -------------------------------------------------------------------------------- /lib/cli/is-locally-installed.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const localServerlessPath = require('./local-serverless-path'); 5 | 6 | module.exports = localServerlessPath === path.resolve(__dirname, '../../'); 7 | -------------------------------------------------------------------------------- /lib/cli/local-serverless-path.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This module should be dependencies free (as it's used at local fallback triage) 4 | // and kept async (as telemetry payload generation depends on it) 5 | 6 | const path = require('path'); 7 | const { createRequire } = require('module'); 8 | 9 | try { 10 | module.exports = path.resolve( 11 | path.dirname( 12 | createRequire(path.resolve(process.cwd(), 'require-resolver')).resolve('serverless') 13 | ), 14 | '..' 15 | ); 16 | } catch { 17 | module.exports = null; 18 | } 19 | -------------------------------------------------------------------------------- /lib/cli/param-reg-exp.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = 4 | /^-(?:-(?[a-zA-Z][A-Za-z0-9:_-]+)|(?[a-z]+))(?:=(?.*)|$)/; 5 | -------------------------------------------------------------------------------- /lib/cli/render-help/command.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { writeText } = require('@serverless/utils/log'); 4 | const resolveInput = require('../resolve-input'); 5 | const renderOptionsHelp = require('./options'); 6 | 7 | const generateCommandUsage = require('./generate-command-usage'); 8 | 9 | module.exports = (commandName) => { 10 | const { commandsSchema } = resolveInput(); 11 | const commandSchema = commandsSchema.get(commandName); 12 | 13 | if (commandSchema) { 14 | writeText(generateCommandUsage(commandName, commandSchema)); 15 | } 16 | for (const [subCommandName, subCommandSchema] of commandsSchema) { 17 | if (!subCommandName.startsWith(`${commandName} `)) continue; 18 | writeText(generateCommandUsage(subCommandName, subCommandSchema)); 19 | } 20 | if (commandSchema) renderOptionsHelp(Object.assign({}, commandSchema.options)); 21 | 22 | writeText(); 23 | }; 24 | -------------------------------------------------------------------------------- /lib/cli/render-help/generate-command-usage.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { style } = require('@serverless/utils/log'); 4 | 5 | module.exports = (commandName, commandSchema) => { 6 | const indentFillLength = 30; 7 | 8 | const usage = commandSchema.usage; 9 | return `${commandName} ${' '.repeat( 10 | Math.max(indentFillLength - commandName.length, 0) 11 | )} ${style.aside(usage)}`; 12 | }; 13 | -------------------------------------------------------------------------------- /lib/cli/render-help/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const resolveInput = require('../resolve-input'); 4 | const renderGeneralHelp = require('./general'); 5 | const renderCommandHelp = require('./command'); 6 | 7 | module.exports = (loadedPlugins) => { 8 | const { command } = resolveInput(); 9 | if (!command) { 10 | renderGeneralHelp(loadedPlugins); 11 | } else if (command === 'help') { 12 | renderGeneralHelp(loadedPlugins); 13 | } else { 14 | renderCommandHelp(command); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /lib/cli/write-service-outputs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { writeText, style } = require('@serverless/utils/log'); 4 | 5 | module.exports = (serviceOutputs) => { 6 | for (const [section, entries] of serviceOutputs) { 7 | if (typeof entries === 'string') { 8 | writeText(`${style.aside(`${section}:`)} ${entries}`); 9 | } else { 10 | writeText(`${style.aside(`${section}:\n`)} ${entries.join('\n ')}`); 11 | } 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /lib/configuration/resolve-provider-name.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const ensureString = require('type/string/ensure'); 4 | const isObject = require('type/object/is'); 5 | const ServerlessError = require('../serverless-error'); 6 | const resolveCliInput = require('../cli/resolve-input'); 7 | 8 | module.exports = (configuration) => { 9 | try { 10 | return ensureString( 11 | isObject(configuration.provider) ? configuration.provider.name : configuration.provider, 12 | { 13 | Error: ServerlessError, 14 | errorMessage: 'Invalid service configuration: "provider.name" property is missing', 15 | errorCode: 'INVALID_CONFIGURATION_PROVIDER_NAME_MISSING', 16 | } 17 | ); 18 | } catch (error) { 19 | if (resolveCliInput().isHelpRequest) return null; 20 | throw error; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /lib/configuration/variables/humanize-property-path-keys.js: -------------------------------------------------------------------------------- 1 | // Stringify property keys array for user facing message 2 | 3 | 'use strict'; 4 | 5 | module.exports = (propertyPathKeys) => { 6 | const rootProperty = propertyPathKeys[0]; 7 | if (propertyPathKeys.length === 1) return rootProperty; 8 | return `${rootProperty}.${propertyPathKeys.slice(1).join('.')}`; 9 | }; 10 | -------------------------------------------------------------------------------- /lib/configuration/variables/is-property-resolved.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = (variablesMeta, propertyPath) => { 4 | const propertyPathKeys = propertyPath.split('\0'); 5 | let propertyPathPart = propertyPathKeys.shift(); 6 | while (propertyPathKeys[0]) { 7 | if (variablesMeta.has(propertyPathPart)) return false; 8 | propertyPathPart += `\0${propertyPathKeys.shift()}`; 9 | } 10 | if (variablesMeta.has(propertyPathPart)) return false; 11 | 12 | for (const variablePropertyPath of variablesMeta.keys()) { 13 | if (variablePropertyPath.startsWith(`${propertyPath}\0`)) return false; 14 | } 15 | return true; 16 | }; 17 | -------------------------------------------------------------------------------- /lib/configuration/variables/source-resolution-error.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class VariableSourceResolutionError extends Error { 4 | constructor(message, code) { 5 | super(message); 6 | this.code = code; 7 | } 8 | } 9 | 10 | Object.defineProperty(VariableSourceResolutionError.prototype, 'name', { 11 | value: VariableSourceResolutionError.name, 12 | configurable: true, 13 | writable: true, 14 | }); 15 | 16 | module.exports = VariableSourceResolutionError; 17 | -------------------------------------------------------------------------------- /lib/configuration/variables/sources/opt.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const ensureString = require('type/string/ensure'); 4 | const ServerlessError = require('../../../serverless-error'); 5 | 6 | module.exports = { 7 | resolve: ({ address, options, isSourceFulfilled }) => { 8 | address = ensureString(address, { 9 | isOptional: true, 10 | Error: ServerlessError, 11 | errorMessage: 'Non-string address argument in variable "opt" source: %v', 12 | errorCode: 'INVALID_OPT_SOURCE_ADDRESS', 13 | }); 14 | if (!isSourceFulfilled) { 15 | if (address == null) return { value: null, isPending: true }; 16 | if (options[address] !== undefined) return { value: options[address] }; 17 | return { value: null, isPending: true }; 18 | } 19 | 20 | if (address == null) return { value: options }; 21 | 22 | return { value: options[address] == null ? null : options[address] }; 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /lib/configuration/variables/sources/self.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | resolve: async ({ address, resolveConfigurationProperty }) => { 5 | const result = await resolveConfigurationProperty(address ? address.split('.') : []); 6 | return { value: result == null ? null : result }; 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /lib/plugins/aws/common/lib/cleanup-temp-dir.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fse = require('fs-extra'); 5 | 6 | module.exports = { 7 | async cleanupTempDir() { 8 | if (this.serverless.serviceDir) { 9 | const serverlessTmpDirPath = path.join(this.serverless.serviceDir, '.serverless'); 10 | 11 | if (this.serverless.utils.dirExistsSync(serverlessTmpDirPath)) { 12 | fse.removeSync(serverlessTmpDirPath); 13 | } 14 | } 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /lib/plugins/aws/custom-resources/resources/README.md: -------------------------------------------------------------------------------- 1 | # Serverless Custom CloudFormation Resources 2 | 3 | This directory contains the Lambda functions for the Serverless Custom CloudFormation Resources. 4 | -------------------------------------------------------------------------------- /lib/plugins/aws/custom-resources/resources/event-bridge/lib/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const crypto = require('crypto'); 4 | 5 | function getEventBusName(eventBus) { 6 | if (eventBus && eventBus.startsWith('arn')) { 7 | return eventBus.slice(eventBus.indexOf('/') + 1); 8 | } 9 | return eventBus; 10 | } 11 | 12 | function getEventBusTargetId(ruleName) { 13 | const targetIdSuffix = 'target'; 14 | let targetId = `${ruleName}-${targetIdSuffix}`; 15 | if (targetId.length > 64) { 16 | // Target ids cannot be longer than 64. 17 | targetId = `${targetId.slice(0, 31 - targetIdSuffix.length)}${crypto 18 | .createHash('md5') 19 | .update(targetId) 20 | .digest('hex')}-${targetIdSuffix}`; 21 | } 22 | 23 | return targetId; 24 | } 25 | 26 | module.exports = { 27 | getEventBusName, 28 | getEventBusTargetId, 29 | }; 30 | -------------------------------------------------------------------------------- /lib/plugins/aws/info/get-resource-count.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const BbPromise = require('bluebird'); 4 | 5 | module.exports = { 6 | async getResourceCount(nextToken, resourceCount = 0) { 7 | const params = { 8 | StackName: this.provider.naming.getStackName(), 9 | NextToken: nextToken, 10 | }; 11 | return this.provider.request('CloudFormation', 'listStackResources', params).then((result) => { 12 | if (Object.keys(result).length) { 13 | this.gatheredData.info.resourceCount = resourceCount + result.StackResourceSummaries.length; 14 | if (result.NextToken) { 15 | return this.getResourceCount(result.NextToken, this.gatheredData.info.resourceCount); 16 | } 17 | } 18 | return BbPromise.resolve(); 19 | }); 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | runtime-wrappers/java/target 3 | runtime-wrappers/java/.project 4 | runtime-wrappers/java/.settings 5 | runtime-wrappers/java/.classpath 6 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/MANIFEST.mf: -------------------------------------------------------------------------------- 1 | Manifest-version: 1.0 2 | Main-Class: com.serverless.InvokeBridge 3 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/main/java/com/serverless/LambdaLogger.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import java.io.IOException; 4 | 5 | public class LambdaLogger implements com.amazonaws.services.lambda.runtime.LambdaLogger { 6 | 7 | @Override 8 | public void log(String message) { 9 | System.out.println(message); 10 | } 11 | 12 | @Override 13 | public void log(byte[] message) { 14 | try { 15 | System.out.write(message); 16 | } catch (IOException e) { 17 | // I guess never happen on AWS lambda 18 | e.printStackTrace(); 19 | } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/main/java/com/serverless/mapper/AbstractMapper.java: -------------------------------------------------------------------------------- 1 | package com.serverless.mapper; 2 | 3 | public abstract class AbstractMapper implements Mapper { 4 | protected final Class targetClass; 5 | 6 | public AbstractMapper(Class targetClass) { 7 | this.targetClass = targetClass; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/main/java/com/serverless/mapper/HashMapWrapper.java: -------------------------------------------------------------------------------- 1 | package com.serverless.mapper; 2 | 3 | import java.util.HashMap; 4 | 5 | public class HashMapWrapper { 6 | private final HashMap hashMap; 7 | 8 | public HashMapWrapper(HashMap hashMap) { 9 | this.hashMap = hashMap; 10 | } 11 | 12 | public String getAsString(String key) { 13 | return String.class.cast(hashMap.get(key)); 14 | } 15 | 16 | public Long getAsLong(String key) { 17 | Object o = hashMap.get(key); 18 | if (o instanceof Integer) { 19 | return new Long(Integer.class.cast(o).longValue()); 20 | } else { 21 | return Long.class.cast(o); 22 | } 23 | } 24 | 25 | public HashMapWrapper getAsHashMapWrapper(String key) { 26 | return new HashMapWrapper(HashMap.class.cast(hashMap.get(key))); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/main/java/com/serverless/mapper/Mapper.java: -------------------------------------------------------------------------------- 1 | package com.serverless.mapper; 2 | 3 | import java.util.HashMap; 4 | 5 | public interface Mapper { 6 | Object read(HashMap event) throws Exception; 7 | } 8 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/AbstractRequestHandler.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import java.util.Map; 4 | 5 | import com.amazonaws.services.lambda.runtime.Context; 6 | 7 | public abstract class AbstractRequestHandler 8 | implements com.amazonaws.services.lambda.runtime.RequestHandler, Object> { 9 | 10 | abstract Object handleMe(); 11 | 12 | @Override 13 | public Object handleRequest(Map stringObjectMap, Context context) { 14 | return "Parent Complete.|" + handleMe(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/ConcreteRequestHandler.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | public class ConcreteRequestHandler extends AbstractRequestHandler { 4 | 5 | @Override 6 | Object handleMe() { 7 | return "Child Complete."; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/InvokeBridgeInheritanceTest.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | 6 | public class InvokeBridgeInheritanceTest { 7 | @Before 8 | public void before() { 9 | System.setProperty("artifactPath", "target/test-classes/com/serverless/ConcreteRequestHandler.class"); 10 | System.setProperty("className", "com.serverless.ConcreteRequestHandler"); 11 | System.setProperty("handlerName", "handleRequest"); 12 | } 13 | 14 | @Test 15 | public void verifyInvoke() { 16 | System.setIn(getClass().getResourceAsStream("/test.json")); 17 | InvokeBridge.main(new String[] {}); 18 | // Nothing to verify, if this doesn't throw NoSuchMethodException, we are good. 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandler.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import java.util.Map; 4 | 5 | import com.amazonaws.services.lambda.runtime.Context; 6 | 7 | public class RequestHandler 8 | implements com.amazonaws.services.lambda.runtime.RequestHandler, Object> { 9 | static Map input; 10 | 11 | @Override 12 | public Object handleRequest(Map stringObjectMap, Context context) { 13 | input = stringObjectMap; 14 | System.out.println("Input received:" + input); 15 | return "RequestHandler invoke Complete."; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandlerCloudFrontEvent.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import com.amazonaws.services.lambda.runtime.Context; 4 | import com.amazonaws.services.lambda.runtime.RequestHandler; 5 | import com.amazonaws.services.lambda.runtime.events.CloudFrontEvent; 6 | 7 | public class RequestHandlerCloudFrontEvent implements RequestHandler { 8 | public static CloudFrontEvent input; 9 | 10 | @Override 11 | public Object handleRequest(CloudFrontEvent event, Context context) { 12 | input = event; 13 | System.out.println("Input received:" + event.toString()); 14 | return "RequesHandlerCloudFrontEvent invoke Complete."; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandlerCodeCommitEvent.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import com.amazonaws.services.lambda.runtime.Context; 4 | import com.amazonaws.services.lambda.runtime.RequestHandler; 5 | import com.amazonaws.services.lambda.runtime.events.CodeCommitEvent; 6 | 7 | public class RequestHandlerCodeCommitEvent implements RequestHandler { 8 | public static CodeCommitEvent input; 9 | 10 | @Override 11 | public Object handleRequest(CodeCommitEvent event, Context context) { 12 | input = event; 13 | System.out.println("Input received:" + event.toString()); 14 | return "RequesHandlerCodeCommitEvent invoke Complete."; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandlerCognitoEvent.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import com.amazonaws.services.lambda.runtime.Context; 4 | import com.amazonaws.services.lambda.runtime.RequestHandler; 5 | import com.amazonaws.services.lambda.runtime.events.CognitoEvent; 6 | 7 | public class RequestHandlerCognitoEvent implements RequestHandler { 8 | public static CognitoEvent input; 9 | 10 | @Override 11 | public Object handleRequest(CognitoEvent event, Context context) { 12 | input = event; 13 | System.out.println("Input received:" + event.toString()); 14 | return "RequesHandlerCognitoEvent invoke Complete."; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandlerConfigEvent.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import com.amazonaws.services.lambda.runtime.Context; 4 | import com.amazonaws.services.lambda.runtime.RequestHandler; 5 | import com.amazonaws.services.lambda.runtime.events.ConfigEvent; 6 | 7 | public class RequestHandlerConfigEvent implements RequestHandler { 8 | public static ConfigEvent input; 9 | 10 | @Override 11 | public Object handleRequest(ConfigEvent event, Context context) { 12 | input = event; 13 | System.out.println("Input received:" + event.toString()); 14 | return "RequesHandlerConfigEvent invoke Complete."; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandlerDynamodbEvent.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import com.amazonaws.services.lambda.runtime.Context; 4 | import com.amazonaws.services.lambda.runtime.RequestHandler; 5 | import com.amazonaws.services.lambda.runtime.events.DynamodbEvent; 6 | 7 | public class RequestHandlerDynamodbEvent implements RequestHandler { 8 | public static DynamodbEvent input; 9 | 10 | @Override 11 | public Object handleRequest(DynamodbEvent event, Context context) { 12 | input = event; 13 | System.out.println("Input received:" + event.toString()); 14 | return "RequesHandlerDynamodbEvent invoke Complete."; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandlerIoTButtonEvent.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import com.amazonaws.services.lambda.runtime.Context; 4 | import com.amazonaws.services.lambda.runtime.RequestHandler; 5 | import com.amazonaws.services.lambda.runtime.events.IoTButtonEvent; 6 | 7 | public class RequestHandlerIoTButtonEvent implements RequestHandler { 8 | 9 | public static IoTButtonEvent input; 10 | 11 | @Override 12 | public Object handleRequest(IoTButtonEvent event, Context context) { 13 | input = event; 14 | System.out.println("Input received:" + event.toString()); 15 | return "RequesHandlerIoTButtonEvent invoke Complete."; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandlerKinesisEvent.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import com.amazonaws.services.lambda.runtime.Context; 4 | import com.amazonaws.services.lambda.runtime.RequestHandler; 5 | import com.amazonaws.services.lambda.runtime.events.KinesisEvent; 6 | 7 | public class RequestHandlerKinesisEvent implements RequestHandler { 8 | public static KinesisEvent input; 9 | 10 | @Override 11 | public Object handleRequest(KinesisEvent event, Context context) { 12 | input = event; 13 | System.out.println("Input received:" + event.toString()); 14 | return "RequesHandlerKinesisEvent invoke Complete."; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandlerKinesisFirehoseEvent.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import com.amazonaws.services.lambda.runtime.Context; 4 | import com.amazonaws.services.lambda.runtime.RequestHandler; 5 | import com.amazonaws.services.lambda.runtime.events.KinesisFirehoseEvent; 6 | 7 | public class RequestHandlerKinesisFirehoseEvent 8 | implements RequestHandler { 9 | public static KinesisFirehoseEvent input; 10 | 11 | @Override 12 | public Object handleRequest(KinesisFirehoseEvent event, Context context) { 13 | input = event; 14 | System.out.println("Input received:" + event.toString()); 15 | return "RequesHandlerKinesisFirehoseEvent invoke Complete."; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandlerLexEvent.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import com.amazonaws.services.lambda.runtime.Context; 4 | import com.amazonaws.services.lambda.runtime.RequestHandler; 5 | import com.amazonaws.services.lambda.runtime.events.LexEvent; 6 | 7 | public class RequestHandlerLexEvent implements RequestHandler { 8 | public static LexEvent input; 9 | 10 | @Override 11 | public Object handleRequest(LexEvent event, Context context) { 12 | input = event; 13 | System.out.println("Input received:" + event.toString()); 14 | return "RequesHandlerLexEvent invoke Complete."; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandlerSNSEvent.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import com.amazonaws.services.lambda.runtime.Context; 4 | import com.amazonaws.services.lambda.runtime.RequestHandler; 5 | import com.amazonaws.services.lambda.runtime.events.SNSEvent; 6 | 7 | public class RequestHandlerSNSEvent implements RequestHandler { 8 | public static SNSEvent input; 9 | 10 | @Override 11 | public Object handleRequest(SNSEvent event, Context context) { 12 | input = event; 13 | System.out.println("Input received:" + event.toString()); 14 | return "RequesHandlerSNSEvent invoke Complete."; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandlerSQSEvent.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import com.amazonaws.services.lambda.runtime.Context; 4 | import com.amazonaws.services.lambda.runtime.RequestHandler; 5 | import com.amazonaws.services.lambda.runtime.events.SQSEvent; 6 | 7 | public class RequestHandlerSQSEvent implements RequestHandler { 8 | public static SQSEvent input; 9 | 10 | @Override 11 | public Object handleRequest(SQSEvent event, Context context) { 12 | input = event; 13 | System.out.println("Input received:" + event.toString()); 14 | return "RequesHandlerSQSEvent invoke Complete."; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/java/com/serverless/RequestHandlerScheduledEvent.java: -------------------------------------------------------------------------------- 1 | package com.serverless; 2 | 3 | import com.amazonaws.services.lambda.runtime.Context; 4 | import com.amazonaws.services.lambda.runtime.RequestHandler; 5 | import com.amazonaws.services.lambda.runtime.events.ScheduledEvent; 6 | 7 | public class RequestHandlerScheduledEvent implements RequestHandler { 8 | public static ScheduledEvent input; 9 | 10 | @Override 11 | public Object handleRequest(ScheduledEvent event, Context context) { 12 | input = event; 13 | System.out.println("Input received:" + event.toString()); 14 | return "RequesHandlerScheduledEvent invoke Complete."; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/resources/cloud-front-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "context": {}, 3 | "event": { 4 | "Records": [ 5 | { 6 | "cf": { 7 | "config": { 8 | "distributionId": "EXAMPLEDISTID" 9 | }, 10 | "request": { 11 | "clientIp": "192.168.0.1", 12 | "method": "GET", 13 | "uri": "/picture.jpg", 14 | "headers": { 15 | "host": [ 16 | { 17 | "key": "Host", 18 | "value": "MYCFHOST.cloudfront.net" 19 | } 20 | ], 21 | "user-agent": [ 22 | { 23 | "key": "User-Agent", 24 | "value": "curl/7.64.1" 25 | } 26 | ] 27 | } 28 | } 29 | } 30 | } 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/resources/cloud-watch-logs-event-decoded.json: -------------------------------------------------------------------------------- 1 | { 2 | "messageType": "DATA_MESSAGE", 3 | "owner": "123456789012", 4 | "logGroup": "/aws/lambda/hello", 5 | "logStream": "2020/07/19/[$LATEST]1234567890abcded1234567890abcdef", 6 | "subscriptionFilters": ["LambdaStream_cloudwatchlogs-hello"], 7 | "logEvents": [ 8 | { 9 | "id": "12345678901234567890123456789012345678901234567890123456", 10 | "timestamp": 1595030400, 11 | "message": "Hello" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/resources/cloud-watch-logs-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "context": {}, 3 | "event": { 4 | "awslogs": { 5 | "data": "ewogICJtZXNzYWdlVHlwZSI6ICJEQVRBX01FU1NBR0UiLAogICJvd25lciI6ICIxMjM0NTY3ODkwMTIiLAogICJsb2dHcm91cCI6ICIvYXdzL2xhbWJkYS9oZWxsbyIsCiAgImxvZ1N0cmVhbSI6ICIyMDIwLzA3LzE5L1skTEFURVNUXTEyMzQ1Njc4OTBhYmNkZWQxMjM0NTY3ODkwYWJjZGVmIiwKICAic3Vic2NyaXB0aW9uRmlsdGVycyI6IFsiTGFtYmRhU3RyZWFtX2Nsb3Vkd2F0Y2hsb2dzLWhlbGxvIl0sCiAgImxvZ0V2ZW50cyI6IFsKICAgIHsKICAgICAgImlkIjogIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2IiwKICAgICAgInRpbWVzdGFtcCI6IDE1OTUwMzA0MDAsCiAgICAgICJtZXNzYWdlIjogIkhlbGxvIgogICAgfQogIF0KfQo=" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/resources/cognito-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "context": {}, 3 | "event": { 4 | "datasetName": "MYDATASET", 5 | "eventType": "SyncTrigger", 6 | "region": "ap-northeast-1", 7 | "identityId": "MYID", 8 | "datasetRecords": { 9 | "key1": { 10 | "newValue": "v2", 11 | "oldValue": "v1", 12 | "op": "replace" 13 | } 14 | }, 15 | "identityPoolId": "MYIDPOOLID", 16 | "version": 2 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/resources/iot-button-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "context": {}, 3 | "event": { 4 | "serialNumber": "EXAMPLESIRIALNUMBER", 5 | "batteryVoltage": "1200mV", 6 | "clickType": "SINGLE" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/resources/lex-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "context": {}, 3 | "event": { 4 | "messageVersion": "1.0", 5 | "invocationSource": "FulfillmentCodeHook", 6 | "userId": "EXAMPLEUSERID", 7 | "sessionAttributes": { 8 | "sk1": "sv1", 9 | "sk2": "sv2" 10 | }, 11 | "bot": { 12 | "name": "MyBot", 13 | "alias": "dev", 14 | "version": "1" 15 | }, 16 | "outputDialogMode": "Text", 17 | "currentIntent": { 18 | "name": "MyBot", 19 | "slots": { 20 | "ProductType": "Bento", 21 | "PickupDate": "2020-07-20", 22 | "PickupTime": "18:00" 23 | }, 24 | "confirmationStatus": "Confirmed" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/plugins/aws/invoke-local/runtime-wrappers/java/src/test/resources/scheduled-event.json: -------------------------------------------------------------------------------- 1 | { 2 | "context": {}, 3 | "event": { 4 | "version": "0", 5 | "id": "EXAMPLEID", 6 | "detail-type": "RDS DB Instance Event", 7 | "source": "aws.rds", 8 | "account": "EXAMPLEACCOUNTID", 9 | "time": "2020-07-19T07:20:20Z", 10 | "region": "ap-northeast-1", 11 | "resources": ["arn:aws:rds:ap-northeast-1:EXAMPLEACCOUNTID:db:EXAMPLEDBID"], 12 | "detail": { 13 | "EventCategories": ["backup"], 14 | "SourceType": "DB_INSTANCE", 15 | "SourceArn": "arn:aws:rds:ap-northeast-1:EXAMPLEACCOUNTID:db:EXAMPLEDBID", 16 | "Date": "2020-07-19T07:20:20.112Z", 17 | "Message": "Finished DB Instance backup", 18 | "SourceIdentifier": "EXAMPLESOURCEID" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/plugins/aws/lib/check-if-bucket-exists.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const ServerlessError = require('../../../serverless-error'); 4 | 5 | module.exports = { 6 | async checkIfBucketExists(bucketName) { 7 | try { 8 | await this.provider.request('S3', 'headBucket', { 9 | Bucket: bucketName, 10 | }); 11 | return true; 12 | } catch (err) { 13 | if (err.code === 'AWS_S3_HEAD_BUCKET_NOT_FOUND') { 14 | return false; 15 | } 16 | 17 | if (err.code === 'AWS_S3_HEAD_BUCKET_FORBIDDEN') { 18 | throw new ServerlessError( 19 | 'Could not access the deployment bucket. Make sure you have sufficient permissions to access it.', 20 | err.code 21 | ); 22 | } 23 | 24 | throw err; 25 | } 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /lib/plugins/aws/lib/get-create-change-set-params.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | getCreateChangeSetParams({ changeSetType, templateUrl, templateBody }) { 5 | const changeSetName = this.provider.naming.getStackChangeSetName(); 6 | const params = { 7 | ...this.getSharedStackActionParams({ templateUrl, templateBody }), 8 | ChangeSetName: changeSetName, 9 | ChangeSetType: changeSetType, 10 | }; 11 | 12 | if (this.serverless.service.provider.rollbackConfiguration) { 13 | params.RollbackConfiguration = this.serverless.service.provider.rollbackConfiguration; 14 | } 15 | 16 | return params; 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /lib/plugins/aws/lib/get-create-stack-params.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | getCreateStackParams(options) { 5 | const params = { 6 | ...this.getSharedStackActionParams(options), 7 | OnFailure: 'DELETE', 8 | }; 9 | 10 | if (this.serverless.service.provider.disableRollback) { 11 | delete params.OnFailure; 12 | params.DisableRollback = this.serverless.service.provider.disableRollback; 13 | } 14 | 15 | return params; 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /lib/plugins/aws/lib/get-execute-change-set-params.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | getExecuteChangeSetParams() { 5 | const stackName = this.provider.naming.getStackName(); 6 | const changeSetName = this.provider.naming.getStackChangeSetName(); 7 | 8 | const executeChangeSetParams = { 9 | StackName: stackName, 10 | ChangeSetName: changeSetName, 11 | }; 12 | 13 | if (this.serverless.service.provider.disableRollback) { 14 | executeChangeSetParams.DisableRollback = this.serverless.service.provider.disableRollback; 15 | } 16 | 17 | return executeChangeSetParams; 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /lib/plugins/aws/lib/get-service-state.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = { 6 | getServiceState() { 7 | const stateFileName = this.provider.naming.getServiceStateFileName(); 8 | const serviceDir = this.serverless.serviceDir; 9 | const packageDirName = this.options.package || '.serverless'; 10 | 11 | const stateFilePath = path.resolve(serviceDir, packageDirName, stateFileName); 12 | return this.serverless.utils.readFileSync(stateFilePath); 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /lib/plugins/aws/lib/get-update-stack-params.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | getUpdateStackParams(options) { 5 | const params = this.getSharedStackActionParams(options); 6 | 7 | // Policy must have at least one statement, otherwise no updates would be possible at all 8 | if ( 9 | this.serverless.service.provider.stackPolicy && 10 | Object.keys(this.serverless.service.provider.stackPolicy).length 11 | ) { 12 | params.StackPolicyBody = JSON.stringify({ 13 | Statement: this.serverless.service.provider.stackPolicy, 14 | }); 15 | } 16 | 17 | if (this.serverless.service.provider.rollbackConfiguration) { 18 | params.RollbackConfiguration = this.serverless.service.provider.rollbackConfiguration; 19 | } 20 | 21 | if (this.serverless.service.provider.disableRollback) { 22 | params.DisableRollback = this.serverless.service.provider.disableRollback; 23 | } 24 | return params; 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /lib/plugins/aws/lib/set-bucket-name.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | async setBucketName() { 5 | if (this.bucketName) { 6 | return this.bucketName; 7 | } 8 | 9 | return this.provider.getServerlessDeploymentBucketName().then((bucketName) => { 10 | this.bucketName = bucketName; 11 | }); 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /lib/plugins/aws/lib/validate.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const ServerlessError = require('../../../serverless-error'); 4 | 5 | module.exports = { 6 | validate() { 7 | if (!this.serverless.serviceDir) { 8 | throw new ServerlessError( 9 | 'This command can only be run inside a service directory', 10 | 'MISSING_SERVICE_DIRECTORY' 11 | ); 12 | } 13 | 14 | this.options.stage = this.provider.getStage(); 15 | this.options.region = this.provider.getRegion(); 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /lib/plugins/aws/package/compile/events/api-gateway/lib/hack/README.md: -------------------------------------------------------------------------------- 1 | # Hack 2 | 3 | This directory contains code which performs raw SDK calls rather than going through CloudFormation template compilations. 4 | 5 | We're planning to port the logic of these code snippets to raw CloudFormation once AWS fixes the problems currently preventing us from solely relying on CloudFormation. 6 | -------------------------------------------------------------------------------- /lib/plugins/aws/package/compile/events/msk/get-msk-cluster-name-token.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const getMskClusterNameToken = (eventSourceArn) => { 4 | if (eventSourceArn['Fn::ImportValue']) { 5 | return eventSourceArn['Fn::ImportValue']; 6 | } else if (eventSourceArn.Ref) { 7 | return eventSourceArn.Ref; 8 | } 9 | 10 | return eventSourceArn.split('/')[1]; 11 | }; 12 | 13 | module.exports = getMskClusterNameToken; 14 | -------------------------------------------------------------------------------- /lib/plugins/aws/package/compile/events/websockets/lib/pick-websockets-template-part.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | 5 | module.exports = (cfTemplate, token) => 6 | _.pickBy(cfTemplate.Resources, (resource, resourceKey) => { 7 | if (resourceKey === token) return true; 8 | if (_.get(resource, 'Properties.ApiId.Ref') === token) return true; 9 | if ( 10 | resource && 11 | resource.DependsOn && 12 | Array.isArray(resource.DependsOn) && 13 | resource.DependsOn.includes(token) 14 | ) { 15 | return true; 16 | } 17 | return false; 18 | }); 19 | -------------------------------------------------------------------------------- /lib/plugins/aws/package/lib/add-export-name-for-outputs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | addExportNameForOutputs() { 5 | const outputs = this.serverless.service.provider.compiledCloudFormationTemplate.Outputs; 6 | for (const [key, data] of Object.entries(outputs)) { 7 | if (!data.Export) { 8 | data.Export = { 9 | Name: `sls-${this.serverless.service.service}-${this.provider.getStage()}-${key}`, 10 | }; 11 | } 12 | } 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /lib/plugins/aws/package/lib/generate-artifact-directory-name.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | generateArtifactDirectoryName() { 5 | // Don't regenerate name if it's already set 6 | if (!this.serverless.service.package.artifactDirectoryName) { 7 | const date = new Date(); 8 | const serviceStage = `${this.serverless.service.service}/${this.provider.getStage()}`; 9 | const dateString = `${date.getTime().toString()}-${date.toISOString()}`; 10 | const prefix = this.provider.getDeploymentPrefix(); 11 | this.serverless.service.package.artifactDirectoryName = `${prefix}/${serviceStage}/${dateString}`; 12 | } 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /lib/plugins/aws/package/lib/save-compiled-template.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs').promises; 4 | const path = require('path'); 5 | 6 | module.exports = { 7 | async saveCompiledTemplate() { 8 | const compiledTemplateFileName = this.provider.naming.getCompiledTemplateFileName(); 9 | 10 | const compiledTemplateFilePath = path.join( 11 | this.serverless.serviceDir, 12 | '.serverless', 13 | compiledTemplateFileName 14 | ); 15 | 16 | const shouldMinify = this.options['minify-template']; 17 | 18 | const templateContents = this.serverless.service.provider.compiledCloudFormationTemplate; 19 | const stringTemplateContents = JSON.stringify(templateContents, null, shouldMinify ? 0 : 2); 20 | 21 | await fs.mkdir(path.dirname(compiledTemplateFilePath), { recursive: true }); 22 | await fs.writeFile(compiledTemplateFilePath, stringTemplateContents); 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /lib/plugins/aws/package/lib/strip-null-props-from-template-resources.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const stripNullPropsFromObj = (obj) => { 4 | Object.entries(obj).forEach(([propName, propVal]) => { 5 | if (propVal === null) { 6 | delete obj[propName]; 7 | } else if (typeof propVal === 'object') { 8 | stripNullPropsFromObj(propVal); 9 | } 10 | }); 11 | }; 12 | 13 | module.exports = { 14 | stripNullPropsFromTemplateResources() { 15 | const resources = this.serverless.service.provider.compiledCloudFormationTemplate.Resources; 16 | 17 | for (const resource of Object.values(resources)) { 18 | if (resource.Properties) { 19 | stripNullPropsFromObj(resource.Properties); 20 | } else { 21 | delete resource.Properties; 22 | } 23 | } 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /lib/plugins/aws/package/lib/validate-template.js: -------------------------------------------------------------------------------- 1 | // Improve error reporting for Framework specific functionalities 2 | 3 | 'use strict'; 4 | 5 | module.exports = { 6 | validateTemplate() { 7 | // No-op at this point 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /lib/plugins/aws/remove/lib/ecr.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | async removeEcrRepository() { 5 | const registryId = await this.provider.getAccountId(); 6 | const repositoryName = this.provider.naming.getEcrRepositoryName(); 7 | const params = { 8 | registryId, 9 | repositoryName, 10 | force: true, // To ensure removal of non-empty repository 11 | }; 12 | 13 | await this.provider.request('ECR', 'deleteRepository', params); 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /lib/plugins/aws/remove/lib/stack.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | async remove() { 5 | const stackName = this.provider.naming.getStackName(); 6 | const params = { 7 | StackName: stackName, 8 | }; 9 | 10 | const customDeploymentRole = this.provider.getCustomDeploymentRole(); 11 | if (customDeploymentRole) { 12 | params.RoleARN = customDeploymentRole; 13 | } 14 | 15 | const cfData = { 16 | StackId: stackName, 17 | }; 18 | 19 | return this.provider.request('CloudFormation', 'deleteStack', params).then(() => cfData); 20 | }, 21 | 22 | async removeStack() { 23 | return this.remove(); 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /lib/plugins/aws/utils/arn-regular-expressions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | cognitoIdpArnExpr: /^arn:[a-zA-Z-]*:cognito-idp/, 5 | lambdaArnExpr: /arn:[a-zA-Z-]*:lambda/, 6 | }; 7 | -------------------------------------------------------------------------------- /lib/plugins/aws/utils/find-and-group-deployments.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | 5 | module.exports = (s3Response, prefix, service, stage) => { 6 | if (s3Response.Contents.length) { 7 | const regex = new RegExp(`${prefix}/${service}/${stage}/(.+-.+-.+-.+)/(.+)`); 8 | const s3Objects = s3Response.Contents.filter((s3Object) => s3Object.Key.match(regex)); 9 | const names = s3Objects.map((s3Object) => { 10 | const match = s3Object.Key.match(regex); 11 | return { 12 | directory: match[1], 13 | file: match[2], 14 | }; 15 | }); 16 | const grouped = _.groupBy(names, 'directory'); 17 | return Object.values(grouped); 18 | } 19 | return []; 20 | }; 21 | -------------------------------------------------------------------------------- /lib/plugins/aws/utils/get-lambda-layer-artifact-path.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | /** 6 | * @param packagePath {string} 7 | * @param layerName {string} 8 | * @param service 9 | * @param naming 10 | * @returns {string} 11 | */ 12 | module.exports = (packagePath, layerName, service, naming) => { 13 | const layerObject = service.getLayer(layerName); 14 | if (layerObject.package && layerObject.package.artifact) { 15 | return layerObject.package.artifact; 16 | } 17 | return path.join(packagePath, naming.getLayerArtifactName(layerName)); 18 | }; 19 | -------------------------------------------------------------------------------- /lib/plugins/aws/utils/get-monitoring-frequency.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = (frequency = null) => { 4 | return frequency || process.env.SLS_AWS_MONITORING_FREQUENCY || 5000; 5 | }; 6 | -------------------------------------------------------------------------------- /lib/plugins/aws/utils/get-s3-endpoint-for-region.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function getS3EndpointForRegion(region) { 4 | const strRegion = region.toLowerCase(); 5 | // look for govcloud - currently s3-us-gov-west-1.amazonaws.com 6 | if (strRegion.match(/us-gov/)) return `s3-${strRegion}.amazonaws.com`; 7 | // look for china - currently s3.cn-north-1.amazonaws.com.cn 8 | if (strRegion.match(/cn-/)) return `s3.${strRegion}.amazonaws.com.cn`; 9 | // look for AWS ISO (US) 10 | if (strRegion.match(/iso-/)) return `s3.${strRegion}.c2s.ic.gov`; 11 | // look for AWS ISOB (US) 12 | if (strRegion.match(/isob-/)) return `s3.${strRegion}.sc2s.sgov.gov`; 13 | // default s3 endpoint for other regions 14 | return 's3.amazonaws.com'; 15 | }; 16 | -------------------------------------------------------------------------------- /lib/plugins/aws/utils/get-s3-objects-from-stacks.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = (stacks, prefix, service, stage) => 4 | stacks.flat().map((entry) => ({ 5 | Key: `${prefix}/${service}/${stage}/${entry.directory}/${entry.file}`, 6 | })); 7 | -------------------------------------------------------------------------------- /lib/plugins/aws/utils/is-change-set-without-changes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = (changeSetDescription) => { 4 | const errorMessages = [ 5 | 'No updates are to be performed.', 6 | "The submitted information didn't contain changes.", 7 | ]; 8 | 9 | return ( 10 | changeSetDescription.Status === 'FAILED' && 11 | errorMessages.some( 12 | (msg) => changeSetDescription.StatusReason && changeSetDescription.StatusReason.includes(msg) 13 | ) 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /lib/plugins/aws/utils/resolve-cf-import-value.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const ServerlessError = require('../../../serverless-error'); 4 | 5 | async function resolveCfImportValue(provider, name, sdkParams = {}) { 6 | return provider.request('CloudFormation', 'listExports', sdkParams).then((result) => { 7 | const targetExportMeta = result.Exports.find((exportMeta) => exportMeta.Name === name); 8 | if (targetExportMeta) return targetExportMeta.Value; 9 | if (result.NextToken) { 10 | return resolveCfImportValue(provider, name, { NextToken: result.NextToken }); 11 | } 12 | 13 | throw new ServerlessError( 14 | `Could not resolve Fn::ImportValue with name ${name}. Are you sure this value is exported ?`, 15 | 'CF_IMPORT_RESOLUTION' 16 | ); 17 | }); 18 | } 19 | 20 | module.exports = resolveCfImportValue; 21 | -------------------------------------------------------------------------------- /lib/plugins/aws/utils/resolve-lambda-target.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const memoizee = require('memoizee'); 4 | const naming = require('../lib/naming'); 5 | 6 | const resolveLambdaTarget = memoizee((functionName, functionObject) => { 7 | const lambdaLogicalId = naming.getLambdaLogicalId(functionName); 8 | const functionArnGetter = { 'Fn::GetAtt': [lambdaLogicalId, 'Arn'] }; 9 | if (!functionObject.targetAlias) return functionArnGetter; 10 | return { 'Fn::Join': [':', [functionArnGetter, functionObject.targetAlias.name]] }; 11 | }); 12 | 13 | module.exports = resolveLambdaTarget; 14 | -------------------------------------------------------------------------------- /lib/plugins/info.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const cliCommandsSchema = require('../cli/commands-schema'); 4 | 5 | class Info { 6 | constructor(serverless) { 7 | this.serverless = serverless; 8 | 9 | this.commands = { 10 | info: { 11 | ...cliCommandsSchema.get('info'), 12 | }, 13 | }; 14 | } 15 | } 16 | 17 | module.exports = Info; 18 | -------------------------------------------------------------------------------- /lib/plugins/logs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const cliCommandsSchema = require('../cli/commands-schema'); 4 | 5 | class Logs { 6 | constructor(serverless) { 7 | this.serverless = serverless; 8 | 9 | this.commands = { 10 | logs: { 11 | ...cliCommandsSchema.get('logs'), 12 | }, 13 | }; 14 | } 15 | } 16 | 17 | module.exports = Logs; 18 | -------------------------------------------------------------------------------- /lib/plugins/metrics.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const cliCommandsSchema = require('../cli/commands-schema'); 4 | 5 | class Metrics { 6 | constructor(serverless, options) { 7 | this.serverless = serverless; 8 | this.options = options; 9 | 10 | this.commands = { 11 | metrics: { 12 | ...cliCommandsSchema.get('metrics'), 13 | }, 14 | }; 15 | } 16 | } 17 | 18 | module.exports = Metrics; 19 | -------------------------------------------------------------------------------- /lib/plugins/plugin/list.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const cliCommandsSchema = require('../../cli/commands-schema'); 4 | const pluginUtils = require('./lib/utils'); 5 | 6 | class PluginList { 7 | constructor(serverless, options) { 8 | this.serverless = serverless; 9 | this.options = options; 10 | 11 | Object.assign(this, pluginUtils); 12 | 13 | this.commands = { 14 | plugin: { 15 | commands: { 16 | list: { 17 | ...cliCommandsSchema.get('plugin list'), 18 | }, 19 | }, 20 | }, 21 | }; 22 | 23 | this.hooks = { 24 | 'plugin:list:list': async () => this.list(), 25 | }; 26 | } 27 | 28 | async list() { 29 | const plugins = await this.getPlugins(); 30 | await this.display(plugins); 31 | } 32 | } 33 | 34 | module.exports = PluginList; 35 | -------------------------------------------------------------------------------- /lib/plugins/plugin/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class Plugin { 4 | constructor(serverless, options) { 5 | this.serverless = serverless; 6 | this.options = options; 7 | 8 | this.commands = { 9 | plugin: { type: 'container' }, 10 | }; 11 | } 12 | } 13 | 14 | module.exports = Plugin; 15 | -------------------------------------------------------------------------------- /lib/plugins/remove.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const cliCommandsSchema = require('../cli/commands-schema'); 4 | 5 | class Remove { 6 | constructor(serverless) { 7 | this.serverless = serverless; 8 | 9 | this.commands = { 10 | remove: { 11 | ...cliCommandsSchema.get('remove'), 12 | }, 13 | }; 14 | } 15 | } 16 | 17 | module.exports = Remove; 18 | -------------------------------------------------------------------------------- /lib/plugins/rollback.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const cliCommandsSchema = require('../cli/commands-schema'); 4 | 5 | class Rollback { 6 | constructor(serverless) { 7 | this.serverless = serverless; 8 | 9 | this.commands = { 10 | rollback: { 11 | ...cliCommandsSchema.get('rollback'), 12 | commands: { 13 | function: { 14 | ...cliCommandsSchema.get('rollback function'), 15 | }, 16 | }, 17 | }, 18 | }; 19 | } 20 | } 21 | 22 | module.exports = Rollback; 23 | -------------------------------------------------------------------------------- /lib/serverless-error.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class ServerlessError extends Error { 4 | constructor(message, code, options = {}) { 5 | super(message); 6 | this.code = code; 7 | this.decoratedMessage = options.decoratedMessage; 8 | } 9 | } 10 | 11 | Object.defineProperty(ServerlessError.prototype, 'name', { 12 | value: ServerlessError.name, 13 | configurable: true, 14 | writable: true, 15 | }); 16 | 17 | module.exports = ServerlessError; 18 | -------------------------------------------------------------------------------- /lib/templates/recommended-list/human-readable.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // class wide constants 4 | const recommendedList = require('./index'); 5 | 6 | let lastGroupName = null; 7 | let result = ''; 8 | let lineCount = 0; 9 | const templateGroupRe = /^([a-z0-9]+)(-|$)/; 10 | for (const templateName of recommendedList) { 11 | const groupName = templateName.match(templateGroupRe)[1]; 12 | if (groupName !== lastGroupName || lineCount === 8) { 13 | result += `\n${' '.repeat(45)}"${templateName}"`; 14 | lastGroupName = groupName; 15 | lineCount = 1; 16 | } else { 17 | result += `, "${templateName}"`; 18 | ++lineCount; 19 | } 20 | } 21 | 22 | module.exports = result; 23 | -------------------------------------------------------------------------------- /lib/templates/recommended-list/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = [ 4 | 'aws-clojure-gradle', 5 | 'aws-clojurescript-gradle', 6 | 'aws-nodejs', 7 | 'aws-nodejs-docker', 8 | 'aws-nodejs-typescript', 9 | 'aws-alexa-typescript', 10 | 'aws-nodejs-ecma-script', 11 | 'aws-python', 12 | 'aws-python3', 13 | 'aws-python-docker', 14 | 'aws-groovy-gradle', 15 | 'aws-java-maven', 16 | 'aws-java-gradle', 17 | 'aws-kotlin-jvm-maven', 18 | 'aws-kotlin-jvm-gradle', 19 | 'aws-kotlin-jvm-gradle-kts', 20 | 'aws-kotlin-nodejs-gradle', 21 | 'aws-scala-sbt', 22 | 'aws-csharp', 23 | 'aws-fsharp', 24 | 'aws-go', 25 | 'aws-go-dep', 26 | 'aws-go-mod', 27 | 'aws-ruby', 28 | 'aws-provided', 29 | 30 | // this template is used to streamline the onboarding process 31 | // it uses the Node.js runtime and AWS provider 32 | 'hello-world', 33 | ]; 34 | -------------------------------------------------------------------------------- /lib/utils/aws-schema-get-cf-value.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.cfValue = (value) => { 4 | return { 5 | anyOf: [value, { $ref: '#/definitions/awsCfFunction' }, { $ref: '#/definitions/awsCfIf' }], 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /lib/utils/aws-sdk-patch.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const metadataServicePrototype = require('aws-sdk/lib/metadata_service').prototype; 4 | 5 | const originalRequest = metadataServicePrototype.request; 6 | 7 | metadataServicePrototype.request = function (path, options, callback) { 8 | this.maxRetries = 0; 9 | if (!this.httpOptions.connectTimeout) this.httpOptions.connectTimeout = 1000; 10 | return originalRequest.call(this, path, options, callback); 11 | }; 12 | -------------------------------------------------------------------------------- /lib/utils/deep-sort-object-by-key.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | 5 | const deepSortObjectByKey = (obj) => { 6 | if (Array.isArray(obj)) { 7 | return obj.map(deepSortObjectByKey); 8 | } 9 | 10 | if (_.isPlainObject(obj)) { 11 | return Object.fromEntries( 12 | Object.entries(obj) 13 | .sort(([key], [otherKey]) => key.localeCompare(otherKey)) 14 | .map(([key, value]) => [key, deepSortObjectByKey(value)]) 15 | ); 16 | } 17 | 18 | return obj; 19 | }; 20 | 21 | module.exports = deepSortObjectByKey; 22 | -------------------------------------------------------------------------------- /lib/utils/ensure-artifact.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const memoizee = require('memoizee'); 4 | const { version } = require('../../package'); 5 | const ensureExists = require('./ensure-exists'); 6 | const path = require('path'); 7 | const os = require('os'); 8 | 9 | const cachePath = path.resolve(os.homedir(), '.serverless/artifacts', version); 10 | 11 | module.exports = memoizee( 12 | async (filename, generate) => { 13 | await ensureExists(path.resolve(cachePath, filename), generate); 14 | return cachePath; 15 | }, 16 | { length: 1, promise: true } 17 | ); 18 | -------------------------------------------------------------------------------- /lib/utils/ensure-exists.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fse = require('fs-extra'); 4 | const fsp = require('fs').promises; 5 | const path = require('path'); 6 | 7 | module.exports = async (filename, generate) => { 8 | const cacheDir = path.dirname(filename); 9 | try { 10 | const stats = await fsp.lstat(filename); 11 | if (stats.isFile()) { 12 | return; 13 | } 14 | } catch (err) { 15 | if (err.code !== 'ENOENT') throw err; 16 | } 17 | 18 | await fse.ensureDir(cacheDir); 19 | await generate(cacheDir); 20 | }; 21 | -------------------------------------------------------------------------------- /lib/utils/filesize.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const ensureNaturalNumber = require('type/natural-number/ensure'); 4 | const { filesize } = require('filesize'); 5 | 6 | const resolveSignificant = (size) => { 7 | return size >= 1000 ? resolveSignificant(Math.floor(size / 1000)) : size; 8 | }; 9 | 10 | module.exports = (size) => 11 | filesize(size, { 12 | round: resolveSignificant(ensureNaturalNumber(size, { name: 'size' })) >= 9 ? 0 : 1, 13 | }); 14 | -------------------------------------------------------------------------------- /lib/utils/fs/copy-dir-contents-sync.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fse = require('fs-extra'); 4 | 5 | const isNotSymbolicLink = (src) => !fse.lstatSync(src).isSymbolicLink(); 6 | 7 | function copyDirContentsSync(srcDir, destDir, { noLinks = false } = {}) { 8 | const copySyncOptions = { 9 | dereference: true, 10 | filter: noLinks ? isNotSymbolicLink : null, 11 | }; 12 | fse.copySync(srcDir, destDir, copySyncOptions); 13 | } 14 | 15 | module.exports = copyDirContentsSync; 16 | -------------------------------------------------------------------------------- /lib/utils/fs/dir-exists-sync.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fse = require('fs-extra'); 4 | 5 | function dirExistsSync(dirPath) { 6 | try { 7 | const stats = fse.statSync(dirPath); 8 | return stats.isDirectory(); 9 | } catch (e) { 10 | return false; 11 | } 12 | } 13 | 14 | module.exports = dirExistsSync; 15 | -------------------------------------------------------------------------------- /lib/utils/fs/dir-exists.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fsp = require('fs').promises; 4 | 5 | async function dirExists(path) { 6 | return fsp.lstat(path).then( 7 | (stats) => stats.isDirectory(), 8 | (error) => { 9 | if (error.code === 'ENOENT') { 10 | return false; 11 | } 12 | throw error; 13 | } 14 | ); 15 | } 16 | 17 | module.exports = dirExists; 18 | -------------------------------------------------------------------------------- /lib/utils/fs/file-exists-sync.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fse = require('fs-extra'); 4 | 5 | function fileExistsSync(filePath) { 6 | try { 7 | const stats = fse.statSync(filePath); 8 | return stats.isFile(); 9 | } catch (e) { 10 | return false; 11 | } 12 | } 13 | 14 | module.exports = fileExistsSync; 15 | -------------------------------------------------------------------------------- /lib/utils/fs/file-exists.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fsp = require('fs').promises; 4 | 5 | async function fileExists(filePath) { 6 | return fsp 7 | .lstat(filePath) 8 | .then((stats) => stats.isFile()) 9 | .catch(() => false); 10 | } 11 | 12 | module.exports = fileExists; 13 | -------------------------------------------------------------------------------- /lib/utils/fs/get-tmp-dir-path.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const os = require('os'); 4 | const path = require('path'); 5 | const crypto = require('crypto'); 6 | 7 | const tmpDirCommonPath = path.join( 8 | os.tmpdir(), 9 | 'tmpdirs-serverless', 10 | crypto.randomBytes(2).toString('hex') 11 | ); 12 | 13 | function getTmpDirPath() { 14 | return path.join(tmpDirCommonPath, crypto.randomBytes(8).toString('hex')); 15 | } 16 | 17 | module.exports = getTmpDirPath; 18 | -------------------------------------------------------------------------------- /lib/utils/fs/read-file-sync.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fse = require('fs-extra'); 4 | const parse = require('./parse'); 5 | 6 | function readFileSync(filePath) { 7 | const contents = fse.readFileSync(filePath); 8 | return parse(filePath, contents); 9 | } 10 | 11 | module.exports = readFileSync; 12 | -------------------------------------------------------------------------------- /lib/utils/fs/read-file.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fsp = require('fs').promises; 4 | const parse = require('./parse'); 5 | 6 | async function readFile(filePath) { 7 | return fsp.readFile(filePath, 'utf8').then((contents) => parse(filePath, contents)); 8 | } 9 | 10 | module.exports = readFile; 11 | -------------------------------------------------------------------------------- /lib/utils/fs/walk-dir-sync.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | 6 | function walkDirSync(dirPath, opts) { 7 | const options = Object.assign( 8 | { 9 | noLinks: false, 10 | }, 11 | opts 12 | ); 13 | let filePaths = []; 14 | const list = fs.readdirSync(dirPath); 15 | list.forEach((filePathParam) => { 16 | let filePath = filePathParam; 17 | filePath = path.join(dirPath, filePath); 18 | const stat = options.noLinks ? fs.lstatSync(filePath) : fs.statSync(filePath); 19 | // skipping symbolic links when noLinks option 20 | if (options.noLinks && stat && stat.isSymbolicLink()) { 21 | return; 22 | } else if (stat && stat.isDirectory()) { 23 | filePaths = filePaths.concat(walkDirSync(filePath, opts)); 24 | } else { 25 | filePaths.push(filePath); 26 | } 27 | }); 28 | 29 | return filePaths; 30 | } 31 | 32 | module.exports = walkDirSync; 33 | -------------------------------------------------------------------------------- /lib/utils/fs/write-file-sync.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fse = require('fs-extra'); 4 | const path = require('path'); 5 | const jc = require('json-cycle'); 6 | const yaml = require('js-yaml'); 7 | 8 | function writeFileSync(filePath, conts, cycles) { 9 | let contents = conts || ''; 10 | 11 | fse.mkdirsSync(path.dirname(filePath)); 12 | 13 | if (filePath.indexOf('.json') !== -1 && typeof contents !== 'string') { 14 | if (cycles) { 15 | contents = jc.stringify(contents, null, 2); 16 | } else { 17 | contents = JSON.stringify(contents, null, 2); 18 | } 19 | } 20 | 21 | const yamlFileExists = filePath.indexOf('.yaml') !== -1; 22 | const ymlFileExists = filePath.indexOf('.yml') !== -1; 23 | 24 | if ((yamlFileExists || ymlFileExists) && typeof contents !== 'string') { 25 | contents = yaml.dump(contents); 26 | } 27 | 28 | return fse.writeFileSync(filePath, contents); 29 | } 30 | 31 | module.exports = writeFileSync; 32 | -------------------------------------------------------------------------------- /lib/utils/get-framework-id.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const configUtils = require('@serverless/utils/config'); 4 | 5 | function getFrameworkId() { 6 | const config = configUtils.getConfig('getFrameworkId'); 7 | return config.frameworkId; 8 | } 9 | 10 | module.exports = getFrameworkId; 11 | -------------------------------------------------------------------------------- /lib/utils/get-require.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const { createRequire } = require('module'); 5 | const memoize = require('memoizee'); 6 | 7 | module.exports = memoize((dirname) => createRequire(path.resolve(dirname, 'require-resolver')), { 8 | primitive: true, 9 | }); 10 | -------------------------------------------------------------------------------- /lib/utils/get-serverless-dir.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const os = require('os'); 5 | 6 | // get .serverless home path 7 | function getServerlessDir() { 8 | return path.join(os.homedir(), '.serverless'); 9 | } 10 | 11 | module.exports = getServerlessDir; 12 | -------------------------------------------------------------------------------- /lib/utils/health-status-filename.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const os = require('os'); 5 | 6 | module.exports = path.resolve(os.homedir(), '.serverless/last-command-health-status'); 7 | -------------------------------------------------------------------------------- /lib/utils/import-esm.js: -------------------------------------------------------------------------------- 1 | // TODO: Remove after dropping support for Node.js v12 2 | 3 | 'use strict'; 4 | 5 | module.exports = async (modPath) => import(`file://${modPath}`); 6 | -------------------------------------------------------------------------------- /lib/utils/is-standalone-executable.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = Boolean(process.pkg && /^(?:\/snapshot\/|[A-Z]+:\\snapshot\\)/.test(__dirname)); 4 | -------------------------------------------------------------------------------- /lib/utils/npm-command-deferred.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fsp = require('fs').promises; 5 | 6 | const localNpmBinPath = path.join(__dirname, '../../node_modules/npm/bin/npm-cli.js'); 7 | 8 | module.exports = fsp 9 | .stat(localNpmBinPath) 10 | .then( 11 | (stats) => stats.isFile(), 12 | (error) => { 13 | if (error.code === 'ENOENT') return null; 14 | throw error; 15 | } 16 | ) 17 | .then((isNpmInstalledLocaly) => { 18 | return isNpmInstalledLocaly 19 | ? { command: 'node', args: [localNpmBinPath] } 20 | : { command: 'npm', args: [] }; 21 | }); 22 | -------------------------------------------------------------------------------- /lib/utils/npm-package/is-global.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const memoizee = require('memoizee'); 4 | const path = require('path'); 5 | const { spawnSync } = require('child_process'); 6 | 7 | const serverlessPackageRoot = path.resolve(__dirname, '../../../'); 8 | 9 | // This method should be kept as sync. The reason for it is the fact that 10 | // telemetry generation and persistence needs to be run in sync manner 11 | // and it depends on this function, either directly or indirectly. 12 | module.exports = memoizee(() => { 13 | const npmPackagesRoot = (() => { 14 | try { 15 | return String(spawnSync('npm', ['root', '-g']).stdout).trim(); 16 | } catch { 17 | return null; 18 | } 19 | })(); 20 | if (!npmPackagesRoot) return false; 21 | return path.resolve(npmPackagesRoot, 'serverless') === serverlessPackageRoot; 22 | }); 23 | -------------------------------------------------------------------------------- /lib/utils/npm-package/is-writable.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fsp = require('fs').promises; 5 | const { log } = require('@serverless/utils/log'); 6 | 7 | const npmPackageRoot = path.resolve(__dirname, '../../../'); 8 | 9 | module.exports = async () => { 10 | const stats = await fsp.stat(npmPackageRoot); 11 | try { 12 | await fsp.utimes(npmPackageRoot, String(stats.atimeMs / 1000), String(stats.mtimeMs / 1000)); 13 | return true; 14 | } catch (error) { 15 | log.info('Auto update: file access error: %O', error); 16 | return false; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /lib/utils/open-browser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const open = require('open'); 4 | const isDockerContainer = require('is-docker'); 5 | const { log, style } = require('@serverless/utils/log'); 6 | 7 | module.exports = function openBrowser(url) { 8 | log.notice(); 9 | log.notice( 10 | style.aside(`If your browser does not open automatically, please open this URL: ${url}`) 11 | ); 12 | log.notice(); 13 | let browser = process.env.BROWSER; 14 | if (browser === 'none' || isDockerContainer()) return; 15 | if (process.platform === 'darwin' && browser === 'open') browser = undefined; 16 | open(url).then((subprocess) => 17 | subprocess.on('error', (err) => { 18 | log.info(`Opening of browser window errored with ${err.stack}`); 19 | }) 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /lib/utils/require-with-import-fallback.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = async (modPath) => { 4 | try { 5 | const mod = require(modPath); 6 | return mod && mod.default ? mod.default : mod; 7 | } catch (error) { 8 | // Fallback to import() if the runtime supports native ESM 9 | if (error.code === 'ERR_REQUIRE_ESM') { 10 | return (await require('./import-esm')(modPath)).default; 11 | } 12 | throw error; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /lib/utils/resolve-region.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const _ = require('lodash'); 3 | 4 | const resolveRegion = ({ configuration, options }) => { 5 | return options.region || _.get(configuration, 'provider.region') || 'us-east-1'; 6 | }; 7 | 8 | module.exports = resolveRegion; 9 | -------------------------------------------------------------------------------- /lib/utils/resolve-stage.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const _ = require('lodash'); 3 | 4 | const resolveStage = ({ configuration, options }) => { 5 | return options.stage || _.get(configuration, 'provider.stage') || 'dev'; 6 | }; 7 | 8 | module.exports = resolveStage; 9 | -------------------------------------------------------------------------------- /lib/utils/telemetry/are-disabled.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This file is still used by tests 4 | module.exports = true; 5 | -------------------------------------------------------------------------------- /lib/utils/tokenize-exception.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { inspect } = require('util'); 4 | const isError = require('type/error/is'); 5 | 6 | const userErrorNames = new Set(['ServerlessError']); 7 | 8 | module.exports = (exception) => { 9 | if (isError(exception)) { 10 | return { 11 | title: exception.name.replace(/([A-Z])/g, ' $1').trim(), 12 | name: exception.name, 13 | stack: exception.stack, 14 | message: exception.message, 15 | isUserError: userErrorNames.has(exception.name), 16 | code: exception.code, 17 | decoratedMessage: exception.decoratedMessage, 18 | }; 19 | } 20 | return { 21 | title: 'Exception', 22 | message: inspect(exception), 23 | isUserError: false, 24 | }; 25 | }; 26 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('@serverless/eslint-config/prettier.config'); 4 | -------------------------------------------------------------------------------- /scripts/test/integration-setup/kafka.server.properties: -------------------------------------------------------------------------------- 1 | auto.create.topics.enable=true 2 | default.replication.factor=2 3 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | .serverless/ 2 | -------------------------------------------------------------------------------- /test/fixtures/cli/config-syntax-error/serverless.yml: -------------------------------------------------------------------------------- 1 | foo: 2 | foo 3 | -------------------------------------------------------------------------------- /test/fixtures/cli/config-type-js-deferred/serverless.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = Promise.resolve({ 4 | service: 'js-service', 5 | provider: 'js-provider', 6 | configValidationMode: 'error', 7 | frameworkVersion: '*', 8 | }); 9 | -------------------------------------------------------------------------------- /test/fixtures/cli/config-type-js/serverless.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | service: 'js-service', 5 | provider: 'js-provider', 6 | configValidationMode: 'error', 7 | frameworkVersion: '*', 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/cli/config-type-json/serverless.json: -------------------------------------------------------------------------------- 1 | { 2 | "service": "json-service", 3 | "provider": "json-provider", 4 | "configValidationMode": "error", 5 | "frameworkVersion": "*" 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/cli/config-type-non-object/serverless.json: -------------------------------------------------------------------------------- 1 | null 2 | -------------------------------------------------------------------------------- /test/fixtures/cli/config-type-yaml/serverless.yaml: -------------------------------------------------------------------------------- 1 | service: 'yaml-service' 2 | provider: 'yaml-provider' 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | -------------------------------------------------------------------------------- /test/fixtures/cli/config-type-yml-and-json/serverless.json: -------------------------------------------------------------------------------- 1 | { 2 | "service": "json-service", 3 | "provider": "json-provider", 4 | "frameworkVersion": "*" 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/cli/config-type-yml-and-json/serverless.yml: -------------------------------------------------------------------------------- 1 | service: 'yml-service' 2 | provider: 'yml-provider' 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | -------------------------------------------------------------------------------- /test/fixtures/cli/config-type-yml/serverless.yml: -------------------------------------------------------------------------------- 1 | service: 'yml-service' 2 | provider: 'yml-provider' 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | -------------------------------------------------------------------------------- /test/fixtures/cli/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('@serverless/test/setup-fixtures-engine')(__dirname); 4 | -------------------------------------------------------------------------------- /test/fixtures/cli/serverless-ts/serverless.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | service: 'serverless-ts-service', 5 | provider: { 6 | name: 'aws', 7 | }, 8 | configValidationMode: 'error', 9 | frameworkVersion: '*', 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/cli/uncaught-exception/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = class Plugin { 4 | constructor() { 5 | setTimeout(() => { 6 | throw new Error('Stop'); 7 | }); 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/cli/uncaught-exception/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | 9 | plugins: 10 | - ./plugin 11 | -------------------------------------------------------------------------------- /test/fixtures/cli/variables/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": "bar" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/cli/variables/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | configValidationMode: error 3 | 4 | provider: 5 | name: aws 6 | runtime: nodejs18.x 7 | 8 | custom: 9 | importedFile: ${file(config.json)} 10 | importedFileWithKey: ${file(config.json):foo} 11 | awsVariable: ${AWS::Region} 12 | cloudFormationReference: ${AnotherResource} 13 | selfReference: ${self:custom.importedFileWithKey} 14 | nestedRef: nestedVal 15 | nestedVal: 16 | prop: resolvedNested 17 | nestedReference: ${self:custom.${self:custom.nestedRef}.prop} 18 | prototype: 19 | nestedInPrototype: ${file(config.json):foo}-in-prototype 20 | -------------------------------------------------------------------------------- /test/fixtures/cli/variables/terraform.tfstate: -------------------------------------------------------------------------------- 1 | { 2 | "version": 4, 3 | "terraform_version": "0.14.4", 4 | "serial": 11, 5 | "lineage": "12ab3c45-abc1-0a1b-1a23-a12b34567c89", 6 | "outputs": { 7 | "listenerarn": { 8 | "value": "arn:aws:elasticloadbalancing:us-west-2:123456789876:listener/app/myapp/1a2b3c4f1a23456b/a1b23c45de6789fa", 9 | "type": "string" 10 | } 11 | }, 12 | "resources": [] 13 | } 14 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/api-gateway/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => { 4 | const resolve = () => 5 | callback(null, { 6 | statusCode: 200, 7 | body: JSON.stringify({ 8 | path: event.path, 9 | method: event.httpMethod, 10 | headers: event.headers, 11 | }), 12 | }); 13 | if (event.path === '/bar/timeout') setTimeout(resolve, 2000); 14 | else resolve(); 15 | }; 16 | 17 | module.exports.minimal = async (event) => { 18 | return { 19 | statusCode: 200, 20 | body: JSON.stringify({ 21 | message: 'Hello from API Gateway! - (minimal)', 22 | event, 23 | }), 24 | }; 25 | }; 26 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/api-gateway/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | apiGateway: 10 | shouldStartNameWithService: true 11 | 12 | functions: 13 | minimal: 14 | handler: index.minimal 15 | events: 16 | - http: GET / 17 | - http: 18 | method: POST 19 | path: minimal-1 20 | foo: 21 | handler: index.handler 22 | events: 23 | - http: 24 | method: GET 25 | path: /foo 26 | - http: 27 | method: POST 28 | path: /some-post 29 | 30 | other: 31 | handler: index.handler 32 | events: 33 | - http: 34 | method: get 35 | path: /bar/{marko} 36 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/aws-loggedin-console-service/.serverlessrc: -------------------------------------------------------------------------------- 1 | { 2 | "frameworkId": "00000000-0000-0000-0000-000000000000", 3 | "meta": { 4 | "created_at": 1560000000, 5 | "updated_at": 1560000000 6 | }, 7 | "auth": { 8 | "refreshToken": "foo", 9 | "idToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJTTFMiLCJpYXQiOjE2MTE3NDAzNTgsImV4cCI6MTk1ODgwOTE1OCwiYXVkIjoic2xzIiwic3ViIjoic2xzQHNscy5jb20ifQ.fy_DY4cWWADDREVYrSy3U5-p7cKT4evEOCjQtQJl9ww" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/aws-loggedin-console-service/serverless.yml: -------------------------------------------------------------------------------- 1 | service: 'some-aws-service' 2 | provider: 'aws' 3 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/aws-loggedin-monitored-service/serverless.yml: -------------------------------------------------------------------------------- 1 | service: 'some-aws-service' 2 | provider: 'aws' 3 | 4 | org: 'testinteractivecli' 5 | app: 'some-aws-service-app' 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/aws-loggedin-noapp-service/serverless.yml: -------------------------------------------------------------------------------- 1 | service: 'some-aws-service' 2 | provider: 'aws' 3 | 4 | org: 'testinteractivecli' 5 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/aws-loggedin-service/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oss-serverless/serverless/7360437f85c4dc6906dd94e658732c3aac6487b4/test/fixtures/programmatic/aws-loggedin-service/index.js -------------------------------------------------------------------------------- /test/fixtures/programmatic/aws-loggedin-service/serverless.yml: -------------------------------------------------------------------------------- 1 | service: 'some-aws-service' 2 | provider: 'aws' 3 | 4 | functions: 5 | app: 6 | handler: index.handler 7 | foo: bar 8 | org: 9 | handler: index.handler 10 | foo: bar 11 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/aws-loggedin-wrongapp-service/serverless.yml: -------------------------------------------------------------------------------- 1 | service: 'some-aws-service' 2 | provider: 'aws' 3 | 4 | org: 'testinteractivecli' 5 | app: 'not-created-app' 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/aws-loggedin-wrongorg-service/serverless.yml: -------------------------------------------------------------------------------- 1 | service: 'some-aws-service' 2 | provider: 'aws' 3 | 4 | org: 'some-other' 5 | app: 'some-aws-service-app' 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/aws/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/blank/serverless.yml: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/check-for-changes/artifact.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oss-serverless/serverless/7360437f85c4dc6906dd94e658732c3aac6487b4/test/fixtures/programmatic/check-for-changes/artifact.zip -------------------------------------------------------------------------------- /test/fixtures/programmatic/check-for-changes/fn-individually.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({}), 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/check-for-changes/fn.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({}), 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/check-for-changes/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | 10 | functions: 11 | fn1: 12 | handler: fn.handler 13 | fn2: 14 | handler: fn.handler 15 | fnIndividually: 16 | handler: fn-individually.handler 17 | package: 18 | patterns: '!fn.js' 19 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/cognito-user-pool/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const logger = console; 4 | 5 | function getMarkers(functionName) { 6 | return { 7 | start: `--- START ${functionName} ---`, 8 | end: `--- END ${functionName} ---`, 9 | }; 10 | } 11 | 12 | function log(functionName, message) { 13 | const markers = getMarkers(functionName); 14 | logger.log(markers.start); 15 | logger.log(message); 16 | logger.log(markers.end); 17 | } 18 | 19 | module.exports = { 20 | getMarkers, 21 | log, 22 | }; 23 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/config-invalid/serverless.yml: -------------------------------------------------------------------------------- 1 | foo: bar 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/config-schema-extensions-error/serverless.yml: -------------------------------------------------------------------------------- 1 | service: configSchemaExtensionsError 2 | 3 | provider: 4 | name: someProvider 5 | runtime: nodejs18.x 6 | 7 | configValidationMode: error 8 | frameworkVersion: '*' 9 | 10 | functions: 11 | someFunction: 12 | handler: 'myHandler.main' 13 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/config-schema-extensions-error/test-plugin-with-colliding-custom-property.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class TestPluginWithCollidingCustomPropertyError { 4 | constructor(serverless) { 5 | serverless.configSchemaHandler.defineCustomProperties({ 6 | properties: { 7 | someProperty: { type: 'string' }, 8 | }, 9 | required: ['someProperty'], 10 | }); 11 | 12 | serverless.configSchemaHandler.defineCustomProperties({ 13 | properties: { 14 | someProperty: { type: 'string' }, 15 | }, 16 | required: ['someProperty'], 17 | }); 18 | } 19 | } 20 | 21 | module.exports = TestPluginWithCollidingCustomPropertyError; 22 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/config-schema-extensions-error/test-plugin-with-colliding-function-event-property.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class TestPluginWithCollidingFunctionEventPropertyError { 4 | constructor(serverless) { 5 | serverless.configSchemaHandler.defineProvider('someProvider', { 6 | functionEvents: { 7 | existingEvent: { 8 | type: 'object', 9 | properties: { existingProp: { type: 'string' } }, 10 | }, 11 | }, 12 | }); 13 | 14 | serverless.configSchemaHandler.defineFunctionEventProperties('someProvider', 'existingEvent', { 15 | properties: { 16 | existingProp: { type: 'string' }, 17 | }, 18 | }); 19 | } 20 | } 21 | 22 | module.exports = TestPluginWithCollidingFunctionEventPropertyError; 23 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/config-schema-extensions-error/test-plugin-with-colliding-function-event.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class TestPluginWithCollidingFunctionEventError { 4 | constructor(serverless) { 5 | serverless.configSchemaHandler.defineProvider('someProvider', { 6 | function: { 7 | properties: { 8 | handler: { type: 'string' }, 9 | }, 10 | }, 11 | functionEvents: { 12 | existingEvent: { 13 | type: 'object', 14 | properties: { existingProp: { type: 'string' } }, 15 | }, 16 | }, 17 | }); 18 | 19 | serverless.configSchemaHandler.defineFunctionEvent('someProvider', 'existingEvent', { 20 | type: 'object', 21 | properties: { 22 | someProperty: { type: 'string' }, 23 | }, 24 | required: ['someProperty'], 25 | additionalProperties: false, 26 | }); 27 | } 28 | } 29 | 30 | module.exports = TestPluginWithCollidingFunctionEventError; 31 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/config-schema-extensions-error/test-plugin-with-colliding-function-property.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class TestPluginWithCollidingFunctionEventPropertyError { 4 | constructor(serverless) { 5 | serverless.configSchemaHandler.defineProvider('someProvider', { 6 | function: { 7 | properties: { 8 | handler: { type: 'string' }, 9 | }, 10 | }, 11 | }); 12 | 13 | serverless.configSchemaHandler.defineFunctionProperties('someProvider', { 14 | properties: { 15 | handler: { type: 'string' }, 16 | }, 17 | }); 18 | } 19 | } 20 | 21 | module.exports = TestPluginWithCollidingFunctionEventPropertyError; 22 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/config-schema-extensions-error/test-plugin-with-colliding-provider-property-in-function.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class TestPluginWithCollidingProviderPropertyInFunctionError { 4 | constructor(serverless) { 5 | serverless.configSchemaHandler.defineProvider('someProvider', { 6 | function: { 7 | type: 'object', 8 | properties: { 9 | events: { type: 'string' }, 10 | }, 11 | }, 12 | }); 13 | } 14 | } 15 | 16 | module.exports = TestPluginWithCollidingProviderPropertyInFunctionError; 17 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/config-schema-extensions-error/test-plugin-with-colliding-provider-property-in-provider.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class TestPluginWithCollidingProviderPropertyInProviderError { 4 | constructor(serverless) { 5 | serverless.configSchemaHandler.defineProvider('someProvider', { 6 | provider: { 7 | type: 'object', 8 | properties: { 9 | name: { type: 'string' }, 10 | }, 11 | }, 12 | }); 13 | } 14 | } 15 | 16 | module.exports = TestPluginWithCollidingProviderPropertyInProviderError; 17 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/config-schema-extensions-error/test-plugin-with-colliding-top-level-property.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class TestPluginWithCollidingTopLevelPropertyError { 4 | constructor(serverless) { 5 | serverless.configSchemaHandler.defineTopLevelProperty('service', { 6 | type: 'string', 7 | }); 8 | } 9 | } 10 | 11 | module.exports = TestPluginWithCollidingTopLevelPropertyError; 12 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/config-schema-extensions-error/test-plugin-with-complex-event-without-object-definition.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class TestPluginWithComplexEventWithoutObjectDefinitionError { 4 | constructor(serverless) { 5 | serverless.configSchemaHandler.defineProvider('someProvider', { 6 | function: { 7 | properties: { 8 | handler: { type: 'string' }, 9 | }, 10 | }, 11 | functionEvents: { 12 | existingComplexEvent: { 13 | anyOf: [{ type: 'string' }, { type: 'integer' }], 14 | }, 15 | }, 16 | }); 17 | 18 | serverless.configSchemaHandler.defineFunctionEventProperties( 19 | 'someProvider', 20 | 'existingComplexEvent', 21 | { 22 | properties: { 23 | someProperty: { type: 'string' }, 24 | }, 25 | } 26 | ); 27 | } 28 | } 29 | 30 | module.exports = TestPluginWithComplexEventWithoutObjectDefinitionError; 31 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/config-schema-extensions-error/test-plugin-with-non-existing-event-error.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class TestPluginWithNonExistingEventError { 4 | constructor(serverless) { 5 | serverless.configSchemaHandler.defineProvider('someProvider', { 6 | function: { 7 | properties: { 8 | handler: { type: 'string' }, 9 | }, 10 | }, 11 | functionEvents: { 12 | existingEvent: { 13 | type: 'object', 14 | properties: { existingProp: { type: 'string' } }, 15 | }, 16 | }, 17 | }); 18 | 19 | serverless.configSchemaHandler.defineFunctionEventProperties( 20 | 'someProvider', 21 | 'nonExistingEvent', 22 | { 23 | properties: { 24 | someProperty: { type: 'string' }, 25 | }, 26 | } 27 | ); 28 | } 29 | } 30 | 31 | module.exports = TestPluginWithNonExistingEventError; 32 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/config-schema-extensions/serverless.yml: -------------------------------------------------------------------------------- 1 | service: configSchemaExtensions 2 | 3 | disabledDeprecations: 4 | - SOME_DEP_ERROR 5 | 6 | provider: 7 | name: someProvider 8 | 9 | plugins: 10 | - ./test-plugin 11 | 12 | configValidationMode: error 13 | frameworkVersion: '*' 14 | 15 | custom: 16 | someCustomStringProp: can-be-string 17 | 18 | functions: 19 | someFunction: 20 | someFunctionStringProp: function-string-prop 21 | someRequiredFunctionNumberProp: 321 22 | events: 23 | - someEvent: 24 | someRequiredStringProp: some string 25 | someNumberProp: 123 26 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/curated-plugins-python/_setup.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fsp = require('fs').promises; 5 | 6 | const slsDependencyDir = path.resolve(__dirname, 'node_modules/serverless'); 7 | 8 | // Ensure to remove "serverless" installed as peer-dependency to avoid local fallback 9 | module.exports = async () => fsp.rm(slsDependencyDir, { recursive: true, force: true }); 10 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/curated-plugins-python/handler.py: -------------------------------------------------------------------------------- 1 | 2 | import requests 3 | 4 | def hello(event, context): 5 | return requests.get('https://httpbin.org/get').json() 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/curated-plugins-python/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "serverless-python-requirements": "5.1.1" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/curated-plugins-python/requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/curated-plugins-python/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: python3.11 9 | 10 | functions: 11 | function: 12 | handler: handler.hello 13 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/curated-plugins/.env: -------------------------------------------------------------------------------- 1 | DOTENV_PLUGIN_TEST=passed 2 | 3 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/curated-plugins/_setup.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fsp = require('fs').promises; 5 | 6 | const nodeModulesDir = path.resolve(__dirname, 'node_modules'); 7 | 8 | // Ensure to remove "serverless" installed as peer-dependency to avoid local fallback 9 | module.exports = async () => 10 | Promise.all([ 11 | fsp.rm(path.resolve(nodeModulesDir, 'serverless'), { recursive: true, force: true }), 12 | fsp.unlink(path.resolve(nodeModulesDir, '.bin/serverless')).catch(() => {}), 13 | fsp.unlink(path.resolve(nodeModulesDir, '.bin/sls')).catch(() => {}), 14 | ]); 15 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/curated-plugins/index-ts.ts: -------------------------------------------------------------------------------- 1 | interface TestData { 2 | value: string; 3 | } 4 | 5 | // Exported to confirm in tests we've received compiled module 6 | export const testData: TestData = { value: 'test-ts-compilation' }; 7 | 8 | export const handler = (event, context, callback) => { 9 | callback(null, { 10 | statusCode: 200, 11 | body: JSON.stringify({ message: 'Regular lambda test', input: event }, null, 2), 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/curated-plugins/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => { 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({ message: 'Test', input: event }, null, 2), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/curated-plugins/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "serverless-offline": "9.0.0", 4 | "webpack": "5.66.0", 5 | "serverless-webpack": "5.6.0", 6 | "serverless-domain-manager": "5.3.0", 7 | "serverless-prune-plugin": "2.0.1", 8 | "serverless-dotenv-plugin": "3.12.2", 9 | "serverless-iam-roles-per-function": "3.2.0", 10 | "serverless-plugin-typescript": "2.1.0", 11 | "typescript": "4.5.4", 12 | "serverless-step-functions": "3.5.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/curated-plugins/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | useDotenv: true 6 | 7 | custom: 8 | customDomain: 9 | domainName: api.example.com 10 | 11 | provider: 12 | name: aws 13 | runtime: nodejs18.x 14 | 15 | functions: 16 | function: 17 | handler: index.handler 18 | events: 19 | - http: 20 | path: foo 21 | method: GET 22 | - http: 23 | path: foo 24 | method: POST 25 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/curated-plugins/webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { entry: './index.js', target: 'node', mode: 'production' }; 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/custom-config-filename/serverless.custom.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | custom: 7 | looks: good 8 | 9 | provider: 10 | name: aws 11 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/custom-provider/custom-provider.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = class CustomPlugin {}; 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/custom-provider/serverless.yml: -------------------------------------------------------------------------------- 1 | service: custom 2 | 3 | frameworkVersion: '*' 4 | 5 | provider: 6 | name: customProvider 7 | runtime: foo 8 | 9 | plugins: 10 | - ./custom-provider 11 | 12 | functions: 13 | someFunction: 14 | events: 15 | - someEvent: 16 | someProp: some string 17 | otherFunction: 18 | runtime: bar 19 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/ecr/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/lambda/nodejs:12 2 | 3 | COPY app.js ./ 4 | 5 | # Command can be overwritten by providing a different command in the template directly. 6 | CMD ["app.handler"] 7 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/ecr/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/lambda/nodejs:12 2 | 3 | COPY app.js ./ 4 | 5 | # Command can be overwritten by providing a different command in the template directly. 6 | CMD ["app.handler"] 7 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/ecr/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({}), 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/ecr/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | ecr: 10 | images: 11 | baseimage: 12 | path: ./ 13 | 14 | functions: 15 | foo: 16 | image: baseimage 17 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/event-bridge/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | 5 | provider: 6 | name: aws 7 | runtime: nodejs18.x 8 | versionFunctions: false 9 | 10 | functions: 11 | eventBusDefault: 12 | handler: core.eventBusDefault 13 | events: 14 | - eventBridge: 15 | pattern: 16 | source: 17 | - serverless.test 18 | eventBusDefaultArn: 19 | handler: core.eventBusDefaultArn 20 | # Event filled by integration test 21 | eventBusCustom: 22 | handler: core.eventBusCustom 23 | events: 24 | - eventBridge: 25 | eventBus: ${self:service}-named-event-bus 26 | pattern: 27 | source: 28 | - serverless.test 29 | eventBusArn: 30 | handler: core.eventBusArn 31 | # Event filled by integration test 32 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/event-bridge/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const logger = console; 4 | 5 | function getMarkers(functionName) { 6 | return { 7 | start: `--- START ${functionName} ---`, 8 | end: `--- END ${functionName} ---`, 9 | }; 10 | } 11 | 12 | function log(functionName, message) { 13 | const markers = getMarkers(functionName); 14 | logger.log(markers.start); 15 | logger.log(message); 16 | logger.log(markers.end); 17 | } 18 | 19 | module.exports = { 20 | getMarkers, 21 | log, 22 | }; 23 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/exception/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = class Plugin { 4 | constructor() { 5 | throw new Error('Stop'); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/exception/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | 9 | plugins: 10 | - ./plugin 11 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-active-mq/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "stompit": "^1.0.0" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-active-mq/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | # VPC and Events configuration is added dynamically during test run 7 | # Because it has to be provisioned separately via CloudFormation stack 8 | 9 | provider: 10 | name: aws 11 | runtime: nodejs18.x 12 | versionFunctions: false 13 | 14 | functions: 15 | producer: 16 | handler: core.producer 17 | consumer: 18 | handler: core.consumer 19 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-cloud-front/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => { 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({ message: 'cloudfront event', input: event }, null, 2), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-cloud-front/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | 10 | functions: 11 | foo: 12 | handler: index.handler 13 | events: 14 | - cloudFront: 15 | eventType: origin-request 16 | origin: https://example.com 17 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-efs/core.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | 5 | const filename = process.env.FILENAME; 6 | 7 | function writer(event, context, callback) { 8 | fs.writeFileSync(filename, 'fromlambda', 'utf8'); 9 | return callback(null, event); 10 | } 11 | 12 | function reader(event, context, callback) { 13 | const result = fs.readFileSync(filename, 'utf8'); 14 | return callback(null, { result }); 15 | } 16 | 17 | module.exports = { writer, reader }; 18 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-efs/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | 5 | # VPC and EFS configuration is added dynamically during test run 6 | # Because it has to be provisioned separately via CloudFormation stack 7 | 8 | provider: 9 | name: aws 10 | runtime: nodejs18.x 11 | versionFunctions: false 12 | 13 | functions: 14 | writer: 15 | handler: core.writer 16 | reader: 17 | handler: core.reader 18 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-layers/extra-layers/test-layer-source-change/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.layer = (foo, bar) => { 4 | const newVariable = 12; 5 | return foo + bar + newVariable; 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-layers/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({}), 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-layers/test-layer/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.layer = (foo, bar) => { 4 | return foo + bar; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-msk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "kafkajs": "^1.13.0" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-msk/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | # VPC and Events configuration is added dynamically during test run 7 | # Because it has to be provisioned separately via CloudFormation stack 8 | 9 | provider: 10 | name: aws 11 | runtime: nodejs18.x 12 | versionFunctions: false 13 | 14 | functions: 15 | producer: 16 | handler: core.producer 17 | consumer: 18 | handler: core.consumer 19 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-rabbit-mq/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "amqplib": "^0.8.0" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function-rabbit-mq/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | # VPC and Events configuration is added dynamically during test run 7 | # Because it has to be provisioned separately via CloudFormation stack 8 | 9 | provider: 10 | name: aws 11 | runtime: nodejs18.x 12 | versionFunctions: false 13 | 14 | functions: 15 | producer: 16 | handler: core.producer 17 | consumer: 18 | handler: core.consumer 19 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function/basic.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({ message: 'Basic', input: event }), 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function/other.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({ message: 'Other', input: event }), 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | 10 | functions: 11 | basic: 12 | handler: basic.handler 13 | other: 14 | handler: other.handler 15 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function/stream.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const streamifyResponse = awslambda.streamifyResponse; 4 | 5 | module.exports.handler = streamifyResponse(async (event, responseStream) => { 6 | responseStream.write('Hello'); 7 | responseStream.end(); 8 | }); 9 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function/target.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => { 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({ message: 'Target', input: event }, null, 2), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/function/trigger.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => { 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({ message: 'Trigger', input: event }, null, 2), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/http-api-catch-all/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => { 4 | const httpData = event.requestContext.http; 5 | callback(null, { 6 | statusCode: 200, 7 | body: JSON.stringify({ 8 | path: httpData.path, 9 | method: httpData.method, 10 | }), 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/http-api-catch-all/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | 10 | functions: 11 | foo: 12 | handler: index.handler 13 | # provisionedConcurrency: 1 14 | events: 15 | - httpApi: '*' 16 | 17 | other: 18 | handler: index.handler 19 | events: 20 | - httpApi: 21 | method: '*' 22 | path: /foo 23 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/http-api-export/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | 10 | resources: 11 | Resources: 12 | HttpApi: 13 | Type: AWS::ApiGatewayV2::Api 14 | Properties: 15 | Name: dev-${self:service} 16 | ProtocolType: HTTP 17 | HttpApiStage: 18 | Type: AWS::ApiGatewayV2::Stage 19 | Properties: 20 | ApiId: 21 | Ref: HttpApi 22 | StageName: $default 23 | AutoDeploy: true 24 | Outputs: 25 | HttpApiId: 26 | Value: 27 | Ref: HttpApi 28 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/http-api/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => { 4 | const httpData = event.requestContext.http; 5 | const resolve = () => 6 | callback(null, { 7 | statusCode: 200, 8 | body: JSON.stringify({ 9 | path: httpData.path, 10 | method: httpData.method, 11 | }), 12 | }); 13 | if (httpData.path === '/bar/timeout') setTimeout(resolve, 2000); 14 | else resolve(); 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/http-api/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | logRetentionInDays: 14 10 | 11 | functions: 12 | foo: 13 | handler: index.handler 14 | # provisionedConcurrency: 1 # Increases significantly test time 15 | events: 16 | - httpApi: 17 | method: GET 18 | path: /foo 19 | - httpApi: 20 | method: POST 21 | path: /some-post 22 | 23 | other: 24 | handler: index.handler 25 | events: 26 | - httpApi: 27 | method: get 28 | path: /bar/{marko} 29 | 30 | simpleCustomAuthorizer: 31 | handler: authorizers.simpleAuthorizer 32 | 33 | standardCustomAuthorizer: 34 | handler: authorizers.standardAuthorizer 35 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('@serverless/test/setup-fixtures-engine')(__dirname); 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/async-cjs.cjs: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = async (event, context) => { 4 | if (event && event.shouldFail) throw new Error('Failed on request'); 5 | return { 6 | statusCode: 200, 7 | body: JSON.stringify({ 8 | message: 'Invoked', 9 | event, 10 | clientContext: context.clientContext, 11 | env: process.env, 12 | }), 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/async.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = async (event, context) => { 4 | if (event && event.shouldFail) throw new Error('Failed on request'); 5 | return { 6 | statusCode: 200, 7 | body: JSON.stringify({ 8 | message: 'Invoked', 9 | event, 10 | clientContext: context.clientContext, 11 | env: process.env, 12 | }), 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/callback.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => { 4 | if (event && event.shouldFail) { 5 | callback(new Error('Failed on request')); 6 | return; 7 | } 8 | callback(null, { 9 | statusCode: 200, 10 | body: JSON.stringify({ 11 | message: 'Invoked', 12 | event, 13 | clientContext: context.clientContext, 14 | env: process.env, 15 | }), 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/class.rb: -------------------------------------------------------------------------------- 1 | module MyModule 2 | class MyClass 3 | def self.my_class_method(event:, context:) 4 | {"source" => "rubyclass"} 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/context-done.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context) => { 4 | if (event && event.shouldFail) { 5 | context.done(new Error('Failed on request')); 6 | return; 7 | } 8 | context.done(null, { 9 | statusCode: 200, 10 | body: JSON.stringify({ 11 | message: 'Invoked', 12 | event, 13 | clientContext: context.clientContext, 14 | env: process.env, 15 | }), 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/context-succeed.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context) => { 4 | if (event && event.shouldFail) { 5 | context.fail(new Error('Failed on request')); 6 | return; 7 | } 8 | context.succeed({ 9 | statusCode: 200, 10 | body: JSON.stringify({ 11 | message: 'Invoked', 12 | event, 13 | clientContext: context.clientContext, 14 | env: process.env, 15 | }), 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/context.json: -------------------------------------------------------------------------------- 1 | { "testProp": "testValue" } 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/deadline_ms.rb: -------------------------------------------------------------------------------- 1 | def handler(event:, context:) 2 | {"deadlineMs" => context.deadline_ms} 3 | end 4 | 5 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/doubled-resolution-callback-first.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => { 4 | process.nextTick(() => 5 | callback(null, { 6 | statusCode: 200, 7 | body: JSON.stringify({ 8 | mode: 'callback', 9 | }), 10 | }) 11 | ); 12 | return new Promise((resolve) => 13 | setTimeout(() => 14 | resolve({ 15 | statusCode: 200, 16 | body: JSON.stringify({ 17 | mode: 'promise', 18 | }), 19 | }) 20 | ) 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/doubled-resolution-promise-first.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = async (event, context, callback) => { 4 | setTimeout(() => 5 | callback(null, { 6 | statusCode: 200, 7 | body: JSON.stringify({ 8 | mode: 'callback', 9 | }), 10 | }) 11 | ); 12 | return { 13 | statusCode: 200, 14 | body: JSON.stringify({ 15 | mode: 'promise', 16 | }), 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/esm/async-esm.js: -------------------------------------------------------------------------------- 1 | export const handler = async (event, context) => { 2 | if (event && event.shouldFail) throw new Error('Failed on request'); 3 | return { 4 | statusCode: 200, 5 | body: JSON.stringify({ 6 | message: 'Invoked', 7 | event, 8 | clientContext: context.clientContext, 9 | env: process.env, 10 | }), 11 | }; 12 | }; 13 | 14 | export default handler; 15 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/handler.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | 5 | def handler(event, context): 6 | return { 7 | "statusCode": 200, 8 | "body": json.dumps({ 9 | "message": "Invoked", 10 | "env": dict(os.environ) 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/handler.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | def handler(event:, context:) 4 | {"statusCode" => 200, "body" => {"message" => "Invoked", "env" => ENV.to_hash}.to_json } 5 | end 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/init-fail.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | throw new Error('Initialization failure'); 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/invocation-fail.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = () => { 4 | throw new Error('Invocation fail'); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/payload.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { dataInputKey: 'dataInputValue' }; 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/payload.json: -------------------------------------------------------------------------------- 1 | { "dataInputKey": "dataInputValue" } 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/payload.yaml: -------------------------------------------------------------------------------- 1 | dataInputKey: dataInputValue 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/remaining-time.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => { 4 | const data = [context.getRemainingTimeInMillis()]; 5 | setTimeout(() => { 6 | data.push(context.getRemainingTimeInMillis()); 7 | setTimeout(() => { 8 | data.push(context.getRemainingTimeInMillis()); 9 | callback(null, { 10 | statusCode: 200, 11 | body: JSON.stringify({ data }), 12 | }); 13 | }); 14 | }, 100); 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/remaining_time.py: -------------------------------------------------------------------------------- 1 | from time import sleep 2 | 3 | 4 | def handler(event, context): 5 | start = context.get_remaining_time_in_millis() 6 | sleep(0.1) 7 | stop = context.get_remaining_time_in_millis() 8 | 9 | return { 10 | "start": start, 11 | "stop": stop 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/invocation/remaining_time.rb: -------------------------------------------------------------------------------- 1 | def handler(event:, context:) 2 | start = context.get_remaining_time_in_millis() 3 | sleep(0.1) 4 | stop = context.get_remaining_time_in_millis() 5 | 6 | {"start" => start, "stop" => stop} 7 | end 8 | 9 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/iot-fleet-provisioning/hook.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.main = (_event, _context, callback) => { 4 | callback(null, { allowProvisioning: true }); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/iot-fleet-provisioning/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "aws-iot-device-sdk-v2": "^1.8.4" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/iot-fleet-provisioning/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Parameters": {}, 3 | "Resources": { 4 | "certificate": { 5 | "Type": "AWS::IoT::Certificate", 6 | "Properties": { 7 | "CertificateId": { "Ref": "AWS::IoT::Certificate::Id" }, 8 | "Status": "Active" 9 | } 10 | }, 11 | "policy": { 12 | "Type": "AWS::IoT::Policy", 13 | "Properties": { 14 | "PolicyName": "${self:service}-${sls:stage}-iot-policy" 15 | } 16 | }, 17 | "thing": { 18 | "Type": "AWS::IoT::Thing", 19 | "Properties": { 20 | "ThingName": "${self:service}-${sls:stage}" 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/iot/core.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // NOTE: the `utils.js` file is bundled into the deployment package 4 | // eslint-disable-next-line 5 | const { log } = require('./utils'); 6 | 7 | function iotBasic(event, context, callback) { 8 | const functionName = 'iotBasic'; 9 | log(functionName, JSON.stringify(event)); 10 | return callback(null, event); 11 | } 12 | 13 | module.exports = { iotBasic }; 14 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/iot/serverless.yml: -------------------------------------------------------------------------------- 1 | service: CHANGE_TO_UNIQUE_PER_RUN 2 | 3 | configValidationMode: error 4 | 5 | provider: 6 | name: aws 7 | runtime: nodejs18.x 8 | versionFunctions: false 9 | 10 | functions: 11 | iotBasic: 12 | handler: core.iotBasic 13 | events: 14 | - iot: 15 | sql: "SELECT * FROM '${self:service}/test'" 16 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/iot/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const logger = console; 4 | 5 | function getMarkers(functionName) { 6 | return { 7 | start: `--- START ${functionName} ---`, 8 | end: `--- END ${functionName} ---`, 9 | }; 10 | } 11 | 12 | function log(functionName, message) { 13 | const markers = getMarkers(functionName); 14 | logger.log(markers.start); 15 | logger.log(message); 16 | logger.log(markers.end); 17 | } 18 | 19 | module.exports = { 20 | getMarkers, 21 | log, 22 | }; 23 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/layer/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({}), 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/layer/layer/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = {}; 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/layer/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | 10 | functions: 11 | function: 12 | handler: index.handler 13 | layers: 14 | - { Ref: LayerLambdaLayer } 15 | 16 | layers: 17 | layer: 18 | path: layer 19 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/locally-installed-serverless/_setup.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | 6 | const fixturePath = path.resolve(__dirname, 'node_modules/serverless'); 7 | const fixtureModulePath = path.resolve(fixturePath, 'bin/serverless.js'); 8 | 9 | module.exports = (originalFixturePath) => { 10 | const content = fs.readFileSync(fixtureModulePath); 11 | fs.writeFileSync( 12 | fixtureModulePath, 13 | String(content).replace( 14 | '$SERVERLESS_PATH', 15 | JSON.stringify(path.resolve(originalFixturePath, '../../../../')) 16 | ) 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/locally-installed-serverless/node_modules/serverless/bin/serverless.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // eslint-disable-next-line no-undef 4 | require($SERVERLESS_PATH); 5 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/locally-installed-serverless/node_modules/serverless/lib/serverless.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/locally-installed-serverless/node_modules/serverless/package.json: -------------------------------------------------------------------------------- 1 | { "main": "lib/serverless.js", "version": "2.0.0-local" } 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/locally-installed-serverless/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/multi-service/file.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": "bar" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/multi-service/service-a/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({}), 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/multi-service/service-a/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | 10 | custom: 11 | env: ${env:ENV_SOURCE_TEST, null} 12 | file: ${file(../file.json)} 13 | opt: ${opt:stage, null} 14 | self: ${self:custom.file.foo} 15 | strToBool: ${strToBool('false')} 16 | 17 | functions: 18 | foo: 19 | handler: index.handler 20 | other: 21 | handler: index.handler 22 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/package-artifact-in-serverless-dir/my-own.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oss-serverless/serverless/7360437f85c4dc6906dd94e658732c3aac6487b4/test/fixtures/programmatic/package-artifact-in-serverless-dir/my-own.zip -------------------------------------------------------------------------------- /test/fixtures/programmatic/package-artifact-in-serverless-dir/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | 10 | plugins: 11 | # Mutates `package.artifact` to point to copied `.serverless/NAME.zip` 12 | - ./package-artifact-plugin 13 | 14 | functions: 15 | foo: 16 | handler: index.handler 17 | other: 18 | handler: index.handler 19 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/package-artifact/absolute-artifact.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oss-serverless/serverless/7360437f85c4dc6906dd94e658732c3aac6487b4/test/fixtures/programmatic/package-artifact/absolute-artifact.zip -------------------------------------------------------------------------------- /test/fixtures/programmatic/package-artifact/artifact-function.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oss-serverless/serverless/7360437f85c4dc6906dd94e658732c3aac6487b4/test/fixtures/programmatic/package-artifact/artifact-function.zip -------------------------------------------------------------------------------- /test/fixtures/programmatic/package-artifact/artifact.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oss-serverless/serverless/7360437f85c4dc6906dd94e658732c3aac6487b4/test/fixtures/programmatic/package-artifact/artifact.zip -------------------------------------------------------------------------------- /test/fixtures/programmatic/package-artifact/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({}), 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/package-artifact/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | 10 | package: 11 | artifact: artifact.zip 12 | 13 | functions: 14 | foo: 15 | handler: index.handler 16 | other: 17 | handler: index.handler 18 | package: 19 | artifact: artifact-function.zip 20 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/.env: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oss-serverless/serverless/7360437f85c4dc6906dd94e658732c3aac6487b4/test/fixtures/programmatic/packaging/.env -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/.env.stage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oss-serverless/serverless/7360437f85c4dc6906dd94e658732c3aac6487b4/test/fixtures/programmatic/packaging/.env.stage -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/.gitignore: -------------------------------------------------------------------------------- 1 | # File created just to test packaging exclusion defaults 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/.serverless_plugins/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function SomePlugin() {}; 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/artifact-function.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oss-serverless/serverless/7360437f85c4dc6906dd94e658732c3aac6487b4/test/fixtures/programmatic/packaging/artifact-function.zip -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/artifact.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oss-serverless/serverless/7360437f85c4dc6906dd94e658732c3aac6487b4/test/fixtures/programmatic/packaging/artifact.zip -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/custom-plugins/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function SomePlugin() {}; 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/custom-plugins/plugin-2/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function SomePlugin() {}; 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/custom-plugins/plugin-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "src/main.js" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/custom-plugins/plugin-3/src/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function SomePlugin() {}; 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/custom-plugins/plugin-4/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function SomePlugin() {}; 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/dir1/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/dir1/subdir1/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/dir1/subdir2/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/dir1/subdir2/subsubdir1/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/dir1/subdir2/subsubdir2/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/dir1/subdir2/subsubdir3/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/dir1/subdir3/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/dir1/subdir4/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/dir2/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/dir3/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = (event, context, callback) => 4 | callback(null, { 5 | statusCode: 200, 6 | body: JSON.stringify({}), 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/layer/layer-module-1.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/layer/layer-module-2.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/aws/aws-lambda-go/lambda" 5 | ) 6 | 7 | // Handler is our lambda handler invoked by the `lambda.Start` function call 8 | func Handler() (string, error) { 9 | return "Go Serverless!", nil 10 | } 11 | 12 | func main() { 13 | // Make the handler available for Remote Procedure Call by AWS Lambda 14 | lambda.Start(Handler) 15 | } 16 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/packaging/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | disabledDeprecations: LOAD_VARIABLES_FROM_ENV_FILES 6 | 7 | provider: 8 | name: aws 9 | runtime: nodejs18.x 10 | 11 | functions: 12 | fnService: 13 | handler: index.handler 14 | fnIndividual: 15 | handler: index.handler 16 | package: 17 | individually: true 18 | 19 | fnGo: 20 | handler: bin/main 21 | runtime: go1.x 22 | 23 | layers: 24 | layer: 25 | path: layer 26 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/plugin/broken-plugin/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | throw new Error('failed to load plugin'); 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/plugin/custom-variable-source.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = class CustomVariableSourcePlugin { 4 | constructor(serverless, options, utils) { 5 | this.serverless = serverless; 6 | this.options = options; 7 | this.utils = utils; 8 | this.configurationVariablesSources = { 9 | other: { 10 | async resolve({ address }) { 11 | // `address` contains the name of the variable to resolve: 12 | // In `${foo:some-variable}`, address will contain `some-variable`. 13 | 14 | // Resolver is expected to return an object with the value in the `value` property: 15 | return { 16 | // 17 | value: `Resolving variable ${address}`, 18 | }; 19 | }, 20 | }, 21 | }; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/plugin/local-esm-plugin/index.js: -------------------------------------------------------------------------------- 1 | export default class LocalESMPlugin { 2 | constructor(serverless, options, utils) { 3 | this.serverless = serverless; 4 | this.options = options; 5 | this.utils = utils; 6 | this.commands = { 7 | esmCustomCommand: { 8 | usage: 'Description of custom command', 9 | configDependent: false, 10 | }, 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/plugin/local-esm-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/plugin/node_modules/esm-plugin/index.js: -------------------------------------------------------------------------------- 1 | export default class ESMPlugin { 2 | constructor(serverless, options, utils) { 3 | this.serverless = serverless; 4 | this.options = options; 5 | this.utils = utils; 6 | this.commands = { 7 | esmCustomCommand: { 8 | usage: 'Description of custom command', 9 | configDependent: false, 10 | }, 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/plugin/node_modules/esm-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/plugin/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = class TestPlugin { 4 | constructor(serverless, options, utils) { 5 | this.serverless = serverless; 6 | this.options = options; 7 | this.utils = utils; 8 | this.commands = { 9 | customCommand: { 10 | usage: 'Description of custom command', 11 | configDependent: false, 12 | }, 13 | }; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/plugin/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | frameworkVersion: '*' 5 | 6 | provider: 7 | name: aws 8 | runtime: nodejs18.x 9 | 10 | plugins: 11 | - ./plugin 12 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/provisioned-concurrency/core.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function handler(event, context, callback) { 4 | const functionName = 'provisionedFunc'; 5 | const { Records } = event; 6 | const messages = Records.map((record) => { 7 | if (record.eventSource === 'aws:sqs') { 8 | return record.body; 9 | } else if (record.eventSource === 'aws:kinesis') { 10 | return Buffer.from(record.kinesis.data, 'base64').toString(); 11 | } 12 | return ''; 13 | }); 14 | // eslint-disable-next-line no-console 15 | console.log(functionName, JSON.stringify(messages)); 16 | return callback(null, event); 17 | } 18 | 19 | module.exports = { handler }; 20 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/provisioned-concurrency/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | 5 | provider: 6 | name: aws 7 | runtime: nodejs18.x 8 | versionFunctions: false 9 | 10 | functions: 11 | provisionedFunc: 12 | handler: core.handler 13 | provisionedConcurrency: 1 14 | events: 15 | - stream: 16 | type: kinesis 17 | arn: 18 | Fn::Join: 19 | - ':' 20 | - - arn 21 | - aws 22 | - kinesis 23 | - Ref: AWS::Region 24 | - Ref: AWS::AccountId 25 | - stream/${self:service}-kinesis 26 | - sqs: 27 | arn: 28 | Fn::Join: 29 | - ':' 30 | - - arn 31 | - aws 32 | - sqs 33 | - Ref: AWS::Region 34 | - Ref: AWS::AccountId 35 | - ${self:service}-provisioned 36 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/request-parameters/target.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = () => { 4 | return { 5 | statusCode: 200, 6 | body: 'OK', 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/request-schema/dummy-schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "definitions": {}, 3 | "$schema": "http://json-schema.org/draft-04/schema#", 4 | "type": "object", 5 | "title": "Test Validation Schema", 6 | "required": ["id"], 7 | "properties": { 8 | "id": { 9 | "type": "number", 10 | "title": "ID for object", 11 | "pattern": "[0-9]+" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/request-schema/target.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.handler = () => { 4 | return { 5 | statusCode: 200, 6 | body: 'OK', 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/s3/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const logger = console; 4 | 5 | function getMarkers(functionName) { 6 | return { 7 | start: `--- START ${functionName} ---`, 8 | end: `--- END ${functionName} ---`, 9 | }; 10 | } 11 | 12 | function log(functionName, message) { 13 | const markers = getMarkers(functionName); 14 | logger.log(markers.start); 15 | logger.log(message); 16 | logger.log(markers.end); 17 | } 18 | 19 | module.exports = { 20 | getMarkers, 21 | log, 22 | }; 23 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/schedule/core.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // NOTE: the `utils.js` file is bundled into the deployment package 4 | // eslint-disable-next-line 5 | const { log } = require('./utils'); 6 | 7 | function scheduleMinimal(event, context, callback) { 8 | const functionName = 'scheduleMinimal'; 9 | log(functionName, JSON.stringify(event)); 10 | return callback(null, event); 11 | } 12 | 13 | function scheduleExtended(event, context, callback) { 14 | const functionName = 'scheduleExtended'; 15 | log(functionName, JSON.stringify(event)); 16 | return callback(null, event); 17 | } 18 | 19 | function scheduleExtendedArray(event, context, callback) { 20 | const functionName = 'scheduleExtendedArray'; 21 | log(functionName, JSON.stringify(event)); 22 | return callback(null, event); 23 | } 24 | 25 | module.exports = { scheduleMinimal, scheduleExtended, scheduleExtendedArray }; 26 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/schedule/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const logger = console; 4 | 5 | function getMarkers(functionName) { 6 | return { 7 | start: `--- START ${functionName} ---`, 8 | end: `--- END ${functionName} ---`, 9 | }; 10 | } 11 | 12 | function log(functionName, message) { 13 | const markers = getMarkers(functionName); 14 | logger.log(markers.start); 15 | logger.log(message); 16 | logger.log(markers.end); 17 | } 18 | 19 | module.exports = { 20 | getMarkers, 21 | log, 22 | }; 23 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/sns/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const logger = console; 4 | 5 | function getMarkers(functionName) { 6 | return { 7 | start: `--- START ${functionName} ---`, 8 | end: `--- END ${functionName} ---`, 9 | }; 10 | } 11 | 12 | function log(functionName, message) { 13 | const markers = getMarkers(functionName); 14 | logger.log(markers.start); 15 | logger.log(message); 16 | logger.log(markers.end); 17 | } 18 | 19 | module.exports = { 20 | getMarkers, 21 | log, 22 | }; 23 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/sqs/core.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // NOTE: the `utils.js` file is bundled into the deployment package 4 | // eslint-disable-next-line 5 | const { log } = require('./utils'); 6 | 7 | function sqsBasic(event, context, callback) { 8 | const functionName = 'sqsBasic'; 9 | log(functionName, JSON.stringify(event)); 10 | return callback(null, event); 11 | } 12 | 13 | module.exports = { sqsBasic }; 14 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/sqs/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | 5 | provider: 6 | name: aws 7 | runtime: nodejs18.x 8 | versionFunctions: false 9 | 10 | functions: 11 | sqsBasic: 12 | handler: core.sqsBasic 13 | events: 14 | - sqs: 15 | arn: 16 | Fn::Join: 17 | - ':' 18 | - - arn 19 | - aws 20 | - sqs 21 | - Ref: AWS::Region 22 | - Ref: AWS::AccountId 23 | - ${self:service}-basic 24 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/sqs/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const logger = console; 4 | 5 | function getMarkers(functionName) { 6 | return { 7 | start: `--- START ${functionName} ---`, 8 | end: `--- END ${functionName} ---`, 9 | }; 10 | } 11 | 12 | function log(functionName, message) { 13 | const markers = getMarkers(functionName); 14 | logger.log(markers.start); 15 | logger.log(message); 16 | logger.log(markers.end); 17 | } 18 | 19 | module.exports = { 20 | getMarkers, 21 | log, 22 | }; 23 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/stream/core.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // NOTE: the `utils.js` file is bundled into the deployment package 4 | // eslint-disable-next-line 5 | const { log } = require('./utils'); 6 | 7 | function streamKinesis(event, context, callback) { 8 | const functionName = 'streamKinesis'; 9 | const { Records } = event; 10 | const messages = Records.map(({ kinesis: { data } }) => Buffer.from(data, 'base64').toString()); 11 | log(functionName, JSON.stringify(messages)); 12 | return callback(null, event); 13 | } 14 | 15 | function streamDynamoDb(event, context, callback) { 16 | const functionName = 'streamDynamoDb'; 17 | log(functionName, JSON.stringify(event)); 18 | return callback(null, event); 19 | } 20 | 21 | module.exports = { streamKinesis, streamDynamoDb }; 22 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/stream/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const logger = console; 4 | 5 | function getMarkers(functionName) { 6 | return { 7 | start: `--- START ${functionName} ---`, 8 | end: `--- END ${functionName} ---`, 9 | }; 10 | } 11 | 12 | function log(functionName, message) { 13 | const markers = getMarkers(functionName); 14 | logger.log(markers.start); 15 | logger.log(message); 16 | logger.log(markers.end); 17 | } 18 | 19 | module.exports = { 20 | getMarkers, 21 | log, 22 | }; 23 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/variables-legacy/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": "bar" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/variables-legacy/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | provider: 4 | name: aws 5 | runtime: nodejs18.x 6 | 7 | custom: 8 | importedFile: ${file(config.json)} 9 | importedFileWithKey: ${file(config.json):foo} 10 | importedTerraformState: ${file(terraform.tfstate)} 11 | importedTerraformStateWithKey: ${file(terraform.tfstate):outputs.listenerarn.type} 12 | awsVariable: ${AWS::Region} 13 | cloudFormationReference: ${AnotherResource} 14 | selfReference: ${self:custom.importedFileWithKey} 15 | serviceReference: ${self:} 16 | nestedRef: nestedVal 17 | nestedVal: 18 | prop: resolvedNested 19 | nestedReference: ${self:custom.${self:custom.nestedRef}.prop} 20 | prototype: 21 | nestedInPrototype: ${file(config.json):foo}-in-prototype 22 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/variables-legacy/terraform.tfstate: -------------------------------------------------------------------------------- 1 | { 2 | "version": 4, 3 | "terraform_version": "0.14.4", 4 | "serial": 11, 5 | "lineage": "12ab3c45-abc1-0a1b-1a23-a12b34567c89", 6 | "outputs": { 7 | "listenerarn": { 8 | "value": "arn:aws:elasticloadbalancing:us-west-2:123456789876:listener/app/myapp/1a2b3c4f1a23456b/a1b23c45de6789fa", 9 | "type": "string" 10 | } 11 | }, 12 | "resources": [] 13 | } 14 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/websocket-external-auth/core.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.minimal = async function minimal() { 4 | return { statusCode: 200 }; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/websocket-external-auth/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | 5 | provider: 6 | name: aws 7 | runtime: nodejs18.x 8 | versionFunctions: false 9 | 10 | functions: 11 | # core functions 12 | minimal: 13 | handler: core.minimal 14 | events: 15 | - websocket: 16 | route: $connect 17 | authorizer: 18 | arn: 'arn:aws:lambda:us-east-1:000000000000:function:auth' 19 | - websocket: 20 | route: $disconnect 21 | - websocket: 22 | route: $default 23 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/websocket/core.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function minimal(event, context, callback) { 4 | // eslint-disable-next-line no-console 5 | console.info('Event type', event.requestContext.eventType); 6 | // eslint-disable-next-line no-console 7 | if (event.body) console.info('Event body', event.body); 8 | return callback(null, { statusCode: 200 }); 9 | } 10 | 11 | function sayHello(event, context, callback) { 12 | const body = JSON.parse(event.body); 13 | return callback(null, { statusCode: 200, body: `Hello, ${body.name}` }); 14 | } 15 | 16 | module.exports = { 17 | minimal, 18 | sayHello, 19 | }; 20 | -------------------------------------------------------------------------------- /test/fixtures/programmatic/websocket/serverless.yml: -------------------------------------------------------------------------------- 1 | service: service 2 | 3 | configValidationMode: error 4 | 5 | provider: 6 | name: aws 7 | runtime: nodejs18.x 8 | versionFunctions: false 9 | logs: 10 | websocket: true 11 | 12 | functions: 13 | # core functions 14 | minimal: 15 | handler: core.minimal 16 | events: 17 | - websocket: 18 | route: $connect 19 | - websocket: 20 | route: $disconnect 21 | - websocket: 22 | route: $default 23 | sayHello: 24 | handler: core.sayHello 25 | events: 26 | - websocket: 27 | route: hello 28 | routeResponseSelectionExpression: $default 29 | -------------------------------------------------------------------------------- /test/integration-package/fixtures/artifact/artifact.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oss-serverless/serverless/7360437f85c4dc6906dd94e658732c3aac6487b4/test/integration-package/fixtures/artifact/artifact.zip -------------------------------------------------------------------------------- /test/integration-package/fixtures/artifact/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.hello = function (event) { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify( 7 | { 8 | message: 'Go Serverless v1.0! Your function executed successfully!', 9 | input: event, 10 | }, 11 | null, 12 | 2 13 | ), 14 | }; 15 | 16 | // Use this code if you don't use the http event with the LAMBDA-PROXY integration 17 | // return { message: 'Go Serverless v1.0! Your function executed successfully!', event }; 18 | }; 19 | -------------------------------------------------------------------------------- /test/integration-package/fixtures/artifact/serverless.yml: -------------------------------------------------------------------------------- 1 | service: aws-nodejs 2 | 3 | configValidationMode: error 4 | 5 | provider: 6 | name: aws 7 | runtime: nodejs18.x 8 | 9 | functions: 10 | hello: 11 | handler: handler.hello 12 | 13 | package: 14 | artifact: artifact.zip 15 | -------------------------------------------------------------------------------- /test/integration-package/fixtures/individually-function/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.hello = function (event) { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify( 7 | { 8 | message: 'Go Serverless v1.0! Your function executed successfully!', 9 | input: event, 10 | }, 11 | null, 12 | 2 13 | ), 14 | }; 15 | 16 | // Use this code if you don't use the http event with the LAMBDA-PROXY integration 17 | // return { message: 'Go Serverless v1.0! Your function executed successfully!', event }; 18 | }; 19 | -------------------------------------------------------------------------------- /test/integration-package/fixtures/individually-function/handler2.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.hello = function (event) { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify( 7 | { 8 | message: 'Go Serverless v1.0! Your function executed successfully!', 9 | input: event, 10 | }, 11 | null, 12 | 2 13 | ), 14 | }; 15 | 16 | // Use this code if you don't use the http event with the LAMBDA-PROXY integration 17 | // return { message: 'Go Serverless v1.0! Your function executed successfully!', event }; 18 | }; 19 | -------------------------------------------------------------------------------- /test/integration-package/fixtures/individually-function/serverless.yml: -------------------------------------------------------------------------------- 1 | service: aws-nodejs 2 | 3 | configValidationMode: error 4 | 5 | provider: 6 | name: aws 7 | runtime: nodejs18.x 8 | 9 | functions: 10 | hello: 11 | handler: handler.hello 12 | package: 13 | individually: true 14 | patterns: 15 | - handler.js 16 | - '!handler2.js' 17 | hello2: 18 | handler: handler2.hello 19 | package: 20 | individually: true 21 | patterns: 22 | - handler2.js 23 | - '!handler.js' 24 | -------------------------------------------------------------------------------- /test/integration-package/fixtures/individually/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.hello = function (event) { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify( 7 | { 8 | message: 'Go Serverless v1.0! Your function executed successfully!', 9 | input: event, 10 | }, 11 | null, 12 | 2 13 | ), 14 | }; 15 | 16 | // Use this code if you don't use the http event with the LAMBDA-PROXY integration 17 | // return { message: 'Go Serverless v1.0! Your function executed successfully!', event }; 18 | }; 19 | -------------------------------------------------------------------------------- /test/integration-package/fixtures/individually/handler2.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.hello = function (event) { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify( 7 | { 8 | message: 'Go Serverless v1.0! Your function executed successfully!', 9 | input: event, 10 | }, 11 | null, 12 | 2 13 | ), 14 | }; 15 | 16 | // Use this code if you don't use the http event with the LAMBDA-PROXY integration 17 | // return { message: 'Go Serverless v1.0! Your function executed successfully!', event }; 18 | }; 19 | -------------------------------------------------------------------------------- /test/integration-package/fixtures/individually/serverless.yml: -------------------------------------------------------------------------------- 1 | service: aws-nodejs 2 | 3 | configValidationMode: error 4 | 5 | provider: 6 | name: aws 7 | runtime: nodejs18.x 8 | 9 | package: 10 | individually: true 11 | 12 | functions: 13 | hello: 14 | handler: handler.hello 15 | package: 16 | patterns: 17 | - handler.js 18 | - '!handler2.js' 19 | hello2: 20 | handler: handler2.hello 21 | package: 22 | patterns: 23 | - handler2.js 24 | - '!handler.js' 25 | -------------------------------------------------------------------------------- /test/integration-package/fixtures/regular/handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.hello = function (event) { 4 | return { 5 | statusCode: 200, 6 | body: JSON.stringify( 7 | { 8 | message: 'Go Serverless v1.0! Your function executed successfully!', 9 | input: event, 10 | }, 11 | null, 12 | 2 13 | ), 14 | }; 15 | 16 | // Use this code if you don't use the http event with the LAMBDA-PROXY integration 17 | // return { message: 'Go Serverless v1.0! Your function executed successfully!', event }; 18 | }; 19 | -------------------------------------------------------------------------------- /test/integration-package/fixtures/regular/serverless.yml: -------------------------------------------------------------------------------- 1 | service: aws-nodejs 2 | 3 | configValidationMode: error 4 | 5 | provider: 6 | name: aws 7 | runtime: nodejs18.x 8 | 9 | functions: 10 | hello: 11 | handler: handler.hello 12 | custom-name: 13 | name: ${self:service}-${opt:region, self:provider.region, 'us-east-1'}-custom-name 14 | handler: handler.hello 15 | -------------------------------------------------------------------------------- /test/serverless-binary.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = (() => { 6 | if (process.env.SERVERLESS_BINARY_PATH) return path.resolve(process.env.SERVERLESS_BINARY_PATH); 7 | return path.join(__dirname, '../bin/serverless.js'); 8 | })(); 9 | -------------------------------------------------------------------------------- /test/unit/lib/cli/commands-schema/common-options/aws-service.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { expect } = require('chai'); 4 | const awsServiceCommonOptions = require('../../../../../../lib/cli/commands-schema/common-options/aws-service'); 5 | 6 | describe('test/unit/lib/cli/commands-schema/common-options/aws-service.test.js', () => { 7 | it('should expose global common options', () => 8 | expect(awsServiceCommonOptions).to.have.property('help')); 9 | it('should expose service common options', () => 10 | expect(awsServiceCommonOptions).to.have.property('config')); 11 | it('should expose AWS service common options', () => 12 | expect(awsServiceCommonOptions).to.have.property('region')); 13 | }); 14 | -------------------------------------------------------------------------------- /test/unit/lib/cli/commands-schema/common-options/global.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { expect } = require('chai'); 4 | const globalCommonOptions = require('../../../../../../lib/cli/commands-schema/common-options/global'); 5 | 6 | describe('test/unit/lib/cli/commands-schema/common-options/global.test.js', () => { 7 | it('should expose global common options', () => 8 | expect(globalCommonOptions).to.have.property('help')); 9 | it('should not expose service common options', () => 10 | expect(globalCommonOptions).to.not.have.property('config')); 11 | it('should not expose AWS service common options', () => 12 | expect(globalCommonOptions).to.not.have.property('region')); 13 | }); 14 | -------------------------------------------------------------------------------- /test/unit/lib/cli/commands-schema/common-options/service.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { expect } = require('chai'); 4 | const serviceCommonOptions = require('../../../../../../lib/cli/commands-schema/common-options/service'); 5 | 6 | describe('test/unit/lib/cli/commands-schema/common-options/service.test.js', () => { 7 | it('should expose global common options', () => 8 | expect(serviceCommonOptions).to.have.property('help')); 9 | it('should expose service common options', () => 10 | expect(serviceCommonOptions).to.have.property('config')); 11 | it('should not expose AWS service common options', () => 12 | expect(serviceCommonOptions).to.not.have.property('region')); 13 | }); 14 | -------------------------------------------------------------------------------- /test/unit/lib/cli/render-help/general.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { expect } = require('chai'); 4 | const renderGeneralHelp = require('../../../../../lib/cli/render-help/general'); 5 | const observeOutput = require('@serverless/test/observe-output'); 6 | 7 | describe('test/unit/lib/cli/render-help/general.test.js', () => { 8 | it('should show help', async () => { 9 | const output = await observeOutput(() => renderGeneralHelp(new Set())); 10 | expect(output).to.have.string('Usage'); 11 | expect(output).to.have.string('deploy function'); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /test/unit/lib/cli/render-help/generate-command-usage.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { expect } = require('chai'); 4 | const generateCommandUsage = require('../../../../../lib/cli/render-help/generate-command-usage'); 5 | const commandsSchema = require('../../../../../lib/cli/commands-schema/no-service'); 6 | 7 | describe('test/unit/lib/cli/render-help/generate-command-usage.test.js', () => { 8 | it('should generate usage info', async () => { 9 | const commandSchema = commandsSchema.get('config'); 10 | const resultString = generateCommandUsage('config', commandSchema); 11 | expect(resultString).to.have.string('config'); 12 | expect(resultString).to.have.string(commandSchema.usage); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /test/unit/lib/cli/render-help/options.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { expect } = require('chai'); 4 | const renderOptionsHelp = require('../../../../../lib/cli/render-help/options'); 5 | const observeOutput = require('@serverless/test/observe-output'); 6 | 7 | describe('test/unit/lib/cli/render-help/options.test.js', () => { 8 | it('should list options', async () => { 9 | const output = await observeOutput(() => 10 | renderOptionsHelp({ 11 | foo: { 12 | usage: 'Some option', 13 | shortcut: 'b', 14 | required: true, 15 | }, 16 | bar: { 17 | usage: 'Elo', 18 | }, 19 | noData: {}, 20 | }) 21 | ); 22 | expect(output).to.have.string('--foo'); 23 | expect(output).to.have.string('-b'); 24 | expect(output).to.have.string('Some option'); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /test/unit/lib/cli/render-version.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { expect } = require('chai'); 4 | const listVersion = require('../../../../lib/cli/render-version'); 5 | const observeOutput = require('@serverless/test/observe-output'); 6 | 7 | describe('test/unit/lib/cli/list-version.test.js', () => { 8 | it('should log version', async () => { 9 | const output = await observeOutput(() => listVersion()); 10 | expect(output).to.have.string('osls version: '); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/@osls/compose/js/project/serverless-compose.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | name: 'serverless-compose-example', 5 | services: { 6 | resources: { 7 | path: 'resources', 8 | }, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/@osls/compose/json/project/serverless-compose.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "serverless-compose-example", 3 | "services": { 4 | "resources": { 5 | "path": "resources" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/@osls/compose/ts/project/serverless-compose.ts: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "name": "serverless-compose-example", 3 | "services": { 4 | "resources": { 5 | "path": "resources" 6 | } 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/@osls/compose/yaml/project/serverless-compose.yaml: -------------------------------------------------------------------------------- 1 | name: serverless-compose-example 2 | 3 | services: 4 | resources: 5 | path: resources 6 | 7 | producer: 8 | path: producer 9 | params: 10 | workerQueueArn: ${resources.WorkerQueueArn} 11 | workerQueueUrl: ${resources.WorkerQueueUrl} 12 | 13 | consumer: 14 | path: consumer 15 | params: 16 | workerQueueArn: ${resources.WorkerQueueArn} 17 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/@osls/compose/yml/project/serverless-compose.yml: -------------------------------------------------------------------------------- 1 | name: serverless-compose-example 2 | 3 | services: 4 | resources: 5 | path: resources 6 | 7 | producer: 8 | path: producer 9 | params: 10 | workerQueueArn: ${resources.WorkerQueueArn} 11 | workerQueueUrl: ${resources.WorkerQueueUrl} 12 | 13 | consumer: 14 | path: consumer 15 | params: 16 | workerQueueArn: ${resources.WorkerQueueArn} 17 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/serverless/js/component-in-custom/serverless.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { service: 'foo', provider: { name: 'foo' }, custom: { component: 'foo' } }; 4 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/serverless/js/projects/bar/serverless.yml: -------------------------------------------------------------------------------- 1 | service: foo 2 | provider: 3 | name: any 4 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/serverless/js/projects/foo/serverless.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { component: 'foo' }; 4 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/serverless/json/component-in-custom/serverless.json: -------------------------------------------------------------------------------- 1 | { "service": "foo", "provider": { "name": "foo" }, "custom": { "component": "foo" } } 2 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/serverless/json/projects/bar/serverless.yml: -------------------------------------------------------------------------------- 1 | service: foo 2 | provider: 3 | name: any 4 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/serverless/json/projects/foo/serverless.json: -------------------------------------------------------------------------------- 1 | { "component": "foo" } 2 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/serverless/ts/any/serverless.ts: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | foo: { component: 'foo' }, 3 | }; 4 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/serverless/yml/component-in-custom/serverless.yml: -------------------------------------------------------------------------------- 1 | service: foo 2 | 3 | provider: 4 | name: aws 5 | 6 | custom: 7 | component: foo 8 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/serverless/yml/projects/bar/serverless.yml: -------------------------------------------------------------------------------- 1 | service: foo 2 | provider: 3 | name: any 4 | -------------------------------------------------------------------------------- /test/unit/lib/cli/triage/fixtures/serverless/yml/projects/foo/serverless.yml: -------------------------------------------------------------------------------- 1 | component: foo 2 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/humanize-property-path-keys.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { expect } = require('chai'); 4 | 5 | const humanizePropertyPathTokens = require('../../../../../lib/configuration/variables/humanize-property-path-keys'); 6 | 7 | describe('test/unit/lib/configuration/variables/humanize-property-path-tokens.test.js', () => { 8 | it('should resolve human frendly path string', () => { 9 | expect(humanizePropertyPathTokens(['foo'])).to.equal('foo'); 10 | expect(humanizePropertyPathTokens(['foo', 'bar'])).to.equal('foo.bar'); 11 | expect(humanizePropertyPathTokens(['foo', 'bar', '1'])).to.equal('foo.bar.1'); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/dir.yaml/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oss-serverless/serverless/7360437f85c4dc6906dd94e658732c3aac6487b4/test/unit/lib/configuration/variables/sources/fixture/dir.yaml/.gitkeep -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-ambiguous.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": { "bar": "object" }, 3 | "foo.bar": "string" 4 | } 5 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-function-access-unresolvable-property.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ({ resolveConfigurationProperty }) => 4 | resolveConfigurationProperty(['unresolvable']); 5 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-function-errored-non-error.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = () => { 4 | throw null; // eslint-disable-line no-throw-literal 5 | }; 6 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-function-errored.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = () => { 4 | throw new Error('Stop'); 5 | }; 6 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-function-many-variables.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = async ({ resolveVariable }) => ({ 4 | varResult: await resolveVariable('file(file-function-many-variables.yaml)'), 5 | }); 6 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-function-many-variables.yaml: -------------------------------------------------------------------------------- 1 | # The resolve nest depth is 10, so we have to resolve at least 10 files to ensure it's not being hit. 2 | result: 3 | - ${file(./file.yml):result} 4 | - ${file(./file.yml):result} 5 | - ${file(./file.yml):result} 6 | - ${file(./file.yml):result} 7 | - ${file(./file.yml):result} 8 | - ${file(./file.yml):result} 9 | - ${file(./file.yml):result} 10 | - ${file(./file.yml):result} 11 | - ${file(./file.yml):result} 12 | - ${file(./file.yml):result} 13 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-function-variable-missing-source.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = async ({ resolveVariable }) => ({ 4 | varResult: await resolveVariable('file(missing.yaml)'), 5 | }); 6 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-function-variable.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = async ({ resolveVariable }) => ({ 4 | varResult: await resolveVariable('file(file.yaml)'), 5 | }); 6 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-function.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = () => ({ result: 'js-function' }); 4 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-primitive.json: -------------------------------------------------------------------------------- 1 | 20 2 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-promise-rejected-non-error.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = Promise.reject(null); 4 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-promise-rejected.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = Promise.reject(new Error('Stop')); 4 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-property-function-access-unresolvable-property.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.property = ({ resolveConfigurationProperty }) => 4 | resolveConfigurationProperty(['unresolvable']); 5 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-property-function-errored-non-error.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.property = () => { 4 | throw null; // eslint-disable-line no-throw-literal 5 | }; 6 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-property-function-errored.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.property = () => { 4 | throw new Error('Stop'); 5 | }; 6 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-property-function-variable-missing-source.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.property = async ({ resolveVariable }) => ({ 4 | varResult: await resolveVariable('file(missing.json)'), 5 | }); 6 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-property-function-variable.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.property = async ({ resolveVariable }) => ({ 4 | varResult: await resolveVariable('file(file.json)'), 5 | }); 6 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-property-function.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.property = () => ({ result: 'js-property-function' }); 4 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-property-promise.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports.property = Promise.resolve({ result: 'js-property-promise' }); 4 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-variables-nest-1.yaml: -------------------------------------------------------------------------------- 1 | n1: ${file(./file-variables-nest-2.yaml):root} 2 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-variables-nest-2.yaml: -------------------------------------------------------------------------------- 1 | root: 2 | n2: ${file(./file-variables-nest-3.yaml):root} 3 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file-variables-nest-3.yaml: -------------------------------------------------------------------------------- 1 | root: 2 | n3: result 3 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file.cjs: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = Promise.resolve({ result: 'cjs' }); 4 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = Promise.resolve({ result: 'js' }); 4 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file.json: -------------------------------------------------------------------------------- 1 | { "result": "json" } 2 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file.tfstate: -------------------------------------------------------------------------------- 1 | { "result": "tfstate" } 2 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file.yaml: -------------------------------------------------------------------------------- 1 | result: yaml 2 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/file.yml: -------------------------------------------------------------------------------- 1 | result: yml 2 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/invalid.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | throw new Error('Stop'); 4 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/invalid.json: -------------------------------------------------------------------------------- 1 | "result": "json" 2 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/invalid.yml: -------------------------------------------------------------------------------- 1 | foo: 2 | foo 3 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/invalid2.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | throw null; // eslint-disable-line no-throw-literal 4 | -------------------------------------------------------------------------------- /test/unit/lib/configuration/variables/sources/fixture/non-standard.ext: -------------------------------------------------------------------------------- 1 | result: non-standard 2 | -------------------------------------------------------------------------------- /test/unit/lib/plugins/aws/custom-resources/test/eventBridge.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { expect } = require('chai'); 4 | const { 5 | getEventBusTargetId, 6 | } = require('../../../../../../../lib/plugins/aws/custom-resources/resources/event-bridge/lib/utils'); 7 | 8 | describe('#getEventBusTargetId()', () => { 9 | const assertions = [ 10 | { ruleName: 'some-function-name-rule-1' }, 11 | { ruleName: 'some-very-very-very-long-and-complicated-function-name-rule-1' }, 12 | ]; 13 | 14 | assertions.forEach(({ ruleName }) => { 15 | it(`should append "target" suffix on ${ruleName} and ensure output targetId length is less than or equal 64`, () => { 16 | const targetId = getEventBusTargetId(ruleName); 17 | 18 | expect(targetId.endsWith('target')).to.be.true; 19 | expect(targetId).lengthOf.lte(64); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /test/unit/lib/plugins/aws/utils/resolve-cf-import-value.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const expect = require('chai').expect; 4 | const resolveCfImportValue = require('../../../../../../lib/plugins/aws/utils/resolve-cf-import-value'); 5 | 6 | describe('#resolveCfImportValue', () => { 7 | it('should return matching exported value if found', async () => { 8 | const provider = { 9 | request: async () => ({ 10 | Exports: [ 11 | { 12 | Name: 'anotherName', 13 | Value: 'anotherValue', 14 | }, 15 | { 16 | Name: 'exportName', 17 | Value: 'exportValue', 18 | }, 19 | ], 20 | }), 21 | }; 22 | const result = await resolveCfImportValue(provider, 'exportName'); 23 | expect(result).to.equal('exportValue'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /test/unit/lib/plugins/aws/utils/resolve-cf-ref-value.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const expect = require('chai').expect; 4 | const resolveCfRefValue = require('../../../../../../lib/plugins/aws/utils/resolve-cf-ref-value'); 5 | 6 | describe('#resolveCfRefValue', () => { 7 | it('should return matching exported value if found', async () => { 8 | const provider = { 9 | naming: { 10 | getStackName: () => 'stack-name', 11 | }, 12 | request: async () => ({ 13 | StackResourceSummaries: [ 14 | { 15 | LogicalResourceId: 'myS3', 16 | PhysicalResourceId: 'stack-name-s3-id', 17 | }, 18 | { 19 | LogicalResourceId: 'myDB', 20 | PhysicalResourceId: 'stack-name-db-id', 21 | }, 22 | ], 23 | }), 24 | }; 25 | const result = await resolveCfRefValue(provider, 'myDB'); 26 | expect(result).to.equal('stack-name-db-id'); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /test/unit/lib/plugins/config.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const BbPromise = require('bluebird'); 5 | const runServerless = require('../../../utils/run-serverless'); 6 | 7 | BbPromise.promisifyAll(fs); 8 | 9 | describe('Config', () => { 10 | it('should support "config credentials" command', () => 11 | runServerless({ 12 | noService: true, 13 | command: 'config credentials', 14 | options: { provider: 'aws', key: 'foo', secret: 'bar' }, 15 | })); 16 | }); 17 | -------------------------------------------------------------------------------- /test/unit/lib/plugins/info.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const chai = require('chai'); 4 | const Info = require('../../../../lib/plugins/info'); 5 | const Serverless = require('../../../../lib/serverless'); 6 | 7 | const expect = chai.expect; 8 | chai.use(require('chai-as-promised')); 9 | chai.use(require('sinon-chai')); 10 | 11 | describe('Info', () => { 12 | let info; 13 | let serverless; 14 | 15 | beforeEach(() => { 16 | serverless = new Serverless({ commands: [], options: {} }); 17 | info = new Info(serverless); 18 | }); 19 | 20 | describe('#constructor()', () => { 21 | it('should have commands', () => expect(info.commands).to.be.not.empty); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /test/unit/lib/plugins/metrics.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const expect = require('chai').expect; 4 | const Metrics = require('../../../../lib/plugins/metrics'); 5 | const Serverless = require('../../../../lib/serverless'); 6 | 7 | describe('Metrics', () => { 8 | let metrics; 9 | let serverless; 10 | 11 | beforeEach(() => { 12 | serverless = new Serverless({ commands: [], options: {} }); 13 | const options = {}; 14 | metrics = new Metrics(serverless, options); 15 | }); 16 | 17 | describe('#constructor()', () => { 18 | it('should have the command "metrics"', () => { 19 | // eslint-disable-next-line no-unused-expressions 20 | expect(metrics.commands.metrics).to.not.be.undefined; 21 | }); 22 | 23 | it('should have a lifecycle event "metrics"', () => { 24 | expect(metrics.commands.metrics.lifecycleEvents).to.deep.equal(['metrics']); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/unit/lib/plugins/print.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const chai = require('chai'); 4 | 5 | const runServerless = require('../../../utils/run-serverless'); 6 | 7 | chai.use(require('chai-as-promised')); 8 | 9 | const expect = chai.expect; 10 | 11 | describe('test/unit/lib/plugins/print.test.js', () => { 12 | it('correctly prints config', async () => { 13 | const { output } = await runServerless({ 14 | fixture: 'aws', 15 | command: 'print', 16 | }); 17 | 18 | expect(output).to.include('name: aws'); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/unit/lib/plugins/remove.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const chai = require('chai'); 4 | const Remove = require('../../../../lib/plugins/remove'); 5 | const Serverless = require('../../../../lib/serverless'); 6 | 7 | const expect = chai.expect; 8 | 9 | describe('Remove', () => { 10 | let remove; 11 | let serverless; 12 | 13 | beforeEach(() => { 14 | serverless = new Serverless({ commands: [], options: {} }); 15 | remove = new Remove(serverless); 16 | }); 17 | 18 | describe('#constructor()', () => { 19 | it('should have access to the serverless instance', () => { 20 | expect(remove.serverless).to.deep.equal(serverless); 21 | }); 22 | 23 | it('should have commands', () => expect(remove.commands).to.be.not.empty); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /test/unit/lib/templates/recommended-list.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { expect } = require('chai'); 4 | 5 | const humanReadable = require('../../../../lib/templates/recommended-list/human-readable'); 6 | 7 | describe('test/unit/lib/templates/recommended-list.test.js', () => { 8 | // Sanity check 9 | it('should export string withlist of templates', async () => { 10 | expect(typeof humanReadable).to.equal('string'); 11 | expect(humanReadable).to.include('aws-nodejs'); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /test/unit/lib/utils/fs/create-zip-file.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const chai = require('chai'); 5 | const createZipFile = require('../../../../../lib/utils/fs/create-zip-file'); 6 | const { createTmpFile, listZipFiles } = require('../../../../utils/fs'); 7 | 8 | // Configure chai 9 | chai.use(require('chai-as-promised')); 10 | chai.use(require('sinon-chai')); 11 | const expect = require('chai').expect; 12 | 13 | describe('#createZipFile()', () => { 14 | it('should create a zip file with the source directory content', async () => { 15 | const toZipFilePath = createTmpFile('foo.json'); 16 | const zipFilePath = createTmpFile('package.zip'); 17 | 18 | const srcDirPath = toZipFilePath.split(path.sep).slice(0, -1).join(path.sep); 19 | 20 | return createZipFile(srcDirPath, zipFilePath) 21 | .then(listZipFiles) 22 | .then((files) => expect(files).to.deep.equal(['foo.json'])); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /test/unit/lib/utils/fs/file-exists.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const chai = require('chai'); 5 | const fileExists = require('../../../../../lib/utils/fs/file-exists'); 6 | 7 | // Configure chai 8 | chai.use(require('chai-as-promised')); 9 | chai.use(require('sinon-chai')); 10 | const expect = require('chai').expect; 11 | 12 | describe('#fileExists()', () => { 13 | describe('When reading a file', () => { 14 | it('should detect if a file exists', () => 15 | expect(fileExists(__filename)).to.eventually.equal(true)); 16 | 17 | it("should detect if a file doesn't exist", () => 18 | expect(fileExists(path.join(__dirname, 'XYZ.json'))).to.eventually.equal(false)); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/unit/lib/utils/fs/get-tmp-dir-path.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const expect = require('chai').expect; 4 | const getTmpDirPath = require('../../../../../lib/utils/fs/get-tmp-dir-path'); 5 | 6 | describe('#getTmpDirPath()', () => { 7 | it('should return a scoped tmp dir path', () => { 8 | const tmpDirPath = getTmpDirPath(); 9 | expect(tmpDirPath).to.match(/tmpdirs-serverless/); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /test/unit/lib/utils/standalone.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { expect } = require('chai'); 4 | const standalone = require('../../../../lib/utils/standalone'); 5 | 6 | describe('#standalone', () => { 7 | it('Should resolve standalone url', () => 8 | expect(standalone.resolveUrl('v2.8.0')).to.match(/^https:\/\//)); 9 | }); 10 | -------------------------------------------------------------------------------- /test/utils/child-process.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { execSync: originalExecSync } = require('child_process'); 4 | 5 | function execSync(command, options = null) { 6 | // Same as native but outputs std in case of error 7 | try { 8 | return originalExecSync(command, options); 9 | } catch (error) { 10 | if (error.stdout) process.stdout.write(error.stdout); 11 | if (error.stderr) process.stderr.write(error.stderr); 12 | throw error; 13 | } 14 | } 15 | 16 | module.exports = { execSync }; 17 | -------------------------------------------------------------------------------- /test/utils/dynamodb.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const awsRequest = require('@serverless/test/aws-request'); 4 | const DDBDocumentClient = require('aws-sdk').DynamoDB.DocumentClient; 5 | 6 | async function putDynamoDbItem(tableName, item) { 7 | const params = { 8 | TableName: tableName, 9 | Item: item, 10 | }; 11 | 12 | return awsRequest(DDBDocumentClient, 'put', params); 13 | } 14 | 15 | module.exports = { 16 | putDynamoDbItem, 17 | }; 18 | -------------------------------------------------------------------------------- /test/utils/event-bridge.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const awsRequest = require('@serverless/test/aws-request'); 4 | const EventBridgeService = require('aws-sdk').EventBridge; 5 | 6 | async function createEventBus(name) { 7 | return awsRequest(EventBridgeService, 'createEventBus', { Name: name }); 8 | } 9 | 10 | async function deleteEventBus(name) { 11 | return awsRequest(EventBridgeService, 'deleteEventBus', { Name: name }); 12 | } 13 | 14 | async function describeEventBus(name) { 15 | return awsRequest(EventBridgeService, 'describeEventBus', { Name: name }); 16 | } 17 | 18 | async function putEvents(EventBusName, Entries) { 19 | Entries.map((entry) => (entry.EventBusName = EventBusName)); 20 | const params = { 21 | Entries, 22 | }; 23 | return awsRequest(EventBridgeService, 'putEvents', params); 24 | } 25 | 26 | module.exports = { 27 | createEventBus, 28 | deleteEventBus, 29 | describeEventBus, 30 | putEvents, 31 | }; 32 | -------------------------------------------------------------------------------- /test/utils/iot.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const awsRequest = require('@serverless/test/aws-request'); 4 | const IotService = require('aws-sdk').Iot; 5 | const IotDataService = require('aws-sdk').IotData; 6 | 7 | async function resolveIotEndpoint() { 8 | return awsRequest(IotService, 'describeEndpoint', { endpointType: 'iot:Data-ATS' }).then( 9 | (data) => { 10 | return data.endpointAddress; 11 | } 12 | ); 13 | } 14 | 15 | async function publishIotData(topic, message) { 16 | return resolveIotEndpoint().then((endpoint) => { 17 | const params = { 18 | topic, 19 | payload: Buffer.from(message), 20 | }; 21 | 22 | return awsRequest({ client: IotDataService, params: { endpoint } }, 'publish', params); 23 | }); 24 | } 25 | 26 | module.exports = { 27 | resolveIotEndpoint, 28 | publishIotData, 29 | }; 30 | -------------------------------------------------------------------------------- /test/utils/plugins.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fse = require('fs-extra'); 5 | 6 | // mock to test functionality bound to a serverless plugin 7 | class ServerlessPlugin { 8 | constructor(serverless, options, testSubject) { 9 | this.options = options; 10 | this.serverless = serverless; 11 | 12 | Object.assign(this, testSubject); 13 | } 14 | } 15 | 16 | function installPlugin(installDir, PluginClass) { 17 | const pluginPkg = { name: path.basename(installDir), version: '0.0.0' }; 18 | const className = new PluginClass().constructor.name; 19 | fse.outputFileSync(path.join(installDir, 'package.json'), JSON.stringify(pluginPkg), 'utf8'); 20 | fse.outputFileSync( 21 | path.join(installDir, 'index.js'), 22 | `"use strict";\n${PluginClass.toString()}\nmodule.exports = ${className}`, 23 | 'utf8' 24 | ); 25 | } 26 | 27 | module.exports = { 28 | ServerlessPlugin, 29 | installPlugin, 30 | }; 31 | -------------------------------------------------------------------------------- /test/utils/run-serverless.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = require('@serverless/test/setup-run-serverless-fixtures-engine')({ 6 | fixturesDir: path.resolve(__dirname, '../fixtures/programmatic'), 7 | serverlessDir: path.resolve(__dirname, '../../'), 8 | }); 9 | --------------------------------------------------------------------------------