Skip to content

Commit 624d720

Browse files
committed
ADD: cloudFormation decorator for DynamoTable class; FIX: cli serverless command
1 parent 319aa92 commit 624d720

File tree

8 files changed

+58
-24
lines changed

8 files changed

+58
-24
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { CLASS_CLOUDFORMATION } from '../../constants';
2+
import { getMetadata, defineMetadata } from '../../metadata';
3+
import { rest, CorsConfig } from '../rest';
4+
5+
export const defaultConfig = {
6+
stack: null,
7+
resourceName: null
8+
};
9+
10+
export const cloudFormation = (config?: { stack?: string; resourceName?: string }) => {
11+
return (target: Function) => {
12+
let metadata = getMetadata(CLASS_CLOUDFORMATION, target);
13+
if (!metadata) {
14+
metadata = { ...defaultConfig };
15+
}
16+
defineMetadata(CLASS_CLOUDFORMATION, { ...metadata, ...config }, target);
17+
};
18+
};

src/annotations/classes/dynamoTable.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export const dynamoTable = (tableConfig?: {
4040
...tableConfig,
4141
environmentKey: templatedKey,
4242
tableName: templatedValue,
43-
definedBy: target.name
43+
definedBy: target
4444
})
4545

4646
defineMetadata(CLASS_DYNAMOTABLECONFIGURATIONKEY, [...tableDefinitions], target)

src/annotations/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const CLASS_GROUP = 'functionly:class:group'
77
export const CLASS_ENVIRONMENTKEY = 'functionly:class:environment'
88
export const CLASS_MIDDLEWAREKEY = 'functionly:class:middleware'
99
export const CLASS_APIGATEWAYKEY = 'functionly:class:apigateway'
10+
export const CLASS_CLOUDFORMATION = 'functionly:class:cloudformation'
1011
export const CLASS_CLOUDWATCHEVENT = 'functionly:class:cloudwatchevent'
1112
export const CLASS_TAGKEY = 'functionly:class:tag'
1213
export const CLASS_LOGKEY = 'functionly:class:log'

src/annotations/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export { templates, applyTemplates } from './templates'
22
export { injectable, InjectionScope } from './classes/injectable'
33
export { apiGateway } from './classes/aws/apiGateway'
4+
export { cloudFormation } from './classes/aws/cloudFormation'
45
export { cloudWatchEvent } from './classes/aws/cloudWatchEvent'
56
export { httpTrigger } from './classes/azure/httpTrigger'
67
export { rest, httpGet, httpPost, httpPut, httpPatch, httpDelete, IHttpMethod } from './classes/rest'

src/cli/commands/serverless.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export default (api) => {
6363

6464
for (const tableConfig of context.tableConfigs) {
6565
const properties = { TableName: tableConfig.tableName, ...tableConfig.nativeConfig }
66-
dynamoStatement.Resource.push("arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/" + properties.TableName)
66+
dynamoStatement.Resource.push("arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/" + properties.TableName + '-' + context.stage)
6767
}
6868

6969
context.serverless.provider.iamRoleStatements.push(dynamoStatement)
@@ -146,28 +146,30 @@ export default (api) => {
146146

147147
for (const tableDefinition of context.tableConfigs) {
148148
await executor({
149-
context: { ...context, tableConfig },
149+
context: { ...context, tableConfig: tableDefinition },
150150
name: 'tableConfig',
151-
method: tableConfig
151+
method: tableConfiguration
152152
})
153153
}
154154

155155
}
156156

157-
const tableConfig = async ({ tableConfig, serverless }) => {
157+
const tableConfiguration = async ({ stage, tableConfig, serverless }) => {
158158
const properties = {
159159
...__dynamoDBDefaults,
160160
TableName: tableConfig.tableName,
161161
...tableConfig.nativeConfig
162162
}
163163

164+
const resName = properties.TableName
165+
properties.TableName += '-' + stage
164166

165167
const tableResource = {
166168
"Type": "AWS::DynamoDB::Table",
167169
"Properties": properties
168170
}
169171

170-
const name = normalizeName(properties.TableName)
172+
const name = normalizeName(resName)
171173

172174
serverless.resources.Resources[name] = tableResource
173175
}

src/cli/providers/cloudFormation/context/dynamoTable.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import { defaultsDeep } from 'lodash'
2-
import { __dynamoDBDefaults } from '../../../../annotations'
2+
import { __dynamoDBDefaults, getMetadata, constants } from '../../../../annotations'
33
import { ExecuteStep, executor } from '../../../context'
44
import { setResource } from '../utils'
55
import { createStack, setStackParameter, getStackName } from './stack'
6+
import { cloudFormation } from '../../../../annotations/classes/aws/cloudFormation';
67

78
export const DYNAMODB_TABLE_STACK = 'DynamoDBTableStack'
89

10+
const { CLASS_CLOUDFORMATION } = constants
11+
912
export const tableResources = ExecuteStep.register('DynamoDB-Tables', async (context) => {
1013
await executor({
1114
context: { ...context, stackName: DYNAMODB_TABLE_STACK },
@@ -52,13 +55,21 @@ export const tableResource = async (context) => {
5255
"Properties": properties
5356
}
5457

55-
const tableResourceName = `Dynamo${tableConfig.tableName}`
56-
const resourceName = setResource(context, tableResourceName, dynamoDb, DYNAMODB_TABLE_STACK, true)
58+
tableConfig.tableStackName = DYNAMODB_TABLE_STACK
59+
let tableResourceName = `Dynamo${tableConfig.tableName}`
60+
61+
const cloudFormationConfig = getMetadata(CLASS_CLOUDFORMATION, tableConfig.definedBy)
62+
if (cloudFormationConfig) {
63+
tableConfig.tableStackName = cloudFormationConfig.stack
64+
tableResourceName = cloudFormationConfig.resourceName || tableResourceName
65+
}
66+
67+
const resourceName = setResource(context, tableResourceName, dynamoDb, tableConfig.tableStackName, true)
5768

5869
await setStackParameter({
5970
...context,
6071
resourceName,
61-
sourceStackName: DYNAMODB_TABLE_STACK
72+
sourceStackName: tableConfig.tableStackName
6273
})
6374

6475
tableConfig.resourceName = resourceName
@@ -80,7 +91,7 @@ export const tableSubscribers = ExecuteStep.register('DynamoDB-Table-Subscriptio
8091

8192
export const tableSubscriber = async (context) => {
8293
const { tableConfig, subscriber } = context
83-
94+
8495
if (tableConfig.exists) return
8596

8697
const properties = {
@@ -105,7 +116,7 @@ export const tableSubscriber = async (context) => {
105116
await setStackParameter({
106117
...context,
107118
resourceName: tableConfig.resourceName,
108-
sourceStackName: DYNAMODB_TABLE_STACK,
119+
sourceStackName: tableConfig.tableStackName,
109120
targetStackName: getStackName(subscriber.serviceDefinition),
110121
attr: 'StreamArn'
111122
})
@@ -122,7 +133,7 @@ export const tableSubscriber = async (context) => {
122133

123134
export const dynamoStreamingPolicy = async (context) => {
124135
const { tableConfig, serviceDefinition } = context
125-
136+
126137
if (tableConfig.exists) return
127138

128139
let policy = serviceDefinition.roleResource.Properties.Policies.find(p => p.PolicyDocument.Statement[0].Action.includes('dynamodb:GetRecords'))

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ export { addProvider, removeProvider } from './providers'
1717
export {
1818
injectable, apiGateway, httpTrigger, rest, httpGet, httpPost, httpPut, httpPatch, httpDelete, IHttpMethod, environment,
1919
tag, log, functionName, dynamoTable, sns, s3Storage, eventSource, classConfig, use, description, role, group, aws, azure,
20-
param, serviceParams, request, error, result, functionalServiceName, provider, stage, inject, cloudWatchEvent, dynamo
20+
param, serviceParams, request, error, result, functionalServiceName, provider, stage, inject, cloudWatchEvent, dynamo,
21+
cloudFormation
2122
} from './annotations'
2223
export { mongoCollection, mongoConnection } from './plugins/mongo'
2324

test/annotation.tests.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ describe('annotations', () => {
608608

609609
expect(metadata).to.have.property('tableName', 'DynamoTableTestClass-table')
610610
expect(metadata).to.have.property('environmentKey', 'DynamoTableTestClass_TABLE_NAME')
611-
expect(metadata).to.have.property('definedBy', DynamoTableTestClass.name)
611+
expect(metadata).to.have.property('definedBy', DynamoTableTestClass)
612612
expect(metadata).to.have.deep.property('nativeConfig').that.deep.equal(__dynamoDBDefaults);
613613
})
614614
it("empty", () => {
@@ -623,7 +623,7 @@ describe('annotations', () => {
623623

624624
expect(metadata).to.have.property('tableName', 'DynamoTableTestClass-table')
625625
expect(metadata).to.have.property('environmentKey', 'DynamoTableTestClass_TABLE_NAME')
626-
expect(metadata).to.have.property('definedBy', DynamoTableTestClass.name)
626+
expect(metadata).to.have.property('definedBy', DynamoTableTestClass)
627627
expect(metadata).to.have.deep.property('nativeConfig').that.deep.equal(__dynamoDBDefaults);
628628
})
629629
it("tableName", () => {
@@ -638,7 +638,7 @@ describe('annotations', () => {
638638

639639
expect(metadata).to.have.property('tableName', 'mytablename')
640640
expect(metadata).to.have.property('environmentKey', 'DynamoTableTestClass_TABLE_NAME')
641-
expect(metadata).to.have.property('definedBy', DynamoTableTestClass.name)
641+
expect(metadata).to.have.property('definedBy', DynamoTableTestClass)
642642
expect(metadata).to.have.deep.property('nativeConfig').that.deep.equal(__dynamoDBDefaults);
643643
})
644644
it("environmentKey", () => {
@@ -653,7 +653,7 @@ describe('annotations', () => {
653653

654654
expect(metadata).to.have.property('tableName', 'mytablename')
655655
expect(metadata).to.have.property('environmentKey', 'myenvkey')
656-
expect(metadata).to.have.property('definedBy', DynamoTableTestClass.name)
656+
expect(metadata).to.have.property('definedBy', DynamoTableTestClass)
657657
expect(metadata).to.have.deep.property('nativeConfig').that.deep.equal(__dynamoDBDefaults);
658658
})
659659
it("nativeConfig", () => {
@@ -675,7 +675,7 @@ describe('annotations', () => {
675675

676676
expect(metadata).to.have.property('tableName', 'mytablename')
677677
expect(metadata).to.have.property('environmentKey', 'DynamoTableTestClass_TABLE_NAME')
678-
expect(metadata).to.have.property('definedBy', DynamoTableTestClass.name)
678+
expect(metadata).to.have.property('definedBy', DynamoTableTestClass)
679679
expect(metadata).to.have.deep.property('nativeConfig').that.deep.equal({
680680
...__dynamoDBDefaults,
681681
ProvisionedThroughput: {
@@ -698,7 +698,7 @@ describe('annotations', () => {
698698

699699
expect(metadata).to.have.property('tableName', 'DynamoTableTestClass-table')
700700
expect(metadata).to.have.property('environmentKey', 'DynamoTableTestClass_TABLE_NAME')
701-
expect(metadata).to.have.property('definedBy', DynamoTableTestClass.name)
701+
expect(metadata).to.have.property('definedBy', DynamoTableTestClass)
702702
expect(metadata).to.have.deep.property('nativeConfig').that.deep.equal(__dynamoDBDefaults);
703703
})
704704
it("empty", () => {
@@ -713,7 +713,7 @@ describe('annotations', () => {
713713

714714
expect(metadata).to.have.property('tableName', 'DynamoTableTestClass-table')
715715
expect(metadata).to.have.property('environmentKey', 'DynamoTableTestClass_TABLE_NAME')
716-
expect(metadata).to.have.property('definedBy', DynamoTableTestClass.name)
716+
expect(metadata).to.have.property('definedBy', DynamoTableTestClass)
717717
expect(metadata).to.have.deep.property('nativeConfig').that.deep.equal(__dynamoDBDefaults);
718718
})
719719
it("tableName", () => {
@@ -728,7 +728,7 @@ describe('annotations', () => {
728728

729729
expect(metadata).to.have.property('tableName', 'mytablename')
730730
expect(metadata).to.have.property('environmentKey', 'DynamoTableTestClass_TABLE_NAME')
731-
expect(metadata).to.have.property('definedBy', DynamoTableTestClass.name)
731+
expect(metadata).to.have.property('definedBy', DynamoTableTestClass)
732732
expect(metadata).to.have.deep.property('nativeConfig').that.deep.equal(__dynamoDBDefaults);
733733
})
734734
it("environmentKey", () => {
@@ -743,7 +743,7 @@ describe('annotations', () => {
743743

744744
expect(metadata).to.have.property('tableName', 'mytablename')
745745
expect(metadata).to.have.property('environmentKey', 'myenvkey')
746-
expect(metadata).to.have.property('definedBy', DynamoTableTestClass.name)
746+
expect(metadata).to.have.property('definedBy', DynamoTableTestClass)
747747
expect(metadata).to.have.deep.property('nativeConfig').that.deep.equal(__dynamoDBDefaults);
748748
})
749749
it("nativeConfig", () => {
@@ -765,7 +765,7 @@ describe('annotations', () => {
765765

766766
expect(metadata).to.have.property('tableName', 'mytablename')
767767
expect(metadata).to.have.property('environmentKey', 'DynamoTableTestClass_TABLE_NAME')
768-
expect(metadata).to.have.property('definedBy', DynamoTableTestClass.name)
768+
expect(metadata).to.have.property('definedBy', DynamoTableTestClass)
769769
expect(metadata).to.have.deep.property('nativeConfig').that.deep.equal({
770770
...__dynamoDBDefaults,
771771
ProvisionedThroughput: {

0 commit comments

Comments
 (0)