zapier-platform-cli 15.5.1 → 15.5.2

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 CHANGED
@@ -1421,6 +1421,7 @@ The method `z.dehydrate(func, inputData)` has two required arguments:
1421
1421
 
1422
1422
  * `func` - the function to call to fetch the extra data. Can be any raw `function`, defined in the file doing the dehydration or imported from another part of your app. You must also register the function in the app's `hydrators` property. Note that since v10.1.0, the maximum payload size to pass to `z.dehydrate` / `z.dehydrateFile` is 6KB.
1423
1423
  * `inputData` - this is an object that contains things like a `path` or `id` - whatever you need to load data on the other side
1424
+ * A known limitation of hydration is a 5 minute cache if the hydration call is made with identical `inputData` within that timeframe. To workaround this cache for records triggering hydration in close succession, include a unique value in the `inputData`, for example a `timestamp` in addition to the record `id`.
1424
1425
 
1425
1426
  > **Why do I need to register my functions?** Because of how JavaScript works with its module system, we need an explicit handle on the function that can be accessed from the App definition without trying to "automagically" (and sometimes incorrectly) infer code locations.
1426
1427
 
package/README.md CHANGED
@@ -22,7 +22,7 @@ You may find some documents on the Zapier site duplicate or outdated. The most u
22
22
 
23
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 (**15.5.1**), as of this writing. If you're using an older version of the CLI, you may want to check out these historical releases:
25
+ This doc describes the latest CLI version (**15.5.2**), 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
27
  - CLI Docs: [14.x](https://github.com/zapier/zapier-platform/blob/zapier-platform-cli@14.1.2/packages/cli/README.md), [13.x](https://github.com/zapier/zapier-platform/blob/zapier-platform-cli@13.0.0/packages/cli/README.md)
28
28
  - CLI Reference: [14.x](https://github.com/zapier/zapier-platform/blob/zapier-platform-cli@14.1.2/packages/cli/docs/cli.md), [13.x](https://github.com/zapier/zapier-platform/blob/zapier-platform-cli@13.0.0/packages/cli/docs/cli.md)
@@ -2465,7 +2465,7 @@ This behavior has changed periodically across major versions, which changes how/
2465
2465
 
2466
2466
  ![](https://cdn.zappy.app/e835d9beca1b6489a065d51a381613f3.png)
2467
2467
 
2468
- Ensure you're handling errors correctly for your platform version. The latest released version is **15.5.1**.
2468
+ Ensure you're handling errors correctly for your platform version. The latest released version is **15.5.2**.
2469
2469
 
2470
2470
  ### HTTP Request Options
2471
2471
 
@@ -2573,6 +2573,7 @@ The method `z.dehydrate(func, inputData)` has two required arguments:
2573
2573
 
2574
2574
  * `func` - the function to call to fetch the extra data. Can be any raw `function`, defined in the file doing the dehydration or imported from another part of your app. You must also register the function in the app's `hydrators` property. Note that since v10.1.0, the maximum payload size to pass to `z.dehydrate` / `z.dehydrateFile` is 6KB.
2575
2575
  * `inputData` - this is an object that contains things like a `path` or `id` - whatever you need to load data on the other side
2576
+ * A known limitation of hydration is a 5 minute cache if the hydration call is made with identical `inputData` within that timeframe. To workaround this cache for records triggering hydration in close succession, include a unique value in the `inputData`, for example a `timestamp` in addition to the record `id`.
2576
2577
 
2577
2578
  > **Why do I need to register my functions?** Because of how JavaScript works with its module system, we need an explicit handle on the function that can be accessed from the App definition without trying to "automagically" (and sometimes incorrectly) infer code locations.
2578
2579
 
@@ -3638,7 +3639,7 @@ Broadly speaking, all releases will continue to work indefinitely. While you nev
3638
3639
  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).
3639
3640
 
3640
3641
  <!-- TODO: if we decouple releases, change this -->
3641
- The most recently released version of `cli` and `core` is **15.5.1**. You can see the versions you're working with by running `zapier -v`.
3642
+ The most recently released version of `cli` and `core` is **15.5.2**. You can see the versions you're working with by running `zapier -v`.
3642
3643
 
3643
3644
  To update `cli`, run `npm install -g zapier-platform-cli`.
3644
3645
 
@@ -1 +1 @@
1
- {"version":"15.5.1","commands":{"analytics":{"id":"analytics","description":"Show the status of the analytics that are collected. Also used to change what is collected.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier analytics --mode enabled"],"flags":{"mode":{"name":"mode","type":"option","char":"m","description":"Choose how much information to share. Anonymous mode drops the OS type and Zapier user id, but keeps command info. Identifying information is used only for debugging purposes.","options":["enabled","anonymous","disabled"]},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"build":{"id":"build","description":"Build a pushable zip from the current directory.\n\nThis command does the following:\n\n* Creates a temporary folder\n* Copies all code into the temporary folder\n* Adds an entry point: `zapierwrapper.js`\n* Generates and validates app definition.\n* Detects dependencies via browserify (optional, on by default)\n* Zips up all needed `.js` files. If you want to include more files, add a \"includeInBuild\" property (array with strings of regexp paths) to your `.zapierapprc`.\n* Moves the zip to `build/build.zip` and `build/source.zip` and deletes the temp folder\n\nThis command is typically followed by `zapier upload`.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"disable-dependency-detection":{"name":"disable-dependency-detection","type":"boolean","description":"Disable \"smart\" file inclusion. By default, Zapier only includes files that are required by `index.js`. If you (or your dependencies) require files dynamically (such as with `require(someVar)`), then you may see \"Cannot find module\" errors. Disabling this may make your `build.zip` too large. If that's the case, try using the `includeInBuild` option in your `.zapierapprc`. See the docs about `includeInBuild` for more info.","allowNo":false},"skip-npm-install":{"name":"skip-npm-install","type":"boolean","description":"Skips installing a fresh copy of npm dependencies on build. Helpful for using `yarn` or local copies of dependencies.","hidden":true,"allowNo":false},"skip-validation":{"name":"skip-validation","type":"boolean","description":"Skips local pre-push validation checks, and remote validation check of the CLI app's schema and AppVersion integrity.","hidden":true,"allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"convert":{"id":"convert","description":"Convert a Visual Builder integration to a CLI integration.\n\nThe resulting CLI integration will be identical to its Visual Builder version and ready to push and use immediately!\n\nIf you re-run this command on an existing directory it will leave existing files alone and not clobber them.\n\nYou'll need to do a `zapier push` before the new version is visible in the editor, but otherwise you're good to go.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"version":{"name":"version","type":"option","char":"v","description":"Convert a specific version. Required when converting a Visual Builder integration.","required":true},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"integrationId","description":"To get the integration/app ID, go to \"https://developer.zapier.com\", click on an integration, and copy the number directly after \"/app/\" in the URL.","required":true},{"name":"path","description":"Relative to your current path - IE: `.` for current directory.","required":true}]},"deprecate":{"id":"deprecate","description":"Mark a non-production version of your integration as deprecated, with removal by a certain date.\n\nUse this when an integration version will not be supported or start breaking at a known date.\n\nZapier will send an email warning users of the deprecation once a date is set, they'll start seeing it as \"Deprecated\" in the UI, and once the deprecation date arrives, if the Zaps weren't updated, they'll be paused and the users will be emailed again explaining what happened.\n\nAfter the deprecation date has passed it will be safe to delete that integration version.\n\nDo not use this if you have non-breaking changes, such as fixing help text.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier deprecate 1.2.3 2011-10-01"],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"version","description":"The version to deprecate.","required":true},{"name":"date","description":"The date (YYYY-MM-DD) when Zapier will make the specified version unavailable.","required":true}]},"describe":{"id":"describe","description":"Describe the current integration.\n\nThis command prints a human readable enumeration of your integrations's\ntriggers, searches, and creates as seen by Zapier. Useful to understand how your\nresources convert and relate to different actions.\n\n* **Noun**: your action's noun\n* **Label**: your action's label\n* **Resource**: the resource (if any) this action is tied to\n* **Available Methods**: testable methods for this action","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"history":{"id":"history","description":"Get the history of your integration.\n\nHistory includes all the changes made over the lifetime of your integration. This includes everything from creation, updates, migrations, admins, and invitee changes, as well as who made the change and when.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"init":{"id":"init","description":"Initialize a new Zapier integration with a project template.\n\nAfter running this, you'll have a new integration in the specified directory. If you re-run this command on an existing directory, it will prompt before overwriting any existing files.\n\nThis doesn't register or deploy the integration with Zapier - try the `zapier register` and `zapier push` commands for that!","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier init myapp","zapier init ./path/myapp --template oauth2"],"flags":{"template":{"name":"template","type":"option","char":"t","description":"The template to start your integration with.","options":["basic-auth","callback","custom-auth","digest-auth","dynamic-dropdown","files","minimal","oauth1-trello","oauth2","search-or-create","session-auth","typescript"]},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"path","description":"Where to create the new integration. If the directory doesn't exist, it will be created. If the directory isn't empty, we'll ask for confirmation","required":true}]},"integrations":{"id":"integrations","description":"List integrations you have admin access to.\n\nThis command also checks the current directory for a linked integration.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["apps"],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"jobs":{"id":"jobs","description":"Lists ongoing migration or promotion jobs for the current integration.\n\nA job represents a background process that will be queued up when users execute a \"migrate\" or \"promote\" command for the current integration.\n\nEach job will be added to the end of a queue of \"promote\" and \"migration\" jobs where the \"Job Stage\" will then be initialized with \"requested\".\n\nJob stages will then move to \"estimating\", \"in_progress\" and finally one of four \"end\" stages: \"complete\", \"aborted\", \"errored\" or \"paused\".\n\nJob times will vary as it depends on the size of the queue and how many users your integration has.\n\nJobs are returned from oldest to newest.\n","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier jobs"],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"link":{"id":"link","description":"Link the current directory with an existing integration.\n\nThis command generates a `.zapierapprc` file in the directory in which it's ran. This file ties this code to an integration and is referenced frequently during `push` and `validate` operations. This file should be checked into source control.\n\nIf you're starting an integration from scratch, use `zapier init` instead.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"login":{"id":"login","description":"Configure your `~/.zapierrc` with a deploy key.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"sso":{"name":"sso","type":"boolean","char":"s","description":"Use this flag if you log into Zapier a Single Sign-On (SSO) button and don't have a Zapier password.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"logout":{"id":"logout","description":"Deactivate your active deploy key and reset `~/.zapierrc`.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"logs":{"id":"logs","description":"Print recent logs.\n\nLogs are created when your integration is run as part of a Zap. They come from explicit calls to `z.console.log()`, usage of `z.request()`, and any runtime errors.\n\nThis won't show logs from running locally with `zapier test`, since those never hit our server.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"version":{"name":"version","type":"option","char":"v","description":"Filter logs to the specified version."},"status":{"name":"status","type":"option","char":"s","description":"Filter logs to only see errors or successes","options":["any","success","error"],"default":"any"},"type":{"name":"type","type":"option","char":"t","description":"See logs of the specified type","options":["console","bundle","http"],"default":"console"},"detailed":{"name":"detailed","type":"boolean","description":"See extra info, like request/response body and headers.","allowNo":false},"user":{"name":"user","type":"option","char":"u","description":"Only show logs for this user. Defaults to your account.","default":"me"},"limit":{"name":"limit","type":"option","description":"Cap the number of logs returned. Max is 50 (also the default)","default":50},"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"migrate":{"id":"migrate","description":"Migrate a percentage of users or a single user from one version of your integration to another.\n\nStart a migration to move users between different versions of your integration. You may also \"revert\" by simply swapping the from/to verion strings in the command line arguments (i.e. `zapier migrate 1.0.1 1.0.0`).\n\n**Only use this command to migrate users between non-breaking versions, use `zapier deprecate` if you have breaking changes!**\n\nMigration time varies based on the number of affected Zaps. Be patient and check `zapier jobs` to track the status. Or use `zapier history` if you want to see older jobs.\n\nSince a migration is only for non-breaking changes, users are not emailed about the update/migration. It will be a transparent process for them.\n\nWe recommend migrating a small subset of users first, via the percent argument, then watching error logs of the new version for any sort of odd behavior. When you feel confident there are no bugs, go ahead and migrate everyone. If you see unexpected errors, you can revert.\n\nYou can migrate a specific user's Zaps by using `--user` (i.e. `zapier migrate 1.0.0 1.0.1 --user=user@example.com`). This will migrate Zaps in any account the user is a member of where the following criteria is met.\n\n - The Zap is owned by the user.\n - The Zap is not shared.\n - The integration auth used is not shared.\n\nAlternatively, you can pass the `--account` flag, (i.e. `zapier migrate 1.0.0 1.0.1 --account=account@example.com`). This will migrate all users' Zaps, Private & Shared, within all accounts for which the specified user is a member.\n\n**The `--account` flag should be used cautiously as it can break shared Zaps for other users in Team or Company accounts.**\n\nYou cannot pass both `PERCENT` and `--user` or `--account`.\n\nYou cannot pass both `--user` and `--account`.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier migrate 1.0.0 1.0.1","zapier migrate 1.0.1 2.0.0 10","zapier migrate 2.0.0 2.0.1 --user=user@example.com","zapier migrate 2.0.0 2.0.1 --account=account@example.com"],"flags":{"user":{"name":"user","type":"option","description":"Migrates all of a users' Private Zaps within all accounts for which the specified user is a member"},"account":{"name":"account","type":"option","description":"Migrates all of a users' Zaps, Private & Shared, within all accounts for which the specified user is a member"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"fromVersion","description":"The version FROM which to migrate users.","required":true},{"name":"toVersion","description":"The version TO which to migrate users.","required":true},{"name":"percent","description":"Percentage (between 1 and 100) of users to migrate.","default":100}]},"promote":{"id":"promote","description":"Promote a specific version to public access.\n\nPromote an integration version into production (non-private) rotation, which means new users can use this integration version.\n\n* This **does** mark the version as the official public version - all other versions & users are grandfathered.\n* This does **NOT** build/upload or deploy a version to Zapier - you should `zapier push` first.\n* This does **NOT** move old users over to this version - `zapier migrate 1.0.0 1.0.1` does that.\n* This does **NOT** recommend old users stop using this version - `zapier deprecate 1.0.0 2017-01-01` does that.\n\nPromotes are an inherently safe operation for all existing users of your integration.\n\nIf your integration is private and passes our integration checks, this will give you a URL to a form where you can fill in additional information for your integration to go public. After reviewing, the Zapier team will approve to make it public if there are no issues or decline with feedback.\n\nCheck `zapier jobs` to track the status of the promotion. Or use `zapier history` if you want to see older jobs.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier promote 1.0.0"],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Automatically answer \"yes\" to any prompts. Useful if you want to avoid interactive prompts to run this command in CI.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"version","description":"The version you want to promote.","required":true}]},"push":{"id":"push","description":"Build and upload the current integration.\n\nThis command is the same as running `zapier build` and `zapier upload` in sequence. See those for more info.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"disable-dependency-detection":{"name":"disable-dependency-detection","type":"boolean","description":"Disable \"smart\" file inclusion. By default, Zapier only includes files that are required by `index.js`. If you (or your dependencies) require files dynamically (such as with `require(someVar)`), then you may see \"Cannot find module\" errors. Disabling this may make your `build.zip` too large. If that's the case, try using the `includeInBuild` option in your `.zapierapprc`. See the docs about `includeInBuild` for more info.","allowNo":false},"skip-npm-install":{"name":"skip-npm-install","type":"boolean","description":"Skips installing a fresh copy of npm dependencies on build. Helpful for using `yarn` or local copies of dependencies.","hidden":true,"allowNo":false},"skip-validation":{"name":"skip-validation","type":"boolean","description":"Skips local pre-push validation checks, and remote validation check of the CLI app's schema and AppVersion integrity.","hidden":true,"allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"register":{"id":"register","description":"Register a new integration in your account, or update the existing one if a `.zapierapprc` file is found.\n\nThis command creates a new integration and links it in the `./.zapierapprc` file. If `.zapierapprc` already exists, it will ask you if you want to update the currently-linked integration, as opposed to creating a new one.\n\nAfter registering a new integration, you can run `zapier push` to build and upload your integration for use in the Zapier editor. This will change `.zapierapprc`, which identifies this directory as holding code for a specific integration.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier register","zapier register \"My Cool Integration\"","zapier register \"My Cool Integration\" --desc \"My Cool Integration helps you integrate your apps with the apps that you need.\" --no-subscribe","zapier register \"My Cool Integration\" --url \"https://www.zapier.com\" --audience private --role employee --category marketing-automation","zapier register --subscribe"],"flags":{"desc":{"name":"desc","type":"option","char":"D","description":"A sentence describing your app in 140 characters or less, e.g. \"Trello is a team collaboration tool to organize tasks and keep projects on track.\""},"url":{"name":"url","type":"option","char":"u","description":"The homepage URL of your app, e.g., https://example.com."},"audience":{"name":"audience","type":"option","char":"a","description":"Are you building a public or private integration?"},"role":{"name":"role","type":"option","char":"r","description":"What is your relationship with the app you're integrating with Zapier?"},"category":{"name":"category","type":"option","char":"c","description":"How would you categorize your app? Choose the most appropriate option for your app's core features."},"subscribe":{"name":"subscribe","type":"boolean","char":"s","description":"Get tips and recommendations about this integration along with our monthly newsletter that details the performance of your integration and the latest Zapier news.","allowNo":true},"yes":{"name":"yes","type":"boolean","char":"y","description":"Assume yes for all yes/no prompts. This flag will also update an existing integration (as opposed to registering a new one) if a .zapierapprc file is found.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"title","description":"Your integration's public title. Asked interactively if not present."}]},"scaffold":{"id":"scaffold","description":"Add a starting trigger, create, search, or resource to your integration.\n\nThe first argument should be one of `trigger|search|create|resource` followed by the noun that this will act on (something like \"contact\" or \"deal\").\n\nThe scaffold command does two general things:\n\n* Creates a new file (such as `triggers/contact.js`)\n* Imports and registers it inside your `index.js`\n\nYou can mix and match several options to customize the created scaffold for your project.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier scaffold trigger contact","zapier scaffold search contact --dest=my_src/searches","zapier scaffold create contact --entry=src/index.js","zapier scaffold resource contact --force"],"flags":{"dest":{"name":"dest","type":"option","char":"d","description":"Specify the new file's directory. Use this flag when you want to create a different folder structure such as `src/triggers` instead of the default `triggers`. Defaults to `[triggers|searches|creates]/{noun}`."},"test-dest":{"name":"test-dest","type":"option","description":"Specify the new test file's directory. Use this flag when you want to create a different folder structure such as `src/triggers` instead of the default `triggers`. Defaults to `test/[triggers|searches|creates]/{noun}`."},"entry":{"name":"entry","type":"option","char":"e","description":"Supply the path to your integration's root (`index.js`). Only needed if your `index.js` is in a subfolder, like `src`.","default":"index.js"},"force":{"name":"force","type":"boolean","char":"f","description":"Should we overwrite an exisiting trigger/search/create file?","allowNo":false},"no-help":{"name":"no-help","type":"boolean","description":"When scaffolding, should we skip adding helpful intro comments? Useful if this isn't your first rodeo.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"actionType","required":true,"options":["trigger","search","create","resource"]},{"name":"noun","required":true}]},"test":{"id":"test","description":"Test your integration via the \"test\" script in your \"package.json\".\n\nThis command is a wrapper around `npm test` that also validates the structure of your integration and sets up extra environment variables.\n\nYou can pass any args/flags after a `--`; they will get forwarded onto your test script.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier test","zapier test --skip-validate -- -t 30000 --grep api","zapier test -- -fo --testNamePattern \"auth pass\""],"flags":{"skip-validate":{"name":"skip-validate","type":"boolean","description":"Forgo running `zapier validate` before tests are run. This will speed up tests if you're modifying functionality of an existing integration rather than adding new actions.","allowNo":false},"yarn":{"name":"yarn","type":"boolean","description":"Use `yarn` instead of `npm`. This happens automatically if there's a `yarn.lock` file, but you can manually force `yarn` if you run tests from a sub-directory.","allowNo":false},"pnpm":{"name":"pnpm","type":"boolean","description":"Use `pnpm` instead of `npm`. This happens automatically if there's a `pnpm-lock.yaml` file, but you can manually force `pnpm` if you run tests from a sub-directory.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"upload":{"id":"upload","description":"Upload the latest build of your integration to Zapier.\n\nThis command sends both build/build.zip and build/source.zip to Zapier for use.\n\nTypically we recommend using `zapier push`, which does a build and upload, rather than `upload` by itself.\n","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"validate":{"id":"validate","description":"Validate your integration.\n\nRun the standard validation routine powered by json-schema that checks your integration for any structural errors. This is the same routine that runs during `zapier build`, `zapier upload`, `zapier push` or even as a test in `zapier test`.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier validate","zapier validate --without-style","zapier validate --format json"],"flags":{"without-style":{"name":"without-style","type":"boolean","description":"Forgo pinging the Zapier server to run further checks.","allowNo":false},"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"versions":{"id":"versions","description":"List the versions of your integration available for use in the Zapier editor.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"cache:clear":{"id":"cache:clear","description":"Clear the cache data for a major version. \n\nThis command clears the cache data for a major version of your integration.\nThe job will be run in the background and may take some time to complete.\nYou can check `zapier history` to see the job status.\n","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier cache:clear","zapier cache:clear 2"],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"majorVersion","description":"(Optional) The cache data will be deleted for this major version. If not provided, you must pick from a list of major versions for this integration.","required":false}]},"delete:integration":{"id":"delete:integration","description":"Delete your integration (including all versions).\n\nThis only works if there are no active users or Zaps on any version. If you only want to delete certain versions, use the `zapier delete:version` command instead. It's unlikely that you'll be able to run this on an app that you've pushed publicly, since there are usually still users.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["delete:app"],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"delete:version":{"id":"delete:version","description":"Delete a specific version of your integration.\n\nThis only works if there are no users or Zaps on that version. You will probably need to have run `zapier migrate` and `zapier deprecate` before this command will work.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"version","description":"Specify the version to delete. It must have no users or Zaps.","required":true}]},"env:get":{"id":"env:get","description":"Get environment variables for a version.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier env:get 1.2.3"],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"version","description":"The version to get the environment for.","required":true}]},"env:set":{"id":"env:set","description":"Set environment variables for a version.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier env:set 1.2.3 SECRET=12345 OTHER=4321"],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"version","description":"The version to set the environment for. Values are copied forward when a new version is created, but this command will only ever affect the specified version.","required":true},{"name":"key-value pairs...","description":"The key-value pairs to set. Keys are case-insensitive. Each pair should be space separated and pairs should be separated by an `=`. For example: `A=123 B=456`"}]},"env:unset":{"id":"env:unset","description":"Unset environment variables for a version.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier env:unset 1.2.3 SECRET OTHER"],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"version","description":"The version to set the environment for.","required":true},{"name":"keys...","description":"The keys to unset. Keys are case-insensitive."}]},"team:add":{"id":"team:add","description":"Add a team member to your integration.\n\nThese users come in three levels:\n\n * `admin`, who can edit everything about the integration\n * `collaborator`, who has read-only access for the app, and will receive periodic email updates. These updates include quarterly health scores and more.\n * `subscriber`, who can't directly access the app, but will receive periodic email updates. These updates include quarterly health scores and more.\n\nTeam members can be freely added and removed.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["team:invite"],"examples":["zapier team:add bruce@wayne.com admin","zapier team:add robin@wayne.com collaborator \"Hey Robin, check out this app.\"","zapier team:add alfred@wayne.com subscriber \"Hey Alfred, check out this app.\""],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"email","description":"The user to be invited. If they don't have a Zapier account, they'll be prompted to create one.","required":true},{"name":"role","description":"The level the invited team member should be at. Admins can edit everything and get email updates. Collaborators have read-access to the app and get email updates. Subscribers only get email updates.","required":true,"options":["admin","collaborator","subscriber"]},{"name":"message","description":"A message sent in the email to your team member, if you need to provide context. Wrap the message in quotes to ensure spaces get saved."}]},"team:get":{"id":"team:get","description":"Get team members involved with your integration.\n\nThese users come in three levels:\n\n * `admin`, who can edit everything about the integration\n * `collaborator`, who has read-only access for the app, and will receive periodic email updates. These updates include quarterly health scores and more.\n * `subscriber`, who can't directly access the app, but will receive periodic email updates. These updates include quarterly health scores and more.\n\nUse the `zapier team:add` and `zapier team:remove` commands to modify your team.\n","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["team:list"],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"team:remove":{"id":"team:remove","description":"Remove a team member from all versions of your integration.\n\nAdmins will immediately lose write access to the integration.\nCollaborators will immediately lose read access to the integration.\nSubscribers won't receive future email updates.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["team:delete"],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"users:add":{"id":"users:add","description":"Add a user to some or all versions of your integration.\n\nWhen this command is run, we'll send an email to the user inviting them to try your integration. You can track the status of that invite using the `zapier users:get` command.\n\nInvited users will be able to see your integration's name, logo, and description. They'll also be able to create Zaps using any available triggers and actions.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["users:invite"],"examples":["zapier users:add bruce@wayne.com","zapier users:add alfred@wayne.com 1.2.3"],"flags":{"force":{"name":"force","type":"boolean","char":"f","description":"Skip confirmation. Useful for running programatically.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"email","description":"The user to be invited. If they don't have a Zapier account, they'll be prompted to create one.","required":true},{"name":"version","description":"A version string (like 1.2.3). Optional, used only if you want to invite a user to a specific version instead of all versions."}]},"users:get":{"id":"users:get","description":"Get a list of users who have been invited to your integration.\n\nNote that this list of users is NOT a comprehensive list of everyone who is using your integration. It only includes users who were invited directly by email (using the `\u001b[36mzapier users:add\u001b[39m` command or the web UI). Users who joined by clicking links generated using the `\u001b[36mzapier user:links\u001b[39m` command won't show up here.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["users:list"],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"users:links":{"id":"users:links","description":"Get a list of links that are used to invite users to your integration.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"users:remove":{"id":"users:remove","description":"Remove a user from all versions of your integration.\n\nWhen this command is run, their Zaps will immediately turn off. They won't be able to use your app again until they're re-invited or it has gone public. In practice, this command isn't run often as it's very disruptive to users.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["users:delete"],"flags":{"force":{"name":"force","type":"boolean","char":"f","description":"Skips confirmation. Useful for running programatically.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"email","description":"The user to be removed.","required":true}]}}}
1
+ {"version":"15.5.2","commands":{"analytics":{"id":"analytics","description":"Show the status of the analytics that are collected. Also used to change what is collected.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier analytics --mode enabled"],"flags":{"mode":{"name":"mode","type":"option","char":"m","description":"Choose how much information to share. Anonymous mode drops the OS type and Zapier user id, but keeps command info. Identifying information is used only for debugging purposes.","options":["enabled","anonymous","disabled"]},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"build":{"id":"build","description":"Build a pushable zip from the current directory.\n\nThis command does the following:\n\n* Creates a temporary folder\n* Copies all code into the temporary folder\n* Adds an entry point: `zapierwrapper.js`\n* Generates and validates app definition.\n* Detects dependencies via browserify (optional, on by default)\n* Zips up all needed `.js` files. If you want to include more files, add a \"includeInBuild\" property (array with strings of regexp paths) to your `.zapierapprc`.\n* Moves the zip to `build/build.zip` and `build/source.zip` and deletes the temp folder\n\nThis command is typically followed by `zapier upload`.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"disable-dependency-detection":{"name":"disable-dependency-detection","type":"boolean","description":"Disable \"smart\" file inclusion. By default, Zapier only includes files that are required by `index.js`. If you (or your dependencies) require files dynamically (such as with `require(someVar)`), then you may see \"Cannot find module\" errors. Disabling this may make your `build.zip` too large. If that's the case, try using the `includeInBuild` option in your `.zapierapprc`. See the docs about `includeInBuild` for more info.","allowNo":false},"skip-npm-install":{"name":"skip-npm-install","type":"boolean","description":"Skips installing a fresh copy of npm dependencies on build. Helpful for using `yarn` or local copies of dependencies.","hidden":true,"allowNo":false},"skip-validation":{"name":"skip-validation","type":"boolean","description":"Skips local pre-push validation checks, and remote validation check of the CLI app's schema and AppVersion integrity.","hidden":true,"allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"convert":{"id":"convert","description":"Convert a Visual Builder integration to a CLI integration.\n\nThe resulting CLI integration will be identical to its Visual Builder version and ready to push and use immediately!\n\nIf you re-run this command on an existing directory it will leave existing files alone and not clobber them.\n\nYou'll need to do a `zapier push` before the new version is visible in the editor, but otherwise you're good to go.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"version":{"name":"version","type":"option","char":"v","description":"Convert a specific version. Required when converting a Visual Builder integration.","required":true},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"integrationId","description":"To get the integration/app ID, go to \"https://developer.zapier.com\", click on an integration, and copy the number directly after \"/app/\" in the URL.","required":true},{"name":"path","description":"Relative to your current path - IE: `.` for current directory.","required":true}]},"deprecate":{"id":"deprecate","description":"Mark a non-production version of your integration as deprecated, with removal by a certain date.\n\nUse this when an integration version will not be supported or start breaking at a known date.\n\nZapier will send an email warning users of the deprecation once a date is set, they'll start seeing it as \"Deprecated\" in the UI, and once the deprecation date arrives, if the Zaps weren't updated, they'll be paused and the users will be emailed again explaining what happened.\n\nAfter the deprecation date has passed it will be safe to delete that integration version.\n\nDo not use this if you have non-breaking changes, such as fixing help text.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier deprecate 1.2.3 2011-10-01"],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"version","description":"The version to deprecate.","required":true},{"name":"date","description":"The date (YYYY-MM-DD) when Zapier will make the specified version unavailable.","required":true}]},"describe":{"id":"describe","description":"Describe the current integration.\n\nThis command prints a human readable enumeration of your integrations's\ntriggers, searches, and creates as seen by Zapier. Useful to understand how your\nresources convert and relate to different actions.\n\n* **Noun**: your action's noun\n* **Label**: your action's label\n* **Resource**: the resource (if any) this action is tied to\n* **Available Methods**: testable methods for this action","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"history":{"id":"history","description":"Get the history of your integration.\n\nHistory includes all the changes made over the lifetime of your integration. This includes everything from creation, updates, migrations, admins, and invitee changes, as well as who made the change and when.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"init":{"id":"init","description":"Initialize a new Zapier integration with a project template.\n\nAfter running this, you'll have a new integration in the specified directory. If you re-run this command on an existing directory, it will prompt before overwriting any existing files.\n\nThis doesn't register or deploy the integration with Zapier - try the `zapier register` and `zapier push` commands for that!","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier init myapp","zapier init ./path/myapp --template oauth2"],"flags":{"template":{"name":"template","type":"option","char":"t","description":"The template to start your integration with.","options":["basic-auth","callback","custom-auth","digest-auth","dynamic-dropdown","files","minimal","oauth1-trello","oauth2","search-or-create","session-auth","typescript"]},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"path","description":"Where to create the new integration. If the directory doesn't exist, it will be created. If the directory isn't empty, we'll ask for confirmation","required":true}]},"integrations":{"id":"integrations","description":"List integrations you have admin access to.\n\nThis command also checks the current directory for a linked integration.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["apps"],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"jobs":{"id":"jobs","description":"Lists ongoing migration or promotion jobs for the current integration.\n\nA job represents a background process that will be queued up when users execute a \"migrate\" or \"promote\" command for the current integration.\n\nEach job will be added to the end of a queue of \"promote\" and \"migration\" jobs where the \"Job Stage\" will then be initialized with \"requested\".\n\nJob stages will then move to \"estimating\", \"in_progress\" and finally one of four \"end\" stages: \"complete\", \"aborted\", \"errored\" or \"paused\".\n\nJob times will vary as it depends on the size of the queue and how many users your integration has.\n\nJobs are returned from oldest to newest.\n","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier jobs"],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"link":{"id":"link","description":"Link the current directory with an existing integration.\n\nThis command generates a `.zapierapprc` file in the directory in which it's ran. This file ties this code to an integration and is referenced frequently during `push` and `validate` operations. This file should be checked into source control.\n\nIf you're starting an integration from scratch, use `zapier init` instead.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"login":{"id":"login","description":"Configure your `~/.zapierrc` with a deploy key.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"sso":{"name":"sso","type":"boolean","char":"s","description":"Use this flag if you log into Zapier a Single Sign-On (SSO) button and don't have a Zapier password.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"logout":{"id":"logout","description":"Deactivate your active deploy key and reset `~/.zapierrc`.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"logs":{"id":"logs","description":"Print recent logs.\n\nLogs are created when your integration is run as part of a Zap. They come from explicit calls to `z.console.log()`, usage of `z.request()`, and any runtime errors.\n\nThis won't show logs from running locally with `zapier test`, since those never hit our server.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"version":{"name":"version","type":"option","char":"v","description":"Filter logs to the specified version."},"status":{"name":"status","type":"option","char":"s","description":"Filter logs to only see errors or successes","options":["any","success","error"],"default":"any"},"type":{"name":"type","type":"option","char":"t","description":"See logs of the specified type","options":["console","bundle","http"],"default":"console"},"detailed":{"name":"detailed","type":"boolean","description":"See extra info, like request/response body and headers.","allowNo":false},"user":{"name":"user","type":"option","char":"u","description":"Only show logs for this user. Defaults to your account.","default":"me"},"limit":{"name":"limit","type":"option","description":"Cap the number of logs returned. Max is 50 (also the default)","default":50},"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"migrate":{"id":"migrate","description":"Migrate a percentage of users or a single user from one version of your integration to another.\n\nStart a migration to move users between different versions of your integration. You may also \"revert\" by simply swapping the from/to verion strings in the command line arguments (i.e. `zapier migrate 1.0.1 1.0.0`).\n\n**Only use this command to migrate users between non-breaking versions, use `zapier deprecate` if you have breaking changes!**\n\nMigration time varies based on the number of affected Zaps. Be patient and check `zapier jobs` to track the status. Or use `zapier history` if you want to see older jobs.\n\nSince a migration is only for non-breaking changes, users are not emailed about the update/migration. It will be a transparent process for them.\n\nWe recommend migrating a small subset of users first, via the percent argument, then watching error logs of the new version for any sort of odd behavior. When you feel confident there are no bugs, go ahead and migrate everyone. If you see unexpected errors, you can revert.\n\nYou can migrate a specific user's Zaps by using `--user` (i.e. `zapier migrate 1.0.0 1.0.1 --user=user@example.com`). This will migrate Zaps in any account the user is a member of where the following criteria is met.\n\n - The Zap is owned by the user.\n - The Zap is not shared.\n - The integration auth used is not shared.\n\nAlternatively, you can pass the `--account` flag, (i.e. `zapier migrate 1.0.0 1.0.1 --account=account@example.com`). This will migrate all users' Zaps, Private & Shared, within all accounts for which the specified user is a member.\n\n**The `--account` flag should be used cautiously as it can break shared Zaps for other users in Team or Company accounts.**\n\nYou cannot pass both `PERCENT` and `--user` or `--account`.\n\nYou cannot pass both `--user` and `--account`.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier migrate 1.0.0 1.0.1","zapier migrate 1.0.1 2.0.0 10","zapier migrate 2.0.0 2.0.1 --user=user@example.com","zapier migrate 2.0.0 2.0.1 --account=account@example.com"],"flags":{"user":{"name":"user","type":"option","description":"Migrates all of a users' Private Zaps within all accounts for which the specified user is a member"},"account":{"name":"account","type":"option","description":"Migrates all of a users' Zaps, Private & Shared, within all accounts for which the specified user is a member"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"fromVersion","description":"The version FROM which to migrate users.","required":true},{"name":"toVersion","description":"The version TO which to migrate users.","required":true},{"name":"percent","description":"Percentage (between 1 and 100) of users to migrate.","default":100}]},"promote":{"id":"promote","description":"Promote a specific version to public access.\n\nPromote an integration version into production (non-private) rotation, which means new users can use this integration version.\n\n* This **does** mark the version as the official public version - all other versions & users are grandfathered.\n* This does **NOT** build/upload or deploy a version to Zapier - you should `zapier push` first.\n* This does **NOT** move old users over to this version - `zapier migrate 1.0.0 1.0.1` does that.\n* This does **NOT** recommend old users stop using this version - `zapier deprecate 1.0.0 2017-01-01` does that.\n\nPromotes are an inherently safe operation for all existing users of your integration.\n\nIf your integration is private and passes our integration checks, this will give you a URL to a form where you can fill in additional information for your integration to go public. After reviewing, the Zapier team will approve to make it public if there are no issues or decline with feedback.\n\nCheck `zapier jobs` to track the status of the promotion. Or use `zapier history` if you want to see older jobs.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier promote 1.0.0"],"flags":{"yes":{"name":"yes","type":"boolean","char":"y","description":"Automatically answer \"yes\" to any prompts. Useful if you want to avoid interactive prompts to run this command in CI.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"version","description":"The version you want to promote.","required":true}]},"push":{"id":"push","description":"Build and upload the current integration.\n\nThis command is the same as running `zapier build` and `zapier upload` in sequence. See those for more info.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"disable-dependency-detection":{"name":"disable-dependency-detection","type":"boolean","description":"Disable \"smart\" file inclusion. By default, Zapier only includes files that are required by `index.js`. If you (or your dependencies) require files dynamically (such as with `require(someVar)`), then you may see \"Cannot find module\" errors. Disabling this may make your `build.zip` too large. If that's the case, try using the `includeInBuild` option in your `.zapierapprc`. See the docs about `includeInBuild` for more info.","allowNo":false},"skip-npm-install":{"name":"skip-npm-install","type":"boolean","description":"Skips installing a fresh copy of npm dependencies on build. Helpful for using `yarn` or local copies of dependencies.","hidden":true,"allowNo":false},"skip-validation":{"name":"skip-validation","type":"boolean","description":"Skips local pre-push validation checks, and remote validation check of the CLI app's schema and AppVersion integrity.","hidden":true,"allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"register":{"id":"register","description":"Register a new integration in your account, or update the existing one if a `.zapierapprc` file is found.\n\nThis command creates a new integration and links it in the `./.zapierapprc` file. If `.zapierapprc` already exists, it will ask you if you want to update the currently-linked integration, as opposed to creating a new one.\n\nAfter registering a new integration, you can run `zapier push` to build and upload your integration for use in the Zapier editor. This will change `.zapierapprc`, which identifies this directory as holding code for a specific integration.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier register","zapier register \"My Cool Integration\"","zapier register \"My Cool Integration\" --desc \"My Cool Integration helps you integrate your apps with the apps that you need.\" --no-subscribe","zapier register \"My Cool Integration\" --url \"https://www.zapier.com\" --audience private --role employee --category marketing-automation","zapier register --subscribe"],"flags":{"desc":{"name":"desc","type":"option","char":"D","description":"A sentence describing your app in 140 characters or less, e.g. \"Trello is a team collaboration tool to organize tasks and keep projects on track.\""},"url":{"name":"url","type":"option","char":"u","description":"The homepage URL of your app, e.g., https://example.com."},"audience":{"name":"audience","type":"option","char":"a","description":"Are you building a public or private integration?"},"role":{"name":"role","type":"option","char":"r","description":"What is your relationship with the app you're integrating with Zapier?"},"category":{"name":"category","type":"option","char":"c","description":"How would you categorize your app? Choose the most appropriate option for your app's core features."},"subscribe":{"name":"subscribe","type":"boolean","char":"s","description":"Get tips and recommendations about this integration along with our monthly newsletter that details the performance of your integration and the latest Zapier news.","allowNo":true},"yes":{"name":"yes","type":"boolean","char":"y","description":"Assume yes for all yes/no prompts. This flag will also update an existing integration (as opposed to registering a new one) if a .zapierapprc file is found.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"title","description":"Your integration's public title. Asked interactively if not present."}]},"scaffold":{"id":"scaffold","description":"Add a starting trigger, create, search, or resource to your integration.\n\nThe first argument should be one of `trigger|search|create|resource` followed by the noun that this will act on (something like \"contact\" or \"deal\").\n\nThe scaffold command does two general things:\n\n* Creates a new file (such as `triggers/contact.js`)\n* Imports and registers it inside your `index.js`\n\nYou can mix and match several options to customize the created scaffold for your project.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier scaffold trigger contact","zapier scaffold search contact --dest=my_src/searches","zapier scaffold create contact --entry=src/index.js","zapier scaffold resource contact --force"],"flags":{"dest":{"name":"dest","type":"option","char":"d","description":"Specify the new file's directory. Use this flag when you want to create a different folder structure such as `src/triggers` instead of the default `triggers`. Defaults to `[triggers|searches|creates]/{noun}`."},"test-dest":{"name":"test-dest","type":"option","description":"Specify the new test file's directory. Use this flag when you want to create a different folder structure such as `src/triggers` instead of the default `triggers`. Defaults to `test/[triggers|searches|creates]/{noun}`."},"entry":{"name":"entry","type":"option","char":"e","description":"Supply the path to your integration's root (`index.js`). Only needed if your `index.js` is in a subfolder, like `src`.","default":"index.js"},"force":{"name":"force","type":"boolean","char":"f","description":"Should we overwrite an exisiting trigger/search/create file?","allowNo":false},"no-help":{"name":"no-help","type":"boolean","description":"When scaffolding, should we skip adding helpful intro comments? Useful if this isn't your first rodeo.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"actionType","required":true,"options":["trigger","search","create","resource"]},{"name":"noun","required":true}]},"test":{"id":"test","description":"Test your integration via the \"test\" script in your \"package.json\".\n\nThis command is a wrapper around `npm test` that also validates the structure of your integration and sets up extra environment variables.\n\nYou can pass any args/flags after a `--`; they will get forwarded onto your test script.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier test","zapier test --skip-validate -- -t 30000 --grep api","zapier test -- -fo --testNamePattern \"auth pass\""],"flags":{"skip-validate":{"name":"skip-validate","type":"boolean","description":"Forgo running `zapier validate` before tests are run. This will speed up tests if you're modifying functionality of an existing integration rather than adding new actions.","allowNo":false},"yarn":{"name":"yarn","type":"boolean","description":"Use `yarn` instead of `npm`. This happens automatically if there's a `yarn.lock` file, but you can manually force `yarn` if you run tests from a sub-directory.","allowNo":false},"pnpm":{"name":"pnpm","type":"boolean","description":"Use `pnpm` instead of `npm`. This happens automatically if there's a `pnpm-lock.yaml` file, but you can manually force `pnpm` if you run tests from a sub-directory.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"upload":{"id":"upload","description":"Upload the latest build of your integration to Zapier.\n\nThis command sends both build/build.zip and build/source.zip to Zapier for use.\n\nTypically we recommend using `zapier push`, which does a build and upload, rather than `upload` by itself.\n","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"validate":{"id":"validate","description":"Validate your integration.\n\nRun the standard validation routine powered by json-schema that checks your integration for any structural errors. This is the same routine that runs during `zapier build`, `zapier upload`, `zapier push` or even as a test in `zapier test`.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier validate","zapier validate --without-style","zapier validate --format json"],"flags":{"without-style":{"name":"without-style","type":"boolean","description":"Forgo pinging the Zapier server to run further checks.","allowNo":false},"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"versions":{"id":"versions","description":"List the versions of your integration available for use in the Zapier editor.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"cache:clear":{"id":"cache:clear","description":"Clear the cache data for a major version. \n\nThis command clears the cache data for a major version of your integration.\nThe job will be run in the background and may take some time to complete.\nYou can check `zapier history` to see the job status.\n","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier cache:clear","zapier cache:clear 2"],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"majorVersion","description":"(Optional) The cache data will be deleted for this major version. If not provided, you must pick from a list of major versions for this integration.","required":false}]},"delete:integration":{"id":"delete:integration","description":"Delete your integration (including all versions).\n\nThis only works if there are no active users or Zaps on any version. If you only want to delete certain versions, use the `zapier delete:version` command instead. It's unlikely that you'll be able to run this on an app that you've pushed publicly, since there are usually still users.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["delete:app"],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"delete:version":{"id":"delete:version","description":"Delete a specific version of your integration.\n\nThis only works if there are no users or Zaps on that version. You will probably need to have run `zapier migrate` and `zapier deprecate` before this command will work.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"version","description":"Specify the version to delete. It must have no users or Zaps.","required":true}]},"env:get":{"id":"env:get","description":"Get environment variables for a version.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier env:get 1.2.3"],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"version","description":"The version to get the environment for.","required":true}]},"env:set":{"id":"env:set","description":"Set environment variables for a version.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier env:set 1.2.3 SECRET=12345 OTHER=4321"],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"version","description":"The version to set the environment for. Values are copied forward when a new version is created, but this command will only ever affect the specified version.","required":true},{"name":"key-value pairs...","description":"The key-value pairs to set. Keys are case-insensitive. Each pair should be space separated and pairs should be separated by an `=`. For example: `A=123 B=456`"}]},"env:unset":{"id":"env:unset","description":"Unset environment variables for a version.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"examples":["zapier env:unset 1.2.3 SECRET OTHER"],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"version","description":"The version to set the environment for.","required":true},{"name":"keys...","description":"The keys to unset. Keys are case-insensitive."}]},"team:add":{"id":"team:add","description":"Add a team member to your integration.\n\nThese users come in three levels:\n\n * `admin`, who can edit everything about the integration\n * `collaborator`, who has read-only access for the app, and will receive periodic email updates. These updates include quarterly health scores and more.\n * `subscriber`, who can't directly access the app, but will receive periodic email updates. These updates include quarterly health scores and more.\n\nTeam members can be freely added and removed.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["team:invite"],"examples":["zapier team:add bruce@wayne.com admin","zapier team:add robin@wayne.com collaborator \"Hey Robin, check out this app.\"","zapier team:add alfred@wayne.com subscriber \"Hey Alfred, check out this app.\""],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"email","description":"The user to be invited. If they don't have a Zapier account, they'll be prompted to create one.","required":true},{"name":"role","description":"The level the invited team member should be at. Admins can edit everything and get email updates. Collaborators have read-access to the app and get email updates. Subscribers only get email updates.","required":true,"options":["admin","collaborator","subscriber"]},{"name":"message","description":"A message sent in the email to your team member, if you need to provide context. Wrap the message in quotes to ensure spaces get saved."}]},"team:get":{"id":"team:get","description":"Get team members involved with your integration.\n\nThese users come in three levels:\n\n * `admin`, who can edit everything about the integration\n * `collaborator`, who has read-only access for the app, and will receive periodic email updates. These updates include quarterly health scores and more.\n * `subscriber`, who can't directly access the app, but will receive periodic email updates. These updates include quarterly health scores and more.\n\nUse the `zapier team:add` and `zapier team:remove` commands to modify your team.\n","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["team:list"],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"team:remove":{"id":"team:remove","description":"Remove a team member from all versions of your integration.\n\nAdmins will immediately lose write access to the integration.\nCollaborators will immediately lose read access to the integration.\nSubscribers won't receive future email updates.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["team:delete"],"flags":{"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"users:add":{"id":"users:add","description":"Add a user to some or all versions of your integration.\n\nWhen this command is run, we'll send an email to the user inviting them to try your integration. You can track the status of that invite using the `zapier users:get` command.\n\nInvited users will be able to see your integration's name, logo, and description. They'll also be able to create Zaps using any available triggers and actions.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["users:invite"],"examples":["zapier users:add bruce@wayne.com","zapier users:add alfred@wayne.com 1.2.3"],"flags":{"force":{"name":"force","type":"boolean","char":"f","description":"Skip confirmation. Useful for running programatically.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"email","description":"The user to be invited. If they don't have a Zapier account, they'll be prompted to create one.","required":true},{"name":"version","description":"A version string (like 1.2.3). Optional, used only if you want to invite a user to a specific version instead of all versions."}]},"users:get":{"id":"users:get","description":"Get a list of users who have been invited to your integration.\n\nNote that this list of users is NOT a comprehensive list of everyone who is using your integration. It only includes users who were invited directly by email (using the `\u001b[36mzapier users:add\u001b[39m` command or the web UI). Users who joined by clicking links generated using the `\u001b[36mzapier user:links\u001b[39m` command won't show up here.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["users:list"],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"users:links":{"id":"users:links","description":"Get a list of links that are used to invite users to your integration.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":[],"flags":{"format":{"name":"format","type":"option","char":"f","description":"Change the way structured data is presented. If \"json\" or \"raw\", you can pipe the output of the command into other tools, such as jq.","options":["plain","json","raw","row","table"],"default":"table"},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[]},"users:remove":{"id":"users:remove","description":"Remove a user from all versions of your integration.\n\nWhen this command is run, their Zaps will immediately turn off. They won't be able to use your app again until they're re-invited or it has gone public. In practice, this command isn't run often as it's very disruptive to users.","pluginName":"zapier-platform-cli","pluginType":"core","aliases":["users:delete"],"flags":{"force":{"name":"force","type":"boolean","char":"f","description":"Skips confirmation. Useful for running programatically.","allowNo":false},"debug":{"name":"debug","type":"boolean","char":"d","description":"Show extra debugging output.","allowNo":false},"invokedFromAnotherCommand":{"name":"invokedFromAnotherCommand","type":"boolean","hidden":true,"allowNo":false}},"args":[{"name":"email","description":"The user to be removed.","required":true}]}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zapier-platform-cli",
3
- "version": "15.5.1",
3
+ "version": "15.5.2",
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/",
@@ -32,6 +32,7 @@
32
32
  "lint": "eslint src snippets",
33
33
  "lint:fix": "eslint --fix src snippets",
34
34
  "test": "cross-env NODE_ENV=test mocha -t 50s --recursive src/tests --exit",
35
+ "test-debug": "cross-env NODE_ENV=test node inspect ../../node_modules/.bin/mocha -t 50s --recursive src/tests --exit",
35
36
  "smoke-test": "cross-env NODE_ENV=test mocha -t 2m --recursive src/smoke-tests --exit",
36
37
  "validate-templates": "./scripts/validate-app-templates.js",
37
38
  "set-template-versions": "./scripts/set-app-template-versions.js",
@@ -41,7 +42,7 @@
41
42
  "@oclif/command": "1.8.27",
42
43
  "@oclif/config": "1.18.10",
43
44
  "@oclif/plugin-autocomplete": "0.3.0",
44
- "@oclif/plugin-help": "3.2.2",
45
+ "@oclif/plugin-help": "3.2.20",
45
46
  "@oclif/plugin-not-found": "1.2.4",
46
47
  "adm-zip": "0.5.10",
47
48
  "archiver": "5.3.1",
@@ -59,6 +60,7 @@
59
60
  "lodash": "4.17.21",
60
61
  "marked": "4.2.12",
61
62
  "marked-terminal": "5.2.0",
63
+ "minimatch": "9.0.3",
62
64
  "node-fetch": "2.6.7",
63
65
  "ora": "5.4.0",
64
66
  "parse-gitignore": "0.5.1",
@@ -10,7 +10,7 @@ describe('<%= ACTION_PLURAL %>.<%= KEY %>', () => {
10
10
  it('should run', async () => {
11
11
  const bundle = { inputData: {} };
12
12
 
13
- const results = await appTester(App.<%= ACTION_PLURAL %>.<%= KEY %>.<%= MAYBE_RESOURCE %>operation.perform, bundle);
13
+ const results = await appTester(App.<%= ACTION_PLURAL %>['<%= KEY %>'].<%= MAYBE_RESOURCE %>operation.perform, bundle);
14
14
  expect(results).toBeDefined();
15
15
  // TODO: add more assertions
16
16
  });
@@ -137,6 +137,7 @@ const writeForStandaloneTemplate = (gen) => {
137
137
  devDependencies: {
138
138
  '@types/jest': '^26.0.23',
139
139
  '@types/node': '^14',
140
+ '@types/node-fetch': '^2.6.11',
140
141
  rimraf: '^3.0.2',
141
142
  typescript: '^4.9.4',
142
143
  },
@@ -1,6 +1,6 @@
1
1
  const { Command } = require('@oclif/command');
2
- const { stdtermwidth } = require('@oclif/plugin-help/lib/screen');
3
- const { renderList } = require('@oclif/plugin-help/lib/list');
2
+ const { stdtermwidth } = require('@oclif/help/lib/screen');
3
+ const { renderList } = require('@oclif/help/lib/list');
4
4
  const colors = require('colors/safe');
5
5
 
6
6
  const { startSpinner, endSpinner, formatStyles } = require('../utils/display');
@@ -1,7 +1,7 @@
1
1
  const chalk = require('chalk');
2
2
  const { marked } = require('marked');
3
3
  const TerminalRenderer = require('marked-terminal');
4
- const { stdtermwidth } = require('@oclif/plugin-help/lib/screen');
4
+ const { stdtermwidth } = require('@oclif/help/lib/screen');
5
5
 
6
6
  marked.setOptions({
7
7
  renderer: new TerminalRenderer({
@@ -14,6 +14,7 @@ const colors = require('colors/safe');
14
14
  const ignore = require('ignore');
15
15
  const gitIgnore = require('parse-gitignore');
16
16
  const semver = require('semver');
17
+ const { minimatch } = require('minimatch');
17
18
 
18
19
  const {
19
20
  constants: { Z_BEST_COMPRESSION },
@@ -45,7 +46,7 @@ const {
45
46
 
46
47
  const checkMissingAppInfo = require('./check-missing-app-info');
47
48
 
48
- const { runCommand, isWindows } = require('./misc');
49
+ const { runCommand, isWindows, findCorePackageDir } = require('./misc');
49
50
 
50
51
  const debug = require('debug')('zapier:build');
51
52
 
@@ -318,10 +319,32 @@ const maybeRunBuildScript = async (options = {}) => {
318
319
  }
319
320
  };
320
321
 
322
+ // Get `workspaces` from root package.json and convert them to absolute paths.
323
+ // Returns an empty array if package.json can't be found.
324
+ const listWorkspaces = (workspaceRoot) => {
325
+ const packageJsonPath = path.join(workspaceRoot, 'package.json');
326
+ if (!fs.existsSync(packageJsonPath)) {
327
+ return [];
328
+ }
329
+
330
+ let packageJson;
331
+ try {
332
+ packageJson = require(packageJsonPath);
333
+ } catch (err) {
334
+ return [];
335
+ }
336
+
337
+ return (packageJson.workspaces || []).map((relpath) =>
338
+ path.resolve(workspaceRoot, relpath)
339
+ );
340
+ };
341
+
321
342
  const _buildFunc = async ({
322
343
  skipNpmInstall = false,
323
344
  disableDependencyDetection = false,
324
345
  skipValidation = false,
346
+ printProgress = true,
347
+ checkOutdated = true,
325
348
  } = {}) => {
326
349
  const zipPath = constants.BUILD_PATH;
327
350
  const sourceZipPath = constants.SOURCE_PATH;
@@ -332,8 +355,11 @@ const _buildFunc = async ({
332
355
  osTmpDir,
333
356
  'zapier-' + crypto.randomBytes(4).toString('hex')
334
357
  );
358
+ debug('Using temp directory: ', tmpDir);
335
359
 
336
- maybeNotifyAboutOutdated();
360
+ if (checkOutdated) {
361
+ maybeNotifyAboutOutdated();
362
+ }
337
363
 
338
364
  await maybeRunBuildScript();
339
365
 
@@ -341,15 +367,59 @@ const _buildFunc = async ({
341
367
  await ensureDir(tmpDir);
342
368
  await ensureDir(constants.BUILD_DIR);
343
369
 
344
- startSpinner('Copying project to temp directory');
345
- await copyDir(wdir, tmpDir, {
346
- filter: skipNpmInstall ? (dir) => !dir.includes('.zip') : undefined,
347
- });
370
+ if (printProgress) {
371
+ startSpinner('Copying project to temp directory');
372
+ }
373
+
374
+ const copyFilter = skipNpmInstall
375
+ ? (src) => !src.endsWith('.zip')
376
+ : undefined;
377
+
378
+ await copyDir(wdir, tmpDir, { filter: copyFilter });
379
+
380
+ if (skipNpmInstall) {
381
+ const corePackageDir = findCorePackageDir();
382
+ const nodeModulesDir = path.dirname(corePackageDir);
383
+ const workspaceRoot = path.dirname(nodeModulesDir);
384
+ if (wdir !== workspaceRoot) {
385
+ // If we're in here, it means the user is using npm/yarn workspaces
386
+ const workspaces = listWorkspaces(workspaceRoot);
387
+
388
+ await copyDir(nodeModulesDir, path.join(tmpDir, 'node_modules'), {
389
+ filter: (src) => {
390
+ if (src.endsWith('.zip')) {
391
+ return false;
392
+ }
393
+ const stat = fse.lstatSync(src);
394
+ if (stat.isSymbolicLink()) {
395
+ const realPath = path.resolve(
396
+ path.dirname(src),
397
+ fse.readlinkSync(src)
398
+ );
399
+ for (const workspace of workspaces) {
400
+ // Use minimatch to do glob pattern match. If match, it means the
401
+ // symlink points to a workspace package, so we don't copy it.
402
+ if (minimatch(realPath, workspace)) {
403
+ return false;
404
+ }
405
+ }
406
+ }
407
+ return true;
408
+ },
409
+ onDirExists: (dir) => {
410
+ // Don't overwrite existing sub-directories in node_modules
411
+ return false;
412
+ },
413
+ });
414
+ }
415
+ }
348
416
 
349
417
  let output = {};
350
418
  if (!skipNpmInstall) {
351
- endSpinner();
352
- startSpinner('Installing project dependencies');
419
+ if (printProgress) {
420
+ endSpinner();
421
+ startSpinner('Installing project dependencies');
422
+ }
353
423
  output = await runCommand('npm', ['install', '--production'], {
354
424
  cwd: tmpDir,
355
425
  });
@@ -366,9 +436,12 @@ const _buildFunc = async ({
366
436
  'Could not install dependencies properly. Error log:\n' + output.stderr
367
437
  );
368
438
  }
369
- endSpinner();
370
439
 
371
- startSpinner('Applying entry point file');
440
+ if (printProgress) {
441
+ endSpinner();
442
+ startSpinner('Applying entry point file');
443
+ }
444
+
372
445
  // TODO: should this routine for include exist elsewhere?
373
446
  const zapierWrapperBuf = await readFile(
374
447
  path.join(
@@ -383,9 +456,12 @@ const _buildFunc = async ({
383
456
  path.join(tmpDir, 'zapierwrapper.js'),
384
457
  zapierWrapperBuf.toString()
385
458
  );
386
- endSpinner();
387
459
 
388
- startSpinner('Building app definition.json');
460
+ if (printProgress) {
461
+ endSpinner();
462
+ startSpinner('Building app definition.json');
463
+ }
464
+
389
465
  const rawDefinition = (
390
466
  await _appCommandZapierWrapper(tmpDir, {
391
467
  command: 'definition',
@@ -403,7 +479,10 @@ const _buildFunc = async ({
403
479
  `Unable to write ${tmpDir}/definition.json, please check file permissions!`
404
480
  );
405
481
  }
406
- endSpinner();
482
+
483
+ if (printProgress) {
484
+ endSpinner();
485
+ }
407
486
 
408
487
  if (!skipValidation) {
409
488
  /**
@@ -412,7 +491,9 @@ const _buildFunc = async ({
412
491
  * (Remote - `validateApp`) Both the Schema, AppVersion, and Auths are validated
413
492
  */
414
493
 
415
- startSpinner('Validating project schema');
494
+ if (printProgress) {
495
+ startSpinner('Validating project schema and style');
496
+ }
416
497
  const validateResponse = await _appCommandZapierWrapper(tmpDir, {
417
498
  command: 'validate',
418
499
  });
@@ -425,8 +506,6 @@ const _buildFunc = async ({
425
506
  );
426
507
  }
427
508
 
428
- startSpinner('Validating project style');
429
-
430
509
  // No need to mention specifically we're validating style checks as that's
431
510
  // implied from `zapier validate`, though it happens as a separate process
432
511
  const styleChecksResponse = await validateApp(rawDefinition);
@@ -441,7 +520,9 @@ const _buildFunc = async ({
441
520
  'We hit some style validation errors, try running `zapier validate` to see them!'
442
521
  );
443
522
  }
444
- endSpinner();
523
+ if (printProgress) {
524
+ endSpinner();
525
+ }
445
526
 
446
527
  if (_.get(styleChecksResponse, ['warnings', 'total_failures'])) {
447
528
  console.log(colors.yellow('WARNINGS:'));
@@ -457,16 +538,21 @@ const _buildFunc = async ({
457
538
  debug('\nWarning: Skipping Validation');
458
539
  }
459
540
 
460
- startSpinner('Zipping project and dependencies');
541
+ if (printProgress) {
542
+ startSpinner('Zipping project and dependencies');
543
+ }
461
544
  await makeZip(tmpDir, path.join(wdir, zipPath), disableDependencyDetection);
462
545
  await makeSourceZip(
463
546
  tmpDir,
464
547
  path.join(wdir, sourceZipPath),
465
548
  disableDependencyDetection
466
549
  );
467
- endSpinner();
468
550
 
469
- startSpinner('Testing build');
551
+ if (printProgress) {
552
+ endSpinner();
553
+ startSpinner('Testing build');
554
+ }
555
+
470
556
  if (!isWindows()) {
471
557
  // TODO err, what should we do on windows?
472
558
 
@@ -479,11 +565,17 @@ const _buildFunc = async ({
479
565
  { cwd: tmpDir }
480
566
  );
481
567
  }
482
- endSpinner();
483
568
 
484
- startSpinner('Cleaning up temp directory');
569
+ if (printProgress) {
570
+ endSpinner();
571
+ startSpinner('Cleaning up temp directory');
572
+ }
573
+
485
574
  await removeDir(tmpDir);
486
- endSpinner();
575
+
576
+ if (printProgress) {
577
+ endSpinner();
578
+ }
487
579
 
488
580
  return zipPath;
489
581
  };
@@ -1,6 +1,7 @@
1
1
  const path = require('path');
2
2
 
3
3
  const _ = require('lodash');
4
+ const chalk = require('chalk');
4
5
  const prettier = require('prettier');
5
6
  const semver = require('semver');
6
7
  const traverse = require('traverse');
@@ -157,6 +158,15 @@ const renderPackageJson = async (appInfo, appDefinition) => {
157
158
  const renderSource = (definition, functions = {}) => {
158
159
  traverse(definition).forEach(function (source) {
159
160
  if (this.key === 'source') {
161
+ if (
162
+ this.path.length >= 2 &&
163
+ this.path[0] === 'operation' &&
164
+ this.path[1] === 'sample'
165
+ ) {
166
+ // Don't replace 'source' if it's in sample
167
+ return;
168
+ }
169
+
160
170
  const args = this.parent.node.args || ['z', 'bundle'];
161
171
  // Find first parent that is not an array (applies to inputFields)
162
172
  const funcNameBase = this.path
@@ -178,7 +188,7 @@ const renderSource = (definition, functions = {}) => {
178
188
  });
179
189
  };
180
190
 
181
- const renderDefinitionSlice = (definitionSlice) => {
191
+ const renderDefinitionSlice = (definitionSlice, filename) => {
182
192
  let exportBlock = _.cloneDeep(definitionSlice);
183
193
  let functionBlock = {};
184
194
 
@@ -190,7 +200,17 @@ const renderDefinitionSlice = (definitionSlice) => {
190
200
 
191
201
  functionBlock = Object.values(functionBlock).join('\n\n');
192
202
 
193
- return prettifyJs(functionBlock + '\n\n' + exportBlock);
203
+ const uglyCode = functionBlock + '\n\n' + exportBlock;
204
+ try {
205
+ return prettifyJs(uglyCode);
206
+ } catch (err) {
207
+ console.warn(
208
+ `Warning: Your code has syntax error in ${chalk.underline.bold(
209
+ filename
210
+ )}. ` + `It will be left as is and won't be prettified.\n\n${err.message}`
211
+ );
212
+ return uglyCode;
213
+ }
194
214
  };
195
215
 
196
216
  const renderStepTest = async (stepType, definition) => {
@@ -205,10 +225,10 @@ const renderStepTest = async (stepType, definition) => {
205
225
  };
206
226
 
207
227
  const renderAuth = async (appDefinition) =>
208
- renderDefinitionSlice(appDefinition.authentication);
228
+ renderDefinitionSlice(appDefinition.authentication, 'authentication.js');
209
229
 
210
230
  const renderHydrators = async (appDefinition) =>
211
- renderDefinitionSlice(appDefinition.hydrators);
231
+ renderDefinitionSlice(appDefinition.hydrators, 'hydrators.js');
212
232
 
213
233
  const renderIndex = async (appDefinition) => {
214
234
  let exportBlock = _.cloneDeep(appDefinition);
@@ -234,7 +254,12 @@ const renderIndex = async (appDefinition) => {
234
254
  },
235
255
  (importNameSuffix, stepType) => {
236
256
  _.each(appDefinition[stepType], (definition, key) => {
237
- const importName = _.camelCase(key) + importNameSuffix;
257
+ let importName = _.camelCase(key) + importNameSuffix;
258
+
259
+ if (importName[0].match(/[0-9]/)) {
260
+ importName = `cannotStartWithNumber${importName}`;
261
+ }
262
+
238
263
  const filepath = `./${stepType}/${_.snakeCase(key)}.js`;
239
264
 
240
265
  importBlock.push(`const ${importName} = require('${filepath}');`);
@@ -284,7 +309,7 @@ const renderEnvironment = (appDefinition) => {
284
309
 
285
310
  const writeStep = async (stepType, definition, key, newAppDir) => {
286
311
  const filename = `${stepType}/${snakeCase(key)}.js`;
287
- const content = await renderDefinitionSlice(definition);
312
+ const content = await renderDefinitionSlice(definition, filename);
288
313
  await createFile(content, filename, newAppDir);
289
314
  };
290
315
 
@@ -4,6 +4,7 @@ const os = require('os');
4
4
  const path = require('path');
5
5
 
6
6
  const fse = require('fs-extra');
7
+ const colors = require('colors/safe');
7
8
 
8
9
  const fixHome = (dir) => {
9
10
  const home = process.env.HOME || process.env.USERPROFILE;
@@ -83,60 +84,105 @@ const copyFile = (src, dest, mode) => {
83
84
  });
84
85
  };
85
86
 
86
- // Returns a promise that copies a directory.
87
- const copyDir = (src, dst, options) => {
88
- const defaultFilter = (dir) => {
89
- const isntPackage = dir.indexOf('node_modules') === -1;
90
- const isntBuild = dir.indexOf('.zip') === -1;
87
+ /*
88
+ Returns a promise that copies a directory recursively.
89
+
90
+ Options:
91
+
92
+ - clobber: Overwrite existing files? Default is false.
93
+ - filter:
94
+ A function that returns true if the file should be copied. By default, it
95
+ ignores node_modules and .zip files.
96
+ - onCopy:
97
+ A function called when a file is copied. Takes the destination path as an
98
+ argument.
99
+ - onSkip:
100
+ A function called when a file is skipped. Takes the destination path as an
101
+ argument.
102
+ - onDirExists:
103
+ A function called when a directory exists. Takes the destination path as
104
+ an argument. Returns true to carry on copying. Returns false to skip.
105
+ */
106
+ const copyDir = async (src, dst, options) => {
107
+ const defaultFilter = (srcPath) => {
108
+ const isntPackage = !srcPath.includes('node_modules');
109
+ const isntBuild = !srcPath.endsWith('.zip');
91
110
  return isntPackage && isntBuild;
92
111
  };
93
112
 
94
- options = _.defaults(options || {}, {
113
+ options = {
95
114
  clobber: false,
96
115
  filter: defaultFilter,
97
116
  onCopy: () => {},
98
117
  onSkip: () => {},
99
- });
118
+ onDirExists: () => true,
119
+ ...options,
120
+ };
100
121
 
101
- return ensureDir(dst)
102
- .then(() => fse.readdir(src))
103
- .then((files) => {
104
- const promises = files.map((file) => {
105
- const srcItem = path.resolve(src, file);
106
- const dstItem = path.resolve(dst, file);
107
- const stat = fse.statSync(srcItem);
108
- const dstExists = fileExistsSync(dstItem);
109
-
110
- if (!options.filter(srcItem)) {
111
- return Promise.resolve();
112
- }
122
+ if (!options.filter) {
123
+ options.filter = defaultFilter;
124
+ }
113
125
 
114
- if (dstExists && options.clobber) {
115
- fse.removeSync(dstItem);
116
- } else if (dstExists) {
117
- if (!stat.isDirectory()) {
118
- options.onSkip(dstItem);
119
- return Promise.resolve();
120
- }
121
- }
126
+ await ensureDir(dst);
127
+ const files = await fse.readdirSync(src);
128
+
129
+ const promises = files.map(async (file) => {
130
+ const srcItem = path.resolve(src, file);
131
+
132
+ let srcStat;
133
+ try {
134
+ srcStat = fse.statSync(srcItem);
135
+ } catch (err) {
136
+ // If the file is a symlink and the target doesn't exist, skip it.
137
+ if (fse.lstatSync(srcItem).isSymbolicLink()) {
138
+ console.warn(
139
+ colors.yellow(
140
+ `\n! Warning: symlink "${srcItem}" points to a non-existent file. Skipping!\n`
141
+ )
142
+ );
143
+ return null;
144
+ }
145
+
146
+ // otherwise, rethrow the error
147
+ throw err;
148
+ }
149
+
150
+ const srcIsFile = srcStat.isFile();
122
151
 
123
- if (stat.isDirectory()) {
124
- return ensureDir(dstItem).then(() =>
125
- copyDir(srcItem, dstItem, options)
126
- );
127
- } else {
128
- return copyFile(srcItem, dstItem, stat.mode).then(() => {
129
- options.onCopy(dstItem);
130
- });
152
+ const dstItem = path.resolve(dst, file);
153
+ const dstExists = fileExistsSync(dstItem);
154
+ if (!options.filter(srcItem)) {
155
+ return null;
156
+ }
157
+
158
+ if (srcIsFile) {
159
+ if (dstExists) {
160
+ if (!options.clobber) {
161
+ options.onSkip(dstItem);
162
+ return null;
131
163
  }
132
- });
164
+ fse.removeSync(dstItem);
165
+ }
133
166
 
134
- return Promise.all(promises);
135
- });
167
+ await copyFile(srcItem, dstItem, srcStat.mode);
168
+ options.onCopy(dstItem);
169
+ } else {
170
+ let shouldCopyRecursively = true;
171
+ if (dstExists) {
172
+ shouldCopyRecursively = options.onDirExists(dstItem);
173
+ }
174
+ if (shouldCopyRecursively) {
175
+ await copyDir(srcItem, dstItem, options);
176
+ }
177
+ }
178
+ });
179
+
180
+ return Promise.all(promises);
136
181
  };
137
182
 
138
183
  // Delete a directory.
139
184
  const removeDir = (dir) => fse.remove(dir);
185
+ const removeDirSync = (dir) => fse.removeSync(dir);
140
186
 
141
187
  // Returns true if directory is empty, else false.
142
188
  // Rejects if directory does not exist.
@@ -164,6 +210,7 @@ module.exports = {
164
210
  readFile,
165
211
  readFileStr,
166
212
  removeDir,
213
+ removeDirSync,
167
214
  validateFileExists,
168
215
  writeFile,
169
216
  copyFile,
@@ -16,7 +16,7 @@ const getLocalAppHandler = ({ reload = false, baseEvent = {} } = {}) => {
16
16
  let appRaw, zapier;
17
17
  try {
18
18
  appRaw = require(entryPath);
19
- zapier = require(`${rootPath}/node_modules/${PLATFORM_PACKAGE}`);
19
+ zapier = require(PLATFORM_PACKAGE);
20
20
  } catch (err) {
21
21
  // this err.stack doesn't give a nice traceback at all :-(
22
22
  // maybe we could do require('syntax-error') in the future
package/src/utils/misc.js CHANGED
@@ -77,6 +77,22 @@ const runCommand = (command, args, options) => {
77
77
  const isValidNodeVersion = (version = process.version) =>
78
78
  semver.satisfies(version, NODE_VERSION_CLI_REQUIRES);
79
79
 
80
+ const findCorePackageDir = () => {
81
+ let baseDir = process.cwd();
82
+ // 500 is just an arbitrary number to prevent infinite loops
83
+ for (let i = 0; i < 500; i++) {
84
+ const dir = path.join(baseDir, 'node_modules', PLATFORM_PACKAGE);
85
+ if (fse.existsSync(dir)) {
86
+ return dir;
87
+ }
88
+ if (baseDir === '/' || baseDir.match(/^[a-z]:\\$/i)) {
89
+ break;
90
+ }
91
+ baseDir = path.dirname(baseDir);
92
+ }
93
+ throw new Error(`Could not find ${PLATFORM_PACKAGE}.`);
94
+ };
95
+
80
96
  const isValidAppInstall = () => {
81
97
  let packageJson, dependedCoreVersion;
82
98
  try {
@@ -91,7 +107,7 @@ const isValidAppInstall = () => {
91
107
  valid: false,
92
108
  reason: `Your app doesn't depend on ${PLATFORM_PACKAGE}. Run \`${colors.cyan(
93
109
  `npm install -E ${PLATFORM_PACKAGE}`
94
- )}\` to resolve`,
110
+ )}\` to resolve.`,
95
111
  };
96
112
  } else if (!semver.valid(dependedCoreVersion)) {
97
113
  // semver.valid only matches exact versions
@@ -104,30 +120,30 @@ const isValidAppInstall = () => {
104
120
  return { valid: false, reason: String(err) };
105
121
  }
106
122
 
123
+ let corePackageDir;
107
124
  try {
108
- const installedPackageJson = require(path.join(
109
- process.cwd(),
110
- 'node_modules',
111
- PLATFORM_PACKAGE,
112
- 'package.json'
113
- ));
114
-
115
- const installedCoreVersion = installedPackageJson.version;
116
- // not an error for now, but something to mention to them
117
- if (dependedCoreVersion !== installedCoreVersion) {
118
- console.warn(
119
- `\nYour code depends on v${dependedCoreVersion} of ${PLATFORM_PACKAGE}, but your local copy is v${installedCoreVersion}. You should probably reinstall your dependencies.\n`
120
- );
121
- }
125
+ corePackageDir = findCorePackageDir();
122
126
  } catch (err) {
123
127
  return {
124
128
  valid: false,
125
129
  reason: `Looks like you're missing a local installation of ${PLATFORM_PACKAGE}. Run \`${colors.cyan(
126
130
  'npm install'
127
- )}\` to resolve`,
131
+ )}\` to resolve.`,
128
132
  };
129
133
  }
130
134
 
135
+ const installedPackageJson = require(path.join(
136
+ corePackageDir,
137
+ 'package.json'
138
+ ));
139
+ const installedCoreVersion = installedPackageJson.version;
140
+
141
+ if (installedCoreVersion !== dependedCoreVersion) {
142
+ console.warn(
143
+ `\nYour code depends on v${dependedCoreVersion} of ${PLATFORM_PACKAGE}, but your local copy is v${installedCoreVersion}. You should probably reinstall your dependencies.\n`
144
+ );
145
+ }
146
+
131
147
  return { valid: true };
132
148
  };
133
149
 
@@ -214,6 +230,7 @@ const printVersionInfo = (context) => {
214
230
  module.exports = {
215
231
  camelCase,
216
232
  entryPoint,
233
+ findCorePackageDir,
217
234
  isValidAppInstall,
218
235
  isValidNodeVersion,
219
236
  isWindows,