@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/dist/index.js ADDED
@@ -0,0 +1,299 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.prepareBuildEnvironment = prepareBuildEnvironment;
7
+ exports.runBuild = runBuild;
8
+ exports.DEFAULT_BUILD_PARALLELISM = void 0;
9
+
10
+ var _fs = _interopRequireDefault(require("fs"));
11
+
12
+ var _util = _interopRequireDefault(require("util"));
13
+
14
+ var _path = _interopRequireDefault(require("path"));
15
+
16
+ var _mkdirp = _interopRequireDefault(require("mkdirp"));
17
+
18
+ var _cpr = _interopRequireDefault(require("cpr"));
19
+
20
+ var _yerror = _interopRequireDefault(require("yerror"));
21
+
22
+ var _knifecycle = _interopRequireWildcard(require("knifecycle"));
23
+
24
+ var _whook = require("@whook/whook");
25
+
26
+ var _autoload = _interopRequireDefault(require("./services/_autoload"));
27
+
28
+ var _httpRouter = require("@whook/http-router");
29
+
30
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
31
+
32
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
33
+
34
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
35
+
36
+ /* eslint global-require:0 */
37
+ const DEFAULT_BUILD_PARALLELISM = 10;
38
+ exports.DEFAULT_BUILD_PARALLELISM = DEFAULT_BUILD_PARALLELISM;
39
+
40
+ const readFileAsync = _util.default.promisify(_fs.default.readFile);
41
+
42
+ const writeFileAsync = _util.default.promisify(_fs.default.writeFile);
43
+
44
+ const cprAsync = _util.default.promisify(_cpr.default);
45
+
46
+ const BUILD_DEFINITIONS = {
47
+ http: {
48
+ type: 'HTTP',
49
+ wrapper: {
50
+ name: 'wrapHandlerForGoogleHTTPFunction',
51
+ path: _path.default.join(__dirname, 'wrappers', 'googleHTTPFunction')
52
+ },
53
+ suffix: 'Wrapped'
54
+ }
55
+ };
56
+
57
+ async function prepareBuildEnvironment($ = new _knifecycle.default()) {
58
+ $.register((0, _knifecycle.constant)('INITIALIZER_PATH_MAP', {
59
+ ENV: '@whook/whook/dist/services/ProxyedENV',
60
+ log: __dirname + '/services/log',
61
+ time: 'common-services/dist/time',
62
+ delay: 'common-services/dist/delay'
63
+ }));
64
+ $.register(_knifecycle.initInitializerBuilder);
65
+ $.register(_autoload.default);
66
+ $.register(_whook.initCompiler);
67
+ $.register((0, _knifecycle.constant)('PORT', 1337));
68
+ $.register((0, _knifecycle.constant)('HOST', 'localhost'));
69
+ return $;
70
+ }
71
+
72
+ async function runBuild(aPrepareBuildEnvironment) {
73
+ try {
74
+ const handlerName = process.argv[2];
75
+ const $ = await aPrepareBuildEnvironment();
76
+ const {
77
+ NODE_ENV,
78
+ BUILD_PARALLELISM,
79
+ BUILD_OPTIONS,
80
+ PROJECT_DIR,
81
+ compiler,
82
+ log,
83
+ $autoload,
84
+ API,
85
+ buildInitializer
86
+ } = await $.run(['NODE_ENV', '?BUILD_PARALLELISM', '?BUILD_OPTIONS', 'PROJECT_DIR', 'process', 'compiler', 'log', '$autoload', 'API', 'buildInitializer']);
87
+ log('info', 'Environment initialized 🚀🌕');
88
+ const operations = (await (0, _httpRouter.dereferenceOpenAPIOperations)(API, (0, _httpRouter.getOpenAPIOperations)(API))).filter(operation => {
89
+ if (handlerName) {
90
+ const sourceOperationId = operation['x-whook'] && operation['x-whook'].sourceOperationId;
91
+ return handlerName === operation.operationId || handlerName === sourceOperationId;
92
+ }
93
+
94
+ return true;
95
+ });
96
+ log('warning', `${operations.length} operations to process.`);
97
+ await processOperations({
98
+ NODE_ENV,
99
+ BUILD_OPTIONS: BUILD_OPTIONS || _whook.DEFAULT_BUILD_OPTIONS,
100
+ BUILD_PARALLELISM: BUILD_PARALLELISM || DEFAULT_BUILD_PARALLELISM,
101
+ PROJECT_DIR,
102
+ compiler,
103
+ log,
104
+ $autoload,
105
+ buildInitializer
106
+ }, operations);
107
+ await $.destroy();
108
+ } catch (err) {
109
+ // eslint-disable-next-line
110
+ console.error('💀 - Cannot launch the build:', err.stack, JSON.stringify(err.params, null, 2));
111
+ process.exit(1);
112
+ }
113
+ }
114
+
115
+ async function processOperations({
116
+ NODE_ENV,
117
+ BUILD_PARALLELISM,
118
+ BUILD_OPTIONS,
119
+ PROJECT_DIR,
120
+ compiler,
121
+ log,
122
+ $autoload,
123
+ buildInitializer
124
+ }, operations) {
125
+ const operationsLeft = operations.slice(BUILD_PARALLELISM);
126
+ await Promise.all(operations.slice(0, BUILD_PARALLELISM).map(operation => buildAnyLambda({
127
+ NODE_ENV,
128
+ PROJECT_DIR,
129
+ BUILD_OPTIONS,
130
+ compiler,
131
+ log,
132
+ $autoload,
133
+ buildInitializer
134
+ }, operation)));
135
+
136
+ if (operationsLeft.length) {
137
+ log('info', operationsLeft.length, ' operations left.');
138
+ return processOperations({
139
+ NODE_ENV,
140
+ BUILD_PARALLELISM,
141
+ BUILD_OPTIONS,
142
+ PROJECT_DIR,
143
+ compiler,
144
+ log,
145
+ $autoload,
146
+ buildInitializer
147
+ }, operationsLeft);
148
+ }
149
+
150
+ log('info', 'No more operations.');
151
+ }
152
+
153
+ async function buildAnyLambda({
154
+ NODE_ENV,
155
+ PROJECT_DIR,
156
+ BUILD_OPTIONS,
157
+ compiler,
158
+ log,
159
+ $autoload,
160
+ buildInitializer
161
+ }, operation) {
162
+ const {
163
+ operationId
164
+ } = operation;
165
+
166
+ try {
167
+ const whookConfig = operation['x-whook'] || {};
168
+ const operationType = whookConfig.type || 'http';
169
+ const sourceOperationId = whookConfig.sourceOperationId;
170
+ const entryPoint = operationId;
171
+ const finalEntryPoint = (sourceOperationId ? sourceOperationId : operationId) + ((operation['x-whook'] || {}).suffix || '');
172
+ log('warning', `Building ${operationType} "${finalEntryPoint}"...`);
173
+ const buildDefinition = BUILD_DEFINITIONS[operationType]; // eslint-disable-next-line
174
+
175
+ const applyWrapper = require(buildDefinition.wrapper.path).default;
176
+
177
+ const rootNode = await $autoload(entryPoint + (buildDefinition.suffix || ''));
178
+
179
+ const lambdaPath = _path.default.join(PROJECT_DIR, 'builds', NODE_ENV, finalEntryPoint);
180
+
181
+ const finalHandlerInitializer = applyWrapper(rootNode.initializer);
182
+ const initializerContent = await buildInitializer(finalHandlerInitializer[_knifecycle.SPECIAL_PROPS.INJECT].map(name => name === 'OPERATION_API' ? `OPERATION_API>OPERATION_API_${finalEntryPoint}` : name), BUILD_OPTIONS);
183
+ const indexContent = await buildLambdaIndex(rootNode, {
184
+ name: buildDefinition.wrapper.name,
185
+ path: buildDefinition.wrapper.path
186
+ }, BUILD_OPTIONS);
187
+ await (0, _mkdirp.default)(lambdaPath);
188
+ await Promise.all([copyStaticFiles({
189
+ PROJECT_DIR,
190
+ log
191
+ }, lambdaPath, whookConfig.staticFiles || []), ensureFileAsync({
192
+ log
193
+ }, _path.default.join(lambdaPath, 'initialize.js'), initializerContent), ensureFileAsync({
194
+ log
195
+ }, _path.default.join(lambdaPath, 'main.js'), indexContent)]);
196
+ await buildFinalLambda({
197
+ compiler,
198
+ log
199
+ }, lambdaPath, whookConfig);
200
+ } catch (err) {
201
+ log('error', `Error building "${operationId}"...`);
202
+ log('stack', err.stack);
203
+ log('debug', JSON.stringify(err.params, null, 2));
204
+ throw _yerror.default.wrap(err, 'E_LAMBDA_BUILD', operationId);
205
+ }
206
+ }
207
+
208
+ async function buildLambdaIndex(rootNode, buildWrapper, options) {
209
+ return `${options.modules === 'commonjs' ? `const pickModule = (m) => { return m && m.default || m; }
210
+ const initHandler = pickModule(require('${rootNode.path}'));
211
+ const ${buildWrapper.name} = pickModule(require('${buildWrapper.path}'));
212
+ const { initialize } = require('./initialize');` : `import initHandler from '${rootNode.path}';
213
+ import ${buildWrapper.name} from '${buildWrapper.path}';
214
+ import { initialize } from './initialize';`}
215
+
216
+ const handlerInitializer = ${buildWrapper.name}(
217
+ initHandler
218
+ );
219
+
220
+ const handlerPromise = initialize()
221
+ .then(handlerInitializer);
222
+
223
+ ${options.modules === 'commonjs' ? 'module.exports = {}; module.exports.default = ' : 'export default '}function handler (req, res) {
224
+ return handlerPromise
225
+ .then(handler => handler(req, res));
226
+ };
227
+ `;
228
+ }
229
+
230
+ async function buildFinalLambda({
231
+ compiler,
232
+ log
233
+ }, lambdaPath, whookConfig) {
234
+ const entryPoint = `${lambdaPath}/main.js`;
235
+ const {
236
+ contents,
237
+ mappings
238
+ } = await compiler(entryPoint, whookConfig.compilerOptions);
239
+ await Promise.all([ensureFileAsync({
240
+ log
241
+ }, `${lambdaPath}/index.js`, contents, 'utf-8'), mappings ? ensureFileAsync({
242
+ log
243
+ }, `${lambdaPath}/index.js.map`, mappings, 'utf-8') : Promise.resolve()]);
244
+ }
245
+
246
+ async function copyStaticFiles({
247
+ PROJECT_DIR,
248
+ log
249
+ }, lambdaPath, staticFiles = []) {
250
+ await Promise.all(staticFiles.map(async staticFile => await copyFiles({
251
+ log
252
+ }, _path.default.join(PROJECT_DIR, 'node_modules', staticFile), _path.default.join(lambdaPath, 'node_modules', staticFile))));
253
+ }
254
+
255
+ async function copyFiles({
256
+ log
257
+ }, source, destination) {
258
+ let theError;
259
+
260
+ try {
261
+ await (0, _mkdirp.default)(destination);
262
+ const data = await readFileAsync(source, 'utf-8');
263
+ await ensureFileAsync({
264
+ log
265
+ }, destination, data, 'utf-8');
266
+ } catch (err) {
267
+ theError = err;
268
+ }
269
+
270
+ if (theError) {
271
+ if ('EISDIR' !== theError.code) {
272
+ throw theError;
273
+ }
274
+
275
+ await cprAsync(source, destination, {
276
+ overwrite: true
277
+ });
278
+ }
279
+ }
280
+
281
+ async function ensureFileAsync({
282
+ log
283
+ }, path, content, encoding = 'utf-8') {
284
+ try {
285
+ const oldContent = await readFileAsync(path, encoding);
286
+
287
+ if (oldContent === content) {
288
+ log('debug', `Ignore unchanged file: "${path}".`);
289
+ return;
290
+ }
291
+ } catch (err) {
292
+ log('debug', `Write new file: "${path}".`);
293
+ return await writeFileAsync(path, content, encoding);
294
+ }
295
+
296
+ log('debug', `Write changed file: "${path}".`);
297
+ return await writeFileAsync(path, content, encoding);
298
+ }
299
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":["DEFAULT_BUILD_PARALLELISM","readFileAsync","util","promisify","fs","readFile","writeFileAsync","writeFile","cprAsync","cpr","BUILD_DEFINITIONS","http","type","wrapper","name","path","join","__dirname","suffix","prepareBuildEnvironment","$","Knifecycle","register","ENV","log","time","delay","initInitializerBuilder","initBuildAutoloader","initCompiler","runBuild","aPrepareBuildEnvironment","handlerName","process","argv","NODE_ENV","BUILD_PARALLELISM","BUILD_OPTIONS","PROJECT_DIR","compiler","$autoload","API","buildInitializer","run","operations","filter","operation","sourceOperationId","operationId","length","processOperations","DEFAULT_BUILD_OPTIONS","destroy","err","console","error","stack","JSON","stringify","params","exit","operationsLeft","slice","Promise","all","map","buildAnyLambda","whookConfig","operationType","entryPoint","finalEntryPoint","buildDefinition","applyWrapper","require","default","rootNode","lambdaPath","finalHandlerInitializer","initializer","initializerContent","SPECIAL_PROPS","INJECT","indexContent","buildLambdaIndex","copyStaticFiles","staticFiles","ensureFileAsync","buildFinalLambda","YError","wrap","buildWrapper","options","modules","contents","mappings","compilerOptions","resolve","staticFile","copyFiles","source","destination","theError","data","code","overwrite","content","encoding","oldContent"],"mappings":"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","sourcesContent":["/* eslint global-require:0 */\nimport fs from 'fs';\nimport util from 'util';\nimport path from 'path';\nimport mkdirp from 'mkdirp';\nimport cpr from 'cpr';\nimport YError from 'yerror';\nimport Knifecycle, {\n SPECIAL_PROPS,\n constant,\n initInitializerBuilder,\n} from 'knifecycle';\nimport { DEFAULT_BUILD_OPTIONS, initCompiler } from '@whook/whook';\nimport initBuildAutoloader from './services/_autoload';\nimport {\n dereferenceOpenAPIOperations,\n getOpenAPIOperations,\n} from '@whook/http-router';\nimport type { Autoloader, Dependencies, BuildInitializer } from 'knifecycle';\nimport type {\n WhookOperation,\n WhookCompilerOptions,\n WhookCompilerService,\n} from '@whook/whook';\nimport type { OpenAPIV3 } from 'openapi-types';\nimport type { LogService } from 'common-services';\nimport type { CprOptions } from 'cpr';\nimport type { BuildOptions } from 'knifecycle/dist/build';\n\nexport const DEFAULT_BUILD_PARALLELISM = 10;\n\nexport type WhookBuildConfig = {\n BUILD_OPTIONS?: BuildOptions;\n BUILD_PARALLELISM?: number;\n};\nexport type WhookAPIOperationGCPFunctionConfig = {\n type?: 'http';\n sourceOperationId?: string;\n staticFiles?: string[];\n compilerOptions?: WhookCompilerOptions;\n suffix?: string;\n};\n\nconst readFileAsync = util.promisify(fs.readFile) as (\n path: string,\n encoding: string,\n) => Promise<string>;\nconst writeFileAsync = util.promisify(fs.writeFile) as (\n path: string,\n content: string,\n encoding: string,\n) => Promise<void>;\nconst cprAsync = util.promisify(cpr) as (\n source: string,\n destination: string,\n options: CprOptions,\n) => Promise<string[]>;\n\nconst BUILD_DEFINITIONS: Record<\n WhookAPIOperationGCPFunctionConfig['type'],\n {\n type: string;\n wrapper: { name: string; path: string };\n suffix?: string;\n }\n> = {\n http: {\n type: 'HTTP',\n wrapper: {\n name: 'wrapHandlerForGoogleHTTPFunction',\n path: path.join(__dirname, 'wrappers', 'googleHTTPFunction'),\n },\n suffix: 'Wrapped',\n },\n};\n\nexport async function prepareBuildEnvironment<\n T extends Knifecycle<Dependencies>,\n>($: T = new Knifecycle() as T): Promise<T> {\n $.register(\n constant('INITIALIZER_PATH_MAP', {\n ENV: '@whook/whook/dist/services/ProxyedENV',\n log: __dirname + '/services/log',\n time: 'common-services/dist/time',\n delay: 'common-services/dist/delay',\n }),\n );\n $.register(initInitializerBuilder);\n $.register(initBuildAutoloader);\n $.register(initCompiler);\n $.register(constant('PORT', 1337));\n $.register(constant('HOST', 'localhost'));\n\n return $;\n}\n\nexport async function runBuild(\n aPrepareBuildEnvironment: typeof prepareBuildEnvironment,\n): Promise<void> {\n try {\n const handlerName = process.argv[2];\n const $ = await aPrepareBuildEnvironment();\n const {\n NODE_ENV,\n BUILD_PARALLELISM,\n BUILD_OPTIONS,\n PROJECT_DIR,\n compiler,\n log,\n $autoload,\n API,\n buildInitializer,\n }: WhookBuildConfig & {\n NODE_ENV: string;\n PROJECT_DIR: string;\n compiler: WhookCompilerService;\n log: LogService;\n $autoload: Autoloader;\n API: OpenAPIV3.Document;\n buildInitializer: BuildInitializer;\n } = await $.run([\n 'NODE_ENV',\n '?BUILD_PARALLELISM',\n '?BUILD_OPTIONS',\n 'PROJECT_DIR',\n 'process',\n 'compiler',\n 'log',\n '$autoload',\n 'API',\n 'buildInitializer',\n ]);\n\n log('info', 'Environment initialized 🚀🌕');\n\n const operations = (\n await dereferenceOpenAPIOperations(\n API,\n getOpenAPIOperations<WhookAPIOperationGCPFunctionConfig>(API),\n )\n ).filter((operation) => {\n if (handlerName) {\n const sourceOperationId =\n operation['x-whook'] && operation['x-whook'].sourceOperationId;\n\n return (\n handlerName === operation.operationId ||\n handlerName === sourceOperationId\n );\n }\n return true;\n });\n\n log('warning', `${operations.length} operations to process.`);\n await processOperations(\n {\n NODE_ENV,\n BUILD_OPTIONS: BUILD_OPTIONS || DEFAULT_BUILD_OPTIONS,\n BUILD_PARALLELISM: BUILD_PARALLELISM || DEFAULT_BUILD_PARALLELISM,\n PROJECT_DIR,\n compiler,\n log,\n $autoload,\n buildInitializer,\n },\n operations,\n );\n await $.destroy();\n } catch (err) {\n // eslint-disable-next-line\n console.error(\n '💀 - Cannot launch the build:',\n err.stack,\n JSON.stringify(err.params, null, 2),\n );\n process.exit(1);\n }\n}\n\nasync function processOperations(\n {\n NODE_ENV,\n BUILD_PARALLELISM,\n BUILD_OPTIONS,\n PROJECT_DIR,\n compiler,\n log,\n $autoload,\n buildInitializer,\n }: {\n NODE_ENV: string;\n BUILD_PARALLELISM: number;\n BUILD_OPTIONS: BuildOptions;\n PROJECT_DIR: string;\n compiler: WhookCompilerService;\n log: LogService;\n $autoload: Autoloader;\n buildInitializer: BuildInitializer;\n },\n operations: WhookOperation<WhookAPIOperationGCPFunctionConfig>[],\n): Promise<void> {\n const operationsLeft = operations.slice(BUILD_PARALLELISM);\n\n await Promise.all(\n operations.slice(0, BUILD_PARALLELISM).map((operation) =>\n buildAnyLambda(\n {\n NODE_ENV,\n PROJECT_DIR,\n BUILD_OPTIONS,\n compiler,\n log,\n $autoload,\n buildInitializer,\n },\n operation,\n ),\n ),\n );\n\n if (operationsLeft.length) {\n log('info', operationsLeft.length, ' operations left.');\n return processOperations(\n {\n NODE_ENV,\n BUILD_PARALLELISM,\n BUILD_OPTIONS,\n PROJECT_DIR,\n compiler,\n log,\n $autoload,\n buildInitializer,\n },\n operationsLeft,\n );\n }\n log('info', 'No more operations.');\n}\n\nasync function buildAnyLambda(\n {\n NODE_ENV,\n PROJECT_DIR,\n BUILD_OPTIONS,\n compiler,\n log,\n $autoload,\n buildInitializer,\n }: {\n NODE_ENV: string;\n PROJECT_DIR: string;\n BUILD_OPTIONS: BuildOptions;\n compiler: WhookCompilerService;\n log: LogService;\n $autoload: Autoloader;\n buildInitializer: BuildInitializer;\n },\n operation: WhookOperation<WhookAPIOperationGCPFunctionConfig>,\n): Promise<void> {\n const { operationId } = operation;\n\n try {\n const whookConfig: WhookAPIOperationGCPFunctionConfig =\n operation['x-whook'] || {};\n const operationType = whookConfig.type || 'http';\n const sourceOperationId = whookConfig.sourceOperationId;\n const entryPoint = operationId;\n const finalEntryPoint =\n (sourceOperationId ? sourceOperationId : operationId) +\n ((operation['x-whook'] || {}).suffix || '');\n log('warning', `Building ${operationType} \"${finalEntryPoint}\"...`);\n const buildDefinition = BUILD_DEFINITIONS[operationType];\n // eslint-disable-next-line\n const applyWrapper = require(buildDefinition.wrapper.path).default;\n const rootNode = await $autoload(\n entryPoint + (buildDefinition.suffix || ''),\n );\n const lambdaPath = path.join(\n PROJECT_DIR,\n 'builds',\n NODE_ENV,\n finalEntryPoint,\n );\n const finalHandlerInitializer = applyWrapper(rootNode.initializer);\n\n const initializerContent = await buildInitializer(\n finalHandlerInitializer[SPECIAL_PROPS.INJECT].map((name) =>\n name === 'OPERATION_API'\n ? `OPERATION_API>OPERATION_API_${finalEntryPoint}`\n : name,\n ),\n BUILD_OPTIONS,\n );\n const indexContent = await buildLambdaIndex(\n rootNode,\n {\n name: buildDefinition.wrapper.name,\n path: buildDefinition.wrapper.path,\n },\n BUILD_OPTIONS,\n );\n\n await mkdirp(lambdaPath);\n await Promise.all([\n copyStaticFiles(\n { PROJECT_DIR, log },\n lambdaPath,\n whookConfig.staticFiles || [],\n ),\n ensureFileAsync(\n { log },\n path.join(lambdaPath, 'initialize.js'),\n initializerContent,\n ),\n ensureFileAsync({ log }, path.join(lambdaPath, 'main.js'), indexContent),\n ]);\n await buildFinalLambda({ compiler, log }, lambdaPath, whookConfig);\n } catch (err) {\n log('error', `Error building \"${operationId}\"...`);\n log('stack', err.stack);\n log('debug', JSON.stringify(err.params, null, 2));\n throw YError.wrap(err, 'E_LAMBDA_BUILD', operationId);\n }\n}\n\nasync function buildLambdaIndex(\n rootNode: { path: string },\n buildWrapper: { name: string; path: string },\n options: BuildOptions,\n): Promise<string> {\n return `${\n options.modules === 'commonjs'\n ? `const pickModule = (m) => { return m && m.default || m; }\nconst initHandler = pickModule(require('${rootNode.path}'));\nconst ${buildWrapper.name} = pickModule(require('${buildWrapper.path}'));\nconst { initialize } = require('./initialize');`\n : `import initHandler from '${rootNode.path}';\nimport ${buildWrapper.name} from '${buildWrapper.path}';\nimport { initialize } from './initialize';`\n }\n\nconst handlerInitializer = ${buildWrapper.name}(\n initHandler\n);\n\nconst handlerPromise = initialize()\n .then(handlerInitializer);\n\n${\n options.modules === 'commonjs'\n ? 'module.exports = {}; module.exports.default = '\n : 'export default '\n}function handler (req, res) {\n return handlerPromise\n .then(handler => handler(req, res));\n};\n`;\n}\n\nasync function buildFinalLambda(\n { compiler, log }: { compiler: WhookCompilerService; log: LogService },\n lambdaPath: string,\n whookConfig: WhookAPIOperationGCPFunctionConfig,\n): Promise<void> {\n const entryPoint = `${lambdaPath}/main.js`;\n const { contents, mappings } = await compiler(\n entryPoint,\n whookConfig.compilerOptions,\n );\n\n await Promise.all([\n ensureFileAsync({ log }, `${lambdaPath}/index.js`, contents, 'utf-8'),\n mappings\n ? ensureFileAsync(\n { log },\n `${lambdaPath}/index.js.map`,\n mappings,\n 'utf-8',\n )\n : Promise.resolve(),\n ]);\n}\n\nasync function copyStaticFiles(\n { PROJECT_DIR, log }: { PROJECT_DIR: string; log: LogService },\n lambdaPath: string,\n staticFiles: string[] = [],\n): Promise<void> {\n await Promise.all(\n staticFiles.map(\n async (staticFile) =>\n await copyFiles(\n { log },\n path.join(PROJECT_DIR, 'node_modules', staticFile),\n path.join(lambdaPath, 'node_modules', staticFile),\n ),\n ),\n );\n}\n\nasync function copyFiles(\n { log }: { log: LogService },\n source: string,\n destination: string,\n): Promise<void> {\n let theError;\n try {\n await mkdirp(destination);\n const data = await readFileAsync(source, 'utf-8');\n await ensureFileAsync({ log }, destination, data, 'utf-8');\n } catch (err) {\n theError = err;\n }\n if (theError) {\n if ('EISDIR' !== theError.code) {\n throw theError;\n }\n await cprAsync(source, destination, {\n overwrite: true,\n });\n }\n}\n\nasync function ensureFileAsync(\n { log }: { log: LogService },\n path: string,\n content: string,\n encoding = 'utf-8',\n): Promise<void> {\n try {\n const oldContent = await readFileAsync(path, encoding);\n\n if (oldContent === content) {\n log('debug', `Ignore unchanged file: \"${path}\".`);\n return;\n }\n } catch (err) {\n log('debug', `Write new file: \"${path}\".`);\n return await writeFileAsync(path, content, encoding);\n }\n log('debug', `Write changed file: \"${path}\".`);\n return await writeFileAsync(path, content, encoding);\n}\n"],"file":"index.js"}
package/dist/index.mjs ADDED
@@ -0,0 +1,265 @@
1
+ /* eslint global-require:0 */
2
+ import fs from 'fs';
3
+ import util from 'util';
4
+ import path from 'path';
5
+ import mkdirp from 'mkdirp';
6
+ import cpr from 'cpr';
7
+ import YError from 'yerror';
8
+ import Knifecycle, { SPECIAL_PROPS, constant, initInitializerBuilder } from 'knifecycle';
9
+ import { DEFAULT_BUILD_OPTIONS, initCompiler } from '@whook/whook';
10
+ import initBuildAutoloader from './services/_autoload';
11
+ import { dereferenceOpenAPIOperations, getOpenAPIOperations } from '@whook/http-router';
12
+ export const DEFAULT_BUILD_PARALLELISM = 10;
13
+ const readFileAsync = util.promisify(fs.readFile);
14
+ const writeFileAsync = util.promisify(fs.writeFile);
15
+ const cprAsync = util.promisify(cpr);
16
+ const BUILD_DEFINITIONS = {
17
+ http: {
18
+ type: 'HTTP',
19
+ wrapper: {
20
+ name: 'wrapHandlerForGoogleHTTPFunction',
21
+ path: path.join(__dirname, 'wrappers', 'googleHTTPFunction')
22
+ },
23
+ suffix: 'Wrapped'
24
+ }
25
+ };
26
+ export async function prepareBuildEnvironment($ = new Knifecycle()) {
27
+ $.register(constant('INITIALIZER_PATH_MAP', {
28
+ ENV: '@whook/whook/dist/services/ProxyedENV',
29
+ log: __dirname + '/services/log',
30
+ time: 'common-services/dist/time',
31
+ delay: 'common-services/dist/delay'
32
+ }));
33
+ $.register(initInitializerBuilder);
34
+ $.register(initBuildAutoloader);
35
+ $.register(initCompiler);
36
+ $.register(constant('PORT', 1337));
37
+ $.register(constant('HOST', 'localhost'));
38
+ return $;
39
+ }
40
+ export async function runBuild(aPrepareBuildEnvironment) {
41
+ try {
42
+ const handlerName = process.argv[2];
43
+ const $ = await aPrepareBuildEnvironment();
44
+ const {
45
+ NODE_ENV,
46
+ BUILD_PARALLELISM,
47
+ BUILD_OPTIONS,
48
+ PROJECT_DIR,
49
+ compiler,
50
+ log,
51
+ $autoload,
52
+ API,
53
+ buildInitializer
54
+ } = await $.run(['NODE_ENV', '?BUILD_PARALLELISM', '?BUILD_OPTIONS', 'PROJECT_DIR', 'process', 'compiler', 'log', '$autoload', 'API', 'buildInitializer']);
55
+ log('info', 'Environment initialized 🚀🌕');
56
+ const operations = (await dereferenceOpenAPIOperations(API, getOpenAPIOperations(API))).filter(operation => {
57
+ if (handlerName) {
58
+ const sourceOperationId = operation['x-whook'] && operation['x-whook'].sourceOperationId;
59
+ return handlerName === operation.operationId || handlerName === sourceOperationId;
60
+ }
61
+
62
+ return true;
63
+ });
64
+ log('warning', `${operations.length} operations to process.`);
65
+ await processOperations({
66
+ NODE_ENV,
67
+ BUILD_OPTIONS: BUILD_OPTIONS || DEFAULT_BUILD_OPTIONS,
68
+ BUILD_PARALLELISM: BUILD_PARALLELISM || DEFAULT_BUILD_PARALLELISM,
69
+ PROJECT_DIR,
70
+ compiler,
71
+ log,
72
+ $autoload,
73
+ buildInitializer
74
+ }, operations);
75
+ await $.destroy();
76
+ } catch (err) {
77
+ // eslint-disable-next-line
78
+ console.error('💀 - Cannot launch the build:', err.stack, JSON.stringify(err.params, null, 2));
79
+ process.exit(1);
80
+ }
81
+ }
82
+
83
+ async function processOperations({
84
+ NODE_ENV,
85
+ BUILD_PARALLELISM,
86
+ BUILD_OPTIONS,
87
+ PROJECT_DIR,
88
+ compiler,
89
+ log,
90
+ $autoload,
91
+ buildInitializer
92
+ }, operations) {
93
+ const operationsLeft = operations.slice(BUILD_PARALLELISM);
94
+ await Promise.all(operations.slice(0, BUILD_PARALLELISM).map(operation => buildAnyLambda({
95
+ NODE_ENV,
96
+ PROJECT_DIR,
97
+ BUILD_OPTIONS,
98
+ compiler,
99
+ log,
100
+ $autoload,
101
+ buildInitializer
102
+ }, operation)));
103
+
104
+ if (operationsLeft.length) {
105
+ log('info', operationsLeft.length, ' operations left.');
106
+ return processOperations({
107
+ NODE_ENV,
108
+ BUILD_PARALLELISM,
109
+ BUILD_OPTIONS,
110
+ PROJECT_DIR,
111
+ compiler,
112
+ log,
113
+ $autoload,
114
+ buildInitializer
115
+ }, operationsLeft);
116
+ }
117
+
118
+ log('info', 'No more operations.');
119
+ }
120
+
121
+ async function buildAnyLambda({
122
+ NODE_ENV,
123
+ PROJECT_DIR,
124
+ BUILD_OPTIONS,
125
+ compiler,
126
+ log,
127
+ $autoload,
128
+ buildInitializer
129
+ }, operation) {
130
+ const {
131
+ operationId
132
+ } = operation;
133
+
134
+ try {
135
+ const whookConfig = operation['x-whook'] || {};
136
+ const operationType = whookConfig.type || 'http';
137
+ const sourceOperationId = whookConfig.sourceOperationId;
138
+ const entryPoint = operationId;
139
+ const finalEntryPoint = (sourceOperationId ? sourceOperationId : operationId) + ((operation['x-whook'] || {}).suffix || '');
140
+ log('warning', `Building ${operationType} "${finalEntryPoint}"...`);
141
+ const buildDefinition = BUILD_DEFINITIONS[operationType]; // eslint-disable-next-line
142
+
143
+ const applyWrapper = require(buildDefinition.wrapper.path).default;
144
+
145
+ const rootNode = await $autoload(entryPoint + (buildDefinition.suffix || ''));
146
+ const lambdaPath = path.join(PROJECT_DIR, 'builds', NODE_ENV, finalEntryPoint);
147
+ const finalHandlerInitializer = applyWrapper(rootNode.initializer);
148
+ const initializerContent = await buildInitializer(finalHandlerInitializer[SPECIAL_PROPS.INJECT].map(name => name === 'OPERATION_API' ? `OPERATION_API>OPERATION_API_${finalEntryPoint}` : name), BUILD_OPTIONS);
149
+ const indexContent = await buildLambdaIndex(rootNode, {
150
+ name: buildDefinition.wrapper.name,
151
+ path: buildDefinition.wrapper.path
152
+ }, BUILD_OPTIONS);
153
+ await mkdirp(lambdaPath);
154
+ await Promise.all([copyStaticFiles({
155
+ PROJECT_DIR,
156
+ log
157
+ }, lambdaPath, whookConfig.staticFiles || []), ensureFileAsync({
158
+ log
159
+ }, path.join(lambdaPath, 'initialize.js'), initializerContent), ensureFileAsync({
160
+ log
161
+ }, path.join(lambdaPath, 'main.js'), indexContent)]);
162
+ await buildFinalLambda({
163
+ compiler,
164
+ log
165
+ }, lambdaPath, whookConfig);
166
+ } catch (err) {
167
+ log('error', `Error building "${operationId}"...`);
168
+ log('stack', err.stack);
169
+ log('debug', JSON.stringify(err.params, null, 2));
170
+ throw YError.wrap(err, 'E_LAMBDA_BUILD', operationId);
171
+ }
172
+ }
173
+
174
+ async function buildLambdaIndex(rootNode, buildWrapper, options) {
175
+ return `${options.modules === 'commonjs' ? `const pickModule = (m) => { return m && m.default || m; }
176
+ const initHandler = pickModule(require('${rootNode.path}'));
177
+ const ${buildWrapper.name} = pickModule(require('${buildWrapper.path}'));
178
+ const { initialize } = require('./initialize');` : `import initHandler from '${rootNode.path}';
179
+ import ${buildWrapper.name} from '${buildWrapper.path}';
180
+ import { initialize } from './initialize';`}
181
+
182
+ const handlerInitializer = ${buildWrapper.name}(
183
+ initHandler
184
+ );
185
+
186
+ const handlerPromise = initialize()
187
+ .then(handlerInitializer);
188
+
189
+ ${options.modules === 'commonjs' ? 'module.exports = {}; module.exports.default = ' : 'export default '}function handler (req, res) {
190
+ return handlerPromise
191
+ .then(handler => handler(req, res));
192
+ };
193
+ `;
194
+ }
195
+
196
+ async function buildFinalLambda({
197
+ compiler,
198
+ log
199
+ }, lambdaPath, whookConfig) {
200
+ const entryPoint = `${lambdaPath}/main.js`;
201
+ const {
202
+ contents,
203
+ mappings
204
+ } = await compiler(entryPoint, whookConfig.compilerOptions);
205
+ await Promise.all([ensureFileAsync({
206
+ log
207
+ }, `${lambdaPath}/index.js`, contents, 'utf-8'), mappings ? ensureFileAsync({
208
+ log
209
+ }, `${lambdaPath}/index.js.map`, mappings, 'utf-8') : Promise.resolve()]);
210
+ }
211
+
212
+ async function copyStaticFiles({
213
+ PROJECT_DIR,
214
+ log
215
+ }, lambdaPath, staticFiles = []) {
216
+ await Promise.all(staticFiles.map(async staticFile => await copyFiles({
217
+ log
218
+ }, path.join(PROJECT_DIR, 'node_modules', staticFile), path.join(lambdaPath, 'node_modules', staticFile))));
219
+ }
220
+
221
+ async function copyFiles({
222
+ log
223
+ }, source, destination) {
224
+ let theError;
225
+
226
+ try {
227
+ await mkdirp(destination);
228
+ const data = await readFileAsync(source, 'utf-8');
229
+ await ensureFileAsync({
230
+ log
231
+ }, destination, data, 'utf-8');
232
+ } catch (err) {
233
+ theError = err;
234
+ }
235
+
236
+ if (theError) {
237
+ if ('EISDIR' !== theError.code) {
238
+ throw theError;
239
+ }
240
+
241
+ await cprAsync(source, destination, {
242
+ overwrite: true
243
+ });
244
+ }
245
+ }
246
+
247
+ async function ensureFileAsync({
248
+ log
249
+ }, path, content, encoding = 'utf-8') {
250
+ try {
251
+ const oldContent = await readFileAsync(path, encoding);
252
+
253
+ if (oldContent === content) {
254
+ log('debug', `Ignore unchanged file: "${path}".`);
255
+ return;
256
+ }
257
+ } catch (err) {
258
+ log('debug', `Write new file: "${path}".`);
259
+ return await writeFileAsync(path, content, encoding);
260
+ }
261
+
262
+ log('debug', `Write changed file: "${path}".`);
263
+ return await writeFileAsync(path, content, encoding);
264
+ }
265
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":["fs","util","path","mkdirp","cpr","YError","Knifecycle","SPECIAL_PROPS","constant","initInitializerBuilder","DEFAULT_BUILD_OPTIONS","initCompiler","initBuildAutoloader","dereferenceOpenAPIOperations","getOpenAPIOperations","DEFAULT_BUILD_PARALLELISM","readFileAsync","promisify","readFile","writeFileAsync","writeFile","cprAsync","BUILD_DEFINITIONS","http","type","wrapper","name","join","__dirname","suffix","prepareBuildEnvironment","$","register","ENV","log","time","delay","runBuild","aPrepareBuildEnvironment","handlerName","process","argv","NODE_ENV","BUILD_PARALLELISM","BUILD_OPTIONS","PROJECT_DIR","compiler","$autoload","API","buildInitializer","run","operations","filter","operation","sourceOperationId","operationId","length","processOperations","destroy","err","console","error","stack","JSON","stringify","params","exit","operationsLeft","slice","Promise","all","map","buildAnyLambda","whookConfig","operationType","entryPoint","finalEntryPoint","buildDefinition","applyWrapper","require","default","rootNode","lambdaPath","finalHandlerInitializer","initializer","initializerContent","INJECT","indexContent","buildLambdaIndex","copyStaticFiles","staticFiles","ensureFileAsync","buildFinalLambda","wrap","buildWrapper","options","modules","contents","mappings","compilerOptions","resolve","staticFile","copyFiles","source","destination","theError","data","code","overwrite","content","encoding","oldContent"],"mappings":"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","sourcesContent":["/* eslint global-require:0 */\nimport fs from 'fs';\nimport util from 'util';\nimport path from 'path';\nimport mkdirp from 'mkdirp';\nimport cpr from 'cpr';\nimport YError from 'yerror';\nimport Knifecycle, {\n SPECIAL_PROPS,\n constant,\n initInitializerBuilder,\n} from 'knifecycle';\nimport { DEFAULT_BUILD_OPTIONS, initCompiler } from '@whook/whook';\nimport initBuildAutoloader from './services/_autoload';\nimport {\n dereferenceOpenAPIOperations,\n getOpenAPIOperations,\n} from '@whook/http-router';\nimport type { Autoloader, Dependencies, BuildInitializer } from 'knifecycle';\nimport type {\n WhookOperation,\n WhookCompilerOptions,\n WhookCompilerService,\n} from '@whook/whook';\nimport type { OpenAPIV3 } from 'openapi-types';\nimport type { LogService } from 'common-services';\nimport type { CprOptions } from 'cpr';\nimport type { BuildOptions } from 'knifecycle/dist/build';\n\nexport const DEFAULT_BUILD_PARALLELISM = 10;\n\nexport type WhookBuildConfig = {\n BUILD_OPTIONS?: BuildOptions;\n BUILD_PARALLELISM?: number;\n};\nexport type WhookAPIOperationGCPFunctionConfig = {\n type?: 'http';\n sourceOperationId?: string;\n staticFiles?: string[];\n compilerOptions?: WhookCompilerOptions;\n suffix?: string;\n};\n\nconst readFileAsync = util.promisify(fs.readFile) as (\n path: string,\n encoding: string,\n) => Promise<string>;\nconst writeFileAsync = util.promisify(fs.writeFile) as (\n path: string,\n content: string,\n encoding: string,\n) => Promise<void>;\nconst cprAsync = util.promisify(cpr) as (\n source: string,\n destination: string,\n options: CprOptions,\n) => Promise<string[]>;\n\nconst BUILD_DEFINITIONS: Record<\n WhookAPIOperationGCPFunctionConfig['type'],\n {\n type: string;\n wrapper: { name: string; path: string };\n suffix?: string;\n }\n> = {\n http: {\n type: 'HTTP',\n wrapper: {\n name: 'wrapHandlerForGoogleHTTPFunction',\n path: path.join(__dirname, 'wrappers', 'googleHTTPFunction'),\n },\n suffix: 'Wrapped',\n },\n};\n\nexport async function prepareBuildEnvironment<\n T extends Knifecycle<Dependencies>,\n>($: T = new Knifecycle() as T): Promise<T> {\n $.register(\n constant('INITIALIZER_PATH_MAP', {\n ENV: '@whook/whook/dist/services/ProxyedENV',\n log: __dirname + '/services/log',\n time: 'common-services/dist/time',\n delay: 'common-services/dist/delay',\n }),\n );\n $.register(initInitializerBuilder);\n $.register(initBuildAutoloader);\n $.register(initCompiler);\n $.register(constant('PORT', 1337));\n $.register(constant('HOST', 'localhost'));\n\n return $;\n}\n\nexport async function runBuild(\n aPrepareBuildEnvironment: typeof prepareBuildEnvironment,\n): Promise<void> {\n try {\n const handlerName = process.argv[2];\n const $ = await aPrepareBuildEnvironment();\n const {\n NODE_ENV,\n BUILD_PARALLELISM,\n BUILD_OPTIONS,\n PROJECT_DIR,\n compiler,\n log,\n $autoload,\n API,\n buildInitializer,\n }: WhookBuildConfig & {\n NODE_ENV: string;\n PROJECT_DIR: string;\n compiler: WhookCompilerService;\n log: LogService;\n $autoload: Autoloader;\n API: OpenAPIV3.Document;\n buildInitializer: BuildInitializer;\n } = await $.run([\n 'NODE_ENV',\n '?BUILD_PARALLELISM',\n '?BUILD_OPTIONS',\n 'PROJECT_DIR',\n 'process',\n 'compiler',\n 'log',\n '$autoload',\n 'API',\n 'buildInitializer',\n ]);\n\n log('info', 'Environment initialized 🚀🌕');\n\n const operations = (\n await dereferenceOpenAPIOperations(\n API,\n getOpenAPIOperations<WhookAPIOperationGCPFunctionConfig>(API),\n )\n ).filter((operation) => {\n if (handlerName) {\n const sourceOperationId =\n operation['x-whook'] && operation['x-whook'].sourceOperationId;\n\n return (\n handlerName === operation.operationId ||\n handlerName === sourceOperationId\n );\n }\n return true;\n });\n\n log('warning', `${operations.length} operations to process.`);\n await processOperations(\n {\n NODE_ENV,\n BUILD_OPTIONS: BUILD_OPTIONS || DEFAULT_BUILD_OPTIONS,\n BUILD_PARALLELISM: BUILD_PARALLELISM || DEFAULT_BUILD_PARALLELISM,\n PROJECT_DIR,\n compiler,\n log,\n $autoload,\n buildInitializer,\n },\n operations,\n );\n await $.destroy();\n } catch (err) {\n // eslint-disable-next-line\n console.error(\n '💀 - Cannot launch the build:',\n err.stack,\n JSON.stringify(err.params, null, 2),\n );\n process.exit(1);\n }\n}\n\nasync function processOperations(\n {\n NODE_ENV,\n BUILD_PARALLELISM,\n BUILD_OPTIONS,\n PROJECT_DIR,\n compiler,\n log,\n $autoload,\n buildInitializer,\n }: {\n NODE_ENV: string;\n BUILD_PARALLELISM: number;\n BUILD_OPTIONS: BuildOptions;\n PROJECT_DIR: string;\n compiler: WhookCompilerService;\n log: LogService;\n $autoload: Autoloader;\n buildInitializer: BuildInitializer;\n },\n operations: WhookOperation<WhookAPIOperationGCPFunctionConfig>[],\n): Promise<void> {\n const operationsLeft = operations.slice(BUILD_PARALLELISM);\n\n await Promise.all(\n operations.slice(0, BUILD_PARALLELISM).map((operation) =>\n buildAnyLambda(\n {\n NODE_ENV,\n PROJECT_DIR,\n BUILD_OPTIONS,\n compiler,\n log,\n $autoload,\n buildInitializer,\n },\n operation,\n ),\n ),\n );\n\n if (operationsLeft.length) {\n log('info', operationsLeft.length, ' operations left.');\n return processOperations(\n {\n NODE_ENV,\n BUILD_PARALLELISM,\n BUILD_OPTIONS,\n PROJECT_DIR,\n compiler,\n log,\n $autoload,\n buildInitializer,\n },\n operationsLeft,\n );\n }\n log('info', 'No more operations.');\n}\n\nasync function buildAnyLambda(\n {\n NODE_ENV,\n PROJECT_DIR,\n BUILD_OPTIONS,\n compiler,\n log,\n $autoload,\n buildInitializer,\n }: {\n NODE_ENV: string;\n PROJECT_DIR: string;\n BUILD_OPTIONS: BuildOptions;\n compiler: WhookCompilerService;\n log: LogService;\n $autoload: Autoloader;\n buildInitializer: BuildInitializer;\n },\n operation: WhookOperation<WhookAPIOperationGCPFunctionConfig>,\n): Promise<void> {\n const { operationId } = operation;\n\n try {\n const whookConfig: WhookAPIOperationGCPFunctionConfig =\n operation['x-whook'] || {};\n const operationType = whookConfig.type || 'http';\n const sourceOperationId = whookConfig.sourceOperationId;\n const entryPoint = operationId;\n const finalEntryPoint =\n (sourceOperationId ? sourceOperationId : operationId) +\n ((operation['x-whook'] || {}).suffix || '');\n log('warning', `Building ${operationType} \"${finalEntryPoint}\"...`);\n const buildDefinition = BUILD_DEFINITIONS[operationType];\n // eslint-disable-next-line\n const applyWrapper = require(buildDefinition.wrapper.path).default;\n const rootNode = await $autoload(\n entryPoint + (buildDefinition.suffix || ''),\n );\n const lambdaPath = path.join(\n PROJECT_DIR,\n 'builds',\n NODE_ENV,\n finalEntryPoint,\n );\n const finalHandlerInitializer = applyWrapper(rootNode.initializer);\n\n const initializerContent = await buildInitializer(\n finalHandlerInitializer[SPECIAL_PROPS.INJECT].map((name) =>\n name === 'OPERATION_API'\n ? `OPERATION_API>OPERATION_API_${finalEntryPoint}`\n : name,\n ),\n BUILD_OPTIONS,\n );\n const indexContent = await buildLambdaIndex(\n rootNode,\n {\n name: buildDefinition.wrapper.name,\n path: buildDefinition.wrapper.path,\n },\n BUILD_OPTIONS,\n );\n\n await mkdirp(lambdaPath);\n await Promise.all([\n copyStaticFiles(\n { PROJECT_DIR, log },\n lambdaPath,\n whookConfig.staticFiles || [],\n ),\n ensureFileAsync(\n { log },\n path.join(lambdaPath, 'initialize.js'),\n initializerContent,\n ),\n ensureFileAsync({ log }, path.join(lambdaPath, 'main.js'), indexContent),\n ]);\n await buildFinalLambda({ compiler, log }, lambdaPath, whookConfig);\n } catch (err) {\n log('error', `Error building \"${operationId}\"...`);\n log('stack', err.stack);\n log('debug', JSON.stringify(err.params, null, 2));\n throw YError.wrap(err, 'E_LAMBDA_BUILD', operationId);\n }\n}\n\nasync function buildLambdaIndex(\n rootNode: { path: string },\n buildWrapper: { name: string; path: string },\n options: BuildOptions,\n): Promise<string> {\n return `${\n options.modules === 'commonjs'\n ? `const pickModule = (m) => { return m && m.default || m; }\nconst initHandler = pickModule(require('${rootNode.path}'));\nconst ${buildWrapper.name} = pickModule(require('${buildWrapper.path}'));\nconst { initialize } = require('./initialize');`\n : `import initHandler from '${rootNode.path}';\nimport ${buildWrapper.name} from '${buildWrapper.path}';\nimport { initialize } from './initialize';`\n }\n\nconst handlerInitializer = ${buildWrapper.name}(\n initHandler\n);\n\nconst handlerPromise = initialize()\n .then(handlerInitializer);\n\n${\n options.modules === 'commonjs'\n ? 'module.exports = {}; module.exports.default = '\n : 'export default '\n}function handler (req, res) {\n return handlerPromise\n .then(handler => handler(req, res));\n};\n`;\n}\n\nasync function buildFinalLambda(\n { compiler, log }: { compiler: WhookCompilerService; log: LogService },\n lambdaPath: string,\n whookConfig: WhookAPIOperationGCPFunctionConfig,\n): Promise<void> {\n const entryPoint = `${lambdaPath}/main.js`;\n const { contents, mappings } = await compiler(\n entryPoint,\n whookConfig.compilerOptions,\n );\n\n await Promise.all([\n ensureFileAsync({ log }, `${lambdaPath}/index.js`, contents, 'utf-8'),\n mappings\n ? ensureFileAsync(\n { log },\n `${lambdaPath}/index.js.map`,\n mappings,\n 'utf-8',\n )\n : Promise.resolve(),\n ]);\n}\n\nasync function copyStaticFiles(\n { PROJECT_DIR, log }: { PROJECT_DIR: string; log: LogService },\n lambdaPath: string,\n staticFiles: string[] = [],\n): Promise<void> {\n await Promise.all(\n staticFiles.map(\n async (staticFile) =>\n await copyFiles(\n { log },\n path.join(PROJECT_DIR, 'node_modules', staticFile),\n path.join(lambdaPath, 'node_modules', staticFile),\n ),\n ),\n );\n}\n\nasync function copyFiles(\n { log }: { log: LogService },\n source: string,\n destination: string,\n): Promise<void> {\n let theError;\n try {\n await mkdirp(destination);\n const data = await readFileAsync(source, 'utf-8');\n await ensureFileAsync({ log }, destination, data, 'utf-8');\n } catch (err) {\n theError = err;\n }\n if (theError) {\n if ('EISDIR' !== theError.code) {\n throw theError;\n }\n await cprAsync(source, destination, {\n overwrite: true,\n });\n }\n}\n\nasync function ensureFileAsync(\n { log }: { log: LogService },\n path: string,\n content: string,\n encoding = 'utf-8',\n): Promise<void> {\n try {\n const oldContent = await readFileAsync(path, encoding);\n\n if (oldContent === content) {\n log('debug', `Ignore unchanged file: \"${path}\".`);\n return;\n }\n } catch (err) {\n log('debug', `Write new file: \"${path}\".`);\n return await writeFileAsync(path, content, encoding);\n }\n log('debug', `Write changed file: \"${path}\".`);\n return await writeFileAsync(path, content, encoding);\n}\n"],"file":"index.mjs"}
@@ -0,0 +1,5 @@
1
+ import type { LogService } from 'common-services';
2
+ export declare function loadLambda({ PROJECT_DIR, log, }: {
3
+ PROJECT_DIR: string;
4
+ log: LogService;
5
+ }, target: string, operationId: string, type: string): Promise<any>;