zapier-platform-core 17.3.1 → 17.5.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/index.js +1 -0
- package/index.mjs +3 -0
- package/package.json +5 -5
- package/src/tools/bundle-encryption.js +40 -9
- package/types/custom.d.ts +29 -20
- package/types/schemas.generated.d.ts +10 -2
package/index.js
CHANGED
package/index.mjs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import zapier from './src/index.js';
|
|
2
2
|
import packageJson from './package.json' with { type: 'json' };
|
|
3
3
|
import _tools from './src/tools/exported.js';
|
|
4
|
+
import _errors from './src/errors.js';
|
|
4
5
|
zapier.version = packageJson.version;
|
|
5
6
|
zapier.tools = _tools;
|
|
7
|
+
zapier.errors = _errors;
|
|
6
8
|
// Allows `import { ... } from 'zapier-platform-core'`
|
|
7
9
|
export const {
|
|
8
10
|
createAppHandler,
|
|
@@ -16,6 +18,7 @@ export const {
|
|
|
16
18
|
integrationTestHandler,
|
|
17
19
|
tools,
|
|
18
20
|
version,
|
|
21
|
+
errors,
|
|
19
22
|
} = zapier;
|
|
20
23
|
// Allows `import zapier from 'zapier-platform-core'`
|
|
21
24
|
export default zapier;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zapier-platform-core",
|
|
3
|
-
"version": "17.
|
|
3
|
+
"version": "17.5.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/",
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"types": "types/index.d.ts",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
|
+
"types": "./types/index.d.ts",
|
|
12
13
|
"require": "./index.js",
|
|
13
|
-
"import": "./index.mjs"
|
|
14
|
-
"types": "./types/index.d.ts"
|
|
14
|
+
"import": "./index.mjs"
|
|
15
15
|
},
|
|
16
16
|
"./src/*": {
|
|
17
17
|
"require": "./src/*.js"
|
|
@@ -56,14 +56,14 @@
|
|
|
56
56
|
"content-disposition": "0.5.4",
|
|
57
57
|
"dotenv": "16.5.0",
|
|
58
58
|
"fernet": "^0.3.3",
|
|
59
|
-
"form-data": "4.0.
|
|
59
|
+
"form-data": "4.0.4",
|
|
60
60
|
"lodash": "4.17.21",
|
|
61
61
|
"mime-types": "2.1.35",
|
|
62
62
|
"node-abort-controller": "3.1.1",
|
|
63
63
|
"node-fetch": "2.7.0",
|
|
64
64
|
"oauth-sign": "0.9.0",
|
|
65
65
|
"semver": "7.7.1",
|
|
66
|
-
"zapier-platform-schema": "17.
|
|
66
|
+
"zapier-platform-schema": "17.5.0"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@types/node-fetch": "^2.6.11",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const crypto = require('crypto');
|
|
4
4
|
const fernet = require('fernet');
|
|
5
|
-
|
|
5
|
+
const zlib = require('zlib');
|
|
6
6
|
/**
|
|
7
7
|
* Decrypt a bundle using secret key
|
|
8
8
|
*
|
|
@@ -10,10 +10,12 @@ const fernet = require('fernet');
|
|
|
10
10
|
* 1. Hash the secret with SHA256 to get 32 bytes
|
|
11
11
|
* 2. Base64url encode those bytes to make Fernet-compatible key
|
|
12
12
|
* 3. Use Fernet library to decrypt (handles all token parsing internally)
|
|
13
|
+
* 4. Base64 decode the decrypted string to get compressed binary data
|
|
14
|
+
* 5. Decompress the data using gzip
|
|
13
15
|
*
|
|
14
16
|
* @param {string} bundle - The bundle represented as an encrypted token
|
|
15
17
|
* @param {string} secret - The secret key for decryption
|
|
16
|
-
* @returns {Object} The decrypted bundle object
|
|
18
|
+
* @returns {Object} The decrypted and decompressed bundle object
|
|
17
19
|
*/
|
|
18
20
|
const decryptBundleWithSecret = (bundle, secret) => {
|
|
19
21
|
try {
|
|
@@ -26,24 +28,54 @@ const decryptBundleWithSecret = (bundle, secret) => {
|
|
|
26
28
|
throw new Error('Invalid secret - must be a non-empty string');
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
// Create the same key as backend
|
|
31
|
+
// Step 1: Create the same key as backend
|
|
30
32
|
// Hash the secret and take first 32 bytes, then base64url encode for Fernet
|
|
31
33
|
const keyHash = crypto.createHash('sha256').update(secret).digest();
|
|
32
34
|
const keyBytes = keyHash.subarray(0, 32); // Take first 32 bytes
|
|
33
35
|
const fernetKey = keyBytes.toString('base64url'); // Use built-in base64url encoding
|
|
34
|
-
|
|
35
36
|
// Use Fernet library to decrypt (handles all the token parsing)
|
|
37
|
+
const secretObj = new fernet.Secret(fernetKey);
|
|
36
38
|
const token = new fernet.Token({
|
|
37
|
-
secret:
|
|
39
|
+
secret: secretObj,
|
|
38
40
|
token: bundle,
|
|
39
41
|
ttl: 0,
|
|
40
42
|
});
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
// Step 2: Decrypt the token - this should now be a valid UTF-8 string (base64 encoded)
|
|
45
|
+
let decryptedString;
|
|
46
|
+
try {
|
|
47
|
+
decryptedString = token.decode();
|
|
48
|
+
} catch (fernetError) {
|
|
49
|
+
throw new Error(`Fernet decryption failed: ${fernetError.message}`);
|
|
50
|
+
}
|
|
43
51
|
|
|
44
|
-
//
|
|
52
|
+
// Step 3: The decrypted data should be a base64 encoded string
|
|
53
|
+
// Base64 decode it to get the compressed binary data
|
|
54
|
+
let compressedBytes;
|
|
45
55
|
try {
|
|
46
|
-
|
|
56
|
+
compressedBytes = Buffer.from(decryptedString, 'base64');
|
|
57
|
+
} catch (base64Error) {
|
|
58
|
+
throw new Error(`Base64 decoding failed: ${base64Error.message}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Step 4: The data is compressed, so we need to decompress it
|
|
62
|
+
let decompressed;
|
|
63
|
+
try {
|
|
64
|
+
// Try to decompress first (for new format with compression)
|
|
65
|
+
decompressed = zlib.gunzipSync(compressedBytes).toString('utf8');
|
|
66
|
+
} catch (decompressionError) {
|
|
67
|
+
// If decompression fails, assume it's the old format without compression
|
|
68
|
+
// This provides backward compatibility
|
|
69
|
+
console.warn(
|
|
70
|
+
'Bundle decompression failed, falling back to uncompressed format:',
|
|
71
|
+
decompressionError.message,
|
|
72
|
+
);
|
|
73
|
+
decompressed = decryptedString;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Step 5: Parse JSON
|
|
77
|
+
try {
|
|
78
|
+
return JSON.parse(decompressed);
|
|
47
79
|
} catch (error) {
|
|
48
80
|
throw new Error('Invalid JSON in decrypted bundle');
|
|
49
81
|
}
|
|
@@ -51,7 +83,6 @@ const decryptBundleWithSecret = (bundle, secret) => {
|
|
|
51
83
|
throw new Error(`Bundle decryption failed: ${error.message}`);
|
|
52
84
|
}
|
|
53
85
|
};
|
|
54
|
-
|
|
55
86
|
module.exports = {
|
|
56
87
|
decryptBundleWithSecret,
|
|
57
88
|
};
|
package/types/custom.d.ts
CHANGED
|
@@ -10,7 +10,12 @@ import { Headers } from 'node-fetch';
|
|
|
10
10
|
|
|
11
11
|
// The EXPORTED OBJECT
|
|
12
12
|
export const version: string;
|
|
13
|
-
export const tools: {
|
|
13
|
+
export const tools: {
|
|
14
|
+
env: { inject: (filename?: string) => void };
|
|
15
|
+
};
|
|
16
|
+
export const errors: ErrorsModule;
|
|
17
|
+
|
|
18
|
+
|
|
14
19
|
|
|
15
20
|
// see: https://github.com/zapier/zapier-platform-cli/issues/339#issue-336888249
|
|
16
21
|
export const createAppTester: (
|
|
@@ -138,19 +143,30 @@ export interface Bundle<
|
|
|
138
143
|
targetUrl?: string;
|
|
139
144
|
}
|
|
140
145
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
// Error class types that match the runtime structure from src/errors.js
|
|
147
|
+
type ErrorConstructor = new (message?: string) => Error;
|
|
148
|
+
type AppErrorConstructor = new (message: string, code?: string, status?: number) => Error;
|
|
149
|
+
type ThrottledErrorConstructor = new (message: string, delay?: number) => Error;
|
|
150
|
+
type ResponseErrorConstructor = new (response: HttpResponse) => Error;
|
|
151
|
+
|
|
152
|
+
interface ErrorsModule {
|
|
153
|
+
Error: AppErrorConstructor;
|
|
154
|
+
HaltedError: ErrorConstructor;
|
|
155
|
+
ExpiredAuthError: ErrorConstructor;
|
|
156
|
+
RefreshAuthError: ErrorConstructor;
|
|
157
|
+
ThrottledError: ThrottledErrorConstructor;
|
|
158
|
+
ResponseError: ResponseErrorConstructor;
|
|
159
|
+
CheckError: ErrorConstructor;
|
|
160
|
+
DehydrateError: ErrorConstructor;
|
|
161
|
+
MethodDoesNotExist: ErrorConstructor;
|
|
162
|
+
NotImplementedError: ErrorConstructor;
|
|
163
|
+
RequireModuleError: ErrorConstructor;
|
|
164
|
+
StashedBundleError: ErrorConstructor;
|
|
165
|
+
StopRequestError: ErrorConstructor;
|
|
166
|
+
handleError: (...args: any[]) => never;
|
|
152
167
|
}
|
|
153
168
|
|
|
169
|
+
|
|
154
170
|
// copied http stuff from external typings
|
|
155
171
|
export interface HttpRequestOptions {
|
|
156
172
|
agent?: Agent;
|
|
@@ -286,14 +302,7 @@ export interface ZObject {
|
|
|
286
302
|
input_encoding?: string,
|
|
287
303
|
) => string;
|
|
288
304
|
|
|
289
|
-
errors:
|
|
290
|
-
Error: typeof AppError;
|
|
291
|
-
HaltedError: typeof HaltedError;
|
|
292
|
-
ExpiredAuthError: typeof ExpiredAuthError;
|
|
293
|
-
RefreshAuthError: typeof RefreshAuthError;
|
|
294
|
-
ThrottledError: typeof ThrottledError;
|
|
295
|
-
ResponseError: typeof ResponseError;
|
|
296
|
-
};
|
|
305
|
+
errors: ErrorsModule;
|
|
297
306
|
|
|
298
307
|
cache: {
|
|
299
308
|
get: (key: string) => Promise<any>;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* files, and/or the schema-to-ts tool and run its CLI to regenerate
|
|
5
5
|
* these typings.
|
|
6
6
|
*
|
|
7
|
-
* zapier-platform-schema version: 17.
|
|
7
|
+
* zapier-platform-schema version: 17.4.0
|
|
8
8
|
* schema-to-ts compiler version: 0.1.0
|
|
9
9
|
*/
|
|
10
10
|
import type {
|
|
@@ -704,7 +704,15 @@ export interface AuthField {
|
|
|
704
704
|
label?: string;
|
|
705
705
|
|
|
706
706
|
/** The type of this value used to be. */
|
|
707
|
-
type?:
|
|
707
|
+
type?:
|
|
708
|
+
| 'string'
|
|
709
|
+
| 'number'
|
|
710
|
+
| 'boolean'
|
|
711
|
+
| 'datetime'
|
|
712
|
+
| 'copy'
|
|
713
|
+
| 'password'
|
|
714
|
+
| 'integer'
|
|
715
|
+
| 'text';
|
|
708
716
|
|
|
709
717
|
/** If this value is required or not. This defaults to `true`. */
|
|
710
718
|
required?: boolean;
|