From 4ad9e62b17a427e408fb6c1b8a94a9229074fd82 Mon Sep 17 00:00:00 2001 From: CorentinDoue Date: Sat, 3 Apr 2021 13:19:21 +0200 Subject: [PATCH] feat: add schema validation --- package/googlePackage.js | 17 ++++++ package/googlePackage.test.js | 16 +++++ provider/googleProvider.js | 105 ++++++++++++++++++++++++++++++++ provider/googleProvider.test.js | 7 +++ test/serverless.js | 5 ++ 5 files changed, 150 insertions(+) diff --git a/package/googlePackage.js b/package/googlePackage.js index 754d6db..4ea2354 100644 --- a/package/googlePackage.js +++ b/package/googlePackage.js @@ -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, diff --git a/package/googlePackage.test.js b/package/googlePackage.test.js index 27c77a6..2b7965c 100644 --- a/package/googlePackage.test.js +++ b/package/googlePackage.test.js @@ -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; diff --git a/provider/googleProvider.js b/provider/googleProvider.js index 5fc5e12..3bb85bd 100644 --- a/provider/googleProvider.js +++ b/provider/googleProvider.js @@ -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; diff --git a/provider/googleProvider.test.js b/provider/googleProvider.test.js index d55b848..7163088 100644 --- a/provider/googleProvider.test.js +++ b/provider/googleProvider.test.js @@ -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()', () => { diff --git a/test/serverless.js b/test/serverless.js index c79458d..9529555 100644 --- a/test/serverless.js +++ b/test/serverless.js @@ -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) {