From 7c2827162f94b817f5e8f3c00e279263bff120e7 Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 6 Jul 2020 11:02:43 +0800 Subject: [PATCH 01/54] feat: add integration test --- package.json | 6 +++- tests/integration.test.js | 63 +++++++++++++++++++++++++++++++++++++++ tests/src/package.json | 14 +++++++++ tests/src/sls.js | 8 +++++ tests/utils.js | 24 +++++++++++++++ 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 tests/integration.test.js create mode 100644 tests/src/package.json create mode 100644 tests/src/sls.js create mode 100644 tests/utils.js diff --git a/package.json b/package.json index b06f08f..d75b331 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "access": "public" }, "scripts": { - "test": "npm run lint && npm run prettier", + "int-test": "jest ./tests/integration.test.js --testEnvironment node", + "test": "npm run lint && npm run prettier && npm run int-test", "commitlint": "commitlint -f HEAD@{15}", "lint": "eslint --ext .js,.ts,.tsx .", "lint:fix": "eslint --fix --ext .js,.ts,.tsx .", @@ -44,6 +45,8 @@ "@semantic-release/git": "^9.0.0", "@semantic-release/npm": "^7.0.4", "@semantic-release/release-notes-generator": "^9.0.1", + "@serverless/platform-client-china": "^1.0.19", + "axios": "^0.19.2", "babel-eslint": "^10.1.0", "dotenv": "^8.2.0", "eslint": "^6.8.0", @@ -51,6 +54,7 @@ "eslint-plugin-import": "^2.20.1", "eslint-plugin-prettier": "^3.1.2", "husky": "^4.2.3", + "jest": "^25.0.1", "lint-staged": "^10.0.8", "prettier": "^1.19.1", "semantic-release": "^17.0.4" diff --git a/tests/integration.test.js b/tests/integration.test.js new file mode 100644 index 0000000..ce855ea --- /dev/null +++ b/tests/integration.test.js @@ -0,0 +1,63 @@ +const { generateId, getServerlessSdk } = require('./utils') +const execSync = require('child_process').execSync +const path = require('path') +const axios = require('axios') + +// set enough timeout for deployment to finish +jest.setTimeout(300000) + +// the yaml file we're testing against +const instanceYaml = { + org: 'orgDemo', + app: 'appDemo', + component: 'express@dev', + name: `express-integration-tests-${generateId()}`, + stage: 'dev', + inputs: { + region: 'ap-guangzhou', + runtime: 'Nodejs8.9', + apigatewayConf: { environment: 'test' } + } +} + +// get credentials from process.env but need to init empty credentials object +const credentials = { + tencent: {} +} + +// get serverless construct sdk +const sdk = getServerlessSdk(instanceYaml.org) + +it('should successfully deploy express app', async () => { + const instance = await sdk.deploy(instanceYaml, { tencent: {} }) + + expect(instance).toBeDefined() + expect(instance.instanceName).toEqual(instanceYaml.name) + // get src from template by default + expect(instance.outputs.templateUrl).toBeDefined() + expect(instance.outputs.region).toEqual(instanceYaml.inputs.region) + expect(instance.outputs.apigw).toBeDefined() + expect(instance.outputs.apigw.environment).toEqual(instanceYaml.inputs.apigatewayConf.environment) + expect(instance.outputs.scf).toBeDefined() + expect(instance.outputs.scf.runtime).toEqual(instanceYaml.inputs.runtime) +}) + +it('should successfully update source code', async () => { + // change source to own source './src' and need to install packages before deploy + const srcPath = path.join(__dirname, 'src') + execSync('npm install', { cwd: srcPath }) + instanceYaml.inputs.src = srcPath + + const instance = await sdk.deploy(instanceYaml, credentials) + const response = await axios.get(instance.outputs.apigw.url) + + expect(response.data).toEqual('hello world') + expect(instance.outputs.templateUrl).not.toBeDefined() +}) + +it('should successfully remove express app', async () => { + await sdk.remove(instanceYaml, credentials) + result = await sdk.getInstance(instanceYaml.org, instanceYaml.stage, instanceYaml.app, instanceYaml.name) + + expect(result.instance.instanceStatus).toEqual('inactive') +}) diff --git a/tests/src/package.json b/tests/src/package.json new file mode 100644 index 0000000..f47e0f8 --- /dev/null +++ b/tests/src/package.json @@ -0,0 +1,14 @@ +{ + "name": "serverless-express", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.17.1" + } +} diff --git a/tests/src/sls.js b/tests/src/sls.js new file mode 100644 index 0000000..e2d2260 --- /dev/null +++ b/tests/src/sls.js @@ -0,0 +1,8 @@ +const express = require('express') +const app = express() + +app.get('/', function(req, res) { + res.json('hello world') +}) + +module.exports = app diff --git a/tests/utils.js b/tests/utils.js new file mode 100644 index 0000000..d047afa --- /dev/null +++ b/tests/utils.js @@ -0,0 +1,24 @@ +const { ServerlessSDK } = require('@serverless/platform-client-china') + +/* + * Generate random id + */ +const generateId = () => + Math.random() + .toString(36) + .substring(6) + +/* + * Initializes and returns an instance of the serverless sdk + * @param ${string} orgName - the serverless org name. + */ +const getServerlessSdk = (orgName) => { + const sdk = new ServerlessSDK({ + context: { + orgName + } + }) + return sdk +} + +module.exports = { generateId, getServerlessSdk } From 7d4fcc3693bfd084dd9fc0dc82caffaa86452e4c Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 6 Jul 2020 11:13:25 +0800 Subject: [PATCH 02/54] chore: update serverless.component.yml --- serverless.component.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/serverless.component.yml b/serverless.component.yml index c9a84d4..4afdeeb 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -4,7 +4,7 @@ author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploys a serverless Express.js application onto Tencent SCF and Tencent APIGateway. keywords: tencent, serverless, express -repo: https://github.com/serverless-components/tencent-express/tree/v2 -readme: https://github.com/serverless-components/tencent-express/tree/v2/README.md +repo: https://github.com/serverless-components/tencent-express +readme: https://github.com/serverless-components/tencent-express/tree/master/README.md license: MIT main: ./src From 4ba2edf8570e511b9fd5a8286ae81044b531c094 Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 6 Jul 2020 17:00:41 +0800 Subject: [PATCH 03/54] fix: upgrade tencent-component-toolkit --- src/config.js | 2 +- src/package.json | 13 +------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/config.js b/src/config.js index 51f414a..b069602 100644 --- a/src/config.js +++ b/src/config.js @@ -9,7 +9,7 @@ const CONFIGS = { timeout: 3, memorySize: 128, namespace: 'default', - description: 'This is a function created by serverless component' + description: 'Created by Serverless Component' } module.exports = CONFIGS diff --git a/src/package.json b/src/package.json index f99537f..157a43e 100644 --- a/src/package.json +++ b/src/package.json @@ -1,18 +1,7 @@ { - "name": "@serverless/express", - "main": "./serverless.js", - "publishConfig": { - "access": "public" - }, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "lint": "eslint . --fix --cache" - }, - "author": "Tencent Cloud, Inc.", - "license": "MIT", "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.12.7", + "tencent-component-toolkit": "^1.12.9", "type": "^2.0.0" } } From 89ec507cfe96efd91d6404c2bf5967ef92251ed6 Mon Sep 17 00:00:00 2001 From: yugasun Date: Tue, 7 Jul 2020 13:01:48 +0800 Subject: [PATCH 04/54] docs: fix typo --- docs/configure.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/configure.md b/docs/configure.md index 28f4c0e..ea407d3 100644 --- a/docs/configure.md +++ b/docs/configure.md @@ -73,20 +73,20 @@ inputs: 主要的参数 -| 参数名称 | 是否必选 | 默认值 | 描述 | -| ------------------------------------ | :------: | :-------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| runtime | 否 | Nodejs10.15 | 执行环境, 目前支持: Nodejs6.10, Nodejs8.9, Nodejs10.15, Nodejs12.16.16 | -| region | 否 | ap-guangzhou | 项目部署所在区域,默认广州区 | -| functionName | 否 | | 云函数名称 | -| serviceName | 否 | | API 网关服务名称, 默认创建一个新的服务名称 | -| serviceId | 否 | | API 网关服务 ID,如果存在将使用这个 API 网关服务 | -| src | 否 | `process.cwd()` | 默认为当前目录, 如果是对象, 配置参数参考 [执行目录](#执行目录) | -| layers | 否 | | 云函数绑定的 layer, 配置参数参考 [层配置](#层配置) | -| traffic | 否 | 1 | 配置默认流量中 `$LATEST` 版本比重,取值范围:0 ~ 1,比如 80%,可配置成 0.8。注意如果皮遏制灰度流量,需要配置对应的 API 网关触发器的 endpoints 的 `function.functionQualifier` 参数为 `$DEFAULT` (默认流量) | -| [functionConf](#函数配置) | 否 | | 函数配置 | -| [apigatewayConf](#API-网关配置) | 否 | | API 网关配置 | -| [cloudDNSConf](#DNS-配置) | 否 | | DNS 配置 | -| [Region special config](#指定区配置) | 否 | | 指定区配置 | +| 参数名称 | 是否必选 | 默认值 | 描述 | +| ------------------------------------ | :------: | :-------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| runtime | 否 | Nodejs10.15 | 执行环境, 目前支持: Nodejs6.10, Nodejs8.9, Nodejs10.15, Nodejs12.16 | +| region | 否 | ap-guangzhou | 项目部署所在区域,默认广州区 | +| functionName | 否 | | 云函数名称 | +| serviceName | 否 | | API 网关服务名称, 默认创建一个新的服务名称 | +| serviceId | 否 | | API 网关服务 ID,如果存在将使用这个 API 网关服务 | +| src | 否 | `process.cwd()` | 默认为当前目录, 如果是对象, 配置参数参考 [执行目录](#执行目录) | +| layers | 否 | | 云函数绑定的 layer, 配置参数参考 [层配置](#层配置) | +| traffic | 否 | 1 | 配置默认流量中 `$LATEST` 版本比重,取值范围:0 ~ 1,比如 80%,可配置成 0.8。注意如果配置灰度流量,需要配置对应的 API 网关触发器的 endpoints 的 `function.functionQualifier` 参数为 `$DEFAULT` (默认流量) | +| [functionConf](#函数配置) | 否 | | 函数配置 | +| [apigatewayConf](#API-网关配置) | 否 | | API 网关配置 | +| [cloudDNSConf](#DNS-配置) | 否 | | DNS 配置 | +| [Region special config](#指定区配置) | 否 | | 指定区配置 | ## 执行目录 From 99669eddbfbcdeb8b9b9d4c191989ccb4c4bc36f Mon Sep 17 00:00:00 2001 From: yugasun Date: Tue, 7 Jul 2020 15:25:03 +0800 Subject: [PATCH 05/54] chore: disable auto release --- .travis.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index b9f070c..f1ee195 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,12 +11,12 @@ install: jobs: include: # Define the release stage that runs semantic-release - - stage: release - node_js: 10.18 - # Advanced: optionally overwrite your default `script` step to skip the tests - # script: skip - deploy: - provider: script - skip_cleanup: true - script: - - npm run release + # - stage: release + # node_js: 10.18 + # # Advanced: optionally overwrite your default `script` step to skip the tests + # # script: skip + # deploy: + # provider: script + # skip_cleanup: true + # script: + # - npm run release From 6a1f7a86d4838d02cef19de37a2f6e9714ee640b Mon Sep 17 00:00:00 2001 From: yugasun Date: Thu, 9 Jul 2020 20:55:40 +0800 Subject: [PATCH 06/54] fix: upgrade deps --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 157a43e..1c0cd56 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.12.9", + "tencent-component-toolkit": "^1.12.10", "type": "^2.0.0" } } From ec5802466a931b61ded0f58cc9471c73345fc1a5 Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 13 Jul 2020 10:48:49 +0800 Subject: [PATCH 07/54] chore: add webDeployable --- serverless.component.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/serverless.component.yml b/serverless.component.yml index 4afdeeb..46ecc30 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -8,3 +8,4 @@ repo: https://github.com/serverless-components/tencent-express readme: https://github.com/serverless-components/tencent-express/tree/master/README.md license: MIT main: ./src +webDeployable: true From bdd5062f6501fbe91e167ce3e7a91da2e8eb4acd Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 20 Jul 2020 20:29:45 +0800 Subject: [PATCH 08/54] fix: upgrade tencent-component-toolkit --- package.json | 2 +- serverless.component.yml | 2 +- src/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index d75b331..7230bcf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@serverless/express", - "version": "0.0.17", + "version": "0.0.18", "main": "src/serverless.js", "publishConfig": { "access": "public" diff --git a/serverless.component.yml b/serverless.component.yml index 46ecc30..1138f17 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.0.17 +version: 0.0.18 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploys a serverless Express.js application onto Tencent SCF and Tencent APIGateway. diff --git a/src/package.json b/src/package.json index 1c0cd56..48bda34 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.12.10", + "tencent-component-toolkit": "^1.12.13", "type": "^2.0.0" } } From d5c013b6a04487a29b9848442d31cc71c6230c5f Mon Sep 17 00:00:00 2001 From: yugasun Date: Tue, 21 Jul 2020 16:12:11 +0800 Subject: [PATCH 09/54] fix: upgrade deps --- serverless.component.yml | 2 +- src/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/serverless.component.yml b/serverless.component.yml index 1138f17..dc08901 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -2,7 +2,7 @@ name: express version: 0.0.18 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. -description: Deploys a serverless Express.js application onto Tencent SCF and Tencent APIGateway. +description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. keywords: tencent, serverless, express repo: https://github.com/serverless-components/tencent-express readme: https://github.com/serverless-components/tencent-express/tree/master/README.md diff --git a/src/package.json b/src/package.json index 48bda34..b0203fe 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.12.13", + "tencent-component-toolkit": "^1.12.15", "type": "^2.0.0" } } From cf58bcd1aa5c7bee660e5c030aef4e6029254145 Mon Sep 17 00:00:00 2001 From: yugasun Date: Tue, 21 Jul 2020 16:16:52 +0800 Subject: [PATCH 10/54] chore: release v0.0.19 --- package.json | 2 +- serverless.component.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7230bcf..8d15475 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@serverless/express", - "version": "0.0.18", + "version": "0.0.19", "main": "src/serverless.js", "publishConfig": { "access": "public" diff --git a/serverless.component.yml b/serverless.component.yml index dc08901..69b3aa8 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.0.18 +version: 0.0.19 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. From 6ca0cc41aa7a01c76652d02fb7869ff6dac97790 Mon Sep 17 00:00:00 2001 From: yugasun Date: Tue, 21 Jul 2020 20:08:01 +0800 Subject: [PATCH 11/54] docs: update configure --- docs/configure.md | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/docs/configure.md b/docs/configure.md index ea407d3..dd774e2 100644 --- a/docs/configure.md +++ b/docs/configure.md @@ -30,7 +30,6 @@ inputs: layers: - name: layerName # layer名称 version: 1 # 版本 - traffic: 0.9 # 配置默认流量中 $LATEST 版本比重:0 - 1 functionConf: # 函数配置相关 timeout: 10 # 超时时间,单位秒 memorySize: 128 # 内存大小,单位MB @@ -73,20 +72,19 @@ inputs: 主要的参数 -| 参数名称 | 是否必选 | 默认值 | 描述 | -| ------------------------------------ | :------: | :-------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| runtime | 否 | Nodejs10.15 | 执行环境, 目前支持: Nodejs6.10, Nodejs8.9, Nodejs10.15, Nodejs12.16 | -| region | 否 | ap-guangzhou | 项目部署所在区域,默认广州区 | -| functionName | 否 | | 云函数名称 | -| serviceName | 否 | | API 网关服务名称, 默认创建一个新的服务名称 | -| serviceId | 否 | | API 网关服务 ID,如果存在将使用这个 API 网关服务 | -| src | 否 | `process.cwd()` | 默认为当前目录, 如果是对象, 配置参数参考 [执行目录](#执行目录) | -| layers | 否 | | 云函数绑定的 layer, 配置参数参考 [层配置](#层配置) | -| traffic | 否 | 1 | 配置默认流量中 `$LATEST` 版本比重,取值范围:0 ~ 1,比如 80%,可配置成 0.8。注意如果配置灰度流量,需要配置对应的 API 网关触发器的 endpoints 的 `function.functionQualifier` 参数为 `$DEFAULT` (默认流量) | -| [functionConf](#函数配置) | 否 | | 函数配置 | -| [apigatewayConf](#API-网关配置) | 否 | | API 网关配置 | -| [cloudDNSConf](#DNS-配置) | 否 | | DNS 配置 | -| [Region special config](#指定区配置) | 否 | | 指定区配置 | +| 参数名称 | 是否必选 | 默认值 | 描述 | +| ------------------------------------ | :------: | :-------------: | :------------------------------------------------------------------ | +| runtime | 否 | Nodejs10.15 | 执行环境, 目前支持: Nodejs6.10, Nodejs8.9, Nodejs10.15, Nodejs12.16 | +| region | 否 | ap-guangzhou | 项目部署所在区域,默认广州区 | +| functionName | 否 | | 云函数名称 | +| serviceName | 否 | | API 网关服务名称, 默认创建一个新的服务名称 | +| serviceId | 否 | | API 网关服务 ID,如果存在将使用这个 API 网关服务 | +| src | 否 | `process.cwd()` | 默认为当前目录, 如果是对象, 配置参数参考 [执行目录](#执行目录) | +| layers | 否 | | 云函数绑定的 layer, 配置参数参考 [层配置](#层配置) | +| [functionConf](#函数配置) | 否 | | 函数配置 | +| [apigatewayConf](#API-网关配置) | 否 | | API 网关配置 | +| [cloudDNSConf](#DNS-配置) | 否 | | DNS 配置 | +| [Region special config](#指定区配置) | 否 | | 指定区配置 | ## 执行目录 From 7b99b09413ecd6f04ba8251592474b6429665cd0 Mon Sep 17 00:00:00 2001 From: yugasun Date: Wed, 22 Jul 2020 16:06:55 +0800 Subject: [PATCH 12/54] docs: update configure isDefaultMapping --- docs/configure.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/configure.md b/docs/configure.md index dd774e2..458d8ba 100644 --- a/docs/configure.md +++ b/docs/configure.md @@ -45,6 +45,8 @@ inputs: customDomains: # 自定义域名绑定 - domain: abc.com # 待绑定的自定义的域名 certificateId: abcdefg # 待绑定自定义域名的证书唯一 ID + # 如要设置自定义路径映射,请设置为 false + isDefaultMapping: false # 自定义路径映射的路径。使用自定义映射时,可一次仅映射一个 path 到一个环境,也可映射多个 path 到多个环境。并且一旦使用自定义映射,原本的默认映射规则不再生效,只有自定义映射路径生效。 pathMappingSet: - path: / @@ -180,13 +182,13 @@ inputs: Refer to: https://cloud.tencent.com/document/product/628/14906 -| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 | -| ---------------- | :------: | :------: | :------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| domain | 是 | String | | 待绑定的自定义的域名。 | -| certificateId | 否 | String | | 待绑定自定义域名的证书唯一 ID,如果设置了 type 为 https,则为必选 | -| isDefaultMapping | 否 | String | `'TRUE'` | 是否使用默认路径映射,默认为 TRUE。为 FALSE 时,表示自定义路径映射,此时 pathMappingSet 必填。 | -| pathMappingSet | 否 | Object[] | `[]` | 自定义路径映射的路径。使用自定义映射时,可一次仅映射一个 path 到一个环境,也可映射多个 path 到多个环境。并且一旦使用自定义映射,原本的默认映射规则不再生效,只有自定义映射路径生效。 | -| protocol | 否 | String[] | | 绑定自定义域名的协议类型,默认与服务的前端协议一致。 | +| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 | +| ---------------- | :------: | :------: | :----: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| domain | 是 | String | | 待绑定的自定义的域名。 | +| certificateId | 否 | String | | 待绑定自定义域名的证书唯一 ID,如果设置了 type 为 https,则为必选 | +| isDefaultMapping | 否 | String | `true` | 是否使用默认路径映射,默认为 true。为 false 时,表示自定义路径映射,此时 pathMappingSet 必填。 | +| pathMappingSet | 否 | Object[] | `[]` | 自定义路径映射的路径。使用自定义映射时,可一次仅映射一个 path 到一个环境,也可映射多个 path 到多个环境。并且一旦使用自定义映射,原本的默认映射规则不再生效,只有自定义映射路径生效。 | +| protocol | 否 | String[] | | 绑定自定义域名的协议类型,默认与服务的前端协议一致。 | - 自定义路径映射 From c14e8f1492fa8ca7e3bedbc8018571556aa0c6ff Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 27 Jul 2020 15:59:36 +0800 Subject: [PATCH 13/54] fix: update deps --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index b0203fe..9e5637b 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.12.15", + "tencent-component-toolkit": "^1.13.0", "type": "^2.0.0" } } From 6530096a70c2f4ea8b3f63c833dbdcd38399574f Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 27 Jul 2020 16:21:32 +0800 Subject: [PATCH 14/54] chore: release v0.0.20 --- package.json | 2 +- serverless.component.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 8d15475..07c5fa8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@serverless/express", - "version": "0.0.19", + "version": "0.0.20", "main": "src/serverless.js", "publishConfig": { "access": "public" diff --git a/serverless.component.yml b/serverless.component.yml index 69b3aa8..a2a9466 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.0.19 +version: 0.0.20 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. From 62c597fdef0a8e296b1943dba13baa60725afd53 Mon Sep 17 00:00:00 2001 From: yugasun Date: Thu, 6 Aug 2020 16:54:52 +0800 Subject: [PATCH 15/54] fix: support eip config --- docs/configure.md | 46 ++++++++++++++++++++++++---------------------- src/config.js | 1 - src/package.json | 2 +- src/utils.js | 13 +++---------- 4 files changed, 28 insertions(+), 34 deletions(-) diff --git a/docs/configure.md b/docs/configure.md index 458d8ba..6a6c4cb 100644 --- a/docs/configure.md +++ b/docs/configure.md @@ -32,6 +32,7 @@ inputs: version: 1 # 版本 functionConf: # 函数配置相关 timeout: 10 # 超时时间,单位秒 + eip: false # 是否固定出口IP memorySize: 128 # 内存大小,单位MB environment: # 环境变量 variables: # 环境变量数组 @@ -76,8 +77,8 @@ inputs: | 参数名称 | 是否必选 | 默认值 | 描述 | | ------------------------------------ | :------: | :-------------: | :------------------------------------------------------------------ | -| runtime | 否 | Nodejs10.15 | 执行环境, 目前支持: Nodejs6.10, Nodejs8.9, Nodejs10.15, Nodejs12.16 | -| region | 否 | ap-guangzhou | 项目部署所在区域,默认广州区 | +| runtime | 否 | `Nodejs10.15` | 执行环境, 目前支持: Nodejs6.10, Nodejs8.9, Nodejs10.15, Nodejs12.16 | +| region | 否 | `ap-guangzhou` | 项目部署所在区域,默认广州区 | | functionName | 否 | | 云函数名称 | | serviceName | 否 | | API 网关服务名称, 默认创建一个新的服务名称 | | serviceId | 否 | | API 网关服务 ID,如果存在将使用这个 API 网关服务 | @@ -110,7 +111,7 @@ inputs: | 参数名称 | 是否必选 | 类型 | 默认值 | 描述 | | ---------- | :------: | -------- | :----: | :---------------------------------------------- | -| ttl | 否 | Number | 600 | TTL 值,范围 1 - 604800,不同等级域名最小值不同 | +| ttl | 否 | Number | `600` | TTL 值,范围 1 - 604800,不同等级域名最小值不同 | | recordLine | 否 | String[] | | 记录的线路名称 | ### 指定区配置 @@ -125,12 +126,13 @@ inputs: 参考: https://cloud.tencent.com/document/product/583/18586 -| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 | -| ----------- | :------: | :----: | :----: | :------------------------------------------------------------------------------ | -| timeout | 否 | Number | 3 | 函数最长执行时间,单位为秒,可选值范围 1-900 秒,默认为 3 秒 | -| memorySize | 否 | Number | 128 | 函数运行时内存大小,默认为 128M,可选范围 64、128MB-3072MB,并且以 128MB 为阶梯 | -| environment | 否 | Object | | 函数的环境变量, 参考 [环境变量](#环境变量) | -| vpcConfig | 否 | Object | | 函数的 VPC 配置, 参考 [VPC 配置](#VPC-配置) | +| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 | +| ----------- | :------: | :-----: | :-----: | :------------------------------------------------------------------------------ | +| timeout | 否 | Number | `3` | 函数最长执行时间,单位为秒,可选值范围 1-900 秒,默认为 3 秒 | +| memorySize | 否 | Number | `128` | 函数运行时内存大小,默认为 128M,可选范围 64、128MB-3072MB,并且以 128MB 为阶梯 | +| environment | 否 | Object | | 函数的环境变量, 参考 [环境变量](#环境变量) | +| vpcConfig | 否 | Object | | 函数的 VPC 配置, 参考 [VPC 配置](#VPC-配置) | +| eip | 否 | Boolean | `false` | 是否固定出口 IP | ##### 环境变量 @@ -147,16 +149,16 @@ inputs: ### API 网关配置 -| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 | -| -------------- | :------: | :------- | :------- | :--------------------------------------------------------------------------------- | -| protocols | 否 | String[] | ['http'] | 前端请求的类型,如 http,https,http 与 https | -| environment | 否 | String | release | 发布环境. 目前支持三种发布环境: test(测试), prepub(预发布) 与 release(发布). | -| usagePlan | 否 | | | 使用计划配置, 参考 [使用计划](#使用计划) | -| auth | 否 | | | API 密钥配置, 参考 [API 密钥](#API-密钥配置) | -| customDomain | 否 | Object[] | | 自定义 API 域名配置, 参考 [自定义域名](#自定义域名) | -| enableCORS | 否 | Boolean | `false` | 开启跨域。默认值为否。 | -| serviceTimeout | 否 | Number | `15` | Api 超时时间,单位: 秒 | -| isDisabled | 否 | Boolean | `false` | 关闭自动创建 API 网关功能。默认值为否,即默认自动创建 API 网关。 | +| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 | +| -------------- | :------: | :------- | :--------- | :--------------------------------------------------------------------------------- | +| protocols | 否 | String[] | `['http']` | 前端请求的类型,如 http,https,http 与 https | +| environment | 否 | String | `release` | 发布环境. 目前支持三种发布环境: test(测试), prepub(预发布) 与 release(发布). | +| usagePlan | 否 | | | 使用计划配置, 参考 [使用计划](#使用计划) | +| auth | 否 | | | API 密钥配置, 参考 [API 密钥](#API-密钥配置) | +| customDomain | 否 | Object[] | | 自定义 API 域名配置, 参考 [自定义域名](#自定义域名) | +| enableCORS | 否 | Boolean | `false` | 开启跨域。默认值为否。 | +| serviceTimeout | 否 | Number | `15` | Api 超时时间,单位: 秒 | +| isDisabled | 否 | Boolean | `false` | 关闭自动创建 API 网关功能。默认值为否,即默认自动创建 API 网关。 | ##### 使用计划 @@ -167,7 +169,7 @@ inputs: | usagePlanId | 否 | String | 用户自定义使用计划 ID | | usagePlanName | 否 | String | 用户自定义的使用计划名称 | | usagePlanDesc | 否 | String | 用户自定义的使用计划描述 | -| maxRequestNum | 否 | Int | 请求配额总数,如果为空,将使用-1 作为默认值,表示不开启 | +| maxRequestNum | 否 | Number | 请求配额总数,如果为空,将使用-1 作为默认值,表示不开启 | ##### API 密钥配置 @@ -185,8 +187,8 @@ Refer to: https://cloud.tencent.com/document/product/628/14906 | 参数名称 | 是否必选 | 类型 | 默认值 | 描述 | | ---------------- | :------: | :------: | :----: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | domain | 是 | String | | 待绑定的自定义的域名。 | -| certificateId | 否 | String | | 待绑定自定义域名的证书唯一 ID,如果设置了 type 为 https,则为必选 | -| isDefaultMapping | 否 | String | `true` | 是否使用默认路径映射,默认为 true。为 false 时,表示自定义路径映射,此时 pathMappingSet 必填。 | +| certificateId | 否 | String | | 待绑定自定义域名的证书唯一 ID,如果设置了 type 为 `https`,则为必选 | +| isDefaultMapping | 否 | String | `true` | 是否使用默认路径映射。为 `false` 时,表示自定义路径映射,此时 pathMappingSet 必填。 | | pathMappingSet | 否 | Object[] | `[]` | 自定义路径映射的路径。使用自定义映射时,可一次仅映射一个 path 到一个环境,也可映射多个 path 到多个环境。并且一旦使用自定义映射,原本的默认映射规则不再生效,只有自定义映射路径生效。 | | protocol | 否 | String[] | | 绑定自定义域名的协议类型,默认与服务的前端协议一致。 | diff --git a/src/config.js b/src/config.js index b069602..b4c6f64 100644 --- a/src/config.js +++ b/src/config.js @@ -5,7 +5,6 @@ const CONFIGS = { compFullname: 'Express.js', handler: 'sl_handler.handler', runtime: 'Nodejs10.15', - exclude: ['.git/**', '.gitignore', '.DS_Store'], timeout: 3, memorySize: 128, namespace: 'default', diff --git a/src/package.json b/src/package.json index 9e5637b..9a9d323 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.13.0", + "tencent-component-toolkit": "^1.13.2", "type": "^2.0.0" } } diff --git a/src/utils.js b/src/utils.js index 5403265..28d7c9c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -242,7 +242,9 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { }), publish: inputs.publish, traffic: inputs.traffic, - lastVersion: instance.state.lastVersion + lastVersion: instance.state.lastVersion, + eip: tempFunctionConf.eip === true, + l5Enable: tempFunctionConf.l5Enable === true } // validate traffic @@ -255,15 +257,6 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { default: null }) - functionConf.include = ensureIterable( - tempFunctionConf.include ? tempFunctionConf.include : inputs.include, - { default: [], ensureItem: ensureString } - ) - functionConf.exclude = ensureIterable( - tempFunctionConf.exclude ? tempFunctionConf.exclude : inputs.exclude, - { default: [], ensureItem: ensureString } - ) - functionConf.exclude.push('.git/**', '.gitignore', '.serverless', '.DS_Store') if (inputs.functionConf) { functionConf.timeout = inputs.functionConf.timeout ? inputs.functionConf.timeout From ee8c14c6ef1b1ccf03c73542584f7036ceb6de65 Mon Sep 17 00:00:00 2001 From: yugasun Date: Thu, 6 Aug 2020 17:04:06 +0800 Subject: [PATCH 16/54] chore: release v0.1.0 --- package.json | 2 +- serverless.component.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 07c5fa8..e8e7bba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@serverless/express", - "version": "0.0.20", + "version": "0.1.0", "main": "src/serverless.js", "publishConfig": { "access": "public" diff --git a/serverless.component.yml b/serverless.component.yml index a2a9466..1b326a8 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.0.20 +version: 0.1.0 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. From f624171b927f0efd4605566c6168d67a3f9b8302 Mon Sep 17 00:00:00 2001 From: yugasun Date: Thu, 6 Aug 2020 18:32:38 +0800 Subject: [PATCH 17/54] fix: apigw isDisabled --- src/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index 28d7c9c..7e57217 100644 --- a/src/utils.js +++ b/src/utils.js @@ -274,7 +274,7 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { // 对apigw inputs进行标准化 const apigatewayConf = inputs.apigatewayConf ? inputs.apigatewayConf : {} - apigatewayConf.isDisabled = inputs.apigatewayConf === true + apigatewayConf.isDisabled = apigatewayConf.isDisabled === true apigatewayConf.fromClientRemark = fromClientRemark apigatewayConf.serviceName = inputs.serviceName apigatewayConf.description = `Serverless Framework Tencent-${capitalString( From cc625ad3e8a410b161b4744813685aa42a700898 Mon Sep 17 00:00:00 2001 From: yugasun Date: Wed, 12 Aug 2020 14:47:55 +0800 Subject: [PATCH 18/54] feat: support api gw metrics --- src/package.json | 2 +- src/serverless.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 9a9d323..03daa1e 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.13.2", + "tencent-component-toolkit": "^1.14.4", "type": "^2.0.0" } } diff --git a/src/serverless.js b/src/serverless.js index 5b69ee9..0f690c2 100644 --- a/src/serverless.js +++ b/src/serverless.js @@ -290,6 +290,12 @@ class ServerlessComponent extends Component { region, timezone: inputs.tz } + + const curState = this.state[region] + if (curState.serviceId) { + options.apigwServiceId = curState.serviceId + options.apigwEnvironment = curState.environment || 'release' + } const credentials = this.getCredentials() const mertics = new Metrics(credentials, options) const metricResults = await mertics.getDatas( From 9320c0402a457309b2153ff51b50c7398ca82708 Mon Sep 17 00:00:00 2001 From: yugasun Date: Wed, 12 Aug 2020 14:53:47 +0800 Subject: [PATCH 19/54] chore: release v0.1.1 --- package.json | 2 +- serverless.component.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e8e7bba..4c570c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@serverless/express", - "version": "0.1.0", + "version": "0.1.1", "main": "src/serverless.js", "publishConfig": { "access": "public" diff --git a/serverless.component.yml b/serverless.component.yml index 1b326a8..dd5e0a3 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.1.0 +version: 0.1.1 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. From 0285406c812284bd8b5847f0c201c9b69761c9d6 Mon Sep 17 00:00:00 2001 From: yugasun Date: Wed, 19 Aug 2020 16:19:31 +0800 Subject: [PATCH 20/54] fix: traffic zero display bug --- src/serverless.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/serverless.js b/src/serverless.js index 0f690c2..fa4bcff 100644 --- a/src/serverless.js +++ b/src/serverless.js @@ -70,11 +70,12 @@ class ServerlessComponent extends Component { : this.state.lastVersion || '$LATEST' // default traffic is 1.0, it can also be 0, so we should compare to undefined - outputs[curRegion].traffic = scfOutput.Traffic - ? scfOutput.Traffic - : this.state.traffic !== undefined - ? this.state.traffic - : 1 + outputs[curRegion].traffic = + scfOutput.Traffic !== undefined + ? scfOutput.Traffic + : this.state.traffic !== undefined + ? this.state.traffic + : 1 if (outputs[curRegion].traffic !== 1 && scfOutput.ConfigTrafficVersion) { outputs[curRegion].configTrafficVersion = scfOutput.ConfigTrafficVersion From ed2d3abd0e5bd2bf3753f4812066551001241a06 Mon Sep 17 00:00:00 2001 From: yugasun Date: Thu, 20 Aug 2020 11:21:47 +0800 Subject: [PATCH 21/54] docs: udpate readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 651a98e..401001b 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,8 @@ $ npm install -g serverless 通过如下命令和模板链接,快速创建一个 Express 应用: ```bash -$ serverless create --template-url https://github.com/serverless-components/tencent-express/tree/v2/serverless-express -$ cd serverless-express +$ serverless create --template-url https://github.com/serverless-components/tencent-express/tree/master/example +$ cd example ``` 执行如下命令,安装 Express 应用的对应依赖 From 2e551db26dcfa02adf5aa2c63d6c08fea771ed00 Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 24 Aug 2020 17:29:11 +0800 Subject: [PATCH 22/54] fix: update deps --- example/serverless.yml | 15 ++++++--------- src/package.json | 2 +- src/utils.js | 8 +++----- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/example/serverless.yml b/example/serverless.yml index 9eae45b..fe13841 100644 --- a/example/serverless.yml +++ b/example/serverless.yml @@ -1,18 +1,15 @@ -org: orgDemo # (optional) serverless dashboard org. default is the first org you created during signup. -app: appDemo # (optional) serverless dashboard app. default is the same as the name property. -stage: dev # (optional) serverless dashboard stage. default is dev. -component: express # (required) name of the component. In that case, it's express. -name: expressDemo # (required) name of your express component instance. +org: orgDemo +app: appDemo +stage: dev +component: express +name: expressDemo inputs: src: - src: ./ # (optional) path to the source folder. default is a hello world app. + src: ./ exclude: - .env - region: ap-guangzhou - runtime: Nodejs10.15 apigatewayConf: protocols: - http - https - environment: release diff --git a/src/package.json b/src/package.json index 03daa1e..cde9ba5 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.14.4", + "tencent-component-toolkit": "^1.15.4", "type": "^2.0.0" } } diff --git a/src/utils.js b/src/utils.js index 7e57217..4a6cb5c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -161,6 +161,9 @@ const capitalString = (str) => { } const getDefaultProtocol = (protocols) => { + if (!protocols || protocols.length < 1) { + return 'http' + } if (protocols.map((i) => i.toLowerCase()).includes('https')) { return 'https' } @@ -277,13 +280,8 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { apigatewayConf.isDisabled = apigatewayConf.isDisabled === true apigatewayConf.fromClientRemark = fromClientRemark apigatewayConf.serviceName = inputs.serviceName - apigatewayConf.description = `Serverless Framework Tencent-${capitalString( - CONFIGS.compName - )} Component` apigatewayConf.serviceId = inputs.serviceId || stateServiceId apigatewayConf.region = functionConf.region - apigatewayConf.protocols = apigatewayConf.protocols || ['http'] - apigatewayConf.environment = apigatewayConf.environment ? apigatewayConf.environment : 'release' apigatewayConf.endpoints = [ { path: '/', From 0566c25285e9b2b201e45f2ee0a224132b9341eb Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 24 Aug 2020 17:32:42 +0800 Subject: [PATCH 23/54] chore: release v0.1.2 --- package.json | 1 - serverless.component.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 4c570c5..074214f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,5 @@ { "name": "@serverless/express", - "version": "0.1.1", "main": "src/serverless.js", "publishConfig": { "access": "public" diff --git a/serverless.component.yml b/serverless.component.yml index dd5e0a3..5c3c38a 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.1.1 +version: 0.1.2 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. From ae238bc2c7790edad6ccb846d919c164379918e6 Mon Sep 17 00:00:00 2001 From: Avril Li Date: Wed, 26 Aug 2020 17:11:41 +0800 Subject: [PATCH 24/54] chore: enable semantic release --- .travis.yml | 21 +++++++++++---------- release.config.js | 12 ++---------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index f1ee195..d78fad9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: node_js node_js: - - 8 - 10 install: @@ -11,12 +10,14 @@ install: jobs: include: # Define the release stage that runs semantic-release - # - stage: release - # node_js: 10.18 - # # Advanced: optionally overwrite your default `script` step to skip the tests - # # script: skip - # deploy: - # provider: script - # skip_cleanup: true - # script: - # - npm run release + - stage: release + node_js: 10.18 + # Advanced: optionally overwrite your default `script` step to skip the tests + # script: skip + deploy: + provider: script + skip_cleanup: true + on: + branch: master + script: + - npm run release diff --git a/release.config.js b/release.config.js index 53f3398..a13798c 100644 --- a/release.config.js +++ b/release.config.js @@ -1,7 +1,6 @@ module.exports = { verifyConditions: [ '@semantic-release/changelog', - '@semantic-release/npm', '@semantic-release/git', '@semantic-release/github' ], @@ -12,7 +11,8 @@ module.exports = { preset: 'angular', parserOpts: { noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'BREAKING'] - } + }, + releaseRules: [{ type: 'feat', release: 'patch' }] } ], [ @@ -33,14 +33,6 @@ module.exports = { changelogFile: 'CHANGELOG.md' } ], - [ - '@semantic-release/npm', - { - pkgRoot: '.', - npmPublish: false, - tarballDir: false - } - ], [ '@semantic-release/git', { From e062eff94c93f55f0e4734da1a989f2ba72f72a6 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 26 Aug 2020 09:22:36 +0000 Subject: [PATCH 25/54] chore(release): version 0.1.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [0.1.2](https://github.com/serverless-components/tencent-express/compare/v0.1.1...v0.1.2) (2020-08-26) ### Bug Fixes * add apigw/scf deployed state saving manually ([0fcc0b8](https://github.com/serverless-components/tencent-express/commit/0fcc0b84bdeb7119086cdbb050ae2c8ab734ff32)) * add regionList state ([f66d8d8](https://github.com/serverless-components/tencent-express/commit/f66d8d8ee6564e343442bb59b9996bf23fd475b9)) * add release config ([26c7e12](https://github.com/serverless-components/tencent-express/commit/26c7e1201caf79830843e860237f3ebf6efdf1e7)) * apigw custom domain update bug ([1a53027](https://github.com/serverless-components/tencent-express/commit/1a53027effde871dc9f021f510fd7a13cc86794a)) * apigw isDisabled ([f624171](https://github.com/serverless-components/tencent-express/commit/f624171b927f0efd4605566c6168d67a3f9b8302)) * bind unexist role bug ([6cd8990](https://github.com/serverless-components/tencent-express/commit/6cd89900111c7afd1e073d95f81f99364debfb96)) * cache http server ([fc5c824](https://github.com/serverless-components/tencent-express/commit/fc5c82453e2469d66837e1b525d317e811b3115a)) * change entry to sls.js ([61bd482](https://github.com/serverless-components/tencent-express/commit/61bd4820dfcacefa1338580fa8d3b0f2609ffe4c)) * cns ([65aa8b8](https://github.com/serverless-components/tencent-express/commit/65aa8b8b42880c9709ff583429899275978b007e)) * enableCORS for apigw ([a0f59ef](https://github.com/serverless-components/tencent-express/commit/a0f59ef01d5dfe500758adfe2c4f05d7ffc2f22b)) * handle usageplan & auth undefined ([2a257d5](https://github.com/serverless-components/tencent-express/commit/2a257d564e0968c8db1e0a4030412749cb19e847)) * make default runtime to 10.15 ([a295bd4](https://github.com/serverless-components/tencent-express/commit/a295bd49a9b48f470a3416026531e840dd2177ac)) * metics data bug ([6bdf89b](https://github.com/serverless-components/tencent-express/commit/6bdf89bbe3b3665012acee5ca66e08fdff9f05db)) * metrics qps limit ([dddb9f6](https://github.com/serverless-components/tencent-express/commit/dddb9f607c96d86a3500eddeae248d600e2c9813)) * monitor timeout bug ([de33311](https://github.com/serverless-components/tencent-express/commit/de333111a692b5bc8d14e9274b81b5b2e5e57e84)) * optimize outputs for one region ([b3c6964](https://github.com/serverless-components/tencent-express/commit/b3c69646528edfdb8ff0d6455a4dc2b16e13cb81)) * optimize traffic config outputs ([8545ead](https://github.com/serverless-components/tencent-express/commit/8545ead58183454536ca43c412d42d9be9c05580)) * package version ([d682b66](https://github.com/serverless-components/tencent-express/commit/d682b66ab7858bb85c29548f90514056f8c34749)) * prettier config ([e17bd6f](https://github.com/serverless-components/tencent-express/commit/e17bd6fe939666f7d8c5c89182ed24125409e068)) * read bucket and object from srcOriginal ([1b2cf9d](https://github.com/serverless-components/tencent-express/commit/1b2cf9d7c890a94e7deaa830814b9758ac42cdf4)) * release v0.0.1 for v2 ([52b2a37](https://github.com/serverless-components/tencent-express/commit/52b2a37a9f57550d48af868b6d53ac3a9c020fd5)) * remove credential bug ([bca2d1f](https://github.com/serverless-components/tencent-express/commit/bca2d1f9c6ab79ee7b29844fe8bdf2085ddac94c)) * role check error ([1a0b4bf](https://github.com/serverless-components/tencent-express/commit/1a0b4bf3ec1fed5492d72f07378ca7b5d26bbfe8)) * support apigw endpoint timeout config ([01dd4c9](https://github.com/serverless-components/tencent-express/commit/01dd4c931235ec5547ce5f34e0997beb4e094fd1)) * support eip config ([62c597f](https://github.com/serverless-components/tencent-express/commit/62c597fdef0a8e296b1943dba13baa60725afd53)) * template url output ([88df485](https://github.com/serverless-components/tencent-express/commit/88df48503bd1f106e451ce102ec5bd16d6a1442a)) * throw error when no temp secrets ([2a9167e](https://github.com/serverless-components/tencent-express/commit/2a9167e98a9648fb3ed7264956b10ea2808ce490)) * traffic zero display bug ([0285406](https://github.com/serverless-components/tencent-express/commit/0285406c812284bd8b5847f0c201c9b69761c9d6)) * uniform throw error ([c09b6f5](https://github.com/serverless-components/tencent-express/commit/c09b6f5b0071a2fb6a3251b0f8f31bc0dd614d3b)) * update deploy code ([90a4339](https://github.com/serverless-components/tencent-express/commit/90a433968502f9d1499534cf852c6d4c3db12ba6)) * update deps ([2e551db](https://github.com/serverless-components/tencent-express/commit/2e551db26dcfa02adf5aa2c63d6c08fea771ed00)) * update deps ([c14e8f1](https://github.com/serverless-components/tencent-express/commit/c14e8f1492fa8ca7e3bedbc8018571556aa0c6ff)) * update error message ([c4c7243](https://github.com/serverless-components/tencent-express/commit/c4c724358fe5be700e596929b8bddcfa94faa6fd)) * update get credential error message ([ed47b3d](https://github.com/serverless-components/tencent-express/commit/ed47b3d759944e41b0c8fa7641594450d88704de)) * update toolkit verison ([2e99bc7](https://github.com/serverless-components/tencent-express/commit/2e99bc73c438318d125d50d959bf3f9de4a6e85e)) * update usageplan & auth logic ([afa8807](https://github.com/serverless-components/tencent-express/commit/afa8807792aa0e69c191391b1fb49b059add3c35)) * upgrade deps ([6a1f7a8](https://github.com/serverless-components/tencent-express/commit/6a1f7a86d4838d02cef19de37a2f6e9714ee640b)) * upgrade deps ([d5c013b](https://github.com/serverless-components/tencent-express/commit/d5c013b6a04487a29b9848442d31cc71c6230c5f)) * upgrade tencent-component-toolkit ([4ba2edf](https://github.com/serverless-components/tencent-express/commit/4ba2edf8570e511b9fd5a8286ae81044b531c094)) * upgrade tencent-component-toolkit ([af8c234](https://github.com/serverless-components/tencent-express/commit/af8c234622058253a21ebe0231796dd7a47902f8)) * upgrade tencent-component-toolkit ([bdd5062](https://github.com/serverless-components/tencent-express/commit/bdd5062f6501fbe91e167ce3e7a91da2e8eb4acd)) * upgrade tencent-component-toolkit ([00f4a09](https://github.com/serverless-components/tencent-express/commit/00f4a0993d04d4a7be3cf8ea15381a6d8ff04c98)) * upgrade tencent-component-toolkit for deleting compatibility ([fa215bf](https://github.com/serverless-components/tencent-express/commit/fa215bfb66264c360c24a3aca68f4b63cb4c60fd)) * wrong region parameter bug ([#31](https://github.com/serverless-components/tencent-express/issues/31)) ([32e519c](https://github.com/serverless-components/tencent-express/commit/32e519ca00170ed75f0bea19b80c0255288e8d37)) * 增加cns ([b452285](https://github.com/serverless-components/tencent-express/commit/b45228501a381dd6ede9381ca8d05cd5f403d585)) * 增加cns ([a2b87d9](https://github.com/serverless-components/tencent-express/commit/a2b87d92908935dc4299dfb0d5b01029c5fc8649)) ### Features * add binary types support ([60603d6](https://github.com/serverless-components/tencent-express/commit/60603d61bbeb1cbdcf44d5bb6b9cd5a6f2b08fd6)) * add integration test ([7c28271](https://github.com/serverless-components/tencent-express/commit/7c2827162f94b817f5e8f3c00e279263bff120e7)) * add layers config support ([d971be9](https://github.com/serverless-components/tencent-express/commit/d971be985daf3bc4127c6648fd0e474c535ad1eb)) * add metrics api ([#27](https://github.com/serverless-components/tencent-express/issues/27)) ([0d40154](https://github.com/serverless-components/tencent-express/commit/0d40154347b5db735fcac66a8a9b5ccf0e6ca035)) * add state store, and remove method ([8815e40](https://github.com/serverless-components/tencent-express/commit/8815e4045cf7896e8843c017abb16b24720caa79)) * optimize code zip flow ([f2d60ce](https://github.com/serverless-components/tencent-express/commit/f2d60ce03e96257f4aacda464ab83a4dc144fecb)) * optimize deploy log ([80a2bc0](https://github.com/serverless-components/tencent-express/commit/80a2bc0a23a08051ede3c5d54657833499e0d2fc)) * optimize metics and support disable apigw creating ([e722c80](https://github.com/serverless-components/tencent-express/commit/e722c80d3d1fce8315e08a86808c131402a7a81b)) * support api gw metrics ([cc625ad](https://github.com/serverless-components/tencent-express/commit/cc625ad3e8a410b161b4744813685aa42a700898)) * support role config ([f1d6ed6](https://github.com/serverless-components/tencent-express/commit/f1d6ed664b7354376f5791bd162113cdd44b7b5b)) * support scf publish version and traffic setup ([8807d0e](https://github.com/serverless-components/tencent-express/commit/8807d0ef0fd8c560b3c7aaa8fa37165473a5f863)) * update config and support usageplan+auth ([b067a14](https://github.com/serverless-components/tencent-express/commit/b067a149acec78d97f701aea893e95ad3833f7c3)) * update event and context attach method ([31d0c1d](https://github.com/serverless-components/tencent-express/commit/31d0c1de42354103a800e0515f9a069971b357df)) * use metrics api from toolkit library([#32](https://github.com/serverless-components/tencent-express/issues/32)) ([4b4742d](https://github.com/serverless-components/tencent-express/commit/4b4742d7e53a04fbbd7845073a0ebd2031a1dcd6)) * using temporary secret for credentials ([cf61300](https://github.com/serverless-components/tencent-express/commit/cf61300f7d94f3149648a0d3378b8876a440aca1)) --- CHANGELOG.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..5e6dc94 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,70 @@ +## [0.1.2](https://github.com/serverless-components/tencent-express/compare/v0.1.1...v0.1.2) (2020-08-26) + + +### Bug Fixes + +* add apigw/scf deployed state saving manually ([0fcc0b8](https://github.com/serverless-components/tencent-express/commit/0fcc0b84bdeb7119086cdbb050ae2c8ab734ff32)) +* add regionList state ([f66d8d8](https://github.com/serverless-components/tencent-express/commit/f66d8d8ee6564e343442bb59b9996bf23fd475b9)) +* add release config ([26c7e12](https://github.com/serverless-components/tencent-express/commit/26c7e1201caf79830843e860237f3ebf6efdf1e7)) +* apigw custom domain update bug ([1a53027](https://github.com/serverless-components/tencent-express/commit/1a53027effde871dc9f021f510fd7a13cc86794a)) +* apigw isDisabled ([f624171](https://github.com/serverless-components/tencent-express/commit/f624171b927f0efd4605566c6168d67a3f9b8302)) +* bind unexist role bug ([6cd8990](https://github.com/serverless-components/tencent-express/commit/6cd89900111c7afd1e073d95f81f99364debfb96)) +* cache http server ([fc5c824](https://github.com/serverless-components/tencent-express/commit/fc5c82453e2469d66837e1b525d317e811b3115a)) +* change entry to sls.js ([61bd482](https://github.com/serverless-components/tencent-express/commit/61bd4820dfcacefa1338580fa8d3b0f2609ffe4c)) +* cns ([65aa8b8](https://github.com/serverless-components/tencent-express/commit/65aa8b8b42880c9709ff583429899275978b007e)) +* enableCORS for apigw ([a0f59ef](https://github.com/serverless-components/tencent-express/commit/a0f59ef01d5dfe500758adfe2c4f05d7ffc2f22b)) +* handle usageplan & auth undefined ([2a257d5](https://github.com/serverless-components/tencent-express/commit/2a257d564e0968c8db1e0a4030412749cb19e847)) +* make default runtime to 10.15 ([a295bd4](https://github.com/serverless-components/tencent-express/commit/a295bd49a9b48f470a3416026531e840dd2177ac)) +* metics data bug ([6bdf89b](https://github.com/serverless-components/tencent-express/commit/6bdf89bbe3b3665012acee5ca66e08fdff9f05db)) +* metrics qps limit ([dddb9f6](https://github.com/serverless-components/tencent-express/commit/dddb9f607c96d86a3500eddeae248d600e2c9813)) +* monitor timeout bug ([de33311](https://github.com/serverless-components/tencent-express/commit/de333111a692b5bc8d14e9274b81b5b2e5e57e84)) +* optimize outputs for one region ([b3c6964](https://github.com/serverless-components/tencent-express/commit/b3c69646528edfdb8ff0d6455a4dc2b16e13cb81)) +* optimize traffic config outputs ([8545ead](https://github.com/serverless-components/tencent-express/commit/8545ead58183454536ca43c412d42d9be9c05580)) +* package version ([d682b66](https://github.com/serverless-components/tencent-express/commit/d682b66ab7858bb85c29548f90514056f8c34749)) +* prettier config ([e17bd6f](https://github.com/serverless-components/tencent-express/commit/e17bd6fe939666f7d8c5c89182ed24125409e068)) +* read bucket and object from srcOriginal ([1b2cf9d](https://github.com/serverless-components/tencent-express/commit/1b2cf9d7c890a94e7deaa830814b9758ac42cdf4)) +* release v0.0.1 for v2 ([52b2a37](https://github.com/serverless-components/tencent-express/commit/52b2a37a9f57550d48af868b6d53ac3a9c020fd5)) +* remove credential bug ([bca2d1f](https://github.com/serverless-components/tencent-express/commit/bca2d1f9c6ab79ee7b29844fe8bdf2085ddac94c)) +* role check error ([1a0b4bf](https://github.com/serverless-components/tencent-express/commit/1a0b4bf3ec1fed5492d72f07378ca7b5d26bbfe8)) +* support apigw endpoint timeout config ([01dd4c9](https://github.com/serverless-components/tencent-express/commit/01dd4c931235ec5547ce5f34e0997beb4e094fd1)) +* support eip config ([62c597f](https://github.com/serverless-components/tencent-express/commit/62c597fdef0a8e296b1943dba13baa60725afd53)) +* template url output ([88df485](https://github.com/serverless-components/tencent-express/commit/88df48503bd1f106e451ce102ec5bd16d6a1442a)) +* throw error when no temp secrets ([2a9167e](https://github.com/serverless-components/tencent-express/commit/2a9167e98a9648fb3ed7264956b10ea2808ce490)) +* traffic zero display bug ([0285406](https://github.com/serverless-components/tencent-express/commit/0285406c812284bd8b5847f0c201c9b69761c9d6)) +* uniform throw error ([c09b6f5](https://github.com/serverless-components/tencent-express/commit/c09b6f5b0071a2fb6a3251b0f8f31bc0dd614d3b)) +* update deploy code ([90a4339](https://github.com/serverless-components/tencent-express/commit/90a433968502f9d1499534cf852c6d4c3db12ba6)) +* update deps ([2e551db](https://github.com/serverless-components/tencent-express/commit/2e551db26dcfa02adf5aa2c63d6c08fea771ed00)) +* update deps ([c14e8f1](https://github.com/serverless-components/tencent-express/commit/c14e8f1492fa8ca7e3bedbc8018571556aa0c6ff)) +* update error message ([c4c7243](https://github.com/serverless-components/tencent-express/commit/c4c724358fe5be700e596929b8bddcfa94faa6fd)) +* update get credential error message ([ed47b3d](https://github.com/serverless-components/tencent-express/commit/ed47b3d759944e41b0c8fa7641594450d88704de)) +* update toolkit verison ([2e99bc7](https://github.com/serverless-components/tencent-express/commit/2e99bc73c438318d125d50d959bf3f9de4a6e85e)) +* update usageplan & auth logic ([afa8807](https://github.com/serverless-components/tencent-express/commit/afa8807792aa0e69c191391b1fb49b059add3c35)) +* upgrade deps ([6a1f7a8](https://github.com/serverless-components/tencent-express/commit/6a1f7a86d4838d02cef19de37a2f6e9714ee640b)) +* upgrade deps ([d5c013b](https://github.com/serverless-components/tencent-express/commit/d5c013b6a04487a29b9848442d31cc71c6230c5f)) +* upgrade tencent-component-toolkit ([4ba2edf](https://github.com/serverless-components/tencent-express/commit/4ba2edf8570e511b9fd5a8286ae81044b531c094)) +* upgrade tencent-component-toolkit ([af8c234](https://github.com/serverless-components/tencent-express/commit/af8c234622058253a21ebe0231796dd7a47902f8)) +* upgrade tencent-component-toolkit ([bdd5062](https://github.com/serverless-components/tencent-express/commit/bdd5062f6501fbe91e167ce3e7a91da2e8eb4acd)) +* upgrade tencent-component-toolkit ([00f4a09](https://github.com/serverless-components/tencent-express/commit/00f4a0993d04d4a7be3cf8ea15381a6d8ff04c98)) +* upgrade tencent-component-toolkit for deleting compatibility ([fa215bf](https://github.com/serverless-components/tencent-express/commit/fa215bfb66264c360c24a3aca68f4b63cb4c60fd)) +* wrong region parameter bug ([#31](https://github.com/serverless-components/tencent-express/issues/31)) ([32e519c](https://github.com/serverless-components/tencent-express/commit/32e519ca00170ed75f0bea19b80c0255288e8d37)) +* 增加cns ([b452285](https://github.com/serverless-components/tencent-express/commit/b45228501a381dd6ede9381ca8d05cd5f403d585)) +* 增加cns ([a2b87d9](https://github.com/serverless-components/tencent-express/commit/a2b87d92908935dc4299dfb0d5b01029c5fc8649)) + + +### Features + +* add binary types support ([60603d6](https://github.com/serverless-components/tencent-express/commit/60603d61bbeb1cbdcf44d5bb6b9cd5a6f2b08fd6)) +* add integration test ([7c28271](https://github.com/serverless-components/tencent-express/commit/7c2827162f94b817f5e8f3c00e279263bff120e7)) +* add layers config support ([d971be9](https://github.com/serverless-components/tencent-express/commit/d971be985daf3bc4127c6648fd0e474c535ad1eb)) +* add metrics api ([#27](https://github.com/serverless-components/tencent-express/issues/27)) ([0d40154](https://github.com/serverless-components/tencent-express/commit/0d40154347b5db735fcac66a8a9b5ccf0e6ca035)) +* add state store, and remove method ([8815e40](https://github.com/serverless-components/tencent-express/commit/8815e4045cf7896e8843c017abb16b24720caa79)) +* optimize code zip flow ([f2d60ce](https://github.com/serverless-components/tencent-express/commit/f2d60ce03e96257f4aacda464ab83a4dc144fecb)) +* optimize deploy log ([80a2bc0](https://github.com/serverless-components/tencent-express/commit/80a2bc0a23a08051ede3c5d54657833499e0d2fc)) +* optimize metics and support disable apigw creating ([e722c80](https://github.com/serverless-components/tencent-express/commit/e722c80d3d1fce8315e08a86808c131402a7a81b)) +* support api gw metrics ([cc625ad](https://github.com/serverless-components/tencent-express/commit/cc625ad3e8a410b161b4744813685aa42a700898)) +* support role config ([f1d6ed6](https://github.com/serverless-components/tencent-express/commit/f1d6ed664b7354376f5791bd162113cdd44b7b5b)) +* support scf publish version and traffic setup ([8807d0e](https://github.com/serverless-components/tencent-express/commit/8807d0ef0fd8c560b3c7aaa8fa37165473a5f863)) +* update config and support usageplan+auth ([b067a14](https://github.com/serverless-components/tencent-express/commit/b067a149acec78d97f701aea893e95ad3833f7c3)) +* update event and context attach method ([31d0c1d](https://github.com/serverless-components/tencent-express/commit/31d0c1de42354103a800e0515f9a069971b357df)) +* use metrics api from toolkit library([#32](https://github.com/serverless-components/tencent-express/issues/32)) ([4b4742d](https://github.com/serverless-components/tencent-express/commit/4b4742d7e53a04fbbd7845073a0ebd2031a1dcd6)) +* using temporary secret for credentials ([cf61300](https://github.com/serverless-components/tencent-express/commit/cf61300f7d94f3149648a0d3378b8876a440aca1)) From 153a5aef0dc4735cb1ee9570bf04f2a264ef55a2 Mon Sep 17 00:00:00 2001 From: Avril Li Date: Wed, 26 Aug 2020 17:25:48 +0800 Subject: [PATCH 26/54] chore: update release rule --- release.config.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/release.config.js b/release.config.js index a13798c..98b3864 100644 --- a/release.config.js +++ b/release.config.js @@ -11,8 +11,7 @@ module.exports = { preset: 'angular', parserOpts: { noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'BREAKING'] - }, - releaseRules: [{ type: 'feat', release: 'patch' }] + } } ], [ From f0a8f892f469efcda67070ff940421aa83a100c0 Mon Sep 17 00:00:00 2001 From: yugasun Date: Thu, 27 Aug 2020 15:28:14 +0800 Subject: [PATCH 27/54] fix: update deps for error message --- serverless.component.yml | 2 +- src/package.json | 2 +- tests/integration.test.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/serverless.component.yml b/serverless.component.yml index 5c3c38a..9c610a0 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.1.2 +version: 0.1.3 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. diff --git a/src/package.json b/src/package.json index cde9ba5..a53fc4f 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.15.4", + "tencent-component-toolkit": "^1.15.7", "type": "^2.0.0" } } diff --git a/tests/integration.test.js b/tests/integration.test.js index ce855ea..6989e91 100644 --- a/tests/integration.test.js +++ b/tests/integration.test.js @@ -10,12 +10,12 @@ jest.setTimeout(300000) const instanceYaml = { org: 'orgDemo', app: 'appDemo', - component: 'express@dev', + component: 'express', name: `express-integration-tests-${generateId()}`, stage: 'dev', inputs: { region: 'ap-guangzhou', - runtime: 'Nodejs8.9', + runtime: 'Nodejs10.15', apigatewayConf: { environment: 'test' } } } From 9d1a1e1793d866f5fbe5bdce61090db8381bb103 Mon Sep 17 00:00:00 2001 From: yugasun Date: Thu, 27 Aug 2020 15:39:53 +0800 Subject: [PATCH 28/54] fix: support cfs --- src/utils.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/utils.js b/src/utils.js index 4a6cb5c..4ce62a2 100644 --- a/src/utils.js +++ b/src/utils.js @@ -243,6 +243,9 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { layers: ensureIterable(tempFunctionConf.layers ? tempFunctionConf.layers : inputs.layers, { default: [] }), + cfs: ensureIterable(tempFunctionConf.cfs ? tempFunctionConf.cfs : inputs.cfs, { + default: [] + }), publish: inputs.publish, traffic: inputs.traffic, lastVersion: instance.state.lastVersion, From 09690a9b12d53d1a0f005e93965998fafc8eca64 Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 31 Aug 2020 20:24:12 +0800 Subject: [PATCH 29/54] docs: update readme --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 401001b..225e894 100644 --- a/README.md +++ b/README.md @@ -89,12 +89,13 @@ app: appDemo # (optional) serverless dashboard app. default is the same as the n stage: dev # (optional) serverless dashboard stage. default is dev. inputs: - src: ./ # (optional) path to the source folder. default is a hello world app. + src: + src: ./ # (optional) path to the source folder. default is a hello world app. + exclude: + - .env functionName: expressDemo region: ap-guangzhou runtime: Nodejs10.15 - exclude: - - .env apigatewayConf: protocols: - http @@ -102,7 +103,7 @@ inputs: environment: release ``` -点此查看[全量配置及配置说明](https://github.com/serverless-components/tencent-express/blob/v2/docs/configure.md) +点此查看[全量配置及配置说明](https://github.com/serverless-components/tencent-express/tree/master/docs/configure.md) 当你根据该配置文件更新配置字段后,再次运行 `serverless deploy` 或者 `serverless` 就可以更新配置到云端。 From 0f69412c8b34780b02ed6b822b365033412047ae Mon Sep 17 00:00:00 2001 From: Avril Li Date: Tue, 1 Sep 2020 19:42:31 +0800 Subject: [PATCH 30/54] chore: add ygsec check --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 074214f..f41dde1 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,9 @@ }, "husky": { "hooks": { - "pre-commit": "lint-staged", + "pre-commit": "ygsec && lint-staged", "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", - "pre-push": "npm run lint:fix && npm run prettier:fix" + "pre-push": "ygsec && npm run lint:fix && npm run prettier:fix" } }, "lint-staged": { @@ -45,6 +45,7 @@ "@semantic-release/npm": "^7.0.4", "@semantic-release/release-notes-generator": "^9.0.1", "@serverless/platform-client-china": "^1.0.19", + "@ygkit/secure": "0.0.3", "axios": "^0.19.2", "babel-eslint": "^10.1.0", "dotenv": "^8.2.0", @@ -52,7 +53,7 @@ "eslint-config-prettier": "^6.10.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-prettier": "^3.1.2", - "husky": "^4.2.3", + "husky": "^4.2.5", "jest": "^25.0.1", "lint-staged": "^10.0.8", "prettier": "^1.19.1", From 04a3c6db282f7a674f1e90d3d6f1ef713a664476 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 1 Sep 2020 11:46:48 +0000 Subject: [PATCH 31/54] chore(release): version 0.1.3 ## [0.1.3](https://github.com/serverless-components/tencent-express/compare/v0.1.2...v0.1.3) (2020-09-01) ### Bug Fixes * support cfs ([9d1a1e1](https://github.com/serverless-components/tencent-express/commit/9d1a1e1793d866f5fbe5bdce61090db8381bb103)) * update deps for error message ([f0a8f89](https://github.com/serverless-components/tencent-express/commit/f0a8f892f469efcda67070ff940421aa83a100c0)) --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e6dc94..ad5fc14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [0.1.3](https://github.com/serverless-components/tencent-express/compare/v0.1.2...v0.1.3) (2020-09-01) + + +### Bug Fixes + +* support cfs ([9d1a1e1](https://github.com/serverless-components/tencent-express/commit/9d1a1e1793d866f5fbe5bdce61090db8381bb103)) +* update deps for error message ([f0a8f89](https://github.com/serverless-components/tencent-express/commit/f0a8f892f469efcda67070ff940421aa83a100c0)) + ## [0.1.2](https://github.com/serverless-components/tencent-express/compare/v0.1.1...v0.1.2) (2020-08-26) From 7e25e8a86f539b2db449caf969cbbd58c5af4d1b Mon Sep 17 00:00:00 2001 From: yugasun Date: Wed, 2 Sep 2020 10:30:04 +0800 Subject: [PATCH 32/54] fix: update tencnet-component-toolkit for api mark --- example/README.md | 172 +++++++++++++++++++++++++++++++++++++++ serverless.component.yml | 2 +- src/package.json | 2 +- 3 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 example/README.md diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..225e894 --- /dev/null +++ b/example/README.md @@ -0,0 +1,172 @@ +[![Serverless Components](https://img.serverlesscloud.cn/2020210/1581352135771-express.png)](http://serverless.com) + +
+ +**腾讯云 Express 组件** ⎯⎯⎯ 通过使用 [Tencent Serverless Framework](https://github.com/serverless/components/tree/cloud),基于云上 Serverless 服务(如网关、云函数等),实现“0”配置,便捷开发,极速部署你的 Express 应用,Express 组件支持丰富的配置扩展,提供了目前最易用、低成本并且弹性伸缩的 Express 项目开发/托管能力。 +
+ +特性介绍: + +- [x] **按需付费** - 按照请求的使用量进行收费,没有请求时无需付费 +- [x] **"0"配置** - 只需要关心项目代码,之后部署即可,Serverless Framework 会搞定所有配置。 +- [x] **极速部署** - 仅需几秒,部署你的整个 Express 应用。 +- [x] **实时日志** - 通过实时日志的输出查看业务状态,便于直接在云端开发应用。 +- [x] **云端调试** - 针对 Node.js 框架支持一键云端调试能力,屏蔽本地环境的差异。 +- [x] **便捷协作** - 通过云端的状态信息和部署日志,方便的进行多人协作开发。 +- [x] **自定义域名** - 支持配置自定义域名及 HTTPS 访问 + +
+ + + +快速开始: + +1. [**安装**](#1-安装) +2. [**创建**](#2-创建) +3. [**部署**](#3-部署) +4. [**配置**](#4-配置) +5. [**开发调试**](#5-开发调试) +6. [**查看状态**](#6-查看状态) +7. [**移除**](#7-移除) + +更多资源: + +- [**架构说明**](#架构说明) +- [**账号配置**](#账号配置) + +  + +### 1. 安装 + +通过 npm 安装最新版本的 Serverless Framework + +```bash +$ npm install -g serverless +``` + +### 2. 创建 + +通过如下命令和模板链接,快速创建一个 Express 应用: + +```bash +$ serverless create --template-url https://github.com/serverless-components/tencent-express/tree/master/example +$ cd example +``` + +执行如下命令,安装 Express 应用的对应依赖 + +``` +$ npm install +``` + +### 3. 部署 + +在 `serverless.yml` 文件下的目录中运行 `serverless deploy` 进行 Express 项目的部署。第一次部署可能耗时相对较久,但后续的二次部署会在几秒钟之内完成。部署完毕后,你可以在命令行的输出中查看到你 Express 应用的 URL 地址,点击地址即可访问你的 Express 项目。 + +**注意:** + +如您的账号未[登陆](https://cloud.tencent.com/login)或[注册](https://cloud.tencent.com/register)腾讯云,您可以直接通过`微信`扫描命令行中的二维码进行授权登陆和注册。 + +如果出现了 `internal server error` 的报错,请检查是否在创建模板后没有运行 `npm install`。 + +如果希望查看更多部署过程的信息,可以通过`sls deploy --debug` 命令查看部署过程中的实时日志信息,`sls`是 `serverless` 命令的缩写。 + +
+ +### 4. 配置 + +Express 组件支持 0 配置部署,也就是可以直接通过配置文件中的默认值进行部署。但你依然可以修改更多可选配置来进一步开发该 Express 项目。 + +以下是 Express 组件的 `serverless.yml`完整配置说明: + +```yml +# serverless.yml + +component: express # (required) name of the component. In that case, it's express. +name: expressDemo # (required) name of your express component instance. +org: orgDemo # (optional) serverless dashboard org. default is the first org you created during signup. +app: appDemo # (optional) serverless dashboard app. default is the same as the name property. +stage: dev # (optional) serverless dashboard stage. default is dev. + +inputs: + src: + src: ./ # (optional) path to the source folder. default is a hello world app. + exclude: + - .env + functionName: expressDemo + region: ap-guangzhou + runtime: Nodejs10.15 + apigatewayConf: + protocols: + - http + - https + environment: release +``` + +点此查看[全量配置及配置说明](https://github.com/serverless-components/tencent-express/tree/master/docs/configure.md) + +当你根据该配置文件更新配置字段后,再次运行 `serverless deploy` 或者 `serverless` 就可以更新配置到云端。 + +### 5. 开发调试 + +部署了 Express.js 应用后,可以通过开发调试能力对该项目进行二次开发,从而开发一个生产应用。在本地修改和更新代码后,不需要每次都运行 `serverless deploy` 命令来反复部署。你可以直接通过 `serverless dev` 命令对本地代码的改动进行检测和自动上传。 + +可以通过在 `serverless.yml`文件所在的目录下运行 `serverless dev` 命令开启开发调试能力。 + +`serverless dev` 同时支持实时输出云端日志,每次部署完毕后,对项目进行访问,即可在命令行中实时输出调用日志,便于查看业务情况和排障。 + +除了实时日志输出之外,针对 Node.js 应用,当前也支持云端调试能力。在开启 `serverless dev` 命令之后,将会自动监听远端端口,并将函数的超时时间临时配置为 900s。此时你可以通过访问 chrome://inspect/#devices 查找远端的调试路径,并直接对云端代码进行断点等调试。在调试模式结束后,需要再次部署从而将代码更新并将超时时间设置为原来的值。详情参考[开发模式和云端调试](https://cloud.tencent.com/document/product/1154/43220)。 + +### 6. 查看状态 + +在`serverless.yml`文件所在的目录下,通过如下命令查看部署状态: + +``` +$ serverless info +``` + +### 7. 移除 + +在`serverless.yml`文件所在的目录下,通过以下命令移除部署的 Express 服务。移除后该组件会对应删除云上部署时所创建的所有相关资源。 + +``` +$ serverless remove +``` + +和部署类似,支持通过 `sls remove --debug` 命令查看移除过程中的实时日志信息,`sls`是 `serverless` 命令的缩写。 + +## 架构说明 + +Express 组件将在腾讯云账户中使用到如下 Serverless 服务: + +- [x] **API 网关** - API 网关将会接收外部请求并且转发到 SCF 云函数中。 +- [x] **SCF 云函数** - 云函数将承载 Express.js 应用。 +- [x] **CAM 访问控制** - 该组件会创建默认 CAM 角色用于授权访问关联资源。 +- [x] **COS 对象存储** - 为确保上传速度和质量,云函数压缩并上传代码时,会默认将代码包存储在特定命名的 COS 桶中。 +- [x] **SSL 证书服务** - 如果你在 yaml 文件中配置了 `apigatewayConf.customDomains` 字段,需要做自定义域名绑定并开启 HTTPS 时,也会用到证书管理服务和域名服务。Serverless Framework 会根据已经备案的域名自动申请并配置 SSL 证书。 + +## 账号配置 + +当前默认支持 CLI 扫描二维码登录,如您希望配置持久的环境变量/秘钥信息,也可以本地创建 `.env` 文件 + +```console +$ touch .env # 腾讯云的配置信息 +``` + +在 `.env` 文件中配置腾讯云的 SecretId 和 SecretKey 信息并保存 + +如果没有腾讯云账号,可以在此[注册新账号](https://cloud.tencent.com/register)。 + +如果已有腾讯云账号,可以在[API 密钥管理](https://console.cloud.tencent.com/cam/capi)中获取 `SecretId` 和`SecretKey`. + +``` +# .env +TENCENT_SECRET_ID=123 +TENCENT_SECRET_KEY=123 +``` + +## License + +MIT License + +Copyright (c) 2020 Tencent Cloud, Inc. diff --git a/serverless.component.yml b/serverless.component.yml index 9c610a0..5ccc2a5 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.1.3 +version: 0.1.4 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. diff --git a/src/package.json b/src/package.json index a53fc4f..ffdd2b3 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.15.7", + "tencent-component-toolkit": "^1.16.2", "type": "^2.0.0" } } From 45412f0cad7e7606a945e8089c20fd9b28a261e0 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 2 Sep 2020 02:33:00 +0000 Subject: [PATCH 33/54] chore(release): version 0.1.4 ## [0.1.4](https://github.com/serverless-components/tencent-express/compare/v0.1.3...v0.1.4) (2020-09-02) ### Bug Fixes * update tencnet-component-toolkit for api mark ([7e25e8a](https://github.com/serverless-components/tencent-express/commit/7e25e8a86f539b2db449caf969cbbd58c5af4d1b)) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad5fc14..0566c84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.1.4](https://github.com/serverless-components/tencent-express/compare/v0.1.3...v0.1.4) (2020-09-02) + + +### Bug Fixes + +* update tencnet-component-toolkit for api mark ([7e25e8a](https://github.com/serverless-components/tencent-express/commit/7e25e8a86f539b2db449caf969cbbd58c5af4d1b)) + ## [0.1.3](https://github.com/serverless-components/tencent-express/compare/v0.1.2...v0.1.3) (2020-09-01) From 33ae21248a7c191e3ceea2371fd2e69a6b1ebf67 Mon Sep 17 00:00:00 2001 From: yugasun Date: Thu, 3 Sep 2020 19:42:54 +0800 Subject: [PATCH 34/54] fix: update deploy flow for multi region --- serverless.component.yml | 2 +- src/package.json | 2 +- src/serverless.js | 229 ++++++++++++++++----------------- src/utils.js | 265 ++++++++++++++------------------------- 4 files changed, 211 insertions(+), 287 deletions(-) diff --git a/serverless.component.yml b/serverless.component.yml index 5ccc2a5..3fea1e6 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.1.4 +version: 0.1.5 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. diff --git a/src/package.json b/src/package.json index ffdd2b3..54c63c8 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.16.2", + "tencent-component-toolkit": "^1.16.4", "type": "^2.0.0" } } diff --git a/src/serverless.js b/src/serverless.js index fa4bcff..f5c536b 100644 --- a/src/serverless.js +++ b/src/serverless.js @@ -1,7 +1,7 @@ const { Component } = require('@serverless/core') -const { MultiApigw, Scf, Apigw, Cns, Cam, Metrics } = require('tencent-component-toolkit') +const { Scf, Apigw, Cns, Cam, Metrics } = require('tencent-component-toolkit') const { TypeError } = require('tencent-component-toolkit/src/utils/error') -const { uploadCodeToCos, getDefaultProtocol, deleteRecord, prepareInputs } = require('./utils') +const { uploadCodeToCos, getDefaultProtocol, prepareInputs, deepClone } = require('./utils') const CONFIGS = require('./config') class ServerlessComponent extends Component { @@ -39,135 +39,141 @@ class ServerlessComponent extends Component { } } - const uploadCodeHandler = [] const outputs = {} const appId = this.getAppId() - for (let eveRegionIndex = 0; eveRegionIndex < regionList.length; eveRegionIndex++) { - const curRegion = regionList[eveRegionIndex] - const funcDeployer = async () => { - const code = await uploadCodeToCos(this, appId, credentials, inputs, curRegion) - const scf = new Scf(credentials, curRegion) - const tempInputs = { - ...inputs, - code - } - const scfOutput = await scf.deploy(tempInputs) - outputs[curRegion] = { - functionName: scfOutput.FunctionName, - runtime: scfOutput.Runtime, - namespace: scfOutput.Namespace - } - - this.state[curRegion] = { - ...(this.state[curRegion] ? this.state[curRegion] : {}), - ...outputs[curRegion] - } + const funcDeployer = async (curRegion) => { + const code = await uploadCodeToCos(this, appId, credentials, inputs, curRegion) + const scf = new Scf(credentials, curRegion) + const tempInputs = { + ...inputs, + code + } + const scfOutput = await scf.deploy(deepClone(tempInputs)) + outputs[curRegion] = { + functionName: scfOutput.FunctionName, + runtime: scfOutput.Runtime, + namespace: scfOutput.Namespace + } - // default version is $LATEST - outputs[curRegion].lastVersion = scfOutput.LastVersion - ? scfOutput.LastVersion - : this.state.lastVersion || '$LATEST' - - // default traffic is 1.0, it can also be 0, so we should compare to undefined - outputs[curRegion].traffic = - scfOutput.Traffic !== undefined - ? scfOutput.Traffic - : this.state.traffic !== undefined - ? this.state.traffic - : 1 - - if (outputs[curRegion].traffic !== 1 && scfOutput.ConfigTrafficVersion) { - outputs[curRegion].configTrafficVersion = scfOutput.ConfigTrafficVersion - this.state.configTrafficVersion = scfOutput.ConfigTrafficVersion - } + this.state[curRegion] = { + ...(this.state[curRegion] ? this.state[curRegion] : {}), + ...outputs[curRegion] + } - this.state.lastVersion = outputs[curRegion].lastVersion - this.state.traffic = outputs[curRegion].traffic + // default version is $LATEST + outputs[curRegion].lastVersion = scfOutput.LastVersion + ? scfOutput.LastVersion + : this.state.lastVersion || '$LATEST' + + // default traffic is 1.0, it can also be 0, so we should compare to undefined + outputs[curRegion].traffic = + scfOutput.Traffic !== undefined + ? scfOutput.Traffic + : this.state.traffic !== undefined + ? this.state.traffic + : 1 + + if (outputs[curRegion].traffic !== 1 && scfOutput.ConfigTrafficVersion) { + outputs[curRegion].configTrafficVersion = scfOutput.ConfigTrafficVersion + this.state.configTrafficVersion = scfOutput.ConfigTrafficVersion } - uploadCodeHandler.push(funcDeployer()) + + this.state.lastVersion = outputs[curRegion].lastVersion + this.state.traffic = outputs[curRegion].traffic + } + + for (let i = 0; i < regionList.length; i++) { + const curRegion = regionList[i] + await funcDeployer(curRegion) } - await Promise.all(uploadCodeHandler) this.save() return outputs } + // try to add dns record + async tryToAddDnsRecord(credentials, customDomains) { + try { + const cns = new Cns(credentials) + for (let i = 0; i < customDomains.length; i++) { + const item = customDomains[i] + if (item.domainPrefix) { + await cns.deploy({ + domain: item.subDomain.replace(`${item.domainPrefix}.`, ''), + records: [ + { + subDomain: item.domainPrefix, + recordType: 'CNAME', + recordLine: '默认', + value: item.cname, + ttl: 600, + mx: 10, + status: 'enable' + } + ] + }) + } + } + } catch (e) { + console.log('METHOD_tryToAddDnsRecord', e.message) + } + } + async deployApigateway(credentials, inputs, regionList) { if (inputs.isDisabled) { return {} } - const apigw = new MultiApigw(credentials, regionList) - const oldState = this.state[regionList[0]] || {} - inputs.oldState = { - apiList: oldState.apiList || [], - customDomains: oldState.customDomains || [] + + const getServiceId = (instance, region) => { + const regionState = instance.state[region] + return inputs.serviceId || (regionState && regionState.serviceId) } - const apigwOutputs = await apigw.deploy(inputs) - const outputs = {} - Object.keys(apigwOutputs).forEach((curRegion) => { - const curOutput = apigwOutputs[curRegion] - outputs[curRegion] = { - serviceId: curOutput.serviceId, - subDomain: curOutput.subDomain, - environment: curOutput.environment, - url: `${getDefaultProtocol(inputs.protocols)}://${curOutput.subDomain}/${ - curOutput.environment - }/` - } - if (curOutput.customDomains) { - outputs[curRegion].customDomains = curOutput.customDomains - } - this.state[curRegion] = { - created: curOutput.created, - ...(this.state[curRegion] ? this.state[curRegion] : {}), - ...outputs[curRegion], - apiList: curOutput.apiList - } - }) - this.save() - return outputs - } - async deployCns(credentials, inputs, regionList, apigwOutputs) { - const cns = new Cns(credentials) - const cnsRegion = {} + const deployTasks = [] + const outputs = {} regionList.forEach((curRegion) => { - const curApigwOutput = apigwOutputs[curRegion] - cnsRegion[curRegion] = curApigwOutput.subDomain - }) + const apigwDeployer = async () => { + const apigw = new Apigw(credentials, curRegion) - const state = [] - const outputs = {} - const tempJson = {} - for (let i = 0; i < inputs.length; i++) { - const curCns = inputs[i] - for (let j = 0; j < curCns.records.length; j++) { - curCns.records[j].value = - cnsRegion[curCns.records[j].value.replace('temp_value_about_', '')] - } - const tencentCnsOutputs = await cns.deploy(curCns) - outputs[curCns.domain] = tencentCnsOutputs.DNS - ? tencentCnsOutputs.DNS - : 'The domain name has already been added.' - tencentCnsOutputs.domain = curCns.domain - state.push(tencentCnsOutputs) - } + const oldState = this.state[curRegion] || {} + const apigwInputs = { + ...inputs, + oldState: { + apiList: oldState.apiList || [], + customDomains: oldState.customDomains || [] + } + } + // different region deployment has different service id + apigwInputs.serviceId = getServiceId(this, curRegion) + const apigwOutput = await apigw.deploy(deepClone(apigwInputs)) + outputs[curRegion] = { + serviceId: apigwOutput.serviceId, + subDomain: apigwOutput.subDomain, + environment: apigwOutput.environment, + url: `${getDefaultProtocol(inputs.protocols)}://${apigwOutput.subDomain}/${ + apigwOutput.environment + }/` + } - // 删除serverless创建的但是不在本次列表中 - try { - for (let i = 0; i < state.length; i++) { - tempJson[state[i].domain] = state[i].records - } - const recordHistory = this.state.cns || [] - for (let i = 0; i < recordHistory.length; i++) { - const delList = deleteRecord(tempJson[recordHistory[i].domain], recordHistory[i].records) - if (delList && delList.length > 0) { - await cns.remove({ deleteList: delList }) + if (apigwOutput.customDomains) { + // TODO: need confirm add cns authentication + if (inputs.autoAddDnsRecord === true) { + // await this.tryToAddDnsRecord(credentials, apigwOutput.customDomains) + } + outputs[curRegion].customDomains = apigwOutput.customDomains + } + this.state[curRegion] = { + created: true, + ...(this.state[curRegion] ? this.state[curRegion] : {}), + ...outputs[curRegion], + apiList: apigwOutput.apiList } } - } catch (e) {} + deployTasks.push(apigwDeployer()) + }) + + await Promise.all(deployTasks) - this.state['cns'] = state this.save() return outputs } @@ -178,7 +184,7 @@ class ServerlessComponent extends Component { const credentials = this.getCredentials() // 对Inputs内容进行标准化 - const { regionList, functionConf, apigatewayConf, cnsConf } = await prepareInputs( + const { regionList, functionConf, apigatewayConf } = await prepareInputs( this, credentials, inputs @@ -210,11 +216,6 @@ class ServerlessComponent extends Component { outputs['scf'] = functionOutputs } - // cns depends on apigw, so if disabled apigw, just ignore it. - if (cnsConf.length > 0 && apigatewayConf.isDisabled !== true) { - outputs['cns'] = await this.deployCns(credentials, cnsConf, regionList, apigwOutputs) - } - this.state.region = regionList[0] this.state.regionList = regionList this.state.lambdaArn = functionConf.name diff --git a/src/utils.js b/src/utils.js index 4ce62a2..9251bcb 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,5 +1,5 @@ const path = require('path') -const { Domain, Cos } = require('tencent-component-toolkit') +const { Cos } = require('tencent-component-toolkit') const ensureObject = require('type/object/ensure') const ensureIterable = require('type/iterable/ensure') const ensureString = require('type/string/ensure') @@ -15,10 +15,45 @@ const generateId = () => .toString(36) .substring(6) +const deepClone = (obj) => { + return JSON.parse(JSON.stringify(obj)) +} + const getType = (obj) => { return Object.prototype.toString.call(obj).slice(8, -1) } +const mergeJson = (sourceJson, targetJson) => { + Object.entries(sourceJson).forEach(([key, val]) => { + targetJson[key] = deepClone(val) + }) + return targetJson +} + +const capitalString = (str) => { + if (str.length < 2) { + return str.toUpperCase() + } + + return `${str[0].toUpperCase()}${str.slice(1)}` +} + +const getDefaultProtocol = (protocols) => { + return String(protocols).includes('https') ? 'https' : 'http' +} + +const getDefaultFunctionName = () => { + return `${CONFIGS.compName}_component_${generateId()}` +} + +const getDefaultServiceName = () => { + return 'serverless' +} + +const getDefaultServiceDescription = () => { + return 'Created by Serverless Component' +} + const validateTraffic = (num) => { if (getType(num) !== 'Number') { throw new TypeError( @@ -107,12 +142,18 @@ const uploadCodeToCos = async (instance, appId, credentials, inputs, region) => object: objectName, method: 'PUT' }) - const slsSDKEntries = instance.getSDKEntries('_shims/handler.handler') + // if shims and sls sdk entries had been injected to zipPath, no need to injected again console.log(`Uploading code to bucket ${bucketName}`) - await instance.uploadSourceZipToCOS(zipPath, uploadUrl, slsSDKEntries, { - _shims: path.join(__dirname, '_shims') - }) + if (instance.codeInjected === true) { + await instance.uploadSourceZipToCOS(zipPath, uploadUrl, {}, {}) + } else { + const slsSDKEntries = instance.getSDKEntries('_shims/handler.handler') + await instance.uploadSourceZipToCOS(zipPath, uploadUrl, slsSDKEntries, { + _shims: path.join(__dirname, '_shims') + }) + instance.codeInjected = true + } console.log(`Upload ${objectName} to bucket ${bucketName} success`) } } @@ -127,72 +168,6 @@ const uploadCodeToCos = async (instance, appId, credentials, inputs, region) => } } -const mergeJson = (sourceJson, targetJson) => { - for (const eveKey in sourceJson) { - if (targetJson.hasOwnProperty(eveKey)) { - if (['protocols', 'endpoints', 'customDomain'].indexOf(eveKey) != -1) { - for (let i = 0; i < sourceJson[eveKey].length; i++) { - const sourceEvents = JSON.stringify(sourceJson[eveKey][i]) - const targetEvents = JSON.stringify(targetJson[eveKey]) - if (targetEvents.indexOf(sourceEvents) == -1) { - targetJson[eveKey].push(sourceJson[eveKey][i]) - } - } - } else { - if (typeof sourceJson[eveKey] != 'string') { - mergeJson(sourceJson[eveKey], targetJson[eveKey]) - } else { - targetJson[eveKey] = sourceJson[eveKey] - } - } - } else { - targetJson[eveKey] = sourceJson[eveKey] - } - } - return targetJson -} - -const capitalString = (str) => { - if (str.length < 2) { - return str.toUpperCase() - } - - return `${str[0].toUpperCase()}${str.slice(1)}` -} - -const getDefaultProtocol = (protocols) => { - if (!protocols || protocols.length < 1) { - return 'http' - } - if (protocols.map((i) => i.toLowerCase()).includes('https')) { - return 'https' - } - return 'http' -} - -const deleteRecord = (newRecords, historyRcords) => { - const deleteList = [] - for (let i = 0; i < historyRcords.length; i++) { - let temp = false - for (let j = 0; j < newRecords.length; j++) { - if ( - newRecords[j].domain == historyRcords[i].domain && - newRecords[j].subDomain == historyRcords[i].subDomain && - newRecords[j].recordType == historyRcords[i].recordType && - newRecords[j].value == historyRcords[i].value && - newRecords[j].recordLine == historyRcords[i].recordLine - ) { - temp = true - break - } - } - if (!temp) { - deleteList.push(historyRcords[i]) - } - } - return deleteList -} - const prepareInputs = async (instance, credentials, inputs = {}) => { // 对function inputs进行标准化 const tempFunctionConf = inputs.functionConf ? inputs.functionConf : {} @@ -206,9 +181,6 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { // chenck state function name const stateFunctionName = instance.state[regionList[0]] && instance.state[regionList[0]].functionName - // check state service id - const stateServiceId = instance.state[regionList[0]] && instance.state[regionList[0]].serviceId - const functionConf = { code: { src: inputs.src, @@ -218,7 +190,7 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { name: ensureString(inputs.functionName, { isOptional: true }) || stateFunctionName || - `${CONFIGS.compName}_component_${generateId()}`, + getDefaultFunctionName(), region: regionList, role: ensureString(tempFunctionConf.role ? tempFunctionConf.role : inputs.role, { default: '' @@ -250,7 +222,12 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { traffic: inputs.traffic, lastVersion: instance.state.lastVersion, eip: tempFunctionConf.eip === true, - l5Enable: tempFunctionConf.l5Enable === true + l5Enable: tempFunctionConf.l5Enable === true, + timeout: tempFunctionConf.timeout ? tempFunctionConf.timeout : CONFIGS.timeout, + memorySize: tempFunctionConf.memorySize ? tempFunctionConf.memorySize : CONFIGS.memorySize, + tags: ensureObject(tempFunctionConf.tags ? tempFunctionConf.tags : inputs.tag, { + default: null + }) } // validate traffic @@ -259,68 +236,55 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { } functionConf.needSetTraffic = inputs.traffic !== undefined && functionConf.lastVersion - functionConf.tags = ensureObject(tempFunctionConf.tags ? tempFunctionConf.tags : inputs.tag, { - default: null - }) - - if (inputs.functionConf) { - functionConf.timeout = inputs.functionConf.timeout - ? inputs.functionConf.timeout - : CONFIGS.timeout - functionConf.memorySize = inputs.functionConf.memorySize - ? inputs.functionConf.memorySize - : CONFIGS.memorySize - if (inputs.functionConf.environment) { - functionConf.environment = inputs.functionConf.environment - } - if (inputs.functionConf.vpcConfig) { - functionConf.vpcConfig = inputs.functionConf.vpcConfig - } + if (tempFunctionConf.environment) { + functionConf.environment = inputs.functionConf.environment + } + if (tempFunctionConf.vpcConfig) { + functionConf.vpcConfig = inputs.functionConf.vpcConfig } // 对apigw inputs进行标准化 - const apigatewayConf = inputs.apigatewayConf ? inputs.apigatewayConf : {} - apigatewayConf.isDisabled = apigatewayConf.isDisabled === true - apigatewayConf.fromClientRemark = fromClientRemark - apigatewayConf.serviceName = inputs.serviceName - apigatewayConf.serviceId = inputs.serviceId || stateServiceId - apigatewayConf.region = functionConf.region - apigatewayConf.endpoints = [ - { - path: '/', - enableCORS: apigatewayConf.enableCORS, - serviceTimeout: apigatewayConf.serviceTimeout, - method: 'ANY', - function: { - isIntegratedResponse: apigatewayConf.isIntegratedResponse === false ? false : true, - functionName: functionConf.name, - functionNamespace: functionConf.namespace, - functionQualifier: functionConf.needSetTraffic ? '$DEFAULT' : '$LATEST' + const tempApigwConf = inputs.apigatewayConf ? inputs.apigatewayConf : {} + const apigatewayConf = { + serviceId: inputs.serviceId, + region: regionList, + isDisabled: tempApigwConf.isDisabled === true, + fromClientRemark: fromClientRemark, + serviceName: inputs.serviceName || getDefaultServiceName(instance), + description: getDefaultServiceDescription(instance), + protocols: tempApigwConf.protocols || ['http'], + environment: tempApigwConf.environment ? tempApigwConf.environment : 'release', + endpoints: [ + { + path: '/', + enableCORS: tempApigwConf.enableCORS, + serviceTimeout: tempApigwConf.serviceTimeout, + method: 'ANY', + function: { + isIntegratedResponse: true, + functionName: functionConf.name, + functionNamespace: functionConf.namespace + } } - } - ] - if (apigatewayConf.usagePlan) { + ], + customDomains: tempApigwConf.customDomains || [] + } + if (tempApigwConf.usagePlan) { apigatewayConf.endpoints[0].usagePlan = { - usagePlanId: apigatewayConf.usagePlan.usagePlanId, - usagePlanName: apigatewayConf.usagePlan.usagePlanName, - usagePlanDesc: apigatewayConf.usagePlan.usagePlanDesc, - maxRequestNum: apigatewayConf.usagePlan.maxRequestNum + usagePlanId: tempApigwConf.usagePlan.usagePlanId, + usagePlanName: tempApigwConf.usagePlan.usagePlanName, + usagePlanDesc: tempApigwConf.usagePlan.usagePlanDesc, + maxRequestNum: tempApigwConf.usagePlan.maxRequestNum } } - if (apigatewayConf.auth) { + if (tempApigwConf.auth) { apigatewayConf.endpoints[0].auth = { - secretName: apigatewayConf.auth.secretName, - secretIds: apigatewayConf.auth.secretIds + secretName: tempApigwConf.auth.secretName, + secretIds: tempApigwConf.auth.secretIds } } - // 对cns inputs进行标准化 - const tempCnsConf = {} - const tempCnsBaseConf = inputs.cloudDNSConf ? inputs.cloudDNSConf : {} - - // 分地域处理functionConf/apigatewayConf/cnsConf - for (let i = 0; i < functionConf.region.length; i++) { - const curRegion = functionConf.region[i] + regionList.forEach((curRegion) => { const curRegionConf = inputs[curRegion] if (curRegionConf && curRegionConf.functionConf) { functionConf[curRegion] = curRegionConf.functionConf @@ -328,62 +292,21 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { if (curRegionConf && curRegionConf.apigatewayConf) { apigatewayConf[curRegion] = curRegionConf.apigatewayConf } - - const tempRegionCnsConf = mergeJson( - tempCnsBaseConf, - curRegionConf && curRegionConf.cloudDNSConf ? curRegionConf.cloudDNSConf : {} - ) - - tempCnsConf[functionConf.region[i]] = { - recordType: 'CNAME', - recordLine: tempRegionCnsConf.recordLine ? tempRegionCnsConf.recordLine : undefined, - ttl: tempRegionCnsConf.ttl, - mx: tempRegionCnsConf.mx, - status: tempRegionCnsConf.status ? tempRegionCnsConf.status : 'enable' - } - } - - const cnsConf = [] - // 对cns inputs进行检查和赋值 - if (apigatewayConf.customDomain && apigatewayConf.customDomain.length > 0) { - const domain = new Domain(credentials) - for (let domianNum = 0; domianNum < apigatewayConf.customDomain.length; domianNum++) { - const domainData = await domain.check(apigatewayConf.customDomain[domianNum].domain) - const tempInputs = { - domain: domainData.domain, - records: [] - } - for (let eveRecordNum = 0; eveRecordNum < functionConf.region.length; eveRecordNum++) { - if (tempCnsConf[functionConf.region[eveRecordNum]].recordLine) { - tempInputs.records.push({ - subDomain: domainData.subDomain || '@', - recordType: 'CNAME', - recordLine: tempCnsConf[functionConf.region[eveRecordNum]].recordLine, - value: `temp_value_about_${functionConf.region[eveRecordNum]}`, - ttl: tempCnsConf[functionConf.region[eveRecordNum]].ttl, - mx: tempCnsConf[functionConf.region[eveRecordNum]].mx, - status: tempCnsConf[functionConf.region[eveRecordNum]].status || 'enable' - }) - } - } - cnsConf.push(tempInputs) - } - } + }) return { regionList, functionConf, - apigatewayConf, - cnsConf + apigatewayConf } } module.exports = { + deepClone, generateId, uploadCodeToCos, mergeJson, capitalString, getDefaultProtocol, - deleteRecord, prepareInputs } From f40f3bd848bb52921686219a2cb1bf8f3aaaa656 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 3 Sep 2020 11:47:04 +0000 Subject: [PATCH 35/54] chore(release): version 0.1.5 ## [0.1.5](https://github.com/serverless-components/tencent-express/compare/v0.1.4...v0.1.5) (2020-09-03) ### Bug Fixes * update deploy flow for multi region ([33ae212](https://github.com/serverless-components/tencent-express/commit/33ae21248a7c191e3ceea2371fd2e69a6b1ebf67)) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0566c84..fe19091 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.1.5](https://github.com/serverless-components/tencent-express/compare/v0.1.4...v0.1.5) (2020-09-03) + + +### Bug Fixes + +* update deploy flow for multi region ([33ae212](https://github.com/serverless-components/tencent-express/commit/33ae21248a7c191e3ceea2371fd2e69a6b1ebf67)) + ## [0.1.4](https://github.com/serverless-components/tencent-express/compare/v0.1.3...v0.1.4) (2020-09-02) From 80e28903422c5710a56a8267f64ffe47398ddcf8 Mon Sep 17 00:00:00 2001 From: yugasun Date: Sat, 10 Oct 2020 18:59:41 +0800 Subject: [PATCH 36/54] feat: support custom entry file and all scf config --- .github/workflows/release.yml | 48 ++++++++++++++++++++++++++++++++++ .github/workflows/test.yml | 45 +++++++++++++++++++++++++++++++ .github/workflows/validate.yml | 45 +++++++++++++++++++++++++++++++ .travis.yml | 23 ---------------- docs/configure.md | 28 +++++++++++--------- package.json | 27 ++++++++++++++++--- serverless.component.yml | 2 +- src/_shims/handler.js | 8 +++--- src/config.js | 1 + src/package.json | 2 +- src/utils.js | 29 +++++++++++++------- tests/integration.test.js | 9 ++++--- 12 files changed, 210 insertions(+), 57 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/test.yml create mode 100644 .github/workflows/validate.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..4c476a4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,48 @@ +name: Release + +on: + push: + branches: [master] + +jobs: + release: + name: Release + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.GH_TOKEN }} + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + persist-credentials: false + + - name: Install Node.js and npm + uses: actions/setup-node@v1 + with: + node-version: 14.x + registry-url: https://registry.npmjs.org + + - name: Retrieve dependencies from cache + id: cacheNpm + uses: actions/cache@v2 + with: + path: | + ~/.npm + node_modules + key: npm-v14-${{ runner.os }}-refs/heads/master-${{ hashFiles('package.json') }} + restore-keys: npm-v14-${{ runner.os }}-refs/heads/master- + + - name: Install dependencies + if: steps.cacheNpm.outputs.cache-hit != 'true' + run: | + npm update --no-save + npm update --save-dev --no-save + - name: Releasing + run: | + npm run release + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + GIT_AUTHOR_NAME: slsplus + GIT_AUTHOR_EMAIL: yuga.sun.bj@gmail.com + GIT_COMMITTER_NAME: slsplus + GIT_COMMITTER_EMAIL: yuga.sun.bj@gmail.com diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..e8bdb44 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,45 @@ +name: Test + +on: + pull_request: + branches: [master] + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + # Ensure connection with 'master' branch + fetch-depth: 2 + + - name: Install Node.js and npm + uses: actions/setup-node@v1 + with: + node-version: 14.x + registry-url: https://registry.npmjs.org + + - name: Retrieve dependencies from cache + id: cacheNpm + uses: actions/cache@v2 + with: + path: | + ~/.npm + node_modules + key: npm-v14-${{ runner.os }}-${{ github.ref }}-${{ hashFiles('package.json') }} + restore-keys: | + npm-v14-${{ runner.os }}-${{ github.ref }}- + npm-v14-${{ runner.os }}-refs/heads/master- + + - name: Install dependencies + if: steps.cacheNpm.outputs.cache-hit != 'true' + run: | + npm update --no-save + npm update --save-dev --no-save + - name: Running integration tests + run: npm run test + env: + TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }} + TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }} diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..3840792 --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,45 @@ +name: Validate + +on: + pull_request: + branches: [master] + +jobs: + lintAndFormatting: + name: Lint & Formatting + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + # Ensure connection with 'master' branch + fetch-depth: 2 + + - name: Install Node.js and npm + uses: actions/setup-node@v1 + with: + node-version: 14.x + registry-url: https://registry.npmjs.org + + - name: Retrieve dependencies from cache + id: cacheNpm + uses: actions/cache@v2 + with: + path: | + ~/.npm + node_modules + key: npm-v14-${{ runner.os }}-${{ github.ref }}-${{ hashFiles('package.json') }} + restore-keys: | + npm-v14-${{ runner.os }}-${{ github.ref }}- + npm-v14-${{ runner.os }}-refs/heads/master- + + - name: Install dependencies + if: steps.cacheNpm.outputs.cache-hit != 'true' + run: | + npm update --no-save + npm update --save-dev --no-save + + - name: Validate Formatting + run: npm run prettier:fix + - name: Validate Lint rules + run: npm run lint:fix diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index d78fad9..0000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: node_js - -node_js: - - 10 - -install: - - npm install - -# should change to serverless registry publish -jobs: - include: - # Define the release stage that runs semantic-release - - stage: release - node_js: 10.18 - # Advanced: optionally overwrite your default `script` step to skip the tests - # script: skip - deploy: - provider: script - skip_cleanup: true - on: - branch: master - script: - - npm run release diff --git a/docs/configure.md b/docs/configure.md index 6a6c4cb..ce276cd 100644 --- a/docs/configure.md +++ b/docs/configure.md @@ -17,6 +17,7 @@ inputs: serviceName: mytest # api网关服务名称 runtime: Nodejs10.15 # 运行环境 serviceId: service-np1uloxw # api网关服务ID + entryFile: sls.js # 自定义 server 的入口文件名,默认为 sls.js,如果不想修改文件名为 sls.js 可以自定义 src: ./src # 第一种为string时,会打包src对应目录下的代码上传到默认cos上。 # src: # 第二种,部署src下的文件代码,并打包成zip上传到bucket上 # src: ./src # 本地需要打包的文件目录 @@ -75,19 +76,20 @@ inputs: 主要的参数 -| 参数名称 | 是否必选 | 默认值 | 描述 | -| ------------------------------------ | :------: | :-------------: | :------------------------------------------------------------------ | -| runtime | 否 | `Nodejs10.15` | 执行环境, 目前支持: Nodejs6.10, Nodejs8.9, Nodejs10.15, Nodejs12.16 | -| region | 否 | `ap-guangzhou` | 项目部署所在区域,默认广州区 | -| functionName | 否 | | 云函数名称 | -| serviceName | 否 | | API 网关服务名称, 默认创建一个新的服务名称 | -| serviceId | 否 | | API 网关服务 ID,如果存在将使用这个 API 网关服务 | -| src | 否 | `process.cwd()` | 默认为当前目录, 如果是对象, 配置参数参考 [执行目录](#执行目录) | -| layers | 否 | | 云函数绑定的 layer, 配置参数参考 [层配置](#层配置) | -| [functionConf](#函数配置) | 否 | | 函数配置 | -| [apigatewayConf](#API-网关配置) | 否 | | API 网关配置 | -| [cloudDNSConf](#DNS-配置) | 否 | | DNS 配置 | -| [Region special config](#指定区配置) | 否 | | 指定区配置 | +| 参数名称 | 必选 | 默认值 | 描述 | +| ------------------------------------ | :--: | :-------------: | :------------------------------------------------------------------ | +| runtime | 否 | `Nodejs10.15` | 执行环境, 目前支持: Nodejs6.10, Nodejs8.9, Nodejs10.15, Nodejs12.16 | +| region | 否 | `ap-guangzhou` | 项目部署所在区域,默认广州区 | +| functionName | 否 | | 云函数名称 | +| serviceName | 否 | | API 网关服务名称, 默认创建一个新的服务名称 | +| serviceId | 否 | | API 网关服务 ID,如果存在将使用这个 API 网关服务 | +| entryFile | 否 | `sls.js` | 自定义 server 的入口文件名 | +| src | 否 | `process.cwd()` | 默认为当前目录, 如果是对象, 配置参数参考 [执行目录](#执行目录) | +| layers | 否 | | 云函数绑定的 layer, 配置参数参考 [层配置](#层配置) | +| [functionConf](#函数配置) | 否 | | 函数配置 | +| [apigatewayConf](#API-网关配置) | 否 | | API 网关配置 | +| [cloudDNSConf](#DNS-配置) | 否 | | DNS 配置 | +| [Region special config](#指定区配置) | 否 | | 指定区配置 | ## 执行目录 diff --git a/package.json b/package.json index f41dde1..ee3b975 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,7 @@ "access": "public" }, "scripts": { - "int-test": "jest ./tests/integration.test.js --testEnvironment node", - "test": "npm run lint && npm run prettier && npm run int-test", + "test": "jest ./tests/integration.test.js --testEnvironment node", "commitlint": "commitlint -f HEAD@{15}", "lint": "eslint --ext .js,.ts,.tsx .", "lint:fix": "eslint --fix --ext .js,.ts,.tsx .", @@ -58,5 +57,27 @@ "lint-staged": "^10.0.8", "prettier": "^1.19.1", "semantic-release": "^17.0.4" - } + }, + "description": "Easily deploy serverless Express.js applications to Tencent Cloud with the Serverless Framework", + "directories": { + "doc": "docs", + "example": "example", + "test": "tests" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/serverless-components/tencent-express.git" + }, + "keywords": [ + "serverless-express", + "serverless", + "express", + "serverless-framework", + "serverless-components", + "tencent-cloud" + ], + "bugs": { + "url": "https://github.com/serverless-components/tencent-express/issues" + }, + "homepage": "https://github.com/serverless-components/tencent-express#readme" } diff --git a/serverless.component.yml b/serverless.component.yml index 3fea1e6..9d302b4 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.1.5 +version: 0.2.0 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. diff --git a/src/_shims/handler.js b/src/_shims/handler.js index f132ec2..5ce2f0b 100644 --- a/src/_shims/handler.js +++ b/src/_shims/handler.js @@ -4,15 +4,15 @@ const path = require('path') const { createServer, proxy } = require('tencent-serverless-http') let server +let app exports.handler = async (event, context) => { - const userSls = path.join(__dirname, '..', 'sls.js') - let app + const userSls = path.join(__dirname, '..', process.env.SLS_ENTRY_FILE) if (fs.existsSync(userSls)) { - // load the user provided app + // eslint-disable-next-line + console.log(`Using user custom entry file ${process.env.SLS_ENTRY_FILE}`) app = require(userSls) } else { - // load the built-in default app app = require('./sls.js') } diff --git a/src/config.js b/src/config.js index b4c6f64..35901dd 100644 --- a/src/config.js +++ b/src/config.js @@ -3,6 +3,7 @@ const CONFIGS = { 'https://serverless-templates-1300862921.cos.ap-beijing.myqcloud.com/express-demo.zip', compName: 'express', compFullname: 'Express.js', + defaultEntryFile: 'sls.js', handler: 'sl_handler.handler', runtime: 'Nodejs10.15', timeout: 3, diff --git a/src/package.json b/src/package.json index 54c63c8..d144f82 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.16.4", + "tencent-component-toolkit": "^1.17.0", "type": "^2.0.0" } } diff --git a/src/utils.js b/src/utils.js index 9251bcb..7780fc8 100644 --- a/src/utils.js +++ b/src/utils.js @@ -181,7 +181,7 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { // chenck state function name const stateFunctionName = instance.state[regionList[0]] && instance.state[regionList[0]].functionName - const functionConf = { + const functionConf = Object.assign(tempFunctionConf, { code: { src: inputs.src, bucket: inputs.srcOriginal && inputs.srcOriginal.bucket, @@ -221,14 +221,12 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { publish: inputs.publish, traffic: inputs.traffic, lastVersion: instance.state.lastVersion, - eip: tempFunctionConf.eip === true, - l5Enable: tempFunctionConf.l5Enable === true, timeout: tempFunctionConf.timeout ? tempFunctionConf.timeout : CONFIGS.timeout, memorySize: tempFunctionConf.memorySize ? tempFunctionConf.memorySize : CONFIGS.memorySize, tags: ensureObject(tempFunctionConf.tags ? tempFunctionConf.tags : inputs.tag, { default: null }) - } + }) // validate traffic if (inputs.traffic !== undefined) { @@ -237,15 +235,26 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { functionConf.needSetTraffic = inputs.traffic !== undefined && functionConf.lastVersion if (tempFunctionConf.environment) { - functionConf.environment = inputs.functionConf.environment + functionConf.environment = tempFunctionConf.environment + functionConf.environment.variables = functionConf.environment.variables || {} + functionConf.environment.variables.SERVERLESS = '1' + functionConf.environment.variables.SLS_ENTRY_FILE = inputs.entryFile || CONFIGS.defaultEntryFile + } else { + functionConf.environment = { + variables: { + SERVERLESS: '1', + SLS_ENTRY_FILE: inputs.entryFile || CONFIGS.defaultEntryFile + } + } } + if (tempFunctionConf.vpcConfig) { - functionConf.vpcConfig = inputs.functionConf.vpcConfig + functionConf.vpcConfig = tempFunctionConf.vpcConfig } // 对apigw inputs进行标准化 const tempApigwConf = inputs.apigatewayConf ? inputs.apigatewayConf : {} - const apigatewayConf = { + const apigatewayConf = Object.assign(tempApigwConf, { serviceId: inputs.serviceId, region: regionList, isDisabled: tempApigwConf.isDisabled === true, @@ -263,12 +272,14 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { function: { isIntegratedResponse: true, functionName: functionConf.name, - functionNamespace: functionConf.namespace + functionNamespace: functionConf.namespace, + functionQualifier: + (tempApigwConf.function && tempApigwConf.function.functionQualifier) || '$LATEST' } } ], customDomains: tempApigwConf.customDomains || [] - } + }) if (tempApigwConf.usagePlan) { apigatewayConf.endpoints[0].usagePlan = { usagePlanId: tempApigwConf.usagePlan.usagePlanId, diff --git a/tests/integration.test.js b/tests/integration.test.js index 6989e91..5ff900d 100644 --- a/tests/integration.test.js +++ b/tests/integration.test.js @@ -1,3 +1,4 @@ +require('dotenv').config() const { generateId, getServerlessSdk } = require('./utils') const execSync = require('child_process').execSync const path = require('path') @@ -20,16 +21,18 @@ const instanceYaml = { } } -// get credentials from process.env but need to init empty credentials object const credentials = { - tencent: {} + tencent: { + SecretId: process.env.TENCENT_SECRET_ID, + SecretKey: process.env.TENCENT_SECRET_KEY, + } } // get serverless construct sdk const sdk = getServerlessSdk(instanceYaml.org) it('should successfully deploy express app', async () => { - const instance = await sdk.deploy(instanceYaml, { tencent: {} }) + const instance = await sdk.deploy(instanceYaml, credentials) expect(instance).toBeDefined() expect(instance.instanceName).toEqual(instanceYaml.name) From ec3ffc7fb6a6959dbdb734b8a2137f5ac777d05c Mon Sep 17 00:00:00 2001 From: yugasun Date: Sat, 10 Oct 2020 19:38:48 +0800 Subject: [PATCH 37/54] fix: support all parameters for apigw --- src/serverless.js | 2 +- src/utils.js | 31 +++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/serverless.js b/src/serverless.js index f5c536b..530110f 100644 --- a/src/serverless.js +++ b/src/serverless.js @@ -152,7 +152,7 @@ class ServerlessComponent extends Component { environment: apigwOutput.environment, url: `${getDefaultProtocol(inputs.protocols)}://${apigwOutput.subDomain}/${ apigwOutput.environment - }/` + }${apigwInputs.endpoints[0].path}` } if (apigwOutput.customDomains) { diff --git a/src/utils.js b/src/utils.js index 7780fc8..72c30b5 100644 --- a/src/utils.js +++ b/src/utils.js @@ -170,7 +170,11 @@ const uploadCodeToCos = async (instance, appId, credentials, inputs, region) => const prepareInputs = async (instance, credentials, inputs = {}) => { // 对function inputs进行标准化 - const tempFunctionConf = inputs.functionConf ? inputs.functionConf : {} + const tempFunctionConf = inputs.functionConf + ? inputs.functionConf + : inputs.functionConfig + ? inputs.functionConfig + : {} const fromClientRemark = `tencent-${CONFIGS.compName}` const regionList = inputs.region ? typeof inputs.region == 'string' @@ -253,22 +257,30 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { } // 对apigw inputs进行标准化 - const tempApigwConf = inputs.apigatewayConf ? inputs.apigatewayConf : {} + const tempApigwConf = inputs.apigatewayConf + ? inputs.apigatewayConf + : inputs.apigwConfig + ? inputs.apigwConfig + : {} const apigatewayConf = Object.assign(tempApigwConf, { - serviceId: inputs.serviceId, + serviceId: inputs.serviceId || tempApigwConf.serviceId, region: regionList, isDisabled: tempApigwConf.isDisabled === true, fromClientRemark: fromClientRemark, - serviceName: inputs.serviceName || getDefaultServiceName(instance), - description: getDefaultServiceDescription(instance), + serviceName: inputs.serviceName || tempApigwConf.serviceName || getDefaultServiceName(instance), + serviceDesc: tempApigwConf.serviceDesc || getDefaultServiceDescription(instance), protocols: tempApigwConf.protocols || ['http'], environment: tempApigwConf.environment ? tempApigwConf.environment : 'release', - endpoints: [ + customDomains: tempApigwConf.customDomains || [] + }) + if (!apigatewayConf.endpoints) { + apigatewayConf.endpoints = [ { - path: '/', + path: tempApigwConf.path || '/', enableCORS: tempApigwConf.enableCORS, serviceTimeout: tempApigwConf.serviceTimeout, method: 'ANY', + apiName: tempApigwConf.apiName || 'index', function: { isIntegratedResponse: true, functionName: functionConf.name, @@ -277,9 +289,8 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { (tempApigwConf.function && tempApigwConf.function.functionQualifier) || '$LATEST' } } - ], - customDomains: tempApigwConf.customDomains || [] - }) + ] + } if (tempApigwConf.usagePlan) { apigatewayConf.endpoints[0].usagePlan = { usagePlanId: tempApigwConf.usagePlan.usagePlanId, From 49a1ff81749bf15440d3089d86343cec2c83cdb1 Mon Sep 17 00:00:00 2001 From: slsplus Date: Mon, 12 Oct 2020 02:13:41 +0000 Subject: [PATCH 38/54] chore(release): version 0.2.0 # [0.2.0](https://github.com/serverless-components/tencent-express/compare/v0.1.5...v0.2.0) (2020-10-12) ### Bug Fixes * support all parameters for apigw ([ec3ffc7](https://github.com/serverless-components/tencent-express/commit/ec3ffc7fb6a6959dbdb734b8a2137f5ac777d05c)) ### Features * support custom entry file and all scf config ([80e2890](https://github.com/serverless-components/tencent-express/commit/80e28903422c5710a56a8267f64ffe47398ddcf8)) --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe19091..53da79b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# [0.2.0](https://github.com/serverless-components/tencent-express/compare/v0.1.5...v0.2.0) (2020-10-12) + + +### Bug Fixes + +* support all parameters for apigw ([ec3ffc7](https://github.com/serverless-components/tencent-express/commit/ec3ffc7fb6a6959dbdb734b8a2137f5ac777d05c)) + + +### Features + +* support custom entry file and all scf config ([80e2890](https://github.com/serverless-components/tencent-express/commit/80e28903422c5710a56a8267f64ffe47398ddcf8)) + ## [0.1.5](https://github.com/serverless-components/tencent-express/compare/v0.1.4...v0.1.5) (2020-09-03) From 2fae11c9b3db69ceae5e2816d4a434a640df6a22 Mon Sep 17 00:00:00 2001 From: Tim Qian Date: Thu, 22 Oct 2020 17:15:57 +0800 Subject: [PATCH 39/54] docs: update doc (#43) --- README.md | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 225e894..dbb41bc 100644 --- a/README.md +++ b/README.md @@ -49,35 +49,27 @@ $ npm install -g serverless 通过如下命令和模板链接,快速创建一个 Express 应用: ```bash -$ serverless create --template-url https://github.com/serverless-components/tencent-express/tree/master/example +$ serverless init express-starter --name example $ cd example ``` -执行如下命令,安装 Express 应用的对应依赖 - -``` -$ npm install -``` - ### 3. 部署 -在 `serverless.yml` 文件下的目录中运行 `serverless deploy` 进行 Express 项目的部署。第一次部署可能耗时相对较久,但后续的二次部署会在几秒钟之内完成。部署完毕后,你可以在命令行的输出中查看到你 Express 应用的 URL 地址,点击地址即可访问你的 Express 项目。 - -**注意:** +在 `serverless.yml` 文件所在的项目根目录,运行以下指令进行部署: -如您的账号未[登陆](https://cloud.tencent.com/login)或[注册](https://cloud.tencent.com/register)腾讯云,您可以直接通过`微信`扫描命令行中的二维码进行授权登陆和注册。 - -如果出现了 `internal server error` 的报错,请检查是否在创建模板后没有运行 `npm install`。 +```bash +$ serverless deploy +``` -如果希望查看更多部署过程的信息,可以通过`sls deploy --debug` 命令查看部署过程中的实时日志信息,`sls`是 `serverless` 命令的缩写。 +部署时需要进行身份验证,如您的账号未 [登陆](https://cloud.tencent.com/login) 或 [注册](https://cloud.tencent.com/register) 腾讯云,您可以直接通过 `微信` 扫描命令行中的二维码进行授权登陆和注册。 -
+> 注意: 如果希望查看更多部署过程的信息,可以通过`serverless deploy --debug` 命令查看部署过程中的实时日志信息。 ### 4. 配置 Express 组件支持 0 配置部署,也就是可以直接通过配置文件中的默认值进行部署。但你依然可以修改更多可选配置来进一步开发该 Express 项目。 -以下是 Express 组件的 `serverless.yml`完整配置说明: +以下是 Express 组件的 `serverless.yml`配置示例: ```yml # serverless.yml @@ -133,7 +125,7 @@ $ serverless info $ serverless remove ``` -和部署类似,支持通过 `sls remove --debug` 命令查看移除过程中的实时日志信息,`sls`是 `serverless` 命令的缩写。 +和部署类似,支持通过 `serverless remove --debug` 命令查看移除过程中的实时日志信息。 ## 架构说明 From 968a96532f85f960789688a9cfb43763c40719ff Mon Sep 17 00:00:00 2001 From: Austen Date: Mon, 9 Nov 2020 20:05:18 -0800 Subject: [PATCH 40/54] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index dbb41bc..0e8404a 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,6 @@
- - 快速开始: 1. [**安装**](#1-安装) From a76fe586846269132f3a9b9141302050b02a13c3 Mon Sep 17 00:00:00 2001 From: yugasun Date: Fri, 11 Dec 2020 17:29:23 +0800 Subject: [PATCH 41/54] fix: update to deployment to serial flow --- serverless.component.yml | 2 +- src/package.json | 2 +- src/serverless.js | 19 ++++++++++++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/serverless.component.yml b/serverless.component.yml index 9d302b4..b51eed3 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.2.0 +version: 0.2.1 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. diff --git a/src/package.json b/src/package.json index d144f82..cec15fd 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.17.0", + "tencent-component-toolkit": "^1.19.8", "type": "^2.0.0" } } diff --git a/src/serverless.js b/src/serverless.js index 530110f..8017e4d 100644 --- a/src/serverless.js +++ b/src/serverless.js @@ -196,24 +196,33 @@ class ServerlessComponent extends Component { outputs.templateUrl = CONFIGS.templateUrl } - const deployTasks = [this.deployFunction(credentials, functionConf, regionList, outputs)] + let apigwOutputs + const functionOutputs = await this.deployFunction( + credentials, + functionConf, + regionList, + outputs + ) // support apigatewayConf.isDisabled if (apigatewayConf.isDisabled !== true) { - deployTasks.push(this.deployApigateway(credentials, apigatewayConf, regionList, outputs)) + apigwOutputs = await this.deployApigateway(credentials, apigatewayConf, regionList, outputs) } else { this.state.apigwDisabled = true } - const [functionOutputs, apigwOutputs = {}] = await Promise.all(deployTasks) // optimize outputs for one region if (regionList.length === 1) { const [oneRegion] = regionList outputs.region = oneRegion - outputs['apigw'] = apigwOutputs[oneRegion] outputs['scf'] = functionOutputs[oneRegion] + if (apigwOutputs) { + outputs['apigw'] = apigwOutputs[oneRegion] + } } else { - outputs['apigw'] = apigwOutputs outputs['scf'] = functionOutputs + if (apigwOutputs) { + outputs['apigw'] = apigwOutputs + } } this.state.region = regionList[0] From 59c00391e2e4877261ebd4c169005d54993dd2f8 Mon Sep 17 00:00:00 2001 From: slsplus Date: Tue, 15 Dec 2020 02:50:52 +0000 Subject: [PATCH 42/54] chore(release): version 0.2.1 ## [0.2.1](https://github.com/serverless-components/tencent-express/compare/v0.2.0...v0.2.1) (2020-12-15) ### Bug Fixes * update to deployment to serial flow ([a76fe58](https://github.com/serverless-components/tencent-express/commit/a76fe586846269132f3a9b9141302050b02a13c3)) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53da79b..04e4112 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.2.1](https://github.com/serverless-components/tencent-express/compare/v0.2.0...v0.2.1) (2020-12-15) + + +### Bug Fixes + +* update to deployment to serial flow ([a76fe58](https://github.com/serverless-components/tencent-express/commit/a76fe586846269132f3a9b9141302050b02a13c3)) + # [0.2.0](https://github.com/serverless-components/tencent-express/compare/v0.1.5...v0.2.0) (2020-10-12) From f766ee69cf39cf410df0203fc71644297ef70693 Mon Sep 17 00:00:00 2001 From: yugasun Date: Tue, 15 Dec 2020 11:37:02 +0800 Subject: [PATCH 43/54] fix: update remove flow --- .github/workflows/release.yml | 4 ++-- .github/workflows/test.yml | 2 +- .../index.test.js | 18 +++++++----------- {tests => __tests__/lib}/utils.js | 0 jest.config.js | 14 ++++++++++++++ package.json | 2 +- serverless.component.yml | 2 +- src/serverless.js | 8 ++++---- tests/src/package.json | 14 -------------- tests/src/sls.js | 8 -------- 10 files changed, 30 insertions(+), 42 deletions(-) rename tests/integration.test.js => __tests__/index.test.js (82%) rename {tests => __tests__/lib}/utils.js (100%) create mode 100644 jest.config.js delete mode 100644 tests/src/package.json delete mode 100644 tests/src/sls.js diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4c476a4..11c8ac8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,6 +43,6 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} GIT_AUTHOR_NAME: slsplus - GIT_AUTHOR_EMAIL: yuga.sun.bj@gmail.com + GIT_AUTHOR_EMAIL: slsplus.sz@gmail.com GIT_COMMITTER_NAME: slsplus - GIT_COMMITTER_EMAIL: yuga.sun.bj@gmail.com + GIT_COMMITTER_EMAIL: slsplus.sz@gmail.com diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e8bdb44..21b004e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,7 +38,7 @@ jobs: run: | npm update --no-save npm update --save-dev --no-save - - name: Running integration tests + - name: Running tests run: npm run test env: TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }} diff --git a/tests/integration.test.js b/__tests__/index.test.js similarity index 82% rename from tests/integration.test.js rename to __tests__/index.test.js index 5ff900d..2e67e22 100644 --- a/tests/integration.test.js +++ b/__tests__/index.test.js @@ -1,17 +1,15 @@ -require('dotenv').config() -const { generateId, getServerlessSdk } = require('./utils') +const { join } = require('path'); +require('dotenv').config({ path: join(__dirname, '.env.test') }); + +const { generateId, getServerlessSdk } = require('./lib/utils') const execSync = require('child_process').execSync const path = require('path') const axios = require('axios') -// set enough timeout for deployment to finish -jest.setTimeout(300000) - -// the yaml file we're testing against const instanceYaml = { org: 'orgDemo', app: 'appDemo', - component: 'express', + component: 'express@dev', name: `express-integration-tests-${generateId()}`, stage: 'dev', inputs: { @@ -28,7 +26,6 @@ const credentials = { } } -// get serverless construct sdk const sdk = getServerlessSdk(instanceYaml.org) it('should successfully deploy express app', async () => { @@ -36,7 +33,6 @@ it('should successfully deploy express app', async () => { expect(instance).toBeDefined() expect(instance.instanceName).toEqual(instanceYaml.name) - // get src from template by default expect(instance.outputs.templateUrl).toBeDefined() expect(instance.outputs.region).toEqual(instanceYaml.inputs.region) expect(instance.outputs.apigw).toBeDefined() @@ -47,14 +43,14 @@ it('should successfully deploy express app', async () => { it('should successfully update source code', async () => { // change source to own source './src' and need to install packages before deploy - const srcPath = path.join(__dirname, 'src') + const srcPath = path.join(__dirname, '..', 'example') execSync('npm install', { cwd: srcPath }) instanceYaml.inputs.src = srcPath const instance = await sdk.deploy(instanceYaml, credentials) const response = await axios.get(instance.outputs.apigw.url) - expect(response.data).toEqual('hello world') + expect(response.data.includes('Serverless Framework')).toBeTruthy() expect(instance.outputs.templateUrl).not.toBeDefined() }) diff --git a/tests/utils.js b/__tests__/lib/utils.js similarity index 100% rename from tests/utils.js rename to __tests__/lib/utils.js diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..a70dd57 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,14 @@ +const { join } = require('path') +require('dotenv').config({ path: join(__dirname, '.env.test') }) + +const config = { + verbose: true, + silent: false, + testTimeout: 600000, + testEnvironment: 'node', + testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(js|ts)$', + testPathIgnorePatterns: ['/node_modules/', '/__tests__/lib/'], + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] +} + +module.exports = config diff --git a/package.json b/package.json index ee3b975..4b0d707 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "access": "public" }, "scripts": { - "test": "jest ./tests/integration.test.js --testEnvironment node", + "test": "jest", "commitlint": "commitlint -f HEAD@{15}", "lint": "eslint --ext .js,.ts,.tsx .", "lint:fix": "eslint --fix --ext .js,.ts,.tsx .", diff --git a/serverless.component.yml b/serverless.component.yml index b51eed3..06b37ba 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.2.1 +version: 0.2.2 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. diff --git a/src/serverless.js b/src/serverless.js index 8017e4d..f76e037 100644 --- a/src/serverless.js +++ b/src/serverless.js @@ -247,10 +247,6 @@ class ServerlessComponent extends Component { const scf = new Scf(credentials, curRegion) const apigw = new Apigw(credentials, curRegion) const handler = async () => { - await scf.remove({ - functionName: curState.functionName, - namespace: curState.namespace - }) // if disable apigw, no need to remove if (state.apigwDisabled !== true) { await apigw.remove({ @@ -261,6 +257,10 @@ class ServerlessComponent extends Component { customDomains: curState.customDomains }) } + await scf.remove({ + functionName: curState.functionName, + namespace: curState.namespace + }) } removeHandlers.push(handler()) } diff --git a/tests/src/package.json b/tests/src/package.json deleted file mode 100644 index f47e0f8..0000000 --- a/tests/src/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "serverless-express", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "express": "^4.17.1" - } -} diff --git a/tests/src/sls.js b/tests/src/sls.js deleted file mode 100644 index e2d2260..0000000 --- a/tests/src/sls.js +++ /dev/null @@ -1,8 +0,0 @@ -const express = require('express') -const app = express() - -app.get('/', function(req, res) { - res.json('hello world') -}) - -module.exports = app From 5c6661365944a966ef7b39ee61b86545dcc58fe4 Mon Sep 17 00:00:00 2001 From: slsplus Date: Tue, 15 Dec 2020 03:40:59 +0000 Subject: [PATCH 44/54] chore(release): version 0.2.2 ## [0.2.2](https://github.com/serverless-components/tencent-express/compare/v0.2.1...v0.2.2) (2020-12-15) ### Bug Fixes * update remove flow ([f766ee6](https://github.com/serverless-components/tencent-express/commit/f766ee69cf39cf410df0203fc71644297ef70693)) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04e4112..333b0c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.2.2](https://github.com/serverless-components/tencent-express/compare/v0.2.1...v0.2.2) (2020-12-15) + + +### Bug Fixes + +* update remove flow ([f766ee6](https://github.com/serverless-components/tencent-express/commit/f766ee69cf39cf410df0203fc71644297ef70693)) + ## [0.2.1](https://github.com/serverless-components/tencent-express/compare/v0.2.0...v0.2.1) (2020-12-15) From be7b170eaad99c5734d45c5ecfd4b7e78eb06ae1 Mon Sep 17 00:00:00 2001 From: yugasun Date: Tue, 15 Dec 2020 14:47:01 +0800 Subject: [PATCH 45/54] docs: update readme --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index 0e8404a..b12ae38 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,26 @@ TENCENT_SECRET_ID=123 TENCENT_SECRET_KEY=123 ``` +## 静态资源服务 + +如果想要支持 `express.static()` 返回静态资源,比如图片之类的,需要在入口文件 `sls.js` 中指定相关 `MIME` 类型的文件为二进制,这样云函数在返回请求结果给 API 网关是,会对指定类型进行 `Base64` 编码,最终返回给客户端才能正常显示。如下: + +```js +const express = require('express') +const app = express() + +// Routes +// ... + +app.binaryTypes = ['*/*'] + +module.exports = app +``` + +`['*/*']` 代表所有文件类型将进行 `Base64` 编码,如果需要定制化,可以配置为 `['image/png']`,意思是指定 `png` 格式的图片类型。 + +更多文件类型的 `MIME` 类型,可参考 [mime-db](https://github.com/jshttp/mime-db/blob/master/db.json)。 + ## License MIT License From 1b4f7806112dea72536ff514ee68e54095a535a7 Mon Sep 17 00:00:00 2001 From: yugasun Date: Tue, 15 Dec 2020 15:00:27 +0800 Subject: [PATCH 46/54] ci: update test action env --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 21b004e..c966e94 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,5 +41,7 @@ jobs: - name: Running tests run: npm run test env: + SERVERLESS_PLATFORM_VENDOR: tencent + GLOBAL_ACCELERATOR_NA: true TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }} TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }} From 7f18f2c5e8e86cc0a9252e5bd036742251964e4d Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 28 Dec 2020 11:19:46 +0800 Subject: [PATCH 47/54] fix: add sls initialize before creating server --- README.md | 28 +++++++++++++++++++++++++++- src/_shims/handler.js | 10 +++++----- src/package.json | 2 +- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b12ae38..233b69e 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ TENCENT_SECRET_KEY=123 ## 静态资源服务 -如果想要支持 `express.static()` 返回静态资源,比如图片之类的,需要在入口文件 `sls.js` 中指定相关 `MIME` 类型的文件为二进制,这样云函数在返回请求结果给 API 网关是,会对指定类型进行 `Base64` 编码,最终返回给客户端才能正常显示。如下: +如果想要支持返回静态资源,比如图片之类的,需要在入口文件 `sls.js` 中指定相关 `MIME` 类型的文件为二进制,这样云函数在返回请求结果给 API 网关是,会对指定类型进行 `Base64` 编码,最终返回给客户端才能正常显示。如下: ```js const express = require('express') @@ -175,6 +175,32 @@ module.exports = app 更多文件类型的 `MIME` 类型,可参考 [mime-db](https://github.com/jshttp/mime-db/blob/master/db.json)。 +### slsInitialize 应用初始化 + +有些时候,Express 服务在启动前,需要进行一个初始化操作,比如数据库建连,就可以通过在 Express 实例对象上添加 `slsInitialize` 函数来实现,如下: + +```js +const express = require('express') +const mysql = require('mysql2/promise') + +const app = new express() + +// ... + +app.slsInitialize = async () => { + app.db = await mysql.createConnection({ + host: 'localhost', + user: 'root', + database: 'test' + }) +} + +// don't forget to export! +module.exports = app +``` + +这样应用部署到云函数后,在函数服务逻辑执行前,会先执行 `slsInitialize()` 函数,来初始化数据库连接。 + ## License MIT License diff --git a/src/_shims/handler.js b/src/_shims/handler.js index 5ce2f0b..5863add 100644 --- a/src/_shims/handler.js +++ b/src/_shims/handler.js @@ -20,6 +20,11 @@ exports.handler = async (event, context) => { app.request.__SLS_EVENT__ = event app.request.__SLS_CONTEXT__ = context + // provide sls intialize hooks + if (app.slsInitialize && typeof app.slsInitialize === 'function') { + await app.slsInitialize() + } + // cache server, not create repeatly if (!server) { server = createServer(app, null, app.binaryTypes || []) @@ -27,11 +32,6 @@ exports.handler = async (event, context) => { context.callbackWaitsForEmptyEventLoop = app.callbackWaitsForEmptyEventLoop === true - // provide sls intialize hooks - if (app.slsInitialize && typeof app.slsInitialize === 'function') { - await app.slsInitialize() - } - const result = await proxy(server, event, context, 'PROMISE') return result.promise } diff --git a/src/package.json b/src/package.json index cec15fd..d4f74e1 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.19.8", + "tencent-component-toolkit": "^1.20.6", "type": "^2.0.0" } } From 1cb1be494ffc5d71c790a8191292791ad9d85a41 Mon Sep 17 00:00:00 2001 From: slsplus Date: Mon, 28 Dec 2020 03:46:45 +0000 Subject: [PATCH 48/54] chore(release): version 0.2.3 ## [0.2.3](https://github.com/serverless-components/tencent-express/compare/v0.2.2...v0.2.3) (2020-12-28) ### Bug Fixes * add sls initialize before creating server ([7f18f2c](https://github.com/serverless-components/tencent-express/commit/7f18f2c5e8e86cc0a9252e5bd036742251964e4d)) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 333b0c5..7a1b14d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.2.3](https://github.com/serverless-components/tencent-express/compare/v0.2.2...v0.2.3) (2020-12-28) + + +### Bug Fixes + +* add sls initialize before creating server ([7f18f2c](https://github.com/serverless-components/tencent-express/commit/7f18f2c5e8e86cc0a9252e5bd036742251964e4d)) + ## [0.2.2](https://github.com/serverless-components/tencent-express/compare/v0.2.1...v0.2.2) (2020-12-15) From f6851129afc13e73938b4b4840203a0a092b5e65 Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 28 Dec 2020 11:48:18 +0800 Subject: [PATCH 49/54] chore: update version --- serverless.component.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serverless.component.yml b/serverless.component.yml index 06b37ba..483d953 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.2.2 +version: 0.2.3 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. From aedd8b77de4698eb0eba5cec912f82d4da7a6e68 Mon Sep 17 00:00:00 2001 From: wwwzbwcom Date: Thu, 21 Jan 2021 20:00:32 +0800 Subject: [PATCH 50/54] doc: add output doc --- README.md | 4 ++++ docs/output.md | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 docs/output.md diff --git a/README.md b/README.md index 233b69e..99a4a7e 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,10 @@ $ serverless deploy > 注意: 如果希望查看更多部署过程的信息,可以通过`serverless deploy --debug` 命令查看部署过程中的实时日志信息。 +部署完成后,控制台会打印相关的输出信息,您可以通过 `${output:${stage}:${app}:apigw.url}` 的形式在其他 `serverless` 组件中引用该组件的 API 网关访问链接(或通过类似的形式引用该组建其他输出结果),具体的,可以查看完成的输出文档: + +- [点击此处查看输出文档](https://github.com/serverless-components/tencent-express/tree/master/docs/output.md) + ### 4. 配置 Express 组件支持 0 配置部署,也就是可以直接通过配置文件中的默认值进行部署。但你依然可以修改更多可选配置来进一步开发该 Express 项目。 diff --git a/docs/output.md b/docs/output.md new file mode 100644 index 0000000..96e86d5 --- /dev/null +++ b/docs/output.md @@ -0,0 +1,53 @@ +# 部署 `output` 参数介绍 + +> 组件输出可以在别的组件中通过 `${output:${stage}:${app}:.}` 获取 +> +> 例如,如果该组件名称是 `test_name`, ·且只部署于一个地域,则可以通过 `${output:${stage}:${app}:test_name.apigw.url}` 在别的组件中获取该组件的 API 网关的 `url`。 + +| 名称 | 类型 | 描述 | +| :---------- | :-------------: | :----------------------------------------------------- | ---------------- | +| templateUrl | string | 未提供代码时的模板代码 url | +| region | string | 地域信息(只有一个地域时才提供) | +| scf | [`FunctionOutput | Record`](#云函数输出-`FunctionOutput`) | 云函数输出信息 | +| apigw | [`ApigwOutput | Record`](#API-网关输出-`ApigwOutput`) | API 网关输出信息 | + +## 云函数输出 `FunctionOutput` + +| 名称 | 类型 | 描述 | +| :------------------- | :------------: | :--------------------- | +| functionName | string | 云函数名称 | +| runtime | string | 云运行环境 | +| namespace | string | 云函数名称空间 | +| lastVersion | string | 云函数版本 | +| traffic | `number (0~1)` | 将多少流量导向该云函数 | +| configTrafficVersion | string | | + +## API 网关输出 `ApigwOutput` + +| 名称 | 类型 | 描述 | +| :------------ | :------------------------------------------------------------------: | :------------------------- | ------- | -------- | +| serviceId | string | API 网关 ID | +| subDomain | string | API 网关子域名 | +| enviroment | `"release" | "prepub" | "test"` | API 网关 | +| url | string | API 网关对外的完整 URL | +| traffic | number (0~1) | 将多少流量导向该云函数 | +| customDomains | [CustomDomain[]](#API-网关自定义域名输出-`ApigwOutput.CustomDomain`) | API 网关自定义域名输出列表 | + +## API 网关自定义域名输出 `ApigwOutput.CustomDomain` + +| 名称 | 类型 | 描述 | +| :--------------- | :----------------------------------------------------------------: | :------------------------- | ---------- | +| domain | string | 自定义域名 | +| certificateId | string | 域名证书 ID | +| isDefaultMapping | boolean | 该自定义域名是否为默认域名 | +| pathMappingSet | [PathMapping[]](#-API-网关域名映射规则-`CustomDomain.PathMapping`) | 该域名的路径映射规则列表 | +| protocols | `"http" | "https"` | 启用的协议 | + + + +## API 网关域名映射规则 `CustomDomain.PathMapping` + +| 名称 | 类型 | 描述 | +| :--------- | :----: | :--------------- | +| path | string | 路径 | +| enviroment | string | 路径映射到的环境 | From 78ca26613eec65558852ff1b6a130a841b0178f3 Mon Sep 17 00:00:00 2001 From: yugasun Date: Fri, 22 Jan 2021 20:28:06 +0800 Subject: [PATCH 51/54] feat: support apigw base64 encode --- docs/configure.md | 22 ++++++++++++---------- docs/output.md | 22 ++++++++++------------ serverless.component.yml | 2 +- src/package.json | 2 +- src/utils.js | 3 +++ 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/docs/configure.md b/docs/configure.md index ce276cd..392f030 100644 --- a/docs/configure.md +++ b/docs/configure.md @@ -61,6 +61,7 @@ inputs: - https environment: test serviceTimeout: 15 + isBase64Encoded: false usagePlan: # 用户使用计划 usagePlanId: 1111 usagePlanName: slscmp @@ -151,16 +152,17 @@ inputs: ### API 网关配置 -| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 | -| -------------- | :------: | :------- | :--------- | :--------------------------------------------------------------------------------- | -| protocols | 否 | String[] | `['http']` | 前端请求的类型,如 http,https,http 与 https | -| environment | 否 | String | `release` | 发布环境. 目前支持三种发布环境: test(测试), prepub(预发布) 与 release(发布). | -| usagePlan | 否 | | | 使用计划配置, 参考 [使用计划](#使用计划) | -| auth | 否 | | | API 密钥配置, 参考 [API 密钥](#API-密钥配置) | -| customDomain | 否 | Object[] | | 自定义 API 域名配置, 参考 [自定义域名](#自定义域名) | -| enableCORS | 否 | Boolean | `false` | 开启跨域。默认值为否。 | -| serviceTimeout | 否 | Number | `15` | Api 超时时间,单位: 秒 | -| isDisabled | 否 | Boolean | `false` | 关闭自动创建 API 网关功能。默认值为否,即默认自动创建 API 网关。 | +| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 | +| --------------- | :------: | :------- | :--------- | :--------------------------------------------------------------------------------- | +| protocols | 否 | String[] | `['http']` | 前端请求的类型,如 http,https,http 与 https | +| environment | 否 | String | `release` | 发布环境. 目前支持三种发布环境: test(测试), prepub(预发布) 与 release(发布). | +| usagePlan | 否 | | | 使用计划配置, 参考 [使用计划](#使用计划) | +| auth | 否 | | | API 密钥配置, 参考 [API 密钥](#API-密钥配置) | +| customDomain | 否 | Object[] | | 自定义 API 域名配置, 参考 [自定义域名](#自定义域名) | +| enableCORS | 否 | Boolean | `false` | 开启跨域。默认值为否。 | +| serviceTimeout | 否 | Number | `15` | Api 超时时间,单位: 秒 | +| isDisabled | 否 | Boolean | `false` | 关闭自动创建 API 网关功能。默认值为否,即默认自动创建 API 网关。 | +| isBase64Encoded | 否 | Boolean | `false` | 是否开启 Base64 编码,如果需要文件上传,请配置为 `true` | ##### 使用计划 diff --git a/docs/output.md b/docs/output.md index 96e86d5..f9fdd99 100644 --- a/docs/output.md +++ b/docs/output.md @@ -4,12 +4,12 @@ > > 例如,如果该组件名称是 `test_name`, ·且只部署于一个地域,则可以通过 `${output:${stage}:${app}:test_name.apigw.url}` 在别的组件中获取该组件的 API 网关的 `url`。 -| 名称 | 类型 | 描述 | -| :---------- | :-------------: | :----------------------------------------------------- | ---------------- | -| templateUrl | string | 未提供代码时的模板代码 url | -| region | string | 地域信息(只有一个地域时才提供) | -| scf | [`FunctionOutput | Record`](#云函数输出-`FunctionOutput`) | 云函数输出信息 | -| apigw | [`ApigwOutput | Record`](#API-网关输出-`ApigwOutput`) | API 网关输出信息 | +| 名称 | 类型 | 描述 | +| :---------- | :------------------------------------------------------------------------------: | :------------------------------- | +| templateUrl | string | 未提供代码时的模板代码 url | +| region | string | 地域信息(只有一个地域时才提供) | +| scf | [`FunctionOutput | Record`](#云函数输出-`FunctionOutput`) | 云函数输出信息 | +| apigw | [`ApigwOutput | Record`](#API-网关输出-`ApigwOutput`) | API 网关输出信息 | ## 云函数输出 `FunctionOutput` @@ -25,10 +25,10 @@ ## API 网关输出 `ApigwOutput` | 名称 | 类型 | 描述 | -| :------------ | :------------------------------------------------------------------: | :------------------------- | ------- | -------- | +| :------------ | :------------------------------------------------------------------: | :------------------------- | | serviceId | string | API 网关 ID | | subDomain | string | API 网关子域名 | -| enviroment | `"release" | "prepub" | "test"` | API 网关 | +| enviroment | `"release" | "prepub" | "test"` | API 网关 | | url | string | API 网关对外的完整 URL | | traffic | number (0~1) | 将多少流量导向该云函数 | | customDomains | [CustomDomain[]](#API-网关自定义域名输出-`ApigwOutput.CustomDomain`) | API 网关自定义域名输出列表 | @@ -36,14 +36,12 @@ ## API 网关自定义域名输出 `ApigwOutput.CustomDomain` | 名称 | 类型 | 描述 | -| :--------------- | :----------------------------------------------------------------: | :------------------------- | ---------- | +| :--------------- | :----------------------------------------------------------------: | :------------------------- | | domain | string | 自定义域名 | | certificateId | string | 域名证书 ID | | isDefaultMapping | boolean | 该自定义域名是否为默认域名 | | pathMappingSet | [PathMapping[]](#-API-网关域名映射规则-`CustomDomain.PathMapping`) | 该域名的路径映射规则列表 | -| protocols | `"http" | "https"` | 启用的协议 | - - +| protocols | `"http" | "https"` | 启用的协议 | ## API 网关域名映射规则 `CustomDomain.PathMapping` diff --git a/serverless.component.yml b/serverless.component.yml index 483d953..34269df 100644 --- a/serverless.component.yml +++ b/serverless.component.yml @@ -1,5 +1,5 @@ name: express -version: 0.2.3 +version: 0.3.0 author: Tencent Cloud, Inc. org: Tencent Cloud, Inc. description: Deploy a serverless Express.js application on Tencent SCF and API Gateway. diff --git a/src/package.json b/src/package.json index d4f74e1..8722896 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "dependencies": { "download": "^8.0.0", - "tencent-component-toolkit": "^1.20.6", + "tencent-component-toolkit": "^1.20.10", "type": "^2.0.0" } } diff --git a/src/utils.js b/src/utils.js index 72c30b5..b8b6b6d 100644 --- a/src/utils.js +++ b/src/utils.js @@ -281,6 +281,9 @@ const prepareInputs = async (instance, credentials, inputs = {}) => { serviceTimeout: tempApigwConf.serviceTimeout, method: 'ANY', apiName: tempApigwConf.apiName || 'index', + isBase64Encoded: tempApigwConf.isBase64Encoded, + isBase64Trigger: tempApigwConf.isBase64Trigger, + base64EncodedTriggerRules: tempApigwConf.base64EncodedTriggerRules, function: { isIntegratedResponse: true, functionName: functionConf.name, From e81810888c906e12160cdbf84035bb5e1f845b0c Mon Sep 17 00:00:00 2001 From: slsplus Date: Tue, 26 Jan 2021 02:15:42 +0000 Subject: [PATCH 52/54] chore(release): version 0.3.0 # [0.3.0](https://github.com/serverless-components/tencent-express/compare/v0.2.3...v0.3.0) (2021-01-26) ### Features * support apigw base64 encode ([78ca266](https://github.com/serverless-components/tencent-express/commit/78ca26613eec65558852ff1b6a130a841b0178f3)) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a1b14d..96dfed8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.3.0](https://github.com/serverless-components/tencent-express/compare/v0.2.3...v0.3.0) (2021-01-26) + + +### Features + +* support apigw base64 encode ([78ca266](https://github.com/serverless-components/tencent-express/commit/78ca26613eec65558852ff1b6a130a841b0178f3)) + ## [0.2.3](https://github.com/serverless-components/tencent-express/compare/v0.2.2...v0.2.3) (2020-12-28) From d323c1eb851205760d7517cd4e7e245ec628f2dd Mon Sep 17 00:00:00 2001 From: yugasun Date: Tue, 26 Jan 2021 20:36:35 +0800 Subject: [PATCH 53/54] chore: add upload template entry file --- docs/upload.md | 31 +++++++++++++++++++++++ example/sls.js | 11 +++++--- example/sls.upload.js | 59 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 docs/upload.md create mode 100644 example/sls.upload.js diff --git a/docs/upload.md b/docs/upload.md new file mode 100644 index 0000000..2e5e68d --- /dev/null +++ b/docs/upload.md @@ -0,0 +1,31 @@ +## 文件上传说明 + +项目中如果涉及到文件上传,需要依赖 API 网关提供的 [Base64 编码能力](https://cloud.tencent.com/document/product/628/51799),使用时只需要 `serverless.yml` 中配置 `isBase64Encoded` 为 `true`,如下: + +```yaml +app: appDemo +stage: dev +component: express +name: expressDemo + +inputs: + # 省略... + apigatewayConf: + isBase64Encoded: true + # 省略... + # 省略... +``` + +当前 API 网关支持上传最大文件大小为 `2M`,如果文件过大,请修改为前端直传对象存储方案。 + +## Base64 示例 + +此 Github 项目的 `example` 目录下存在模板文件: + +- [sls.upload.js](../example/sls.upload.js) + +开发者可根据个人项目需要参考修改,使用时需要复制文件名为 `sls.js`。 + +文件中实现了文件上传接口 `POST /upload`,如果要支持文件上传,需要安装 `multer` 包。 + +同时需要在 `serverless.yml` 的 `apigatewayConf` 中配置 `isBase64Encoded` 为 `true`。 diff --git a/example/sls.js b/example/sls.js index ce89135..b0d9090 100644 --- a/example/sls.js +++ b/example/sls.js @@ -1,6 +1,7 @@ const express = require('express') const path = require('path') const app = express() +const isServerless = process.env.SERVERLESS // Routes app.get(`/`, (req, res) => { @@ -39,6 +40,10 @@ app.use(function(err, req, res, next) { res.status(500).send('Internal Serverless Error') }) -app.listen(8080) - -module.exports = app +if (isServerless) { + module.exports = app +} else { + app.listen(3000, () => { + console.log(`Server start on http://localhost:3000`) + }) +} diff --git a/example/sls.upload.js b/example/sls.upload.js new file mode 100644 index 0000000..14b8552 --- /dev/null +++ b/example/sls.upload.js @@ -0,0 +1,59 @@ +const multer = require('multer') +const express = require('express') +const path = require('path') + +const app = express() +const isServerless = process.env.SERVERLESS +const upload = multer({ dest: isServerless ? '/tmp/upload' : './upload' }) + +// Routes +app.post('/upload', upload.single('file'), (req, res) => { + res.send({ + success: true, + data: req.file + }) +}) + +app.get(`/`, (req, res) => { + res.sendFile(path.join(__dirname, 'index.html')) +}) + +app.get('/user', (req, res) => { + res.send([ + { + title: 'serverless framework', + link: 'https://serverless.com/' + } + ]) +}) + +app.get('/user/:id', (req, res) => { + const id = req.params.id + res.send({ + id: id, + title: 'serverless framework', + link: 'https://serverless.com/' + }) +}) + +app.get('/404', (req, res) => { + res.status(404).send('Not found') +}) + +app.get('/500', (req, res) => { + res.status(500).send('Server Error') +}) + +// Error handler +app.use(function(err, req, res, next) { + console.error(err) + res.status(500).send('Internal Serverless Error') +}) + +if (isServerless) { + module.exports = app +} else { + app.listen(3000, () => { + console.log(`Server start on http://localhost:3000`) + }) +} From a9765683ca88b0895774625bdaf613b35b1b232d Mon Sep 17 00:00:00 2001 From: yugasun Date: Mon, 22 Mar 2021 16:18:31 +0800 Subject: [PATCH 54/54] docs: update readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 99a4a7e..9fb1b9d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +⚠️⚠️⚠️ 所有框架组件项目迁移到 [tencent-framework-components](https://github.com/serverless-components/tencent-framework-components). + [![Serverless Components](https://img.serverlesscloud.cn/2020210/1581352135771-express.png)](http://serverless.com)