zapier-platform-cli 12.2.1 → 14.0.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/README-source.md +113 -48
- package/README.md +201 -74
- package/oclif.manifest.json +1 -1
- package/package.json +29 -26
- package/scaffold/create.template.js +2 -2
- package/scaffold/resource.template.js +2 -2
- package/scaffold/search.template.js +2 -2
- package/scaffold/trigger.template.js +2 -2
- package/src/constants.js +4 -1
- package/src/generators/templates/README.template.md +1 -1
- package/src/generators/templates/callback/README.md +1 -1
- package/src/generators/templates/files/README.md +1 -1
- package/src/oclif/ZapierBaseCommand.js +44 -2
- package/src/oclif/commands/convert.js +27 -64
- package/src/oclif/commands/link.js +1 -1
- package/src/oclif/commands/promote.js +4 -1
- package/src/oclif/commands/register.js +274 -22
- package/src/oclif/hooks/getAppRegistrationFieldChoices.js +45 -0
- package/src/utils/api.js +7 -0
- package/src/utils/build.js +4 -0
- package/src/utils/check-missing-app-info.js +26 -0
- package/src/version-store.js +1 -1
package/README.md
CHANGED
|
@@ -16,17 +16,17 @@ Zapier is a platform for creating integrations and workflows. This CLI is your g
|
|
|
16
16
|
|
|
17
17
|
You may find docs duplicate or outdated across the Zapier site. The most up-to-date contents are always available on GitHub:
|
|
18
18
|
|
|
19
|
-
- [Latest CLI Docs](https://github.com/zapier/zapier-platform/blob/
|
|
20
|
-
- [Latest CLI Reference](https://github.com/zapier/zapier-platform/blob/
|
|
21
|
-
- [Latest Schema Docs](https://github.com/zapier/zapier-platform/blob/
|
|
19
|
+
- [Latest CLI Docs](https://github.com/zapier/zapier-platform/blob/main/packages/cli/README.md)
|
|
20
|
+
- [Latest CLI Reference](https://github.com/zapier/zapier-platform/blob/main/packages/cli/docs/cli.md)
|
|
21
|
+
- [Latest Schema Docs](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md)
|
|
22
22
|
|
|
23
|
-
Our code is updated frequently. To see a full list of changes, look no further than [the CHANGELOG](https://github.com/zapier/zapier-platform/blob/
|
|
23
|
+
Our code is updated frequently. To see a full list of changes, look no further than [the CHANGELOG](https://github.com/zapier/zapier-platform/blob/main/CHANGELOG.md).
|
|
24
24
|
|
|
25
|
-
This doc describes the latest CLI version (**
|
|
25
|
+
This doc describes the latest CLI version (**14.0.0**), as of this writing. If you're using an older version of the CLI, you may want to check out these historical releases:
|
|
26
26
|
|
|
27
|
-
- CLI Docs: [
|
|
28
|
-
- CLI Reference: [
|
|
29
|
-
- Schema Docs: [
|
|
27
|
+
- CLI Docs: [11.3.3](https://github.com/zapier/zapier-platform/blob/zapier-platform-cli@11.3.3/packages/cli/README.md), [10.2.0](https://github.com/zapier/zapier-platform/blob/zapier-platform-cli@10.2.0/packages/cli/README.md), [9.7.3](https://github.com/zapier/zapier-platform/blob/zapier-platform-cli@9.7.3/packages/cli/README.md)
|
|
28
|
+
- CLI Reference: [11.3.3](https://github.com/zapier/zapier-platform/blob/zapier-platform-cli@11.3.3/packages/cli/docs/cli.md), [10.2.0](https://github.com/zapier/zapier-platform/blob/zapier-platform-cli@10.2.0/packages/cli/docs/cli.md), [9.7.3](https://github.com/zapier/zapier-platform/blob/zapier-platform-cli@9.7.3/packages/cli/docs/cli.md)
|
|
29
|
+
- Schema Docs: [11.3.3](https://github.com/zapier/zapier-platform/blob/zapier-platform-schema@11.3.3/packages/schema/docs/build/schema.md), [10.2.0](https://github.com/zapier/zapier-platform/blob/zapier-platform-schema@10.2.0/packages/schema/docs/build/schema.md), [9.7.3](https://github.com/zapier/zapier-platform/blob/zapier-platform-schema@9.7.3/packages/schema/docs/build/schema.md)
|
|
30
30
|
|
|
31
31
|
## Table of Contents
|
|
32
32
|
|
|
@@ -55,11 +55,13 @@ This doc describes the latest CLI version (**12.2.1**), as of this writing. If y
|
|
|
55
55
|
* [Session](#session)
|
|
56
56
|
* [OAuth1](#oauth1)
|
|
57
57
|
* [OAuth2](#oauth2)
|
|
58
|
+
* [OAuth2 with PKCE](#oauth2-with-pkce)
|
|
58
59
|
* [Connection Label](#connection-label)
|
|
59
60
|
- [Resources](#resources)
|
|
60
61
|
* [Resource Definition](#resource-definition)
|
|
61
62
|
- [Triggers/Searches/Creates](#triggerssearchescreates)
|
|
62
63
|
* [Return Types](#return-types)
|
|
64
|
+
+ [Returning Line Items (Array of Objects)](#returning-line-items-array-of-objects)
|
|
63
65
|
* [Fallback Sample](#fallback-sample)
|
|
64
66
|
- [Input Fields](#input-fields)
|
|
65
67
|
* [Custom/Dynamic Fields](#customdynamic-fields)
|
|
@@ -157,7 +159,7 @@ This doc describes the latest CLI version (**12.2.1**), as of this writing. If y
|
|
|
157
159
|
> Note: this document uses "app" while modern Zapier nomenclature refers instead to "integrations". In both cases, the phrase refers to your code that connects your API with Zapier.
|
|
158
160
|
|
|
159
161
|
A CLI App is an implementation of your app's API. You build a Node.js application
|
|
160
|
-
that exports a single object ([JSON Schema](https://github.com/zapier/zapier-platform/blob/
|
|
162
|
+
that exports a single object ([JSON Schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#appschema)) and upload it to Zapier.
|
|
161
163
|
Zapier introspects that definition to find out what your app is capable of and
|
|
162
164
|
what options to present end users in the Zap Editor.
|
|
163
165
|
|
|
@@ -186,15 +188,15 @@ Zapier Platform CLI is designed to be used by development teams who collaborate
|
|
|
186
188
|
|
|
187
189
|
### Requirements
|
|
188
190
|
|
|
189
|
-
All Zapier CLI apps are run using Node.js `
|
|
191
|
+
All Zapier CLI apps are run using Node.js `v16`.
|
|
190
192
|
|
|
191
|
-
You can develop using any version of Node you'd like, but your eventual code must be compatible with `
|
|
193
|
+
You can develop using any version of Node you'd like, but your eventual code must be compatible with `v16`. If you're using features not yet available in `v16`, you can transpile your code to a compatible format with [Babel](https://babeljs.io/) (or similar).
|
|
192
194
|
|
|
193
|
-
To ensure stability for our users, we strongly encourage you run tests on `
|
|
195
|
+
To ensure stability for our users, we strongly encourage you run tests on `v16` sometime before your code reaches users. This can be done multiple ways.
|
|
194
196
|
|
|
195
|
-
Firstly, by using a CI tool (like [Travis CI](https://travis-ci.org/) or [Circle CI](https://circleci.com/), which are free for open source projects). We provide a sample [.travis.yml](https://github.com/zapier/zapier-platform/blob/
|
|
197
|
+
Firstly, by using a CI tool (like [Travis CI](https://travis-ci.org/) or [Circle CI](https://circleci.com/), which are free for open source projects). We provide a sample [.travis.yml](https://github.com/zapier/zapier-platform/blob/main/example-apps/trigger/.travis.yml) file in our template apps to get you started.
|
|
196
198
|
|
|
197
|
-
Alternatively, you can change your local node version with tools such as [nvm](https://github.com/nvm-sh/nvm#installation-and-update). Then you can either swap to that version with `nvm use
|
|
199
|
+
Alternatively, you can change your local node version with tools such as [nvm](https://github.com/nvm-sh/nvm#installation-and-update). Then you can either swap to that version with `nvm use v16`, or do `nvm exec v16 zapier test` so you can run tests without having to switch versions while developing.
|
|
198
200
|
|
|
199
201
|
|
|
200
202
|
### Quick Setup Guide
|
|
@@ -223,7 +225,7 @@ cd example-app
|
|
|
223
225
|
npm install
|
|
224
226
|
```
|
|
225
227
|
|
|
226
|
-
> Note: When you run `zapier init`, you'll be presented with a list of templates to start with. Pick the one that matches a feature you'll need (such as "dynamic-dropdown" for an integration with [dynamic dropdown fields](#dynamic-dropdowns)), or select "minimal" for an integration with only the essentials. [View more example apps here](https://github.com/zapier/zapier-platform/tree/
|
|
228
|
+
> Note: When you run `zapier init`, you'll be presented with a list of templates to start with. Pick the one that matches a feature you'll need (such as "dynamic-dropdown" for an integration with [dynamic dropdown fields](#dynamic-dropdowns)), or select "minimal" for an integration with only the essentials. [View more example apps here](https://github.com/zapier/zapier-platform/tree/main/example-apps).
|
|
227
229
|
|
|
228
230
|
You should now have a working local app. You can run several local commands to try it out.
|
|
229
231
|
|
|
@@ -452,7 +454,7 @@ When a user authenticates to your application through Zapier, a "connection" is
|
|
|
452
454
|
|
|
453
455
|
Useful if your app requires two pieces of information to authenticate: `username` and `password`, which only the end user can provide. By default, Zapier will do the standard Basic authentication base64 header encoding for you (via an automatically registered middleware).
|
|
454
456
|
|
|
455
|
-
> To create a new integration with basic authentication, run `zapier init [your app name] --template basic-auth`. You can also review an example of that code [here](https://github.com/zapier/zapier-platform/tree/
|
|
457
|
+
> To create a new integration with basic authentication, run `zapier init [your app name] --template basic-auth`. You can also review an example of that code [here](https://github.com/zapier/zapier-platform/tree/main/example-apps/basic-auth).
|
|
456
458
|
|
|
457
459
|
If your app uses Basic auth with an encoded API key rather than a username and password, like `Authorization: Basic APIKEYHERE:x`, consider the [Custom](#custom) authentication method instead.
|
|
458
460
|
|
|
@@ -469,7 +471,7 @@ const authentication = {
|
|
|
469
471
|
|
|
470
472
|
const App = {
|
|
471
473
|
// ...
|
|
472
|
-
authentication
|
|
474
|
+
authentication,
|
|
473
475
|
// ...
|
|
474
476
|
};
|
|
475
477
|
|
|
@@ -481,7 +483,7 @@ const App = {
|
|
|
481
483
|
|
|
482
484
|
The setup and user experience of Digest Auth is identical to Basic Auth. Users provide Zapier their username and password, and Zapier handles all the nonce and quality of protection details automatically.
|
|
483
485
|
|
|
484
|
-
> To create a new integration with digest authentication, run `zapier init [your app name] --template digest-auth`. You can also review an example of that code [here](https://github.com/zapier/zapier-platform/tree/
|
|
486
|
+
> To create a new integration with digest authentication, run `zapier init [your app name] --template digest-auth`. You can also review an example of that code [here](https://github.com/zapier/zapier-platform/tree/main/example-apps/digest-auth).
|
|
485
487
|
|
|
486
488
|
> Limitation: Currently, MD5-sess and SHA are not implemented. Only the MD5 algorithm is supported. In addition, server nonces are not reused. That means for every `z.request` call, Zapier will send an additional request beforehand to get the server nonce.
|
|
487
489
|
|
|
@@ -504,7 +506,7 @@ const authentication = {
|
|
|
504
506
|
|
|
505
507
|
const App = {
|
|
506
508
|
// ...
|
|
507
|
-
authentication
|
|
509
|
+
authentication,
|
|
508
510
|
// ...
|
|
509
511
|
};
|
|
510
512
|
|
|
@@ -514,15 +516,14 @@ const App = {
|
|
|
514
516
|
|
|
515
517
|
Custom auth is most commonly used for apps that authenticate with API keys, although it also provides flexibility for any unusual authentication setup. You'll likely provide some custom `beforeRequest` middleware or a `requestTemplate` (see [Making HTTP Requests](#making-http-requests)) to pass in data returned from the authentication process, most commonly by adding/computing needed headers.
|
|
516
518
|
|
|
517
|
-
> To create a new integration with custom authentication, run `zapier init [your app name] --template custom-auth`. You can also review an example of that code [here](https://github.com/zapier/zapier-platform/tree/
|
|
519
|
+
> To create a new integration with custom authentication, run `zapier init [your app name] --template custom-auth`. You can also review an example of that code [here](https://github.com/zapier/zapier-platform/tree/main/example-apps/custom-auth).
|
|
518
520
|
|
|
519
521
|
```js
|
|
520
522
|
const authentication = {
|
|
521
523
|
type: 'custom',
|
|
522
524
|
// "test" could also be a function
|
|
523
525
|
test: {
|
|
524
|
-
url:
|
|
525
|
-
'https://{{bundle.authData.subdomain}}.example.com/api/accounts/me.json',
|
|
526
|
+
url: 'https://{{bundle.authData.subdomain}}.example.com/api/accounts/me.json',
|
|
526
527
|
},
|
|
527
528
|
fields: [
|
|
528
529
|
{
|
|
@@ -551,7 +552,7 @@ const addApiKeyToHeader = (request, z, bundle) => {
|
|
|
551
552
|
|
|
552
553
|
const App = {
|
|
553
554
|
// ...
|
|
554
|
-
authentication
|
|
555
|
+
authentication,
|
|
555
556
|
beforeRequest: [addApiKeyToHeader],
|
|
556
557
|
// ...
|
|
557
558
|
};
|
|
@@ -562,7 +563,7 @@ const App = {
|
|
|
562
563
|
|
|
563
564
|
Session auth gives you the ability to exchange some user-provided data for some authentication data; for example, username and password for a session key. It can be used to implement almost any authentication method that uses that pattern - for example, alternative OAuth flows.
|
|
564
565
|
|
|
565
|
-
> To create a new integration with session authentication, run `zapier init [your app name] --template session-auth`. You can also review an example of that code [here](https://github.com/zapier/zapier-platform/tree/
|
|
566
|
+
> To create a new integration with session authentication, run `zapier init [your app name] --template session-auth`. You can also review an example of that code [here](https://github.com/zapier/zapier-platform/tree/main/example-apps/session-auth).
|
|
566
567
|
|
|
567
568
|
```js
|
|
568
569
|
const getSessionKey = async (z, bundle) => {
|
|
@@ -623,7 +624,7 @@ const includeSessionKeyHeader = (request, z, bundle) => {
|
|
|
623
624
|
|
|
624
625
|
const App = {
|
|
625
626
|
// ...
|
|
626
|
-
authentication
|
|
627
|
+
authentication,
|
|
627
628
|
beforeRequest: [includeSessionKeyHeader],
|
|
628
629
|
// ...
|
|
629
630
|
};
|
|
@@ -638,7 +639,7 @@ For Session auth, the function that fetches the additional authentication data n
|
|
|
638
639
|
|
|
639
640
|
Zapier's OAuth1 implementation matches [Twitter](https://developer.twitter.com/en/docs/tutorials/authenticating-with-twitter-api-for-enterprise/authentication-method-overview#oauth1.0a) and [Trello](https://developer.atlassian.com/cloud/trello/guides/rest-api/authorization/#using-basic-oauth) implementations of the 3-legged OAuth flow.
|
|
640
641
|
|
|
641
|
-
> To create a new integration with OAuth1, run `zapier init [your app name] --template oauth1-trello`. You can also check out [oauth1-trello](https://github.com/zapier/zapier-platform/tree/
|
|
642
|
+
> To create a new integration with OAuth1, run `zapier init [your app name] --template oauth1-trello`. You can also check out [oauth1-trello](https://github.com/zapier/zapier-platform/tree/main/example-apps/oauth1-trello), [oauth1-tumblr](https://github.com/zapier/zapier-platform/tree/main/example-apps/oauth1-tumblr), and [oauth1-twitter](https://github.com/zapier/zapier-platform/tree/main/example-apps/oauth1-twitter) for working example apps with OAuth1.
|
|
642
643
|
|
|
643
644
|
The flow works like this:
|
|
644
645
|
|
|
@@ -741,7 +742,7 @@ const includeAccessToken = (req, z, bundle) => {
|
|
|
741
742
|
|
|
742
743
|
const App = {
|
|
743
744
|
// ...
|
|
744
|
-
authentication
|
|
745
|
+
authentication,
|
|
745
746
|
beforeRequest: [includeAccessToken],
|
|
746
747
|
// ...
|
|
747
748
|
};
|
|
@@ -758,7 +759,7 @@ Also, `authentication.oauth1Config.getAccessToken` has access to the additional
|
|
|
758
759
|
|
|
759
760
|
Zapier's OAuth2 implementation is based on the `authorization_code` flow, similar to [GitHub](https://developer.github.com/v3/oauth/) and [Facebook](https://developers.facebook.com/docs/authentication/server-side/).
|
|
760
761
|
|
|
761
|
-
> To create a new integration with OAuth2, run `zapier init [your app name] --template oauth2`. You can also check out [our working example app](https://github.com/zapier/zapier-platform/tree/
|
|
762
|
+
> To create a new integration with OAuth2, run `zapier init [your app name] --template oauth2`. You can also check out [our working example app](https://github.com/zapier/zapier-platform/tree/main/example-apps/oauth2).
|
|
762
763
|
|
|
763
764
|
If your app's OAuth2 flow uses a different grant type, such as `client_credentials`, try using [Session auth](#session) instead.
|
|
764
765
|
|
|
@@ -794,16 +795,14 @@ Your auth definition would look something like this:
|
|
|
794
795
|
const authentication = {
|
|
795
796
|
type: 'oauth2',
|
|
796
797
|
test: {
|
|
797
|
-
url:
|
|
798
|
-
'https://{{bundle.authData.subdomain}}.example.com/api/accounts/me.json',
|
|
798
|
+
url: 'https://{{bundle.authData.subdomain}}.example.com/api/accounts/me.json',
|
|
799
799
|
},
|
|
800
800
|
// you can provide additional fields for inclusion in authData
|
|
801
801
|
oauth2Config: {
|
|
802
802
|
// "authorizeUrl" could also be a function returning a string url
|
|
803
803
|
authorizeUrl: {
|
|
804
804
|
method: 'GET',
|
|
805
|
-
url:
|
|
806
|
-
'https://{{bundle.inputData.subdomain}}.example.com/api/oauth2/authorize',
|
|
805
|
+
url: 'https://{{bundle.inputData.subdomain}}.example.com/api/oauth2/authorize',
|
|
807
806
|
params: {
|
|
808
807
|
client_id: '{{process.env.CLIENT_ID}}',
|
|
809
808
|
state: '{{bundle.inputData.state}}',
|
|
@@ -815,8 +814,7 @@ const authentication = {
|
|
|
815
814
|
// "getAccessToken" could also be a function returning an object
|
|
816
815
|
getAccessToken: {
|
|
817
816
|
method: 'POST',
|
|
818
|
-
url:
|
|
819
|
-
'https://{{bundle.inputData.subdomain}}.example.com/api/v2/oauth2/token',
|
|
817
|
+
url: 'https://{{bundle.inputData.subdomain}}.example.com/api/v2/oauth2/token',
|
|
820
818
|
body: {
|
|
821
819
|
code: '{{bundle.inputData.code}}',
|
|
822
820
|
client_id: '{{process.env.CLIENT_ID}}',
|
|
@@ -850,7 +848,7 @@ const addBearerHeader = (request, z, bundle) => {
|
|
|
850
848
|
|
|
851
849
|
const App = {
|
|
852
850
|
// ...
|
|
853
|
-
authentication
|
|
851
|
+
authentication,
|
|
854
852
|
beforeRequest: [addBearerHeader],
|
|
855
853
|
// ...
|
|
856
854
|
};
|
|
@@ -865,6 +863,99 @@ Also, `authentication.oauth2Config.getAccessToken` has access to the additional
|
|
|
865
863
|
|
|
866
864
|
If you define `fields` to collect additional details from the user, please note that `client_id` and `client_secret` are reserved keys and cannot be used as keys for input form fields.
|
|
867
865
|
|
|
866
|
+
|
|
867
|
+
### OAuth2 with PKCE
|
|
868
|
+
|
|
869
|
+
*Added in v14.0.0.*
|
|
870
|
+
|
|
871
|
+
Zapier's OAuth2 implementation also supports [PKCE](https://oauth.net/2/pkce/). This implementation is an extension of the OAuth2 `authorization_code` flow described above.
|
|
872
|
+
|
|
873
|
+
To use PKCE in your OAuth2 flow, you'll need to set the following variables:
|
|
874
|
+
1. `enablePkce: true`
|
|
875
|
+
2. `getAccessToken.body` to include `code_verifier: "{{bundle.inputData.code_verifier}}"`
|
|
876
|
+
|
|
877
|
+
The OAuth2 PKCE flow uses the same flow as OAuth2 but adds a few extra parameters:
|
|
878
|
+
|
|
879
|
+
1. Zapier computes a `code_verifier` and `code_challenge` internally and stores the `code_verifier` in the Zapier bundle.
|
|
880
|
+
2. Zapier sends the user to the authorization URL defined by your app, passing along the computed `code_challenge`.
|
|
881
|
+
3. Once authorized, your website sends the user to the `redirect_uri` Zapier provided.
|
|
882
|
+
4. Zapier makes a call to your API to exchange the `code` and the computed `code_verifier` for an `access_token`.
|
|
883
|
+
5. Zapier stores the `access_token` and uses it to make calls on behalf of the user.
|
|
884
|
+
|
|
885
|
+
Your auth definition would look something like this:
|
|
886
|
+
|
|
887
|
+
```js
|
|
888
|
+
const authentication = {
|
|
889
|
+
type: 'oauth2',
|
|
890
|
+
test: {
|
|
891
|
+
url: 'https://{{bundle.authData.subdomain}}.example.com/api/accounts/me.json',
|
|
892
|
+
},
|
|
893
|
+
// you can provide additional fields for inclusion in authData
|
|
894
|
+
oauth2Config: {
|
|
895
|
+
// "authorizeUrl" could also be a function returning a string url
|
|
896
|
+
authorizeUrl: {
|
|
897
|
+
method: 'GET',
|
|
898
|
+
url: 'https://{{bundle.inputData.subdomain}}.example.com/api/oauth2/authorize',
|
|
899
|
+
params: {
|
|
900
|
+
client_id: '{{process.env.CLIENT_ID}}',
|
|
901
|
+
state: '{{bundle.inputData.state}}',
|
|
902
|
+
redirect_uri: '{{bundle.inputData.redirect_uri}}',
|
|
903
|
+
response_type: 'code',
|
|
904
|
+
},
|
|
905
|
+
},
|
|
906
|
+
// Zapier expects a response providing {access_token: 'abcd'}
|
|
907
|
+
// "getAccessToken" could also be a function returning an object
|
|
908
|
+
getAccessToken: {
|
|
909
|
+
method: 'POST',
|
|
910
|
+
url: 'https://{{bundle.inputData.subdomain}}.example.com/api/v2/oauth2/token',
|
|
911
|
+
body: {
|
|
912
|
+
code: '{{bundle.inputData.code}}',
|
|
913
|
+
client_id: '{{process.env.CLIENT_ID}}',
|
|
914
|
+
client_secret: '{{process.env.CLIENT_SECRET}}',
|
|
915
|
+
redirect_uri: '{{bundle.inputData.redirect_uri}}',
|
|
916
|
+
grant_type: 'authorization_code',
|
|
917
|
+
code_verifier: '{{bundle.inputData.code_verifier}}', // Added for PKCE
|
|
918
|
+
},
|
|
919
|
+
headers: {
|
|
920
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
921
|
+
},
|
|
922
|
+
},
|
|
923
|
+
scope: 'read,write',
|
|
924
|
+
enablePkce: true, // Added for PKCE
|
|
925
|
+
},
|
|
926
|
+
// If you need any fields upfront, put them here
|
|
927
|
+
fields: [
|
|
928
|
+
{ key: 'subdomain', type: 'string', required: true, default: 'app' },
|
|
929
|
+
// For OAuth2 we store `access_token` and `refresh_token` automatically
|
|
930
|
+
// in `bundle.authData` for future use. If you need to save/use something
|
|
931
|
+
// that the user shouldn't need to type/choose, add a "computed" field, like:
|
|
932
|
+
// {key: 'user_id': type: 'string', required: false, computed: true}
|
|
933
|
+
// And remember to return it in oauth2Config.getAccessToken/refreshAccessToken
|
|
934
|
+
],
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
const addBearerHeader = (request, z, bundle) => {
|
|
938
|
+
if (bundle.authData && bundle.authData.access_token) {
|
|
939
|
+
request.headers.Authorization = `Bearer ${bundle.authData.access_token}`;
|
|
940
|
+
}
|
|
941
|
+
return request;
|
|
942
|
+
};
|
|
943
|
+
|
|
944
|
+
const App = {
|
|
945
|
+
// ...
|
|
946
|
+
authentication,
|
|
947
|
+
beforeRequest: [addBearerHeader],
|
|
948
|
+
// ...
|
|
949
|
+
};
|
|
950
|
+
|
|
951
|
+
module.exports = App;
|
|
952
|
+
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
The computed `code_verifier` uses this standard: [RFC 7636 Code Verifier](https://www.rfc-editor.org/rfc/rfc7636#section-4.1)
|
|
956
|
+
|
|
957
|
+
The computed `code_challenge` uses this standard: [RFC 7636 Code Challenge](https://www.rfc-editor.org/rfc/rfc7636#section-4.2)
|
|
958
|
+
|
|
868
959
|
### Connection Label
|
|
869
960
|
|
|
870
961
|
When a user connects to your app via Zapier and a connection is created to hold the related data in `bundle.authData`, the connection is automatically labeled with the app name. You also have the option of setting a connection label (`connectionLabel`), which can be extremely helpful to identify information like which user is connected or what instance of your app they are connected to. That way, users don't get confused if they have multiple connections to your app.
|
|
@@ -915,10 +1006,10 @@ This will generate the resource file and add the necessary statements to the `in
|
|
|
915
1006
|
A resource has a few basic properties. The first is the `key`, which allows Zapier to identify the resource on our backend.
|
|
916
1007
|
The second is the `noun`, the user-friendly name of the resource that is presented to users throughout the Zapier UI.
|
|
917
1008
|
|
|
918
|
-
> Check out [this working example app](https://github.com/zapier/zapier-platform/tree/
|
|
1009
|
+
> Check out [this working example app](https://github.com/zapier/zapier-platform/tree/main/example-apps/resource) to see resources in action.
|
|
919
1010
|
|
|
920
1011
|
After those, there is a set of optional properties that tell Zapier what methods can be performed on the resource.
|
|
921
|
-
The complete list of available methods can be found in the [Resource Schema Docs](https://github.com/zapier/zapier-platform/blob/
|
|
1012
|
+
The complete list of available methods can be found in the [Resource Schema Docs](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#resourceschema).
|
|
922
1013
|
For now, let's focus on two:
|
|
923
1014
|
|
|
924
1015
|
* `list` - Tells Zapier how to fetch a set of this resource. This becomes a Trigger in the Zapier Editor.
|
|
@@ -945,7 +1036,7 @@ const Recipe = {
|
|
|
945
1036
|
|
|
946
1037
|
```
|
|
947
1038
|
|
|
948
|
-
The method is made up of two properties, a `display` and an `operation`. The `display` property ([schema](https://github.com/zapier/zapier-platform/blob/
|
|
1039
|
+
The method is made up of two properties, a `display` and an `operation`. The `display` property ([schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#basicdisplayschema)) holds the info needed to present the method as an available Trigger in the Zapier Editor. The `operation` ([schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#resourceschema)) provides the implementation to make the API call.
|
|
949
1040
|
|
|
950
1041
|
Adding a create method looks very similar.
|
|
951
1042
|
|
|
@@ -1017,24 +1108,60 @@ const App = {
|
|
|
1017
1108
|
|
|
1018
1109
|
```
|
|
1019
1110
|
|
|
1020
|
-
You can find more details on the definition for each by looking at the [Trigger Schema](https://github.com/zapier/zapier-platform/blob/
|
|
1021
|
-
[Search Schema](https://github.com/zapier/zapier-platform/blob/
|
|
1111
|
+
You can find more details on the definition for each by looking at the [Trigger Schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#triggerschema),
|
|
1112
|
+
[Search Schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#searchschema), and [Create Schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#createschema).
|
|
1022
1113
|
|
|
1023
|
-
> To create a new integration with a premade trigger, search, or create, run `zapier init [your app name]` and select from the list that appears. You can also check out our working example apps [here](https://github.com/zapier/zapier-platform/tree/
|
|
1114
|
+
> To create a new integration with a premade trigger, search, or create, run `zapier init [your app name]` and select from the list that appears. You can also check out our working example apps [here](https://github.com/zapier/zapier-platform/tree/main/example-apps).
|
|
1024
1115
|
|
|
1025
1116
|
> To add a trigger, search, or create to an existing integration, run `zapier scaffold [trigger|search|create] [noun]` to create the necessary files to your project. For example, `zapier scaffold trigger post` will create a new trigger called "New Post".
|
|
1026
1117
|
### Return Types
|
|
1027
1118
|
|
|
1028
|
-
Each of the 3 types of function
|
|
1119
|
+
Each of the 3 types of function should return a certain data type for use by the platform. There are automated checks to let you know when you're trying to pass the wrong type back. For reference, each expects:
|
|
1029
1120
|
|
|
1030
1121
|
| Method | Return Type | Notes |
|
|
1031
1122
|
|---------|-------------|----------------------------------------------------------------------------------------------------------------------|
|
|
1032
|
-
| Trigger | Array | 0 or more objects; passed to the [deduper](https://zapier.com/
|
|
1123
|
+
| Trigger | Array | 0 or more objects; passed to the [deduper](https://platform.zapier.com/docs/dedupe/) if polling |
|
|
1033
1124
|
| Search | Array | 0 or more objects. Only the first object will be returned, so if len > 1, put the best match first |
|
|
1034
|
-
|
|
|
1125
|
+
| Create | Object | Return values are evaluated by [`isPlainObject`](https://lodash.com/docs#isPlainObject) |
|
|
1035
1126
|
|
|
1036
1127
|
When a trigger function returns an empty array, the Zap will not trigger. For REST Hook triggers, this can be used to filter data if the available subscription options are not specific enough for the Zap's needs.
|
|
1037
1128
|
|
|
1129
|
+
#### Returning Line Items (Array of Objects)
|
|
1130
|
+
|
|
1131
|
+
In some cases, you may want to include multiple items in the data you return for Searches or Creates. To do that, return the set of items as an array of objects under a descriptive key. This may be as part of another object (like items in an invoice) or as multiple top-level items.
|
|
1132
|
+
|
|
1133
|
+
For example, a Create Order action returning an order with multiple items might look like this:
|
|
1134
|
+
|
|
1135
|
+
```
|
|
1136
|
+
order = {
|
|
1137
|
+
name: 'Zap Zaplar',
|
|
1138
|
+
total_cost: 25.96,
|
|
1139
|
+
items: [
|
|
1140
|
+
{ name: 'Zapier T-Shirt', unit_price: 11.99, quantity: 3, line_amount: 35.97, category: 'shirts' },
|
|
1141
|
+
{ name: 'Orange Widget', unit_price: 7.99, quantity: 10, line_amount: 79.90, category: 'widgets' },
|
|
1142
|
+
{ name:'Stuff', unit_price: 2.99, quantity: 7, line_amount: 20.93, category: 'stuff' },
|
|
1143
|
+
{ name: 'Allbird Shoes', unit_price: 2.99, quantity: 7, line_amount: 20.93, category: 'shoes' },
|
|
1144
|
+
],
|
|
1145
|
+
zip: 01002
|
|
1146
|
+
}
|
|
1147
|
+
```
|
|
1148
|
+
|
|
1149
|
+
While a Find Users search could return multiple items under an object key within an array, like this:
|
|
1150
|
+
|
|
1151
|
+
```
|
|
1152
|
+
result = [{
|
|
1153
|
+
users: [
|
|
1154
|
+
{ name: 'Zap Zaplar', age: 12, city: 'Columbia', region: 'Missouri' },
|
|
1155
|
+
{ name: 'Orange Crush', age: 28, city: 'West Ocean City', region: 'Maryland' },
|
|
1156
|
+
{ name: 'Lego Brick', age: 91, city: 'Billund', region: 'Denmark' },
|
|
1157
|
+
],
|
|
1158
|
+
}];
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
A standard search would return just the inner array of users, and only the first user would be provided as a final result. Returning line items instead means that the "first result" return is the object containing all the user details within it.
|
|
1162
|
+
|
|
1163
|
+
Using the standard approach is recommended, because not all Zapier integrations support line items directly, so users may need to take additional actions to reformat this data for use in their Zaps. More detail on that at [Use line items in Zaps](https://zapier.com/help/create/basics/use-line-items-in-zaps). However, there are use cases where returning multiple results is helpful enough to outweigh that additional effort.
|
|
1164
|
+
|
|
1038
1165
|
### Fallback Sample
|
|
1039
1166
|
In cases where Zapier needs to show an example record to the user, but we are unable to get a live example from the API, Zapier will fallback to this hard-coded sample. This should reflect the data structure of the Trigger's perform method, and have dummy values that we can show to any user.
|
|
1040
1167
|
|
|
@@ -1099,7 +1226,7 @@ Notably, fields come in different types, which may look and act differently in t
|
|
|
1099
1226
|
| `password` | Displays entered characters as hidden, accepts text input. Does not accept input from previous steps. |
|
|
1100
1227
|
| `copy` | Does not allow users enter data. Shows the value of the Markdown-formatted Help Text for the field as a rich text note in the Zap editor. Good for important notices to users. |
|
|
1101
1228
|
|
|
1102
|
-
You can find more details on the different field schema options at [our Field Schema](https://github.com/zapier/zapier-platform/blob/
|
|
1229
|
+
You can find more details on the different field schema options at [our Field Schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#fieldschema).
|
|
1103
1230
|
|
|
1104
1231
|
### Custom/Dynamic Fields
|
|
1105
1232
|
|
|
@@ -1494,7 +1621,7 @@ You can see examples of computed fields in the [OAuth2](#oauth2) or [Session Aut
|
|
|
1494
1621
|
|
|
1495
1622
|
### Nested & Children (Line Item) Fields
|
|
1496
1623
|
|
|
1497
|
-
When your action needs to accept an array of items, you can include an input field with the `children` attribute. The `children` attribute accepts a list of [fields](https://github.com/zapier/zapier-platform/blob/
|
|
1624
|
+
When your action needs to accept an array of items, you can include an input field with the `children` attribute. The `children` attribute accepts a list of [fields](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#fieldschema) that can be input for each item in this array.
|
|
1498
1625
|
|
|
1499
1626
|
```js
|
|
1500
1627
|
const App = {
|
|
@@ -1540,7 +1667,7 @@ Output Fields are optional, but can be used to:
|
|
|
1540
1667
|
- Define friendly labels for the returned fields. By default, we will *humanize* for example `my_key` as *My Key*.
|
|
1541
1668
|
- Make sure that custom fields that may not be found in every live sample and - since they're custom to the connected account - cannot be defined in the static sample, can still be mapped.
|
|
1542
1669
|
|
|
1543
|
-
The [schema](https://github.com/zapier/zapier-platform/blob/
|
|
1670
|
+
The [schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#fieldschema) for `outputFields` is shared with `inputFields` but only the `key` and `required` properties are relevant.
|
|
1544
1671
|
|
|
1545
1672
|
Custom/Dynamic Output Fields are defined in the same way as [Custom/Dynamic Input Fields](#customdynamic-fields).
|
|
1546
1673
|
|
|
@@ -1896,7 +2023,7 @@ module.exports = {
|
|
|
1896
2023
|
};
|
|
1897
2024
|
```
|
|
1898
2025
|
|
|
1899
|
-
Read more in the [REST hook example](https://github.com/zapier/zapier-platform/blob/
|
|
2026
|
+
Read more in the [REST hook example](https://github.com/zapier/zapier-platform/blob/main/example-apps/rest-hooks/triggers/recipe.js).
|
|
1900
2027
|
|
|
1901
2028
|
### `bundle.subscribeData`
|
|
1902
2029
|
|
|
@@ -1904,7 +2031,7 @@ Read more in the [REST hook example](https://github.com/zapier/zapier-platform/b
|
|
|
1904
2031
|
|
|
1905
2032
|
This is an object that contains the data you returned from the `performSubscribe` function. It should contain whatever information you need send a `DELETE` request to your server to stop sending webhooks to Zapier.
|
|
1906
2033
|
|
|
1907
|
-
Read more in the [REST hook example](https://github.com/zapier/zapier-platform/blob/
|
|
2034
|
+
Read more in the [REST hook example](https://github.com/zapier/zapier-platform/blob/main/example-apps/rest-hooks/triggers/recipe.js).
|
|
1908
2035
|
|
|
1909
2036
|
## Environment
|
|
1910
2037
|
|
|
@@ -2212,7 +2339,7 @@ Here is the full request lifecycle when you call `z.request({...})`:
|
|
|
2212
2339
|
|
|
2213
2340
|
The resulting response object is returned from `z.request()`.
|
|
2214
2341
|
|
|
2215
|
-
> Example App: check out https://github.com/zapier/zapier-platform/tree/
|
|
2342
|
+
> Example App: check out https://github.com/zapier/zapier-platform/tree/main/example-apps/middleware for a working example app using HTTP middleware.
|
|
2216
2343
|
|
|
2217
2344
|
#### Error Response Handling
|
|
2218
2345
|
|
|
@@ -2259,7 +2386,7 @@ This behavior has changed periodically across major versions, which changes how/
|
|
|
2259
2386
|
|
|
2260
2387
|

|
|
2261
2388
|
|
|
2262
|
-
Ensure you're handling errors correctly for your platform version. The latest released version is **
|
|
2389
|
+
Ensure you're handling errors correctly for your platform version. The latest released version is **14.0.0**.
|
|
2263
2390
|
|
|
2264
2391
|
### HTTP Request Options
|
|
2265
2392
|
|
|
@@ -2402,7 +2529,7 @@ const App = {
|
|
|
2402
2529
|
// don't forget to register hydrators here!
|
|
2403
2530
|
// it can be imported from any module
|
|
2404
2531
|
hydrators: {
|
|
2405
|
-
getMovieDetails
|
|
2532
|
+
getMovieDetails,
|
|
2406
2533
|
},
|
|
2407
2534
|
|
|
2408
2535
|
triggers: {
|
|
@@ -2544,7 +2671,7 @@ module.exports = App;
|
|
|
2544
2671
|
|
|
2545
2672
|
```
|
|
2546
2673
|
|
|
2547
|
-
> To create a new integration for handling files, run `zapier init [your app name] --template files`. You can also check out our working example app [here](https://github.com/zapier/zapier-platform/tree/
|
|
2674
|
+
> To create a new integration for handling files, run `zapier init [your app name] --template files`. You can also check out our working example app [here](https://github.com/zapier/zapier-platform/tree/main/example-apps/files).
|
|
2548
2675
|
|
|
2549
2676
|
|
|
2550
2677
|
## Logging
|
|
@@ -2696,15 +2823,12 @@ Example: `throw new z.errors.RefreshAuthError();`
|
|
|
2696
2823
|
### Handling Throttled Requests
|
|
2697
2824
|
|
|
2698
2825
|
Since v11.2.0, there are two types of errors that can cause Zapier to throttle an operation and retry at a later time.
|
|
2699
|
-
This is useful if the API you're interfacing with
|
|
2826
|
+
This is useful if the API you're interfacing with reports it is receiving too many requests, often indicated by
|
|
2700
2827
|
receiving a response status code of 429.
|
|
2701
2828
|
|
|
2702
2829
|
If a response receives a status code of 429 and is not caught, Zapier will re-attempt the operation after a delay.
|
|
2703
|
-
The delay can be customized by the server response containing a
|
|
2704
|
-
[Retry-After](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header
|
|
2705
|
-
|
|
2706
|
-
Another way to request Zapier retry an operation is to throw a `ThrottledError`, which may also optionally specify a
|
|
2707
|
-
delay in seconds:
|
|
2830
|
+
The delay can be customized by the server response containing a specific
|
|
2831
|
+
[Retry-After](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header in your error response or with a specified time delay in seconds using a `ThrottledError`:
|
|
2708
2832
|
|
|
2709
2833
|
```js
|
|
2710
2834
|
const yourAfterResponse = (resp) => {
|
|
@@ -2714,6 +2838,9 @@ const yourAfterResponse = (resp) => {
|
|
|
2714
2838
|
return resp;
|
|
2715
2839
|
};
|
|
2716
2840
|
```
|
|
2841
|
+
Instead of a user’s Zap erroring and halting, the request will be repeatedly retried at the specified time.
|
|
2842
|
+
|
|
2843
|
+
For throttled requests that occur during processing of a webhook trigger's perform, before results are produced; there is a max retry delay of 300 seconds and a default delay of 60 seconds if none is specified. For webhook processing only, if a request during the retry attempt is also throttled, it will not be re-attempted again.
|
|
2717
2844
|
|
|
2718
2845
|
## Testing
|
|
2719
2846
|
|
|
@@ -2914,7 +3041,7 @@ This makes it straightforward to integrate into your testing interface. For exam
|
|
|
2914
3041
|
```yaml
|
|
2915
3042
|
language: node_js
|
|
2916
3043
|
node_js:
|
|
2917
|
-
- "
|
|
3044
|
+
- "v16"
|
|
2918
3045
|
before_script: npm install -g zapier-platform-cli
|
|
2919
3046
|
script: CLIENT_ID=1234 CLIENT_SECRET=abcd zapier test
|
|
2920
3047
|
```
|
|
@@ -3097,17 +3224,17 @@ zapier push
|
|
|
3097
3224
|
|
|
3098
3225
|
There are a lot of details left out - check out the full example app for a working setup.
|
|
3099
3226
|
|
|
3100
|
-
> To create a new integration with Babel, run `zapier init [your app name] --template babel`. You can also check out our working example app [here](https://github.com/zapier/zapier-platform/tree/
|
|
3227
|
+
> To create a new integration with Babel, run `zapier init [your app name] --template babel`. You can also check out our working example app [here](https://github.com/zapier/zapier-platform/tree/main/example-apps/babel).
|
|
3101
3228
|
|
|
3102
3229
|
## FAQs
|
|
3103
3230
|
|
|
3104
3231
|
### Why doesn't Zapier support newer versions of Node.js?
|
|
3105
3232
|
|
|
3106
|
-
We run your code on AWS Lambda, which only supports a few [versions](https://docs.aws.amazon.com/lambda/latest/dg/programming-model.html) of Node
|
|
3233
|
+
We run your code on AWS Lambda, which only supports a few [versions](https://docs.aws.amazon.com/lambda/latest/dg/programming-model.html) of Node. Sometimes that doesn't include the latest version. Additionally, with thousands of apps running on the Zapier platform, we have to be sure upgrading to the latest Node version will not have a negative impact.
|
|
3107
3234
|
|
|
3108
3235
|
### How do I manually set the Node.js version to run my app with?
|
|
3109
3236
|
|
|
3110
|
-
Update your `zapier-platform-core` dependency in `package.json`. Each major version ties to a specific version of Node.js. You can find the mapping [here](https://github.com/zapier/zapier-platform/blob/
|
|
3237
|
+
Update your `zapier-platform-core` dependency in `package.json`. Each major version ties to a specific version of Node.js. You can find the mapping [here](https://github.com/zapier/zapier-platform/blob/main/packages/cli/src/version-store.js). We only support the version(s) supported by [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/programming-model.html).
|
|
3111
3238
|
|
|
3112
3239
|
**IMPORTANT CAVEAT**: AWS periodically deprecates Node versions as they reach EOL. They announce this[on their blog](https://aws.amazon.com/blogs/developer/node-js-6-is-approaching-end-of-life-upgrade-your-aws-lambda-functions-to-the-node-js-10-lts/). Similar info and dates are available on [github](https://github.com/nodejs/Release). Well before this date, we'll have a version of `core` that targets the newer Node version.
|
|
3113
3240
|
|
|
@@ -3310,7 +3437,7 @@ const performWithoutAsync = (z, bundle) => {
|
|
|
3310
3437
|
return z.request(
|
|
3311
3438
|
'https://5ae7ad3547436a00143e104d.mockapi.io/api/recipes',
|
|
3312
3439
|
{
|
|
3313
|
-
params: { cursor
|
|
3440
|
+
params: { cursor }, // if cursor is null, it's ignored here
|
|
3314
3441
|
}
|
|
3315
3442
|
);
|
|
3316
3443
|
})
|
|
@@ -3336,7 +3463,7 @@ const performWithAsync = async (z, bundle) => {
|
|
|
3336
3463
|
{
|
|
3337
3464
|
// if cursor is null, it's sent as an empty query
|
|
3338
3465
|
// param and should be ignored by the server
|
|
3339
|
-
params: { cursor
|
|
3466
|
+
params: { cursor },
|
|
3340
3467
|
}
|
|
3341
3468
|
);
|
|
3342
3469
|
|
|
@@ -3350,7 +3477,7 @@ const performWithAsync = async (z, bundle) => {
|
|
|
3350
3477
|
|
|
3351
3478
|
Cursors are stored per-zap and last about an hour. Per the above, make sure to only include the cursor if `bundle.meta.page !== 0`, so you don't accidentally reuse a cursor from a previous poll.
|
|
3352
3479
|
|
|
3353
|
-
Lastly, you need to set `canPaginate` to `true` in your polling definition (per the [schema](https://github.com/zapier/zapier-platform/blob/
|
|
3480
|
+
Lastly, you need to set `canPaginate` to `true` in your polling definition (per the [schema](https://github.com/zapier/zapier-platform/blob/main/packages/schema/docs/build/schema.md#basicpollingoperationschema)) for the `z.cursor` methods to work as expected.
|
|
3354
3481
|
|
|
3355
3482
|
<a id="dedup"></a>
|
|
3356
3483
|
### How does deduplication work?
|
|
@@ -3384,9 +3511,9 @@ InvalidParameterValueException An error occurred (InvalidParameterValueException
|
|
|
3384
3511
|
|
|
3385
3512
|
... then you need to update your `zapier-platform-core` dependency to a non-deprecated version that uses a newer version of Node.js. Complete the following instructions as soon as possible:
|
|
3386
3513
|
|
|
3387
|
-
1. Edit `package.json` to depend on a later major version of `zapier-platform-core`. There's a list of all breaking changes (marked with a :exclamation:) in the [changelog](https://github.com/zapier/zapier-platform/blob/
|
|
3514
|
+
1. Edit `package.json` to depend on a later major version of `zapier-platform-core`. There's a list of all breaking changes (marked with a :exclamation:) in the [changelog](https://github.com/zapier/zapier-platform/blob/main/CHANGELOG.md).
|
|
3388
3515
|
2. Increment the `version` property in `package.json`
|
|
3389
|
-
3. Ensure you're using version `
|
|
3516
|
+
3. Ensure you're using version `v16` (or greater) of node locally (`node -v`). Use [nvm](https://github.com/nvm-sh/nvm) to use a different one if need be.
|
|
3390
3517
|
4. Run `rm -rf node_modules && npm i` to get a fresh copy of everything
|
|
3391
3518
|
5. Run `zapier test` to ensure your tests still pass
|
|
3392
3519
|
6. Run `zapier push`
|
|
@@ -3437,9 +3564,9 @@ Follow those instructions to enable completion for `zapier` commands and flags!
|
|
|
3437
3564
|
|
|
3438
3565
|
The Zapier Platform consists of 3 npm packages that are released simultaneously.
|
|
3439
3566
|
|
|
3440
|
-
- [`zapier-platform-cli`](https://github.com/zapier/zapier-platform/tree/
|
|
3441
|
-
- [`zapier-platform-core`](https://github.com/zapier/zapier-platform/tree/
|
|
3442
|
-
- [`zapier-platform-schema`](https://github.com/zapier/zapier-platform/tree/
|
|
3567
|
+
- [`zapier-platform-cli`](https://github.com/zapier/zapier-platform/tree/main/packages/cli) is the code that powers the `zapier` command. You use it most commonly with the `test`, `scaffold`, and `push` commands. It's installed with `npm install -g zapier-platform-cli` and does not correspond to a particular app.
|
|
3568
|
+
- [`zapier-platform-core`](https://github.com/zapier/zapier-platform/tree/main/packages/core) is what allows your app to interact with Zapier. It holds the `z` object and app tester code. Your app depends on a specific version of `zapier-platform-core` in the `package.json` file. It's installed via `npm install` along with the rest of your app's dependencies.
|
|
3569
|
+
- [`zapier-platform-schema`](https://github.com/zapier/zapier-platform/tree/main/packages/schema) enforces app structure behind the scenes. It's a dependency of `core`, so it will be installed automatically.
|
|
3443
3570
|
|
|
3444
3571
|
To learn more about the structure of the code (especially if you're interested in contributing), check out the `ARCHITECTURE.md` file(s).
|
|
3445
3572
|
|
|
@@ -3447,12 +3574,12 @@ To learn more about the structure of the code (especially if you're interested i
|
|
|
3447
3574
|
|
|
3448
3575
|
The Zapier platform and its tools are under active development. While you don't need to install every release, we release new versions because they are better than the last. We do our best to adhere to [Semantic Versioning](https://semver.org/) wherein we won't break your code unless there's a `major` release. Otherwise, we're just fixing bugs (`patch`) and adding features (`minor`).
|
|
3449
3576
|
|
|
3450
|
-
Broadly speaking, all releases will continue to work indefinitely. While you never *have* to upgrade your app's `zapier-platform-core` dependency, we recommend keeping an eye on the [changelog](https://github.com/zapier/zapier-platform/blob/
|
|
3577
|
+
Broadly speaking, all releases will continue to work indefinitely. While you never *have* to upgrade your app's `zapier-platform-core` dependency, we recommend keeping an eye on the [changelog](https://github.com/zapier/zapier-platform/blob/main/CHANGELOG.md) to see what new features and bug fixes are available.
|
|
3451
3578
|
|
|
3452
3579
|
For more info about which Node versions are supported, see [the faq](#how-do-i-manually-set-the-nodejs-version-to-run-my-app-with).
|
|
3453
3580
|
|
|
3454
3581
|
<!-- TODO: if we decouple releases, change this -->
|
|
3455
|
-
The most recently released version of `cli` and `core` is **
|
|
3582
|
+
The most recently released version of `cli` and `core` is **14.0.0**. You can see the versions you're working with by running `zapier -v`.
|
|
3456
3583
|
|
|
3457
3584
|
To update `cli`, run `npm install -g zapier-platform-cli`.
|
|
3458
3585
|
|
|
@@ -3468,4 +3595,4 @@ You can get help by either emailing `partners@zapier.com` or by [joining our dev
|
|
|
3468
3595
|
|
|
3469
3596
|
## Developing on the CLI
|
|
3470
3597
|
|
|
3471
|
-
See [CONTRIBUTING.md](https://github.com/zapier/zapier-platform/blob/
|
|
3598
|
+
See [CONTRIBUTING.md](https://github.com/zapier/zapier-platform/blob/main/CONTRIBUTING.md).
|