Skip to content

Commit c332d3d

Browse files
authored
feat: Add schema validation (#252)
1 parent 8a34b88 commit c332d3d

File tree

5 files changed

+150
-0
lines changed

5 files changed

+150
-0
lines changed

package/googlePackage.js

+17
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,23 @@ class GooglePackage {
1818
this.serverless = serverless;
1919
this.options = options;
2020
this.provider = this.serverless.getProvider('google');
21+
this.serverless.configSchemaHandler.defineFunctionEvent('google', 'http', { type: 'string' });
22+
this.serverless.configSchemaHandler.defineFunctionEvent('google', 'event', {
23+
type: 'object',
24+
properties: {
25+
eventType: {
26+
type: 'string',
27+
},
28+
path: {
29+
type: 'string',
30+
},
31+
resource: {
32+
type: 'string',
33+
},
34+
},
35+
required: ['eventType', 'resource'],
36+
additionalProperties: false,
37+
});
2138

2239
Object.assign(
2340
this,

package/googlePackage.test.js

+16
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,22 @@ describe('GooglePackage', () => {
3535
expect(googlePackage.provider).toBeInstanceOf(GoogleProvider);
3636
});
3737

38+
it('should define the schema of the http triggered function', () => {
39+
expect(serverless.configSchemaHandler.defineFunctionEvent).toHaveBeenCalledWith(
40+
'google',
41+
'http',
42+
expect.any(Object)
43+
);
44+
});
45+
46+
it('should define the schema of the event triggered function', () => {
47+
expect(serverless.configSchemaHandler.defineFunctionEvent).toHaveBeenCalledWith(
48+
'google',
49+
'event',
50+
expect.any(Object)
51+
);
52+
});
53+
3854
describe('hooks', () => {
3955
let cleanupServerlessDirStub;
4056
let validateStub;

provider/googleProvider.js

+105
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,111 @@ class GoogleProvider {
2222
this.serverless = serverless;
2323
this.provider = this; // only load plugin in a Google service context
2424
this.serverless.setProvider(constants.providerName, this);
25+
this.serverless.configSchemaHandler.defineProvider(constants.providerName, {
26+
definitions: {
27+
cloudFunctionRegion: {
28+
// Source: https://cloud.google.com/functions/docs/locations
29+
enum: [
30+
// Tier pricing 1
31+
'us-central1', // (Iowa)
32+
'us-east1', // (South Carolina)
33+
'us-east4', // (Northern Virginia)
34+
'europe-west1', // (Belgium)
35+
'europe-west2', // (London)
36+
'asia-east2', // (Hong Kong)
37+
'asia-northeast1', // (Tokyo)
38+
'asia-northeast2', // (Osaka)
39+
// Tier pricing 2
40+
'us-west2', // (Los Angeles)
41+
'us-west3', // (Salt Lake City)
42+
'us-west4', // (Las Vegas)
43+
'northamerica-northeast1', // (Montreal)
44+
'southamerica-east1', // (Sao Paulo)
45+
'europe-west3', // (Frankfurt)
46+
'europe-west6', // (Zurich)
47+
'australia-southeast1', // (Sydney)
48+
'asia-south1', // (Mumbai)
49+
'asia-southeast2', // (Jakarta)
50+
'asia-northeast3', // (Seoul)
51+
],
52+
},
53+
cloudFunctionRuntime: {
54+
// Source: https://cloud.google.com/functions/docs/concepts/exec#runtimes
55+
enum: [
56+
'nodejs6', // decommissioned
57+
'nodejs8', // deprecated
58+
'nodejs10',
59+
'nodejs12',
60+
'nodejs14',
61+
'python37',
62+
'python38',
63+
'go111',
64+
'go113',
65+
'java11',
66+
'dotnet3',
67+
'ruby26',
68+
'ruby27',
69+
],
70+
},
71+
cloudFunctionMemory: {
72+
// Source: https://cloud.google.com/functions/docs/concepts/exec#memory
73+
enum: [
74+
128,
75+
256, // default
76+
512,
77+
1024,
78+
2048,
79+
4096,
80+
],
81+
},
82+
cloudFunctionEnvironmentVariables: {
83+
type: 'object',
84+
patternProperties: {
85+
'^.*$': { type: 'string' },
86+
},
87+
additionalProperties: false,
88+
},
89+
resourceManagerLabels: {
90+
type: 'object',
91+
propertyNames: {
92+
type: 'string',
93+
minLength: 1,
94+
maxLength: 63,
95+
},
96+
patternProperties: {
97+
'^[a-z][a-z0-9_.]*$': { type: 'string' },
98+
},
99+
additionalProperties: false,
100+
},
101+
},
102+
103+
provider: {
104+
properties: {
105+
credentials: { type: 'string' },
106+
project: { type: 'string' },
107+
region: { $ref: '#/definitions/cloudFunctionRegion' },
108+
runtime: { $ref: '#/definitions/cloudFunctionRuntime' }, // Can be overridden by function configuration
109+
serviceAccountEmail: { type: 'string' }, // Can be overridden by function configuration
110+
memorySize: { $ref: '#/definitions/cloudFunctionMemory' }, // Can be overridden by function configuration
111+
timeout: { type: 'string' }, // Can be overridden by function configuration
112+
environment: { $ref: '#/definitions/cloudFunctionEnvironmentVariables' }, // Can be overridden by function configuration
113+
vpc: { type: 'string' }, // Can be overridden by function configuration
114+
labels: { $ref: '#/definitions/resourceManagerLabels' }, // Can be overridden by function configuration
115+
},
116+
},
117+
function: {
118+
properties: {
119+
handler: { type: 'string' },
120+
runtime: { $ref: '#/definitions/cloudFunctionRuntime' }, // Override provider configuration
121+
serviceAccountEmail: { type: 'string' }, // Override provider configuration
122+
memorySize: { $ref: '#/definitions/cloudFunctionMemory' }, // Override provider configuration
123+
timeout: { type: 'string' }, // Override provider configuration
124+
environment: { $ref: '#/definitions/cloudFunctionEnvironmentVariables' }, // Override provider configuration
125+
vpc: { type: 'string' }, // Override provider configuration
126+
labels: { $ref: '#/definitions/resourceManagerLabels' }, // Override provider configuration
127+
},
128+
},
129+
});
25130

26131
const serverlessVersion = this.serverless.version;
27132
const pluginVersion = pluginPackageJson.version;

provider/googleProvider.test.js

+7
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ describe('GoogleProvider', () => {
6767
expect(google._options.headers['User-Agent']) // eslint-disable-line no-underscore-dangle
6868
.toMatch(/Serverless\/.+ Serverless-Google-Provider\/.+ Googleapis\/.+/);
6969
});
70+
71+
it('should define the schema of the provider', () => {
72+
expect(serverless.configSchemaHandler.defineProvider).toHaveBeenCalledWith(
73+
'google',
74+
expect.any(Object)
75+
);
76+
});
7077
});
7178

7279
describe('#request()', () => {

test/serverless.js

+5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ class Serverless {
3434
this.pluginManager = {
3535
addPlugin: (plugin) => this.plugins.push(plugin),
3636
};
37+
38+
this.configSchemaHandler = {
39+
defineProvider: jest.fn(),
40+
defineFunctionEvent: jest.fn(),
41+
};
3742
}
3843

3944
setProvider(name, provider) {

0 commit comments

Comments
 (0)