zapier-platform-cli 17.4.0 → 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.
@@ -2505,5 +2505,5 @@
2505
2505
  ]
2506
2506
  }
2507
2507
  },
2508
- "version": "17.4.0"
2508
+ "version": "17.5.0"
2509
2509
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zapier-platform-cli",
3
- "version": "17.4.0",
3
+ "version": "17.5.0",
4
4
  "description": "The CLI for managing integrations in Zapier Developer Platform.",
5
5
  "repository": "zapier/zapier-platform",
6
6
  "homepage": "https://platform.zapier.com/",
@@ -130,11 +130,11 @@ const authTypes = {
130
130
  const writeGenericAuth = (gen) => {
131
131
  const authType = authTypes[gen.options.template];
132
132
  const content = authFilesCodegen[authType](gen.options.language);
133
- const destPath =
134
- gen.options.language === 'typescript'
135
- ? 'src/authentication.ts'
136
- : 'authentication.js';
137
- gen.fs.write(gen.destinationPath(destPath), content);
133
+ const destPath = (key) =>
134
+ gen.options.language === 'typescript' ? `src/${key}.ts` : `${key}.js`;
135
+ Object.entries(content).forEach(([key, value]) => {
136
+ gen.fs.write(gen.destinationPath(destPath(key)), value);
137
+ });
138
138
  };
139
139
 
140
140
  const writeGenericAuthTest = (gen) => {
@@ -1,9 +1,6 @@
1
1
  <% if (hasAuth) { %>
2
- const {
3
- config: authentication,
4
- befores = [],
5
- afters = [],
6
- } = require('./authentication');
2
+ const authentication = require('./authentication');
3
+ const { befores = [], afters = [] } = require('./middleware');
7
4
  <% } %>
8
5
 
9
6
  module.exports = {
@@ -2,8 +2,8 @@ import zapier, { defineApp } from 'zapier-platform-core';
2
2
 
3
3
  import packageJson from '../package.json' with { type: 'json' };
4
4
 
5
- import authenticationModule from './authentication.js';
6
- const { config: authentication, befores, afters } = authenticationModule;
5
+ import authentication from './authentication.js';
6
+ import { befores, afters } from './middleware.js';
7
7
 
8
8
  export default defineApp({
9
9
  version: packageJson.version,
@@ -982,6 +982,7 @@ class InvokeCommand extends BaseCommand {
982
982
  method: methodName,
983
983
  bundle: {
984
984
  inputData,
985
+ inputDataRaw: inputData, // At this point, inputData hasn't been transformed yet
985
986
  authData,
986
987
  meta,
987
988
  },
@@ -1013,6 +1014,8 @@ class InvokeCommand extends BaseCommand {
1013
1014
  );
1014
1015
  }
1015
1016
 
1017
+ // Preserve original inputData as inputDataRaw before type resolution
1018
+ const inputDataRaw = { ...inputData };
1016
1019
  inputData = resolveInputDataTypes(inputData, inputFields, timezone);
1017
1020
  methodName = `${actionTypePlural}.${action.key}.operation.perform`;
1018
1021
 
@@ -1022,6 +1025,7 @@ class InvokeCommand extends BaseCommand {
1022
1025
  method: methodName,
1023
1026
  bundle: {
1024
1027
  inputData,
1028
+ inputDataRaw,
1025
1029
  authData,
1026
1030
  meta,
1027
1031
  },
@@ -50,8 +50,6 @@ const authFileExport = (
50
50
  authType,
51
51
  authDescription,
52
52
  {
53
- beforeFuncNames = [],
54
- afterFuncNames = [],
55
53
  extraConfigProps = [],
56
54
  connectionLabel = strLiteral('{{json.username}}'),
57
55
  test = objProperty('test'),
@@ -85,14 +83,37 @@ const authFileExport = (
85
83
  ? objTS('Authentication', ...configProps)
86
84
  : obj(...configProps);
87
85
 
88
- return exportStatement(
89
- obj(
90
- objProperty('config', configObj),
91
- objProperty('befores', arr(...beforeFuncNames)),
92
- objProperty('afters', arr(...afterFuncNames)),
93
- ),
94
- language,
95
- );
86
+ return exportStatement(configObj, language);
87
+ };
88
+
89
+ const middlewareFileExport = (
90
+ language,
91
+ { beforeFuncNames = [], afterFuncNames = [] },
92
+ ) => {
93
+ const exportConst = language === 'typescript';
94
+ return language === 'typescript'
95
+ ? [
96
+ // for Typescript, export the befores and afters separately as consts
97
+ variableAssignmentDeclaration(
98
+ 'befores',
99
+ arr(...beforeFuncNames),
100
+ exportConst,
101
+ ),
102
+ variableAssignmentDeclaration(
103
+ 'afters',
104
+ arr(...afterFuncNames),
105
+ exportConst,
106
+ ),
107
+ ]
108
+ : [
109
+ // for Javascript, export the befores and afters together using module.exports
110
+ exportStatement(
111
+ obj(
112
+ objProperty('befores', arr(...beforeFuncNames)),
113
+ objProperty('afters', arr(...afterFuncNames)),
114
+ ),
115
+ ),
116
+ ];
96
117
  };
97
118
 
98
119
  const authTestFunc = (language, testUrl = strLiteral(authJsonUrl('me'))) =>
@@ -126,15 +147,12 @@ const handleBadResponsesFunc = (
126
147
  );
127
148
 
128
149
  const basicAuthFile = (language) => {
129
- const badFuncName = 'handleBadResponses';
130
150
  const fileInput = [
131
151
  authTestFunc(language),
132
- handleBadResponsesFunc(badFuncName, language),
133
152
  authFileExport(
134
153
  language,
135
154
  'basic',
136
155
  '"basic" auth automatically creates "username" and "password" input fields. It also registers default middleware to create the authentication header.',
137
- { afterFuncNames: [badFuncName] },
138
156
  ),
139
157
  ];
140
158
  return language === 'typescript'
@@ -142,6 +160,27 @@ const basicAuthFile = (language) => {
142
160
  : file(...fileInput);
143
161
  };
144
162
 
163
+ const basicMiddlewareFile = (language) => {
164
+ const badFuncName = 'handleBadResponses';
165
+ const fileInput = [
166
+ handleBadResponsesFunc(badFuncName, language),
167
+ ...middlewareFileExport(language, {
168
+ beforeFuncNames: [],
169
+ afterFuncNames: [badFuncName],
170
+ }),
171
+ ];
172
+ return language === 'typescript'
173
+ ? fileTS(standardTypes, ...fileInput)
174
+ : file(...fileInput);
175
+ };
176
+
177
+ const basicFiles = (language) => {
178
+ return {
179
+ middleware: basicMiddlewareFile(language),
180
+ authentication: basicAuthFile(language),
181
+ };
182
+ };
183
+
145
184
  /**
146
185
  * boilerplate for a "before" middleware. No need to return the requst at the end
147
186
  */
@@ -274,6 +313,7 @@ const getAccessTokenFunc = (language) => {
274
313
  'If your app does an app refresh, then `refresh_token` should be returned here as well',
275
314
  ),
276
315
  ],
316
+ language,
277
317
  });
278
318
  };
279
319
 
@@ -288,23 +328,20 @@ const refreshTokenFunc = (language) => {
288
328
  'If the refresh token does change, return it here to update the stored value in Zapier',
289
329
  ),
290
330
  ],
331
+ language,
291
332
  });
292
333
  };
293
334
 
294
335
  const oauth2AuthFile = (language) => {
295
- const bearerFuncName = 'includeBearerToken';
296
336
  const fileInput = [
297
337
  getAccessTokenFunc(language),
298
338
  refreshTokenFunc(language),
299
- includeBearerFunc(bearerFuncName, language),
300
339
  authTestFunc(language),
301
340
  authFileExport(
302
341
  language,
303
342
  'oauth2',
304
343
  'OAuth2 is a web authentication standard. There are a lot of configuration options that will fit most any situation.',
305
344
  {
306
- beforeFuncNames: [bearerFuncName],
307
- afterFuncNames: [],
308
345
  extraConfigProps: [
309
346
  objProperty(
310
347
  'oauth2Config',
@@ -351,11 +388,55 @@ const oauth2AuthFile = (language) => {
351
388
  ? fileTS(standardTypes, ...fileInput)
352
389
  : file(...fileInput);
353
390
  };
391
+
392
+ const oauth2MiddlewareFile = (language) => {
393
+ const bearerFuncName = 'includeBearerToken';
394
+ const fileInput = [
395
+ includeBearerFunc(bearerFuncName, language),
396
+ ...middlewareFileExport(language, {
397
+ beforeFuncNames: [bearerFuncName],
398
+ afterFuncNames: [],
399
+ }),
400
+ ];
401
+ return language === 'typescript'
402
+ ? fileTS(standardTypes, ...fileInput)
403
+ : file(...fileInput);
404
+ };
405
+
406
+ const oauth2Files = (language) => {
407
+ return {
408
+ middleware: oauth2MiddlewareFile(language),
409
+ authentication: oauth2AuthFile(language),
410
+ };
411
+ };
412
+
354
413
  const customAuthFile = (language) => {
414
+ const fileInput = [
415
+ authTestFunc(language),
416
+ authFileExport(
417
+ language,
418
+ 'custom',
419
+ '"custom" is the catch-all auth type. The user supplies some info and Zapier can make authenticated requests with it',
420
+ {
421
+ authFields: [
422
+ obj(
423
+ objProperty('key', strLiteral('apiKey')),
424
+ objProperty('label', strLiteral('API Key')),
425
+ objProperty('required', 'true'),
426
+ ),
427
+ ],
428
+ },
429
+ ),
430
+ ];
431
+ return language === 'typescript'
432
+ ? fileTS(standardTypes, ...fileInput)
433
+ : file(...fileInput);
434
+ };
435
+
436
+ const customMiddlewareFile = (language) => {
355
437
  const includeApiKeyFuncName = 'includeApiKey';
356
438
  const handleResponseFuncName = 'handleBadResponses';
357
439
  const fileInput = [
358
- authTestFunc(language),
359
440
  handleBadResponsesFunc(handleResponseFuncName, language, 'API Key'),
360
441
  beforeMiddlewareFunc(
361
442
  includeApiKeyFuncName,
@@ -372,30 +453,24 @@ const customAuthFile = (language) => {
372
453
  comment('request.headers.Authorization = bundle.authData.apiKey;'),
373
454
  ),
374
455
  ),
375
- authFileExport(
376
- language,
377
- 'custom',
378
- '"custom" is the catch-all auth type. The user supplies some info and Zapier can make authenticated requests with it',
379
- {
380
- beforeFuncNames: [includeApiKeyFuncName],
381
- afterFuncNames: [handleResponseFuncName],
382
- authFields: [
383
- obj(
384
- objProperty('key', strLiteral('apiKey')),
385
- objProperty('label', strLiteral('API Key')),
386
- objProperty('required', 'true'),
387
- ),
388
- ],
389
- },
390
- ),
456
+ ...middlewareFileExport(language, {
457
+ beforeFuncNames: [includeApiKeyFuncName],
458
+ afterFuncNames: [handleResponseFuncName],
459
+ }),
391
460
  ];
392
461
  return language === 'typescript'
393
462
  ? fileTS(standardTypes, ...fileInput)
394
463
  : file(...fileInput);
395
464
  };
396
465
 
466
+ const customFiles = (language) => {
467
+ return {
468
+ middleware: customMiddlewareFile(language),
469
+ authentication: customAuthFile(language),
470
+ };
471
+ };
472
+
397
473
  const digestAuthFile = (language) => {
398
- const badFuncName = 'handleBadResponses';
399
474
  const fileInput = [
400
475
  // special digest auth
401
476
  authTestFunc(
@@ -404,12 +479,10 @@ const digestAuthFile = (language) => {
404
479
  'https://httpbin.zapier-tooling.com/digest-auth/auth/myuser/mypass',
405
480
  ),
406
481
  ),
407
- handleBadResponsesFunc(badFuncName, language),
408
482
  authFileExport(
409
483
  language,
410
484
  'digest',
411
485
  '"digest" auth automatically creates "username" and "password" input fields. It also registers default middleware to create the authentication header.',
412
- { afterFuncNames: [badFuncName] },
413
486
  ),
414
487
  ];
415
488
  return language === 'typescript'
@@ -417,9 +490,29 @@ const digestAuthFile = (language) => {
417
490
  : file(...fileInput);
418
491
  };
419
492
 
493
+ const digestMiddlewareFile = (language) => {
494
+ const badFuncName = 'handleBadResponses';
495
+ const fileInput = [
496
+ handleBadResponsesFunc(badFuncName, language),
497
+ ...middlewareFileExport(language, {
498
+ beforeFuncNames: [],
499
+ afterFuncNames: [badFuncName],
500
+ }),
501
+ ];
502
+ return language === 'typescript'
503
+ ? fileTS(standardTypes, ...fileInput)
504
+ : file(...fileInput);
505
+ };
506
+
507
+ const digestFiles = (language) => {
508
+ return {
509
+ middleware: digestMiddlewareFile(language),
510
+ authentication: digestAuthFile(language),
511
+ };
512
+ };
513
+
420
514
  const sessionAuthFile = (language) => {
421
515
  const getSessionKeyName = 'getSessionKey';
422
- const includeSessionKeyName = 'includeSessionKeyHeader';
423
516
  const fileInput = [
424
517
  authTestFunc(language),
425
518
  tokenExchangeFunc(
@@ -437,25 +530,11 @@ const sessionAuthFile = (language) => {
437
530
  objProperty('sessionKey', 'response.data.sessionKey || "secret"'),
438
531
  ],
439
532
  ),
440
- beforeMiddlewareFunc(
441
- includeSessionKeyName,
442
- language,
443
- ifStatement(
444
- 'bundle.authData.sessionKey',
445
- assignmentStatement('request.headers', 'request.headers || {}'),
446
- assignmentStatement(
447
- "request.headers['X-API-Key']",
448
- 'bundle.authData.sessionKey',
449
- ),
450
- ),
451
- ),
452
533
  authFileExport(
453
534
  language,
454
535
  'session',
455
536
  '"session" auth exchanges user data for a different session token (that may be periodically refreshed")',
456
537
  {
457
- beforeFuncNames: [includeSessionKeyName],
458
- afterFuncNames: [],
459
538
  authFields: [
460
539
  obj(
461
540
  objProperty('key', strLiteral('username')),
@@ -484,6 +563,38 @@ const sessionAuthFile = (language) => {
484
563
  : file(...fileInput);
485
564
  };
486
565
 
566
+ const sessionMiddlewareFile = (language) => {
567
+ const includeSessionKeyName = 'includeSessionKeyHeader';
568
+ const fileInput = [
569
+ beforeMiddlewareFunc(
570
+ includeSessionKeyName,
571
+ language,
572
+ ifStatement(
573
+ 'bundle.authData.sessionKey',
574
+ assignmentStatement('request.headers', 'request.headers || {}'),
575
+ assignmentStatement(
576
+ "request.headers['X-API-Key']",
577
+ 'bundle.authData.sessionKey',
578
+ ),
579
+ ),
580
+ ),
581
+ ...middlewareFileExport(language, {
582
+ beforeFuncNames: [includeSessionKeyName],
583
+ afterFuncNames: [],
584
+ }),
585
+ ];
586
+ return language === 'typescript'
587
+ ? fileTS(standardTypes, ...fileInput)
588
+ : file(...fileInput);
589
+ };
590
+
591
+ const sessionFiles = (language) => {
592
+ return {
593
+ middleware: sessionMiddlewareFile(language),
594
+ authentication: sessionAuthFile(language),
595
+ };
596
+ };
597
+
487
598
  // just different enough from oauth2 that it gets its own function
488
599
  const oauth1TokenExchangeFunc = (
489
600
  funcName,
@@ -520,7 +631,6 @@ const oauth1AuthFile = (language) => {
520
631
  const accessTokenVarName = 'ACCESS_TOKEN_URL';
521
632
  const authorizeUrlVarName = 'AUTHORIZE_URL';
522
633
  const getRequestTokenFuncName = 'getRequestToken';
523
- const includeAccessTokenFuncName = 'includeAccessToken';
524
634
  const fileInput = [
525
635
  variableAssignmentDeclaration('querystring', "require('querystring')"),
526
636
  block(
@@ -553,33 +663,8 @@ const oauth1AuthFile = (language) => {
553
663
  objProperty('oauth_token_secret', 'bundle.inputData.oauth_token_secret'),
554
664
  objProperty('oauth_verifier', 'bundle.inputData.oauth_verifier'),
555
665
  ),
556
- beforeMiddlewareFunc(
557
- includeAccessTokenFuncName,
558
- language,
559
- ifStatement(
560
- 'bundle.authData && bundle.authData.oauth_token && bundle.authData.oauth_token_secret',
561
- comment(
562
- 'Put your OAuth1 credentials in `req.auth`, Zapier will sign the request for you.',
563
- ),
564
- assignmentStatement(
565
- 'request.auth',
566
- obj(
567
- objProperty('oauth_consumer_key', 'process.env.CLIENT_ID'),
568
- objProperty('oauth_consumer_secret', 'process.env.CLIENT_SECRET'),
569
- objProperty('oauth_token', 'bundle.authData.oauth_token'),
570
- objProperty(
571
- 'oauth_token_secret',
572
- 'bundle.authData.oauth_token_secret',
573
- ),
574
- comment("oauth_version: '1.0', // sometimes required"),
575
- objProperty('...(request.auth || {})'),
576
- ),
577
- ),
578
- ),
579
- ),
580
666
  authTestFunc(language, strLiteral('https://api.trello.com/1/members/me/')),
581
667
  authFileExport(language, 'oauth1', 'OAuth1 is an older form of OAuth', {
582
- beforeFuncNames: [includeAccessTokenFuncName],
583
668
  extraConfigProps: [
584
669
  objProperty(
585
670
  'oauth1Config',
@@ -619,11 +704,55 @@ const oauth1AuthFile = (language) => {
619
704
  : file(...fileInput);
620
705
  };
621
706
 
707
+ const oauth1MiddlewareFile = (language) => {
708
+ const includeAccessTokenFuncName = 'includeAccessToken';
709
+ const fileInput = [
710
+ beforeMiddlewareFunc(
711
+ includeAccessTokenFuncName,
712
+ language,
713
+ ifStatement(
714
+ 'bundle.authData && bundle.authData.oauth_token && bundle.authData.oauth_token_secret',
715
+ comment(
716
+ 'Put your OAuth1 credentials in `req.auth`, Zapier will sign the request for you.',
717
+ ),
718
+ assignmentStatement(
719
+ 'request.auth',
720
+ obj(
721
+ objProperty('oauth_consumer_key', 'process.env.CLIENT_ID'),
722
+ objProperty('oauth_consumer_secret', 'process.env.CLIENT_SECRET'),
723
+ objProperty('oauth_token', 'bundle.authData.oauth_token'),
724
+ objProperty(
725
+ 'oauth_token_secret',
726
+ 'bundle.authData.oauth_token_secret',
727
+ ),
728
+ comment("oauth_version: '1.0', // sometimes required"),
729
+ objProperty('...(request.auth || {})'),
730
+ ),
731
+ ),
732
+ ),
733
+ ),
734
+ ...middlewareFileExport(language, {
735
+ beforeFuncNames: [includeAccessTokenFuncName],
736
+ afterFuncNames: [],
737
+ }),
738
+ ];
739
+ return language === 'typescript'
740
+ ? fileTS(standardTypes, ...fileInput)
741
+ : file(...fileInput);
742
+ };
743
+
744
+ const oauth1Files = (language) => {
745
+ return {
746
+ middleware: oauth1MiddlewareFile(language),
747
+ authentication: oauth1AuthFile(language),
748
+ };
749
+ };
750
+
622
751
  module.exports = {
623
- basic: basicAuthFile,
624
- custom: customAuthFile,
625
- digest: digestAuthFile,
626
- oauth1: oauth1AuthFile,
627
- oauth2: oauth2AuthFile,
628
- session: sessionAuthFile,
752
+ basic: basicFiles,
753
+ custom: customFiles,
754
+ digest: digestFiles,
755
+ oauth1: oauth1Files,
756
+ oauth2: oauth2Files,
757
+ session: sessionFiles,
629
758
  };
@@ -75,6 +75,9 @@ const findRequiredFiles = async (workingDir, entryPoints) => {
75
75
  write: false, // no need to write outfile
76
76
  absWorkingDir: workingDir,
77
77
  tsconfigRaw: '{}',
78
+ loader: {
79
+ '.node': 'file',
80
+ },
78
81
  });
79
82
 
80
83
  let relPaths = Object.keys(result.metafile.inputs);
@@ -49,8 +49,8 @@ const objProperty = (key, value, satisfiesType) => {
49
49
  return `'${key}': ${value}${satisfiesType ? ` satisfies ${satisfiesType}` : ''}`;
50
50
  };
51
51
 
52
- const variableAssignmentDeclaration = (varName, value) =>
53
- `const ${varName} = ${value}`;
52
+ const variableAssignmentDeclaration = (varName, value, exportConst = false) =>
53
+ `${exportConst ? 'export const' : 'const'} ${varName} = ${value}`;
54
54
 
55
55
  const fatArrowReturnFunctionDeclaration = (varname, args, statement) =>
56
56
  `const ${varname} = (${args.join(', ')}) => ${statement}`;