11const axios = require('../axios');
22const set = require('lodash/set');
33const merge = require('lodash/merge');
4+ const https = require('https');
5+ const fs = require('fs');
6+
7+ // Environment variables injected during generation
8+ const env = {
9+ directExecute: {{ executionConfig.directExecute }} ,
10+ mtls: {
11+ certPath: '{{ executionConfig.mtls.certPath }} ',
12+ keyPath: '{{ executionConfig.mtls.keyPath }} ',
13+ caPath: '{{ executionConfig.mtls.caPath }} ',
14+ rejectUnauthorized: {{ executionConfig.mtls.rejectUnauthorized }} ,
15+ }
16+ };
417
518const functions = [
619{{ #each specifications }}
720 ['{{ #if context }} {{ context }} .{{ /if }} {{ name }} ', '{{ id }} ',{{ #each function.arguments }} '{{ name }} ',{{ /each }} ],
821{{ /each }}
922];
1023
24+ // Create MTLS agent if paths are provided
25+ let httpsAgent = undefined;
26+ const getHttpsAgent = () => {
27+ if (httpsAgent) {
28+ return httpsAgent;
29+ }
30+
31+ const { mtls } = env;
32+ if (!mtls.certPath || !mtls.keyPath || !mtls.caPath) {
33+ return undefined;
34+ }
35+
36+ httpsAgent = new https.Agent({
37+ cert: fs.readFileSync(mtls.certPath),
38+ key: fs.readFileSync(mtls.keyPath),
39+ ca: fs.readFileSync(mtls.caPath),
40+ rejectUnauthorized: mtls.rejectUnauthorized,
41+ });
42+
43+ return httpsAgent;
44+ };
45+
1146module.exports = (clientID, polyCustom) => merge(
1247 {},
1348 functions.reduce(
1449 (acc, [path, id, ...argKeys]) => set(
1550 acc,
1651 path,
1752 (...args) => {
18- const requestStartTime = Date.now();
53+ const requestServerStartTime = Date.now();
1954 const requestArgs = argKeys.reduce((acc, key, index) => ({ ...acc, [key]: args[index] }), {});
55+
56+ // Check if direct execution is enabled
57+ const { directExecute } = env;
58+
59+ if (directExecute === true) {
60+ // Make direct API call
61+
62+ let polyHeaders;
63+ let serverPreperationTimeMs;
64+ let roundTripServerNetworkLatencyMs;
65+ let requestApiStartTime;
66+
67+ return axios.post(
68+ `/functions/api/${id}/direct-execute?clientId=${clientID}`,
69+ requestArgs,
70+ {
71+ headers: {
72+ 'x-poly-execution-id': polyCustom.executionId,
73+ }
74+ }
75+ ).then(({ headers, data }) => {
76+ polyHeaders = headers;
77+ if (data && (data.status < 200 || data.status >= 300)) {
78+ console.error('Error getting direct execution data for api function with id:', id, 'Status code:', data.status, 'Request data:', requestArgs, 'Response data:', data.data);
79+ }
80+
81+ serverPreperationTimeMs = Number(polyHeaders['x-poly-execution-duration']);
82+ roundTripServerNetworkLatencyMs = Date.now() - requestServerStartTime - serverPreperationTimeMs;
83+
84+ requestApiStartTime = Date.now();
85+ const httpsAgent = getHttpsAgent();
86+
87+ return axios({
88+ ...data,
89+ headers: {
90+ ...data.headers,
91+ },
92+ httpsAgent,
93+ })
94+ }).then(({ headers, data, status, ...args }) => {
95+ if (status && (status < 200 || status >= 300)) {
96+ console.error('Error direct executing api function with id:', id, 'Status code:', status, 'Request data:', requestArgs, 'Response data:', data.data);
97+ }
98+ const apiExecutionTimeMs = Date.now() - requestApiStartTime;
99+ return {
100+ data: data,
101+ status: status,
102+ headers: { ...headers },
103+ metrics: {
104+ roundTripServerNetworkLatencyMs,
105+ serverPreperationTimeMs,
106+ apiExecutionTimeMs,
107+ }
108+ };
109+ });
110+ }
111+
112+ // default indirect execution
20113 return axios.post(
21114 `/functions/api/${id}/execute?clientId=${clientID}`,
22115 {
@@ -36,7 +129,7 @@ module.exports = (clientID, polyCustom) => merge(
36129 console.error('Error executing api function with id:', id, 'Status code:', data.status, 'Request data:', requestArgs, 'Response data:', responseData);
37130 }
38131 const serverExecutionTimeMs = Number(headers['x-poly-execution-duration']);
39- const roundTripNetworkLatencyMs = Date.now() - requestStartTime - serverExecutionTimeMs;
132+ const roundTripNetworkLatencyMs = Date.now() - requestServerStartTime - serverExecutionTimeMs;
40133 return {
41134 ...data,
42135 metrics: {
0 commit comments