zapier-platform-core 14.0.1 → 14.1.1

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/index.d.ts CHANGED
@@ -16,7 +16,8 @@ export const createAppTester: (
16
16
  options?: { customStoreKey?: string }
17
17
  ) => <T, B extends Bundle>(
18
18
  func: (z: ZObject, bundle: B) => T | Promise<T>,
19
- bundle?: Partial<B> // partial so we don't have to make a full bundle in tests
19
+ bundle?: Partial<B>, // partial so we don't have to make a full bundle in tests
20
+ clearZcacheBeforeUse?: boolean
20
21
  ) => Promise<T>; // appTester always returns a promise
21
22
 
22
23
  // internal only
@@ -193,4 +194,10 @@ export interface ZObject {
193
194
  RefreshAuthError: typeof RefreshAuthError;
194
195
  ThrottledError: typeof ThrottledError;
195
196
  };
197
+
198
+ cache: {
199
+ get: (key: string) => Promise<any>;
200
+ set: (key: string, value: any, ttl?: number) => Promise<boolean>;
201
+ delete: (key: string) => Promise<boolean>;
202
+ };
196
203
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zapier-platform-core",
3
- "version": "14.0.1",
3
+ "version": "14.1.1",
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/",
@@ -51,7 +51,7 @@
51
51
  "node-fetch": "2.6.7",
52
52
  "oauth-sign": "0.9.0",
53
53
  "semver": "7.3.5",
54
- "zapier-platform-schema": "14.0.1"
54
+ "zapier-platform-schema": "14.1.1"
55
55
  },
56
56
  "devDependencies": {
57
57
  "adm-zip": "0.5.10",
@@ -3,6 +3,7 @@
3
3
  const _ = require('lodash');
4
4
 
5
5
  const createAppRequestClient = require('../../tools/create-app-request-client');
6
+ const createCache = require('../../tools/create-cache');
6
7
  const createDehydrator = require('../../tools/create-dehydrator');
7
8
  const createFileStasher = require('../../tools/create-file-stasher');
8
9
  const createJSONtool = require('../../tools/create-json-tool');
@@ -19,6 +20,7 @@ const hashing = require('../../tools/hashing');
19
20
  const injectZObject = (input) => {
20
21
  const bundle = _.get(input, '_zapier.event.bundle', {});
21
22
  const zRoot = {
23
+ cache: createCache(input),
22
24
  console: createLoggerConsole(input),
23
25
  cursor: createStoreKeyTool(input),
24
26
  dehydrate: createDehydrator(input, 'method'),
@@ -29,7 +29,7 @@ const createAppTester = (appRaw, { customStoreKey } = {}) => {
29
29
 
30
30
  const randomSeed = genId();
31
31
 
32
- return (methodOrFunc, bundle) => {
32
+ const appTester = (methodOrFunc, bundle, clearZcacheBeforeUse = false) => {
33
33
  bundle = bundle || {};
34
34
 
35
35
  let method = resolveMethodPath(appRaw, methodOrFunc, false);
@@ -53,12 +53,17 @@ const createAppTester = (appRaw, { customStoreKey } = {}) => {
53
53
  : `testKey-${method}-${randomSeed}`
54
54
  : null;
55
55
 
56
+ if (clearZcacheBeforeUse) {
57
+ appTester.zcacheTestObj = {};
58
+ }
59
+
56
60
  const event = {
57
61
  command: 'execute',
58
62
  method,
59
63
  bundle,
60
64
  storeKey,
61
65
  callback_url: 'https://auth-json-server.zapier-staging.com/echo',
66
+ zcacheTestObj: appTester.zcacheTestObj,
62
67
  };
63
68
 
64
69
  if (process.env.LOG_TO_STDOUT) {
@@ -73,6 +78,10 @@ const createAppTester = (appRaw, { customStoreKey } = {}) => {
73
78
  return resp.results;
74
79
  });
75
80
  };
81
+
82
+ appTester.zcacheTestObj = {};
83
+
84
+ return appTester;
76
85
  };
77
86
 
78
87
  module.exports = createAppTester;
@@ -0,0 +1,46 @@
1
+ 'use strict';
2
+
3
+ const _ = require('lodash');
4
+
5
+ const JSON = require('./create-json-tool')();
6
+ const ensureJSONEncodable = require('./ensure-json-encodable');
7
+
8
+ const createCache = (input) => {
9
+ const rpc = _.get(input, '_zapier.rpc');
10
+ const runValidationChecks = (rpc, key, value = null, ttl = null) => {
11
+ if (!rpc) {
12
+ throw new Error('rpc is not available');
13
+ }
14
+
15
+ if (!_.isString(key)) {
16
+ throw new TypeError('key must be a string');
17
+ }
18
+
19
+ if (ttl != null && !_.isInteger(ttl)) {
20
+ throw new TypeError('ttl must be an integer');
21
+ }
22
+
23
+ ensureJSONEncodable(value);
24
+ };
25
+
26
+ return {
27
+ get: async (key) => {
28
+ runValidationChecks(rpc, key);
29
+
30
+ const result = await rpc('zcache_get', key);
31
+ return result ? JSON.parse(result) : null;
32
+ },
33
+ set: async (key, value, ttl = null) => {
34
+ runValidationChecks(rpc, key, value, ttl);
35
+
36
+ return await rpc('zcache_set', key, JSON.stringify(value), ttl);
37
+ },
38
+ delete: async (key) => {
39
+ runValidationChecks(rpc, key);
40
+
41
+ return await rpc('zcache_delete', key);
42
+ },
43
+ };
44
+ };
45
+
46
+ module.exports = createCache;
@@ -8,11 +8,40 @@ const { genId } = require('./data');
8
8
 
9
9
  const FALLBACK_RPC = process.env.ZAPIER_BASE_ENDPOINT + '/platform/rpc/cli';
10
10
 
11
+ const rpcCacheMock = (zcacheTestObj, method, key, value = null, ttl = null) => {
12
+ if (method === 'zcache_get') {
13
+ const result = key in zcacheTestObj ? zcacheTestObj[key] : null;
14
+ return result;
15
+ }
16
+
17
+ if (method === 'zcache_set') {
18
+ zcacheTestObj[key] = value;
19
+ return true;
20
+ }
21
+
22
+ if (method === 'zcache_delete') {
23
+ if (key in zcacheTestObj) {
24
+ delete zcacheTestObj[key];
25
+ return true;
26
+ }
27
+
28
+ return false;
29
+ }
30
+
31
+ throw new Error(`Unexpected method '${method}'`);
32
+ };
33
+
11
34
  const createRpcClient = (event) => {
12
35
  return function (method) {
13
36
  const params = _.toArray(arguments);
14
37
  params.shift();
15
38
 
39
+ const zcacheMethods = ['zcache_get', 'zcache_set', 'zcache_delete'];
40
+ if (zcacheMethods.includes(method) && _.isPlainObject(event.zcacheTestObj)) {
41
+ const [key, value = null] = params;
42
+ return rpcCacheMock(event.zcacheTestObj, method, key, value);
43
+ }
44
+
16
45
  const id = genId();
17
46
  const body = JSON.stringify({
18
47
  id,
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ const _ = require('lodash');
4
+
5
+ const ensureJSONEncodable = (obj, path = null, visited = null) => {
6
+ if (obj === null || _.isBoolean(obj) || _.isNumber(obj) || _.isString(obj)) {
7
+ return;
8
+ }
9
+
10
+ path = path || [];
11
+
12
+ if (!_.isPlainObject(obj) && !_.isArray(obj)) {
13
+ const typeName = typeof obj;
14
+ const pathStr = path.join('.');
15
+ throw new TypeError(
16
+ `Type '${typeName}' is not JSON-encodable (path: '${pathStr}')`
17
+ );
18
+ }
19
+
20
+ visited = visited || new Set();
21
+
22
+ if (visited.has(obj)) {
23
+ const pathStr = path.join('.');
24
+ throw new TypeError(
25
+ `Circular structure is not JSON-encodable (path: '${pathStr}')`
26
+ );
27
+ }
28
+
29
+ visited.add(obj);
30
+
31
+ for (const key in obj) {
32
+ ensureJSONEncodable(obj[key], path.concat(key), visited);
33
+ }
34
+ };
35
+
36
+ module.exports = ensureJSONEncodable;