serverless-step-functions
Version:
The module is AWS Step Functions plugin for Serverless Framework
161 lines (136 loc) • 5.35 kB
JavaScript
'use strict';
const BbPromise = require('bluebird');
const _ = require('lodash');
module.exports = {
compileRequestValidators() {
const apiGatewayConfig = this.serverless.service.provider.apiGateway || {};
this.pluginhttpValidated.events.forEach((event) => {
const resourceName = this.getResourceName(event.http.path);
const methodLogicalId = this.provider.naming
.getMethodLogicalId(resourceName, event.http.method);
const template = this.serverless.service.provider
.compiledCloudFormationTemplate.Resources[methodLogicalId];
let validatorLogicalId;
if (event.http.request && event.http.request.schemas) {
for (const [contentType, schemaConfig] of Object.entries(event.http.request.schemas)) {
let modelLogicalId;
const referencedDefinitionFromProvider = !_.isObject(schemaConfig) && _.get(apiGatewayConfig, `request.schemas.${schemaConfig}`);
if (referencedDefinitionFromProvider) {
modelLogicalId = this.createProviderModel(
schemaConfig,
apiGatewayConfig.request.schemas[schemaConfig],
);
} else {
// In this situation, we have two options - schema is defined as
// string that does not reference model from provider or as an object
let modelName;
let description;
let definition;
if (_.isObject(schemaConfig)) {
if (schemaConfig.schema) {
// In this case, schema is defined as an object with explicit properties
modelName = schemaConfig.name;
description = schemaConfig.description;
definition = schemaConfig.schema;
} else {
// In this case, schema is defined as an implicit object that
// stores whole schema definition
definition = schemaConfig;
}
} else {
// In this case, schema is defined as an implicit string
definition = schemaConfig;
}
modelLogicalId = this.provider.naming.getEndpointModelLogicalId(
resourceName,
event.http.method,
contentType,
);
Object.assign(
this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
{
[modelLogicalId]: {
Type: 'AWS::ApiGateway::Model',
Properties: {
RestApiId: this.provider.getApiGatewayRestApiId(),
ContentType: contentType,
Schema: definition,
Name: modelName,
Description: description,
},
},
},
);
}
if (!validatorLogicalId) {
const requestValidator = this.createRequestValidator();
validatorLogicalId = requestValidator.validatorLogicalId;
}
template.Properties.RequestValidatorId = { Ref: validatorLogicalId };
template.Properties.RequestModels = template.Properties.RequestModels || {};
template.Properties.RequestModels[contentType] = { Ref: modelLogicalId };
}
}
});
return BbPromise.resolve();
},
createProviderModel(schemaId, schemaConfig) {
let modelName;
let description;
let definition;
// If schema is not defined this will try to map resourceDefinition as the schema
if (!schemaConfig.schema) {
definition = schemaConfig;
} else {
definition = schemaConfig.schema;
}
const modelLogicalId = this.provider.naming.getModelLogicalId(schemaId);
if (schemaConfig.name) {
modelName = schemaConfig.name;
}
if (schemaConfig.description) {
description = schemaConfig.description;
}
Object.assign(this.serverless.service.provider.compiledCloudFormationTemplate.Resources, {
[modelLogicalId]: {
Type: 'AWS::ApiGateway::Model',
Properties: {
RestApiId: this.provider.getApiGatewayRestApiId(),
Schema: definition,
ContentType: 'application/json',
},
},
});
if (modelName) {
this.serverless.service.provider.compiledCloudFormationTemplate.Resources[
modelLogicalId
].Properties.Name = modelName;
}
if (description) {
this.serverless.service.provider.compiledCloudFormationTemplate.Resources[
modelLogicalId
].Properties.Description = description;
}
return modelLogicalId;
},
createRequestValidator() {
const validatorLogicalId = this.provider.naming.getValidatorLogicalId();
const validatorName = `${
this.serverless.service.service
}-${this.provider.getStage()} | Validate request body and querystring parameters`;
this.serverless.service.provider.compiledCloudFormationTemplate
.Resources[validatorLogicalId] = {
Type: 'AWS::ApiGateway::RequestValidator',
Properties: {
RestApiId: this.provider.getApiGatewayRestApiId(),
ValidateRequestBody: true,
ValidateRequestParameters: true,
Name: validatorName,
},
};
return {
validatorLogicalId,
validatorName,
};
},
};