zapier-platform-core 15.9.0 → 15.10.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zapier-platform-core",
3
- "version": "15.9.0",
3
+ "version": "15.10.0",
4
4
  "description": "The core SDK for CLI apps in the Zapier Developer Platform.",
5
5
  "repository": "zapier/zapier-platform",
6
6
  "homepage": "https://platform.zapier.com/",
@@ -52,7 +52,7 @@
52
52
  "node-fetch": "2.6.7",
53
53
  "oauth-sign": "0.9.0",
54
54
  "semver": "7.5.2",
55
- "zapier-platform-schema": "15.9.0"
55
+ "zapier-platform-schema": "15.10.0"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/node-fetch": "^2.6.11",
@@ -6,6 +6,9 @@ const responseStasher = require('../../tools/create-response-stasher');
6
6
 
7
7
  const largeResponseCachePointer = async (output) => {
8
8
  const response = cleaner.maskOutput(output);
9
+ if (!response.results) {
10
+ return output;
11
+ }
9
12
 
10
13
  const autostashLimit = output.input._zapier.event.autostashPayloadOutputLimit;
11
14
 
@@ -1,5 +1,8 @@
1
1
  const zlib = require('zlib');
2
2
  const _ = require('lodash');
3
+
4
+ const { ALLOWED_HTTP_DATA_CONTENT_TYPES, getContentType } = require('./http');
5
+
3
6
  const constants = require('../constants');
4
7
 
5
8
  const createHttpPatch = (event) => {
@@ -54,19 +57,34 @@ const createHttpPatch = (event) => {
54
57
  const newCallback = function (response) {
55
58
  const chunks = [];
56
59
 
60
+ // Only include request or response data for specific content types
61
+ // which we are able to read in logs and which are not typically too large
62
+ const requestContentType = getContentType(options.headers || {});
63
+ const responseContentType = getContentType(response.headers || {});
64
+
65
+ const shouldIncludeRequestData =
66
+ ALLOWED_HTTP_DATA_CONTENT_TYPES.has(requestContentType);
67
+ const shouldIncludeResponseData =
68
+ ALLOWED_HTTP_DATA_CONTENT_TYPES.has(responseContentType);
69
+
57
70
  const sendToLogger = (responseBody) => {
58
71
  // Prepare data for GL
59
72
  const logData = {
60
73
  log_type: 'http',
61
- request_type: 'devplatform-outbound',
74
+ // Using a custom request_type to differentiate from z.request() since `request_via_client` is not logged in GL
75
+ request_type: 'patched-devplatform-outbound',
62
76
  request_url: requestUrl,
63
77
  request_method: options.method || 'GET',
64
78
  request_headers: options.headers,
65
- request_data: options.body || '',
79
+ request_data: shouldIncludeRequestData
80
+ ? options.body || ''
81
+ : '<unsupported format>',
66
82
  request_via_client: false,
67
83
  response_status_code: response.statusCode,
68
84
  response_headers: response.headers,
69
- response_content: responseBody,
85
+ response_content: shouldIncludeResponseData
86
+ ? responseBody
87
+ : '<unsupported format>',
70
88
  };
71
89
 
72
90
  object.zapierLogger(
@@ -19,42 +19,43 @@ const environmentTools = require('./environment');
19
19
  const schemaTools = require('./schema');
20
20
  const ZapierPromise = require('./promise');
21
21
 
22
- const RequestSchema = require('zapier-platform-schema/lib/schemas/RequestSchema');
23
- const FunctionSchema = require('zapier-platform-schema/lib/schemas/FunctionSchema');
24
-
25
- const isRequestOrFunction = (obj) => {
22
+ const isDefinedPrimitive = (value) => {
26
23
  return (
27
- RequestSchema.validate(obj).valid || FunctionSchema.validate(obj).valid
24
+ value === null ||
25
+ typeof value === 'string' ||
26
+ typeof value === 'number' ||
27
+ typeof value === 'boolean'
28
28
  );
29
29
  };
30
30
 
31
- const extendAppRaw = (base, extension) => {
32
- const keysToOverride = [
33
- 'test',
34
- 'perform',
35
- 'performList',
36
- 'performSubscribe',
37
- 'performUnsubscribe',
38
- ];
39
- const concatArrayAndOverrideKeys = (objValue, srcValue, key) => {
40
- if (Array.isArray(objValue) && Array.isArray(srcValue)) {
41
- return objValue.concat(srcValue);
42
- }
31
+ const shouldFullyReplace = (path) => {
32
+ // covers inputFields, outputFields, sample, throttle, etc
33
+ const isOperation = path[path.length - 2] === 'operation';
34
+ return isOperation;
35
+ };
43
36
 
44
- if (
45
- // Do full replacement when it comes to keysToOverride
46
- keysToOverride.indexOf(key) !== -1 &&
47
- _.isPlainObject(srcValue) &&
48
- _.isPlainObject(objValue) &&
49
- isRequestOrFunction(srcValue) &&
50
- isRequestOrFunction(objValue)
51
- ) {
52
- return srcValue;
37
+ const extendAppRaw = (base, extension, path) => {
38
+ if (extension === undefined) {
39
+ return base;
40
+ } else if (isDefinedPrimitive(extension)) {
41
+ return extension;
42
+ } else if (Array.isArray(extension)) {
43
+ return [...extension];
44
+ } else if (_.isPlainObject(extension)) {
45
+ path = path || [];
46
+ if (shouldFullyReplace(path)) {
47
+ return extension;
48
+ } else {
49
+ const baseObject = _.isPlainObject(base) ? base : {};
50
+ const result = { ...baseObject };
51
+ for (const [key, value] of Object.entries(extension)) {
52
+ const newPath = [...path, key];
53
+ result[key] = extendAppRaw(baseObject[key], value, newPath);
54
+ }
55
+ return result;
53
56
  }
54
-
55
- return undefined;
56
- };
57
- return _.mergeWith(base, extension, concatArrayAndOverrideKeys);
57
+ }
58
+ throw new TypeError('Unexpected type');
58
59
  };
59
60
 
60
61
  const getAppRawOverride = (rpc, appRawOverride) => {
@@ -116,17 +117,25 @@ const getAppRawOverride = (rpc, appRawOverride) => {
116
117
  // so allow for that, and an event.appRawOverride for "buildless" apps.
117
118
  const loadApp = (event, rpc, appRawOrPath) => {
118
119
  return new ZapierPromise((resolve, reject) => {
120
+ const appRaw = _.isString(appRawOrPath)
121
+ ? require(appRawOrPath)
122
+ : appRawOrPath;
123
+
119
124
  if (event && event.appRawOverride) {
125
+ if (
126
+ Array.isArray(event.appRawOverride) &&
127
+ event.appRawOverride.length > 1 &&
128
+ !event.appRawOverride[0]
129
+ ) {
130
+ event.appRawOverride[0] = appRaw;
131
+ }
132
+
120
133
  return getAppRawOverride(rpc, event.appRawOverride)
121
134
  .then((appRawOverride) => resolve(appRawOverride))
122
135
  .catch((err) => reject(err));
123
136
  }
124
137
 
125
- if (_.isString(appRawOrPath)) {
126
- return resolve(require(appRawOrPath));
127
- }
128
-
129
- return resolve(appRawOrPath);
138
+ return resolve(appRaw);
130
139
  });
131
140
  };
132
141
 
package/src/tools/http.js CHANGED
@@ -4,6 +4,23 @@ const fetch = require('node-fetch');
4
4
  const FORM_TYPE = 'application/x-www-form-urlencoded';
5
5
  const JSON_TYPE = 'application/json';
6
6
  const JSON_TYPE_UTF8 = 'application/json; charset=utf-8';
7
+ const BINARY_TYPE = 'application/octet-stream';
8
+ const HTML_TYPE = 'text/html';
9
+ const TEXT_TYPE = 'text/plain';
10
+ const YAML_TYPE = 'application/yaml';
11
+ const XML_TYPE = 'application/xml';
12
+ const JSONAPI_TYPE = 'application/vnd.api+json';
13
+
14
+ const ALLOWED_HTTP_DATA_CONTENT_TYPES = new Set([
15
+ FORM_TYPE,
16
+ JSON_TYPE,
17
+ JSON_TYPE_UTF8,
18
+ HTML_TYPE,
19
+ TEXT_TYPE,
20
+ YAML_TYPE,
21
+ XML_TYPE,
22
+ JSONAPI_TYPE,
23
+ ]);
7
24
 
8
25
  const getContentType = (headers) => {
9
26
  const headerKeys = Object.keys(headers);
@@ -101,6 +118,13 @@ module.exports = {
101
118
  FORM_TYPE,
102
119
  JSON_TYPE,
103
120
  JSON_TYPE_UTF8,
121
+ BINARY_TYPE,
122
+ HTML_TYPE,
123
+ TEXT_TYPE,
124
+ YAML_TYPE,
125
+ XML_TYPE,
126
+ JSONAPI_TYPE,
127
+ ALLOWED_HTTP_DATA_CONTENT_TYPES,
104
128
  getContentType,
105
129
  parseDictHeader,
106
130
  unheader,
@@ -4,9 +4,11 @@ const crypto = require('crypto');
4
4
 
5
5
  const { DehydrateError } = require('../errors');
6
6
 
7
- // Max URL length for Node is 8KB (https://stackoverflow.com/a/56954244/)
8
- // 8 * 1024 * (3 / 4) = 6144 max, minus some room for additional overhead
9
- const MAX_PAYLOAD_SIZE = 6000;
7
+ // https://nodejs.org/docs/latest-v16.x/api/http.html#httpmaxheadersize
8
+ // Base64 encoding adds approx 4/3 to the original size
9
+ // To account for encoding, we use the inverse to calc the max original size (3/4)
10
+ // 16kb limit * 1024 * (3 / 4) = 12.228 kb max, minus some room for additional overhead
11
+ const MAX_PAYLOAD_SIZE = 12000;
10
12
 
11
13
  const wrapHydrate = (payload) => {
12
14
  payload = JSON.stringify(payload);