Skip to content

Commit 3c7f8e4

Browse files
VirtueMeclaude
andauthored
fix(apiGateway): support object form for apiKeys entries (#716)
Both apiKeys.js and usagePlanKeys.js now accept objects without requiring a name property, allowing value-only keys where AWS auto-generates the name. Fixes #431 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1083101 commit 3c7f8e4

4 files changed

Lines changed: 54 additions & 5 deletions

File tree

lib/deploy/events/apiGateway/apiKeys.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ module.exports = {
1515
_.forEach(apiKeys, (apiKey, i) => {
1616
const apiKeyNumber = i + 1;
1717

18-
if (typeof apiKey !== 'string' && (typeof apiKey !== 'object' || !apiKey.name)) {
19-
throw new this.serverless.classes.Error('API Keys must be strings or objects with a name property');
18+
if (typeof apiKey !== 'string' && typeof apiKey !== 'object') {
19+
throw new this.serverless.classes.Error('API Keys must be strings or objects');
2020
}
2121

2222
const apiKeyName = typeof apiKey === 'object' ? apiKey.name : apiKey;

lib/deploy/events/apiGateway/apiKeys.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,21 @@ describe('#methods()', () => {
105105
});
106106
});
107107

108+
it('should compile api key resource when apiKey is an object with value only', () => {
109+
serverlessStepFunctions.serverless.service.provider.apiGateway.apiKeys = [
110+
{ value: 'my-secret-value' },
111+
];
112+
return serverlessStepFunctions.compileApiKeys().then(() => {
113+
const resource = serverlessStepFunctions.serverless.service.provider
114+
.compiledCloudFormationTemplate.Resources[
115+
serverlessStepFunctions.provider.naming.getApiKeyLogicalId(1)
116+
];
117+
expect(resource.Type).to.equal('AWS::ApiGateway::ApiKey');
118+
expect(resource.Properties.Name).to.equal(undefined);
119+
expect(resource.Properties.Value).to.equal('my-secret-value');
120+
});
121+
});
122+
108123
it('should compile api key resource when apiKey is an object with name only', () => {
109124
serverlessStepFunctions.serverless.service.provider.apiGateway.apiKeys = [
110125
{ name: 'my-api-key' },

lib/deploy/events/apiGateway/usagePlanKeys.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ module.exports = {
1515
_.forEach(apiKeys, (apiKey, i) => {
1616
const usagePlanKeyNumber = i + 1;
1717

18-
if (typeof apiKey !== 'string') {
19-
throw new this.serverless.classes.Error('API Keys must be strings');
18+
if (typeof apiKey !== 'string' && typeof apiKey !== 'object') {
19+
throw new this.serverless.classes.Error('API Keys must be strings or objects');
2020
}
2121

2222
const usagePlanKeyLogicalId = this.provider.naming

lib/deploy/events/apiGateway/usagePlanKeys.test.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,42 @@ describe('#compileUsagePlanKeys()', () => {
7070
expect(() => serverlessStepFunctions.compileUsagePlanKeys()).to.throw(Error);
7171
});
7272

73-
it('throw error if an apiKey is not a string', () => {
73+
it('throw error if an apiKey is not a string or object', () => {
7474
serverlessStepFunctions.serverless.service.provider.apiGateway.apiKeys = [2];
7575
expect(() => serverlessStepFunctions.compileUsagePlanKeys()).to.throw(Error);
7676
});
77+
78+
it('should compile usage plan key resource when apiKey is an object with value only', () => {
79+
serverlessStepFunctions.serverless.service.provider.apiGateway.apiKeys = [
80+
{ value: 'myKeyValue' },
81+
];
82+
return serverlessStepFunctions.compileUsagePlanKeys().then(() => {
83+
expect(
84+
serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate
85+
.Resources[
86+
serverlessStepFunctions.provider.naming.getUsagePlanKeyLogicalId(1)
87+
].Type,
88+
).to.equal('AWS::ApiGateway::UsagePlanKey');
89+
});
90+
});
91+
92+
it('should compile usage plan key resource when apiKey is an object with name and value', () => {
93+
serverlessStepFunctions.serverless.service.provider.apiGateway.apiKeys = [
94+
{ name: 'myKey', value: 'myKeyValue' },
95+
];
96+
return serverlessStepFunctions.compileUsagePlanKeys().then(() => {
97+
expect(
98+
serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate
99+
.Resources[
100+
serverlessStepFunctions.provider.naming.getUsagePlanKeyLogicalId(1)
101+
].Type,
102+
).to.equal('AWS::ApiGateway::UsagePlanKey');
103+
expect(
104+
serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate
105+
.Resources[
106+
serverlessStepFunctions.provider.naming.getUsagePlanKeyLogicalId(1)
107+
].Properties.KeyId.Ref,
108+
).to.equal('ApiGatewayApiKey1');
109+
});
110+
});
77111
});

0 commit comments

Comments
 (0)