Skip to content

Commit

Permalink
feat: add schema validation
Browse files Browse the repository at this point in the history
  • Loading branch information
CorentinDoue committed Apr 3, 2021
1 parent 8a34b88 commit 4ad9e62
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 0 deletions.
17 changes: 17 additions & 0 deletions package/googlePackage.js
Expand Up @@ -18,6 +18,23 @@ class GooglePackage {
this.serverless = serverless;
this.options = options;
this.provider = this.serverless.getProvider('google');
this.serverless.configSchemaHandler.defineFunctionEvent('google', 'http', { type: 'string' });
this.serverless.configSchemaHandler.defineFunctionEvent('google', 'event', {
type: 'object',
properties: {
eventType: {
type: 'string',
},
path: {
type: 'string',
},
resource: {
type: 'string',
},
},
required: ['eventType', 'resource'],
additionalProperties: false,
});

Object.assign(
this,
Expand Down
16 changes: 16 additions & 0 deletions package/googlePackage.test.js
Expand Up @@ -35,6 +35,22 @@ describe('GooglePackage', () => {
expect(googlePackage.provider).toBeInstanceOf(GoogleProvider);
});

it('should define the schema of the http triggered function', () => {
expect(serverless.configSchemaHandler.defineFunctionEvent).toHaveBeenCalledWith(
'google',
'http',
expect.any(Object)
);
});

it('should define the schema of the event triggered function', () => {
expect(serverless.configSchemaHandler.defineFunctionEvent).toHaveBeenCalledWith(
'google',
'event',
expect.any(Object)
);
});

describe('hooks', () => {
let cleanupServerlessDirStub;
let validateStub;
Expand Down
105 changes: 105 additions & 0 deletions provider/googleProvider.js
Expand Up @@ -22,6 +22,111 @@ class GoogleProvider {
this.serverless = serverless;
this.provider = this; // only load plugin in a Google service context
this.serverless.setProvider(constants.providerName, this);
this.serverless.configSchemaHandler.defineProvider(constants.providerName, {
definitions: {
cloudFunctionRegion: {
// Source: https://cloud.google.com/functions/docs/locations
enum: [
// Tier pricing 1
'us-central1', // (Iowa)
'us-east1', // (South Carolina)
'us-east4', // (Northern Virginia)
'europe-west1', // (Belgium)
'europe-west2', // (London)
'asia-east2', // (Hong Kong)
'asia-northeast1', // (Tokyo)
'asia-northeast2', // (Osaka)
// Tier pricing 2
'us-west2', // (Los Angeles)
'us-west3', // (Salt Lake City)
'us-west4', // (Las Vegas)
'northamerica-northeast1', // (Montreal)
'southamerica-east1', // (Sao Paulo)
'europe-west3', // (Frankfurt)
'europe-west6', // (Zurich)
'australia-southeast1', // (Sydney)
'asia-south1', // (Mumbai)
'asia-southeast2', // (Jakarta)
'asia-northeast3', // (Seoul)
],
},
cloudFunctionRuntime: {
// Source: https://cloud.google.com/functions/docs/concepts/exec#runtimes
enum: [
'nodejs6', // decommissioned
'nodejs8', // deprecated
'nodejs10',
'nodejs12',
'nodejs14',
'python37',
'python38',
'go111',
'go113',
'java11',
'dotnet3',
'ruby26',
'ruby27',
],
},
cloudFunctionMemory: {
// Source: https://cloud.google.com/functions/docs/concepts/exec#memory
enum: [
128,
256, // default
512,
1024,
2048,
4096,
],
},
cloudFunctionEnvironmentVariables: {
type: 'object',
patternProperties: {
'^.*$': { type: 'string' },
},
additionalProperties: false,
},
resourceManagerLabels: {
type: 'object',
propertyNames: {
type: 'string',
minLength: 1,
maxLength: 63,
},
patternProperties: {
'^[a-z][a-z0-9_.]*$': { type: 'string' },
},
additionalProperties: false,
},
},

provider: {
properties: {
credentials: { type: 'string' },
project: { type: 'string' },
region: { $ref: '#/definitions/cloudFunctionRegion' },
runtime: { $ref: '#/definitions/cloudFunctionRuntime' }, // Can be overridden by function configuration
serviceAccountEmail: { type: 'string' }, // Can be overridden by function configuration
memorySize: { $ref: '#/definitions/cloudFunctionMemory' }, // Can be overridden by function configuration
timeout: { type: 'string' }, // Can be overridden by function configuration
environment: { $ref: '#/definitions/cloudFunctionEnvironmentVariables' }, // Can be overridden by function configuration
vpc: { type: 'string' }, // Can be overridden by function configuration
labels: { $ref: '#/definitions/resourceManagerLabels' }, // Can be overridden by function configuration
},
},
function: {
properties: {
handler: { type: 'string' },
runtime: { $ref: '#/definitions/cloudFunctionRuntime' }, // Override provider configuration
serviceAccountEmail: { type: 'string' }, // Override provider configuration
memorySize: { $ref: '#/definitions/cloudFunctionMemory' }, // Override provider configuration
timeout: { type: 'string' }, // Override provider configuration
environment: { $ref: '#/definitions/cloudFunctionEnvironmentVariables' }, // Override provider configuration
vpc: { type: 'string' }, // Override provider configuration
labels: { $ref: '#/definitions/resourceManagerLabels' }, // Override provider configuration
},
},
});

const serverlessVersion = this.serverless.version;
const pluginVersion = pluginPackageJson.version;
Expand Down
7 changes: 7 additions & 0 deletions provider/googleProvider.test.js
Expand Up @@ -67,6 +67,13 @@ describe('GoogleProvider', () => {
expect(google._options.headers['User-Agent']) // eslint-disable-line no-underscore-dangle
.toMatch(/Serverless\/.+ Serverless-Google-Provider\/.+ Googleapis\/.+/);
});

it('should define the schema of the provider', () => {
expect(serverless.configSchemaHandler.defineProvider).toHaveBeenCalledWith(
'google',
expect.any(Object)
);
});
});

describe('#request()', () => {
Expand Down
5 changes: 5 additions & 0 deletions test/serverless.js
Expand Up @@ -34,6 +34,11 @@ class Serverless {
this.pluginManager = {
addPlugin: (plugin) => this.plugins.push(plugin),
};

this.configSchemaHandler = {
defineProvider: jest.fn(),
defineFunctionEvent: jest.fn(),
};
}

setProvider(name, provider) {
Expand Down

0 comments on commit 4ad9e62

Please sign in to comment.