@whook/gcp-functions 8.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +187 -0
  3. package/dist/commands/testHTTPFunction.d.ts +12 -0
  4. package/dist/commands/testHTTPFunction.js +156 -0
  5. package/dist/commands/testHTTPFunction.js.map +1 -0
  6. package/dist/commands/testHTTPFunction.mjs +136 -0
  7. package/dist/commands/testHTTPFunction.mjs.map +1 -0
  8. package/dist/index.d.ts +18 -0
  9. package/dist/index.js +299 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/index.mjs +265 -0
  12. package/dist/index.mjs.map +1 -0
  13. package/dist/libs/utils.d.ts +5 -0
  14. package/dist/libs/utils.js +39 -0
  15. package/dist/libs/utils.js.map +1 -0
  16. package/dist/libs/utils.mjs +27 -0
  17. package/dist/libs/utils.mjs.map +1 -0
  18. package/dist/services/_autoload.d.ts +17 -0
  19. package/dist/services/_autoload.js +121 -0
  20. package/dist/services/_autoload.js.map +1 -0
  21. package/dist/services/_autoload.mjs +107 -0
  22. package/dist/services/_autoload.mjs.map +1 -0
  23. package/dist/services/log.d.ts +2 -0
  24. package/dist/services/log.js +14 -0
  25. package/dist/services/log.js.map +1 -0
  26. package/dist/services/log.mjs +4 -0
  27. package/dist/services/log.mjs.map +1 -0
  28. package/dist/services/log.test.d.ts +1 -0
  29. package/dist/services/log.test.js +12 -0
  30. package/dist/services/log.test.js.map +1 -0
  31. package/dist/services/log.test.mjs +7 -0
  32. package/dist/services/log.test.mjs.map +1 -0
  33. package/dist/wrappers/googleHTTPFunction.d.ts +22 -0
  34. package/dist/wrappers/googleHTTPFunction.js +310 -0
  35. package/dist/wrappers/googleHTTPFunction.js.map +1 -0
  36. package/dist/wrappers/googleHTTPFunction.mjs +289 -0
  37. package/dist/wrappers/googleHTTPFunction.mjs.map +1 -0
  38. package/package.json +215 -0
  39. package/src/commands/testHTTPFunction.ts +181 -0
  40. package/src/index.ts +443 -0
  41. package/src/libs/utils.ts +43 -0
  42. package/src/services/_autoload.ts +161 -0
  43. package/src/services/log.test.ts +7 -0
  44. package/src/services/log.ts +4 -0
  45. package/src/wrappers/googleHTTPFunction.ts +468 -0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+ Copyright © 2017 Nicolas Froidure
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the “Software”), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,187 @@
1
+ [//]: # ( )
2
+ [//]: # (This file is automatically generated by a `metapak`)
3
+ [//]: # (module. Do not change it except between the)
4
+ [//]: # (`content:start/end` flags, your changes would)
5
+ [//]: # (be overridden.)
6
+ [//]: # ( )
7
+ # @whook/gcp-functions
8
+ > Build and deploy to GCP Cloud Functions with Whook.
9
+
10
+ [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/nfroidure/whook/blob/master/packages/whook-gcp-functions/LICENSE)
11
+ [![NPM version](https://badge.fury.io/js/%40whook%2Fgcp-functions.svg)](https://npmjs.org/package/@whook/gcp-functions)
12
+
13
+
14
+ [//]: # (::contents:start)
15
+
16
+ This module is aimed to help you to build and deploy your
17
+ [Whook](https://github.com/nfroidure/whook) server to
18
+ [Google Cloud Functions](https://cloud.google.com/functions).
19
+
20
+ You can find a complete setup with a Terraform deployment example in
21
+ [this pull request](https://github.com/nfroidure/whook/pull/66).
22
+
23
+ ## Quick setup
24
+
25
+ Install this module and its peer dependencies :
26
+
27
+ ```sh
28
+ npm i @whook/gcp-functions;
29
+ npm i --save-dev @whook/http-transaction esbuild
30
+ ```
31
+
32
+ Add this module to your Whook plugins and tweak the 2 build functions in your
33
+ `build.ts` main file:
34
+
35
+ ```diff
36
+ - import YError from 'yerror';
37
+ +import {
38
+ + runBuild as runBaseBuild,
39
+ + prepareBuildEnvironment as prepareBaseBuildEnvironment,
40
+ +} from '@whook/gcp-functions';
41
+
42
+ // (...)
43
+
44
+ export async function prepareEnvironment(
45
+ $: Knifecycle = new Knifecycle(),
46
+ ): Promise<Knifecycle> {
47
+
48
+ // (...)
49
+
50
+ // Setup your own whook plugins or avoid whook defaults by leaving it empty
51
+ - $.register(constant('WHOOK_PLUGINS', ['@whook/cli', '@whook/whook']));
52
+ + $.register(constant('WHOOK_PLUGINS', [
53
+ + '@whook/gcp-functions',
54
+ + '@whook/cli',
55
+ + '@whook/whook',
56
+ + ]));
57
+
58
+ // (...)
59
+
60
+ }
61
+
62
+ // (...)
63
+
64
+ // The `runBuild` function is intended to build the
65
+ // project
66
+ export async function runBuild(
67
+ innerPrepareEnvironment = prepareBuildEnvironment,
68
+ ): Promise<void> {
69
+ - throw new YError('E_NO_BUILD_IMPLEMENTED');
70
+
71
+ // Usually, here you call the installed build
72
+ - // return runBaseBuild(innerPrepareEnvironment);
73
+ + return runBaseBuild(innerPrepareEnvironment);
74
+ }
75
+
76
+ // (...)
77
+
78
+ // The `prepareBuildEnvironment` create the build
79
+ // environment
80
+ export async function prepareBuildEnvironment(
81
+ $: Knifecycle = new Knifecycle(),
82
+ ): Promise<Knifecycle> {
83
+ $ = await prepareEnvironment($);
84
+
85
+ // (...)
86
+
87
+ - // Usually, here you call the installed build env
88
+ - // $ = await prepareBaseBuildEnvironment($);
89
+ + // Calling the GCP specific build env
90
+ + $ = await prepareBaseBuildEnvironment($);
91
+
92
+
93
+ // The build often need to know were initializers
94
+ // can be found to create a static build and
95
+ // remove the need to create an injector
96
+ $.register(
97
+ constant('INITIALIZER_PATH_MAP', {
98
+ // (...)
99
+ obfuscator: '@whook/http-transaction/dist/services/obfuscator',
100
+ - log: 'common-services/dist/log',
101
+ + log: '@whook/gcp-functions/dist/services/log',
102
+ time: 'common-services/dist/time',
103
+ delay: 'common-services/dist/delay',
104
+ }),
105
+ );
106
+
107
+ // (...)
108
+
109
+ }
110
+ ```
111
+
112
+ And add the GCP Functions config (usually in `src/config/common/config.js`):
113
+
114
+ ```diff
115
+ + import type { WhookCompilerConfig } from '@whook/whook';
116
+ + import type {
117
+ + WhookAPIOperationGCPFunctionConfig
118
+ + } from '@whook/gcp-functions';
119
+
120
+ // ...
121
+
122
+ export type AppConfigs = WhookConfigs &
123
+ + WhookCompilerConfig &
124
+ APIConfig;
125
+
126
+ const CONFIG: AppConfigs = {
127
+ // ...
128
+ + COMPILER_OPTIONS: {
129
+ + externalModules: [],
130
+ + ignoredModules: [],
131
+ + target: '12', // Node 14 is in public review
132
+ + },
133
+ };
134
+
135
+ // Export custom handlers definitions
136
+ export type APIHandlerDefinition = WhookAPIHandlerDefinition<
137
+ + WhookAPIOperationGCPFunctionConfig &
138
+ WhookAPIOperationSwaggerConfig
139
+ >;
140
+
141
+ export default CONFIG;
142
+ ```
143
+
144
+ # Build
145
+
146
+ To build your functions :
147
+
148
+ ```sh
149
+ # Build all functions
150
+ npm run compile && npm run build
151
+
152
+ # Build only one function
153
+ npm run compile && npm run build -- getPing
154
+ ```
155
+
156
+ # Debug
157
+
158
+ You can easily test your function builds by adding `@whook/gcp-functions` to
159
+ your `WHOOK_PLUGINS` list. It provides you some commands like the
160
+ `testHTTPFunction` one:
161
+
162
+ ```sh
163
+ npx whook testHTTPFunction --name getPing
164
+ ```
165
+
166
+ To get more insights when errors happens:
167
+
168
+ ```sh
169
+ npm run whook-dev -- testHTTPFunction --name getPing
170
+ ```
171
+
172
+ ## Deployment
173
+
174
+ We recommend using [Terraform](https://terraform.io) to deploy your functions.
175
+
176
+ There is a complete example on how to deploy your functions
177
+ [in this pull request](https://github.com/nfroidure/whook/pull/54).
178
+
179
+ [//]: # (::contents:end)
180
+
181
+ # API
182
+
183
+ # Authors
184
+ - [Nicolas Froidure](http://insertafter.com/en/index.html)
185
+
186
+ # License
187
+ [MIT](https://github.com/nfroidure/whook/blob/master/packages/whook-gcp-functions/LICENSE)
@@ -0,0 +1,12 @@
1
+ import type { WhookCommandArgs, WhookCommandDefinition } from '@whook/cli';
2
+ import type { LogService } from 'common-services';
3
+ import type { OpenAPIV3 } from 'openapi-types';
4
+ export declare const definition: WhookCommandDefinition;
5
+ declare const _default: import("knifecycle").ServiceInitializer<{
6
+ NODE_ENV: string;
7
+ PROJECT_DIR: string;
8
+ API: OpenAPIV3.Document<{}>;
9
+ log: LogService;
10
+ args: WhookCommandArgs;
11
+ }, () => Promise<void>>;
12
+ export default _default;
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.definition = void 0;
7
+
8
+ var _utils = require("../libs/utils");
9
+
10
+ var _knifecycle = require("knifecycle");
11
+
12
+ var _cli = require("@whook/cli");
13
+
14
+ var _yerror = _interopRequireDefault(require("yerror"));
15
+
16
+ var _httpRouter = require("@whook/http-router");
17
+
18
+ var _stream = _interopRequireDefault(require("stream"));
19
+
20
+ var _camelcase = _interopRequireDefault(require("camelcase"));
21
+
22
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
+
24
+ const SEARCH_SEPARATOR = '?';
25
+ const PATH_SEPARATOR = '/';
26
+ const definition = {
27
+ description: 'A command for testing AWS HTTP lambda',
28
+ example: `whook testHTTPLambda --name getPing`,
29
+ arguments: {
30
+ type: 'object',
31
+ additionalProperties: false,
32
+ required: ['name'],
33
+ properties: {
34
+ name: {
35
+ description: 'Name of the lamda to run',
36
+ type: 'string'
37
+ },
38
+ type: {
39
+ description: 'Type of lambda to test',
40
+ type: 'string',
41
+ enum: ['main', 'index'],
42
+ default: 'index'
43
+ },
44
+ contentType: {
45
+ description: 'Content type of the payload',
46
+ type: 'string',
47
+ default: 'application/json'
48
+ },
49
+ parameters: {
50
+ description: 'The HTTP call parameters',
51
+ type: 'string',
52
+ default: '{}'
53
+ }
54
+ }
55
+ }
56
+ };
57
+ exports.definition = definition;
58
+
59
+ var _default = (0, _knifecycle.extra)(definition, (0, _knifecycle.service)(initTestHTTPLambdaCommand, "testHTTPLambdaCommand", ["NODE_ENV", "PROJECT_DIR", "API", "log", "args"]));
60
+
61
+ exports.default = _default;
62
+
63
+ async function initTestHTTPLambdaCommand({
64
+ NODE_ENV,
65
+ PROJECT_DIR,
66
+ API,
67
+ log,
68
+ args
69
+ }) {
70
+ return async () => {
71
+ const {
72
+ name,
73
+ type,
74
+ contentType,
75
+ parameters: rawParameters
76
+ } = (0, _cli.readArgs)(definition.arguments, args);
77
+ const handler = await (0, _utils.loadLambda)({
78
+ PROJECT_DIR,
79
+ log
80
+ }, NODE_ENV, name, type);
81
+ const OPERATION = (await (0, _httpRouter.dereferenceOpenAPIOperations)(API, (0, _httpRouter.getOpenAPIOperations)(API))).find(({
82
+ operationId
83
+ }) => operationId === name);
84
+
85
+ if (!OPERATION) {
86
+ throw new _yerror.default('E_OPERATION_NOT_FOUND');
87
+ }
88
+
89
+ const hasBody = !!OPERATION.requestBody;
90
+ const parameters = JSON.parse(rawParameters);
91
+ const search = (OPERATION.parameters || []).filter(p => p.in === 'query').reduce((accSearch, p) => {
92
+ if (null != parameters[p.name]) {
93
+ return accSearch + (accSearch ? '&' : '') + p.name + '=' + parameters[p.name];
94
+ }
95
+
96
+ return accSearch;
97
+ }, '');
98
+ const path = OPERATION.path.split(PATH_SEPARATOR).map(part => {
99
+ const matches = /^\{([\d\w]+)\}$/i.exec(part);
100
+
101
+ if (matches) {
102
+ return parameters[matches[1]];
103
+ }
104
+
105
+ return part;
106
+ }).join(PATH_SEPARATOR);
107
+ const gcpfRequest = {
108
+ method: OPERATION.method,
109
+ originalUrl: path + (search ? SEARCH_SEPARATOR + search : ''),
110
+ headers: (OPERATION.parameters || []).filter(p => p.in === 'header').reduce((headerParameters, p) => {
111
+ headerParameters[p.name] = parameters[(0, _camelcase.default)(p.name)];
112
+ return headerParameters;
113
+ }, {}),
114
+ rawBody: Buffer.from(hasBody ? contentType === 'application/json' ? parameters.body ? JSON.stringify(parameters.body) : '' : parameters.body || '' : '')
115
+ };
116
+
117
+ if (hasBody) {
118
+ gcpfRequest.headers['content-type'] = `${contentType};charset=UTF-8`;
119
+ }
120
+
121
+ log('info', 'GCPF_REQUEST:', gcpfRequest);
122
+ const response = {
123
+ status: 0,
124
+ headers: {},
125
+ data: ''
126
+ };
127
+ await new Promise((resolve, reject) => {
128
+ const gcpfResponse = new _stream.default.PassThrough();
129
+
130
+ gcpfResponse.set = (name, value) => {
131
+ response.headers[name] = value;
132
+ };
133
+
134
+ gcpfResponse.status = code => {
135
+ response.status = code;
136
+ };
137
+
138
+ handler(gcpfRequest, gcpfResponse).catch(reject);
139
+ const chunks = [];
140
+ gcpfResponse.once('end', () => {
141
+ response.data = Buffer.concat(chunks).toString();
142
+ resolve();
143
+ });
144
+ gcpfResponse.once('error', reject);
145
+ gcpfResponse.on('readable', () => {
146
+ let data;
147
+
148
+ while (data = gcpfResponse.read()) {
149
+ chunks.push(data);
150
+ }
151
+ });
152
+ });
153
+ log('info', 'SUCCESS:', response);
154
+ };
155
+ }
156
+ //# sourceMappingURL=testHTTPFunction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/commands/testHTTPFunction.ts"],"names":["SEARCH_SEPARATOR","PATH_SEPARATOR","definition","description","example","arguments","type","additionalProperties","required","properties","name","enum","default","contentType","parameters","initTestHTTPLambdaCommand","NODE_ENV","PROJECT_DIR","API","log","args","rawParameters","handler","OPERATION","find","operationId","YError","hasBody","requestBody","JSON","parse","search","filter","p","in","reduce","accSearch","path","split","map","part","matches","exec","join","gcpfRequest","method","originalUrl","headers","headerParameters","rawBody","Buffer","from","body","stringify","response","status","data","Promise","resolve","reject","gcpfResponse","stream","PassThrough","set","value","code","catch","chunks","once","concat","toString","on","read","push"],"mappings":"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","sourcesContent":["import { loadLambda } from '../libs/utils';\nimport { extra, autoService } from 'knifecycle';\nimport { readArgs } from '@whook/cli';\nimport YError from 'yerror';\nimport {\n dereferenceOpenAPIOperations,\n getOpenAPIOperations,\n} from '@whook/http-router';\nimport stream from 'stream';\nimport camelCase from 'camelcase';\nimport type {\n WhookCommandArgs,\n WhookCommandDefinition,\n WhookCommandNamedArgs,\n} from '@whook/cli';\nimport type { LogService } from 'common-services';\nimport type { OpenAPIV3 } from 'openapi-types';\n\nconst SEARCH_SEPARATOR = '?';\nconst PATH_SEPARATOR = '/';\n\nexport const definition: WhookCommandDefinition = {\n description: 'A command for testing AWS HTTP lambda',\n example: `whook testHTTPLambda --name getPing`,\n arguments: {\n type: 'object',\n additionalProperties: false,\n required: ['name'],\n properties: {\n name: {\n description: 'Name of the lamda to run',\n type: 'string',\n },\n type: {\n description: 'Type of lambda to test',\n type: 'string',\n enum: ['main', 'index'],\n default: 'index',\n },\n contentType: {\n description: 'Content type of the payload',\n type: 'string',\n default: 'application/json',\n },\n parameters: {\n description: 'The HTTP call parameters',\n type: 'string',\n default: '{}',\n },\n },\n },\n};\n\nexport default extra(definition, autoService(initTestHTTPLambdaCommand));\n\nasync function initTestHTTPLambdaCommand({\n NODE_ENV,\n PROJECT_DIR,\n API,\n log,\n args,\n}: {\n NODE_ENV: string;\n PROJECT_DIR: string;\n API: OpenAPIV3.Document;\n log: LogService;\n args: WhookCommandArgs;\n}) {\n return async () => {\n const {\n name,\n type,\n contentType,\n parameters: rawParameters,\n }: WhookCommandNamedArgs = readArgs(definition.arguments, args) as {\n name: string;\n type: string;\n contentType: string;\n parameters: string;\n };\n const handler = await loadLambda(\n { PROJECT_DIR, log },\n NODE_ENV,\n name,\n type,\n );\n const OPERATION = (\n await dereferenceOpenAPIOperations(API, getOpenAPIOperations(API))\n ).find(({ operationId }) => operationId === name);\n\n if (!OPERATION) {\n throw new YError('E_OPERATION_NOT_FOUND');\n }\n\n const hasBody = !!OPERATION.requestBody;\n const parameters = JSON.parse(rawParameters);\n const search = ((OPERATION.parameters || []) as OpenAPIV3.ParameterObject[])\n .filter((p) => p.in === 'query')\n .reduce((accSearch, p) => {\n if (null != parameters[p.name]) {\n return (\n accSearch +\n (accSearch ? '&' : '') +\n p.name +\n '=' +\n parameters[p.name]\n );\n }\n return accSearch;\n }, '');\n\n const path = OPERATION.path\n .split(PATH_SEPARATOR)\n\n .map((part) => {\n const matches = /^\\{([\\d\\w]+)\\}$/i.exec(part);\n\n if (matches) {\n return parameters[matches[1]];\n }\n return part;\n })\n .join(PATH_SEPARATOR);\n const gcpfRequest = {\n method: OPERATION.method,\n originalUrl: path + (search ? SEARCH_SEPARATOR + search : ''),\n headers: ((OPERATION.parameters || []) as OpenAPIV3.ParameterObject[])\n .filter((p) => p.in === 'header')\n .reduce((headerParameters, p) => {\n headerParameters[p.name] = parameters[camelCase(p.name)];\n return headerParameters;\n }, {}),\n rawBody: Buffer.from(\n hasBody\n ? contentType === 'application/json'\n ? parameters.body\n ? JSON.stringify(parameters.body)\n : ''\n : parameters.body || ''\n : '',\n ),\n };\n if (hasBody) {\n gcpfRequest.headers['content-type'] = `${contentType};charset=UTF-8`;\n }\n log('info', 'GCPF_REQUEST:', gcpfRequest);\n\n const response = {\n status: 0,\n headers: {},\n data: '',\n };\n await new Promise<void>((resolve, reject) => {\n const gcpfResponse: any = new stream.PassThrough();\n\n gcpfResponse.set = (name: string, value: string) => {\n response.headers[name] = value;\n };\n gcpfResponse.status = (code: number) => {\n response.status = code;\n };\n\n handler(gcpfRequest, gcpfResponse).catch(reject);\n\n const chunks = [];\n\n gcpfResponse.once('end', () => {\n response.data = Buffer.concat(chunks).toString();\n resolve();\n });\n gcpfResponse.once('error', reject);\n gcpfResponse.on('readable', () => {\n let data;\n while ((data = gcpfResponse.read())) {\n chunks.push(data);\n }\n });\n });\n log('info', 'SUCCESS:', response);\n };\n}\n"],"file":"testHTTPFunction.js"}
@@ -0,0 +1,136 @@
1
+ import { loadLambda } from '../libs/utils';
2
+ import { extra, service as _service } from 'knifecycle';
3
+ import { readArgs } from '@whook/cli';
4
+ import YError from 'yerror';
5
+ import { dereferenceOpenAPIOperations, getOpenAPIOperations } from '@whook/http-router';
6
+ import stream from 'stream';
7
+ import camelCase from 'camelcase';
8
+ const SEARCH_SEPARATOR = '?';
9
+ const PATH_SEPARATOR = '/';
10
+ export const definition = {
11
+ description: 'A command for testing AWS HTTP lambda',
12
+ example: `whook testHTTPLambda --name getPing`,
13
+ arguments: {
14
+ type: 'object',
15
+ additionalProperties: false,
16
+ required: ['name'],
17
+ properties: {
18
+ name: {
19
+ description: 'Name of the lamda to run',
20
+ type: 'string'
21
+ },
22
+ type: {
23
+ description: 'Type of lambda to test',
24
+ type: 'string',
25
+ enum: ['main', 'index'],
26
+ default: 'index'
27
+ },
28
+ contentType: {
29
+ description: 'Content type of the payload',
30
+ type: 'string',
31
+ default: 'application/json'
32
+ },
33
+ parameters: {
34
+ description: 'The HTTP call parameters',
35
+ type: 'string',
36
+ default: '{}'
37
+ }
38
+ }
39
+ }
40
+ };
41
+ export default extra(definition, _service(initTestHTTPLambdaCommand, "testHTTPLambdaCommand", ["NODE_ENV", "PROJECT_DIR", "API", "log", "args"]));
42
+
43
+ async function initTestHTTPLambdaCommand({
44
+ NODE_ENV,
45
+ PROJECT_DIR,
46
+ API,
47
+ log,
48
+ args
49
+ }) {
50
+ return async () => {
51
+ const {
52
+ name,
53
+ type,
54
+ contentType,
55
+ parameters: rawParameters
56
+ } = readArgs(definition.arguments, args);
57
+ const handler = await loadLambda({
58
+ PROJECT_DIR,
59
+ log
60
+ }, NODE_ENV, name, type);
61
+ const OPERATION = (await dereferenceOpenAPIOperations(API, getOpenAPIOperations(API))).find(({
62
+ operationId
63
+ }) => operationId === name);
64
+
65
+ if (!OPERATION) {
66
+ throw new YError('E_OPERATION_NOT_FOUND');
67
+ }
68
+
69
+ const hasBody = !!OPERATION.requestBody;
70
+ const parameters = JSON.parse(rawParameters);
71
+ const search = (OPERATION.parameters || []).filter(p => p.in === 'query').reduce((accSearch, p) => {
72
+ if (null != parameters[p.name]) {
73
+ return accSearch + (accSearch ? '&' : '') + p.name + '=' + parameters[p.name];
74
+ }
75
+
76
+ return accSearch;
77
+ }, '');
78
+ const path = OPERATION.path.split(PATH_SEPARATOR).map(part => {
79
+ const matches = /^\{([\d\w]+)\}$/i.exec(part);
80
+
81
+ if (matches) {
82
+ return parameters[matches[1]];
83
+ }
84
+
85
+ return part;
86
+ }).join(PATH_SEPARATOR);
87
+ const gcpfRequest = {
88
+ method: OPERATION.method,
89
+ originalUrl: path + (search ? SEARCH_SEPARATOR + search : ''),
90
+ headers: (OPERATION.parameters || []).filter(p => p.in === 'header').reduce((headerParameters, p) => {
91
+ headerParameters[p.name] = parameters[camelCase(p.name)];
92
+ return headerParameters;
93
+ }, {}),
94
+ rawBody: Buffer.from(hasBody ? contentType === 'application/json' ? parameters.body ? JSON.stringify(parameters.body) : '' : parameters.body || '' : '')
95
+ };
96
+
97
+ if (hasBody) {
98
+ gcpfRequest.headers['content-type'] = `${contentType};charset=UTF-8`;
99
+ }
100
+
101
+ log('info', 'GCPF_REQUEST:', gcpfRequest);
102
+ const response = {
103
+ status: 0,
104
+ headers: {},
105
+ data: ''
106
+ };
107
+ await new Promise((resolve, reject) => {
108
+ const gcpfResponse = new stream.PassThrough();
109
+
110
+ gcpfResponse.set = (name, value) => {
111
+ response.headers[name] = value;
112
+ };
113
+
114
+ gcpfResponse.status = code => {
115
+ response.status = code;
116
+ };
117
+
118
+ handler(gcpfRequest, gcpfResponse).catch(reject);
119
+ const chunks = [];
120
+ gcpfResponse.once('end', () => {
121
+ response.data = Buffer.concat(chunks).toString();
122
+ resolve();
123
+ });
124
+ gcpfResponse.once('error', reject);
125
+ gcpfResponse.on('readable', () => {
126
+ let data;
127
+
128
+ while (data = gcpfResponse.read()) {
129
+ chunks.push(data);
130
+ }
131
+ });
132
+ });
133
+ log('info', 'SUCCESS:', response);
134
+ };
135
+ }
136
+ //# sourceMappingURL=testHTTPFunction.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/commands/testHTTPFunction.ts"],"names":["loadLambda","extra","autoService","readArgs","YError","dereferenceOpenAPIOperations","getOpenAPIOperations","stream","camelCase","SEARCH_SEPARATOR","PATH_SEPARATOR","definition","description","example","arguments","type","additionalProperties","required","properties","name","enum","default","contentType","parameters","initTestHTTPLambdaCommand","NODE_ENV","PROJECT_DIR","API","log","args","rawParameters","handler","OPERATION","find","operationId","hasBody","requestBody","JSON","parse","search","filter","p","in","reduce","accSearch","path","split","map","part","matches","exec","join","gcpfRequest","method","originalUrl","headers","headerParameters","rawBody","Buffer","from","body","stringify","response","status","data","Promise","resolve","reject","gcpfResponse","PassThrough","set","value","code","catch","chunks","once","concat","toString","on","read","push"],"mappings":"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","sourcesContent":["import { loadLambda } from '../libs/utils';\nimport { extra, autoService } from 'knifecycle';\nimport { readArgs } from '@whook/cli';\nimport YError from 'yerror';\nimport {\n dereferenceOpenAPIOperations,\n getOpenAPIOperations,\n} from '@whook/http-router';\nimport stream from 'stream';\nimport camelCase from 'camelcase';\nimport type {\n WhookCommandArgs,\n WhookCommandDefinition,\n WhookCommandNamedArgs,\n} from '@whook/cli';\nimport type { LogService } from 'common-services';\nimport type { OpenAPIV3 } from 'openapi-types';\n\nconst SEARCH_SEPARATOR = '?';\nconst PATH_SEPARATOR = '/';\n\nexport const definition: WhookCommandDefinition = {\n description: 'A command for testing AWS HTTP lambda',\n example: `whook testHTTPLambda --name getPing`,\n arguments: {\n type: 'object',\n additionalProperties: false,\n required: ['name'],\n properties: {\n name: {\n description: 'Name of the lamda to run',\n type: 'string',\n },\n type: {\n description: 'Type of lambda to test',\n type: 'string',\n enum: ['main', 'index'],\n default: 'index',\n },\n contentType: {\n description: 'Content type of the payload',\n type: 'string',\n default: 'application/json',\n },\n parameters: {\n description: 'The HTTP call parameters',\n type: 'string',\n default: '{}',\n },\n },\n },\n};\n\nexport default extra(definition, autoService(initTestHTTPLambdaCommand));\n\nasync function initTestHTTPLambdaCommand({\n NODE_ENV,\n PROJECT_DIR,\n API,\n log,\n args,\n}: {\n NODE_ENV: string;\n PROJECT_DIR: string;\n API: OpenAPIV3.Document;\n log: LogService;\n args: WhookCommandArgs;\n}) {\n return async () => {\n const {\n name,\n type,\n contentType,\n parameters: rawParameters,\n }: WhookCommandNamedArgs = readArgs(definition.arguments, args) as {\n name: string;\n type: string;\n contentType: string;\n parameters: string;\n };\n const handler = await loadLambda(\n { PROJECT_DIR, log },\n NODE_ENV,\n name,\n type,\n );\n const OPERATION = (\n await dereferenceOpenAPIOperations(API, getOpenAPIOperations(API))\n ).find(({ operationId }) => operationId === name);\n\n if (!OPERATION) {\n throw new YError('E_OPERATION_NOT_FOUND');\n }\n\n const hasBody = !!OPERATION.requestBody;\n const parameters = JSON.parse(rawParameters);\n const search = ((OPERATION.parameters || []) as OpenAPIV3.ParameterObject[])\n .filter((p) => p.in === 'query')\n .reduce((accSearch, p) => {\n if (null != parameters[p.name]) {\n return (\n accSearch +\n (accSearch ? '&' : '') +\n p.name +\n '=' +\n parameters[p.name]\n );\n }\n return accSearch;\n }, '');\n\n const path = OPERATION.path\n .split(PATH_SEPARATOR)\n\n .map((part) => {\n const matches = /^\\{([\\d\\w]+)\\}$/i.exec(part);\n\n if (matches) {\n return parameters[matches[1]];\n }\n return part;\n })\n .join(PATH_SEPARATOR);\n const gcpfRequest = {\n method: OPERATION.method,\n originalUrl: path + (search ? SEARCH_SEPARATOR + search : ''),\n headers: ((OPERATION.parameters || []) as OpenAPIV3.ParameterObject[])\n .filter((p) => p.in === 'header')\n .reduce((headerParameters, p) => {\n headerParameters[p.name] = parameters[camelCase(p.name)];\n return headerParameters;\n }, {}),\n rawBody: Buffer.from(\n hasBody\n ? contentType === 'application/json'\n ? parameters.body\n ? JSON.stringify(parameters.body)\n : ''\n : parameters.body || ''\n : '',\n ),\n };\n if (hasBody) {\n gcpfRequest.headers['content-type'] = `${contentType};charset=UTF-8`;\n }\n log('info', 'GCPF_REQUEST:', gcpfRequest);\n\n const response = {\n status: 0,\n headers: {},\n data: '',\n };\n await new Promise<void>((resolve, reject) => {\n const gcpfResponse: any = new stream.PassThrough();\n\n gcpfResponse.set = (name: string, value: string) => {\n response.headers[name] = value;\n };\n gcpfResponse.status = (code: number) => {\n response.status = code;\n };\n\n handler(gcpfRequest, gcpfResponse).catch(reject);\n\n const chunks = [];\n\n gcpfResponse.once('end', () => {\n response.data = Buffer.concat(chunks).toString();\n resolve();\n });\n gcpfResponse.once('error', reject);\n gcpfResponse.on('readable', () => {\n let data;\n while ((data = gcpfResponse.read())) {\n chunks.push(data);\n }\n });\n });\n log('info', 'SUCCESS:', response);\n };\n}\n"],"file":"testHTTPFunction.mjs"}
@@ -0,0 +1,18 @@
1
+ import Knifecycle from 'knifecycle';
2
+ import type { Dependencies } from 'knifecycle';
3
+ import type { WhookCompilerOptions } from '@whook/whook';
4
+ import type { BuildOptions } from 'knifecycle/dist/build';
5
+ export declare const DEFAULT_BUILD_PARALLELISM = 10;
6
+ export declare type WhookBuildConfig = {
7
+ BUILD_OPTIONS?: BuildOptions;
8
+ BUILD_PARALLELISM?: number;
9
+ };
10
+ export declare type WhookAPIOperationGCPFunctionConfig = {
11
+ type?: 'http';
12
+ sourceOperationId?: string;
13
+ staticFiles?: string[];
14
+ compilerOptions?: WhookCompilerOptions;
15
+ suffix?: string;
16
+ };
17
+ export declare function prepareBuildEnvironment<T extends Knifecycle<Dependencies>>($?: T): Promise<T>;
18
+ export declare function runBuild(aPrepareBuildEnvironment: typeof prepareBuildEnvironment): Promise<void>;