diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml deleted file mode 100644 index 9dfcdd96923de..0000000000000 --- a/.github/workflows/docs.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: Pull Request Checks - -# -# Documentation: -# https://help.github.com/en/articles/workflow-syntax-for-github-actions -# - -on: - pull_request: - branches: - - master - paths: - - 'docs/**' - -jobs: - check_broken_links: - name: Ensure no broken links end up in docs - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4.1.7 - name: Checkout repo - with: - # See https://github.com/actions/checkout#checkout-v2 - # This will be slow. The intent is to fetch all commits - # since the merge-base (the commit where we branched off) - # so we can check the git diff against all changed files. - # By default, the checkout action only returns the last commit, - # There's no native way to do this in the checkout action, so - # we have to fetch the entire history. See - # https://github.com/actions/checkout/issues/266#issuecomment-638346893 - fetch-depth: 0 - - name: Install docs deps and check broken links - run: |- - cd docs - yarn install - npx vuepress check-md docs/ \ No newline at end of file diff --git a/components/air/air.app.mjs b/components/air/air.app.mjs index 950ad8517ab6f..78ca544043ae9 100644 --- a/components/air/air.app.mjs +++ b/components/air/air.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/cats/cats.app.mjs b/components/cats/cats.app.mjs index 46a46360db29b..35105682c0dee 100644 --- a/components/cats/cats.app.mjs +++ b/components/cats/cats.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/fal_ai/fal_ai.app.mjs b/components/fal_ai/fal_ai.app.mjs index e3976ae3d91d8..51166062647ec 100644 --- a/components/fal_ai/fal_ai.app.mjs +++ b/components/fal_ai/fal_ai.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/flexisign/flexisign.app.mjs b/components/flexisign/flexisign.app.mjs index 308bac1bbacd9..a9246c3435314 100644 --- a/components/flexisign/flexisign.app.mjs +++ b/components/flexisign/flexisign.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/microsoft_azure_ai_translator/microsoft_azure_ai_translator.app.mjs b/components/microsoft_azure_ai_translator/microsoft_azure_ai_translator.app.mjs index e4e822e538cfc..c0c4cf190a5a0 100644 --- a/components/microsoft_azure_ai_translator/microsoft_azure_ai_translator.app.mjs +++ b/components/microsoft_azure_ai_translator/microsoft_azure_ai_translator.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/microsoft_text_translate/microsoft_text_translate.app.mjs b/components/microsoft_text_translate/microsoft_text_translate.app.mjs index ad8a5129a94f0..5bd3c6fe11a9f 100644 --- a/components/microsoft_text_translate/microsoft_text_translate.app.mjs +++ b/components/microsoft_text_translate/microsoft_text_translate.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/openphone/openphone.app.mjs b/components/openphone/openphone.app.mjs index fc77209e14dbc..954b90d9e14c3 100644 --- a/components/openphone/openphone.app.mjs +++ b/components/openphone/openphone.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/parallel/parallel.app.mjs b/components/parallel/parallel.app.mjs index bb7d6d051c17e..ddcc94b46e628 100644 --- a/components/parallel/parallel.app.mjs +++ b/components/parallel/parallel.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/tldr/tldr.app.mjs b/components/tldr/tldr.app.mjs index b093bb357fe12..4b5b1565b6754 100644 --- a/components/tldr/tldr.app.mjs +++ b/components/tldr/tldr.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/verifone/verifone.app.mjs b/components/verifone/verifone.app.mjs index 35e5be6629441..c7e4ad1b4a029 100644 --- a/components/verifone/verifone.app.mjs +++ b/components/verifone/verifone.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/docs-v2/package.json b/docs-v2/package.json index b65fc47bc3da0..5e615985f3062 100644 --- a/docs-v2/package.json +++ b/docs-v2/package.json @@ -12,6 +12,7 @@ "homepage": "https://pipedream.com", "dependencies": { "@docsearch/react": "^3.6.1", + "@pipedream/sdk": "^0.1.9", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "@vercel/analytics": "^1.3.1", diff --git a/docs-v2/pages/_meta.json b/docs-v2/pages/_meta.json index b3b881ae820c2..0b3d4a0d22382 100644 --- a/docs-v2/pages/_meta.json +++ b/docs-v2/pages/_meta.json @@ -17,7 +17,7 @@ "event-history": "Event History", "http": "HTTP", "environment-variables": "Environment Variables", - "rest-api": "API Reference", + "rest-api": "REST API", "cli": "CLI", "destinations": "Destinations", "user-settings": "User and Billing Settings", diff --git a/docs-v2/pages/connect/_meta.json b/docs-v2/pages/connect/_meta.json index fc96c02960731..5034e6bc7e4a0 100644 --- a/docs-v2/pages/connect/_meta.json +++ b/docs-v2/pages/connect/_meta.json @@ -25,5 +25,8 @@ }, "connect-link": { "title": "Connect Link" + }, + "migrating-from-project-keys-to-oauth": { + "display": "hidden" } } diff --git a/docs-v2/pages/connect/api.mdx b/docs-v2/pages/connect/api.mdx index 86de64dcf24cb..df9d031209eeb 100644 --- a/docs-v2/pages/connect/api.mdx +++ b/docs-v2/pages/connect/api.mdx @@ -5,14 +5,12 @@ import { Tabs } from 'nextra/components' Pipedream provides a TypeScript SDK and a REST API to interact with the Connect service. You'll find examples using the SDK and the REST API in multiple languages below. - -Note that both the Base URL and authentication method for the Connect REST API are different from the rest of Pipedream's REST API. - - ## REST API Base URL +Pipedream Connect resources are scoped to [projects](/projects), so you'll need to pass [the project's ID](/projects#finding-your-projects-id) as a part of the base URL: + ``` -https://api.pipedream.com/v1/connect +https://api.pipedream.com/v1/connect/{project_id} ``` ## Installing the TypeScript SDK @@ -43,19 +41,23 @@ or a specific version: ## Authentication +See the [REST API Authentication docs](/rest-api/auth). + ### TypeScript SDK (Server) Most of your interactions with the Connect API will happen on the server, to protect API requests and user credentials. You'll use the SDK in [your frontend](#typescript-sdk-browser) to let users connect accounts. Once connected, you'll use the SDK on the server to retrieve credentials, invoke workflows on their behalf, and more. -Find your [project keys](/connect/quickstart#get-your-project-keys) and instantiate the SDK client: +[Create a Pipedream OAuth client](/rest-api/auth#oauth) and instantiate the SDK with your client ID and secret: ```typescript -import { createClient } from "@pipedream/sdk"; +import { createBackendClient } from "@pipedream/sdk"; // These secrets should be saved securely and passed to your environment -const pd = createClient({ - publicKey: "YOUR_PUBLIC_KEY", - secretKey: "YOUR_SECRET_KEY", +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", + } }); // The `pd` client provides methods to interact with the Connect API — see below @@ -71,8 +73,7 @@ You'll primarily use the browser SDK to let your users securely connect apps fro Here's a Next.js example [from our quickstart](/connect/quickstart): ```typescript -// Note that we import the browser-specific SDK client here -import { createClient } from "@pipedream/sdk/browser" +import { createFrontendClient } from "@pipedream/sdk" // Example from our Next.js app import { serverConnectTokenCreate } from "./server" @@ -81,10 +82,11 @@ const { token, expires_at } = await serverConnectTokenCreate({ }); export default function Home() { - const pd = createClient({}) + const pd = createFrontendClient() function connectAccount() { pd.connectAccount({ - app: appSlug, + app: appSlug, // Pass the app name slug of the app you want to integrate + oauthAppId: appId, // For OAuth apps, pass the OAuth app ID; omit this param to use Pipedream's OAuth client or for key-based apps token, // The token you received from your server above onSuccess: ({ id: accountId }) => { console.log(`Account successfully connected: ${accountId}`) @@ -94,480 +96,203 @@ export default function Home() { return (
- +
) } ``` -### REST API - -You authenticate to the Connect API using **Basic Auth**. Send your project public key as the username and the project secret key as the password. When you make API requests, pass an -`Authorization` header of the following format: - -```shell -Authorization: Basic base_64(public_key:secret_key) -``` - -Clients like `cURL` will often make this easy. For example, here's how you list all accounts on a project: - -```shell -curl 'https://api.pipedream.com/v1/connect/accounts' -u public_key:secret_key -``` - ## External users -When you use the Connect API, you'll pass an `external_id` parameter when initiating account connections and retrieving credentials. This is your user's ID, in your system — whatever you use to uniquely identify them. +When you use the Connect API, you'll pass an `external_user_id` parameter when initiating account connections and retrieving credentials. This is your user's ID, in your system — whatever you use to uniquely identify them. Pipedream associates this ID with user accounts, so you can retrieve credentials for a specific user, and invoke workflows on their behalf. -External IDs are limited to 250 characters. +External User IDs are limited to 250 characters. ## Rate limits | API Endpoint | Rate Limit | |----------------------------|------------------------------------------------------| -| `POST /tokens` | 100 requests per minute per `external_id` | +| `POST /tokens` | 100 requests per minute per `external_user_id` | | `GET */accounts/*`| The sum of requests across all `*/accounts/*` endpoints must not exceed 100 requests per minute. This includes requests to `/accounts`, `/apps/:app_id/accounts`, `/accounts/:account_id`, and more — any request for account metadata and credentials is counted towards this total. | If you need higher rate limits, please [reach out](https://pipedream.com/support). ## API Reference -### Tokens - -Your app will initiate the account connection flow for your end users in your frontend. But you can't expose your project keys in the client, since they'd be accessible to anyone. Instead, on your server, **you exchange your project keys for a short-lived token that allows a specific user to connect a specific app**, and return that token to your frontend. - -#### Create a new token - -``` -POST /tokens -``` - -##### Parameters - -- `external_id` - [The external user ID](#external-users) in your system -- `success_redirect_uri` — _Optional_. The URL to redirect the user to after they successfully connect an account -- `error_redirect_uri` — _Optional_. The URL to redirect the user to if they encounter an error during the connection flow - -##### Examples - -To create a short-lived token via TypeScript / JavaScript SDK, you'll need to create a Pipedream API client and call the `connectTokenCreate` method. In our example app, this code is in `app/server.ts`. +### Invoke workflows -In other languages, you'll need to make an HTTP POST request to the `/tokens` endpoint to create a token, then return the token to your frontend. Click into other tabs to see examples in additional languages. +You can use the SDK to invoke workflows on behalf of any end user. **Write one workflow, run it for all of your users**. - + ```typescript -"use server"; - -import { - createClient, - type ConnectAPIResponse, - type ConnectTokenCreateOpts, - type ConnectTokenResponse, -} from "@pipedream/sdk"; - -const pd = createClient({ - publicKey: process.env.PIPEDREAM_PROJECT_PUBLIC_KEY, - secretKey: process.env.PIPEDREAM_PROJECT_SECRET_KEY, +import { createBackendClient, HTTPAuthType } from "@pipedream/sdk"; + +// These secrets should be saved securely and passed to your environment +const pd = createBackendClient({ + credentials: { + clientId: "YOUR_CLIENT_ID", + clientSecret: "YOUR_CLIENT_SECRET", + }, }); -export async function serverConnectTokenCreate(opts: ConnectTokenCreateOpts): Promise> { - return pd.connectTokenCreate(opts); -} - -const { token, expires_at } = await serverConnectTokenCreate({ - external_user_id: externalUserId // The end user's ID in your system -}); +await pd.invokeWorkflowForExternalUser( + "enabc123", // pass the endpoint ID or full URL here + "external_user_id" // The end user's ID in your system + { + method: "POST", + body: { + key: "value", + } + }, + HTTPAuthType.OAuth // Will automatically send the Authorization header with a fresh token +) ``` ```javascript -const fetch = require('node-fetch'); - -class Client { - constructor(opts) { - this.secretKey = opts.secretKey; - this.publicKey = opts.publicKey; - - const apiHost = 'api.pipedream.com'; - this.baseURL = `https://${apiHost}`; - } - - _authorizationHeader() { - const encoded = Buffer.from(`${this.publicKey}:${this.secretKey}`).toString('base64'); - return `Basic ${encoded}`; - } - - async connectTokenCreate(opts) { - const auth = this._authorizationHeader(); - const response = await fetch(`${this.baseURL}/v1/connect/tokens`, { - method: 'POST', - headers: { - 'Authorization': auth, - 'Content-Type': 'application/json', - }, - body: JSON.stringify(opts), - }); - - return response.json(); - } -} +import { createBackendClient } from "@pipedream/sdk"; -const client = new Client({ - publicKey: 'YOUR_PUBLIC_KEY', - secretKey: 'YOUR_SECRET_KEY', +// These secrets should be saved securely and passed to your environment +const pd = createBackendClient({ + credentials: { + clientId: "YOUR_CLIENT_ID", + clientSecret: "YOUR_CLIENT_SECRET", + }, }); -const connectTokenOpts = { - external_id: "USER_ID" // The end user's ID in your system -} - -// Expose this code as an API endpoint in your server to fetch the token from the frontend -client.connectTokenCreate(connectTokenOpts) - .then(response => { - // return the token to the frontend - }) - .catch(error => { - // handle errors - }); -``` - - -```python -import base64 -import json -import requests - -class Client: - def __init__(self, opts): - self.secret_key = opts['secret_key'] - self.public_key = opts['public_key'] - - api_host = 'api.pipedream.com' - self.base_url = f"https://{api_host}" - - def _authorization_header(self): - encoded = base64.b64encode(f"{self.public_key}:{self.secret_key}".encode()).decode() - return f"Basic {encoded}" - - def connect_token_create(self, opts): - auth = self._authorization_header() - response = requests.post( - f"{self.base_url}/v1/connect/tokens", - headers={ - "Authorization": auth, - "Content-Type": "application/json", - }, - data=json.dumps(opts) - ) - return response.json() - -# Usage example -client = Client({ - 'public_key': 'YOUR_PUBLIC_KEY', - 'secret_key': 'YOUR_SECRET_KEY', -}) - -connect_token_opts = { - 'external_id': "USER_ID" -} - -# Expose this code as an API endpoint in your server to fetch the token from the frontend -response = client.connect_token_create(connect_token_opts) - +await pd.invokeWorkflowForExternalUser( + "enabc123", // pass the endpoint ID or full URL here + "external_user_id" // The end user's ID in your system + { + method: "POST", + body: { + key: "value", + } + }, + "oauth" // Will automatically send the Authorization header with a fresh token +) ``` - -```java -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Base64; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; - -public class Client { - private String secretKey; - private String publicKey; - private String baseURL; - - public Client(String secretKey, String publicKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - - String apiHost = "api.pipedream.com"; - this.baseURL = "https://" + apiHost; - } + - private String authorizationHeader() { - String encoded = Base64.getEncoder().encodeToString((publicKey + ":" + secretKey).getBytes(StandardCharsets.UTF_8)); - return "Basic " + encoded; - } +See the [workflow invocation docs](/workflows/triggers#oauth) for more details. - public String connectTokenCreate(String externalId) throws Exception { - String auth = authorizationHeader(); - URL url = new URL(baseURL + "/v1/connect/tokens"); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Authorization", auth); - conn.setRequestProperty("Content-Type", "application/json"); - conn.setDoOutput(true); +### Tokens - String jsonInputString = String.format("{\"external_id\":\"%s\"}", externalId); +Your app will initiate the account connection flow for your end users in your frontend. To securely scope connection to a specific end user, on your server, **you retrieve a short-lived token for that user**, and return that token to your frontend. - try (OutputStream os = conn.getOutputStream()) { - byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8); - os.write(input, 0, input.length); - } +See [the Connect tokens docs](/connect/tokens) for more information. - return new String(conn.getInputStream().readAllBytes(), StandardCharsets.UTF_8); - } +#### Create a new token - public static void main(String[] args) throws Exception { - Client client = new Client("YOUR_SECRET_KEY", "YOUR_PUBLIC_KEY"); +``` +POST /{project_id}/tokens +``` - // Expose this code as an API endpoint in your server to fetch the token from the frontend - String response = client.connectTokenCreate("USER_ID"); - } -} +##### Path parameters -``` - - -```csharp -using System; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; - -public class Client { - private string secretKey; - private string publicKey; - private string baseURL; - - public Client(string secretKey, string publicKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - - string apiHost = "api.pipedream.com"; - this.baseURL = $"https://{apiHost}"; - } +`project_id` **string** - private string AuthorizationHeader() { - string encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{publicKey}:{secretKey}")); - return $"Basic {encoded}"; - } +[The project's ID](/projects#finding-your-projects-id) - public async Task ConnectTokenCreate(string externalId) { - string auth = AuthorizationHeader(); - using (HttpClient client = new HttpClient()) { - client.DefaultRequestHeaders.Add("Authorization", auth); - client.DefaultRequestHeaders.Add("Content-Type", "application/json"); +##### Body parameters - var content = new StringContent($"{{\"external_id\":\"{externalId}\"}}", Encoding.UTF8, "application/json"); - var response = await client.PostAsync($"{baseURL}/v1/connect/tokens", content); +`external_user_id` **string** - return await response.Content.ReadAsStringAsync(); - } - } +The ID of your end user. Use whatever ID uniquely identifies the user in your system. - public static async Task Main(string[] args) { - var client = new Client("YOUR_SECRET_KEY", "YOUR_PUBLIC_KEY"); +--- - // Expose this code as an API endpoint in your server to fetch the token from the frontend - string response = await client.ConnectTokenCreate("USER_ID"); - } -} +`success_redirect_uri` **string** (_optional_) -``` - - -```go -package main - -import ( - "bytes" - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" -) +When using [Connect Link](/connect/connect-link), you can optionally redirect your end user to the `success_redirect_uri` on successful completion of the auth flow. -type Client struct { - SecretKey string - PublicKey string - BaseURL string -} +--- -func NewClient(secretKey, publicKey string) *Client { - apiHost := "api.pipedream.com" - baseURL := fmt.Sprintf("https://%s", apiHost) +`error_redirect_uri` **string** (_optional_) - return &Client{ - PublicKey: publicKey, - SecretKey: secretKey, - } -} +When using [Connect Link](/connect/connect-link), you can optionally redirect your end user to the `error_redirect_uri` on any errors in the auth flow. This lets you handle errors in whatever way you want in your own app. -func (c *Client) authorizationHeader() string { - encoded := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", c.PublicKey, c.SecretKey))) - return fmt.Sprintf("Basic %s", encoded) -} +--- -func (c *Client) ConnectTokenCreate(externalId string) (map[string]interface{}, error) { - auth := c.authorizationHeader() - url := fmt.Sprintf("%s/v1/connect/tokens", c.BaseURL) +`webhook_uri` **string** (_optional_) - opts := map[string]string{ - "external_id": externalId, - } +Pipedream will send events on successful auth, or any errors, to this URL via webhook. [See the webhooks docs](/connect/webhooks) for more information. - jsonData, err := json.Marshal(opts) - if err != nil { - return nil, err - } +--- - req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) - if err != nil { - return nil, err - } +`project_environment` **string** (_optional_) - req.Header.Set("Authorization", auth) - req.Header.Set("Content-Type", "application/json") +Specify the environment (`production` or `development`) to use for the account connection flow. Defaults to `production`. - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() +##### Examples - body, _ := ioutil.ReadAll(resp.Body) +To create a short-lived token via TypeScript / JavaScript SDK, you'll need to create a Pipedream API client and call the `createConnectToken` method. In our example app, this code is in `app/server.ts`. - var result map[string]interface{} - json.Unmarshal(body, &result) - return result, nil -} +In other languages, you'll need to make an HTTP POST request to the `/tokens` endpoint to create a token, then return the token to your frontend. Click into other tabs to see examples in additional languages. -func main() { - client := NewClient("YOUR_SECRET_KEY", "YOUR_PUBLIC_KEY") + + +```typescript +import { + createBackendClient, + type ConnectAPIResponse, + type ConnectTokenCreateOpts, + type ConnectTokenResponse, +} from "@pipedream/sdk"; - // Expose this code as an API endpoint in your server to fetch the token from the frontend - response, err := client.ConnectTokenCreate( "USER_ID") - if err != nil { - fmt.Println("Error:", err) - return - } -} +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", + } +}); +const { token, expires_at } = await pd.createConnectToken({ + project_id: "your-project-id", + external_user_id: "your-external-user-id" // The end user's ID in your system +}); ``` -```php -publicKey = $publicKey; - $this->secretKey = $secretKey; - - $apiHost = 'api.pipedream.com'; - $this->baseURL = "https://$apiHost"; - } - - private function authorizationHeader() { - $encoded = base64_encode("$this->publicKey:$this->secretKey"); - return "Basic $encoded"; - } - - public function connectTokenCreate($externalId) { - $auth = $this->authorizationHeader(); - $url = "$this->baseURL/v1/connect/tokens"; - - $data = json_encode([ - 'external_id' => $externalId - ]); - - $options = [ - 'http' => [ - 'header' => [ - "Authorization: $auth", - "Content-Type: application/json", - ], - 'method' => 'POST', - 'content' => $data, - ], - ]; - - $context = stream_context_create($options); - $result = file_get_contents($url, false, $context); - - return json_decode($result, true); - } -} - -// Usage example -$client = new Client('YOUR_SECRET_KEY', 'YOUR_PUBLIC_KEY'); +```javascript +import { createBackendClient } from "@pipedream/sdk"; -$connectTokenOpts = [ - 'external_id' => "USER_ID" -]; +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", + }, +}); -// Expose this code as an API endpoint in your server to fetch the token from the frontend -$response = $client->connectTokenCreate($connectTokenOpts['external_id']); -?> +const { token, expires_at } = await pd.createConnectToken({ + project_id: "your-project-id", + external_user_id: "your-external-user-id", // The end user's ID in your system +}); ``` -```ruby -require 'base64' -require 'json' -require 'net/http' -require 'uri' - -class Client - def initialize(secret_key, public_key) - @public_key = public_key - @secret_key = secret_key - - api_host = 'api.pipedream.com' - @base_url = "https://#{api_host}" - end - - def authorization_header - encoded = Base64.strict_encode64("#{@public_key}:#{@secret_key}") - "Basic #{encoded}" - end - - def connect_token_create(app_slug, oauth_app_id, external_id) - uri = URI("#{@base_url}/v1/connect/tokens") - req = Net::HTTP::Post.new(uri) - req['Authorization'] = authorization_header - req['Content-Type'] = 'application/json' - req.body = { external_id: external_id }.to_json - - res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| - http.request(req) - end - - JSON.parse(res.body) - end -end - -client = Client.new('YOUR_SECRET_KEY', 'YOUR_PUBLIC_KEY') - -connect_token_opts = { - external_id: "USER_ID" -} +```bash +# First, obtain an OAuth access token +curl -X POST https://api.pipedream.com/v1/oauth/token \ + -H "Content-Type: application/json" \ + -d '{ + "grant_type": "client_credentials", + "client_id": "{oauth_client_id}", + "client_secret": "{oauth_client_secret}" + }' -# Expose this code as an API endpoint in your server to fetch the token from the frontend -response = client.connect_token_create(connect_token_opts[:external_id]) +# The response will include an access_token. Use it in the Authorization header below. + +curl -X POST https://api.pipedream.com/v1/connect/{project_id}/tokens \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer {access_token}" \ + -d '{ + "external_user_id": "your-external-user-id" + }' ``` @@ -576,410 +301,102 @@ response = client.connect_token_create(connect_token_opts[:external_id]) #### List all accounts -List all connected accounts for all end users within your project - - -This endpoint is not currently paginated, so we'll attempt to return all connected accounts for all users within your project. We intend to add pagination soon. - +List all connected accounts for all end users within a project. ``` -GET /accounts/ +GET /{project_id}/accounts/ ``` -##### Parameters - -- `include_credentials` — _Optional_. Pass `include_credentials=1` as a query-string parameter to include the account credentials in the response +##### Path parameters -##### Examples - - - -```typescript -import { - createClient, -} from "@pipedream/sdk"; +`project_id` **string** -const pd = createClient({ - publicKey: "YOUR_PUBLIC_KEY", - secretKey: "YOUR_SECRET_KEY", -}); +[The project's ID](/projects#finding-your-projects-id) -export async function getAccounts(include_credentials: number = 0) { - const accounts = await pd.getAccounts({ - include_credentials, // set to 1 to include credentials - }); +##### Query parameters - // Parse and return the data you need. These may contain credentials, - // which you should never return to the client - return accounts; -} +`app` **string** (_optional_) -``` - - -```javascript -const fetch = require('node-fetch'); +The ID or name slug the app you'd like to retrieve. For example, Slack's unique app ID is `app_OkrhR1`, and its name slug is `slack`. -class Client { - constructor({ publicKey, secretKey }) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = 'https://api.pipedream.com/v1'; - } +You can find the app's ID in the response from the [List apps](#list-apps) endpoint, and the name slug under the **Authentication** section of any [app page](https://pipedream.com/apps). - _authorizationHeader() { - const encoded = Buffer.from(`${this.publicKey}:${this.secretKey}`).toString('base64'); - return `Basic ${encoded}`; - } +--- - async getAccounts() { - const auth = this._authorizationHeader(); - const url = `${this.baseURL}/connect/accounts?include_credentials=1`; +`oauth_app_id` **string** (_optional_) - const response = await fetch(url, { - method: 'GET', - headers: { - 'Authorization': auth, - 'Content-Type': 'application/json', - }, - }); +The ID of the custom [OAuth app](/connect/quickstart#creating-a-custom-oauth-client) you'd like to retrieve accounts for. - const data = await response.json(); +--- - if (!data?.accounts?.length) { - return null; - } +`external_user_id` **string** (_optional_) - // Parse and return data.accounts. Ensure to handle sensitive data appropriately. - return data.accounts; - } -} +[The external user ID](/connect/api/#external-users) in your system that you want to retrieve accounts for. -// Usage example -const client = new Client({ - publicKey: 'YOUR_PUBLIC_KEY', - secretKey: 'YOUR_SECRET_KEY', -}); +--- -client.getAccounts() - .then(accounts => { - console.log(accounts); - }) - .catch(error => { - console.error('Error:', error); - }); -``` - - -```python -import base64 -import requests - -class Client: - def __init__(self, public_key, secret_key): - self.public_key = public_key - self.secret_key = secret_key - self.base_url = "https://api.pipedream.com/v1" - - def _authorization_header(self): - encoded = base64.b64encode(f"{self.public_key}:{self.secret_key}".encode()).decode() - return f"Basic {encoded}" - - def get_accounts(self): - auth = self._authorization_header() - url = f"{self.base_url}/connect/accounts?include_credentials=1" - response = requests.get(url, headers={"Authorization": auth}) - data = response.json() - - if not data.get('accounts'): - return None - - # Parse and return data['accounts']. Ensure to handle sensitive data appropriately. - return data['accounts'] - -# Usage example -client = Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -accounts = client.get_accounts() -print(accounts) -``` - - -```java -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Base64; -import java.io.InputStreamReader; -import java.io.BufferedReader; -import java.nio.charset.StandardCharsets; - -public class Client { - private String publicKey; - private String secretKey; - private String baseURL; - - public Client(String publicKey, String secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com/v1"; - } +`include_credentials` **boolean** (_optional_) - private String authorizationHeader() { - String encoded = Base64.getEncoder().encodeToString((publicKey + ":" + secretKey).getBytes(StandardCharsets.UTF_8)); - return "Basic " + encoded; - } +Pass `include_credentials=true` as a query-string parameter to include the account credentials in the response - public String getAccounts() throws Exception { - String auth = authorizationHeader(); - URL url = new URL(baseURL + "/connect/accounts?include_credentials=1"); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("GET"); - conn.setRequestProperty("Authorization", auth); - - BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); - String inputLine; - StringBuilder content = new StringBuilder(); - while ((inputLine = in.readLine()) != null) { - content.append(inputLine); - } - in.close(); - - String response = content.toString(); - - // Parse response and return accounts data. Ensure to handle sensitive data appropriately. - if (!response.contains("accounts")) { - return null; - } - - return response; // Modify to parse and handle accounts as needed. - } +##### Examples - public static void main(String[] args) throws Exception { - Client client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - String response = client.getAccounts(); - System.out.println(response); - } -} -``` - + -```csharp -using System; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; - -public class Client { - private string publicKey; - private string secretKey; - private string baseURL; - - public Client(string publicKey, string secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com/v1"; - } - - private string AuthorizationHeader() { - string encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{publicKey}:{secretKey}")); - return $"Basic {encoded}"; - } - - public async Task GetAccounts() { - string auth = AuthorizationHeader(); - using (HttpClient client = new HttpClient()) { - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); - HttpResponseMessage response = await client.GetAsync($"{baseURL}/connect/accounts?include_credentials=1"); - - string result = await response.Content.ReadAsStringAsync(); +```typescript +import { + createBackendClient, +} from "@pipedream/sdk"; - // Parse and return accounts data. Ensure to handle sensitive data appropriately. - if (!result.Contains("accounts")) { - return null; - } +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", + } +}); - return result; // Modify to parse and handle accounts as needed. - } - } +const accounts = await pd.getAccounts({ + include_credentials: true, // set to true to include credentials +}); - public static async Task Main(string[] args) { - var client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - string accounts = await client.GetAccounts(); - Console.WriteLine(accounts); - } -} +// Parse and return the data you need. These may contain credentials, +// which you should never return to the client ``` -```go -package main - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" -) - -type Client struct { - PublicKey string - SecretKey string - BaseURL string -} - -func NewClient(publicKey, secretKey string) *Client { - return &Client{ - PublicKey: publicKey, - SecretKey: secretKey, - BaseURL: "https://api.pipedream.com/v1", - } -} - -func (c *Client) authorizationHeader() string { - encoded := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", c.PublicKey, c.SecretKey))) - return fmt.Sprintf("Basic %s", encoded) -} - -func (c *Client) GetAccounts() (map[string]interface{}, error) { - url := fmt.Sprintf("%s/connect/accounts?include_credentials=1", c.BaseURL) - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - - req.Header.Set("Authorization", c.authorizationHeader()) - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - var result map[string]interface{} - err = json.Unmarshal(body, &result) - if err != nil { - return nil, err - } - - if accounts, exists := result["accounts"]; exists { - return accounts.([]interface{}), nil - } - - return nil, nil -} +```javascript +import { createBackendClient } from "@pipedream/sdk"; -func main() { - client := NewClient("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY") +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", + } +}); - accounts, err := client.GetAccounts() - if err != nil { - fmt.Println("Error:", err) - return - } +const accounts = await pd.getAccounts({ + include_credentials: true, // set to true to include credentials +}); - fmt.Println(accounts) -} +// Parse and return the data you need. These may contain credentials, +// which you should never return to the client ``` -```php -publicKey = $publicKey; - $this->secretKey = $secretKey; - $this->baseURL = "https://api.pipedream.com/v1"; - } - - private function authorizationHeader() { - return "Basic " . base64_encode("$this->publicKey:$this->secretKey"); - } - - public function getAccounts() { - $url = "$this->baseURL/connect/accounts?include_credentials=1"; - $opts = [ - 'http' => [ - 'header' => "Authorization: " . $this->authorizationHeader(), - 'method' => 'GET', - ], - ]; - - $context = stream_context_create($opts); - $result = file_get_contents($url, false, $context); - - if ($result === FALSE) { - return null; - } - - $data = json_decode($result, true); - - if (empty($data['accounts'])) { - return null; - } +```bash +# First, obtain an OAuth access token +curl -X POST https://api.pipedream.com/v1/oauth/token \ + -H "Content-Type: application/json" \ + -d '{ + "grant_type": "client_credentials", + "client_id": "{oauth_client_id}", + "client_secret": "{oauth_client_secret}" + }' - return $data['accounts']; // Modify to parse and handle accounts as needed. - } -} +# The response will include an access_token. Use it in the Authorization header below. -// Usage example -$client = new Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY'); -$accounts = $client->getAccounts(); -print_r($accounts); -?> -``` - - -```ruby -require 'base64' -require 'json' -require 'net/http' -require 'uri' - -class Client - def initialize(public_key, secret_key) - @public_key = public_key - @secret_key = secret_key - @base_url = "https://api.pipedream.com/v1" - end - - def authorization_header - encoded = Base64.strict_encode64("#{@public_key}:#{@secret_key}") - "Basic #{encoded}" - end - - def get_accounts - uri = URI("#{@base_url}/connect/accounts?include_credentials=1") - req = Net::HTTP::Get.new(uri) - req['Authorization'] = authorization_header - - res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| - http.request(req) - end - - data = JSON.parse(res.body) - - # Parse and return accounts data. Ensure to handle sensitive data appropriately. - return nil if data['accounts'].nil? || data['accounts'].empty? - - data['accounts'] - end -end - -# Usage example -client = Client.new('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -accounts = client.get_accounts -puts accounts.inspect +curl -X GET "https://api.pipedream.com/v1/connect/{project_id}/accounts/?include_credentials=true" \ + -H "Authorization: Bearer {access_token}" ``` @@ -1060,843 +477,97 @@ puts accounts.inspect } ``` -#### List all accounts for an app +#### Retrieve account details by ID + +Retrieve the account details for a specific account based on the account ID ``` -GET /apps/:app_id/accounts -``` +GET /{project_id}/accounts/{account_id} +``` + +##### Path parameters + +`project_id` **string** + +[The project's ID](/projects#finding-your-projects-id) + +--- + +`account_id` **string** + +The ID of the account you want to retrieve + ##### Parameters -- `app_id` — the `oauth_app_id` for [OAuth apps](/connect/quickstart#creating-a-custom-oauth-client) or [name slug](/connect/quickstart/#find-your-apps-name-slug) for key-based apps -- `include_credentials` — _Optional_. Pass `include_credentials=1` as a query-string parameter to include the account credentials in the response +`include_credentials` **boolean** (_optional_) + +Pass `include_credentials=true` as a query-string parameter to include the account credentials in the response. ##### Examples - + ```typescript import { - createClient, + createBackendClient, } from "@pipedream/sdk"; -const pd = createClient({ - publicKey: "YOUR_PUBLIC_KEY", - secretKey: "YOUR_SECRET_KEY", +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", + } }); -export async function getAccountsByApp(appId: string, include_credentials: number = 0) { - const accounts = await pd.getAccountsByApp(appId, { - include_credentials, // set to 1 to include credentials - }); - - // Parse and return the data you need. These may contain credentials, - // which you should never return to the client - return accounts; -} +const account = await pd.getAccount(accountId, { + include_credentials: true, // set to true to include credentials +}); +// Parse and return the data you need. These may contain credentials, +// which you should never return to the client ``` ```javascript -const fetch = require('node-fetch'); +import { createBackendClient } from "@pipedream/sdk"; -class Client { - constructor({ publicKey, secretKey }) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = 'https://api.pipedream.com/v1'; +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", } +}); - _authorizationHeader() { - const encoded = Buffer.from(`${this.publicKey}:${this.secretKey}`).toString('base64'); - return `Basic ${encoded}`; - } - - async getAccountsByApp(appId) { - const auth = this._authorizationHeader(); - const url = `${this.baseURL}/connect/accounts/app/${appId}?include_credentials=1`; - - const response = await fetch(url, { - method: 'GET', - headers: { - 'Authorization': auth, - 'Content-Type': 'application/json', - }, - }); - - const data = await response.json(); - - if (!data?.accounts?.length) { - return null; - } - - // Parse and return data.accounts. Ensure to handle sensitive data appropriately. - return data.accounts; - } -} +const accountId = "{account_id}"; // Replace with your account ID -// Usage example -const client = new Client({ - publicKey: 'YOUR_PUBLIC_KEY', - secretKey: 'YOUR_SECRET_KEY', +const account = await pd.getAccount(accountId, { + include_credentials: true, // set to true to include credentials }); -client.getAccountsByApp('APP_ID') - .then(accounts => { - console.log(accounts); - }) - .catch(error => { - console.error('Error:', error); - }); -``` - - -```python -import base64 -import requests - -class Client: - def __init__(self, public_key, secret_key): - self.public_key = public_key - self.secret_key = secret_key - self.base_url = "https://api.pipedream.com/v1" - - def _authorization_header(self): - encoded = base64.b64encode(f"{self.public_key}:{self.secret_key}".encode()).decode() - return f"Basic {encoded}" - - def get_accounts_by_app(self, app_id): - auth = self._authorization_header() - url = f"{self.base_url}/connect/accounts/app/{app_id}?include_credentials=1" - response = requests.get(url, headers={"Authorization": auth}) - data = response.json() - - if not data.get('accounts'): - return None - - # Parse and return data['accounts']. Ensure to handle sensitive data appropriately. - return data['accounts'] - -# Usage example -client = Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -accounts = client.get_accounts_by_app('APP_ID') -print(accounts) +// Parse and return the data you need. These may contain credentials, +// which you should never return to the client ``` -```java -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Base64; -import java.io.InputStreamReader; -import java.io.BufferedReader; -import java.nio.charset.StandardCharsets; - -public class Client { - private String publicKey; - private String secretKey; - private String baseURL; - - public Client(String publicKey, String secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com/v1"; - } - - private String authorizationHeader() { - String encoded = Base64.getEncoder().encodeToString((publicKey + ":" + secretKey).getBytes(StandardCharsets.UTF_8)); - return "Basic " + encoded; - } +```bash +# First, obtain an OAuth access token +curl -X POST https://api.pipedream.com/v1/oauth/token \ + -H "Content-Type: application/json" \ + -d '{ + "grant_type": "client_credentials", + "client_id": "{oauth_client_id}", + "client_secret": "{oauth_client_secret}" + }' - public String getAccountsByApp(String appId) throws Exception { - String auth = authorizationHeader(); - URL url = new URL(baseURL + "/connect/accounts/app/" + appId + "?include_credentials=1"); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("GET"); - conn.setRequestProperty("Authorization", auth); - - BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); - String inputLine; - StringBuilder content = new StringBuilder(); - while ((inputLine = in.readLine()) != null) { - content.append(inputLine); - } - in.close(); - - String response = content.toString(); - - // Parse response and return accounts data. Ensure to handle sensitive data appropriately. - if (!response.contains("accounts")) { - return null; - } - - return response; // Modify to parse and handle accounts as needed. - } +# The response will include an access_token. Use it in the Authorization header below. - public static void main(String[] args) throws Exception { - Client client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - String accounts = client.getAccountsByApp("APP_ID"); - System.out.println(accounts); - } -} +curl -X GET "https://api.pipedream.com/v1/connect/{project_id}/accounts/{account_id}?include_credentials=true" \ + -H "Authorization: Bearer {access_token}" ``` - -```csharp -using System; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; - -public class Client { - private string publicKey; - private string secretKey; - private string baseURL; - - public Client(string publicKey, string secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com/v1"; - } - - private string AuthorizationHeader() { - string encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{publicKey}:{secretKey}")); - return $"Basic {encoded}"; - } - - public async Task GetAccountsByApp(string appId) { - string auth = AuthorizationHeader(); - using (HttpClient client = new HttpClient()) { - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); - HttpResponseMessage response = await client.GetAsync($"{baseURL}/connect/accounts/app/{appId}?include_credentials=1"); - - string result = await response.Content.ReadAsStringAsync(); - - // Parse and return accounts data. Ensure to handle sensitive data appropriately. - if (!result.Contains("accounts")) { - return null; - } + - return result; // Modify to parse and handle accounts as needed. - } - } - - public static async Task Main(string[] args) { - var client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - string accounts = await client.GetAccountsByApp("APP_ID"); - Console.WriteLine(accounts); - } -} -``` - - -```go -package main - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" -) - -type Client struct { - PublicKey string - SecretKey string - BaseURL string -} - -func NewClient(publicKey, secretKey string) *Client { - return &Client{ - PublicKey: publicKey, - SecretKey: secretKey, - BaseURL: "https://api.pipedream.com/v1", - } -} - -func (c *Client) authorizationHeader() string { - encoded := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", c.PublicKey, c.SecretKey))) - return fmt.Sprintf("Basic %s", encoded) -} - -func (c *Client) GetAccountsByApp(appId string) (map[string]interface{}, error) { - url := fmt.Sprintf("%s/connect/accounts/app/%s?include_credentials=1", c.BaseURL, appId) - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - - req.Header.Set("Authorization", c.authorizationHeader()) - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - var result map[string]interface{} - err = json.Unmarshal(body, &result) - if err != nil { - return nil, err - } - - if accounts, exists := result["accounts"]; exists { - return accounts.([]interface{}), nil - } - - return nil, nil -} - -func main() { - client := NewClient("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY") - - accounts, err := client.GetAccountsByApp("APP_ID") - if err != nil { - fmt.Println("Error:", err) - return - } - - fmt.Println(accounts) -} -``` - - -```php -publicKey = $publicKey; - $this->secretKey = $secretKey; - $this->baseURL = "https://api.pipedream.com/v1"; - } - - private function authorizationHeader() { - return "Basic " . base64_encode("$this->publicKey:$this->secretKey"); - } - - public function getAccountsByApp($appId) { - $url = "$this->baseURL/connect/accounts/app/$appId?include_credentials=1"; - $opts = [ - 'http' => [ - 'header' => "Authorization: " . $this->authorizationHeader(), - 'method' => 'GET', - ], - ]; - - $context = stream_context_create($opts); - $result = file_get_contents($url, false, $context); - - if ($result === FALSE) { - return null; - } - - $data = json_decode($result, true); - - if (empty($data['accounts'])) { - return null; - } - - return $data['accounts']; // Modify to parse and handle accounts as needed. - } -} - -// Usage example -$client = new Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY'); -$accounts = $client->getAccountsByApp('APP_ID'); -print_r($accounts); -?> -``` - - -```ruby -require 'base64' -require 'json' -require 'net/http' -require 'uri' - -class Client - def initialize(public_key, secret_key) - @public_key = public_key - @secret_key = secret_key - @base_url = "https://api.pipedream.com/v1" - end - - def authorization_header - encoded = Base64.strict_encode64("#{@public_key}:#{@secret_key}") - "Basic #{encoded}" - end - - def get_accounts_by_app(app_id) - uri = URI("#{@base_url}/connect/accounts/app/#{app_id}?include_credentials=1") - req = Net::HTTP::Get.new(uri) - req['Authorization'] = authorization_header - - res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| - http.request(req) - end - - data = JSON.parse(res.body) - - # Parse and return accounts data. Ensure to handle sensitive data appropriately. - return nil if data['accounts'].nil? || data['accounts'].empty? - - data['accounts'] - end -end - -# Usage example -client = Client.new('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -accounts = client.get_accounts_by_app('APP_ID') -puts accounts.inspect -``` - - - -##### Example response - -```json -[ - { - "id": "apn_WYhMlrz", - "name": null, - "external_id": "user-abc-123", - "healthy": true, - "dead": false, - "app": { - "id": "oa_aw4ib2", - "name_slug": "airtable_oauth", - "name": "Airtable", - "auth_type": "oauth", - "description": "Airtable is a low-code platform to build next-gen apps. Move beyond rigid tools, operationalize your critical data, and reimagine workflows with AI.", - "img_src": "https://assets.pipedream.net/s.v0/app_XBxhAl/logo/orig", - "custom_fields_json": "[]", - "categories": ["Productivity"] - }, - "created_at": "2024-08-01T04:04:03.000Z", - "updated_at": "2024-08-01T04:04:03.000Z" - } -] -``` - -#### Retrieve account details by ID - -Retrieve the account details for a specific account based on the account ID - -``` -GET /accounts/:account_id -``` - -##### Parameters - -- `account_id` — the ID of the account you want to retrieve -- `include_credentials` — _Optional_. Pass `include_credentials=1` as a query-string parameter to include the account credentials in the response - -##### Examples - - - -```typescript -import { - createClient, -} from "@pipedream/sdk"; - -const pd = createClient({ - publicKey: "YOUR_PUBLIC_KEY", - secretKey: "YOUR_SECRET_KEY", -}); - -export async function getAccount(accountId: string, include_credentials: number = 0) { - const account = await pd.getAccount(accountId, { - include_credentials, // set to 1 to include credentials - }); - - // Parse and return the data you need. These may contain credentials, - // which you should never return to the client - return account; -} -``` - - -```javascript -const fetch = require('node-fetch'); - -class Client { - constructor({ publicKey, secretKey }) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = 'https://api.pipedream.com/v1'; - } - - _authorizationHeader() { - const encoded = Buffer.from(`${this.publicKey}:${this.secretKey}`).toString('base64'); - return `Basic ${encoded}`; - } - - async getAccount(accountId) { - const auth = this._authorizationHeader(); - const url = `${this.baseURL}/connect/accounts/${accountId}?include_credentials=1`; - - const response = await fetch(url, { - method: 'GET', - headers: { - 'Authorization': auth, - 'Content-Type': 'application/json', - }, - }); - - const data = await response.json(); - - if (!data?.id) { - return null; - } - - // Parse and return data.account. Ensure to handle sensitive data appropriately. - return data; - } -} - -// Usage example -const client = new Client({ - publicKey: 'YOUR_PUBLIC_KEY', - secretKey: 'YOUR_SECRET_KEY', -}); - -client.getAccount('ACCOUNT_ID') - .then(account => { - console.log(account); - }) - .catch(error => { - console.error('Error:', error); - }); -``` - - -```python -import base64 -import requests - -class Client: - def __init__(self, public_key, secret_key): - self.public_key = public_key - self.secret_key = secret_key - self.base_url = "https://api.pipedream.com/v1" - - def _authorization_header(self): - encoded = base64.b64encode(f"{self.public_key}:{self.secret_key}".encode()).decode() - return f"Basic {encoded}" - - def get_account(self, account_id): - auth = self._authorization_header() - url = f"{self.base_url}/connect/accounts/{account_id}?include_credentials=1" - response = requests.get(url, headers={"Authorization": auth}) - data = response.json() - - if not data.get('id'): - return None - - # Parse and return data. Ensure to handle sensitive data appropriately. - return data - -# Usage example -client = Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -account = client.get_account('ACCOUNT_ID') -print(account) -``` - - -```java -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Base64; -import java.io.InputStreamReader; -import java.io.BufferedReader; -import java.nio.charset.StandardCharsets; - -public class Client { - private String publicKey; - private String secretKey; - private String baseURL; - - public Client(String publicKey, String secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com/v1"; - } - - private String authorizationHeader() { - String encoded = Base64.getEncoder().encodeToString((publicKey + ":" + secretKey).getBytes(StandardCharsets.UTF_8)); - return "Basic " + encoded; - } - - public String getAccount(String accountId) throws Exception { - String auth = authorizationHeader(); - URL url = new URL(baseURL + "/connect/accounts/" + accountId + "?include_credentials=1"); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("GET"); - conn.setRequestProperty("Authorization", auth); - - BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); - String inputLine; - StringBuilder content = new StringBuilder(); - while ((inputLine = in.readLine()) != null) { - content.append(inputLine); - } - in.close(); - - String response = content.toString(); - - // Parse response and return account data. Ensure to handle sensitive data appropriately. - if (!response.contains("id")) { - return null; - } - - return response; // Modify to parse and handle account as needed. - } - - public static void main(String[] args) throws Exception { - Client client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - String account = client.getAccount("ACCOUNT_ID"); - System.out.println(account); - } -} -``` - - -```csharp -using System; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; - -public class Client { - private string publicKey; - private string secretKey; - private string baseURL; - - public Client(string publicKey, string secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com/v1"; - } - - private string AuthorizationHeader() { - string encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{publicKey}:{secretKey}")); - return $"Basic {encoded}"; - } - - public async Task GetAccount(string accountId) { - string auth = AuthorizationHeader(); - using (HttpClient client = new HttpClient()) { - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); - HttpResponseMessage response = await client.GetAsync($"{baseURL}/connect/accounts/{accountId}?include_credentials=1"); - - string result = await response.Content.ReadAsStringAsync(); - - // Parse and return account data. Ensure to handle sensitive data appropriately. - if (!result.Contains("id")) { - return null; - } - - return result; // Modify to parse and handle account as needed. - } - } - - public static async Task Main(string[] args) { - var client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - string account = await client.GetAccount("ACCOUNT_ID"); - Console.WriteLine(account); - } -} -``` - - -```go -package main - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" -) - -type Client struct { - PublicKey string - SecretKey string - BaseURL string -} - -func NewClient(publicKey, secretKey string) *Client { - return &Client{ - PublicKey: publicKey, - SecretKey: secretKey, - BaseURL: "https://api.pipedream.com/v1", - } -} - -func (c *Client) authorizationHeader() string { - encoded := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", c.PublicKey, c.SecretKey))) - return fmt.Sprintf("Basic %s", encoded) -} - -func (c *Client) GetAccount(accountId string) (map[string]interface{}, error) { - url := fmt.Sprintf("%s/connect/accounts/%s?include_credentials=1", c.BaseURL, accountId) - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - - req.Header.Set("Authorization", c.authorizationHeader()) - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - var result map[string]interface{} - err = json.Unmarshal(body, &result) - if err != nil { - return nil, err - } - - if id, exists := result["id"]; exists { - return id.(map[string]interface{}), nil - } - - return nil, nil -} - -func main() { - client := NewClient("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY") - - account, err := client.GetAccount("ACCOUNT_ID") - if err != nil { - fmt.Println("Error:", err) - return - } - - fmt.Println(account) -} -``` - - -```php -publicKey = $publicKey; - $this->secretKey = $secretKey; - $this->baseURL = "https://api.pipedream.com/v1"; - } - - private function authorizationHeader() { - return "Basic " . base64_encode("$this->publicKey:$this->secretKey"); - } - - public function getAccount($accountId) { - $url = "$this->baseURL/connect/accounts/$accountId?include_credentials=1"; - $opts = [ - 'http' => [ - 'header' => "Authorization: " . $this->authorizationHeader(), - 'method' => 'GET', - ], - ]; - - $context = stream_context_create($opts); - $result = file_get_contents($url, false, $context); - - if ($result === FALSE) { - return null; - } - - $data = json_decode($result, true); - - if (empty($data['id'])) { - return null; - } - - return $data; // Modify to parse and handle account as needed. - } -} - -// Usage example -$client = new Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY'); -$account = $client->getAccount('ACCOUNT_ID'); -print_r($account); -?> -``` - - -```ruby -require 'base64' -require 'json' -require 'net/http' -require 'uri' - -class Client - def initialize(public_key, secret_key) - @public_key = public_key - @secret_key = secret_key - @base_url = "https://api.pipedream.com/v1" - end - - def authorization_header - encoded = Base64.strict_encode64("#{@public_key}:#{@secret_key}") - "Basic #{encoded}" - end - - def get_account(account_id) - uri = URI("#{@base_url}/connect/accounts/#{account_id}?include_credentials=1") - req = Net::HTTP::Get.new(uri) - req['Authorization'] = authorization_header - - res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| - http.request(req) - end - - data = JSON.parse(res.body) - - # Parse and return account data. Ensure to handle sensitive data appropriately. - return nil if data['id'].nil? - - data - end -end - -# Usage example -client = Client.new('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -account = client.get_account('ACCOUNT_ID') -puts account.inspect -``` - - - -##### Example response (without account credentials) +##### Example response (without account credentials) ```json { @@ -1914,915 +585,116 @@ puts account.inspect "description": "Airtable is a low-code platform to build next-gen apps. Move beyond rigid tools, operationalize your critical data, and reimagine workflows with AI.", "img_src": "https://assets.pipedream.net/s.v0/app_XBxhAl/logo/orig", "custom_fields_json": "[]", - "categories": ["Productivity"] - }, - "created_at": "2024-08-01T04:04:03.000Z", - "updated_at": "2024-08-01T04:04:03.000Z" - } -} -``` - -##### Example Response (with `include_credentials=1`) - -```json -{ - "data": { - "id": "apn_WYhMlrz", - "name": null, - "external_id": "user-abc-123", - "healthy": true, - "dead": false, - "app": { - "id": "app_XBxhAl", - "name": "Airtable" - }, - "created_at": "2024-08-01T04:04:03.000Z", - "updated_at": "2024-08-01T04:04:03.000Z", - "credentials": { - "oauth_client_id": "dd7a26ca-ba11-4f80-8667-xxxxxxxx", - "oauth_access_token": "oaaLa2Ob1umiregWa.v1.xxxxxxxx.xxxxxxxx", - "oauth_refresh_token": "oaaLa2Ob1umiregWa.v1.refresh.xxxxxxxx", - "oauth_uid": "usrnbIhrxxxxxxxx" - }, - "expires_at": "2024-08-01T05:04:03.000Z", - "project_id": 279440, - "user_id": "danny", - "error": null, - "last_refreshed_at": null, - "next_refresh_at": "2024-08-01T04:17:33.000Z" - } -} -``` - -#### Retrieve accounts for an external user - -Retrieve the account details for a specific account based on the external user ID - -``` -GET /users/:external_id/accounts -``` - -##### Parameters - -- `external_id` — [The external user ID](#external-users) in your system -- `include_credentials` — _Optional_. Pass `?include_credentials=1` as a query-string parameter to include the account credentials in the response - -##### Examples - - - -```typescript -import { - createClient, -} from "@pipedream/sdk"; - -const pd = createClient({ - publicKey: PIPEDREAM_PROJECT_PUBLIC_KEY, - secretKey: PIPEDREAM_PROJECT_SECRET_KEY, -}); - -export async function getUserAccounts(externalId: string, include_credentials: number = 0) { - await pd.getAccountsByExternalId(externalId, { - include_credentials, // set to 1 to include credentials - }) - - // Parse and return the data you need. These may contain credentials, - // which you should never return to the client -} -``` - - -```javascript -const fetch = require('node-fetch'); - -class Client { - constructor({ publicKey, secretKey }) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = 'https://api.pipedream.com'; - } - - _authorizationHeader() { - const encoded = Buffer.from(`${this.publicKey}:${this.secretKey}`).toString('base64'); - return `Basic ${encoded}`; - } - - async getUserAccounts(externalId) { - const auth = this._authorizationHeader(); - const url = `${this.baseURL}/v1/connect/users/${externalId}/accounts`; - - const response = await fetch(url, { - method: 'GET', - headers: { - 'Authorization': auth, - 'Content-Type': 'application/json', - }, - }); - - const data = await response.json(); - - if (!data?.accounts?.length) { - return null; - } - - // Parse and return data.accounts. Ensure to handle sensitive data appropriately. - return data.accounts; - } -} - -// Usage example -const client = new Client({ - publicKey: 'YOUR_PUBLIC_KEY', - secretKey: 'YOUR_SECRET_KEY', -}); - -client.getUserAccounts('USER_ID') - .then(response => { - // handle response - }) - .catch(error => { - console.error('Error:', error); - }); -``` - - -```python -import base64 -import requests - -class Client: - def __init__(self, public_key, secret_key): - self.public_key = public_key - self.secret_key = secret_key - self.base_url = "https://api.pipedream.com" - - def _authorization_header(self): - encoded = base64.b64encode(f"{self.public_key}:{self.secret_key}".encode()).decode() - return f"Basic {encoded}" - - def get_user_accounts(self, external_id): - auth = self._authorization_header() - url = f"{self.base_url}/v1/connect/users/{external_id}/accounts" - response = requests.get(url, headers={"Authorization": auth}) - data = response.json() - - if not data.get('accounts'): - return None - - # Parse and return data['accounts']. Ensure to handle sensitive data appropriately. - return data['accounts'] - -# Usage example -client = Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -response = client.get_user_accounts('USER_ID') -``` - - -```java -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Base64; -import java.io.InputStreamReader; -import java.io.BufferedReader; -import java.nio.charset.StandardCharsets; - -public class Client { - private String publicKey; - private String secretKey; - private String baseURL; - - public Client(String publicKey, String secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com"; - } - - private String authorizationHeader() { - String encoded = Base64.getEncoder().encodeToString((publicKey + ":" + secretKey).getBytes(StandardCharsets.UTF_8)); - return "Basic " + encoded; - } - - public String getUserAccounts(String externalId) throws Exception { - String auth = authorizationHeader(); - URL url = new URL(baseURL + "/v1/connect/users/" + externalId + "/accounts"); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("GET"); - conn.setRequestProperty("Authorization", auth); - - BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); - String inputLine; - StringBuilder content = new StringBuilder(); - while ((inputLine = in.readLine()) != null) { - content.append(inputLine); - } - in.close(); - - String response = content.toString(); - - // Parse response and return accounts data. Ensure to handle sensitive data appropriately. - if (!response.contains("accounts")) { - return null; - } - - return response; // Modify to parse and handle accounts as needed. - } - - public static void main(String[] args) throws Exception { - Client client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - String response = client.getUserAccounts("USER_ID"); - } -} -``` - - -```csharp -using System; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; - -public class Client { - private string publicKey; - private string secretKey; - private string baseURL; - - public Client(string publicKey, string secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com"; - } - - private string AuthorizationHeader() { - string encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{publicKey}:{secretKey}")); - return $"Basic {encoded}"; - } - - public async Task GetUserAccounts(string externalId) { - string auth = AuthorizationHeader(); - using (HttpClient client = new HttpClient()) { - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); - HttpResponseMessage response = await client.GetAsync($"{baseURL}/v1/connect/users/{externalId}/accounts"); - - string result = await response.Content.ReadAsStringAsync(); - - // Parse and return accounts data. Ensure to handle sensitive data appropriately. - if (!result.Contains("accounts")) { - return null; - } - - return result; // Modify to parse and handle accounts as needed. - } - } - - public static async Task Main(string[] args) { - var client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - string response = await client.GetUserAccounts("USER_ID"); - } -} -``` - - -```go -package main - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" -) - -type Client struct { - PublicKey string - SecretKey string - BaseURL string -} - -func NewClient(publicKey, secretKey string) *Client { - return &Client{ - PublicKey: publicKey, - SecretKey: secretKey, - BaseURL: "https://api.pipedream.com", - } -} - -func (c *Client) authorizationHeader() string { - encoded := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", c.PublicKey, c.SecretKey))) - return fmt.Sprintf("Basic %s", encoded) -} - -func (c *Client) GetUserAccounts(externalId string) (map[string]interface{}, error) { - url := fmt.Sprintf("%s/v1/connect/users/%s/accounts", c.BaseURL, externalId) - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - - req.Header.Set("Authorization", c.authorizationHeader()) - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - var result map[string]interface{} - err = json.Unmarshal(body, &result) - if err != nil { - return nil, err - } - - if accounts, exists := result["accounts"]; exists { - return accounts.([]interface{}), nil - } - - return nil, nil -} - -func main() { - client := NewClient("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY") - - accounts, err := client.GetUserAccounts("USER_ID") - if err != nil { - fmt.Println("Error:", err) - return - } -} -``` - - -```php -publicKey = $publicKey; - $this->secretKey = $secretKey; - $this->baseURL = "https://api.pipedream.com"; - } - - private function authorizationHeader() { - return "Basic " . base64_encode("$this->publicKey:$this->secretKey"); - } - - public function getUserAccounts($externalId) { - $url = "$this->baseURL/v1/connect/users/$externalId/accounts"; - $opts = [ - 'http' => [ - 'header' => "Authorization: " . $this->authorizationHeader(), - 'method' => 'GET', - ], - ]; - - $context = stream_context_create($opts); - $result = file_get_contents($url, false, $context); - - if ($result === FALSE) { - return null; - } - - $data = json_decode($result, true); - - if (empty($data['accounts'])) { - return null; - } - - return $data['accounts']; // Modify to parse and handle accounts as needed. - } -} - -// Usage example -$client = new Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY'); -$response = $client->getUserAccounts('USER_ID'); -?> -``` - - -```ruby -require 'base64' -require 'json' -require 'net/http' -require 'uri' - -class Client - def initialize(public_key, secret_key) - @public_key = public_key - @secret_key = secret_key - @base_url = "https://api.pipedream.com" - end - - def authorization_header - encoded = Base64.strict_encode64("#{@public_key}:#{@secret_key}") - "Basic #{encoded}" - end - - def get_user_accounts(external_id) - uri = URI("#{@base_url}/v1/connect/users/#{external_id}/accounts") - req = Net::HTTP::Get.new(uri) - req['Authorization'] = authorization_header - - res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| - http.request(req) - end - - data = JSON.parse(res.body) - - # Parse and return accounts data. Ensure to handle sensitive data appropriately. - return nil if data['accounts'].nil? || data['accounts'].empty? - - data['accounts'] - end -end - -# Usage example -client = Client.new('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -response = client.get_user_accounts('USER_ID') -``` - - - -##### Example response (without account credentials) - -```json -[ - { - "id": "apn_WYhM5ov", - "name": null, - "external_id": "user-abc-123", - "healthy": true, - "dead": false, - "app": { - "id": "oa_aw4ib2", - "name_slug": "airtable_oauth", - "name": "Airtable", - "auth_type": "oauth", - "description": "Airtable is a low-code platform to build next-gen apps. Move beyond rigid tools, operationalize your critical data, and reimagine workflows with AI.", - "img_src": "https://assets.pipedream.net/s.v0/app_XBxhAl/logo/orig", - "custom_fields_json": "[]", - "categories": [ - "Productivity" - ] - }, - "created_at": "2024-08-06T21:51:30.000Z", - "updated_at": "2024-08-06T21:51:30.000Z", - "expires_at": "2024-08-06T22:51:30.000Z", - "error": null, - "last_refreshed_at": null, - "next_refresh_at": "2024-08-06T22:04:41.000Z" - }, - { - "id": "apn_KAh7JwW", - "name": null, - "external_id": "user-abc-123", - "healthy": true, - "dead": false, - "app": { - "id": "oa_aPXiQd", - "name_slug": "github", - "name": "GitHub", - "auth_type": "oauth", - "description": "Where the world builds software. Millions of developers and companies build, ship, and maintain their software on GitHub—the largest and most advanced development platform in the world.", - "img_src": "https://assets.pipedream.net/s.v0/app_OrZhaO/logo/orig", - "custom_fields_json": "[]", - "categories": [ - "Developer Tools" - ] + "categories": ["Productivity"] }, - "created_at": "2024-08-06T21:53:05.000Z", - "updated_at": "2024-08-06T21:53:05.000Z", - "expires_at": null, - "error": null, - "last_refreshed_at": null, - "next_refresh_at": "2024-08-06T22:50:01.000Z" + "created_at": "2024-08-01T04:04:03.000Z", + "updated_at": "2024-08-01T04:04:03.000Z" } -] +} ``` -##### Example Response (with `include_credentials=1`) +##### Example Response (with `include_credentials=true`) ```json -[ - { - "id": "apn_WYhM5ov", +{ + "data": { + "id": "apn_WYhMlrz", "name": null, "external_id": "user-abc-123", "healthy": true, "dead": false, "app": { - "id": "oa_aw4ib2", - "name_slug": "airtable_oauth", - "name": "Airtable", - "auth_type": "oauth", - "description": "Airtable is a low-code platform to build next-gen apps. Move beyond rigid tools, operationalize your critical data, and reimagine workflows with AI.", - "img_src": "https://assets.pipedream.net/s.v0/app_XBxhAl/logo/orig", - "custom_fields_json": "[]", - "categories": [ - "Productivity" - ] + "id": "app_XBxhAl", + "name": "Airtable" }, - "created_at": "2024-08-06T21:51:30.000Z", - "updated_at": "2024-08-06T21:51:30.000Z", + "created_at": "2024-08-01T04:04:03.000Z", + "updated_at": "2024-08-01T04:04:03.000Z", "credentials": { "oauth_client_id": "dd7a26ca-ba11-4f80-8667-xxxxxxxx", "oauth_access_token": "oaaLa2Ob1umiregWa.v1.xxxxxxxx.xxxxxxxx", "oauth_refresh_token": "oaaLa2Ob1umiregWa.v1.refresh.xxxxxxxx", "oauth_uid": "usrnbIhrxxxxxxxx" }, - "expires_at": "2024-08-06T22:51:30.000Z", - "error": null, - "last_refreshed_at": null, - "next_refresh_at": "2024-08-06T22:04:41.000Z" - }, - { - "id": "apn_KAh7JwW", - "name": null, - "external_id": "user-abc-123", - "healthy": true, - "dead": false, - "app": { - "id": "oa_aPXiQd", - "name_slug": "github", - "name": "GitHub", - "auth_type": "oauth", - "description": "Where the world builds software. Millions of developers and companies build, ship, and maintain their software on GitHub—the largest and most advanced development platform in the world.", - "img_src": "https://assets.pipedream.net/s.v0/app_OrZhaO/logo/orig", - "custom_fields_json": "[]", - "categories": [ - "Developer Tools" - ] - }, - "created_at": "2024-08-06T21:53:05.000Z", - "updated_at": "2024-08-06T21:53:05.000Z", - "credentials": { - "oauth_client_id": "57dc28xxxxxxxxxxxxx", - "oauth_access_token": "gho_xxxxxxxxxxxxxxxxxx", - "oauth_uid": "104484339" - }, - "expires_at": null, + "expires_at": "2024-08-01T05:04:03.000Z", + "project_id": 279440, + "user_id": "danny", "error": null, "last_refreshed_at": null, - "next_refresh_at": "2024-08-06T22:50:01.000Z" + "next_refresh_at": "2024-08-01T04:17:33.000Z" } -] +} ``` #### Delete connected account Delete a specific connected account for an end user -```shell -DELETE /v1/connect/accounts/:account_id +``` +DELETE /{project_id}/accounts/{account_id} ``` -##### Parameters +##### Path parameters + +`project_id` **string** + +[The project's ID](/projects#finding-your-projects-id) -- `account_id` is the ID of the account you want to retrieve +--- + +`account_id` **string** ##### Examples - + ```typescript import { - createClient, + createBackendClient, } from "@pipedream/sdk"; -const pd = createClient({ - publicKey: "YOUR_PUBLIC_KEY", - secretKey: "YOUR_SECRET_KEY", +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", + } }); -export async function deleteAccount(accountId: string) { - await pd.deleteAccount(accountId); - - // You can return a message or handle any post-deletion logic here. -} +await pd.deleteAccount(accountId); +// You can return a message or handle any post-deletion logic here. ``` ```javascript -const fetch = require('node-fetch'); - -class Client { - constructor({ publicKey, secretKey }) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = 'https://api.pipedream.com/v1'; - } - - _authorizationHeader() { - const encoded = Buffer.from(`${this.publicKey}:${this.secretKey}`).toString('base64'); - return `Basic ${encoded}`; - } +import { createBackendClient } from "@pipedream/sdk"; - async deleteAccount(accountId) { - const auth = this._authorizationHeader(); - const url = `${this.baseURL}/connect/accounts/${accountId}`; - - const response = await fetch(url, { - method: 'DELETE', - headers: { - 'Authorization': auth, - }, - }); - - if (response.status === 204) { - console.log("Account deleted successfully."); - } else { - console.log("Failed to delete account."); - } +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", } -} - -// Usage example -const client = new Client({ - publicKey: 'YOUR_PUBLIC_KEY', - secretKey: 'YOUR_SECRET_KEY', }); -client.deleteAccount('ACCOUNT_ID') - .catch(error => { - console.error('Error:', error); - }); -``` - - -```python -import base64 -import requests - -class Client: - def __init__(self, public_key, secret_key): - self.public_key = public_key - self.secret_key = secret_key - self.base_url = "https://api.pipedream.com/v1" - - def _authorization_header(self): - encoded = base64.b64encode(f"{self.public_key}:{self.secret_key}".encode()).decode() - return f"Basic {encoded}" - - def delete_account(self, account_id): - auth = self._authorization_header() - url = f"{self.base_url}/connect/accounts/{account_id}" - response = requests.delete(url, headers={"Authorization": auth}) - - if response.status_code == 204: - print("Account deleted successfully.") - else: - print("Failed to delete account.") - -# Usage example -client = Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -client.delete_account('ACCOUNT_ID') -``` - - -```java -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Base64; -import java.nio.charset.StandardCharsets; - -public class Client { - private String publicKey; - private String secretKey; - private String baseURL; - - public Client(String publicKey, String secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com/v1"; - } - - private String authorizationHeader() { - String encoded = Base64.getEncoder().encodeToString((publicKey + ":" + secretKey).getBytes(StandardCharsets.UTF_8)); - return "Basic " + encoded; - } - - public void deleteAccount(String accountId) throws Exception { - String auth = authorizationHeader(); - URL url = new URL(baseURL + "/connect/accounts/" + accountId); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("DELETE"); - conn.setRequestProperty("Authorization", auth); - - int responseCode = conn.getResponseCode(); - if (responseCode == 204) { - System.out.println("Account deleted successfully."); - } else { - System.out.println("Failed to delete account. Response code: " + responseCode); - } - } - - public static void main(String[] args) throws Exception { - Client client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - client.deleteAccount("ACCOUNT_ID"); - } -} -``` - - -```csharp -using System; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Threading.Tasks; - -public class Client { - private string publicKey; - private string secretKey; - private string baseURL; - - public Client(string publicKey, string secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com/v1"; - } - - private string AuthorizationHeader() { - string encoded = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes($"{publicKey}:{secretKey}")); - return $"Basic {encoded}"; - } - - public async Task DeleteAccount(string accountId) { - string auth = AuthorizationHeader(); - using (HttpClient client = new HttpClient()) { - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); - HttpResponseMessage response = await client.DeleteAsync($"{baseURL}/connect/accounts/{accountId}"); - - if (response.StatusCode == System.Net.HttpStatusCode.NoContent) { - Console.WriteLine("Account deleted successfully."); - } else { - Console.WriteLine("Failed to delete account."); - } - } - } - - public static async Task Main(string[] args) { - var client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - await client.DeleteAccount("ACCOUNT_ID"); - } -} -``` - - -```go -package main - -import ( - "encoding/base64" - "fmt" - "net/http" -) - -type Client struct { - PublicKey string - SecretKey string - BaseURL string -} - -func NewClient(publicKey, secretKey string) *Client { - return &Client{ - PublicKey: publicKey, - SecretKey: secretKey, - BaseURL: "https://api.pipedream.com/v1", - } -} - -func (c *Client) authorizationHeader() string { - encoded := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", c.PublicKey, c.SecretKey))) - return fmt.Sprintf("Basic %s", encoded) -} - -func (c *Client) DeleteAccount(accountId string) error { - url := fmt.Sprintf("%s/connect/accounts/%s", c.BaseURL, accountId) - req, err := http.NewRequest("DELETE", url, nil) - if err != nil { - return err - } - - req.Header.Set("Authorization", c.authorizationHeader()) - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode == http.StatusNoContent { - fmt.Println("Account deleted successfully.") - } else { - fmt.Printf("Failed to delete account. Status code: %d\n", resp.StatusCode) - } - - return nil -} - -func main() { - client := NewClient("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY") +await pd.deleteAccount(accountId); - err := client.DeleteAccount("ACCOUNT_ID") - if err != nil { - fmt.Println("Error:", err) - } -} +// You can return a message or handle any post-deletion logic here. ``` -```php -publicKey = $publicKey; - $this->secretKey = $secretKey; - $this->baseURL = "https://api.pipedream.com/v1"; - } - - private function authorizationHeader() { - return "Basic " . base64_encode("$this->publicKey:$this->secretKey"); - } +```bash +# First, obtain an OAuth access token +curl -X POST https://api.pipedream.com/v1/oauth/token \ + -H "Content-Type: application/json" \ + -d '{ + "grant_type": "client_credentials", + "client_id": "{oauth_client_id}", + "client_secret": "{oauth_client_secret}" + }' - public function deleteAccount($accountId) { - $url = "$this->baseURL/connect/accounts/$accountId"; - $opts = [ - 'http' => [ - 'header' => "Authorization: " . $this->authorizationHeader(), - 'method' => 'DELETE', - ], - ]; - - $context = stream_context_create($opts); - $result = file_get_contents($url, false, $context); - - if ($http_response_header[0] == 'HTTP/1.1 204 No Content') { - echo "Account deleted successfully."; - } else { - echo "Failed to delete account."; - } - } -} +# The response will include an access_token. Use it in the Authorization header below. -// Usage example -$client = new Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY'); -$client->deleteAccount('ACCOUNT_ID'); -?> -``` - - -```ruby -require 'base64' -require 'net/http' -require 'uri' - -class Client - def initialize(public_key, secret_key) - @public_key = public_key - @secret_key = secret_key - @base_url = "https://api.pipedream.com/v1" - end - - def authorization_header - encoded = Base64.strict_encode64("#{@public_key}:#{@secret_key}") - "Basic #{encoded}" - end - - def delete_account(account_id) - uri = URI("#{@base_url}/connect/accounts/#{account_id}") - req = Net::HTTP::Delete.new(uri) - req['Authorization'] = authorization_header - - res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| - http.request(req) - end - - if res.code.to_i == 204 - puts "Account deleted successfully." - else - puts "Failed to delete account. Status code: #{res.code}" - end - end -end - -# Usage example -client = Client.new('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -client.delete_account('ACCOUNT_ID') +curl -X DELETE "https://api.pipedream.com/v1/connect/{project_id}/accounts/{account_id}" \ + -H "Authorization: Bearer {access_token}" ``` @@ -2835,347 +707,74 @@ Pipedream returns a `204 No Content` response on successful account deletion Delete all connected accounts for a specific app -```shell -DELETE /apps/:app_id/accounts +``` +DELETE /{project_id}/apps/{app_id}/accounts ``` -##### Parameters +##### Path parameters + +`project_id` **string** + +[The project's ID](/projects#finding-your-projects-id) + +--- -- `app_id` can be `oauth_app_id` for [OAuth apps](/connect/quickstart#creating-a-custom-oauth-client) or [name slug](/connect/quickstart/#find-your-apps-name-slug) for key-based apps +`app_id` **string** + +The app ID for which you want to delete all connected accounts. `app_id` can be `oauth_app_id` for [OAuth apps](/connect/quickstart#creating-a-custom-oauth-client) or [name slug](/connect/quickstart/#find-your-apps-name-slug) for key-based apps. ##### Examples - + ```typescript import { - createClient, + createBackendClient, } from "@pipedream/sdk"; -const pd = createClient({ - publicKey: "YOUR_PUBLIC_KEY", - secretKey: "YOUR_SECRET_KEY", +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", + } }); -export async function deleteAccountsByApp(appId: string) { - await pd.deleteAccountsByApp(appId); +await pd.deleteAccountsByApp(appId); - // You can return a message or handle any post-deletion logic here. -} +// You can return a message or handle any post-deletion logic here. ``` ```javascript -const fetch = require('node-fetch'); - -class Client { - constructor({ publicKey, secretKey }) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = 'https://api.pipedream.com/v1'; - } - - _authorizationHeader() { - const encoded = Buffer.from(`${this.publicKey}:${this.secretKey}`).toString('base64'); - return `Basic ${encoded}`; - } - - async deleteAccountsByApp(appId) { - const auth = this._authorizationHeader(); - const url = `${this.baseURL}/connect/accounts/app/${appId}`; +import { createBackendClient } from "@pipedream/sdk"; - const response = await fetch(url, { - method: 'DELETE', - headers: { - 'Authorization': auth, - }, - }); - - if (response.status === 204) { - console.log("Accounts deleted successfully."); - } else { - console.log("Failed to delete accounts."); - } +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", } -} - -// Usage example -const client = new Client({ - publicKey: 'YOUR_PUBLIC_KEY', - secretKey: 'YOUR_SECRET_KEY', }); -client.deleteAccountsByApp('APP_ID') - .catch(error => { - console.error('Error:', error); - }); -``` - - -```python -import base64 -import requests - -class Client: - def __init__(self, public_key, secret_key): - self.public_key = public_key - self.secret_key = secret_key - self.base_url = "https://api.pipedream.com/v1" - - def _authorization_header(self): - encoded = base64.b64encode(f"{self.public_key}:{self.secret_key}".encode()).decode() - return f"Basic {encoded}" - - def delete_accounts_by_app(self, app_id): - auth = self._authorization_header() - url = f"{self.base_url}/connect/accounts/app/{app_id}" - response = requests.delete(url, headers={"Authorization": auth}) - - if response.status_code == 204: - print("Accounts deleted successfully.") - else: - print("Failed to delete accounts.") - -# Usage example -client = Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -client.delete_accounts_by_app('APP_ID') -``` - - -```java -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Base64; -import java.nio.charset.StandardCharsets; - -public class Client { - private String publicKey; - private String secretKey; - private String baseURL; - - public Client(String publicKey, String secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com/v1"; - } - - private String authorizationHeader() { - String encoded = Base64.getEncoder().encodeToString((publicKey + ":" + secretKey).getBytes(StandardCharsets.UTF_8)); - return "Basic " + encoded; - } - - public void deleteAccountsByApp(String appId) throws Exception { - String auth = authorizationHeader(); - URL url = new URL(baseURL + "/connect/accounts/app/" + appId); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("DELETE"); - conn.setRequestProperty("Authorization", auth); - - int responseCode = conn.getResponseCode(); - if (responseCode == 204) { - System.out.println("Accounts deleted successfully."); - } else { - System.out.println("Failed to delete accounts. Response code: " + responseCode); - } - } - - public static void main(String[] args) throws Exception { - Client client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - client.deleteAccountsByApp("APP_ID"); - } -} -``` - - -```csharp -using System; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Threading.Tasks; - -public class Client { - private string publicKey; - private string secretKey; - private string baseURL; - - public Client(string publicKey, string secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com/v1"; - } - - private string AuthorizationHeader() { - string encoded = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes($"{publicKey}:{secretKey}")); - return $"Basic {encoded}"; - } - - public async Task DeleteAccountsByApp(string appId) { - string auth = AuthorizationHeader(); - using (HttpClient client = new HttpClient()) { - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); - HttpResponseMessage response = await client.DeleteAsync($"{baseURL}/connect/accounts/app/{appId}"); - - if (response.StatusCode == System.Net.HttpStatusCode.NoContent) { - Console.WriteLine("Accounts deleted successfully."); - } else { - Console.WriteLine("Failed to delete accounts."); - } - } - } - - public static async Task Main(string[] args) { - var client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - await client.DeleteAccountsByApp("APP_ID"); - } -} -``` - - -```go -package main - -import ( - "encoding/base64" - "fmt" - "net/http" -) - -type Client struct { - PublicKey string - SecretKey string - BaseURL string -} - -func NewClient(publicKey, secretKey string) *Client { - return &Client{ - PublicKey: publicKey, - SecretKey: secretKey, - BaseURL: "https://api.pipedream.com/v1", - } -} - -func (c *Client) authorizationHeader() string { - encoded := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", c.PublicKey, c.SecretKey))) - return fmt.Sprintf("Basic %s", encoded) -} - -func (c *Client) DeleteAccountsByApp(appId string) error { - url := fmt.Sprintf("%s/connect/accounts/app/%s", c.BaseURL, appId) - req, err := http.NewRequest("DELETE", url, nil) - if err != nil { - return err - } - - req.Header.Set("Authorization", c.authorizationHeader()) - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode == http.StatusNoContent { - fmt.Println("Accounts deleted successfully.") - } else { - fmt.Printf("Failed to delete accounts. Status code: %d\n", resp.StatusCode) - } - - return nil -} - -func main() { - client := NewClient("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY") +await pd.deleteAccount(accountId); - err := client.DeleteAccountsByApp("APP_ID") - if err != nil { - fmt.Println("Error:", err) - } -} +// You can return a message or handle any post-deletion logic here. ``` -```php -publicKey = $publicKey; - $this->secretKey = $secretKey; - $this->baseURL = "https://api.pipedream.com/v1"; - } - - private function authorizationHeader() { - return "Basic " . base64_encode("$this->publicKey:$this->secretKey"); - } +```bash +# First, obtain an OAuth access token +curl -X POST https://api.pipedream.com/v1/oauth/token \ + -H "Content-Type: application/json" \ + -d '{ + "grant_type": "client_credentials", + "client_id": "{oauth_client_id}", + "client_secret": "{oauth_client_secret}" + }' - public function deleteAccountsByApp($appId) { - $url = "$this->baseURL/connect/accounts/app/$appId"; - $opts = [ - 'http' => [ - 'header' => "Authorization: " . $this->authorizationHeader(), - 'method' => 'DELETE', - ], - ]; - - $context = stream_context_create($opts); - $result = file_get_contents($url, false, $context); - - if ($http_response_header[0] == 'HTTP/1.1 204 No Content') { - echo "Accounts deleted successfully."; - } else { - echo "Failed to delete accounts."; - } - } -} +# The response will include an access_token. Use it in the Authorization header below. -// Usage example -$client = new Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY'); -$client->deleteAccountsByApp('APP_ID'); -?> -``` - - -```ruby -require 'base64' -require 'net/http' -require 'uri' - -class Client - def initialize(public_key, secret_key) - @public_key = public_key - @secret_key = secret_key - @base_url = "https://api.pipedream.com/v1" - end - - def authorization_header - encoded = Base64.strict_encode64("#{@public_key}:#{@secret_key}") - "Basic #{encoded}" - end - - def delete_accounts_by_app(app_id) - uri = URI("#{@base_url}/connect/accounts/app/#{app_id}") - req = Net::HTTP::Delete.new(uri) - req['Authorization'] = authorization_header - - res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| - http.request(req) - end - - if res.code.to_i == 204 - puts "Accounts deleted successfully." - else - puts "Failed to delete accounts. Status code: #{res.code}" - end - end -end - -# Usage example -client = Client.new('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -client.delete_accounts_by_app('APP_ID') +curl -X DELETE "https://api.pipedream.com/v1/connect/{project_id}/accounts/{account_id}" \ + -H "Authorization: Bearer {access_token}" ``` @@ -3188,352 +787,150 @@ Pipedream returns a `204 No Content` response on successful account deletion Delete an end user and all their connected accounts -```shell -DELETE /users/:external_id +``` +DELETE /{project_id}/users/{external_user_id} ``` -##### Parameters +##### Path parameters + +`project_id` **string** + +[The project's ID](/projects#finding-your-projects-id) + +--- + +`external_user_id` **string** -- `external_id` — [The external user ID](#external-users) in your system +[The external user ID](#external-users) in your system ##### Examples - + ```typescript import { - createClient, + createBackendClient, } from "@pipedream/sdk"; -const pd = createClient({ - publicKey: "YOUR_PUBLIC_KEY", - secretKey: "YOUR_SECRET_KEY", +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", + } }); -export async function deleteExternalUser(externalId: string) { - await pd.deleteExternalUser(externalId); - - console.log("All accounts associated with the external ID have been deleted."); -} +await pd.deleteExternalUser(externalId); +console.log("All accounts associated with the external ID have been deleted."); ``` ```javascript -const fetch = require('node-fetch'); - -class Client { - constructor({ publicKey, secretKey }) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = 'https://api.pipedream.com/v1'; - } +import { createBackendClient } from "@pipedream/sdk"; - _authorizationHeader() { - const encoded = Buffer.from(`${this.publicKey}:${this.secretKey}`).toString('base64'); - return `Basic ${encoded}`; +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", } +}); - async deleteExternalUser(externalId) { - const auth = this._authorizationHeader(); - const url = `${this.baseURL}/users/${externalId}`; - - const response = await fetch(url, { - method: 'DELETE', - headers: { - 'Authorization': auth, - }, - }); - - if (response.status === 204) { - console.log("All accounts associated with the external ID have been deleted."); - } else { - console.log("Failed to delete accounts."); - } - } -} +const externalId = "{external_user_id}"; // Replace with your external user ID -// Usage example -const client = new Client({ - publicKey: 'YOUR_PUBLIC_KEY', - secretKey: 'YOUR_SECRET_KEY', -}); +await pd.deleteExternalUser(externalId); -client.deleteExternalUser('EXTERNAL_ID') - .catch(error => { - console.error('Error:', error); - }); +console.log("All accounts associated with the external ID have been deleted."); ``` -```python -import base64 -import requests - -class Client: - def __init__(self, public_key, secret_key): - self.public_key = public_key - self.secret_key = secret_key - self.base_url = "https://api.pipedream.com/v1" - - def _authorization_header(self): - encoded = base64.b64encode(f"{self.public_key}:{self.secret_key}".encode()).decode() - return f"Basic {encoded}" - - def delete_external_user(self, external_id): - auth = self._authorization_header() - url = f"{self.base_url}/users/{external_id}" - response = requests.delete(url, headers={"Authorization": auth}) - - if response.status_code == 204: - print("All accounts associated with the external ID have been deleted.") - else: - print("Failed to delete accounts.") - -# Usage example -client = Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -client.delete_external_user('EXTERNAL_ID') +```bash +# First, obtain an OAuth access token +curl -X POST https://api.pipedream.com/v1/oauth/token \ + -H "Content-Type: application/json" \ + -d '{ + "grant_type": "client_credentials", + "client_id": "{oauth_client_id}", + "client_secret": "{oauth_client_secret}" + }' + +# The response will include an access_token. Use it in the Authorization header below. + +curl -X DELETE "https://api.pipedream.com/v1/connect/{project_id}/users/{external_user_id}" \ + -H "Authorization: Bearer {access_token}" ``` - -```java -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Base64; -import java.nio.charset.StandardCharsets; - -public class Client { - private String publicKey; - private String secretKey; - private String baseURL; - - public Client(String publicKey, String secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com/v1"; - } + - private String authorizationHeader() { - String encoded = Base64.getEncoder().encodeToString((publicKey + ":" + secretKey).getBytes(StandardCharsets.UTF_8)); - return "Basic " + encoded; - } +##### Response - public void deleteExternalUser(String externalId) throws Exception { - String auth = authorizationHeader(); - URL url = new URL(baseURL + "/users/" + externalId); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("DELETE"); - conn.setRequestProperty("Authorization", auth); - - int responseCode = conn.getResponseCode(); - if (responseCode == 204) { - System.out.println("All accounts associated with the external ID have been deleted."); - } else { - System.out.println("Failed to delete accounts. Response code: " + responseCode); - } - } +Pipedream returns a `204 No Content` response on successful account deletion - public static void main(String[] args) throws Exception { - Client client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - client.deleteExternalUser("EXTERNAL_ID"); - } -} -``` - - -```csharp -using System; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Threading.Tasks; - -public class Client { - private string publicKey; - private string secretKey; - private string baseURL; - - public Client(string publicKey, string secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com/v1"; - } +### Projects - private string AuthorizationHeader() { - string encoded = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes($"{publicKey}:{secretKey}")); - return $"Basic {encoded}"; - } +#### Retrieve project info - public async Task DeleteExternalUser(string externalId) { - string auth = AuthorizationHeader(); - using (HttpClient client = new HttpClient()) { - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); - HttpResponseMessage response = await client.DeleteAsync($"{baseURL}/users/{externalId}"); - - if (response.StatusCode == System.Net.HttpStatusCode.NoContent) { - Console.WriteLine("All accounts associated with the external ID have been deleted."); - } else { - Console.WriteLine("Failed to delete accounts."); - } - } - } +Retrieve the configuration for a specific project - public static async Task Main(string[] args) { - var client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - await client.DeleteExternalUser("EXTERNAL_ID"); - } -} ``` - - -```go -package main +GET /{project_id}/info +``` -import ( - "encoding/base64" - "fmt" - "net/http" -) +##### Path parameters -type Client struct { - PublicKey string - SecretKey string - BaseURL string -} +`project_id` **string** -func NewClient(publicKey, secretKey string) *Client { - return &Client{ - PublicKey: publicKey, - SecretKey: secretKey, - BaseURL: "https://api.pipedream.com/v1", - } -} +[The project's ID](/projects#finding-your-projects-id) -func (c *Client) authorizationHeader() string { - encoded := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", c.PublicKey, c.SecretKey))) - return fmt.Sprintf("Basic %s", encoded) -} +##### Examples -func (c *Client) DeleteExternalUser(externalId string) error { - url := fmt.Sprintf("%s/users/%s", c.BaseURL, externalId) - req, err := http.NewRequest("DELETE", url, nil) - if err != nil { - return err - } - - req.Header.Set("Authorization", c.authorizationHeader()) - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode == http.StatusNoContent { - fmt.Println("All accounts associated with the external ID have been deleted.") - } else { - fmt.Printf("Failed to delete accounts. Status code: %d\n", resp.StatusCode) - } - - return nil -} + + +```typescript +import { createBackendClient } from "@pipedream/sdk"; -func main() { - client := NewClient("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY") +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", + } +}); - err := client.DeleteExternalUser("EXTERNAL_ID") - if err != nil { - fmt.Println("Error:", err) - } -} +const info = await pd.getProjectInfo({ + project_id: "your-project-id", +}); ``` -```php -publicKey = $publicKey; - $this->secretKey = $secretKey; - $this->baseURL = "https://api.pipedream.com/v1"; - } - - private function authorizationHeader() { - return "Basic " . base64_encode("$this->publicKey:$this->secretKey"); - } +```javascript +import { createBackendClient } from "@pipedream/sdk"; - public function deleteExternalUser($externalId) { - $url = "$this->baseURL/users/$externalId"; - $opts = [ - 'http' => [ - 'header' => "Authorization: " . $this->authorizationHeader(), - 'method' => 'DELETE', - ], - ]; - - $context = stream_context_create($opts); - $result = file_get_contents($url, false, $context); - - if ($http_response_header[0] == 'HTTP/1.1 204 No Content') { - echo "All accounts associated with the external ID have been deleted."; - } else { - echo "Failed to delete accounts."; - } - } -} +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", + } +}); -// Usage example -$client = new Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY'); -$client->deleteExternalUser('EXTERNAL_ID'); -?> +const info = await pd.getProjectInfo({ + project_id: "your-project-id", +}); ``` -```ruby -require 'base64' -require 'net/http' -require 'uri' - -class Client - def initialize(public_key, secret_key) - @public_key = public_key - @secret_key = secret_key - @base_url = "https://api.pipedream.com/v1" - end - - def authorization_header - encoded = Base64.strict_encode64("#{@public_key}:#{@secret_key}") - "Basic #{encoded}" - end - - def delete_external_user(external_id) - uri = URI("#{@base_url}/users/#{external_id}") - req = Net::HTTP::Delete.new(uri) - req['Authorization'] = authorization_header - - res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| - http.request(req) - end - - if res.code.to_i == 204 - puts "All accounts associated with the external ID have been deleted." - else - puts "Failed to delete accounts. Status code: #{res.code}" - end - end -end - -# Usage example -client = Client.new('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -client.delete_external_user('EXTERNAL_ID') -``` - - +```bash +# First, obtain an OAuth access token +curl -X POST https://api.pipedream.com/v1/oauth/token \ + -H "Content-Type: application/json" \ + -d '{ + "grant_type": "client_credentials", + "client_id": "{oauth_client_id}", + "client_secret": "{oauth_client_secret}" + }' -##### Response +# The response will include an access_token. Use it in the Authorization header below. -Pipedream returns a `204 No Content` response on successful account deletion \ No newline at end of file +curl -X POST https://api.pipedream.com/v1/connect/{project_id}/info \ + -H "Authorization: Bearer {access_token}" \ +``` + + \ No newline at end of file diff --git a/docs-v2/pages/connect/environments.mdx b/docs-v2/pages/connect/environments.mdx index 77b5222571f69..f9355690d47f6 100644 --- a/docs-v2/pages/connect/environments.mdx +++ b/docs-v2/pages/connect/environments.mdx @@ -7,4 +7,4 @@ Pipedream Connect projects support two environments: `development` and `producti ## How to specify environment -You specify the environment when [creating a new Connect token](/connect/api/#create-a-new-token) with the Pipedream SDK or API. By default, the enviromment is set to `production`. When users succesfully connect their account, Pipedream saves it for that `external_user_id` in the specified `project_environment`. \ No newline at end of file +You specify the environment when [creating a new Connect token](/connect/api/#create-a-new-token) with the Pipedream SDK or API. By default, the enviromment is set to `production`. When users succesfully connect their account, Pipedream saves it for that `external_user_id` in the specified `project_environment`. diff --git a/docs-v2/pages/connect/index.mdx b/docs-v2/pages/connect/index.mdx index fbac92d72b0cf..526f4f06f2935 100644 --- a/docs-v2/pages/connect/index.mdx +++ b/docs-v2/pages/connect/index.mdx @@ -5,23 +5,16 @@ import VideoPlayer from "@/components/VideoPlayer"; # Pipedream Connect - -**Pipedream Connect is currently in preview, and we're looking for feedback!** +Pipedream Connect is the easiest way for your users to connect to [over {process.env.PUBLIC_APPS}+ APIs](https://pipedream.com/apps), **right in your product**. You can build in-app messaging, CRM syncs, AI agents, [and much more](/connect/use-cases), all in a few minutes. Visit [the quickstart](/connect/quickstart) to build your first integration. -**During the preview phase, Connect is free to use for any workspace. The API may change without notice, which may cause breaking changes**. We'll do our best to communicate these changes. +You have full, code-level control over how these integrations work in your app. You handle your product, Pipedream simplifies the integration. -Please reach out at `connect@pipedream.com` or our [Slack community](https://pipedream.com/support) to let us know how you're using it, what's not working, and what else you'd like to see. - +Connect lets you: -Pipedream Connect is the easiest way for your users to connect to [over {process.env.PUBLIC_APPS}+ APIs](https://pipedream.com/apps), **right in your product**. You can build in-app messaging, CRM syncs, AI-driven products, [and much more](/connect/use-cases), all in a few minutes. Visit [the quickstart](/connect/quickstart) to build your first integration. - -Connect lets your users authorize access to any API, directly in your app. You can then retrieve fresh credentials for any account, making requests on their behalf. Pipedream handles the security of credentials and the whole OAuth flow — **no need to manage authorization grants or token refresh yourself.** - -You have full, code-level control over how these integrations work. You handle the product, Pipedream takes care of the auth. Connect provides: - -1. A [Client SDK](https://github.com/PipedreamHQ/pipedream/tree/master/packages/sdk) or [Connect Link](/connect/quickstart#use-connect-link) to initiate authorization or accept API keys on behalf of your users, for any of the [{process.env.PUBLIC_APPS}+ APIs](https://pipedream.com/apps) available on Pipedream -2. A [REST API](/connect/api) to retrieve credentials for your end users — OAuth access tokens, API keys, and other credentials stored for them -3. The Pipedream platform and its [workflow builder](/workflows), [serverless runtime](/), and thousands of no-code [triggers](/workflows/triggers) and [actions](/workflows/actions) +1. Handle authorization or accept API keys on behalf of your users, for any of Pipedream's [{process.env.PUBLIC_APPS}+ APIs](https://pipedream.com/apps). Use the [Client SDK](https://github.com/PipedreamHQ/pipedream/tree/master/packages/sdk) or [Connect Link](/connect/quickstart#use-connect-link) to accept auth in minutes. +2. Securely retrieve OAuth access tokens, API keys, and other credentials for your end users with Pipedream's [REST API](/connect/api) +3. Run workflows for your end users with Pipedream's [workflow builder](/workflows), [serverless runtime](/), and thousands of no-code [triggers](/workflows/triggers) and [actions](/workflows/actions). Build complex integrations in minutes, writing code when you need it and using no-code components when you don't. Pipedream workflows are easy to modify, debug, and scale. +4. Run [any Pipedream action](https://pipedream.com/explore) or [deploy any Pipedream trigger](https://pipedream.com/explore) on behalf of your users, directly from within your application.
@@ -42,15 +35,31 @@ Pipedream Connect lets you build any API integration into your product in minute Watch [the demo](https://www.youtube.com/embed/xhUagMsogkQ) or visit [the quickstart](/connect/quickstart) to build your first integration. -## Plans and pricing +## App configuration for OAuth apps + +Pipedream has more than {process.env.PUBLIC_APPS} apps available for you to integrate via Connect. Getting started is easy — just follow the [quickstart](/connect/quickstart) to get up and running. + +By default, apps that use OAuth to authenticate will use Pipedream's official OAuth client. To deploy your integrations to production, you'll need to configure your own OAuth client. Read more about OAuth clients in Pipedream [here](/connected-accounts/oauth-clients). + +[Let us know](https://pipedream.com/support) if the app you're looking for isn't listed [here](https://pipedream.com/apps). -During the preview phase, **Connect is free to use for any workspace**. +## Users -Please let us know if you have any feedback on the value of Connect and how you'd like to see it priced. +To view or delete your users' connected accounts: + +1. Open your project +2. Click the **Connect** tab +3. In the **Apps** section, add a new app. + +You'll see a list of all users, their connected accounts, and the option to delete any accounts from the UI. You can also retrieve and delete all your users via the API ([see the docs for reference](/connect/api)). + +## Plans and pricing + +**Connect is free to use for any workspace**. ## Security -Pipedream takes the security of our products seriously. Please [review our security docs](/privacy-and-security) and send us any questions or [suspected vulnerabilities](/privacy-and-security#reporting-a-vulnerability). You can also get a copy of our [SOC 2 Type 2 report](/privacy-and-security#soc-2), [sign HIPAA BAAs](/privacy-and-security#hipaa), and get information on other practices and controls. +Pipedream takes the security of our products seriously. See [details on Connect security](/privacy-and-security#pipedream-connect) and [our general security docs](/privacy-and-security). Please send us any questions or [suspected vulnerabilities](/privacy-and-security#reporting-a-vulnerability). You can also get a copy of our [SOC 2 Type 2 report](/privacy-and-security#soc-2), [sign HIPAA BAAs](/privacy-and-security#hipaa), and get information on other practices and controls. ### Storing user credentials, token refresh @@ -58,23 +67,15 @@ All credentials and tokens are sent to Pipedream securely over HTTPS, and encryp ### How to secure your Connect apps -- **Secure all secrets** — Secure your Pipedream project's secret key and user credentials. Never expose secrets in your client-side code. Make all requests to Pipedream's API and third-party APIs from your server-side code. +- **Secure all secrets** — Secure your Pipedream OAuth client credentials, and especially any user credentials. Never expose secrets in your client-side code. Make all requests to Pipedream's API and third-party APIs from your server-side code. - **Use HTTPS** — Always use HTTPS to secure your connections between your client and server. Requests to Pipedream's API will be automatically redirected to HTTPS. - **Use secure, session-based auth between your client and server** — authorize all requests from your client to your server using a secure, session-based auth mechanism. Use well-known identity providers with services like [Clerk](https://clerk.com/), [Firebase](https://firebase.google.com/), or [Auth0](https://auth0.com/) to securely generate and validate authentication tokens. The same follows for Pipedream workflows — if you trigger Pipedream workflows from your client or server, validate all requests in the workflow before executing workflow code. - **Secure your workflows** — See our [standard security practices](/privacy-and-security/best-practices) for recommendations on securing your Pipedream workflows. -## Product roadmap for Connect - -- Address bugs and feedback during the preview phase -- Use Pipedream OAuth clients while in development, to make it easier to get started -- Invoke Pipedream workflows on behalf of your end users -- Improve error handling for Connect developers and end users -- And more! - ## Glossary of terms - **App**: GitHub, Notion, Slack, Google Sheets, and more. The app is the API you want your users to connect to in your product. See the [full list here](https://pipedream.com/apps). - **Developer**: This is probably you, the Pipedream customer who's developing an app and wants to use Connect to make API requests on behalf of your end users. -- **End User**: Your customer or user, whose data you want to access on their behalf. End users are identifed via the `external_id` param in the Connect SDK and API. +- **End User**: Your customer or user, whose data you want to access on their behalf. End users are identifed via the `external_user_id` param in the Connect SDK and API. - **Connected Account**: The account your end user connects. [Read more about connected accounts](/connected-accounts). - **OAuth Client**: Custom OAuth clients you create in Pipedream. [Read more about OAuth clients](/connected-accounts/oauth-clients). diff --git a/docs-v2/pages/connect/migrating-from-project-keys-to-oauth.mdx b/docs-v2/pages/connect/migrating-from-project-keys-to-oauth.mdx new file mode 100644 index 0000000000000..77d25cde30f8a --- /dev/null +++ b/docs-v2/pages/connect/migrating-from-project-keys-to-oauth.mdx @@ -0,0 +1,103 @@ +import Callout from '@/components/Callout' +import { Steps, Tabs } from 'nextra/components' + +# Migrating to the 1.0 SDK + + +This guide is only relevant if: + +- You used the `0.x` version of the JavaScript SDK +- You authenticated with the Pipedream API using project keys + + +## What changed + +- In the `0.x` version of the SDK and the original Connect API, you could authenticate with keys scoped to a specific project. In the `1.x` version of the SDK, you need to authenticate with [OAuth clients](/rest-api/auth#oauth). +- The `createClient` method from both the browser and Node.js SDKs has been replaced with separate methods: `createFrontendClient` and `createBackendClient`, respectively. +- The `connectTokenCreate` method has been renamed `createConnectToken` +- New SDK methods: `projectInfo`, `invokeWorkflow`, and more + +## How to migrate + + + +### Create an OAuth client + +Follow the instructions [here](/rest-api/auth#oauth) to create an OAuth client. + +### Update your SDK version + +Change the `@pipedream/sdk` version in your `package.json`: + +```json +{ + "dependencies": { + "@pipedream/sdk": "1.0.0" + } +} +``` + +Then run + +```bash +npm install +``` + +### Update your project key references to use your OAuth client + +You may have been referencing project keys in environment variables or other config. Replace these with references to the OAuth client you created in step 1. + +For example, `process.env.PIPEDREAM_PROJECT_KEY` should be replaced with `process.env.PIPEDREAM_OAUTH_CLIENT_ID`, and `process.env.PIPEDREAM_PROJECT_SECRET` should be replaced with `process.env.PIPEDREAM_OAUTH_CLIENT_SECRET`. + +### Update your SDK code + +#### Frontend client + +You'll need to make two changes to your frontend client code: + +1. Replace references to `@pipedream/sdk/browser`. Instead, import directly from `@pipedream/sdk`. +2. Change the `createClient` method to `createFrontendClient`. + +```typescript +import { createFrontendClient } from "@pipedream/sdk" +const pd = createFrontendClient() +``` + +#### Backend client + +You'll need to make three changes to your backend code: + +1. Change the `createClient` method to `createBackendClient`. +2. Pass your OAuth client ID and secret to the `createBackendClient` method, removing references to project keys. +3. Change any token create method references from `connectTokenCreate` to `createConnectToken`. + + + +```typescript +import { createBackendClient, HTTPAuthType } from "@pipedream/sdk"; + +// These secrets should be saved securely and passed to your environment +const pd = createBackendClient({ + credentials: { + clientId: "YOUR_CLIENT_ID", + clientSecret: "YOUR_CLIENT_SECRET", + }, +}); +``` + + +```javascript +import { createBackendClient } from "@pipedream/sdk"; + +// These secrets should be saved securely and passed to your environment +const pd = createBackendClient({ + credentials: { + clientId: "YOUR_CLIENT_ID", + clientSecret: "YOUR_CLIENT_SECRET", + }, +}); +``` + + + + \ No newline at end of file diff --git a/docs-v2/pages/connect/oauth-clients.mdx b/docs-v2/pages/connect/oauth-clients.mdx index 4639d7103cc8b..b60e8f9d3e5dd 100644 --- a/docs-v2/pages/connect/oauth-clients.mdx +++ b/docs-v2/pages/connect/oauth-clients.mdx @@ -12,7 +12,7 @@ There are two types of apps in Pipedream: 1. **Key-based**: These apps require static credentials, like API keys. Pipedream stores these credentials securely and exposes them via API. 2. **OAuth**: These apps require OAuth authorization. Pipedream manages the OAuth flow for these apps, ensuring you always have a fresh access token for requests. -**OAuth apps require you create your own OAuth client to [deploy to production](/connect/environments):** +**OAuth apps require you create your own OAuth client to [deploy Connect to production](/connect/environments):** To get started in [development mode](/connect/environments), you can skip these steps. To deploy your app to production, you'll need to [create an OAuth client](#using-a-custom-oauth-client) for the app you're integrating. diff --git a/docs-v2/pages/connect/quickstart.mdx b/docs-v2/pages/connect/quickstart.mdx index 4a81ea662d76d..eb305fdd118fa 100644 --- a/docs-v2/pages/connect/quickstart.mdx +++ b/docs-v2/pages/connect/quickstart.mdx @@ -5,7 +5,7 @@ import VideoPlayer from "@/components/VideoPlayer"; # Quickstart -Pipedream Connect is the easiest way for your users to connect to [over {process.env.PUBLIC_APPS}+ APIs](https://pipedream.com/apps), **right in your product**. You can build in-app messaging, CRM syncs, AI-driven products, [and much more](/connect/use-cases), all in a few minutes. +Pipedream Connect is the easiest way for your users to connect to [over {process.env.PUBLIC_APPS}+ APIs](https://pipedream.com/apps), **right in your product**. You can build in-app messaging, CRM syncs, AI agents, [and much more](/connect/use-cases), all in a few minutes. ## Visual overview @@ -14,24 +14,15 @@ Here's a high-level overview of how Connect works with your app:
Pipedream Connect overview -And here's the technical flow between your frontend, backend, and Pipedream's API, described step-by-step below: +Here's how Connect sits in your frontend and backend, and communicates with Pipedream's API:
Connect developer flow - - -### Get your project keys -1. Open an existing Pipedream project or create a new one at [https://pipedream.com/projects](https://pipedream.com/projects). -2. From within the **Connect** tab in your project, select **Configuration**. -3. Find your project's **Public Key** and **Secret Key**. - -You'll need these when configuring the SDK and making API requests. +## Getting started -
- -Project keys in the Connect tab + ### Run the Pipedream example app or configure your own @@ -56,450 +47,36 @@ and fill the `.env.local` file with your project and app details: ```bash # Used by `app/server.ts` to authorize requests to the Pipedream API — see below -PIPEDREAM_PROJECT_PUBLIC_KEY=pub_abc123 -PIPEDREAM_PROJECT_SECRET_KEY=sec_abc123 +PIPEDREAM_CLIENT_ID=your_client_id +PIPEDREAM_CLIENT_SECRET=your_client_secret +PIPEDREAM_PROJECT_ENVIRONMENT=development +PIPEDREAM_PROJECT_ID=your_project_id ``` If you're building your own app, you'll need to provide these values to the environment, or retrieve them from your secrets store. -### Connect to the Pipedream API from your server and create a token - - -**Why do I need to talk to the Pipedream API from my server?** - -You need to secure specific operations, for example: - -- You need to initiate the account connection flow for your end users. In Pipedream Connect, **you exchange your project keys for a short-lived token that allows a specific user to connect a specific app**, and return either that token or the `connect_link_url` to your frontend. -- If you expose your Pipedream project keys directly to the frontend, anyone could initiate the account connection flow for any user. -- You need to retrieve account credentials for your end users. Again, this should happen securely on your server, not in the frontend, to protect your users' data. - - - -In this Next.js example, we're running Node.js code on our server, via [Next server components](https://nextjs.org/docs/app/building-your-application/rendering/server-components), so we'll use the Pipedream SDK. Additional examples in Python, Ruby, and other languages are noted below. - -To install the [Pipedream SDK](https://www.npmjs.com/package/@pipedream/sdk) in your own project, run: - -```bash -npm i --save @pipedream/sdk -``` - -To create a short-lived token via TypeScript / JavaScript SDK, you'll need to create a Pipedream API client and call the `connectTokenCreate` method. In our example app, this code is in `app/server.ts`. - -In other languages, you'll need to make an HTTP POST request to the `/v1/connect/tokens` endpoint to create a token, then return the token to your frontend. Click into other tabs to see examples in additional languages. - - - -```typescript -"use server"; - -import { - createClient, - type ConnectAPIResponse, - type ConnectTokenCreateOpts, - type ConnectTokenResponse, -} from "@pipedream/sdk"; - -const pd = createClient({ - publicKey: process.env.PIPEDREAM_PROJECT_PUBLIC_KEY, - secretKey: process.env.PIPEDREAM_PROJECT_SECRET_KEY, -}); - -export async function serverConnectTokenCreate(opts: ConnectTokenCreateOpts): Promise> { - return pd.connectTokenCreate(opts); -} -``` - - -```javascript -const fetch = require('node-fetch'); - -class Client { - constructor(opts) { - this.secretKey = opts.secretKey; - this.publicKey = opts.publicKey; - - const apiHost = 'api.pipedream.com'; - this.baseURL = `https://${apiHost}`; - } - - _authorizationHeader() { - const encoded = Buffer.from(`${this.publicKey}:${this.secretKey}`).toString('base64'); - return `Basic ${encoded}`; - } - - async connectTokenCreate(opts) { - const auth = this._authorizationHeader(); - const response = await fetch(`${this.baseURL}/v1/connect/tokens`, { - method: 'POST', - headers: { - 'Authorization': auth, - 'Content-Type': 'application/json', - }, - body: JSON.stringify(opts), - }); - - return response.json(); - } -} - -const client = new Client({ - publicKey: 'YOUR_PUBLIC_KEY', - secretKey: 'YOUR_SECRET_KEY', -}); - -const connectTokenOpts = { - external_id: "USER_ID" // The end user's ID in your system -} - -// Expose this code as an API endpoint in your server to fetch the token from the frontend -client.connectTokenCreate(connectTokenOpts) - .then(response => { - // return the token to the frontend - }) - .catch(error => { - // handle errors - }); -``` - - -```python -import base64 -import json -import requests - -class Client: - def __init__(self, opts): - self.secret_key = opts['secret_key'] - self.public_key = opts['public_key'] - - api_host = 'api.pipedream.com' - self.base_url = f"https://{api_host}" - - def _authorization_header(self): - encoded = base64.b64encode(f"{self.public_key}:{self.secret_key}".encode()).decode() - return f"Basic {encoded}" - - def connect_token_create(self, opts): - auth = self._authorization_header() - response = requests.post( - f"{self.base_url}/v1/connect/tokens", - headers={ - "Authorization": auth, - "Content-Type": "application/json", - }, - data=json.dumps(opts) - ) - return response.json() - -# Usage example -client = Client({ - 'public_key': 'YOUR_PUBLIC_KEY', - 'secret_key': 'YOUR_SECRET_KEY', -}) - -connect_token_opts = { - 'external_id': "USER_ID" -} - -# Expose this code as an API endpoint in your server to fetch the token from the frontend -response = client.connect_token_create(connect_token_opts) - -``` - - -```java -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Base64; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; - -public class Client { - private String secretKey; - private String publicKey; - private String baseURL; - - public Client(String secretKey, String publicKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - - String apiHost = "api.pipedream.com"; - this.baseURL = "https://" + apiHost; - } - - private String authorizationHeader() { - String encoded = Base64.getEncoder().encodeToString((publicKey + ":" + secretKey).getBytes(StandardCharsets.UTF_8)); - return "Basic " + encoded; - } - - public String connectTokenCreate(String externalId) throws Exception { - String auth = authorizationHeader(); - URL url = new URL(baseURL + "/v1/connect/tokens"); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Authorization", auth); - conn.setRequestProperty("Content-Type", "application/json"); - conn.setDoOutput(true); - - String jsonInputString = String.format("{\"external_id\":\"%s\"}", externalId); - - try (OutputStream os = conn.getOutputStream()) { - byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8); - os.write(input, 0, input.length); - } - - return new String(conn.getInputStream().readAllBytes(), StandardCharsets.UTF_8); - } - - public static void main(String[] args) throws Exception { - Client client = new Client("YOUR_SECRET_KEY", "YOUR_PUBLIC_KEY"); - - // Expose this code as an API endpoint in your server to fetch the token from the frontend - String response = client.connectTokenCreate("USER_ID"); - } -} - -``` - - -```csharp -using System; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; - -public class Client { - private string secretKey; - private string publicKey; - private string baseURL; - - public Client(string secretKey, string publicKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - - string apiHost = "api.pipedream.com"; - this.baseURL = $"https://{apiHost}"; - } - - private string AuthorizationHeader() { - string encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{publicKey}:{secretKey}")); - return $"Basic {encoded}"; - } - - public async Task ConnectTokenCreate(string externalId) { - string auth = AuthorizationHeader(); - using (HttpClient client = new HttpClient()) { - client.DefaultRequestHeaders.Add("Authorization", auth); - client.DefaultRequestHeaders.Add("Content-Type", "application/json"); - - var content = new StringContent($"{{\"external_id\":\"{externalId}\"}}", Encoding.UTF8, "application/json"); - var response = await client.PostAsync($"{baseURL}/v1/connect/tokens", content); - - return await response.Content.ReadAsStringAsync(); - } - } - - public static async Task Main(string[] args) { - var client = new Client("YOUR_SECRET_KEY", "YOUR_PUBLIC_KEY"); - - // Expose this code as an API endpoint in your server to fetch the token from the frontend - string response = await client.ConnectTokenCreate("USER_ID"); - } -} - -``` - - -```go -package main - -import ( - "bytes" - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" -) - -type Client struct { - SecretKey string - PublicKey string - BaseURL string -} - -func NewClient(secretKey, publicKey string) *Client { - apiHost := "api.pipedream.com" - baseURL := fmt.Sprintf("https://%s", apiHost) - - return &Client{ - PublicKey: publicKey, - SecretKey: secretKey, - } -} - -func (c *Client) authorizationHeader() string { - encoded := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", c.PublicKey, c.SecretKey))) - return fmt.Sprintf("Basic %s", encoded) -} - -func (c *Client) ConnectTokenCreate(externalId string) (map[string]interface{}, error) { - auth := c.authorizationHeader() - url := fmt.Sprintf("%s/v1/connect/tokens", c.BaseURL) - - opts := map[string]string{ - "external_id": externalId, - } - - jsonData, err := json.Marshal(opts) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) - if err != nil { - return nil, err - } - - req.Header.Set("Authorization", auth) - req.Header.Set("Content-Type", "application/json") - - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() +### Create a project in Pipedream - body, _ := ioutil.ReadAll(resp.Body) - - var result map[string]interface{} - json.Unmarshal(body, &result) - return result, nil -} - -func main() { - client := NewClient("YOUR_SECRET_KEY", "YOUR_PUBLIC_KEY") +1. Open an existing Pipedream project or create a new one at [https://pipedream.com/projects](https://pipedream.com/projects). +2. Click the **Settings** tab, then copy your **Project ID**. - // Expose this code as an API endpoint in your server to fetch the token from the frontend - response, err := client.ConnectTokenCreate("USER_ID") - if err != nil { - fmt.Println("Error:", err) - return - } -} +### Create a Pipedream OAuth client -``` - - -```php -publicKey = $publicKey; - $this->secretKey = $secretKey; - - $apiHost = 'api.pipedream.com'; - $this->baseURL = "https://$apiHost"; - } - - private function authorizationHeader() { - $encoded = base64_encode("$this->publicKey:$this->secretKey"); - return "Basic $encoded"; - } - - public function connectTokenCreate($externalId) { - $auth = $this->authorizationHeader(); - $url = "$this->baseURL/v1/connect/tokens"; - - $data = json_encode([ - 'external_id' => $externalId - ]); - - $options = [ - 'http' => [ - 'header' => [ - "Authorization: $auth", - "Content-Type: application/json", - ], - 'method' => 'POST', - 'content' => $data, - ], - ]; - - $context = stream_context_create($options); - $result = file_get_contents($url, false, $context); - - return json_decode($result, true); - } -} +Pipedream uses OAuth to authorize requests to the REST API. To create an OAuth client: -// Usage example -$client = new Client('YOUR_SECRET_KEY', 'YOUR_PUBLIC_KEY'); +1. Visit the [API settings](https://pipedream.com/settings/api) for your workspace. +2. Click the **New OAuth Client** button. +3. Name your client and click **Create**. +4. Copy the client secret. **It will not be accessible again**. Click **Close**. +5. Copy the client ID from the list. -$connectTokenOpts = [ - 'external_id' => "USER_ID" -]; +You'll need these when configuring the SDK and making API requests. -// Expose this code as an API endpoint in your server to fetch the token from the frontend -$response = $client->connectTokenCreate($connectTokenOpts['external_id']); -?> -``` - - -```ruby -require 'base64' -require 'json' -require 'net/http' -require 'uri' - -class Client - def initialize(secret_key, public_key) - @public_key = public_key - @secret_key = secret_key - - api_host = 'api.pipedream.com' - @base_url = "https://#{api_host}" - end - - def authorization_header - encoded = Base64.strict_encode64("#{@public_key}:#{@secret_key}") - "Basic #{encoded}" - end - - def connect_token_create(external_id) - uri = URI("#{@base_url}/v1/connect/tokens") - req = Net::HTTP::Post.new(uri) - req['Authorization'] = authorization_header - req['Content-Type'] = 'application/json' - req.body = { external_id: external_id }.to_json - - res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| - http.request(req) - end - - JSON.parse(res.body) - end -end - -client = Client.new('YOUR_SECRET_KEY', 'YOUR_PUBLIC_KEY') - -connect_token_opts = { - external_id: "USER_ID" -} +### Generate a short-lived token -# Expose this code as an API endpoint in your server to fetch the token from the frontend -response = client.connect_token_create(connect_token_opts[:external_id]) -``` - - +To securely initiate account connections for your users, you'll need generate a short-lived token for your users and use that in the [account connection flow](#connect-a-users-account). See [the docs on Connect tokens](/connect/tokens) for a general overview of why we need to create tokens and scope them to end users. -In our Next.js app, we call the `serverConnectTokenCreate` method from the frontend to retrieve a token **for a specific user**. +In the Next.js example here, we're running [Next server components](https://nextjs.org/docs/app/building-your-application/rendering/server-components) in `app/server.ts`. We call the `serverConnectTokenCreate` method from the frontend to retrieve a token **for a specific user**. ```typescript import { serverConnectTokenCreate } from "./server" @@ -509,10 +86,12 @@ const { token, expires_at } = await serverConnectTokenCreate({ }); ``` -If you're using a different server / API framework, you'll need to make secure calls to that API to create a new token for your users. For example, you might validate a user's session, then call the Pipedream API to create a new token for that user. +If you're using a different server / API framework, you'll need to make secure calls to that API to create a new token for your users. + +Once you have a token, return it to your frontend to start the account connection flow for the user, or redirect them to a Pipedream-hosted URL with [Connect Link](#use-connect-link). -Refer to the API docs for [all the parameters you can pass](/connect/api#create-a-new-token) in the `ConnectTokenCreate` call. +Refer to the API docs for [full set of parameters you can pass](/connect/api#create-a-new-token) in the `ConnectTokenCreate` call. ### Connect a user's account @@ -520,7 +99,7 @@ Refer to the API docs for [all the parameters you can pass](/connect/api#create- To connect a third-party account for a user, you have two options: 1. [Use the Pipedream SDK](#use-the-pipedream-sdk-in-your-frontend) in your frontend -2. [Use Connect Link](#use-connect-link) to deliver a hosted URL to your user (see above). +2. [Use Connect Link](#use-connect-link) to deliver a hosted URL to your user #### Use the Pipedream SDK in your frontend @@ -540,11 +119,10 @@ In our example, `app/page.tsx` calls the `connectAccount` method from the Pipedr Connect your account button ```typescript -// Note that we import the browser-specific SDK client here -import { createClient } from "@pipedream/sdk/browser" +import { createFrontendClient } from "@pipedream/sdk" export default function Home() { - const pd = createClient() + const pd = createFrontendClient() function connectAccount() { pd.connectAccount({ app: appSlug, // Pass the app name slug of the app you want to integrate @@ -584,25 +162,28 @@ https://pipedream.com/_static/connect.html?token={token}&connectLink=true&app={a ### Retrieve the credentials from the backend -Once the user connects an account, you can retrieve their credentials from your backend with your project keys. +Once your user connects an account, you can retrieve their credentials from your backend. -This example shows you how to fetch credentials by your end user's `external_id` and the app's name slug. You can also fetch all connected accounts for a specific app, or a specific user — see the [Connect API reference](/connect/api). +This example shows you how to fetch credentials by your end user's `external_user_id`. You can also fetch all connected accounts for a specific app, or a specific user — see the [Connect API reference](/connect/api). - + ```typescript import { - createClient, + createBackendClient, } from "@pipedream/sdk"; -const pd = createClient({ - publicKey: PIPEDREAM_PROJECT_PUBLIC_KEY, - secretKey: PIPEDREAM_PROJECT_SECRET_KEY, +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", + } }); -export async function getUserAccounts(externalId: string, include_credentials: number = 0) { - await pd.getAccountsByExternalId(externalId, { - include_credentials, // set to 1 to include credentials +async function getUserAccounts(external_user_id: string, include_credentials: boolean = false) { + await pd.getAccounts({ + external_user_id, + include_credentials, // set to true to include credentials }) // Parse and return the data you need. These may contain credentials, @@ -612,361 +193,26 @@ export async function getUserAccounts(externalId: string, include_credentials: n ```javascript -const fetch = require('node-fetch'); - -class Client { - constructor({ publicKey, secretKey }) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = 'https://api.pipedream.com'; - } - - _authorizationHeader() { - const encoded = Buffer.from(`${this.publicKey}:${this.secretKey}`).toString('base64'); - return `Basic ${encoded}`; - } - - async getUserAccounts(externalId) { - const auth = this._authorizationHeader(); - const url = `${this.baseURL}/v1/connect/users/${externalId}/accounts`; - - const response = await fetch(url, { - method: 'GET', - headers: { - 'Authorization': auth, - 'Content-Type': 'application/json', - }, - }); - - const data = await response.json(); - - if (!data?.accounts?.length) { - return null; - } +import { + createBackendClient, +} from "@pipedream/sdk"; - // Parse and return data.accounts. Ensure to handle sensitive data appropriately. - return data.accounts; +const pd = createBackendClient({ + credentials: { + clientId: "your-oauth-client-id", + clientSecret: "your-oauth-client-secret", } -} - -// Usage example -const client = new Client({ - publicKey: 'YOUR_PUBLIC_KEY', - secretKey: 'YOUR_SECRET_KEY', }); -client.getUserAccounts('USER_ID') - .then(response => { - // handle response +async function getUserAccounts(external_user_id, include_credentials = false) { + await pd.getAccounts({ + external_user_id, + include_credentials, // set to true to include credentials }) - .catch(error => { - console.error('Error:', error); - }); -``` - - -```python -import base64 -import requests - -class Client: - def __init__(self, public_key, secret_key): - self.public_key = public_key - self.secret_key = secret_key - self.base_url = "https://api.pipedream.com" - - def _authorization_header(self): - encoded = base64.b64encode(f"{self.public_key}:{self.secret_key}".encode()).decode() - return f"Basic {encoded}" - - def get_user_accounts(self, external_id): - auth = self._authorization_header() - url = f"{self.base_url}/v1/connect/users/{external_id}/accounts" - response = requests.get(url, headers={"Authorization": auth}) - data = response.json() - - if not data.get('accounts'): - return None - - # Parse and return data['accounts']. Ensure to handle sensitive data appropriately. - return data['accounts'] - -# Usage example -client = Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -response = client.get_user_accounts('USER_ID') -``` - - -```java -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Base64; -import java.io.InputStreamReader; -import java.io.BufferedReader; -import java.nio.charset.StandardCharsets; - -public class Client { - private String publicKey; - private String secretKey; - private String baseURL; - - public Client(String publicKey, String secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com"; - } - - private String authorizationHeader() { - String encoded = Base64.getEncoder().encodeToString((publicKey + ":" + secretKey).getBytes(StandardCharsets.UTF_8)); - return "Basic " + encoded; - } - - public String getUserAccounts(String externalId) throws Exception { - String auth = authorizationHeader(); - URL url = new URL(baseURL + "/v1/connect/users/" + externalId + "/accounts"); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("GET"); - conn.setRequestProperty("Authorization", auth); - - BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); - String inputLine; - StringBuilder content = new StringBuilder(); - while ((inputLine = in.readLine()) != null) { - content.append(inputLine); - } - in.close(); - - String response = content.toString(); - - // Parse response and return accounts data. Ensure to handle sensitive data appropriately. - if (!response.contains("accounts")) { - return null; - } - - return response; // Modify to parse and handle accounts as needed. - } - - public static void main(String[] args) throws Exception { - Client client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - String response = client.getUserAccounts("USER_ID"); - } -} -``` - - -```csharp -using System; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; - -public class Client { - private string publicKey; - private string secretKey; - private string baseURL; - - public Client(string publicKey, string secretKey) { - this.publicKey = publicKey; - this.secretKey = secretKey; - this.baseURL = "https://api.pipedream.com"; - } - - private string AuthorizationHeader() { - string encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{publicKey}:{secretKey}")); - return $"Basic {encoded}"; - } - - public async Task GetUserAccounts(string externalId) { - string auth = AuthorizationHeader(); - using (HttpClient client = new HttpClient()) { - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); - HttpResponseMessage response = await client.GetAsync($"{baseURL}/v1/connect/users/{externalId}/accounts"); - - string result = await response.Content.ReadAsStringAsync(); - - // Parse and return accounts data. Ensure to handle sensitive data appropriately. - if (!result.Contains("accounts")) { - return null; - } - - return result; // Modify to parse and handle accounts as needed. - } - } - - public static async Task Main(string[] args) { - var client = new Client("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY"); - string response = await client.GetUserAccounts("USER_ID"); - } -} -``` - - -```go -package main - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" -) - -type Client struct { - PublicKey string - SecretKey string - BaseURL string -} - -func NewClient(publicKey, secretKey string) *Client { - return &Client{ - PublicKey: publicKey, - SecretKey: secretKey, - BaseURL: "https://api.pipedream.com", - } -} - -func (c *Client) authorizationHeader() string { - encoded := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", c.PublicKey, c.SecretKey))) - return fmt.Sprintf("Basic %s", encoded) -} -func (c *Client) GetUserAccounts(externalId string) (map[string]interface{}, error) { - url := fmt.Sprintf("%s/v1/connect/users/%s/accounts", c.BaseURL, externalId) - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - - req.Header.Set("Authorization", c.authorizationHeader()) - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - var result map[string]interface{} - err = json.Unmarshal(body, &result) - if err != nil { - return nil, err - } - - if accounts, exists := result["accounts"]; exists { - return accounts.([]interface{}), nil - } - - return nil, nil -} - -func main() { - client := NewClient("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY") - - accounts, err := client.GetUserAccounts("USER_ID") - if err != nil { - fmt.Println("Error:", err) - return - } -} -``` - - -```php -publicKey = $publicKey; - $this->secretKey = $secretKey; - $this->baseURL = "https://api.pipedream.com"; - } - - private function authorizationHeader() { - return "Basic " . base64_encode("$this->publicKey:$this->secretKey"); - } - - public function getUserAccounts($externalId) { - $url = "$this->baseURL/v1/connect/users/$externalId/accounts"; - $opts = [ - 'http' => [ - 'header' => "Authorization: " . $this->authorizationHeader(), - 'method' => 'GET', - ], - ]; - - $context = stream_context_create($opts); - $result = file_get_contents($url, false, $context); - - if ($result === FALSE) { - return null; - } - - $data = json_decode($result, true); - - if (empty($data['accounts'])) { - return null; - } - - return $data['accounts']; // Modify to parse and handle accounts as needed. - } + // Parse and return the data you need. These may contain credentials, + // which you should never return to the client } - -// Usage example -$client = new Client('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY'); -$response = $client->getUserAccounts('USER_ID'); -?> -``` - - -```ruby -require 'base64' -require 'json' -require 'net/http' -require 'uri' - -class Client - def initialize(public_key, secret_key) - @public_key = public_key - @secret_key = secret_key - @base_url = "https://api.pipedream.com" - end - - def authorization_header - encoded = Base64.strict_encode64("#{@public_key}:#{@secret_key}") - "Basic #{encoded}" - end - - def get_user_accounts(external_id) - uri = URI("#{@base_url}/v1/connect/users/#{external_id}/accounts") - req = Net::HTTP::Get.new(uri) - req['Authorization'] = authorization_header - - res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| - http.request(req) - end - - data = JSON.parse(res.body) - - # Parse and return accounts data. Ensure to handle sensitive data appropriately. - return nil if data['accounts'].nil? || data['accounts'].empty? - - data['accounts'] - end -end - -# Usage example -client = Client.new('YOUR_PUBLIC_KEY', 'YOUR_SECRET_KEY') -response = client.get_user_accounts('USER_ID') ``` diff --git a/docs-v2/pages/connect/tokens.mdx b/docs-v2/pages/connect/tokens.mdx index fa52eb38ba613..fe86a0ba3c41c 100644 --- a/docs-v2/pages/connect/tokens.mdx +++ b/docs-v2/pages/connect/tokens.mdx @@ -21,8 +21,6 @@ When you generate a token, you can specify a `webhook_uri` where Pipedream will ## Tokens are scoped to end users and project environments -When you [create a new Connect token](/connect/api/#create-a-new-token), you pass an `external_user_id` and an optional `project_environment` parameter. By default, the environment is set to `production`. Available environments include: -- `production` (default) -- `development` +When you [create a new Connect token](/connect/api/#create-a-new-token), you pass an `external_user_id` and an optional `project_environment` parameter. By default, the environment is set to `production`. See the docs on [environments](/connect/environments) for more information. Tokens are scoped to this user and environment. When the user successfully connects an account with that token, it will be saved for that `external_user_id` in the specified `project_environment`. \ No newline at end of file diff --git a/docs-v2/pages/connected-accounts/index.mdx b/docs-v2/pages/connected-accounts/index.mdx index edb4aff970777..a3f6c814259d4 100644 --- a/docs-v2/pages/connected-accounts/index.mdx +++ b/docs-v2/pages/connected-accounts/index.mdx @@ -237,7 +237,11 @@ If you use a secrets store like [Pipedream Connect](/connect) or [HashiCorp Vaul ## Connecting to apps with IP restrictions -If you're connecting to an app that enforces IP restrictions, you may need to whitelist Pipedream's IP addresses: + +These IP addresses are tied to **app connections only**, not workflows or other Pipedream services. To whitelist requests from Pipedream workflows, [use VPCs](/workflows/vpc). + + +If you're connecting to an app that enforces IP restrictions, you may need to whitelist the Pipedream API's IP addresses:
   {process.env.PD_EGRESS_IP_RANGE}
diff --git a/docs-v2/pages/destinations/http.mdx b/docs-v2/pages/destinations/http.mdx
index 70b0c2679d81c..c5ef2307c5c05 100644
--- a/docs-v2/pages/destinations/http.mdx
+++ b/docs-v2/pages/destinations/http.mdx
@@ -112,13 +112,12 @@ Currently, Pipedream will not retry any failed request. If your HTTP destination
 
 ## IP addresses for Pipedream HTTP requests
 
+
+These IP addresses are tied to **requests sent with `$.send.http` only, not other HTTP requests made from workflows**. To whitelist standard HTTP requests from Pipedream workflows, [use VPCs](/workflows/vpc).
+
+
 When you make an HTTP request using `$.send.http()`, the traffic will come from one of the following IP addresses:
 
 
 
-This list may change over time. If you've previously whitelisted these IP addresses and are having trouble sending HTTP requests to your target service, please check to ensure this list matches your firewall rules.
-
-
-These IP addresses are tied specifically to the `$.send.http()` service. If you send traffic directly from a workflow, it will be sent from one of Pipedream's general range of IP addresses. [See our hosting docs for more information](/privacy-and-security/#hosting-details).
-
-
+This list may change over time. If you've previously whitelisted these IP addresses and are having trouble sending HTTP requests to your target service, please check to ensure this list matches your firewall rules.
\ No newline at end of file
diff --git a/docs-v2/pages/privacy-and-security/best-practices.mdx b/docs-v2/pages/privacy-and-security/best-practices.mdx
index 77846fa98647c..dac77a201837a 100644
--- a/docs-v2/pages/privacy-and-security/best-practices.mdx
+++ b/docs-v2/pages/privacy-and-security/best-practices.mdx
@@ -1,10 +1,10 @@
 # Security Best Practices
 
-Pipedream implements a range of [privacy and security measures](/privacy-and-security/) meant to protect your data from unauthorized access. Since Pipedream [workflows](/workflows/), [event sources](/sources/), and other resources can run any Node.js code and process any event data, you also have a responsibility to ensure you handle that code and data securely. We've outlined a handful of best practices for that below.
+Pipedream implements a range of [privacy and security measures](/privacy-and-security/) meant to protect your data from unauthorized access. Since Pipedream [workflows](/workflows/), [event sources](/sources/), and other resources can run any code and process any event data, you also have a responsibility to ensure you handle that code and data securely. We've outlined a handful of best practices for that below.
 
 ## Store secrets as Pipedream connected accounts or environment variables
 
-Even if your workflow code is private, you should never store secrets like API keys in code. These secrets should be stored in one of two ways:
+Never store secrets like API keys directly in code. These secrets should be stored in one of two ways:
 
 - [If Pipedream integrates with the app](https://pipedream.com/apps), use [connected accounts](/connected-accounts/) to link your apps / APIs.
 - If you need to store credentials for an app Pipedream doesn't support, or you need to store arbitrary configuration data, use [environment variables](/environment-variables/).
@@ -13,21 +13,19 @@ Read more about how Pipedream secures connected accounts / environment variables
 
 ## Deliver data to Pipedream securely
 
-Whenever possible, encrypt data in transit to Pipedream. For example, use HTTPS endpoints when sending HTTP traffic to a workflow.
+Always send data over HTTPS to Pipedream endpoints.
 
 ## Send data out of Pipedream securely
 
 When you connect to APIs in a workflow, or deliver data to third-party destinations, encrypt that data in transit. For example, use HTTPS endpoints when sending HTTP traffic to third parties.
 
-## Add authentication to incoming event data
+## Require authorization for HTTP triggers
 
-You can add many public-facing triggers to your workflows. For example, when you add an HTTP trigger to your workflow, anyone with the associated trigger URL can invoke it. You should protect your workflow with an authentication mechanism like [Basic Auth](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication), JWT, or others.
+HTTP triggers are public by default, and require no authorization or token to invoke.
 
-The easiest way to do this is to use the [Validate Webhook Auth action](https://pipedream.com/apps/http/actions/validate-webhook-auth). This supports common auth options, and you don't have to write any code to configure it.
+For many workflows, you should [configure authorization](/workflows/triggers#authorizing-http-requests) to ensure that only authorized parties can invoke your HTTP trigger.
 
-If you need to implement custom logic in code, see [this workflow](https://pipedream.com/new?h=tch_OaJfNv) for a shared API key example. This reads the header `x-api-key` and compares it to the [environment variable](/environment-variables/) called `YOUR_WEBHOOK_API_KEY`. If the `x-api-key` header does not match this variable, it returns a `401 Unauthorized` error and exits the workflow early.
-
-This pattern is typical for protecting workflows: add the authentication logic in a step at the top of your workflow, ending early if auth fails. If auth succeeds, Pipedream runs the remaining steps of your workflow.
+For third-party services like webhooks, that authorize requests using their own mechanism, use the [Validate Webhook Auth action](https://pipedream.com/apps/http/actions/validate-webhook-auth). This supports common auth options, and you don't have to write any code to configure it.
 
 ## Validate signatures for incoming events, where available
 
diff --git a/docs-v2/pages/privacy-and-security/index.mdx b/docs-v2/pages/privacy-and-security/index.mdx
index b0a3736f9cd9c..9564dea0a0773 100644
--- a/docs-v2/pages/privacy-and-security/index.mdx
+++ b/docs-v2/pages/privacy-and-security/index.mdx
@@ -22,7 +22,7 @@ If you suspect Pipedream resources are being used for illegal purposes, or other
 
 ### SOC 2
 
-Pipedream undergoes regular third-party audits. We have demonstrated SOC 2 compliance and can provide a SOC 2 Type 2 report upon request. Please reach out to support@pipedream.com to request the latest report.
+Pipedream undergoes annual third-party audits. We have demonstrated SOC 2 compliance and can provide a SOC 2 Type 2 report upon request. Please reach out to support@pipedream.com to request the latest report.
 
 We use [Drata](https://drata.com) to continuosly monitor our infrastructure's compliance with standards like SOC 2, and you can visit our [Security Report](https://app.drata.com/security-report/b45c2f79-1968-496b-8a10-321115b55845/27f61ebf-57e1-4917-9536-780faed1f236) to see a list of policies and processes we implement and track within Drata.
 
@@ -86,6 +86,61 @@ No credentials are logged in your source or workflow by default. If you log thei
 
 You can delete your OAuth grants or key-based credentials at any time by visiting [https://pipedream.com/accounts](https://pipedream.com/accounts). Deleting OAuth grants within Pipedream **do not** revoke Pipedream's access to your account. You must revoke that access wherever you manage OAuth grants in your third party application.
 
+## Pipedream REST API security, OAuth clients
+
+The Pipedream API supports two methods of authentication: [OAuth](/rest-api/auth#oauth) and [User API keys](/rest-api/auth#user-api-keys). **We recommend using OAuth clients** for a few reasons:
+
+✅ OAuth clients are tied to the workspace, administered by workspace admins 
+✅ Tokens are short-lived
+✅ OAuth clients support scopes, limiting access to specific operations
+ +When testing the API or using the CLI, you can use your user API key. This key is tied to your user account and provides full access to any resources your user has access to, across workspaces. + +### OAuth clients + +Pipedream supports client credentials OAuth clients, which exchange a client ID and client secret for a short-lived access token. These clients are not tied to individual end users, and are meant to be used server-side. You must store these credentials securely on your server, never allowing them to be exposed in client-side code. + +Client secrets are salted and hashed before being saved to the database. The hashed secret is encrypted at rest. Pipedream does not store the client secret in plaintext. + +You can revoke a specific client secret at any time by visiting [https://pipedream.com/settings/api](https://pipedream.com/settings/api). + +### OAuth tokens + +Since Pipedream uses client credentials grants, access tokens must not be shared with end users or stored anywhere outside of your server environment. + +Access tokens are issued as JWTs, signed with an ED25519 private key. The public key used to verify these tokens is available at [https:/api.pipedream.com/.well-known/jwks.json](https://pipedream.com/.well-known/jwks.json). See [this workflow template](https://pipedream.com/new?h=tch_rBf76M) for example code you can use to validate these tokens. + +Access tokens are hashed before being saved in the Pipedream database, and are encrypted at rest. + +Access tokens expire after 1 hour. Tokens can be revoked at any time. + +## Pipedream Connect + +[Pipedream Connect](/connect) is the easiest way for your users to connect to [over {process.env.PUBLIC_APPS}+ APIs](https://pipedream.com/apps), **right in your product**. + +### Client-side SDK + +Pipedream provides a [client-side SDK](/connect/api#typescript-sdk-browser) to initiate authorization or accept API keys on behalf of your users in environments that can run JavaScript. You can see the code for that SDK [here](https://github.com/PipedreamHQ/pipedream/tree/master/packages/sdk). + +When you initiate authorization, you must: + +1. [Create a server-side token for a specific end user](/connect/api#create-a-new-token) +2. Initiate auth with that token, connecting an account for a specific user + +These tokens can only initiate the auth connection flow. They have no permissions to access credentials or perform other operations against the REST API. They are meant to be scoped to a specific user, for use in clients that need to initiate auth flows. + +Tokens expire after 4 hours, at which point you must create a new token for that specific user. + +### Connect Link + +You can also use [Connect Link](/connect/quickstart#use-connect-link) to generate a URL that initiates the authorization flow for a specific user. This is useful when you want to initiate the auth flow from a client-side environment that can't run JavaScript, or include the link in an email, chat message, etc. + +Like tokens, Connect Links are coupled to specific users, and expire after 4 hours. + +### REST API + +The Pipedream Connect API is a subset of the [Pipedream REST API](/rest-api/). See the [REST API Security](#pipedream-rest-api-security-oauth-clients) section for more information on how we secure the API. + ## Execution environment The **execution environment** refers to the environment in which your sources, workflows, and other Pipedream code is executed. diff --git a/docs-v2/pages/projects/index.mdx b/docs-v2/pages/projects/index.mdx index 3ddd71ed76e6c..86b7709da1e6d 100644 --- a/docs-v2/pages/projects/index.mdx +++ b/docs-v2/pages/projects/index.mdx @@ -75,6 +75,10 @@ At this time it's not possible to move workflows out of GitHub Synchronized Proj +## Finding your project's ID + +Visit your project's **Settings** and copy the project ID. + ## Access Controls The [projects list view](https://pipedream.com/projects) contains **Owner** and **Access** columns. diff --git a/docs-v2/pages/rest-api/auth.mdx b/docs-v2/pages/rest-api/auth.mdx index 4447e67c0712d..d6d6a995fd987 100644 --- a/docs-v2/pages/rest-api/auth.mdx +++ b/docs-v2/pages/rest-api/auth.mdx @@ -1,16 +1,105 @@ # Authentication -## Pipedream API Key +The Pipedream API supports two methods of authentication: [OAuth](#oauth) and [User API keys](#user-api-keys). -When you sign up for Pipedream, an API key is automatically generated for your account. You can use this key to authorize requests to the API. +**We recommend OAuth** for a few reasons: + +✅ OAuth clients are tied to the workspace, administered by workspace admins
+✅ Tokens are short-lived
+✅ OAuth clients support scopes, limiting access to specific operations (coming soon!)
+✅ Limit access to specific Pipedream projects (coming soon!)
+ +When testing the API or using the CLI, you can use your user API key. This key is tied to your user account and provides full access to any resources your user has access to, across workspaces. + +## OAuth + +Workspace administrators can create OAuth clients in your workspace's [API settings](https://pipedream.com/settings/api). + +Since API requests are meant to be made server-side, and since grants are not tied to individual end users, all OAuth clients are [**Client Credentials** applications](https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/). + +### Creating an OAuth client + +1. Visit the [API settings](https://pipedream.com/settings/api) for your workspace. +2. Click the **New OAuth Client** button. +3. Name your client and click **Create**. +4. Copy the client secret. **It will not be accessible again**. Click **Close**. +5. Copy the client ID from the list. + +### How to get an access token + +In the client credentials model, you exchange your OAuth client ID and secret for an access token. Then you use the access token to make API requests. + +If you're running a server that executes JavaScript, we recommend using [the Pipedream SDK](/connect/api#installing-the-typescript-sdk), which automatically refreshes tokens for you. + +```javascript +import { createBackendClient } from "@pipedream/sdk"; + +// These secrets should be saved securely and passed to your environment +const pd = createBackendClient({ + credentials: { + clientId: "YOUR_CLIENT_ID", + clientSecret: "YOUR_CLIENT_SECRET", + }, +}); + +// Use the SDK's helper methods to make requests +const accounts = await pd.getAccounts({ include_credentials: 1 }); + +// Or make any Pipedream API request with the fresh token +const accounts = await pd.makeRequest("/accounts", { + method: "GET" + headers: { + "Authorization": await this.oauthAuthorizationHeader(), // Automatically uses a fresh token + }, + params: { + include_credentials: 1, + } +}); +``` + +You can also manage this token refresh process yourself, using the `/oauth/token` API endpoint: + +```bash +curl https://api.pipedream.com/v1/oauth/token \ + -H 'Content-Type: application/json' \ + -d '{ "grant_type": "client_credentials", "client_id": "", "client_secret": "" }' +``` + +Access tokens expire after 1 hour. Store access tokens securely, server-side. + +### Revoking a client secret + +1. Visit your workspace's [API settings](https://pipedream.com/settings/api). +2. Click the **...** button to the right of the OAuth client whose secret you want to revoke, then click **Rotate client secret**. +3. Copy the new client secret. **It will not be accessible again**. + +### OAuth security + +See [the OAuth section of the security docs](/privacy-and-security#pipedream-rest-api-security-oauth-clients) for more information on how Pipedream secures OAuth credentials. + +## User API keys + +When you sign up for Pipedream, an API key is automatically generated for your user account. You can use this key to authorize requests to the API. You'll find this API key in your [User Settings](https://pipedream.com/user) (**My Account** -> **API Key**). +**Use user API keys when testing the API or using the CLI**. This key is tied to your user account and provides full access to any resources your user has access to, across workspaces. + +### Revoking your API key + +You can revoke your API key in your [Account Settings](https://pipedream.com/settings/account) (**Settings** -> **Account**). Click on the **REVOKE** button directly to the right of your API key. + +This will revoke your original API key, generating a new one. Any API requests made with the original token will yield a `401 Unauthorized` error. + ## Authorizing API requests -Pipedream uses [Bearer Authentication](https://oauth.net/2/bearer-tokens/) to authorize your access to the API or SSE event streams. When you make API requests, pass an `Authorization` header of the following format: +Whether you use OAuth access tokens or user API keys, Pipedream uses [Bearer Authentication](https://oauth.net/2/bearer-tokens/) to authorize your access to the API or SSE event streams. When you make API requests, pass an `Authorization` header of the following format: ``` +# OAuth access token +Authorization: Bearer + +# User API key Authorization: Bearer ``` @@ -24,9 +113,3 @@ curl 'https://api.pipedream.com/v1/users/me' \ ## Using the Pipedream CLI You can [link the CLI to your Pipedream account](/cli/login/), which will automatically pass your API key in the `Authorization` header with every API request. - -## Revoking your API key - -You can revoke your API key in your [Account Settings](https://pipedream.com/settings/account) (**Settings** -> **Account**). Click on the **REVOKE** button directly to the right of your API key. - -This will revoke your original API key, generating a new one. Any API requests made with the original token will yield a `401 Unauthorized` error. diff --git a/docs-v2/pages/rest-api/index.mdx b/docs-v2/pages/rest-api/index.mdx index c0a22ee4feed1..d6b42a1f78b6e 100644 --- a/docs-v2/pages/rest-api/index.mdx +++ b/docs-v2/pages/rest-api/index.mdx @@ -4,7 +4,7 @@ import Callout from "@/components/Callout"; ## Overview -Use the REST API to create and manage sources, workflows, subscriptions, and more. +Use the REST API to create workflows, manage event sources, handle subscriptions, and more. ## Base URL @@ -12,34 +12,33 @@ The base URL for all requests is [https://api.pipedream.com/v1](https://api.pipe ## Authentication -You authenticate to the REST API using your [Pipedream API -key](/rest-api/auth/#pipedream-api-key). When you make API requests, pass an -`Authorization` header of the following format: +The Pipedream API supports two methods of authentication: [OAuth](/rest-api/auth#oauth) and [User API keys](/rest-api/auth#user-api-keys). **Pipedream recommends using OAuth for most use cases**. -``` -Authorization: Bearer -``` - -For example, here's how you can use `cURL` to fetch profile information for the -authenticated user: +All credentials are passed as a Bearer token in the `Authorization` header. For example: ```shell -curl 'https://api.pipedream.com/v1/users/me' \ - -H 'Authorization: Bearer ' +curl https://api.pipedream.com/v1/accounts \ + -H "Authorization Bearer " ``` -Learn more about [API authentication](/rest-api/auth/) +Learn more in the [Authentication docs](/rest-api/auth/). + +### Authenticating as a workspace vs. a user + +Pipedream recommends using [OAuth](/rest-api/auth#oauth) to auth against the Pipedream API. OAuth tokens are associated with a workspace, and the API will automatically use the workspace associated with the token. + +When you authenticate with a user API key, you must [specify the workspace ID in the `org_id` parameter](#common-parameters) when making requests to specific endpoints. ## Required headers -The `Authorization` header is required on all endpoints for authentication. +The `Authorization` header is required on all endpoints, to authenticate API requests. `POST` or `PUT` requests that accept JSON payloads also require a `Content-Type` header set to `application/json`. For example: ```shell curl https://api.pipedream.com/v1/components \ - -H "Authorization: Bearer " \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"component_url": "https://github.com/PipedreamHQ/pipedream/blob/master/components/rss/sources/new-item-in-feed/new-item-in-feed.js"}' ``` @@ -70,25 +69,18 @@ including all fields). Pass as a string of comma-separated values: --- -`workspace_id` **string** - -Some endpoints require you to specify [your workspace ID](/workspaces/#finding-your-workspace-s-id) you want the operation to take effect in. For example, if you're creating a new event source in a specific workspace, you'll want to pass the workspace ID in the `workspace_id` query string parameter. - -[Find your workspace's ID here](/workspaces/#finding-your-workspace-s-id). +`org_id` **string** - - If your organization is on one of our legacy plans like the Free Teams or - Teams plan, the `workspace_id` is synonymous with your `org_id`. Just pass - your organization ID as the same parameter. + +The `org_id` parameter is only required when using [User API keys](/rest-api/auth#user-api-keys). When authenticating with OAuth tokens, the API will automatically use the workspace associated with the token. -## Working with resources owned by a workspace +When using [User API keys](/rest-api/auth#user-api-keys), some endpoints require you to specify [your workspace ID](/workspaces/#finding-your-workspace-s-id) you want the operation to take effect in: -If you're interacting with resources owned by a [workspace](/workspaces/), you may need to specify the workspace ID as a part of the request's query string parameter or route: +- When _fetching_ specific resources (for example, when you [retrieve events for a specific source](#get-source-events)), **you should not need to pass `org_id`**. If your user is a part of the workspace, and you have access to that resource, and the API will return the details of the resource. +- When _creating_ new resources, you'll need to specify the `org_id` in which you want to create the resource. -- When fetching specific resources (for example, when you [retrieve events for a specific source](#get-source-events)), you should not need to pass your workspace's ID. If your user is a part of the workspace, you should have access to that resource, and the API will return the details of the resource. -- When _creating_ new resources, you'll need to specify the `org_id` where you want the resource to live as a query string parameter (`?org_id=o_abc123`). Read more about the `org_id` parameter in the [Common Parameters section](#common-parameters). -- When _listing_ resources, use [the workspace-specific endpoints here](#workspaces). +[Find your workspace / org ID here](/workspaces/#finding-your-workspace-s-id). ## Pagination @@ -124,8 +116,6 @@ A cursor, specifying you'd like to retrieve items _before_ this cursor. Cursor strings are returned with all paginated responses. ---- - ### Example Paginated Request This request fetches a page of 5 sources in the authenticated account, after a @@ -165,19 +155,81 @@ The response from the request above will have a shape that looks like: ## Errors Pipedream uses conventional HTTP response codes to indicate the success or -failure of an API request. Codes in the **2xx** range indicate success. Codes in -the **4xx** range indicate an error that failed (e.g., a required parameter was -omitted). Codes in the **5xx** range indicate an error with Pipedream’s server. +failure of an API request: + +- Codes in the `2xx` range indicate success. +- Codes in the `4xx` range indicate an error that failed (e.g., a required parameter was omitted). +- Codes in the `5xx` range indicate an error with Pipedream's server. ## Accounts [Connected accounts](/connected-accounts/) let you manage credentials for integrated APIs. -### Get account +### List accounts + +List connected accounts accessible by the authenticated user or workspace. + +``` +GET /accounts/ +``` + +#### Parameters + +`app` **string** (_optional_) + +The ID or name slug the app you'd like to retrieve. For example, Slack's unique app ID is `app_OkrhR1`, and its name slug is `slack`. + +You can find the app's ID in the response from the [List apps](#list-apps) endpoint, and the name slug under the **Authentication** section of any [app page](https://pipedream.com/apps). + +--- + +`oauth_app_id` **string** (_optional_) + +The ID of the custom [OAuth app](/connect/quickstart#creating-a-custom-oauth-client) you'd like to retrieve accounts for. --- -By default, this route returns metadata for a specific connected account. Set `include_credentials=1` to return credentials that you can use in any app where you need auth. [See this guide](/connected-accounts/api/) to learn more. +`external_user_id` **string** (_optional_) + +[The external user ID](/connect/api/#external-users) in your system that you want to retrieve accounts for. + +--- + +`include_credentials` **boolean** (_optional_) + +Pass `include_credentials=true` as a query-string parameter to include the account credentials in the response + +#### Example Request — Get account metadata + +```bash +curl 'https://api.pipedream.com/v1/accounts' \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" +``` + +#### Example Response — Get account metadata + +```json +{ + "data": [ + { + "id": "apn_abc123", + "created_at": "2022-07-27T20:37:52.000Z", + "updated_at": "2024-02-11T04:18:46.000Z", + "name": "Google Sheets — pipedream.com", // account nickname, if set + "app": { + "id": "app_abc123", + "name": "Google Sheets" + }, + "healthy": true // true if Pipedream can make a successful test request + } + ] +} +``` + +### Get account + +By default, this route returns metadata for a specific connected account. Set `include_credentials=true` to return credentials that you can use in any app where you need auth. [See this guide](/connected-accounts/api/) to learn more. #### Endpoint @@ -187,8 +239,6 @@ GET /accounts/{account_id} #### Parameters ---- - `account_id` **string** To retrieve your account ID: @@ -201,21 +251,21 @@ To retrieve your account ID:
-`include_credentials` **number** +--- -Default `0`: Response only contains account metadata, no credentials. Pass `1` to include `credentials`. +`include_credentials` **boolean** (_optional_) ---- +Pass `include_credentials=true` as a query-string parameter to include the account credentials in the response -#### Example Request — Get account metadata +#### Example Request — Get account metadata ```bash curl 'https://api.pipedream.com/v1/accounts/' \ - -H "Authorization: Bearer " \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" ``` -#### Example Response — Get account metadata +#### Example Response — Get account metadata ```json { @@ -223,7 +273,7 @@ curl 'https://api.pipedream.com/v1/accounts/' \ "id": "apn_abc123", "created_at": "2022-07-27T20:37:52.000Z", "updated_at": "2024-02-11T04:18:46.000Z", - "name": "Google Sheets — pipedream.com", // account nickname, if set + "name": "Google Sheets — pipedream.com", // account nickname, if set "app": { "id": "app_abc123", "name": "Google Sheets" @@ -236,8 +286,8 @@ curl 'https://api.pipedream.com/v1/accounts/' \ #### Example Request — Get account credentials ```bash -curl 'https://api.pipedream.com/v1/accounts/?include_credentials=1' \ - -H "Authorization: Bearer " \ +curl 'https://api.pipedream.com/v1/accounts/?include_credentials=true' \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" ``` @@ -250,7 +300,7 @@ curl 'https://api.pipedream.com/v1/accounts/?include_credentials=1' "created_at": "2022-07-27T20:37:52.000Z", "updated_at": "2024-02-11T04:18:46.000Z", "expires_at": "2024-02-11T05:18:46.000Z", - "name": "Google Sheets — pipedream.com", // account nickname, if set + "name": "Google Sheets — pipedream.com", // account nickname, if set "app": { "id": "app_abc123", "name": "Google Sheets" @@ -268,20 +318,134 @@ The properties of the `credentials` object are specific to the app. All OAuth apps expose the following properties: -- `oauth_access_token` — A fresh OAuth access token -- `oauth_client_id` — The client ID of the OAuth app -- `oauth_refresh_token` — The latest OAuth refresh token for your grant -- `oauth_uid` — A unique identifier in the third party API's system, typically a user ID or email address +- `oauth_access_token` — A fresh OAuth access token +- `oauth_client_id` — The client ID of the OAuth app +- `oauth_refresh_token` — The latest OAuth refresh token for your grant +- `oauth_uid` — A unique identifier in the third party API's system, typically a user ID or email address Apps with static credentials expose fields specific to the API, e.g. `api_key`. Review the response for specific apps to see the app-specific response. +## Apps + +### List Apps + +--- + +Retrieve a list of all apps available on Pipedream. + +#### Endpoint + +``` +GET /apps +``` + +#### Parameters + +`q` **string** (_optional_) + +A query string to filter the list of apps. For example, to search for apps that **contain** the string "Slack", pass `q=Slack`. + +#### Example Request + +```shell +curl https://api.pipedream.com/v1/apps + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" +``` + +#### Example Response + +```json +{ + "page_info": { + "total_count": 2, + "count": 2, + "start_cursor": "c2xhY2s", + "end_cursor": "c2xhY2tfYm90" + }, + "data": [ + { + "id": "app_OkrhR1", + "name_slug": "slack", + "name": "Slack", + "auth_type": "oauth", + "description": "Slack is a channel-based messaging platform. With Slack, people can work together more effectively, connect all their software tools and services, and find the information they need to do their best work — all within a secure, enterprise-grade environment.", + "img_src": "https://assets.pipedream.net/s.v0/app_OkrhR1/logo/orig", + "custom_fields_json": "[]", + "categories": [ + "Communication" + ] + }, + { + "id": "app_mWnheL", + "name_slug": "slack_bot", + "name": "Slack Bot", + "auth_type": "keys", + "description": "Interact with Slack with your own bot user", + "img_src": "https://assets.pipedream.net/s.v0/app_mWnheL/logo/orig", + "custom_fields_json": "[{\"name\":\"bot_token\",\"label\":\"Bot Token\",\"description\":null,\"default\":null,\"optional\":null,\"type\":\"password\"}]", + "categories": [ + "Communication" + ] + } + ] +} +``` + +### Get an App + +Retrieve metadata for a specific app. + +#### Endpoint + +``` +GET /apps/{app_id} +``` + +#### Path Parameters + +`app_id` **string** + +The ID or name slug the app you'd like to retrieve. For example, Slack's unique app ID is `app_OkrhR1`, and its name slug is `slack`. + +You can find the app's ID in the response from the [List apps](#list-apps) endpoint, and the name slug under the **Authentication** section of any [app page](https://pipedream.com/apps). + +#### Example Request + +```bash +curl https://api.pipedream.com/v1/apps/app_OkrhR1 \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" +``` + +#### Example Response + +```json +"data": [ + { + "id": "app_OkrhR1", + "name_slug": "slack", + "name": "Slack", + "auth_type": "oauth", + "description": "Slack is a channel-based messaging platform. With Slack, people can work together more effectively, connect all their software tools and services, and find the information they need to do their best work — all within a secure, enterprise-grade environment.", + "img_src": "https://assets.pipedream.net/s.v0/app_OkrhR1/logo/orig", + "custom_fields_json": "[]", + "categories": [ + "Communication" + ] + } +] +``` + ## Components Components are objects that represent the code for an [event source](#sources). ### Create a component ---- + +`/components` endpoints are only available when using [user API keys](/rest-api/auth#user-api-keys), not yet for workspace [OAuth tokens](/rest-api/auth#oauth). + Before you can create a source using the REST API, you must first create a **component** - the code for the source. @@ -297,8 +461,6 @@ POST /components #### Parameters ---- - `component_code` **string** (_optional_) The full code for a [Pipedream component](/components/api/). @@ -324,7 +486,7 @@ Here's an example of how to create an RSS component from a Github URL: ```shell curl https://api.pipedream.com/v1/components \ - -H "Authorization: Bearer " \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"component_url": "https://github.com/PipedreamHQ/pipedream/blob/master/components/rss/sources/new-item-in-feed/new-item-in-feed.js"}' ``` @@ -375,8 +537,6 @@ GET /components/{key|id} #### Parameters ---- - `key` **string** The component key (identified by the `key` property within the component's @@ -388,13 +548,11 @@ source code) you'd like to fetch metadata for (example: `my-component`) The saved component ID you'd like to fetch metadata for (example: `sc_JDi8EB`) ---- - #### Example Request ```shell curl https://api.pipedream.com/v1/components/my-component \ - -H "Authorization: Bearer " + -H "Authorization: Bearer " ``` #### Example Response @@ -444,20 +602,16 @@ GET /components/registry/{key} #### Parameters ---- - `key` **string** The component key (identified by the `key` property within the component's source code) you'd like to fetch metadata for (example: `my-component`) ---- - #### Example Request ```shell curl https://api.pipedream.com/v1/components/registry/github-new-repository \ - -H "Authorization: Bearer " + -H "Authorization: Bearer " ``` #### Example Response @@ -491,12 +645,77 @@ curl https://api.pipedream.com/v1/components/registry/github-new-repository \ } ``` -## Events +### Search for registry components -### Get Source Events +Search for components in the global registry with natural language. Pipedream will use AI to match your query to the most relevant components. + +#### Endpoint + +``` +GET /components/search +``` + +#### Parameters + +`query` **string** + +The query string to search for components in the global registry, e.g. "Send a message to Slack on new Hubspot contacts" + +--- + +`app` **string** (_optional_) + +The name slug the app you'd like to filter results for. For example, Slack's name slug is `slack`. Returned sources and actions are filtered to only those tied to the specified app. + +You can find the name slug under the **Authentication** section of any [app page](https://pipedream.com/apps). + +--- + +`similarity_threshold` **number** (_optional_) + +The minimum similarity score required for a component to be returned. The similarity score is a number between 0 and 1, where 1 is a perfect match. Similarity here is computed as the cosine distance between the embedding of the user query and the embedding of the component's metadata. --- +`debug` **boolean** (_optional_) + +Pass `debug=true` to return additional data in the response, useful for inspecting the results. + +#### Example Request + +```shell +curl https://api.pipedream.com/v1/components/search\?query\="When someone sends a tweet mentioning my brand, send me an SMS" \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" +``` + +### Example Response + +```json +{ + "sources": [ + "twitter-new-mention-received-by-user", + "twitter-new-tweet-posted-by-user", + "twitter-new-tweet-posted-matching-query" + ], + "actions": [ + "sms-send-sms", + "sms_fusion-send-sms", + "sms_alert-send-sms" + ] +} +``` + +## Connect + +[Pipedream Connect](/connect) is the easiest way for your users to connect to [over {process.env.PUBLIC_APPS}+ APIs](https://pipedream.com/apps), **right in your product**. You can build in-app messaging, CRM syncs, AI-driven products, [and much more](/connect/use-cases), all in a few minutes. Visit [the quickstart](/connect/quickstart) to build your first integration. + +Read more about the Connect API in the [Connect API docs](/connect/api/). + +## Events + +### Get Source Events + Retrieve up to the last 100 events emitted by a source. #### Endpoint @@ -523,8 +742,6 @@ GET /sources/{id}/event_summaries?limit=10 ### Delete source events ---- - Deletes all events, or a specific set of events, tied to a source. By default, making a `DELETE` request to this endpoint deletes **all** events @@ -544,8 +761,6 @@ DELETE /sources/{id}/events #### Parameters ---- - `start_id` **string** The event ID from which you'd like to start deleting events. @@ -591,8 +806,6 @@ curl -X DELETE \ The request will delete the **first two events**. ---- - #### Example Request You can delete a single event by passing its event ID in both the value of the @@ -609,100 +822,112 @@ curl -X DELETE \ Deletion happens asynchronously, so you'll receive a `202 Accepted` HTTP status code in response to any deletion requests. -### List Projects +## OAuth -Programmatically list the workspace's projects. +### Get a new access token + +Exchanges a client ID and client secret for a new access token. #### Endpoint ``` -GET /v1/workspaces//projects +POST /oauth/token ``` -#### Path Parameters +#### Parameters -`workspaces_id` **string** +`grant_type` **string** -[Switch to your workspace's context](/workspaces/#switching-between-workspaces) and [find your org's ID](/workspaces/#finding-your-workspace-s-id). +The OAuth grant type. For Pipedream, this is always `client_credentials`. -#### Example Responses +--- -``` - "data": [ - { - "id": "proj_kYRs18", - "hid": "proj_kYRs18", - "name": "Sample Project", - "repository_id": null, - "repository_path": null, - "created_at": "2024-02-05T21:47:24.000Z", - "updated_at": "2024-02-06T16:13:07.000Z", - "org_id": 1, - "exceptions": null, - "allow_support": false - } - ] +`client_id` **string** + +The client ID of the OAuth app. + +--- + +`client_secret` **string** + +The client secret of the OAuth app. + +#### Example Request + +```bash +curl https://api.pipedream.com/v1/oauth/token \ + -H 'Content-Type: application/json' \ + -d '{ "grant_type": "client_credentials", "client_id": "", "client_secret": "" }' ``` -## Sources +#### Example Response -Event sources run code to collect events from an API, or receive events via -webhooks, emitting those events for use on Pipedream. Event sources can function -as workflow triggers. [Read more here](/sources/). +```json +{ + "access_token": "", + "token_type": "Bearer", + "expires_in": 3600, + "created_at": 1645142400 +} +``` -### List Current User Sources +### Revoke an access token ---- +Revokes an access token, rendering it invalid for future requests. #### Endpoint ``` -GET /users/me/sources/ +POST /oauth/revoke ``` #### Parameters -_No parameters_ +`token` **string** + +The access token to revoke. + +--- + +`client_id` **string** + +The client ID of the OAuth app. + +--- + +`client_secret` **string** + +The client secret of the OAuth app. + +--- #### Example Request -```shell -curl 'https://api.pipedream.com/v1/users/me/sources' \ - -H 'Authorization: Bearer ' +```bash +curl https://api.pipedream.com/v1/oauth/revoke \ + -H 'Content-Type: application/json' \ + -d '{ "token": "", "client_id": "", "client_secret": "" }' ``` #### Example Response +This endpoint will return a `200 OK` response with an empty body if the token was successfully revoked: + ```json -{ - "page_info": { - "total_count": 19, - "count": 10, - "start_cursor": "ZGNfSzB1QWVl", - "end_cursor": "ZGNfeUx1alJx" - }, - "data": [ - { - "id": "dc_abc123", - "component_id": "sc_def456", - "configured_props": { - "http": { - "endpoint_url": "https://myendpoint.m.pipedream.net" - } - }, - "active": true, - "created_at": 1587679599, - "updated_at": 1587764467, - "name": "test", - "name_slug": "test" - } - ] -} +{} ``` +## Sources + +Event sources run code to collect events from an API, or receive events via +webhooks, emitting those events for use on Pipedream. Event sources can function +as workflow triggers. [Read more here](/sources/). + ### Create a Source ---- + +This endpoint is only available when using [user API keys](/rest-api/auth#user-api-keys), not yet for workspace [OAuth tokens](/rest-api/auth#oauth). + #### Endpoint @@ -712,8 +937,6 @@ POST /sources/ #### Parameters ---- - `component_id` **string** (_optional_) The ID of a component previously created in your account. [See the component @@ -754,7 +977,7 @@ of the component used to create the source. ```shell curl https://api.pipedream.com/v1/sources \ - -H "Authorization: Bearer " \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"component_url": "https://github.com/PipedreamHQ/pipedream/blob/master/components/rss/sources/new-item-in-feed/new-item-in-feed.js", "name": "your-name-here", "configured_props": { "url": "https://rss.m.pipedream.net", "timer": { "intervalSeconds": 60 }}}' ``` @@ -785,12 +1008,8 @@ Example response from creating an RSS source that runs once a minute: } ``` ---- - ### Update a source ---- - #### Endpoint ``` @@ -799,8 +1018,6 @@ PUT /sources/{id} #### Parameters ---- - `component_id` **string** (_optional_) The ID of a component previously created in your account. [See the component @@ -848,8 +1065,6 @@ Default: `true`. ### Delete a source ---- - #### Endpoint ``` @@ -860,15 +1075,11 @@ DELETE /sources/{id} ### Listen for events from another source or workflow ---- - You can configure a source or workflow to receive events from any number of other workflows or sources. For example, if you want a single workflow to run on 10 different RSS sources, you can configure the workflow to _listen_ for events from those 10 sources. ---- - #### Endpoint ``` @@ -877,8 +1088,6 @@ POST /subscriptions?emitter_id={emitting_component_id}&event_name={event_name}&l #### Parameters ---- - `emitter_id` **string** The ID of the workflow or component emitting events. Events from this component @@ -924,8 +1133,6 @@ retrieve the ID of existing components. You can retrieve the ID of your workflow in your workflow's URL - it's the string `p_2gCPml` in `https://pipedream.com/@dylan/example-rss-sql-workflow-p_2gCPml/edit`. ---- - #### Example Request You can configure workflow `p_abc123` to listen to events from the source @@ -934,14 +1141,12 @@ You can configure workflow `p_abc123` to listen to events from the source ```shell curl "https://api.pipedream.com/v1/subscriptions?emitter_id=dc_def456&listener_id=p_abc123" \ -X POST \ - -H "Authorization: Bearer " \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" ``` ### Automatically subscribe a listener to events from new workflows / sources ---- - You can use this endpoint to automatically receive events, like workflow errors, in another listening workflow or event source. Once you setup the auto-subscription, any new workflows or event sources you create will @@ -955,8 +1160,6 @@ endpoint](#listen-for-events-from-another-source-or-workflow). **Currently, this feature is enabled only on the API. The Pipedream UI will not display the sources configured as listeners using this API**. ---- - #### Endpoint ``` @@ -965,8 +1168,6 @@ POST /auto_subscriptions?event_name={event_name}&listener_id={receiving_source_i #### Parameters ---- - `event_name` **string** The name of the event stream whose events you'd like to receive: @@ -986,8 +1187,6 @@ retrieve the ID of existing components. You can retrieve the ID of your workflow in your workflow's URL - it's the string `p_2gCPml` in `https://pipedream.com/@dylan/example-rss-sql-workflow-p_2gCPml/edit`. ---- - #### Example Request You can configure workflow `p_abc123` to listen to events from the source @@ -996,21 +1195,17 @@ You can configure workflow `p_abc123` to listen to events from the source ```shell curl "https://api.pipedream.com/v1/auto_subscriptions?event_name=$errors&listener_id=p_abc123" \ -X POST \ - -H "Authorization: Bearer " \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" ``` ### Delete a subscription ---- - Use this endpoint to delete an existing subscription. This endpoint accepts the same parameters as the [`POST /subscriptions` endpoint](#listen-for-events-from-another-source-or-workflow) for creating subscriptions. ---- - #### Endpoint ``` @@ -1019,8 +1214,6 @@ DELETE /subscriptions?emitter_id={emitting_component_id}&listener_id={receiving_ #### Parameters ---- - `emitter_id` **string** The ID of the workflow or component emitting events. Events from this component @@ -1073,8 +1266,6 @@ subscriptions](#get-current-user-s-subscriptions): } ``` ---- - #### Example Request You can delete a subscription you configured for workflow `p_abc123` to listen @@ -1083,15 +1274,17 @@ to events from the source `dc_def456` using the following command: ```shell curl "https://api.pipedream.com/v1/subscriptions?emitter_id=dc_def456&listener_id=p_abc123" \ -X DELETE \ - -H "Authorization: Bearer " \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" ``` ## Users -### Get Current User Info + +These endpoints only work when using [user API keys](/rest-api/auth#user-api-keys), and will not work with workspace-level OAuth clients. + ---- +### Get Current User Info Retrieve information on the authenticated user. @@ -1109,7 +1302,7 @@ _No parameters_ ```bash curl 'https://api.pipedream.com/v1/users/me' \ - -H 'Authorization: Bearer ' + -H 'Authorization: Bearer ' ``` #### Example Response @@ -1168,107 +1361,6 @@ Paid user: } ``` -### Get Current User's Subscriptions - ---- - -Retrieve all the [subscriptions](#subscriptions) configured for the -authenticated user. - -#### Endpoint - -``` -GET /users/me/subscriptions -``` - -#### Parameters - -_No parameters_ - -#### Example Request - -```shell -curl 'https://api.pipedream.com/v1/users/me/subscriptions' \ - -H 'Authorization: Bearer ' -``` - -#### Example Response - -```json -{ - "data": [ - { - "id": "sub_abc123", - "emitter_id": "dc_abc123", - "listener_id": "p_abc123", - "event_name": "" - }, - { - "id": "sub_def456", - "emitter_id": "dc_def456", - "listener_id": "p_def456", - "event_name": "" - } - ] -} -``` - -### Get Current User's Webhooks - ---- - -Retrieve all the [webhooks](#webhooks) configured for the authenticated user. - -#### Endpoint - -``` -GET /users/me/webhooks -``` - -#### Parameters - -_No parameters_ - -#### Example Request - -```shell -curl 'https://api.pipedream.com/v1/users/me/webhooks' \ - -H 'Authorization: Bearer ' -``` - -#### Example Response - -```json -{ - "page_info": { - "total_count": 2, - "count": 2, - "start_cursor": "d2hfMjlsdUd6", - "end_cursor": "d2hfb3dHdWVv" - }, - "data": [ - { - "id": "wh_abc123", - "name": null, - "description": null, - "url": "https://endpoint.m.pipedream.net", - "active": true, - "created_at": 1611964025, - "updated_at": 1611964025 - }, - { - "id": "wh_def456", - "name": "Test webhook", - "description": "just a test", - "url": "https://endpoint2.m.pipedream.net", - "active": true, - "created_at": 1605835136, - "updated_at": 1605835136 - } - ] -} -``` - ## Webhooks Pipedream supports webhooks as a way to deliver events to a endpoint you own. @@ -1295,8 +1387,6 @@ POST /webhooks?url={your_endpoint_url}&name={name}&description={description} #### Parameters ---- - `url` **string** The endpoint URL where you'd like to deliver events. Any events sent to this @@ -1343,7 +1433,7 @@ You can create a webhook that delivers events to ```shell curl "https://api.pipedream.com/v1/webhooks?url=https://endpoint.m.pipedream.net&name=name&description=description" \ -X POST \ - -H "Authorization: Bearer " \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" ``` @@ -1375,8 +1465,6 @@ You can list webhooks you've created in your account using the ### Delete a webhook ---- - Use this endpoint to delete a webhook in your account. #### Endpoint @@ -1387,8 +1475,6 @@ DELETE /webhooks/{id} #### Path Parameters ---- - `id` **string** The ID of a webhook in your account. @@ -1400,15 +1486,21 @@ The ID of a webhook in your account. ```shell curl "https://api.pipedream.com/v1/webhooks/wh_abc123" \ -X DELETE \ - -H "Authorization: Bearer " \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" ``` ## Workflows +### Invoke workflow + +You can invoke workflows by making an HTTP request to a workflow's HTTP trigger. [See the docs on authorizing requests and invoking workflows](/workflows/triggers#authorizing-http-requests) for more detail. + ### Create a Workflow ---- + +This endpoint is only available when using [user API keys](/rest-api/auth#user-api-keys), not yet for workspace [OAuth tokens](/rest-api/auth#oauth). + Creates a new workflow within an organization's project. This endpoint allows defining workflow steps, triggers, and settings, based on a supplied template. @@ -1674,7 +1766,9 @@ The ID of the workflow template to base the workflow on. To find a workflow's `t ### Update a Workflow ---- + +This endpoint is only available when using [user API keys](/rest-api/auth#user-api-keys), not yet for workspace [OAuth tokens](/rest-api/auth#oauth). + Updates the workflow's activation status. If you need to modify the workflow's steps, triggers, or connected accounts [consider making a new workflow](#create-a-workflow). @@ -1705,15 +1799,13 @@ The activation status of a workflow. Set to `true` to activate the workflow, or ```bash curl -X PUT 'https://api.pipedream.com/v1/workflows/p_abc123' \ - -H 'Authorization: Bearer ' \ + -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -d '{"active": false, "org_id": "o_BYDI5y"}' ``` ### Get a Workflow's details ---- - Retrieves the details of a specific workflow within an organization's project. #### Endpoint @@ -1730,7 +1822,7 @@ GET /workflows/{workflow_id} ```bash curl 'https://api.pipedream.com/v1/workflows/p_abc123?org_id=o_abc123' \ - -H 'Authorization: Bearer ' + -H 'Authorization: Bearer ' ``` #### Example Response @@ -1783,8 +1875,6 @@ curl 'https://api.pipedream.com/v1/workflows/p_abc123?org_id=o_abc123' \ ### Get Workflow Emits ---- - Retrieve up to the last 100 events emitted from a workflow using [`$send.emit()`](/destinations/emit/#emit-events). @@ -1814,7 +1904,7 @@ GET /v1/workflows/{workflow_id}/event_summaries?expand=event&limit=1 ```shell curl 'https://api.pipedream.com/v1/workflows/p_abc123/event_summaries?expand=event&limit=1' \ - -H 'Authorization: Bearer ' + -H 'Authorization: Bearer ' ``` #### Example Response @@ -1847,12 +1937,8 @@ curl 'https://api.pipedream.com/v1/workflows/p_abc123/event_summaries?expand=eve } ``` ---- - ### Get Workflow Errors ---- - Retrieve up to the last 100 events for a workflow that threw an error. The details of the error, along with the original event data, will be included @@ -1882,7 +1968,7 @@ GET /v1/workflows/{workflow_id}/$errors/event_summaries?expand=event&limit=1 ```shell curl 'https://api.pipedream.com/v1/workflows/p_abc123/$errors/event_summaries?expand=event&limit=1' \ - -H 'Authorization: Bearer ' + -H 'Authorization: Bearer ' ``` #### Example Response @@ -1942,7 +2028,7 @@ Programmatically view your workspace's current credit usage for the billing peri #### Endpoint ``` -GET /v1/workspaces/ +GET /v1/workspaces/ ``` #### Path Parameters @@ -1968,19 +2054,17 @@ GET /v1/workspaces/ ### Get Workspaces's Connected Accounts ---- - Retrieve all the connected accounts for a specific workspace. #### Endpoint ``` -GET /workspaces//accounts +GET /workspaces//accounts ``` #### Path Parameters -`workspace_id` **string** +`org_id` **string** [Switch to your workspace's context](/workspaces/#switching-between-workspaces) and [find your org's ID](/workspaces/#finding-your-workspace-s-id). @@ -1994,7 +2078,7 @@ To look up the connected account information for a specific app, use the `query` ```shell curl 'https://api.pipedream.com/v1/workspaces/o_abc123/accounts?query=google_sheets' \ - -H 'Authorization: Bearer ' + -H 'Authorization: Bearer ' ``` #### Example Response @@ -2018,14 +2102,12 @@ curl 'https://api.pipedream.com/v1/workspaces/o_abc123/accounts?query=google_she ### Get Workspaces's Subscriptions ---- - Retrieve all the [subscriptions](#subscriptions) configured for a specific workspace. #### Endpoint ``` -GET /workspaces//subscriptions +GET /workspaces//subscriptions ``` #### Path Parameters @@ -2038,7 +2120,7 @@ GET /workspaces//subscriptions ```shell curl 'https://api.pipedream.com/v1/workspaces/o_abc123/subscriptions' \ - -H 'Authorization: Bearer ' + -H 'Authorization: Bearer ' ``` #### Example Response @@ -2064,14 +2146,12 @@ curl 'https://api.pipedream.com/v1/workspaces/o_abc123/subscriptions' \ ### Get Workspaces's Sources ---- - Retrieve all the [event sources](#sources) configured for a specific workspace. #### Endpoint ``` -GET /orgs//sources +GET /orgs//sources ``` #### Path Parameters @@ -2084,7 +2164,7 @@ GET /orgs//sources ```shell curl 'https://api.pipedream.com/v1/orgs/o_abc123/sources' \ - -H 'Authorization: Bearer ' + -H 'Authorization: Bearer ' ``` #### Example Response diff --git a/docs-v2/pages/workflows/triggers.mdx b/docs-v2/pages/workflows/triggers.mdx index 160dfd853d5b4..7b97886f6993d 100644 --- a/docs-v2/pages/workflows/triggers.mdx +++ b/docs-v2/pages/workflows/triggers.mdx @@ -1,5 +1,6 @@ import Image from 'next/image' import Callout from '@/components/Callout' +import { Tabs } from 'nextra/components' import PipedreamImg from '@/components/PipedreamImg' import VideoPlayer from "@/components/VideoPlayer"; @@ -100,9 +101,109 @@ You can send data of any [Media Type](https://www.iana.org/assignments/media-typ The primary limit we impose is on the size of the request body: we'll issue a `413 Payload Too Large` status when the body [exceeds our specified limit](#request-entity-too-large). +### Authorizing HTTP requests + +By default, HTTP triggers are public and require no authorization to invoke. Anyone with the endpoint URL can trigger your workflow. When possible, we recommend adding authorization. + +HTTP triggers support two built-in authorization types in the **Authorization** section of the HTTP trigger configuration: a [static, custom token](#custom-token) and [OAuth](#oauth). + +#### Custom token + +To configure a static, custom token for HTTP auth: + +1. Open the **Configure** section of the HTTP trigger +2. Select **Custom token**. +3. Enter whatever secret you'd like and click **Save and Continue**. + +![Custom token auth](https://res.cloudinary.com/pipedreamin/image/upload/v1729791152/Google_Chrome_-_Untitled_Workflow_-_10-24-2024_10-30_AM_-_Build_-_Pipedream_2024-10-24_at_10.31.01_AM_pkh8dk.png) + +When making HTTP requests, pass the custom token as a `Bearer` token in the `Authorization` header: + +```bash +curl -H 'Authorization: Bearer ' https://myendpoint.m.pipedream.net +``` + +#### OAuth + +You can also authorize requests using [Pipedream OAuth clients](/rest-api/auth#oauth): + +1. Open the **Configure** section of the HTTP trigger. +2. Select **OAuth**. +3. If you don't have an existing OAuth client, [create one in your workspace's API settings](/rest-api/auth#creating-an-oauth-application). + +![OAuth authorization](https://res.cloudinary.com/pipedreamin/image/upload/v1729791415/Google_Chrome_-_Untitled_Workflow_-_10-24-2024_10-30_AM_-_Build_-_Pipedream_2024-10-24_at_10.36.04_AM_ujx34e.png) + +Next, you'll need to [generate an OAuth access token](/rest-api/auth#how-to-get-an-access-token). + +When making HTTP requests, pass the OAuth access token as a `Bearer` token in the `Authorization` header: + +```bash +curl -H 'Authorization: Bearer ' https://myendpoint.m.pipedream.net +``` + +You can use the Pipedream SDK to automatically refresh access tokens and invoke workflows: + + + +```typescript +import { createBackendClient, HTTPAuthType } from "@pipedream/sdk"; + +// These secrets should be saved securely and passed to your environment +const pd = createBackendClient({ + credentials: { + clientId: "YOUR_CLIENT_ID", + clientSecret: "YOUR_CLIENT_SECRET", + }, +}); + +await pd.invokeWorkflow( + "enabc123", // pass the endpoint ID or full URL here + { + method: "POST", + body: { + key: "value", + } + }, + HTTPAuthType.OAuth // Will automatically send the Authorization header with a fresh token +) +``` + + +```javascript +import { createBackendClient } from "@pipedream/sdk"; + +// These secrets should be saved securely and passed to your environment +const pd = createBackendClient({ + credentials: { + clientId: "YOUR_CLIENT_ID", + clientSecret: "YOUR_CLIENT_SECRET", + }, +}); + +await pd.invokeWorkflow( + "enabc123", // pass the endpoint ID or full URL here + { + method: "POST", + body: { + key: "value", + } + }, + "oauth" // Will automatically send the Authorization header with a fresh token +) +``` + + + + +#### Implement your own authorization logic + +Since you have access to the entire request object, and can issue any HTTP response from a workflow, you can implement custom logic to validate requests. + +For example, you could require JWT tokens and validate those tokens using the [`jsonwebtoken` package](https://www.npmjs.com/package/jsonwebtoken) at the start of your workflow. + ### Custom domains -To configure endpoints on your own domain, e.g. `endpoint.yourdomain.com` instead of the default `{process.env.ENDPOINT_BASE_URL}` domain, see the [custom domains](/workflows/domains) docs. +To configure endpoints on your own domain, e.g. `endpoint.yourdomain.com` instead of the default `*.m.pipedream.net` domain, see the [custom domains](/workflows/domains) docs. ### How Pipedream handles JSON payloads @@ -441,20 +542,6 @@ You can also [reach out](https://pipedream.com/support/) to inquire about raisin If you control the application sending requests, you should implement [a backoff strategy](https://medium.com/clover-platform-blog/conquering-api-rate-limiting-dcac5552714d) to temporarily slow the rate of events. -### Validating requests - -Since you have access to the entire request object, and can issue any HTTP response from a workflow, you can implement custom logic to validate requests using any [Node.js code](/code/nodejs/). - -For example, you can [require requests pass a specific secret in a header](https://pipedream.com/@dylburger/end-a-workflow-early-on-invalid-secret-p_YyCmmK/edit). Just copy the workflow and add your secret as the value of the the **Secret** param. Add the rest of your code in steps below this initial one. Requests must contain the secret: - -```bash -curl -H 'X-Pipedream-Secret: abc123' https://myendpoint.m.pipedream.net -``` - -Otherwise, the workflow will [end early](/code/nodejs/#ending-a-workflow-early). - -Since you can [run any code](/code/) in a workflow, you can implement more complex validation. For example, you could require JWT tokens and validate those tokens using the [`jsonwebtoken` package](https://www.npmjs.com/package/jsonwebtoken) at the start of your workflow. - ## Schedule Pipedream allows you to run hosted scheduled jobs — commonly-referred to as a "cron job" — [for free](/pricing/). You can think of workflows like scripts that run on a schedule. @@ -599,26 +686,26 @@ myemailaddr+unsubscribe@pipedream.net This allows you implement conditional logic in your workflow based on the data in that string. -## RSS +### Troubleshooting -Choose the RSS trigger to watch an RSS feed for new items: +#### I'm receiving an `Expired Token` error when trying to read an email attachment -![Selecting the RSS feed trigger](pages/workflows/images/triggers/select-rss-trigger.png) +Email attachments are saved to S3, and are accessible in your workflows over [pre-signed URLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html). -This will create an RSS [event source](/sources/) that polls the feed for new items on the schedule you select. Every time a new item is found, your workflow will run. +If the presigned URL for the attachment has expired, then you'll need to send another email to create a brand new pre-signed URL. -## Don't see a trigger you need? +If you're using email attachments in combination with [`$.flow.delay`](/code/nodejs/delay/) or [`$.flow.rerun`](/code/nodejs/rerun/) which introduces a gap of time between steps in your workflow, then there's a chance the email attachment's URL will expire. -If you don't see a trigger you'd like us to support, please [let us know](https://pipedream.com/support/). +To overcome this, we suggest uploading your email attachments to your Project's [File Store](/projects/file-stores/) for persistent storage. -## Troubleshooting +## RSS -### I'm receiving an `Expired Token` error when trying to read an email attachment +Choose the RSS trigger to watch an RSS feed for new items: -Email attachments are saved to S3, and are accessible in your workflows over [pre-signed URLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html). +![Selecting the RSS feed trigger](pages/workflows/images/triggers/select-rss-trigger.png) -If the presigned URL for the attachment has expired, then you'll need to send another email to create a brand new pre-signed URL. +This will create an RSS [event source](/sources/) that polls the feed for new items on the schedule you select. Every time a new item is found, your workflow will run. -If you're using email attachments in combination with [`$.flow.delay`](/code/nodejs/delay/) or [`$.flow.rerun`](/code/nodejs/rerun/) which introduces a gap of time between steps in your workflow, then there's a chance the email attachment's URL will expire. +## Don't see a trigger you need? -To overcome this, we suggest uploading your email attachments to your Project's [File Store](/projects/file-stores/) for persistent storage. +If you don't see a trigger you'd like us to support, please [let us know](https://pipedream.com/support/). diff --git a/docs-v2/yarn.lock b/docs-v2/yarn.lock index 4b34a2150ffe0..202df7966c3b0 100644 --- a/docs-v2/yarn.lock +++ b/docs-v2/yarn.lock @@ -89,7 +89,7 @@ "@algolia/requester-common" "4.22.1" "@algolia/transporter" "4.22.1" -"@algolia/client-search@>= 4.9.1 < 6", "@algolia/client-search@4.22.1": +"@algolia/client-search@4.22.1": version "4.22.1" resolved "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.22.1.tgz" integrity sha512-yb05NA4tNaOgx3+rOxAmFztgMTtGBi97X7PC3jyNeGiwkAjOZc2QrdZBYyIdcDLoI09N0gjtpClcackoTN0gPA== @@ -177,7 +177,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-8.0.0-alpha.6.tgz" integrity sha512-Oam3YCPXzA5nII8+uqO1nur3PxJF3CcQpFJXHPAXJHhjIKvABCodYacDk8x/FQKBmBiUaMqGlEQ04m3H3rWqlA== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.8.0": +"@babel/core@^7.11.6", "@babel/core@^7.12.3": version "7.23.9" resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz" integrity sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw== @@ -198,7 +198,7 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/core@^8.0.0-alpha.1", "@babel/core@^8.0.0-alpha.6": +"@babel/core@^8.0.0-alpha.1": version "8.0.0-alpha.6" resolved "https://registry.npmjs.org/@babel/core/-/core-8.0.0-alpha.6.tgz" integrity sha512-7wfyFNMnB3VkjKrhgLKEbKHs776ZMzaZmtCI9JlmuvoYje17DPxbbWE+1OR2Yzq0K5wK0KtrNUKUCptpH3UMwg== @@ -638,18 +638,6 @@ resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz" integrity sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A== -"@csstools/css-parser-algorithms@^2.6.3": - version "2.6.3" - -"@csstools/css-tokenizer@^2.3.1": - version "2.3.1" - -"@csstools/media-query-list-parser@^2.1.11": - version "2.1.11" - -"@csstools/selector-specificity@^3.1.1": - version "3.1.1" - "@docsearch/css@3.6.1": version "3.6.1" resolved "https://registry.npmjs.org/@docsearch/css/-/css-3.6.1.tgz" @@ -665,8 +653,12 @@ "@docsearch/css" "3.6.1" algoliasearch "^4.19.1" -"@dual-bundle/import-meta-resolve@^4.1.0": - version "4.1.0" +"@emnapi/runtime@^1.1.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.3.1.tgz#0fcaa575afc31f455fd33534c19381cfce6c6f60" + integrity sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw== + dependencies: + tslib "^2.4.0" "@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" @@ -710,15 +702,53 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@eslint/js@8.57.0": + version "8.57.0" + resolved "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz" + integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== + "@eslint/js@^9.2.0": version "9.8.0" resolved "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz" integrity sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA== -"@eslint/js@8.57.0": - version "8.57.0" - resolved "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz" - integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== +"@hapi/boom@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-10.0.1.tgz#ebb14688275ae150aa6af788dbe482e6a6062685" + integrity sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA== + dependencies: + "@hapi/hoek" "^11.0.2" + +"@hapi/bourne@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-3.0.0.tgz#f11fdf7dda62fe8e336fa7c6642d9041f30356d7" + integrity sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w== + +"@hapi/hoek@^11.0.2", "@hapi/hoek@^11.0.4": + version "11.0.4" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-11.0.4.tgz#42a7f244fd3dd777792bfb74b8c6340ae9182f37" + integrity sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ== + +"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" + integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== + +"@hapi/topo@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" + integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@hapi/wreck@^18.0.0": + version "18.1.0" + resolved "https://registry.yarnpkg.com/@hapi/wreck/-/wreck-18.1.0.tgz#68e631fc7568ebefc6252d5b86cb804466c8dbe6" + integrity sha512-0z6ZRCmFEfV/MQqkQomJ7sl/hyxvcZM7LtuVqN3vdAO4vM9eBbowl0kaqQj9EJJQab+3Uuh1GxbGIBFy4NfJ4w== + dependencies: + "@hapi/boom" "^10.0.1" + "@hapi/bourne" "^3.0.0" + "@hapi/hoek" "^11.0.2" "@headlessui/react@^1.7.17": version "1.7.18" @@ -747,18 +777,119 @@ resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz" integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== +"@img/sharp-darwin-arm64@0.33.4": + version "0.33.4" + resolved "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz" + integrity sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA== + optionalDependencies: + "@img/sharp-libvips-darwin-arm64" "1.0.2" + "@img/sharp-darwin-x64@0.33.4": version "0.33.4" - resolved "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.4.tgz" + resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.4.tgz#f77be2d7c3609d3e77cd337b199a772e07b87bd2" integrity sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw== optionalDependencies: "@img/sharp-libvips-darwin-x64" "1.0.2" +"@img/sharp-libvips-darwin-arm64@1.0.2": + version "1.0.2" + resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.2.tgz" + integrity sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA== + "@img/sharp-libvips-darwin-x64@1.0.2": version "1.0.2" - resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.2.tgz#5665da7360d8e5ed7bee314491c8fe736b6a3c39" integrity sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw== +"@img/sharp-libvips-linux-arm64@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.2.tgz#8a05e5e9e9b760ff46561e32f19bd5e035fa881c" + integrity sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw== + +"@img/sharp-libvips-linux-arm@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.2.tgz#0fd33b9bf3221948ce0ca7a5a725942626577a03" + integrity sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw== + +"@img/sharp-libvips-linux-s390x@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.2.tgz#4b89150ec91b256ee2cbb5bb125321bf029a4770" + integrity sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog== + +"@img/sharp-libvips-linux-x64@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.2.tgz#947ccc22ca5bc8c8cfe921b39a5fdaebc5e39f3f" + integrity sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ== + +"@img/sharp-libvips-linuxmusl-arm64@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.2.tgz#821d58ce774f0f8bed065b69913a62f65d512f2f" + integrity sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ== + +"@img/sharp-libvips-linuxmusl-x64@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.2.tgz#4309474bd8b728a61af0b3b4fad0c476b5f3ccbe" + integrity sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw== + +"@img/sharp-linux-arm64@0.33.4": + version "0.33.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.4.tgz#bd390113e256487041411b988ded13a26cfc5f95" + integrity sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q== + optionalDependencies: + "@img/sharp-libvips-linux-arm64" "1.0.2" + +"@img/sharp-linux-arm@0.33.4": + version "0.33.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.4.tgz#14ecc81f38f75fb4cd7571bc83311746d6745fca" + integrity sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ== + optionalDependencies: + "@img/sharp-libvips-linux-arm" "1.0.2" + +"@img/sharp-linux-s390x@0.33.4": + version "0.33.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.4.tgz#119e8081e2c6741b5ac908fe02244e4c559e525f" + integrity sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ== + optionalDependencies: + "@img/sharp-libvips-linux-s390x" "1.0.2" + +"@img/sharp-linux-x64@0.33.4": + version "0.33.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.4.tgz#21d4c137b8da9a313b069ff5c920ded709f853d7" + integrity sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw== + optionalDependencies: + "@img/sharp-libvips-linux-x64" "1.0.2" + +"@img/sharp-linuxmusl-arm64@0.33.4": + version "0.33.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.4.tgz#f3fde68fd67b85a32da6f1155818c3b58b8e7ae0" + integrity sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-arm64" "1.0.2" + +"@img/sharp-linuxmusl-x64@0.33.4": + version "0.33.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.4.tgz#44373724aecd7b69900e0578228144e181db7892" + integrity sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-x64" "1.0.2" + +"@img/sharp-wasm32@0.33.4": + version "0.33.4" + resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.4.tgz#88e3f18d7e7cd8cfe1af98e9963db4d7b6491435" + integrity sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ== + dependencies: + "@emnapi/runtime" "^1.1.1" + +"@img/sharp-win32-ia32@0.33.4": + version "0.33.4" + resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.4.tgz#b1c772dd2952e983980b1eb85808fa8129484d46" + integrity sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw== + +"@img/sharp-win32-x64@0.33.4": + version "0.33.4" + resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.4.tgz#106f911134035b4157ec92a0c154a6b6f88fa4c1" + integrity sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" @@ -1042,11 +1173,61 @@ "@types/mdx" "^2.0.0" "@types/react" ">=16" +"@napi-rs/simple-git-android-arm-eabi@0.1.16": + version "0.1.16" + resolved "https://registry.yarnpkg.com/@napi-rs/simple-git-android-arm-eabi/-/simple-git-android-arm-eabi-0.1.16.tgz#36b752f84a7e75a9dada3d8b307817f0b015a57d" + integrity sha512-dbrCL0Pl5KZG7x7tXdtVsA5CO6At5ohDX3myf5xIYn9kN4jDFxsocl8bNt6Vb/hZQoJd8fI+k5VlJt+rFhbdVw== + +"@napi-rs/simple-git-android-arm64@0.1.16": + version "0.1.16" + resolved "https://registry.yarnpkg.com/@napi-rs/simple-git-android-arm64/-/simple-git-android-arm64-0.1.16.tgz#f84d9e2fdae91bb810b55ffc30a42ce5fe020c76" + integrity sha512-xYz+TW5J09iK8SuTAKK2D5MMIsBUXVSs8nYp7HcMi8q6FCRO7yJj96YfP9PvKsc/k64hOyqGmL5DhCzY9Cu1FQ== + +"@napi-rs/simple-git-darwin-arm64@0.1.16": + version "0.1.16" + resolved "https://registry.yarnpkg.com/@napi-rs/simple-git-darwin-arm64/-/simple-git-darwin-arm64-0.1.16.tgz#8d995a920146c320bf13b32d1b1654f44beaa16b" + integrity sha512-XfgsYqxhUE022MJobeiX563TJqyQyX4FmYCnqrtJwAfivESVeAJiH6bQIum8dDEYMHXCsG7nL8Ok0Dp8k2m42g== + "@napi-rs/simple-git-darwin-x64@0.1.16": version "0.1.16" - resolved "https://registry.npmjs.org/@napi-rs/simple-git-darwin-x64/-/simple-git-darwin-x64-0.1.16.tgz" + resolved "https://registry.yarnpkg.com/@napi-rs/simple-git-darwin-x64/-/simple-git-darwin-x64-0.1.16.tgz#7cc7155392c62f885d248af5f720e108d0aad2b5" integrity sha512-tkEVBhD6vgRCbeWsaAQqM3bTfpIVGeitamPPRVSbsq8qgzJ5Dx6ZedH27R7KSsA/uao7mZ3dsrNLXbu1Wy5MzA== +"@napi-rs/simple-git-linux-arm-gnueabihf@0.1.16": + version "0.1.16" + resolved "https://registry.yarnpkg.com/@napi-rs/simple-git-linux-arm-gnueabihf/-/simple-git-linux-arm-gnueabihf-0.1.16.tgz#d5135543d372e0571d7c19928e75751eb407d7dd" + integrity sha512-R6VAyNnp/yRaT7DV1Ao3r67SqTWDa+fNq2LrNy0Z8gXk2wB9ZKlrxFtLPE1WSpWknWtyRDLpRlsorh7Evk7+7w== + +"@napi-rs/simple-git-linux-arm64-gnu@0.1.16": + version "0.1.16" + resolved "https://registry.yarnpkg.com/@napi-rs/simple-git-linux-arm64-gnu/-/simple-git-linux-arm64-gnu-0.1.16.tgz#4e293005b2fd62d1eb399b50e53d983378c19fb7" + integrity sha512-LAGI0opFKw/HBMCV2qIBK3uWSEW9h4xd2ireZKLJy8DBPymX6NrWIamuxYNyCuACnFdPRxR4LaRFy4J5ZwuMdw== + +"@napi-rs/simple-git-linux-arm64-musl@0.1.16": + version "0.1.16" + resolved "https://registry.yarnpkg.com/@napi-rs/simple-git-linux-arm64-musl/-/simple-git-linux-arm64-musl-0.1.16.tgz#679edd2c6d88de6aa35993401722ade04595869b" + integrity sha512-I57Ph0F0Yn2KW93ep+V1EzKhACqX0x49vvSiapqIsdDA2PifdEWLc1LJarBolmK7NKoPqKmf6lAKKO9lhiZzkg== + +"@napi-rs/simple-git-linux-x64-gnu@0.1.16": + version "0.1.16" + resolved "https://registry.yarnpkg.com/@napi-rs/simple-git-linux-x64-gnu/-/simple-git-linux-x64-gnu-0.1.16.tgz#b33054b14a88335f19261b812f65f8d567e7d199" + integrity sha512-AZYYFY2V7hlcQASPEOWyOa3e1skzTct9QPzz0LiDM3f/hCFY/wBaU2M6NC5iG3d2Kr38heuyFS/+JqxLm5WaKA== + +"@napi-rs/simple-git-linux-x64-musl@0.1.16": + version "0.1.16" + resolved "https://registry.yarnpkg.com/@napi-rs/simple-git-linux-x64-musl/-/simple-git-linux-x64-musl-0.1.16.tgz#8cfc8f5f35951dacae86e72b5535ea401f868b7a" + integrity sha512-9TyMcYSBJwjT8jwjY9m24BZbu7ozyWTjsmYBYNtK3B0Um1Ov6jthSNneLVvouQ6x+k3Ow+00TiFh6bvmT00r8g== + +"@napi-rs/simple-git-win32-arm64-msvc@0.1.16": + version "0.1.16" + resolved "https://registry.yarnpkg.com/@napi-rs/simple-git-win32-arm64-msvc/-/simple-git-win32-arm64-msvc-0.1.16.tgz#e6b220574421695f4c05be4e065b1fd46ffb7007" + integrity sha512-uslJ1WuAHCYJWui6xjsyT47SjX6KOHDtClmNO8hqKz1pmDSNY7AjyUY8HxvD1lK9bDnWwc4JYhikS9cxCqHybw== + +"@napi-rs/simple-git-win32-x64-msvc@0.1.16": + version "0.1.16" + resolved "https://registry.yarnpkg.com/@napi-rs/simple-git-win32-x64-msvc/-/simple-git-win32-x64-msvc-0.1.16.tgz#4ec44d57fc2c069544ffb923a2871d81d5db7cfc" + integrity sha512-SoEaVeCZCDF1MP+M9bMSXsZWgEjk4On9GWADO5JOulvzR1bKjk0s9PMHwe/YztR9F0sJzrCxwtvBZowhSJsQPg== + "@napi-rs/simple-git@^0.1.9": version "0.1.16" resolved "https://registry.npmjs.org/@napi-rs/simple-git/-/simple-git-0.1.16.tgz" @@ -1069,18 +1250,58 @@ resolved "https://registry.npmjs.org/@next/env/-/env-14.2.5.tgz" integrity sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA== -"@next/eslint-plugin-next@^14.2.5", "@next/eslint-plugin-next@14.2.5": +"@next/eslint-plugin-next@14.2.5", "@next/eslint-plugin-next@^14.2.5": version "14.2.5" resolved "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.5.tgz" integrity sha512-LY3btOpPh+OTIpviNojDpUdIbHW9j0JBYBjsIp8IxtDFfYFyORvw3yNq6N231FVqQA7n7lwaf7xHbVJlA1ED7g== dependencies: glob "10.3.10" +"@next/swc-darwin-arm64@14.2.5": + version "14.2.5" + resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz" + integrity sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ== + "@next/swc-darwin-x64@14.2.5": version "14.2.5" - resolved "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz#eb832a992407f6e6352eed05a073379f1ce0589c" integrity sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA== +"@next/swc-linux-arm64-gnu@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz#098fdab57a4664969bc905f5801ef5a89582c689" + integrity sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA== + +"@next/swc-linux-arm64-musl@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz#243a1cc1087fb75481726dd289c7b219fa01f2b5" + integrity sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA== + +"@next/swc-linux-x64-gnu@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz#b8a2e436387ee4a52aa9719b718992e0330c4953" + integrity sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ== + +"@next/swc-linux-x64-musl@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz#cb8a9adad5fb8df86112cfbd363aab5c6d32757b" + integrity sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ== + +"@next/swc-win32-arm64-msvc@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz#81f996c1c38ea0900d4e7719cc8814be8a835da0" + integrity sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw== + +"@next/swc-win32-ia32-msvc@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz#f61c74ce823e10b2bc150e648fc192a7056422e0" + integrity sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg== + +"@next/swc-win32-x64-msvc@14.2.5": + version "14.2.5" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz#ed199a920efb510cfe941cd75ed38a7be21e756f" + integrity sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -1089,7 +1310,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -1102,6 +1323,13 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@pipedream/sdk@^0.1.9": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@pipedream/sdk/-/sdk-0.1.9.tgz#1d857e10482623c86c3ef8a4bb1b28a9614e44a6" + integrity sha512-f8FXEaoBqIOQpI4vVOO8OrHRAjwQYO4pKIwMUcGRkzS5KJ6cZ/7JYYGyXEu7NcS+y1VfyegtbJWu4tWacDjQZg== + dependencies: + simple-oauth2 "^5.1.0" + "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" @@ -1117,67 +1345,11 @@ resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== -"@putout/babel@^2.0.0", "@putout/babel@^2.4.0": +"@putout/babel@^2.0.0": version "2.8.0" resolved "https://registry.npmjs.org/@putout/babel/-/babel-2.8.0.tgz" integrity sha512-Vq4DgAR6Zfc0VXyspQndmgT4T7sTgJBm8kwigN2zPxtyTtz8R199qjxSrypY1P2d+iAGatG2imksrzlPOlombg== -"@putout/cli-cache@^3.0.0": - version "3.1.0" - dependencies: - file-entry-cache "^9.0.0" - find-cache-dir "^5.0.0" - find-up "^7.0.0" - imurmurhash "^0.1.4" - json-stable-stringify-without-jsonify "^1.0.1" - try-to-catch "^3.0.0" - -"@putout/cli-choose-formatter@^4.0.0": - version "4.0.0" - dependencies: - "@putout/cli-choose" "^2.0.0" - find-up "^7.0.0" - -"@putout/cli-choose@^2.0.0": - version "2.0.0" - dependencies: - enquirer "^2.4.1" - try-to-catch "^3.0.1" - -"@putout/cli-filesystem@^2.0.1": - version "2.0.1" - -"@putout/cli-keypress@^2.0.0": - version "2.0.0" - dependencies: - ci-info "^4.0.0" - fullstore "^3.0.0" - -"@putout/cli-match@^2.0.0": - version "2.2.0" - dependencies: - try-catch "^3.0.0" - try-to-catch "^3.0.0" - -"@putout/cli-ruler@^3.0.0": - version "3.1.0" - dependencies: - try-to-catch "^3.0.0" - -"@putout/cli-staged@^1.0.0": - version "1.1.0" - dependencies: - "@putout/git-status-porcelain" "^3.0.0" - fullstore "^3.0.0" - once "^1.4.0" - try-to-catch "^3.0.1" - -"@putout/cli-validate-args@^1.0.0": - version "1.1.1" - dependencies: - fastest-levenshtein "^1.0.12" - just-kebab-case "^1.1.0" - "@putout/compare@^14.0.0": version "14.1.0" resolved "https://registry.npmjs.org/@putout/compare/-/compare-14.1.0.tgz" @@ -1190,17 +1362,7 @@ jessy "^3.0.0" nessy "^4.0.0" -"@putout/engine-loader@^13.0.0": - version "13.1.0" - dependencies: - "@putout/engine-parser" "^10.0.0" - diff-match-patch "^1.0.4" - nano-memoize "^3.0.11" - once "^1.4.0" - try-catch "^3.0.0" - try-to-catch "^3.0.1" - -"@putout/engine-parser@^10.0.0", "@putout/engine-parser@^10.0.2": +"@putout/engine-parser@^10.0.0": version "10.1.0" resolved "https://registry.npmjs.org/@putout/engine-parser/-/engine-parser-10.1.0.tgz" integrity sha512-5zyOJrbdFMwCJHd38nY4KV/Ttb5jVhDZZ+xedZROPLeJIRCY+KiZnt+qK4l0O6EugHnlhyKhe24VJOp48Xs9bA== @@ -1213,43 +1375,6 @@ once "^1.4.0" try-catch "^3.0.0" -"@putout/engine-processor@^11.0.0": - version "11.2.0" - dependencies: - "@putout/engine-loader" "^13.0.0" - once "^1.4.0" - picomatch "^4.0.1" - try-to-catch "^3.0.1" - -"@putout/engine-reporter@^1.0.0": - version "1.0.2" - dependencies: - "@putout/cli-choose-formatter" "^4.0.0" - "@putout/cli-keypress" "^2.0.0" - "@putout/engine-loader" "^13.0.0" - fullstore "^3.0.0" - try-catch "^3.0.1" - try-to-catch "^3.0.1" - -"@putout/engine-runner@^21.0.0": - version "21.0.3" - dependencies: - "@putout/babel" "^2.0.0" - "@putout/compare" "^14.0.0" - "@putout/engine-parser" "^10.0.0" - "@putout/operate" "^12.0.0" - "@putout/operator-declare" "^9.0.0" - "@putout/operator-filesystem" "^4.0.0" - "@putout/operator-json" "^2.0.0" - "@putout/plugin-filesystem" "^5.0.0" - debug "^4.1.1" - fullstore "^3.0.0" - jessy "^3.0.0" - nessy "^4.0.0" - once "^1.4.0" - try-catch "^3.0.0" - wraptile "^3.0.0" - "@putout/eslint-config@^9.0.0": version "9.1.0" resolved "https://registry.npmjs.org/@putout/eslint-config/-/eslint-config-9.1.0.tgz" @@ -1266,111 +1391,13 @@ find-up "^7.0.0" try-to-catch "^3.0.1" -"@putout/formatter-codeframe@^7.0.0": - version "7.0.0" - dependencies: - "@putout/babel" "^2.0.0" - "@putout/formatter-json" "^2.0.0" - chalk "^5.3.0" - table "^6.0.1" - -"@putout/formatter-dump@^5.0.0": - version "5.0.0" - dependencies: - "@putout/formatter-json" "^2.0.0" - chalk "^5.3.0" - table "^6.0.1" - -"@putout/formatter-frame@^6.0.0": - version "6.0.0" - dependencies: - "@putout/formatter-codeframe" "^7.0.0" - -"@putout/formatter-json-lines@^3.0.0": - version "3.0.0" - -"@putout/formatter-json@^2.0.0": - version "2.0.0" - -"@putout/formatter-memory@^4.0.0": - version "4.0.1" - dependencies: - "@putout/formatter-dump" "^5.0.0" - chalk "^5.3.0" - cli-progress "^3.8.2" - format-io "^2.0.0" - montag "^1.1.0" - once "^1.4.0" - -"@putout/formatter-progress-bar@^4.0.0": - version "4.0.1" - dependencies: - "@putout/formatter-dump" "^5.0.0" - chalk "^5.3.0" - cli-progress "^3.8.2" - once "^1.4.0" - -"@putout/formatter-progress@^5.0.0": - version "5.0.0" - dependencies: - "@putout/formatter-dump" "^5.0.0" - -"@putout/formatter-stream@^5.0.0": - version "5.0.0" - dependencies: - chalk "^5.3.0" - table "^6.0.1" - -"@putout/formatter-time@^3.0.0": - version "3.0.1" - dependencies: - "@putout/formatter-dump" "^5.0.0" - chalk "^5.3.0" - cli-progress "^3.8.2" - format-io "^2.0.0" - montag "^1.1.0" - once "^1.4.0" - timer-node "^5.0.7" - -"@putout/git-status-porcelain@^3.0.0": - version "3.0.0" - -"@putout/operate@^12.0.0", "@putout/operate@^12.5.0": +"@putout/operate@^12.0.0": version "12.9.2" resolved "https://registry.npmjs.org/@putout/operate/-/operate-12.9.2.tgz" integrity sha512-Z1KIlW9iFR5NBrzI60EqkJiC/k2fkqp6WK5+rrEokzvGox8DYJPAE5Dztc5IVMJRUjGB46fh7EXyA2vsY2Hj/Q== dependencies: "@putout/babel" "^2.0.0" -"@putout/operator-add-args@^8.0.0": - version "8.0.1" - dependencies: - "@putout/babel" "^2.0.0" - "@putout/compare" "^14.0.0" - "@putout/engine-parser" "^10.0.2" - -"@putout/operator-declare@^9.0.0": - version "9.1.0" - dependencies: - "@putout/babel" "^2.0.0" - "@putout/compare" "^14.0.0" - "@putout/engine-parser" "^10.0.2" - "@putout/operate" "^12.0.0" - -"@putout/operator-filesystem@^4.0.0": - version "4.1.0" - dependencies: - "@putout/babel" "^2.0.0" - "@putout/operate" "^12.0.0" - fullstore "^3.0.0" - try-catch "^3.0.1" - -"@putout/operator-ignore@^1.0.0": - version "1.2.0" - dependencies: - "@putout/babel" "^2.4.0" - "@putout/operate" "^12.5.0" - "@putout/operator-json@^2.0.0": version "2.1.0" resolved "https://registry.npmjs.org/@putout/operator-json/-/operator-json-2.1.0.tgz" @@ -1378,409 +1405,19 @@ dependencies: remove-blank-lines "^1.4.1" -"@putout/operator-match-files@^3.0.0": - version "3.5.0" - dependencies: - "@putout/babel" "^2.0.0" - "@putout/engine-parser" "^10.0.2" - "@putout/operator-filesystem" "^4.0.0" - "@putout/operator-json" "^2.0.0" - -"@putout/operator-regexp@^1.0.0": - version "1.0.0" - dependencies: - regexp-tree "^0.1.24" - -"@putout/operator-rename-files@^1.0.0": - version "1.0.0" - dependencies: - "@putout/operator-filesystem" "^4.0.0" - -"@putout/plugin-apply-at@^2.0.0": - version "2.0.0" - -"@putout/plugin-apply-destructuring@^7.0.0": - version "7.1.0" - -"@putout/plugin-apply-dot-notation@^2.0.0": - version "2.0.0" - -"@putout/plugin-apply-early-return@^3.0.0": - version "3.0.0" - -"@putout/plugin-apply-flat-map@^2.0.0": - version "2.0.0" - -"@putout/plugin-apply-optional-chaining@^5.0.0": - version "5.0.1" - -"@putout/plugin-apply-overrides@^1.0.0": - version "1.3.0" - -"@putout/plugin-apply-starts-with@^1.0.0": - version "1.1.0" - -"@putout/plugin-apply-template-literals@^3.0.0": - version "3.0.0" - -"@putout/plugin-browserlist@^2.0.0": - version "2.0.0" - -"@putout/plugin-conditions@^4.0.0": - version "4.4.0" - -"@putout/plugin-convert-apply-to-spread@^4.0.0": - version "4.0.0" - -"@putout/plugin-convert-arguments-to-rest@^2.0.0": - version "2.0.0" - -"@putout/plugin-convert-array-copy-to-slice@^3.0.0": - version "3.0.0" - -"@putout/plugin-convert-assignment-to-arrow-function@^1.0.0": - version "1.2.0" - -"@putout/plugin-convert-assignment-to-comparison@^2.0.0": - version "2.0.0" - -"@putout/plugin-convert-concat-to-flat@^1.0.0": - version "1.0.0" - -"@putout/plugin-convert-const-to-let@^1.0.0": - version "1.2.0" - -"@putout/plugin-convert-index-of-to-includes@^2.0.0": - version "2.0.1" - -"@putout/plugin-convert-label-to-object@^1.0.0": - version "1.0.2" - -"@putout/plugin-convert-object-assign-to-merge-spread@^6.0.0": - version "6.0.0" - -"@putout/plugin-convert-object-entries-to-array-entries@^3.0.0": - version "3.0.1" - -"@putout/plugin-convert-optional-to-logical@^3.0.0": - version "3.1.0" - -"@putout/plugin-convert-quotes-to-backticks@^3.0.0": - version "3.0.0" - -"@putout/plugin-convert-template-to-string@^2.0.0": - version "2.0.0" - -"@putout/plugin-convert-to-arrow-function@^4.0.0": - version "4.0.0" - -"@putout/plugin-coverage@^1.0.0": - version "1.0.0" - -"@putout/plugin-declare-before-reference@^4.0.0": - version "4.0.0" - -"@putout/plugin-declare-imports-first@^2.0.0": - version "2.1.0" - -"@putout/plugin-declare@^4.0.0": - version "4.0.0" - -"@putout/plugin-eslint@^8.0.0": - version "8.12.1" - -"@putout/plugin-extract-object-properties@^9.0.0": - version "9.0.0" - -"@putout/plugin-extract-sequence-expressions@^3.0.0": - version "3.5.0" - -"@putout/plugin-filesystem@^5.0.0": - version "5.3.0" - dependencies: - "@putout/babel" "^2.0.0" - "@putout/operate" "^12.0.0" - "@putout/operator-filesystem" "^4.0.0" - "@putout/operator-json" "^2.0.0" - -"@putout/plugin-for-of@^6.0.0": - version "6.1.0" - -"@putout/plugin-generators@^1.0.0": - version "1.0.0" - dependencies: - fullstore "^3.0.0" - -"@putout/plugin-github@^12.0.0": - version "12.3.0" - -"@putout/plugin-gitignore@^6.0.0": - version "6.0.0" - -"@putout/plugin-logical-expressions@^6.0.0": - version "6.0.0" - -"@putout/plugin-madrun@^18.0.0": - version "18.0.0" - -"@putout/plugin-math@^2.0.0": - version "2.1.0" - -"@putout/plugin-maybe@^2.0.0": - version "2.0.1" - -"@putout/plugin-merge-destructuring-properties@^8.0.0": - version "8.0.0" - -"@putout/plugin-merge-duplicate-functions@^2.0.0": - version "2.0.0" - -"@putout/plugin-merge-duplicate-imports@^11.0.0": - version "11.0.0" - -"@putout/plugin-montag@^2.0.0": - version "2.0.0" - -"@putout/plugin-new@^3.0.1": - version "3.0.1" - -"@putout/plugin-nodejs@^11.0.0": - version "11.11.0" - dependencies: - just-camel-case "^6.2.0" - -"@putout/plugin-npmignore@^5.0.0": - version "5.0.0" - -"@putout/plugin-package-json@^7.0.0": - version "7.2.0" - -"@putout/plugin-promises@^15.0.0": - version "15.0.0" - dependencies: - fullstore "^3.0.0" - -"@putout/plugin-putout-config@^5.0.0": - version "5.0.0" - -"@putout/plugin-putout@^20.0.0": - version "20.3.0" - dependencies: - fullstore "^3.0.0" - just-camel-case "^6.0.1" - parse-import-specifiers "^1.0.2" - try-catch "^3.0.0" - -"@putout/plugin-regexp@^8.0.0": - version "8.0.0" - dependencies: - regexp-tree "^0.1.21" - try-catch "^3.0.0" - -"@putout/plugin-remove-console@^6.0.0": - version "6.0.0" - -"@putout/plugin-remove-constant-conditions@^4.0.0": - version "4.0.2" - -"@putout/plugin-remove-debugger@^7.0.0": - version "7.0.0" - -"@putout/plugin-remove-duplicate-case@^3.0.0": - version "3.0.0" - -"@putout/plugin-remove-duplicate-keys@^5.0.0": - version "5.1.0" - dependencies: - fullstore "^3.0.0" - -"@putout/plugin-remove-empty@^12.0.0": - version "12.1.0" - -"@putout/plugin-remove-iife@^4.0.0": - version "4.1.0" - -"@putout/plugin-remove-nested-blocks@^6.0.0": - version "6.3.0" - -"@putout/plugin-remove-unreachable-code@^1.0.0": - version "1.2.0" - -"@putout/plugin-remove-unreferenced-variables@^3.0.0": - version "3.1.0" - -"@putout/plugin-remove-unused-expressions@^8.0.0": - version "8.0.0" - -"@putout/plugin-remove-unused-for-of-variables@^3.0.0": - version "3.0.1" - -"@putout/plugin-remove-unused-private-fields@^2.0.0": - version "2.1.0" - -"@putout/plugin-remove-unused-variables@^9.0.0": - version "9.0.0" - -"@putout/plugin-remove-useless-arguments@^8.0.0": - version "8.0.0" - -"@putout/plugin-remove-useless-array-constructor@^2.0.0": - version "2.0.0" - -"@putout/plugin-remove-useless-array-entries@^1.0.0": - version "1.0.0" - -"@putout/plugin-remove-useless-array@^1.0.0": - version "1.1.0" - -"@putout/plugin-remove-useless-assign@^1.0.0": - version "1.1.0" - -"@putout/plugin-remove-useless-constructor@^1.0.0": - version "1.0.0" - -"@putout/plugin-remove-useless-continue@^2.0.0": - version "2.0.0" - -"@putout/plugin-remove-useless-escape@^6.0.0": - version "6.0.0" - dependencies: - emoji-regex "^10.0.1" - -"@putout/plugin-remove-useless-functions@^3.0.0": - version "3.0.0" - -"@putout/plugin-remove-useless-map@^1.0.0": - version "1.1.0" - -"@putout/plugin-remove-useless-operand@^2.0.0": - version "2.1.0" - -"@putout/plugin-remove-useless-replace@^1.0.1": - version "1.0.4" - -"@putout/plugin-remove-useless-return@^6.0.0": - version "6.0.0" - -"@putout/plugin-remove-useless-spread@^11.0.0": - version "11.0.0" - -"@putout/plugin-remove-useless-template-expressions@^2.0.0": - version "2.0.0" - -"@putout/plugin-remove-useless-variables@^11.0.0": - version "11.1.1" - -"@putout/plugin-reuse-duplicate-init@^5.0.0": - version "5.0.0" - -"@putout/plugin-simplify-assignment@^3.0.0": - version "3.1.0" - -"@putout/plugin-simplify-boolean-return@^1.0.0": - version "1.1.0" - -"@putout/plugin-simplify-ternary@^7.0.0": - version "7.0.0" - -"@putout/plugin-sort-imports-by-specifiers@^1.0.0": - version "1.1.0" - dependencies: - parse-import-specifiers "^1.0.3" - -"@putout/plugin-split-assignment-expressions@^1.0.0": - version "1.0.0" - -"@putout/plugin-split-nested-destructuring@^3.0.0": - version "3.0.0" - -"@putout/plugin-split-variable-declarations@^3.0.0": - version "3.0.0" - -"@putout/plugin-tape@^14.0.0": - version "14.2.0" - -"@putout/plugin-try-catch@^3.0.0": - version "3.0.0" - -"@putout/plugin-types@^4.0.0": - version "4.1.0" - -"@putout/plugin-typescript@^7.0.0": - version "7.4.0" - -"@putout/plugin-webpack@^3.0.0": - version "3.0.0" - -"@putout/printer@^8.0.0", "@putout/printer@^8.0.1": +"@putout/printer@^8.0.0": version "8.5.0" resolved "https://registry.npmjs.org/@putout/printer/-/printer-8.5.0.tgz" integrity sha512-YHJgvZLIA4YI3ypeyg1vxvs+HzKI1sXQ2fzGoQe2XT0dYuwLFlMG72rJQRo2Yi1u3ws/cMsq3Pcqeju7hDXhsA== dependencies: "@putout/babel" "^2.0.0" - "@putout/compare" "^14.0.0" - "@putout/operate" "^12.0.0" - "@putout/operator-json" "^2.0.0" - fullstore "^3.0.0" - just-snake-case "^3.2.0" - parse-import-specifiers "^1.0.1" - rendy "^4.0.0" - -"@putout/processor-css@^9.0.0": - version "9.0.0" - dependencies: - align-spaces "^1.0.4" - cosmiconfig "^9.0.0" - deepmerge "^4.2.2" - prettier "^3.1.0" - stylelint "^16.0.1" - stylelint-config-standard "^36.0.0" - stylelint-prettier "^5.0.0" - -"@putout/processor-filesystem@^4.0.0": - version "4.0.0" - dependencies: - "@putout/cli-filesystem" "^2.0.1" - "@putout/operator-filesystem" "^4.0.0" - "@putout/operator-json" "^2.0.0" - -"@putout/processor-ignore@^6.0.0": - version "6.0.1" - dependencies: - "@putout/operator-json" "^2.0.0" - -"@putout/processor-javascript@^5.0.0": - version "5.0.0" - -"@putout/processor-json@^9.0.0": - version "9.0.0" - dependencies: - "@putout/operator-json" "^2.0.0" - -"@putout/processor-markdown@^12.0.0": - version "12.1.0" - dependencies: - "@putout/operator-json" "^2.0.0" - once "^1.4.0" - remark-parse "^11.0.0" - remark-preset-lint-consistent "^6.0.0" - remark-stringify "^11.0.0" - unified "^11.0.3" - unified-lint-rule "^3.0.0" - unist-util-visit "^5.0.0" - -"@putout/processor-yaml@^8.0.0": - version "8.1.0" - dependencies: - "@putout/operator-json" "^2.0.0" - just-kebab-case "^4.0.2" - try-catch "^3.0.0" - yaml "^2.2.2" - -"@putout/quick-lint@^1.2.0": - version "1.2.0" - dependencies: - once "^1.4.0" + "@putout/compare" "^14.0.0" + "@putout/operate" "^12.0.0" + "@putout/operator-json" "^2.0.0" + fullstore "^3.0.0" + just-snake-case "^3.2.0" + parse-import-specifiers "^1.0.1" + rendy "^4.0.0" "@putout/recast@^1.12.1": version "1.13.0" @@ -1793,17 +1430,28 @@ source-map "~0.6.1" tslib "^2.0.1" -"@putout/traverse@^10.0.0": - version "10.0.1" - dependencies: - "@putout/babel" "^2.0.0" - "@putout/compare" "^14.0.0" - "@rushstack/eslint-patch@^1.3.3": version "1.7.2" resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.7.2.tgz" integrity sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA== +"@sideway/address@^4.1.5": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5" + integrity sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@sideway/formula@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" + integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== + +"@sideway/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== + "@sinclair/typebox@^0.27.8": version "0.27.8" resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz" @@ -1823,7 +1471,7 @@ dependencies: "@sinonjs/commons" "^3.0.0" -"@stylistic/eslint-plugin-js@^2.1.0", "@stylistic/eslint-plugin-js@^2.6.1", "@stylistic/eslint-plugin-js@2.6.1": +"@stylistic/eslint-plugin-js@2.6.1", "@stylistic/eslint-plugin-js@^2.1.0", "@stylistic/eslint-plugin-js@^2.6.1": version "2.6.1" resolved "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.6.1.tgz" integrity sha512-iLOiVzcvqzDGD9U0EuVOX680v+XOPiPAjkxWj+Q6iV2GLOM5NB27tKVOpJY7AzBhidwpRbaLTgg3T4UzYx09jw== @@ -2078,7 +1726,7 @@ resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz" integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== -"@types/react@>= 16.8.0 < 19.0.0", "@types/react@>=16", "@types/react@>=18": +"@types/react@>=16": version "18.2.55" resolved "https://registry.npmjs.org/@types/react/-/react-18.2.55.tgz" integrity sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA== @@ -2124,7 +1772,7 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^5.0.0 || ^6.0.0 || ^7.0.0", "@typescript-eslint/eslint-plugin@^7.0.1", "@typescript-eslint/eslint-plugin@^7.18.0", "@typescript-eslint/eslint-plugin@7.18.0": +"@typescript-eslint/eslint-plugin@7.18.0", "@typescript-eslint/eslint-plugin@^7.0.1", "@typescript-eslint/eslint-plugin@^7.18.0": version "7.18.0" resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz" integrity sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw== @@ -2139,6 +1787,17 @@ natural-compare "^1.4.0" ts-api-utils "^1.3.0" +"@typescript-eslint/parser@7.18.0", "@typescript-eslint/parser@^7.0.1", "@typescript-eslint/parser@^7.18.0": + version "7.18.0" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz" + integrity sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg== + dependencies: + "@typescript-eslint/scope-manager" "7.18.0" + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/typescript-estree" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" + debug "^4.3.4" + "@typescript-eslint/parser@^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0": version "6.21.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz" @@ -2150,17 +1809,6 @@ "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" -"@typescript-eslint/parser@^7.0.0", "@typescript-eslint/parser@^7.0.1", "@typescript-eslint/parser@^7.18.0", "@typescript-eslint/parser@7.18.0": - version "7.18.0" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz" - integrity sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg== - dependencies: - "@typescript-eslint/scope-manager" "7.18.0" - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/typescript-estree" "7.18.0" - "@typescript-eslint/visitor-keys" "7.18.0" - debug "^4.3.4" - "@typescript-eslint/scope-manager@5.62.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz" @@ -2278,6 +1926,16 @@ semver "^7.6.0" ts-api-utils "^1.3.0" +"@typescript-eslint/utils@7.18.0": + version "7.18.0" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz" + integrity sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "7.18.0" + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/typescript-estree" "7.18.0" + "@typescript-eslint/utils@^5.10.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz" @@ -2302,16 +1960,6 @@ "@typescript-eslint/types" "8.0.0" "@typescript-eslint/typescript-estree" "8.0.0" -"@typescript-eslint/utils@7.18.0": - version "7.18.0" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz" - integrity sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "7.18.0" - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/typescript-estree" "7.18.0" - "@typescript-eslint/visitor-keys@5.62.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz" @@ -2361,10 +2009,7 @@ acorn-jsx@^5.0.0, acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn-typescript@^1.4.13: - version "1.4.13" - -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.0.0, acorn@^8.11.3, acorn@^8.12.0, acorn@^8.12.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.9.0, acorn@>=8.9.0: +acorn@^8.0.0, acorn@^8.11.3, acorn@^8.12.0, acorn@^8.12.1, acorn@^8.5.0, acorn@^8.9.0: version "8.12.1" resolved "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== @@ -2379,23 +2024,7 @@ ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.1: - version "8.14.0" - dependencies: - fast-deep-equal "^3.1.3" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.4.1" - -ajv@^8.8.2: - version "8.14.0" - dependencies: - fast-deep-equal "^3.1.3" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.4.1" - -algoliasearch@^4.19.1, "algoliasearch@>= 4.9.1 < 6": +algoliasearch@^4.19.1: version "4.22.1" resolved "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.22.1.tgz" integrity sha512-jwydKFQJKIx9kIZ8Jm44SdpigFwRGPESaxZBaHSV0XWN2yBJAOT4mT7ppvlrpA4UGzz92pqFnVKr/kaZXrcreg== @@ -2415,14 +2044,11 @@ algoliasearch@^4.19.1, "algoliasearch@>= 4.9.1 < 6": "@algolia/requester-node-http" "4.22.1" "@algolia/transporter" "4.22.1" -align-spaces@^1.0.0, align-spaces@^1.0.4: +align-spaces@^1.0.0: version "1.0.4" resolved "https://registry.npmjs.org/align-spaces/-/align-spaces-1.0.4.tgz" integrity sha512-JPl93xFbsX4OY7VFKjerJ9cjaelmKo1wt1EP0ScrKI578vro1WhGy+w9C0nAFup8qYADgAS2FvMb7uLPStTB6g== -ansi-colors@^4.1.1: - version "4.1.3" - ansi-escapes@^4.2.1: version "4.3.2" resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" @@ -2452,28 +2078,14 @@ ansi-sequence-parser@^1.1.0: resolved "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz" integrity sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg== -ansi-styles@^3.1.0: - version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^3.2.1: +ansi-styles@^3.1.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" -ansi-styles@^4.0.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^4.1.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -2508,16 +2120,16 @@ arch@^2.1.0: resolved "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz" integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== -arg@^5.0.2: - version "5.0.2" - resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" - integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== - arg@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/arg/-/arg-1.0.0.tgz" integrity sha512-Wk7TEzl1KqvTGs/uyhmHO/3XLd3t1UeU4IstvPXVzGPM522cTjqjNZ99esCkcL52sjqjo8e8CTBcWhkxvGzoAw== +arg@^5.0.2: + version "5.0.2" + resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" @@ -2651,9 +2263,6 @@ ast-types@^0.16.1: dependencies: tslib "^2.0.1" -astral-regex@^2.0.0: - version "2.0.0" - astring@^1.8.0: version "1.8.6" resolved "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz" @@ -2765,9 +2374,6 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -balanced-match@^2.0.0: - version "2.0.0" - binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" @@ -2795,7 +2401,7 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.22.2, browserslist@^4.23.0, "browserslist@>= 4.21.0": +browserslist@^4.22.2, browserslist@^4.23.0: version "4.23.0" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz" integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== @@ -2865,6 +2471,15 @@ ccount@^2.0.0: resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz" integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== +chalk@2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz" + integrity sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q== + dependencies: + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" + chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" @@ -2882,25 +2497,11 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^5.3.0: - version "5.3.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz" - integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== - -chalk@~5.3.0: +chalk@^5.3.0, chalk@~5.3.0: version "5.3.0" resolved "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz" integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== -chalk@2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz" - integrity sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q== - dependencies: - ansi-styles "^3.1.0" - escape-string-regexp "^1.0.5" - supports-color "^4.0.0" - char-regex@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" @@ -2946,9 +2547,6 @@ ci-info@^3.2.0: resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== -ci-info@^4.0.0: - version "4.0.0" - cjs-module-lexer@^1.0.0: version "1.2.3" resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz" @@ -2961,11 +2559,6 @@ cli-cursor@^5.0.0: dependencies: restore-cursor "^5.0.0" -cli-progress@^3.8.2: - version "3.12.0" - dependencies: - string-width "^4.2.3" - cli-truncate@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz" @@ -2974,7 +2567,7 @@ cli-truncate@^4.0.0: slice-ansi "^5.0.0" string-width "^7.0.0" -client-only@^0.0.1, client-only@0.0.1: +client-only@0.0.1, client-only@^0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== @@ -3025,16 +2618,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + color-string@^1.9.0: version "1.9.1" resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" @@ -3051,9 +2644,6 @@ color@^4.2.3: color-convert "^2.0.1" color-string "^1.9.0" -colord@^2.9.3: - version "2.9.3" - colorette@^2.0.20: version "2.0.20" resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz" @@ -3064,6 +2654,11 @@ comma-separated-tokens@^2.0.0: resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz" integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== +commander@7: + version "7.2.0" + resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + commander@^4.0.0: version "4.1.1" resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" @@ -3079,14 +2674,6 @@ commander@~12.1.0: resolved "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz" integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== -commander@7: - version "7.2.0" - resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -common-path-prefix@^3.0.0: - version "3.0.0" - compute-scroll-into-view@^3.0.2: version "3.1.0" resolved "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz" @@ -3109,14 +2696,6 @@ cose-base@^1.0.0: dependencies: layout-base "^1.0.0" -cosmiconfig@^9.0.0: - version "9.0.0" - dependencies: - env-paths "^2.2.1" - import-fresh "^3.3.0" - js-yaml "^4.1.0" - parse-json "^5.2.0" - create-jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz" @@ -3148,15 +2727,6 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -css-functions-list@^3.2.2: - version "3.2.2" - -css-tree@^2.3.1: - version "2.3.1" - dependencies: - mdn-data "2.0.30" - source-map-js "^1.0.1" - cssesc@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" @@ -3167,9 +2737,6 @@ csstype@^3.0.2: resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== -currify@^4.0.0: - version "4.0.0" - cytoscape-cose-bilkent@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz" @@ -3177,7 +2744,7 @@ cytoscape-cose-bilkent@^4.1.0: dependencies: cose-base "^1.0.0" -cytoscape@^3.2.0, cytoscape@^3.28.1: +cytoscape@^3.28.1: version "3.28.1" resolved "https://registry.npmjs.org/cytoscape/-/cytoscape-3.28.1.tgz" integrity sha512-xyItz4O/4zp9/239wCcH8ZcFuuZooEeF8KHRmzjDfGdXsj3OG9MFSMA0pJE0uX3uCN/ygof6hHf4L7lst+JaDg== @@ -3185,13 +2752,6 @@ cytoscape@^3.2.0, cytoscape@^3.28.1: heap "^0.2.6" lodash "^4.17.21" -d3-array@^3.2.0, "d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3: - version "3.2.4" - resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" - integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== - dependencies: - internmap "1 - 2" - "d3-array@1 - 2": version "2.12.1" resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" @@ -3199,6 +2759,13 @@ d3-array@^3.2.0, "d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", dependencies: internmap "^1.0.0" +"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0: + version "3.2.4" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" + integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== + dependencies: + internmap "1 - 2" + d3-axis@3: version "3.0.0" resolved "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz" @@ -3308,16 +2875,16 @@ d3-hierarchy@3: dependencies: d3-color "1 - 3" -d3-path@^3.1.0, "d3-path@1 - 3", d3-path@3: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" - integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== - d3-path@1: version "1.0.9" resolved "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz" integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== +"d3-path@1 - 3", d3-path@3, d3-path@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" + integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== + d3-polygon@3: version "3.0.1" resolved "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz" @@ -3365,13 +2932,6 @@ d3-scale@4: resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== -d3-shape@^1.2.0: - version "1.3.7" - resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz" - integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== - dependencies: - d3-path "1" - d3-shape@3: version "3.2.0" resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz" @@ -3379,6 +2939,13 @@ d3-shape@3: dependencies: d3-path "^3.1.0" +d3-shape@^1.2.0: + version "1.3.7" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz" + integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== + dependencies: + d3-path "1" + "d3-time-format@2 - 4", d3-time-format@4: version "4.1.0" resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz" @@ -3505,7 +3072,7 @@ deep-is@^0.1.3: resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -deepmerge@^4.0.0, deepmerge@^4.2.2: +deepmerge@^4.2.2: version "4.3.1" resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== @@ -3562,9 +3129,6 @@ didyoumean@^1.2.2: resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz" integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== -diff-match-patch@^1.0.4: - version "1.0.5" - diff-sequences@^29.6.3: version "29.6.3" resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz" @@ -3626,9 +3190,6 @@ emittery@^0.13.1: resolved "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz" integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== -emoji-regex@^10.0.1: - version "10.3.0" - emoji-regex@^10.3.0: version "10.3.0" resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz" @@ -3652,20 +3213,11 @@ enhanced-resolve@^5.12.0, enhanced-resolve@^5.17.0: graceful-fs "^4.2.4" tapable "^2.2.0" -enquirer@^2.4.1: - version "2.4.1" - dependencies: - ansi-colors "^4.1.1" - strip-ansi "^6.0.1" - entities@^4.4.0: version "4.5.0" resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== -env-paths@^2.2.1: - version "2.2.1" - environment@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz" @@ -3873,7 +3425,7 @@ eslint-plugin-es-x@^7.5.0: "@eslint-community/regexpp" "^4.11.0" eslint-compat-utils "^0.5.1" -eslint-plugin-import@*, eslint-plugin-import@^2.28.1: +eslint-plugin-import@^2.28.1: version "2.29.1" resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz" integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== @@ -4034,7 +3586,7 @@ eslint-visitor-keys@^4.0.0: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz" integrity sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw== -eslint@*, "eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", "eslint@^7.23.0 || ^8.0.0", eslint@^8.56.0, eslint@^8.57.0, "eslint@^8.57.0 || ^9.0.0", eslint@^8.9.0, eslint@>=6.0.0, eslint@>=8, eslint@>=8.0.0, eslint@>=8.23.0, eslint@>=8.40.0: +eslint@^8.57.0: version "8.57.0" resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz" integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== @@ -4148,11 +3700,6 @@ estree-util-attach-comments@^2.0.0: dependencies: "@types/estree" "^1.0.0" -estree-util-attach-comments@^3.0.0: - version "3.0.0" - dependencies: - "@types/estree" "^1.0.0" - estree-util-build-jsx@^2.0.0: version "2.2.2" resolved "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-2.2.2.tgz" @@ -4289,10 +3836,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-diff@^1.1.2: - version "1.3.0" - -fast-glob@^3.2.2, fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1, fast-glob@^3.3.2: +fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1: version "3.3.2" resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -4313,9 +3857,6 @@ fast-levenshtein@^2.0.6: resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== -fastest-levenshtein@^1.0.12, fastest-levenshtein@^1.0.16: - version "1.0.16" - fastq@^1.6.0: version "1.17.1" resolved "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz" @@ -4337,11 +3878,6 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-entry-cache@^9.0.0: - version "9.0.0" - dependencies: - flat-cache "^5.0.0" - fill-range@^7.1.1: version "7.1.1" resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" @@ -4349,12 +3885,6 @@ fill-range@^7.1.1: dependencies: to-regex-range "^5.0.1" -find-cache-dir@^5.0.0: - version "5.0.0" - dependencies: - common-path-prefix "^3.0.0" - pkg-dir "^7.0.0" - find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" @@ -4371,12 +3901,6 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -find-up@^6.3.0: - version "6.3.0" - dependencies: - locate-path "^7.1.0" - path-exists "^5.0.0" - find-up@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz" @@ -4395,13 +3919,7 @@ flat-cache@^3.0.4: keyv "^4.5.3" rimraf "^3.0.2" -flat-cache@^5.0.0: - version "5.0.0" - dependencies: - flatted "^3.3.1" - keyv "^4.5.4" - -flatted@^3.2.9, flatted@^3.3.1: +flatted@^3.2.9: version "3.3.1" resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== @@ -4431,11 +3949,6 @@ foreground-child@^3.1.0: cross-spawn "^7.0.0" signal-exit "^4.0.1" -format-io@^2.0.0: - version "2.0.0" - dependencies: - currify "^4.0.0" - fraction.js@^4.3.7: version "4.3.7" resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz" @@ -4572,7 +4085,7 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob@^10.3.10: +glob@10.3.10, glob@^10.3.10: version "10.3.10" resolved "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz" integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== @@ -4595,29 +4108,6 @@ glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@10.3.10: - version "10.3.10" - resolved "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.3.5" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" - -global-modules@^2.0.0: - version "2.0.0" - dependencies: - global-prefix "^3.0.0" - -global-prefix@^3.0.0: - version "3.0.0" - dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" - globals@^11.1.0: version "11.12.0" resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" @@ -4654,23 +4144,6 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -globjoin@^0.1.4: - version "0.1.4" - -goldstein@^5.11.0: - version "5.11.0" - dependencies: - "@putout/plugin-declare" "^4.0.0" - "@putout/plugin-logical-expressions" "^6.0.0" - "@putout/plugin-try-catch" "^3.0.0" - "@putout/printer" "^8.0.1" - acorn "^8.7.1" - acorn-typescript "^1.4.13" - estree-to-babel "^9.0.0" - estree-util-attach-comments "^3.0.0" - putout "^35.0.0" - try-catch "^3.0.1" - gopd@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" @@ -4934,9 +4407,6 @@ html-escaper@^2.0.0: resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -html-tags@^3.3.1: - version "3.3.1" - html-url-attributes@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.0.tgz" @@ -4964,12 +4434,12 @@ iconv-lite@0.6: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ignore@^5.0.4, ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.1: +ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.1: version "5.3.1" resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz" integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== -import-fresh@^3.2.1, import-fresh@^3.3.0: +import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -4998,14 +4468,11 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@^2.0.3, inherits@2: +inherits@2, inherits@^2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@^1.3.5: - version "1.3.8" - inline-style-parser@0.1.1: version "0.1.1" resolved "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz" @@ -5025,16 +4492,16 @@ internal-slot@^1.0.5, internal-slot@^1.0.7: hasown "^2.0.0" side-channel "^1.0.4" -internmap@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" - integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== - "internmap@1 - 2": version "2.0.3" resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz" integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== +internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== + intersection-observer@^0.12.2: version "0.12.2" resolved "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.12.2.tgz" @@ -5245,9 +4712,6 @@ is-plain-obj@^4.0.0: resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz" integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== -is-plain-object@^5.0.0: - version "5.0.0" - is-reference@^3.0.0: version "3.0.2" resolved "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz" @@ -5263,11 +4727,6 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-relative@^1.0.0: - version "1.0.0" - dependencies: - is-unc-path "^1.0.0" - is-set@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" @@ -5323,11 +4782,6 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.13, is-typed-array@^1.1.3, is-typed- dependencies: which-typed-array "^1.1.14" -is-unc-path@^1.0.0: - version "1.0.0" - dependencies: - unc-path-regex "^0.1.2" - is-weakmap@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" @@ -5640,7 +5094,7 @@ jest-resolve-dependencies@^29.7.0: jest-regex-util "^29.6.3" jest-snapshot "^29.7.0" -jest-resolve@*, jest-resolve@^29.7.0: +jest-resolve@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz" integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== @@ -5784,7 +5238,7 @@ jest-worker@^29.7.0: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@*, jest@^29.7.0: +jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz" integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== @@ -5799,6 +5253,17 @@ jiti@^1.21.0: resolved "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz" integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== +joi@^17.6.4: + version "17.13.3" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.13.3.tgz#0f5cc1169c999b30d344366d384b12d92558bcec" + integrity sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA== + dependencies: + "@hapi/hoek" "^9.3.0" + "@hapi/topo" "^5.1.0" + "@sideway/address" "^4.1.5" + "@sideway/formula" "^3.0.1" + "@sideway/pinpoint" "^2.0.0" + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" @@ -5809,9 +5274,6 @@ js-tokens@^8.0.0: resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz" integrity sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw== -js-tokens@^9.0.0: - version "9.0.0" - js-yaml@^3.13.1: version "3.14.1" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" @@ -5852,9 +5314,6 @@ json-schema-traverse@^0.4.1: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" @@ -5897,15 +5356,6 @@ jsonc-parser@^3.2.0: object.assign "^4.1.4" object.values "^1.1.6" -just-camel-case@^6.0.1, just-camel-case@^6.2.0: - version "6.2.0" - -just-kebab-case@^1.1.0: - version "1.1.0" - -just-kebab-case@^4.0.2: - version "4.2.0" - just-snake-case@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/just-snake-case/-/just-snake-case-3.2.0.tgz" @@ -5918,7 +5368,7 @@ katex@^0.16.0, katex@^0.16.9: dependencies: commander "^8.3.0" -keyv@^4.5.3, keyv@^4.5.4: +keyv@^4.5.3: version "4.5.4" resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz" integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== @@ -5945,9 +5395,6 @@ kleur@^4.0.3: resolved "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz" integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== -known-css-properties@^0.31.0: - version "0.31.0" - language-subtag-registry@^0.3.20: version "0.3.22" resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz" @@ -6035,11 +5482,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -locate-path@^7.1.0: - version "7.2.0" - dependencies: - p-locate "^6.0.0" - locate-path@^7.2.0: version "7.2.0" resolved "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz" @@ -6062,9 +5504,6 @@ lodash.merge@^4.6.2: resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.truncate@^4.4.2: - version "4.4.2" - lodash@^4.17.21: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" @@ -6157,15 +5596,6 @@ match-sorter@^6.3.1: "@babel/runtime" "^7.23.8" remove-accents "0.5.0" -mathml-tag-names@^2.1.3: - version "2.1.3" - -mdast-comment-marker@^3.0.0: - version "3.0.0" - dependencies: - "@types/mdast" "^4.0.0" - mdast-util-mdx-expression "^2.0.0" - mdast-util-definitions@^5.0.0: version "5.1.2" resolved "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz" @@ -6279,11 +5709,6 @@ mdast-util-gfm@^2.0.0: mdast-util-gfm-task-list-item "^1.0.0" mdast-util-to-markdown "^1.0.0" -mdast-util-heading-style@^3.0.0: - version "3.0.0" - dependencies: - "@types/mdast" "^4.0.0" - mdast-util-math@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-2.0.2.tgz" @@ -6474,12 +5899,6 @@ mdast-util-to-string@^4.0.0: dependencies: "@types/mdast" "^4.0.0" -mdn-data@2.0.30: - version "2.0.30" - -meow@^13.2.0: - version "13.2.0" - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" @@ -7089,7 +6508,7 @@ micromark@^4.0.0: micromark-util-symbol "^2.0.0" micromark-util-types "^2.0.0" -micromatch@^4.0.4, micromatch@^4.0.5, micromatch@^4.0.7, micromatch@~4.0.7: +micromatch@^4.0.4, micromatch@^4.0.5, micromatch@~4.0.7: version "4.0.7" resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz" integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q== @@ -7112,41 +6531,27 @@ mimic-function@^5.0.0: resolved "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz" integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA== -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^9.0.1: +minimatch@9.0.3, minimatch@^9.0.1: version "9.0.3" resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.4: - version "9.0.5" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz" - integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: - brace-expansion "^2.0.1" + brace-expansion "^1.1.7" -minimatch@^9.0.5: +minimatch@^9.0.4, minimatch@^9.0.5: version "9.0.5" resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz" integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== dependencies: brace-expansion "^2.0.1" -minimatch@9.0.3: - version "9.0.3" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" @@ -7157,24 +6562,21 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== -montag@^1.1.0: - version "1.2.1" - mri@^1.1.0: version "1.2.0" resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + mz@^2.7.0: version "2.7.0" resolved "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz" @@ -7224,7 +6626,7 @@ next-themes@^0.2.1: resolved "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz" integrity sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A== -next@*, next@^14.2.5, "next@^8.1.1-canary.54 || >=9.0.0", "next@>= 13", next@>=9.5.3: +next@^14.2.5: version "14.2.5" resolved "https://registry.npmjs.org/next/-/next-14.2.5.tgz" integrity sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA== @@ -7266,7 +6668,7 @@ nextra-theme-docs@latest: scroll-into-view-if-needed "^3.1.0" zod "^3.22.3" -nextra@2.13.4, nextra@latest: +nextra@latest: version "2.13.4" resolved "https://registry.npmjs.org/nextra/-/nextra-2.13.4.tgz" integrity sha512-7of2rSBxuUa3+lbMmZwG9cqgftcoNOVQLTT6Rxf3EhBR9t1EI7b43dted8YoqSNaigdE3j1CoyNkX8N/ZzlEpw== @@ -7546,7 +6948,7 @@ parse-entities@^4.0.0: is-decimal "^2.0.0" is-hexadecimal "^2.0.0" -parse-import-specifiers@^1.0.1, parse-import-specifiers@^1.0.2, parse-import-specifiers@^1.0.3: +parse-import-specifiers@^1.0.1: version "1.0.3" resolved "https://registry.npmjs.org/parse-import-specifiers/-/parse-import-specifiers-1.0.3.tgz" integrity sha512-jNtWL2DinOHUGnFEzeAyCJhacxwFkLzPnR3Foy3t2mOTIEgzZ3aaOakPw0PvoLaPZUy64CWYuhVFa/QkEMLJhA== @@ -7654,9 +7056,6 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -picomatch@^4.0.1: - version "4.0.2" - picomatch@^4.0.2: version "4.0.2" resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz" @@ -7684,14 +7083,6 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pkg-dir@^7.0.0: - version "7.0.0" - dependencies: - find-up "^6.3.0" - -pluralize@^8.0.0: - version "8.0.0" - postcss-import@^15.1.0: version "15.1.0" resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz" @@ -7723,13 +7114,7 @@ postcss-nested@^6.0.1: dependencies: postcss-selector-parser "^6.0.11" -postcss-resolve-nested-selector@^0.1.1: - version "0.1.1" - -postcss-safe-parser@^7.0.0: - version "7.0.0" - -postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.13, postcss-selector-parser@^6.1.0: +postcss-selector-parser@^6.0.11: version "6.1.1" resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz" integrity sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg== @@ -7742,15 +7127,6 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.0.0, postcss@^8.1.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.31, postcss@^8.4.38, postcss@^8.4.40, postcss@>=8.0.9: - version "8.4.40" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz" - integrity sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q== - dependencies: - nanoid "^3.3.7" - picocolors "^1.0.1" - source-map-js "^1.2.0" - postcss@8.4.31: version "8.4.31" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz" @@ -7760,17 +7136,21 @@ postcss@8.4.31: picocolors "^1.0.0" source-map-js "^1.0.2" +postcss@^8.4.23, postcss@^8.4.40: + version "8.4.40" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz" + integrity sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.1" + source-map-js "^1.2.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier-linter-helpers@^1.0.0: - version "1.0.0" - dependencies: - fast-diff "^1.1.2" - -prettier@^3.1.0, prettier@^3.3.3, prettier@>=3.0.0: +prettier@^3.3.3: version "3.3.3" resolved "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz" integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew== @@ -7826,174 +7206,12 @@ pure-rand@^6.0.0: resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz" integrity sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA== -putout@*, putout@^35.0.0, putout@>=15, putout@>=16, putout@>=18, putout@>=20, putout@>=22.5, putout@>=23, putout@>=25, putout@>=26, putout@>=27, putout@>=28, putout@>=29, putout@>=30, putout@>=31, putout@>=32, putout@>=33, putout@>=34, putout@>=35, putout@>=4.31: - version "35.32.0" - dependencies: - "@putout/babel" "^2.0.0" - "@putout/cli-cache" "^3.0.0" - "@putout/cli-choose-formatter" "^4.0.0" - "@putout/cli-keypress" "^2.0.0" - "@putout/cli-match" "^2.0.0" - "@putout/cli-ruler" "^3.0.0" - "@putout/cli-staged" "^1.0.0" - "@putout/cli-validate-args" "^1.0.0" - "@putout/compare" "^14.0.0" - "@putout/engine-loader" "^13.0.0" - "@putout/engine-parser" "^10.0.0" - "@putout/engine-processor" "^11.0.0" - "@putout/engine-reporter" "^1.0.0" - "@putout/engine-runner" "^21.0.0" - "@putout/eslint" "^3.0.0" - "@putout/formatter-codeframe" "^7.0.0" - "@putout/formatter-dump" "^5.0.0" - "@putout/formatter-frame" "^6.0.0" - "@putout/formatter-json" "^2.0.0" - "@putout/formatter-json-lines" "^3.0.0" - "@putout/formatter-memory" "^4.0.0" - "@putout/formatter-progress" "^5.0.0" - "@putout/formatter-progress-bar" "^4.0.0" - "@putout/formatter-stream" "^5.0.0" - "@putout/formatter-time" "^3.0.0" - "@putout/operate" "^12.0.0" - "@putout/operator-add-args" "^8.0.0" - "@putout/operator-declare" "^9.0.0" - "@putout/operator-filesystem" "^4.0.0" - "@putout/operator-ignore" "^1.0.0" - "@putout/operator-json" "^2.0.0" - "@putout/operator-match-files" "^3.0.0" - "@putout/operator-regexp" "^1.0.0" - "@putout/operator-rename-files" "^1.0.0" - "@putout/plugin-apply-at" "^2.0.0" - "@putout/plugin-apply-destructuring" "^7.0.0" - "@putout/plugin-apply-dot-notation" "^2.0.0" - "@putout/plugin-apply-early-return" "^3.0.0" - "@putout/plugin-apply-flat-map" "^2.0.0" - "@putout/plugin-apply-optional-chaining" "^5.0.0" - "@putout/plugin-apply-overrides" "^1.0.0" - "@putout/plugin-apply-starts-with" "^1.0.0" - "@putout/plugin-apply-template-literals" "^3.0.0" - "@putout/plugin-browserlist" "^2.0.0" - "@putout/plugin-conditions" "^4.0.0" - "@putout/plugin-convert-apply-to-spread" "^4.0.0" - "@putout/plugin-convert-arguments-to-rest" "^2.0.0" - "@putout/plugin-convert-array-copy-to-slice" "^3.0.0" - "@putout/plugin-convert-assignment-to-arrow-function" "^1.0.0" - "@putout/plugin-convert-assignment-to-comparison" "^2.0.0" - "@putout/plugin-convert-concat-to-flat" "^1.0.0" - "@putout/plugin-convert-const-to-let" "^1.0.0" - "@putout/plugin-convert-index-of-to-includes" "^2.0.0" - "@putout/plugin-convert-label-to-object" "^1.0.0" - "@putout/plugin-convert-object-assign-to-merge-spread" "^6.0.0" - "@putout/plugin-convert-object-entries-to-array-entries" "^3.0.0" - "@putout/plugin-convert-optional-to-logical" "^3.0.0" - "@putout/plugin-convert-quotes-to-backticks" "^3.0.0" - "@putout/plugin-convert-template-to-string" "^2.0.0" - "@putout/plugin-convert-to-arrow-function" "^4.0.0" - "@putout/plugin-coverage" "^1.0.0" - "@putout/plugin-declare" "^4.0.0" - "@putout/plugin-declare-before-reference" "^4.0.0" - "@putout/plugin-declare-imports-first" "^2.0.0" - "@putout/plugin-eslint" "^8.0.0" - "@putout/plugin-extract-object-properties" "^9.0.0" - "@putout/plugin-extract-sequence-expressions" "^3.0.0" - "@putout/plugin-filesystem" "^5.0.0" - "@putout/plugin-for-of" "^6.0.0" - "@putout/plugin-generators" "^1.0.0" - "@putout/plugin-github" "^12.0.0" - "@putout/plugin-gitignore" "^6.0.0" - "@putout/plugin-logical-expressions" "^6.0.0" - "@putout/plugin-madrun" "^18.0.0" - "@putout/plugin-math" "^2.0.0" - "@putout/plugin-maybe" "^2.0.0" - "@putout/plugin-merge-destructuring-properties" "^8.0.0" - "@putout/plugin-merge-duplicate-functions" "^2.0.0" - "@putout/plugin-merge-duplicate-imports" "^11.0.0" - "@putout/plugin-montag" "^2.0.0" - "@putout/plugin-new" "^3.0.1" - "@putout/plugin-nodejs" "^11.0.0" - "@putout/plugin-npmignore" "^5.0.0" - "@putout/plugin-package-json" "^7.0.0" - "@putout/plugin-promises" "^15.0.0" - "@putout/plugin-putout" "^20.0.0" - "@putout/plugin-putout-config" "^5.0.0" - "@putout/plugin-regexp" "^8.0.0" - "@putout/plugin-remove-console" "^6.0.0" - "@putout/plugin-remove-constant-conditions" "^4.0.0" - "@putout/plugin-remove-debugger" "^7.0.0" - "@putout/plugin-remove-duplicate-case" "^3.0.0" - "@putout/plugin-remove-duplicate-keys" "^5.0.0" - "@putout/plugin-remove-empty" "^12.0.0" - "@putout/plugin-remove-iife" "^4.0.0" - "@putout/plugin-remove-nested-blocks" "^6.0.0" - "@putout/plugin-remove-unreachable-code" "^1.0.0" - "@putout/plugin-remove-unreferenced-variables" "^3.0.0" - "@putout/plugin-remove-unused-expressions" "^8.0.0" - "@putout/plugin-remove-unused-for-of-variables" "^3.0.0" - "@putout/plugin-remove-unused-private-fields" "^2.0.0" - "@putout/plugin-remove-unused-variables" "^9.0.0" - "@putout/plugin-remove-useless-arguments" "^8.0.0" - "@putout/plugin-remove-useless-array" "^1.0.0" - "@putout/plugin-remove-useless-array-constructor" "^2.0.0" - "@putout/plugin-remove-useless-array-entries" "^1.0.0" - "@putout/plugin-remove-useless-assign" "^1.0.0" - "@putout/plugin-remove-useless-constructor" "^1.0.0" - "@putout/plugin-remove-useless-continue" "^2.0.0" - "@putout/plugin-remove-useless-escape" "^6.0.0" - "@putout/plugin-remove-useless-functions" "^3.0.0" - "@putout/plugin-remove-useless-map" "^1.0.0" - "@putout/plugin-remove-useless-operand" "^2.0.0" - "@putout/plugin-remove-useless-replace" "^1.0.1" - "@putout/plugin-remove-useless-return" "^6.0.0" - "@putout/plugin-remove-useless-spread" "^11.0.0" - "@putout/plugin-remove-useless-template-expressions" "^2.0.0" - "@putout/plugin-remove-useless-variables" "^11.0.0" - "@putout/plugin-reuse-duplicate-init" "^5.0.0" - "@putout/plugin-simplify-assignment" "^3.0.0" - "@putout/plugin-simplify-boolean-return" "^1.0.0" - "@putout/plugin-simplify-ternary" "^7.0.0" - "@putout/plugin-sort-imports-by-specifiers" "^1.0.0" - "@putout/plugin-split-assignment-expressions" "^1.0.0" - "@putout/plugin-split-nested-destructuring" "^3.0.0" - "@putout/plugin-split-variable-declarations" "^3.0.0" - "@putout/plugin-tape" "^14.0.0" - "@putout/plugin-try-catch" "^3.0.0" - "@putout/plugin-types" "^4.0.0" - "@putout/plugin-typescript" "^7.0.0" - "@putout/plugin-webpack" "^3.0.0" - "@putout/processor-css" "^9.0.0" - "@putout/processor-filesystem" "^4.0.0" - "@putout/processor-ignore" "^6.0.0" - "@putout/processor-javascript" "^5.0.0" - "@putout/processor-json" "^9.0.0" - "@putout/processor-markdown" "^12.0.0" - "@putout/processor-yaml" "^8.0.0" - "@putout/traverse" "^10.0.0" - ajv "^8.8.2" - chalk "^5.3.0" - ci-info "^4.0.0" - debug "^4.1.1" - deepmerge "^4.0.0" - escalade "^3.1.1" - fast-glob "^3.2.2" - find-up "^7.0.0" - fullstore "^3.0.0" - ignore "^5.0.4" - is-relative "^1.0.0" - nano-memoize "^3.0.11" - once "^1.4.0" - picomatch "^4.0.1" - samadhi "^2.0.0" - try-catch "^3.0.0" - try-to-catch "^3.0.0" - wraptile "^3.0.0" - yargs-parser "^21.0.0" - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -react-dom@*, "react-dom@^16 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", react-dom@^18.2.0, react-dom@^18.3.1, "react-dom@>= 16.8.0 < 19.0.0", react-dom@>=16.0.0, react-dom@>=16.13.1, "react-dom@>=16.x <=18.x": +react-dom@^18.3.1: version "18.3.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== @@ -8027,7 +7245,7 @@ react-markdown@^9.0.1: unist-util-visit "^5.0.0" vfile "^6.0.0" -react@*, "react@^16 || ^17 || ^18", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^18 || ^19", react@^18.2.0, react@^18.3.1, "react@>= 16.8.0 < 19.0.0", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16, react@>=16.0.0, react@>=16.13.1, "react@>=16.x <=18.x", react@>=18: +react@^18.3.1: version "18.3.1" resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== @@ -8039,233 +7257,88 @@ read-cache@^1.0.0: resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz" integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== dependencies: - pify "^2.3.0" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -reading-time@^1.3.0: - version "1.5.0" - resolved "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz" - integrity sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg== - -reflect.getprototypeof@^1.0.4: - version "1.0.5" - resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz" - integrity sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ== - dependencies: - call-bind "^1.0.5" - define-properties "^1.2.1" - es-abstract "^1.22.3" - es-errors "^1.0.0" - get-intrinsic "^1.2.3" - globalthis "^1.0.3" - which-builtin-type "^1.1.3" - -regenerator-runtime@^0.14.0: - version "0.14.1" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz" - integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== - -regexp-tree@^0.1.21, regexp-tree@^0.1.24: - version "0.1.27" - -regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.2: - version "1.5.2" - resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz" - integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== - dependencies: - call-bind "^1.0.6" - define-properties "^1.2.1" - es-errors "^1.3.0" - set-function-name "^2.0.1" - -rehype-katex@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.0.tgz" - integrity sha512-h8FPkGE00r2XKU+/acgqwWUlyzve1IiOKwsEkg4pDL3k48PiE0Pt+/uLtVHDVkN1yA4iurZN6UES8ivHVEQV6Q== - dependencies: - "@types/hast" "^3.0.0" - "@types/katex" "^0.16.0" - hast-util-from-html-isomorphic "^2.0.0" - hast-util-to-text "^4.0.0" - katex "^0.16.0" - unist-util-visit-parents "^6.0.0" - vfile "^6.0.0" - -rehype-pretty-code@0.9.11: - version "0.9.11" - resolved "https://registry.npmjs.org/rehype-pretty-code/-/rehype-pretty-code-0.9.11.tgz" - integrity sha512-Eq90eCYXQJISktfRZ8PPtwc5SUyH6fJcxS8XOMnHPUQZBtC6RYo67gGlley9X2nR8vlniPj0/7oCDEYHKQa/oA== - dependencies: - "@types/hast" "^2.0.0" - hash-obj "^4.0.0" - parse-numeric-range "^1.3.0" - -rehype-raw@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz" - integrity sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww== - dependencies: - "@types/hast" "^3.0.0" - hast-util-raw "^9.0.0" - vfile "^6.0.0" - -remark-gfm@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz" - integrity sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-gfm "^2.0.0" - micromark-extension-gfm "^2.0.0" - unified "^10.0.0" - -remark-lint-blockquote-indentation@^4.0.0: - version "4.0.0" - dependencies: - "@types/mdast" "^4.0.0" - mdast-util-phrasing "^4.0.0" - pluralize "^8.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit-parents "^6.0.0" - -remark-lint-checkbox-character-style@^5.0.0: - version "5.0.0" - dependencies: - "@types/mdast" "^4.0.0" - mdast-util-phrasing "^4.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit-parents "^6.0.0" - vfile-message "^4.0.0" - -remark-lint-code-block-style@^4.0.0: - version "4.0.0" - dependencies: - "@types/mdast" "^4.0.0" - mdast-util-phrasing "^4.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit-parents "^6.0.0" - vfile-message "^4.0.0" - -remark-lint-emphasis-marker@^4.0.0: - version "4.0.0" - dependencies: - "@types/mdast" "^4.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit-parents "^6.0.0" - vfile-message "^4.0.0" - -remark-lint-fenced-code-marker@^4.0.0: - version "4.0.0" - dependencies: - "@types/mdast" "^4.0.0" - mdast-util-phrasing "^4.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit-parents "^6.0.0" - vfile-message "^4.0.0" - -remark-lint-heading-style@^4.0.0: - version "4.0.0" - dependencies: - "@types/mdast" "^4.0.0" - mdast-util-heading-style "^3.0.0" - mdast-util-phrasing "^4.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit-parents "^6.0.0" - vfile-message "^4.0.0" - -remark-lint-link-title-style@^4.0.0: - version "4.0.0" - dependencies: - "@types/mdast" "^4.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit-parents "^6.0.0" - vfile-message "^4.0.0" + pify "^2.3.0" -remark-lint-list-item-content-indent@^4.0.0: - version "4.0.0" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: - "@types/mdast" "^4.0.0" - mdast-util-phrasing "^4.0.0" - pluralize "^8.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit-parents "^6.0.0" - vfile-message "^4.0.0" + picomatch "^2.2.1" -remark-lint-ordered-list-marker-style@^4.0.0: - version "4.0.0" +reading-time@^1.3.0: + version "1.5.0" + resolved "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz" + integrity sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg== + +reflect.getprototypeof@^1.0.4: + version "1.0.5" + resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz" + integrity sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ== dependencies: - "@types/mdast" "^4.0.0" - mdast-util-phrasing "^4.0.0" - micromark-util-character "^2.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit-parents "^6.0.0" - vfile-message "^4.0.0" + call-bind "^1.0.5" + define-properties "^1.2.1" + es-abstract "^1.22.3" + es-errors "^1.0.0" + get-intrinsic "^1.2.3" + globalthis "^1.0.3" + which-builtin-type "^1.1.3" -remark-lint-ordered-list-marker-value@^4.0.0: - version "4.0.0" +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + +regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.2: + version "1.5.2" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz" + integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== dependencies: - "@types/mdast" "^4.0.0" - devlop "^1.0.0" - mdast-util-phrasing "^4.0.0" - micromark-util-character "^2.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit-parents "^6.0.0" - vfile-message "^4.0.0" + call-bind "^1.0.6" + define-properties "^1.2.1" + es-errors "^1.3.0" + set-function-name "^2.0.1" -remark-lint-rule-style@^4.0.0: - version "4.0.0" +rehype-katex@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.0.tgz" + integrity sha512-h8FPkGE00r2XKU+/acgqwWUlyzve1IiOKwsEkg4pDL3k48PiE0Pt+/uLtVHDVkN1yA4iurZN6UES8ivHVEQV6Q== dependencies: - "@types/mdast" "^4.0.0" - mdast-util-phrasing "^4.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" + "@types/hast" "^3.0.0" + "@types/katex" "^0.16.0" + hast-util-from-html-isomorphic "^2.0.0" + hast-util-to-text "^4.0.0" + katex "^0.16.0" unist-util-visit-parents "^6.0.0" - vfile-message "^4.0.0" + vfile "^6.0.0" -remark-lint-strong-marker@^4.0.0: - version "4.0.0" +rehype-pretty-code@0.9.11: + version "0.9.11" + resolved "https://registry.npmjs.org/rehype-pretty-code/-/rehype-pretty-code-0.9.11.tgz" + integrity sha512-Eq90eCYXQJISktfRZ8PPtwc5SUyH6fJcxS8XOMnHPUQZBtC6RYo67gGlley9X2nR8vlniPj0/7oCDEYHKQa/oA== dependencies: - "@types/mdast" "^4.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit-parents "^6.0.0" - vfile-message "^4.0.0" + "@types/hast" "^2.0.0" + hash-obj "^4.0.0" + parse-numeric-range "^1.3.0" -remark-lint-table-cell-padding@^5.0.0: - version "5.0.0" +rehype-raw@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz" + integrity sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww== dependencies: - "@types/mdast" "^4.0.0" - "@types/unist" "^3.0.0" - devlop "^1.0.0" - mdast-util-phrasing "^4.0.0" - pluralize "^8.0.0" - unified-lint-rule "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit-parents "^6.0.0" - vfile-message "^4.0.0" + "@types/hast" "^3.0.0" + hast-util-raw "^9.0.0" + vfile "^6.0.0" -remark-lint@^10.0.0: - version "10.0.0" +remark-gfm@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz" + integrity sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig== dependencies: - "@types/mdast" "^4.0.0" - remark-message-control "^8.0.0" - unified "^11.0.0" + "@types/mdast" "^3.0.0" + mdast-util-gfm "^2.0.0" + micromark-extension-gfm "^2.0.0" + unified "^10.0.0" remark-math@^5.1.1: version "5.1.1" @@ -8285,14 +7358,6 @@ remark-mdx@^2.0.0: mdast-util-mdx "^2.0.0" micromark-extension-mdxjs "^1.0.0" -remark-message-control@^8.0.0: - version "8.0.0" - dependencies: - "@types/mdast" "^4.0.0" - mdast-comment-marker "^3.0.0" - unified-message-control "^5.0.0" - vfile "^6.0.0" - remark-parse@^10.0.0: version "10.0.2" resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz" @@ -8312,25 +7377,6 @@ remark-parse@^11.0.0: micromark-util-types "^2.0.0" unified "^11.0.0" -remark-preset-lint-consistent@^6.0.0: - version "6.0.0" - dependencies: - remark-lint "^10.0.0" - remark-lint-blockquote-indentation "^4.0.0" - remark-lint-checkbox-character-style "^5.0.0" - remark-lint-code-block-style "^4.0.0" - remark-lint-emphasis-marker "^4.0.0" - remark-lint-fenced-code-marker "^4.0.0" - remark-lint-heading-style "^4.0.0" - remark-lint-link-title-style "^4.0.0" - remark-lint-list-item-content-indent "^4.0.0" - remark-lint-ordered-list-marker-style "^4.0.0" - remark-lint-ordered-list-marker-value "^4.0.0" - remark-lint-rule-style "^4.0.0" - remark-lint-strong-marker "^4.0.0" - remark-lint-table-cell-padding "^5.0.0" - unified "^11.0.0" - remark-reading-time@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/remark-reading-time/-/remark-reading-time-2.0.1.tgz" @@ -8362,13 +7408,6 @@ remark-rehype@^11.0.0: unified "^11.0.0" vfile "^6.0.0" -remark-stringify@^11.0.0: - version "11.0.0" - dependencies: - "@types/mdast" "^4.0.0" - mdast-util-to-markdown "^2.0.0" - unified "^11.0.0" - remove-accents@0.5.0: version "0.5.0" resolved "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz" @@ -8389,9 +7428,6 @@ require-directory@^2.1.1: resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== -require-from-string@^2.0.2: - version "2.0.2" - resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" @@ -8510,14 +7546,6 @@ safe-regex-test@^1.0.3: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -samadhi@^2.0.0: - version "2.2.0" - dependencies: - "@putout/quick-lint" "^1.2.0" - goldstein "^5.11.0" - js-tokens "^9.0.0" - try-catch "^3.0.1" - scheduler@^0.23.2: version "0.23.2" resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz" @@ -8532,9 +7560,6 @@ scroll-into-view-if-needed@^3.1.0: dependencies: compute-scroll-into-view "^3.0.2" -"search-insights@>= 1 < 3": - version "2.14.0" - section-matter@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz" @@ -8543,12 +7568,7 @@ section-matter@^1.0.0: extend-shallow "^2.0.1" kind-of "^6.0.0" -semver@^6.3.0: - version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^6.3.1: +semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -8639,7 +7659,7 @@ shebang-regex@^3.0.0: resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shiki@*, shiki@^0.14.3: +shiki@^0.14.3: version "0.14.7" resolved "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz" integrity sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg== @@ -8664,15 +7684,20 @@ signal-exit@^3.0.0, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -signal-exit@^4.0.1: +signal-exit@^4.0.1, signal-exit@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== -signal-exit@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== +simple-oauth2@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/simple-oauth2/-/simple-oauth2-5.1.0.tgz#1398fe2b8f4b4066298d63c155501b31b42238f2" + integrity sha512-gWDa38Ccm4MwlG5U7AlcJxPv3lvr80dU7ARJWrGdgvOKyzSj1gr3GBPN1rABTedAYvC/LsGYoFuFxwDBPtGEbw== + dependencies: + "@hapi/hoek" "^11.0.4" + "@hapi/wreck" "^18.0.0" + debug "^4.3.4" + joi "^17.6.4" simple-swizzle@^0.2.2: version "0.2.2" @@ -8691,13 +7716,6 @@ slash@^3.0.0: resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^4.0.0: - version "4.0.0" - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - slice-ansi@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz" @@ -8721,7 +7739,7 @@ sort-keys@^5.0.0: dependencies: is-plain-obj "^4.0.0" -source-map-js@^1.0.1, source-map-js@^1.0.2, source-map-js@^1.2.0: +source-map-js@^1.0.2, source-map-js@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz" integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== @@ -8779,16 +7797,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -8865,28 +7874,14 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - -strip-ansi@^7.1.0: +strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== @@ -8949,62 +7944,6 @@ styled-jsx@5.1.1: dependencies: client-only "0.0.1" -stylelint-config-recommended@^14.0.0: - version "14.0.0" - -stylelint-config-standard@^36.0.0: - version "36.0.0" - dependencies: - stylelint-config-recommended "^14.0.0" - -stylelint-prettier@^5.0.0: - version "5.0.0" - dependencies: - prettier-linter-helpers "^1.0.0" - -stylelint@^16.0.0, stylelint@^16.0.1, stylelint@^16.1.0, stylelint@>=16.0.0: - version "16.6.1" - dependencies: - "@csstools/css-parser-algorithms" "^2.6.3" - "@csstools/css-tokenizer" "^2.3.1" - "@csstools/media-query-list-parser" "^2.1.11" - "@csstools/selector-specificity" "^3.1.1" - "@dual-bundle/import-meta-resolve" "^4.1.0" - balanced-match "^2.0.0" - colord "^2.9.3" - cosmiconfig "^9.0.0" - css-functions-list "^3.2.2" - css-tree "^2.3.1" - debug "^4.3.4" - fast-glob "^3.3.2" - fastest-levenshtein "^1.0.16" - file-entry-cache "^9.0.0" - global-modules "^2.0.0" - globby "^11.1.0" - globjoin "^0.1.4" - html-tags "^3.3.1" - ignore "^5.3.1" - imurmurhash "^0.1.4" - is-plain-object "^5.0.0" - known-css-properties "^0.31.0" - mathml-tag-names "^2.1.3" - meow "^13.2.0" - micromatch "^4.0.7" - normalize-path "^3.0.0" - picocolors "^1.0.1" - postcss "^8.4.38" - postcss-resolve-nested-selector "^0.1.1" - postcss-safe-parser "^7.0.0" - postcss-selector-parser "^6.1.0" - postcss-value-parser "^4.2.0" - resolve-from "^5.0.0" - string-width "^4.2.3" - strip-ansi "^7.1.0" - supports-hyperlinks "^3.0.0" - svg-tags "^1.0.0" - table "^6.8.2" - write-file-atomic "^5.0.1" - stylis@^4.1.3: version "4.3.1" resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz" @@ -9037,7 +7976,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.1.0: version "7.2.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -9051,20 +7990,11 @@ supports-color@^8.0.0: dependencies: has-flag "^4.0.0" -supports-hyperlinks@^3.0.0: - version "3.0.0" - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -svg-tags@^1.0.0: - version "1.0.0" - synckit@^0.6.0: version "0.6.2" resolved "https://registry.npmjs.org/synckit/-/synckit-0.6.2.tgz" @@ -9080,15 +8010,6 @@ synckit@^0.9.0: "@pkgr/core" "^0.1.0" tslib "^2.6.2" -table@^6.0.1, table@^6.8.2: - version "6.8.2" - dependencies: - ajv "^8.0.1" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - tailwindcss@^3.4.7: version "3.4.7" resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.7.tgz" @@ -9150,9 +8071,6 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" -timer-node@^5.0.7: - version "5.0.7" - title@^3.5.3: version "3.5.3" resolved "https://registry.npmjs.org/title/-/title-3.5.3.tgz" @@ -9200,12 +8118,12 @@ trough@^2.0.0: resolved "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz" integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw== -try-catch@^3.0.0, try-catch@^3.0.1: +try-catch@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/try-catch/-/try-catch-3.0.1.tgz" integrity sha512-91yfXw1rr/P6oLpHSyHDOHm0vloVvUoo9FVdw8YwY05QjJQG9OT0LUxe2VRAzmHG+0CUOmI3nhxDUMLxDN/NEQ== -try-to-catch@^3.0.0, try-to-catch@^3.0.1: +try-to-catch@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/try-to-catch/-/try-to-catch-3.0.1.tgz" integrity sha512-hOY83V84Hx/1sCzDSaJA+Xz2IIQOHRvjxzt+F0OjbQGPZ6yLPLArMA0gw/484MlfUkQbCpKYMLX3VDCAjWKfzQ== @@ -9327,7 +8245,7 @@ typescript-eslint@^7.18.0: "@typescript-eslint/parser" "7.18.0" "@typescript-eslint/utils" "7.18.0" -typescript@^5.0.4, typescript@^5.5.4, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta", typescript@>=3.3.1, typescript@>=4.2.0, typescript@>=4.9.5: +typescript@^5.0.4, typescript@^5.5.4: version "5.5.4" resolved "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz" integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== @@ -9342,9 +8260,6 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" -unc-path-regex@^0.1.2: - version "0.1.2" - undici-types@~5.26.4: version "5.26.5" resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" @@ -9355,26 +8270,6 @@ unicorn-magic@^0.1.0: resolved "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz" integrity sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ== -unified-lint-rule@^3.0.0: - version "3.0.0" - dependencies: - "@types/unist" "^3.0.0" - trough "^2.0.0" - unified "^11.0.0" - vfile "^6.0.0" - -unified-message-control@^5.0.0: - version "5.0.0" - dependencies: - "@types/unist" "^3.0.0" - devlop "^1.0.0" - space-separated-tokens "^2.0.0" - unist-util-is "^6.0.0" - unist-util-visit "^5.0.0" - vfile "^6.0.0" - vfile-location "^5.0.0" - vfile-message "^4.0.0" - unified@^10.0.0: version "10.1.2" resolved "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz" @@ -9401,17 +8296,6 @@ unified@^11.0.0: trough "^2.0.0" vfile "^6.0.0" -unified@^11.0.3: - version "11.0.4" - dependencies: - "@types/unist" "^3.0.0" - bail "^2.0.0" - devlop "^1.0.0" - extend "^3.0.0" - is-plain-obj "^4.0.0" - trough "^2.0.0" - vfile "^6.0.0" - unist-util-find-after@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz" @@ -9507,15 +8391,7 @@ unist-util-visit-parents@^4.0.0: "@types/unist" "^2.0.0" unist-util-is "^5.0.0" -unist-util-visit-parents@^5.0.0: - version "5.1.3" - resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz" - integrity sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" - -unist-util-visit-parents@^5.1.1: +unist-util-visit-parents@^5.0.0, unist-util-visit-parents@^5.1.1: version "5.1.3" resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz" integrity sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg== @@ -9566,7 +8442,7 @@ update-browserslist-db@^1.0.13: escalade "^3.1.1" picocolors "^1.0.0" -uri-js@^4.2.2, uri-js@^4.4.1: +uri-js@^4.2.2: version "4.4.1" resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== @@ -9646,17 +8522,7 @@ vfile-message@^4.0.0: "@types/unist" "^3.0.0" unist-util-stringify-position "^4.0.0" -vfile@^5.0.0: - version "5.3.7" - resolved "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz" - integrity sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^3.0.0" - vfile-message "^3.0.0" - -vfile@^5.3.0: +vfile@^5.0.0, vfile@^5.3.0: version "5.3.7" resolved "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz" integrity sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g== @@ -9759,11 +8625,6 @@ which@^1.2.9: dependencies: isexe "^2.0.0" -which@^1.3.1: - version "1.3.1" - dependencies: - isexe "^2.0.0" - which@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" @@ -9771,16 +8632,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -9812,9 +8664,6 @@ wrappy@1: resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -wraptile@^3.0.0: - version "3.0.0" - write-file-atomic@^4.0.2: version "4.0.2" resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz" @@ -9823,12 +8672,6 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -write-file-atomic@^5.0.1: - version "5.0.1" - dependencies: - imurmurhash "^0.1.4" - signal-exit "^4.0.1" - y18n@^5.0.5: version "5.0.8" resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" @@ -9849,12 +8692,12 @@ yallist@^4.0.0: resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^2.2.2, yaml@^2.3.4, yaml@~2.4.2: +yaml@^2.3.4, yaml@~2.4.2: version "2.4.5" resolved "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz" integrity sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg== -yargs-parser@^21.0.0, yargs-parser@^21.1.1: +yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 60ce88d46d8b1..0000000000000 --- a/docs/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -yarn-error.log -node_modules -.DS_Store -docs/.vuepress/dist diff --git a/docs/.tool-versions b/docs/.tool-versions deleted file mode 100644 index eedff58c83cc6..0000000000000 --- a/docs/.tool-versions +++ /dev/null @@ -1 +0,0 @@ -nodejs 16.16.0 diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index aacbc08ddb26c..0000000000000 --- a/docs/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# Pipedream Docs - -## Modifying docs and testing locally - -First, install the dependencies for the repo: - -```bash -yarn install -``` - -Then, run the Vuepress app locally: - -```bash -yarn docs:dev -``` - -This should run a local development server on `http://localhost:8080/`. When you make changes to the Markdown files in the repo, the app should hot reload and refresh the browser automatically. - -And that's it! You're ready to develop Pipedream documentation 🏄 - -## The Pull Request process - -When contributing new code to this repo, please do so on a new Git branch, and submit a pull request to merge changes on that branch into `master`. - -A member of the Pipedream team will automatically be notified when you open a pull request. You can also reach out to us on [our community](https://pipedream.com/community/c/dev/11) or [Slack](https://pipedream.com/support). - -### Spellchecking - -A spellchecker is automatically run on Markdown files in PRs. If you see this check fail when you open a PR, check the output for misspelled words: - -```text -Misspelled words: - README.md: html>body>p --------------------------------------------------------------------------------- -lkjsdflkjsdflkjsdflk --------------------------------------------------------------------------------- - -!!!Spelling check failed!!! -Files in repository contain spelling errors -``` - -Some technical words (like Pipedream or JavaScript) aren't in an English dictionary. If the spellchecker fails on a real word, please add it to the `.wordlist.txt` file. - -The spellchecker configuration can be found in `.spellcheck.yml`. The spellchecking is handled by [this GitHub action](https://github.com/rojopolis/spellcheck-github-actions), which uses [PySpelling](https://facelessuser.github.io/pyspelling/). diff --git a/docs/docs/.vuepress/components/AlphaFeatureNotice.vue b/docs/docs/.vuepress/components/AlphaFeatureNotice.vue deleted file mode 100644 index 79c9c6603365f..0000000000000 --- a/docs/docs/.vuepress/components/AlphaFeatureNotice.vue +++ /dev/null @@ -1,31 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/components/BetaFeatureNotice.vue b/docs/docs/.vuepress/components/BetaFeatureNotice.vue deleted file mode 100644 index a394518b39a91..0000000000000 --- a/docs/docs/.vuepress/components/BetaFeatureNotice.vue +++ /dev/null @@ -1,31 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/components/Footer.vue b/docs/docs/.vuepress/components/Footer.vue deleted file mode 100644 index 96530a2a235d3..0000000000000 --- a/docs/docs/.vuepress/components/Footer.vue +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/docs/docs/.vuepress/components/GuideLink.vue b/docs/docs/.vuepress/components/GuideLink.vue deleted file mode 100644 index 22870a58bd47a..0000000000000 --- a/docs/docs/.vuepress/components/GuideLink.vue +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - diff --git a/docs/docs/.vuepress/components/LanguageLink.vue b/docs/docs/.vuepress/components/LanguageLink.vue deleted file mode 100644 index bec36d76156ca..0000000000000 --- a/docs/docs/.vuepress/components/LanguageLink.vue +++ /dev/null @@ -1,17 +0,0 @@ - - diff --git a/docs/docs/.vuepress/components/PythonMappings.vue b/docs/docs/.vuepress/components/PythonMappings.vue deleted file mode 100644 index eb29e15d9cc5e..0000000000000 --- a/docs/docs/.vuepress/components/PythonMappings.vue +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - diff --git a/docs/docs/.vuepress/components/VideoPlayer.vue b/docs/docs/.vuepress/components/VideoPlayer.vue deleted file mode 100644 index 507ba84ac5bcb..0000000000000 --- a/docs/docs/.vuepress/components/VideoPlayer.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/components/python-mappings.json b/docs/docs/.vuepress/components/python-mappings.json deleted file mode 100644 index 0c8f9591ebc0d..0000000000000 --- a/docs/docs/.vuepress/components/python-mappings.json +++ /dev/null @@ -1,1078 +0,0 @@ -{ - "ShopifyAPI": "shopify", - "google-cloud-bigquery": "bigquery", - "carbon3d-client": "carbon3d", - "python-telegram-bot": "telegram", - "pyAFQ": "AFQ", - "agpy": "AG_fft_tools", - "pexpect": "screen", - "Adafruit_Libraries": "Adafruit", - "Zope2": "webdav", - "py_Asterisk": "Asterisk", - "bitbucket_jekyll_hook": "BB_jekyll_hook", - "Banzai_NGS": "Banzai", - "BeautifulSoup": "BeautifulSoupTests", - "biopython": "BioSQL", - "BuildbotEightStatusShields": "BuildbotStatusShields", - "ExtensionClass": "MethodObject", - "pycryptodome": "Crypto", - "pycryptodomex": "Cryptodome", - "51degrees_mobile_detector_v3_wrapper": "FiftyOneDegrees", - "pyfunctional": "functional", - "GeoBasesDev": "GeoBases", - "ipython": "IPython", - "astro_kittens": "Kittens", - "python_Levenshtein": "Levenshtein", - "MySQL-python": "MySQLdb", - "PyOpenGL": "OpenGL", - "pyOpenSSL": "OpenSSL", - "Pillow": "PIL", - "astLib": "PyWCSTools", - "astro_pyxis": "Pyxides", - "PySide": "pysideuic", - "s3cmd": "S3", - "pystick": "SCons", - "PyStemmer": "Stemmer", - "topzootools": "TopZooTools", - "DocumentTemplate": "TreeDisplay", - "aspose_pdf_java_for_python": "WorkingWithDocumentConversion", - "auto_adjust_display_brightness": "aadb", - "abakaffe_cli": "abakaffe", - "abiosgaming.py": "abiosgaming", - "abiquo_api": "abiquo", - "abl.cssprocessor": "abl", - "abl.robot": "abl", - "abl.util": "abl", - "abl.vpath": "abl", - "abo_generator": "abo", - "abris": "abris_transform", - "abstract.jwrotator": "abstract", - "abu.admin": "abu", - "AC_Flask_HipChat": "ac_flask", - "anikom15": "acg", - "acme.dchat": "acme", - "acme.hello": "acme", - "acted.projects": "acted", - "ActionServer": "action", - "actionbar.panel": "actionbar", - "afn": "activehomed", - "ActivePapers.Py": "activepapers", - "address_book_lansry": "address_book", - "adi.commons": "adi", - "adi.devgen": "adi", - "adi.fullscreen": "adi", - "adi.init": "adi", - "adi.playlist": "adi", - "adi.samplecontent": "adi", - "adi.slickstyle": "adi", - "adi.suite": "adi", - "adi.trash": "adi", - "aDict2": "adict", - "aditam.agent": "aditam", - "aditam.core": "aditam", - "adium_sh": "adiumsh", - "AdjectorClient": "adjector", - "AdjectorTracPlugin": "adjector", - "Banner_Ad_Toolkit": "adkit", - "django_admin_tools": "admin_tools", - "adminish_categories": "adminishcategories", - "django_admin_sortable": "adminsortable", - "adspygoogle.adwords": "adspygoogle", - "agtl": "advancedcaching", - "Adytum_PyMonitor": "adytum", - "affinitic.docpyflakes": "affinitic", - "affinitic.recipe.fakezope2eggs": "affinitic", - "affinitic.simplecookiecuttr": "affinitic", - "affinitic.verifyinterface": "affinitic", - "affinitic.zamqp": "affinitic", - "afpy.xap": "afpy", - "agate_sql": "agatesql", - "ageliaco.recipe.csvconfig": "ageliaco", - "agent.http": "agent_http", - "Agora_Client": "agora", - "Agora_Fountain": "agora", - "Agora_Fragment": "agora", - "Agora_Planner": "agora", - "Agora_Service_Provider": "agora", - "agoraplex.themes.sphinx": "agoraplex", - "agsci.blognewsletter": "agsci", - "agx.core": "agx", - "agx.dev": "agx", - "agx.generator.buildout": "agx", - "agx.generator.dexterity": "agx", - "agx.generator.generator": "agx", - "agx.generator.plone": "agx", - "agx.generator.pyegg": "agx", - "agx.generator.sql": "agx", - "agx.generator.uml": "agx", - "agx.generator.zca": "agx", - "agx.transform.uml2fs": "agx", - "agx.transform.xmi2uml": "agx", - "aimes.bundle": "aimes", - "aimes.skeleton": "aimes", - "aio.app": "aio", - "aio.config": "aio", - "aio.core": "aio", - "aio.signals": "aio", - "aio_hs2": "aiohs2", - "aio_routes": "aioroutes", - "aio_s3": "aios3", - "airbrake_flask": "airbrake", - "airship_icloud": "airship", - "airship_steamcloud": "airship", - "edgegrid_python": "akamai", - "alation_api": "alation", - "alba_client_python": "alba_client", - "alburnum_maas_client": "alburnum", - "alchemist.audit": "alchemist", - "alchemist.security": "alchemist", - "alchemist.traversal": "alchemist", - "alchemist.ui": "alchemist", - "alchemyapi_python": "alchemyapi", - "alerta_server": "alerta", - "Alexandria_Upload_Utils": "alexandria_upload", - "alibaba_python_sdk": "alibaba", - "aliyun_python_sdk": "aliyun", - "alicloudcli": "aliyuncli", - "aliyun_python_sdk_acs": "aliyunsdkacs", - "aliyun_python_sdk_batchcompute": "aliyunsdkbatchcompute", - "aliyun_python_sdk_bsn": "aliyunsdkbsn", - "aliyun_python_sdk_bss": "aliyunsdkbss", - "aliyun_python_sdk_cdn": "aliyunsdkcdn", - "aliyun_python_sdk_cms": "aliyunsdkcms", - "aliyun_python_sdk_core": "aliyunsdkcore", - "aliyun_python_sdk_crm": "aliyunsdkcrm", - "aliyun_python_sdk_cs": "aliyunsdkcs", - "aliyun_python_sdk_drds": "aliyunsdkdrds", - "aliyun_python_sdk_ecs": "aliyunsdkecs", - "aliyun_python_sdk_ess": "aliyunsdkess", - "aliyun_python_sdk_ft": "aliyunsdkft", - "aliyun_python_sdk_mts": "aliyunsdkmts", - "aliyun_python_sdk_ocs": "aliyunsdkocs", - "aliyun_python_sdk_oms": "aliyunsdkoms", - "aliyun_python_sdk_ossadmin": "aliyunsdkossadmin", - "aliyun_python_sdk_r_kvstore": "aliyunsdkr-kvstore", - "aliyun_python_sdk_ram": "aliyunsdkram", - "aliyun_python_sdk_rds": "aliyunsdkrds", - "aliyun_python_sdk_risk": "aliyunsdkrisk", - "aliyun_python_sdk_ros": "aliyunsdkros", - "aliyun_python_sdk_slb": "aliyunsdkslb", - "aliyun_python_sdk_sts": "aliyunsdksts", - "aliyun_python_sdk_ubsms": "aliyunsdkubsms", - "aliyun_python_sdk_yundun": "aliyunsdkyundun", - "AllAttachmentsMacro": "allattachments", - "allocine_wrapper": "allocine", - "django_allowedsites": "allowedsites", - "alm.solrindex": "alm", - "aloft.py": "aloft", - "alpaca": "alpacalib", - "alphabetic_simple": "alphabetic", - "alphasms_client": "alphasms", - "altered.states": "altered", - "alterootheme.busycity": "alterootheme", - "alterootheme.intensesimplicity": "alterootheme", - "alterootheme.lazydays": "alterootheme", - "alurinium_image_processing": "alurinium", - "alx": "alxlib", - "amara3_iri": "amara3", - "amara3_xml": "amara3", - "AmazonAPIWrapper": "amazon", - "python_amazon_simple_product_api": "amazon", - "ambikesh1349_1": "ambikesh1349-1", - "AmbilightParty": "ambilight", - "amifs_core": "amifs", - "ami_organizer": "amiorganizer", - "amitu.lipy": "amitu", - "amitu_putils": "amitu", - "amitu_websocket_client": "amitu", - "amitu_zutils": "amitu", - "AMLT_learn": "amltlearn", - "amocrm_api": "amocrm", - "amqp_dispatcher": "amqpdispatcher", - "AMQP_Storm": "amqpstorm", - "analytics_python": "analytics", - "AnalyzeDirectory": "analyzedir", - "ancientsolutions_crypttools": "ancientsolutions", - "anderson.paginator": "anderson_paginator", - "android_resource_remover": "android_clean_app", - "AnelPowerControl": "anel_power_control", - "angus_sdk_python": "angus", - "Annalist": "annalist_root", - "ANNOgesic": "annogesiclib", - "ansible_role_apply": "ansible-role-apply", - "ansible_playbook_debugger": "ansibledebugger", - "ansible_docgen": "ansibledocgen", - "ansible_flow": "ansibleflow", - "ansible_inventory_grapher": "ansibleinventorygrapher", - "ansible_lint": "ansiblelint", - "ansible_roles_graph": "ansiblerolesgraph", - "ansible_tools": "ansibletools", - "anthill.exampletheme": "anthill", - "anthill.skinner": "anthill", - "anthill.tal.macrorenderer": "anthill", - "AnthraxDojoFrontend": "anthrax", - "AnthraxHTMLInput": "anthrax", - "AnthraxImage": "anthrax", - "antiweb": "antisphinx", - "antispoofing.evaluation": "antispoofing", - "antlr4_python2_runtime": "antlr4", - "antlr4_python3_runtime": "antlr4", - "antlr4_python_alt": "antlr4", - "anybox.buildbot.openerp": "anybox", - "anybox.nose.odoo": "anybox", - "anybox.paster.odoo": "anybox", - "anybox.paster.openerp": "anybox", - "anybox.recipe.sysdeps": "anybox", - "anybox.scripts.odoo": "anybox", - "google_api_python_client": "googleapiclient", - "google_apitools": "apitools", - "arpm": "apm", - "django_appdata": "app_data", - "django_appconf": "appconf", - "AppDynamicsDownloader": "appd", - "AppDynamicsREST": "appd", - "appdynamics_bindeps_linux_x64": "appdynamics_bindeps", - "appdynamics_bindeps_linux_x86": "appdynamics_bindeps", - "appdynamics_bindeps_osx_x64": "appdynamics_bindeps", - "appdynamics_proxysupport_linux_x64": "appdynamics_proxysupport", - "appdynamics_proxysupport_linux_x86": "appdynamics_proxysupport", - "appdynamics_proxysupport_osx_x64": "appdynamics_proxysupport", - "Appium_Python_Client": "appium", - "applibase": "appliapps", - "broadwick": "appserver", - "archetypes.kss": "archetypes", - "archetypes.multilingual": "archetypes", - "archetypes.schemaextender": "archetypes", - "ansible_role_manager": "arm", - "armor_api": "armor", - "armstrong.apps.related_content": "armstrong", - "armstrong.apps.series": "armstrong", - "armstrong.cli": "armstrong", - "armstrong.core.arm_access": "armstrong", - "armstrong.core.arm_layout": "armstrong", - "armstrong.core.arm_sections": "armstrong", - "armstrong.core.arm_wells": "armstrong", - "armstrong.dev": "armstrong", - "armstrong.esi": "armstrong", - "armstrong.hatband": "armstrong", - "armstrong.templates.standard": "armstrong", - "armstrong.utils.backends": "armstrong", - "armstrong.utils.celery": "armstrong", - "arstecnica.raccoon.autobahn": "arstecnica", - "arstecnica.sqlalchemy.async": "arstecnica", - "article_downloader": "article-downloader", - "artifact_cli": "artifactcli", - "arvados_python_client": "arvados", - "arvados_cwl_runner": "arvados_cwl", - "arvados_node_manager": "arvnodeman", - "AsanaToGithub": "asana_to_github", - "AsciiBinaryConverter": "asciibinary", - "AdvancedSearchDiscovery": "asd", - "askbot_tuan": "askbot", - "askbot_tuanpa": "askbot", - "asnhistory_redis": "asnhistory", - "aspen_jinja2": "aspen_jinja2_renderer", - "aspen_tornado": "aspen_tornado_engine", - "asprise_ocr_sdk_python_api": "asprise_ocr_api", - "aspy.refactor_imports": "aspy", - "aspy.yaml": "aspy", - "asterisk_ami": "asterisk", - "add_asts": "asts", - "asymmetricbase.enum": "asymmetricbase", - "asymmetricbase.fields": "asymmetricbase", - "asymmetricbase.logging": "asymmetricbase", - "asymmetricbase.utils": "asymmetricbase", - "asyncio_irc": "asyncirc", - "asyncmongoorm_je": "asyncmongoorm", - "asyncssh_unofficial": "asyncssh", - "athletelistyy": "athletelist", - "automium": "atm", - "atmosphere_python_client": "atmosphere", - "gdata": "atom", - "AtomicWrite": "atomic", - "atomisator.db": "atomisator", - "atomisator.enhancers": "atomisator", - "atomisator.feed": "atomisator", - "atomisator.indexer": "atomisator", - "atomisator.outputs": "atomisator", - "atomisator.parser": "atomisator", - "atomisator.readers": "atomisator", - "atreal.cmfeditions.unlocker": "atreal", - "atreal.filestorage.common": "atreal", - "atreal.layouts": "atreal", - "atreal.mailservices": "atreal", - "atreal.massloader": "atreal", - "atreal.monkeyplone": "atreal", - "atreal.override.albumview": "atreal", - "atreal.richfile.preview": "atreal", - "atreal.richfile.qualifier": "atreal", - "atreal.usersinout": "atreal", - "atsim.potentials": "atsim", - "attract_sdk": "attractsdk", - "audio.bitstream": "audio", - "audio.coders": "audio", - "audio.filters": "audio", - "audio.fourier": "audio", - "audio.frames": "audio", - "audio.lp": "audio", - "audio.psychoacoustics": "audio", - "audio.quantizers": "audio", - "audio.shrink": "audio", - "audio.wave": "audio", - "auf_refer": "aufrefer", - "auslfe.formonline.content": "auslfe", - "auspost_apis": "auspost", - "auth0_python": "auth0", - "AuthServerClient": "auth_server_client", - "AuthorizeSauce": "authorize", - "AuthzPolicyPlugin": "authzpolicy", - "autobahn_rce": "autobahn", - "geonode_avatar": "avatar", - "android_webview": "awebview", - "azure_common": "azure", - "azure_mgmt_common": "azure", - "azure_mgmt_compute": "azure", - "azure_mgmt_network": "azure", - "azure_mgmt_nspkg": "azure", - "azure_mgmt_resource": "azure", - "azure_mgmt_storage": "azure", - "azure_nspkg": "azure", - "azure_servicebus": "azure", - "azure_servicemanagement_legacy": "azure", - "azure_storage": "azure", - "b2g_commands": "b2gcommands", - "b2gperf_v1.3": "b2gperf", - "b2gperf_v1.4": "b2gperf", - "b2gperf_v2.0": "b2gperf", - "b2gperf_v2.1": "b2gperf", - "b2gperf_v2.2": "b2gperf", - "b2gpopulate_v1.3": "b2gpopulate", - "b2gpopulate_v1.4": "b2gpopulate", - "b2gpopulate_v2.0": "b2gpopulate", - "b2gpopulate_v2.1": "b2gpopulate", - "b2gpopulate_v2.2": "b2gpopulate", - "b3j0f.annotation": "b3j0f", - "b3j0f.aop": "b3j0f", - "b3j0f.conf": "b3j0f", - "b3j0f.sync": "b3j0f", - "b3j0f.utils": "b3j0f", - "Babel": "babel", - "BabelGladeExtractor": "babelglade", - "backplane2_pyclient": "backplane", - "backport_collections": "backport_abcoll", - "backports.functools_lru_cache": "backports", - "backports.inspect": "backports", - "backports.pbkdf2": "backports", - "backports.shutil_get_terminal_size": "backports", - "backports.socketpair": "backports", - "backports.ssl": "backports", - "backports.ssl_match_hostname": "backports", - "backports.statistics": "backports", - "badgekit_api_client": "badgekit", - "BadLinksPlugin": "badlinks", - "bael.project": "bael", - "baidupy": "baidu", - "buildtools": "balrog", - "baluhn_redux": "baluhn", - "bamboo.pantrybell": "bamboo", - "bamboo.scaffold": "bamboo", - "bamboo.setuptools_version": "bamboo", - "bamboo_data": "bamboo", - "bamboo_server": "bamboo", - "bambu_codemirror": "bambu", - "bambu_dataportability": "bambu", - "bambu_enqueue": "bambu", - "bambu_faq": "bambu", - "bambu_ffmpeg": "bambu", - "bambu_grids": "bambu", - "bambu_international": "bambu", - "bambu_jwplayer": "bambu", - "bambu_minidetect": "bambu", - "bambu_navigation": "bambu", - "bambu_notifications": "bambu", - "bambu_payments": "bambu", - "bambu_pusher": "bambu", - "bambu_saas": "bambu", - "bambu_sites": "bambu", - "Bananas": "banana", - "banana.maya": "banana", - "bangtext": "bang", - "barcode_generator": "barcode", - "bark_ssg": "bark", - "BarkingOwl": "barking_owl", - "bart_py": "bart", - "basalt_tasks": "basalt", - "base_62": "base62", - "basemap_Jim": "basemap", - "bash_toolbelt": "bash", - "Python_Bash_Utils": "bashutils", - "BasicHttp": "basic_http", - "basil_daq": "basil", - "azure_batch_apps": "batchapps", - "python_bcrypt": "bcrypt", - "Beaker": "beaker", - "beets": "beetsplug", - "begins": "begin", - "bench_it": "benchit", - "beproud.utils": "beproud", - "burrito_fillings": "bfillings", - "BigJob": "pilot", - "billboard.py": "billboard", - "anaconda_build": "binstar_build_client", - "anaconda_client": "binstar_client", - "biocommons.dev": "biocommons", - "birdhousebuilder.recipe.conda": "birdhousebuilder", - "birdhousebuilder.recipe.docker": "birdhousebuilder", - "birdhousebuilder.recipe.redis": "birdhousebuilder", - "birdhousebuilder.recipe.supervisor": "birdhousebuilder", - "pymeshio": "blender26-meshio", - "borg.localrole": "borg", - "bagofwords": "bow", - "bpython": "bpdb", - "bisque_api": "bqapi", - "django_braces": "braces", - "briefs_caster": "briefscaster", - "brisa_media_server_plugins": "brisa_media_server/plugins", - "brkt_sdk": "brkt_requests", - "broadcast_logging": "broadcastlogging", - "brocade_tool": "brocadetool", - "bronto_python": "bronto", - "Brownie": "brownie", - "browsermob_proxy": "browsermobproxy", - "brubeck_mysql": "brubeckmysql", - "brubeck_oauth": "brubeckoauth", - "brubeck_service": "brubeckservice", - "brubeck_uploader": "brubeckuploader", - "beautifulsoup4": "bs4", - "pymongo": "gridfs", - "bst.pygasus.core": "bst", - "bst.pygasus.datamanager": "bst", - "bst.pygasus.demo": "bst", - "bst.pygasus.i18n": "bst", - "bst.pygasus.resources": "bst", - "bst.pygasus.scaffolding": "bst", - "bst.pygasus.security": "bst", - "bst.pygasus.session": "bst", - "bst.pygasus.wsgi": "bst", - "btable_py": "btable", - "bananatag_api": "btapi", - "btce_api": "btceapi", - "btce_bot": "btcebot", - "btsync.py": "btsync", - "buck.pprint": "buck", - "bud.nospam": "bud", - "budy_api": "budy", - "buffer_alpaca": "buffer", - "bug.gd": "buggd", - "bugle_sites": "bugle", - "bug_spots": "bugspots", - "python_bugzilla": "bugzilla", - "bugzscout_py": "bugzscout", - "ajk_ios_buildTools": "buildTools", - "BuildNotify": "buildnotifylib", - "buildout.bootstrap": "buildout", - "buildout.disablessl": "buildout", - "buildout.dumppickedversions": "buildout", - "buildout.dumppickedversions2": "buildout", - "buildout.dumprequirements": "buildout", - "buildout.eggnest": "buildout", - "buildout.eggscleaner": "buildout", - "buildout.eggsdirectories": "buildout", - "buildout.eggtractor": "buildout", - "buildout.extensionscripts": "buildout", - "buildout.locallib": "buildout", - "buildout.packagename": "buildout", - "buildout.recipe.isolation": "buildout", - "buildout.removeaddledeggs": "buildout", - "buildout.requirements": "buildout", - "buildout.sanitycheck": "buildout", - "buildout.sendpickedversions": "buildout", - "buildout.threatlevel": "buildout", - "buildout.umask": "buildout", - "buildout.variables": "buildout", - "buildbot_slave": "buildslave", - "pies2overrides": "xmlrpc", - "bumper_lib": "bumper", - "bumple_downloader": "bumple", - "bundesliga_cli": "bundesliga", - "bundlemanager": "bundlemaker", - "burp_ui": "burpui", - "busyflow.pivotal": "busyflow", - "buttercms_django": "buttercms-django", - "buzz_python_client": "buzz", - "buildout_versions_checker": "bvc", - "bvg_grabber": "bvggrabber", - "BYONDTools": "byond", - "Bugzilla_ETL": "bzETL", - "bugzillatools": "bzlib", - "bzr": "bzrlib", - "bzr_automirror": "bzrlib", - "bzr_bash_completion": "bzrlib", - "bzr_colo": "bzrlib", - "bzr_killtrailing": "bzrlib", - "bzr_pqm": "bzrlib", - "c2c.cssmin": "c2c", - "c2c.recipe.closurecompile": "c2c", - "c2c.recipe.cssmin": "c2c", - "c2c.recipe.jarfile": "c2c", - "c2c.recipe.msgfmt": "c2c", - "c2c.recipe.pkgversions": "c2c", - "c2c.sqlalchemy.rest": "c2c", - "c2c.versions": "c2c", - "c2c.recipe.facts": "c2c_recipe_facts", - "cabalgata_silla_de_montar": "cabalgata", - "cabalgata_zookeeper": "cabalgata", - "django_cache_utils": "cache_utils", - "django_recaptcha": "captcha", - "Cartridge": "cartridge", - "cassandra_driver": "cassandra", - "CassandraLauncher": "cassandralauncher", - "42qucc": "cc42", - "Cerberus": "cerberus", - "cfn-lint": "cfnlint", - "Chameleon": "chameleon", - "charm_tools": "charmtools", - "PyChef": "chef", - "c8d": "chip8", - "python_cjson": "cjson", - "django_classy_tags": "classytags", - "ConcurrentLogHandler": "cloghandler", - "virtualenv_clone": "clonevirtualenv", - "al_cloudinsight": "cloud-insight", - "adminapi": "cloud_admin", - "python_cloudservers": "cloudservers", - "cerebrod": "tasksitter", - "django_cms": "cms", - "ba_colander": "colander", - "ansicolors": "colors", - "bf_lc3": "compile", - "docker_compose": "compose", - "django_compressor": "compressor", - "futures": "concurrent", - "ConfigArgParse": "configargparse", - "PyContracts": "contracts", - "weblogo": "weblogolib", - "Couchapp": "couchapp", - "CouchDB": "couchdb", - "couchdb_python_curl": "couchdbcurl", - "coursera_dl": "courseradownloader", - "cow_framework": "cow", - "python_creole": "creole", - "Creoleparser": "creoleparser", - "django_crispy_forms": "crispy_forms", - "python_crontab": "crontab", - "tff": "ctff", - "pycups": "cups", - "elasticsearch_curator": "curator", - "pycurl": "curl", - "python_daemon": "daemon", - "DARE": "dare", - "python_dateutil": "dateutil", - "DAWG": "dawg", - "python_debian": "debian", - "python-decouple": "decouple", - "webunit": "demo", - "PySynth": "pysynth_samp", - "juju_deployer": "deployer", - "filedepot": "depot", - "tg.devtools": "devtools", - "2gis": "dgis", - "pyDHTMLParser": "dhtmlparser", - "python_digitalocean": "digitalocean", - "discord.py": "discord", - "ez_setup": "distribute_setup", - "Distutils2": "distutils2", - "Django": "django", - "amitu_hstore": "django_hstore", - "django_bower": "djangobower", - "django_celery": "djcelery", - "django_kombu": "djkombu", - "djorm_ext_pgarray": "djorm_pgarray", - "dnspython": "dns", - "ansible_docgenerator": "docgen", - "docker_py": "docker", - "dogpile.cache": "dogpile", - "dogpile.core": "dogpile", - "dogapi": "dogshell", - "pydot": "dot_parser", - "pydot2": "dot_parser", - "pydot3k": "dot_parser", - "python-dotenv": "dotenv", - "dpkt_fix": "dpkt", - "python_ldap": "ldif", - "django_durationfield": "durationfield", - "datazilla": "dzclient", - "easybuild_framework": "easybuild", - "python_editor": "editor", - "azure_elasticluster": "elasticluster", - "azure_elasticluster_current": "elasticluster", - "pyelftools": "elftools", - "Elixir": "elixir", - "empy": "emlib", - "pyenchant": "enchant", - "cssutils": "encutils", - "python_engineio": "engineio", - "enum34": "enum", - "pyephem": "ephem", - "abl.errorreporter": "errorreporter", - "beaker_es_plot": "esplot", - "adrest": "example", - "tweepy": "examples", - "pycassa": "ez_setup", - "Fabric": "fabric", - "Faker": "faker", - "python_fedora": "fedora", - "ailove_django_fias": "fias", - "51degrees_mobile_detector": "fiftyone_degrees", - "five.customerize": "five", - "five.globalrequest": "five", - "five.intid": "five", - "five.localsitemanager": "five", - "five.pt": "five", - "android_flasher": "flasher", - "Flask": "flask", - "Frozen_Flask": "flask_frozen", - "Flask_And_Redis": "flask_redis", - "Flask_Bcrypt": "flaskext", - "vnc2flv": "flvscreen", - "django_followit": "followit", - "pyforge": "forge", - "FormEncode": "formencode", - "django_formtools": "formtools", - "4ch": "fourch", - "allegrordf": "franz", - "freetype_py": "freetype", - "python_frontmatter": "frontmatter", - "ftp_cloudfs": "ftpcloudfs", - "librabbitmq": "funtests", - "fusepy": "fuse", - "Fuzzy": "fuzzy", - "tiddlyweb": "gabbi", - "3d_wallet_generator": "gen_3dwallet", - "android_gendimen": "gendimen", - "Genshi": "genshi", - "python_geohash": "quadtree", - "GeoNode": "geonode", - "gsconfig": "geoserver", - "Geraldo": "geraldo", - "django_getenv": "getenv", - "gevent_websocket": "geventwebsocket", - "python_gflags": "gflags", - "GitPython": "git", - "PyGithub": "github", - "github3.py": "github3", - "git_py": "gitpy", - "globusonline_transfer_api_client": "globusonline", - "protobuf": "google", - "grace_dizmo": "grace-dizmo", - "anovelmous_grammar": "grammar", - "graphenelib": "grapheneapi", - "scales": "greplin", - "grokcore.component": "grokcore", - "gsutil": "gslib", - "PyHamcrest": "hamcrest", - "HARPy": "harpy", - "PyHawk_with_a_single_extra_commit": "hawk", - "django_haystack": "haystack", - "mercurial": "hgext", - "hg_git": "hggit", - "python_hglib": "hglib", - "pisa": "sx", - "amarokHola": "hola", - "Hoover": "hoover", - "python_hostlist": "hostlist", - "nosehtmloutput": "htmloutput", - "django_hvad": "hvad", - "hydra-core": "hydra", - "199Fix": "i99fix", - "python_igraph": "igraph", - "IMDbPY": "imdb", - "impyla": "impala", - "ambition_inmemorystorage": "inmemorystorage", - "backport_ipaddress": "ipaddress", - "jaraco.timing": "jaraco", - "jaraco.util": "jaraco", - "Jinja2": "jinja2", - "jira_cli": "jiracli", - "johnny_cache": "johnny", - "JPype1": "jpypex", - "django_jsonfield": "jsonfield", - "aino_jstools": "jstools", - "jupyter_pip": "jupyterpip", - "PyJWT": "jwt", - "asana_kazoo": "kazoo", - "line_profiler": "kernprof", - "python_keyczar": "keyczar", - "django_keyedcache": "keyedcache", - "python_keystoneclient": "keystoneclient", - "kickstart": "kickstarter", - "krbV": "krbv", - "kss.core": "kss", - "Kuyruk": "kuyruk", - "AdvancedLangConv": "langconv", - "lava_utils_interface": "lava", - "lazr.authentication": "lazr", - "lazr.restfulclient": "lazr", - "lazr.uri": "lazr", - "adpasswd": "ldaplib", - "2or3": "lib2or3", - "3to2": "lib3to2", - "Aito": "libaito", - "bugs_everywhere": "libbe", - "bucket": "libbucket", - "apache_libcloud": "libcloud", - "future": "winreg", - "generateDS": "libgenerateDS", - "mitmproxy": "libmproxy", - "7lk_ocr_deploy": "libsvm", - "lisa_server": "lisa", - "aspose_words_java_for_python": "loadingandsaving", - "locustio": "locust", - "Logbook": "logbook", - "buildbot_status_logentries": "logentries", - "logilab_mtconverter": "logilab", - "python_magic": "magic", - "Mako": "mako", - "ManifestDestiny": "manifestparser", - "marionette_client": "marionette", - "Markdown": "markdown", - "pytest_marks": "marks", - "MarkupSafe": "markupsafe", - "pymavlink": "mavnative", - "python_memcached": "memcache", - "AllPairs": "metacomm", - "Metafone": "metaphone", - "metlog_py": "metlog", - "Mezzanine": "mezzanine", - "sqlalchemy_migrate": "migrate", - "python_mimeparse": "mimeparse", - "minitage.paste": "minitage", - "minitage.recipe.common": "minitage", - "android_missingdrawables": "missingdrawables", - "2lazy2rest": "mkrst_themes", - "mockredispy": "mockredis", - "python_modargs": "modargs", - "django_model_utils": "model_utils", - "asposebarcode": "models", - "asposestorage": "models", - "moksha.common": "moksha", - "moksha.hub": "moksha", - "moksha.wsgi": "moksha", - "py_moneyed": "moneyed", - "MongoAlchemy": "mongoalchemy", - "MonthDelta": "monthdelta", - "Mopidy": "mopidy", - "MoPyTools": "mopytools", - "django_mptt": "mptt", - "python-mpv": "mpv", - "mr.bob": "mrbob", - "msgpack_python": "msgpack", - "aino_mutations": "mutations", - "amazon_mws": "mws", - "mysql_connector_repackaged": "mysql", - "django_native_tags": "native_tags", - "ndg_httpsclient": "ndg", - "trytond_nereid": "nereid", - "baojinhuan": "nested", - "Amauri": "nester", - "abofly": "nester", - "bssm_pythonSig": "nester", - "python_novaclient": "novaclient", - "alauda_django_oauth": "oauth2_provider", - "oauth2client": "oauth2client", - "odfpy": "odf", - "Parsley": "ometa", - "python_openid": "openid", - "ali_opensearch": "opensearchsdk", - "oslo.i18n": "oslo_i18n", - "oslo.serialization": "oslo_serialization", - "oslo.utils": "oslo_utils", - "alioss": "oss", - "aliyun_python_sdk_oss": "oss", - "aliyunoss": "oss", - "cashew": "output", - "OWSLib": "owslib", - "nwdiag": "rackdiag", - "paho_mqtt": "paho", - "django_paintstore": "paintstore", - "django_parler": "parler", - "PasteScript": "paste", - "forked_path": "path", - "path.py": "path", - "patricia-trie": "patricia", - "Paver": "paver", - "ProxyTypes": "peak", - "anderson.picasso": "picasso", - "django-picklefield": "picklefield", - "pivotal_py": "pivotal", - "peewee": "pwiz", - "plivo": "plivoxml", - "plone.alterego": "plone", - "plone.api": "plone", - "plone.app.blob": "plone", - "plone.app.collection": "plone", - "plone.app.content": "plone", - "plone.app.contentlisting": "plone", - "plone.app.contentmenu": "plone", - "plone.app.contentrules": "plone", - "plone.app.contenttypes": "plone", - "plone.app.controlpanel": "plone", - "plone.app.customerize": "plone", - "plone.app.dexterity": "plone", - "plone.app.discussion": "plone", - "plone.app.event": "plone", - "plone.app.folder": "plone", - "plone.app.i18n": "plone", - "plone.app.imaging": "plone", - "plone.app.intid": "plone", - "plone.app.layout": "plone", - "plone.app.linkintegrity": "plone", - "plone.app.locales": "plone", - "plone.app.lockingbehavior": "plone", - "plone.app.multilingual": "plone", - "plone.app.portlets": "plone", - "plone.app.querystring": "plone", - "plone.app.redirector": "plone", - "plone.app.registry": "plone", - "plone.app.relationfield": "plone", - "plone.app.textfield": "plone", - "plone.app.theming": "plone", - "plone.app.users": "plone", - "plone.app.uuid": "plone", - "plone.app.versioningbehavior": "plone", - "plone.app.viewletmanager": "plone", - "plone.app.vocabularies": "plone", - "plone.app.widgets": "plone", - "plone.app.workflow": "plone", - "plone.app.z3cform": "plone", - "plone.autoform": "plone", - "plone.batching": "plone", - "plone.behavior": "plone", - "plone.browserlayer": "plone", - "plone.caching": "plone", - "plone.contentrules": "plone", - "plone.dexterity": "plone", - "plone.event": "plone", - "plone.folder": "plone", - "plone.formwidget.namedfile": "plone", - "plone.formwidget.recurrence": "plone", - "plone.i18n": "plone", - "plone.indexer": "plone", - "plone.intelligenttext": "plone", - "plone.keyring": "plone", - "plone.locking": "plone", - "plone.memoize": "plone", - "plone.namedfile": "plone", - "plone.outputfilters": "plone", - "plone.portlet.collection": "plone", - "plone.portlet.static": "plone", - "plone.portlets": "plone", - "plone.protect": "plone", - "plone.recipe.zope2install": "plone", - "plone.registry": "plone", - "plone.resource": "plone", - "plone.resourceeditor": "plone", - "plone.rfc822": "plone", - "plone.scale": "plone", - "plone.schema": "plone", - "plone.schemaeditor": "plone", - "plone.session": "plone", - "plone.stringinterp": "plone", - "plone.subrequest": "plone", - "plone.supermodel": "plone", - "plone.synchronize": "plone", - "plone.theme": "plone", - "plone.transformchain": "plone", - "plone.uuid": "plone", - "plone.z3cform": "plone", - "plonetheme.barceloneta": "plonetheme", - "pypng": "png", - "django_polymorphic": "polymorphic", - "python_postmark": "postmark", - "bash_powerprompt": "powerprompt", - "django-prefetch": "prefetch", - "AndrewList": "printList", - "progressbar2": "progressbar", - "progressbar33": "progressbar", - "django_oauth2_provider": "provider", - "pure_sasl": "puresasl", - "pylzma": "py7zlib", - "pyAMI_core": "pyAMI", - "arsespyder": "pyarsespyder", - "asdf": "pyasdf", - "aspell_python_ctypes": "pyaspell", - "pybbm": "pybb", - "pybloomfiltermmap": "pybloomfilter", - "Pyccuracy": "pyccuracy", - "PyCK": "pyck", - "python_crfsuite": "pycrfsuite", - "PyDispatcher": "pydispatch", - "pygeocoder": "pygeolib", - "Pygments": "pygments", - "python_graph_core": "pygraph", - "pyjon.utils": "pyjon", - "python_jsonrpc": "pyjsonrpc", - "Pykka": "pykka", - "PyLogo": "pylogo", - "adhocracy_Pylons": "pylons", - "libmagic": "pymagic", - "Amalwebcrawler": "pymycraawler", - "AbakaffeNotifier": "pynma", - "Pyphen": "pyphen", - "AEI": "pyrimaa", - "adhocracy_pysqlite": "pysqlite2", - "pysqlite": "pysqlite2", - "python_gettext": "pythongettext", - "python_json_logger": "pythonjsonlogger", - "PyUtilib": "pyutilib", - "Cython": "pyximport", - "qserve": "qs", - "django_quickapi": "quickapi", - "nose_quickunit": "quickunit", - "radical.pilot": "radical", - "radical.utils": "radical", - "readability_lxml": "readability", - "gnureadline": "readline", - "django_recaptcha_works": "recaptcha_works", - "RelStorage": "relstorage", - "django_reportapi": "reportapi", - "Requests": "requests", - "requirements_parser": "requirements", - "djangorestframework": "rest_framework", - "py_restclient": "restclient", - "async_retrial": "retrial", - "django_reversion": "reversion", - "rhaptos2.common": "rhaptos2", - "robotframework": "robot", - "django_robots": "robots", - "rosdep": "rosdep2", - "RSFile": "rsbackends", - "ruamel.base": "ruamel", - "pysaml2": "xmlenc", - "saga_python": "saga", - "aws-sam-translator": "samtranslator", - "libsass": "sassutils", - "alex_sayhi": "sayhi", - "scalr": "scalrtools", - "scikits.talkbox": "scikits", - "scratchpy": "scratch", - "pyScss": "scss", - "dict.sorted": "sdict", - "android_sdk_updater": "sdk_updater", - "django_sekizai": "sekizai", - "pysendfile": "sendfile", - "pyserial": "serial", - "astor": "setuputils", - "pyshp": "shapefile", - "Shapely": "shapely", - "ahonya_sika": "sika", - "pysingleton": "singleton", - "scikit_bio": "skbio", - "scikit_learn": "sklearn", - "slackclient": "slack", - "unicode_slugify": "slugify", - "smk_python_sdk": "smarkets", - "ctypes_snappy": "snappy", - "gevent_socketio": "socketio", - "sockjs_tornado": "sockjs", - "SocksiPy_branch": "socks", - "solrpy": "solr", - "Solution": "solution", - "sorl_thumbnail": "sorl", - "South": "south", - "Sphinx": "sphinx", - "ATD_document": "sphinx_pypi_upload", - "sphinxcontrib_programoutput": "sphinxcontrib", - "SQLAlchemy": "sqlalchemy", - "atlas": "src", - "auto_mix_prep": "src", - "bw_stats_toolkit": "stats_toolkit", - "dogstatsd_python": "statsd", - "python_stdnum": "stdnum", - "StoneageHTML": "stoneagehtml", - "django_storages": "storages", - "mox": "stubout", - "suds_jurko": "suds", - "python_swiftclient": "swiftclient", - "pytabix": "test", - "django_taggit": "taggit", - "django_tastypie": "tastypie", - "teamcity_messages": "teamcity", - "pyTelegramBotAPI": "telebot", - "Tempita": "tempita", - "Tenjin": "tenjin", - "python_termstyle": "termstyle", - "treeherder_client": "thclient", - "django_threaded_multihost": "threaded_multihost", - "3color_Press": "threecolor", - "pytidylib": "tidylib", - "3lwg": "tlw", - "toredis_fork": "toredis", - "tornado_redis": "tornadoredis", - "ansible_tower_cli": "tower_cli", - "Trac": "tracopt", - "android_localization_helper": "translation_helper", - "django_treebeard": "treebeard", - "trytond_stock": "trytond", - "tsuru_circus": "tsuru", - "python_tvrage": "tvrage", - "tw2.core": "tw2", - "tw2.d3": "tw2", - "tw2.dynforms": "tw2", - "tw2.excanvas": "tw2", - "tw2.forms": "tw2", - "tw2.jit": "tw2", - "tw2.jqplugins.flot": "tw2", - "tw2.jqplugins.gritter": "tw2", - "tw2.jqplugins.ui": "tw2", - "tw2.jquery": "tw2", - "tw2.sqla": "tw2", - "Twisted": "twisted", - "python_twitter": "twitter", - "transifex_client": "txclib", - "115wangpan": "u115", - "Unidecode": "unidecode", - "ansible_universe": "universe", - "pyusb": "usb", - "useless.pipes": "useless", - "auth_userpass": "userpass", - "automakesetup.py": "utilities", - "aino_utkik": "utkik", - "uWSGI": "uwsgidecorators", - "ab": "valentine", - "configobj": "validate", - "chartio": "version", - "ar_virtualenv_api": "virtualenvapi", - "brocade_plugins": "vyatta", - "WebOb": "webob", - "websocket_client": "websocket", - "WebTest": "webtest", - "Werkzeug": "werkzeug", - "wheezy.caching": "wheezy", - "wheezy.core": "wheezy", - "wheezy.http": "wheezy", - "tiddlywebwiki": "wikklytext", - "pywinrm": "winrm", - "Alfred_Workflow": "workflow", - "WSME": "wsmeext", - "WTForms": "wtforms", - "wtf_peewee": "wtfpeewee", - "pyxdg": "xdg", - "pytest_xdist": "xdist", - "xmpppy": "xmpp", - "XStatic_Font_Awesome": "xstatic", - "XStatic_jQuery": "xstatic", - "XStatic_jquery_ui": "xstatic", - "PyYAML": "yaml", - "z3c.autoinclude": "z3c", - "z3c.caching": "z3c", - "z3c.form": "z3c", - "z3c.formwidget.query": "z3c", - "z3c.objpath": "z3c", - "z3c.pt": "z3c", - "z3c.relationfield": "z3c", - "z3c.traverser": "z3c", - "z3c.zcmlhook": "z3c", - "pyzmq": "zmq", - "zopyx.textindexng3": "zopyx" -} \ No newline at end of file diff --git a/docs/docs/.vuepress/config.js b/docs/docs/.vuepress/config.js deleted file mode 100644 index 857506085e678..0000000000000 --- a/docs/docs/.vuepress/config.js +++ /dev/null @@ -1,34 +0,0 @@ -const path = require("path"); -const webpack = require("webpack"); -const themeConfig = require("./configs/themeConfig"); - -module.exports = { - title: "", - head: [ - ["link", { rel: "icon", href: "/favicon.ico" }], - ['meta', { name: 'version', content: 'latest' }] - ], - description: "Pipedream Documentation - Connect APIs, remarkably fast", - base: "/docs/", - plugins: [ - [ - "vuepress-plugin-canonical", - { - baseURL: "https://pipedream.com/docs", // base url for your canonical link, optional, default: '' - stripExtension: true, - }, - ], - "check-md", - "tabs", - ['vuepress-plugin-code-copy', { - color: '#34d28b', - backgroundColor: '#34d28b', - backgroundTransition: false, - successText: 'Copied' - }] - ], - themeConfig, - postcss: { - plugins: [require("autoprefixer"), require("tailwindcss")], - } -}; diff --git a/docs/docs/.vuepress/configs/envVars.js b/docs/docs/.vuepress/configs/envVars.js deleted file mode 100644 index 76bf902f86d62..0000000000000 --- a/docs/docs/.vuepress/configs/envVars.js +++ /dev/null @@ -1,41 +0,0 @@ -module.exports = { - PIPEDREAM_BASE_URL: "https://pipedream.com", - API_BASE_URL: "https://api.pipedream.com/v1", - SQL_API_BASE_URL: "https://rt.pipedream.com/sql", - ENDPOINT_BASE_URL: "*.m.pipedream.net", - PAYLOAD_SIZE_LIMIT: "512KB", - MEMORY_LIMIT: "256MB", - MEMORY_ABSOLUTE_LIMIT: "10GB", - EMAIL_PAYLOAD_SIZE_LIMIT: "30MB", - MAX_WORKFLOW_EXECUTION_LIMIT: "750", - base_credits_price: { - memory: 256, - seconds: 30, - }, - DATA_STORES_MAX_KEYS: "1,024", - DAILY_TESTING_LIMIT: "30 minutes", - INSPECTOR_EVENT_EXPIRY_DAYS: "365", - FUNCTION_PAYLOAD_LIMIT: "6MB", - DAILY_INVOCATIONS_LIMIT: "333", - FREE_ORG_DAILY_INVOCATIONS_LIMIT: "66", - PRICE_PER_INVOCATION: "0.0002", - FREE_MONTHLY_INVOCATIONS: "10,000", - PRO_MONTHLY_INVOCATIONS: "20,000", - TEAM_MONTHLY_INVOCATIONS: "20,000", - TEAM_MEMBER_LIMIT: "5", - PRO_MONTHLY_PRICE: "$19", - TEAM_MONTHLY_PRICE: "$19", - DEFAULT_WORKFLOW_QUEUE_SIZE: "100", - MAX_WORKFLOW_QUEUE_SIZE: "10,000", - NODE_VERSION: "18", - PYTHON_VERSION: "3.9", - GO_LANG_VERSION: "1.21.5", - CONFIGURED_PROPS_SIZE_LIMIT: "64KB", - SERVICE_DB_SIZE_LIMIT: "60KB", - TMP_SIZE_LIMIT: "2GB", - DELAY_MIN_MAX_TIME: - "You can pause your workflow for as little as one millisecond, or as long as one year", - PUBLIC_APPS: "1,700", - WARM_WORKERS_INTERVAL: "10 minutes", - WARM_WORKERS_CREDITS_PER_INTERVAL: 5, -}; diff --git a/docs/docs/.vuepress/configs/navConfig.js b/docs/docs/.vuepress/configs/navConfig.js deleted file mode 100644 index df827632c2390..0000000000000 --- a/docs/docs/.vuepress/configs/navConfig.js +++ /dev/null @@ -1,58 +0,0 @@ -module.exports = { - left: [ - { - text: "Documentation", - link: "/", - }, - { - text: "Quickstart", - link: "/quickstart/", - variant: "primary", - }, - { - text: "Guides", - link: "/guides/", - }, - { - text: "Reference", - items: [ - { text: "Components API", link: "/components/api/" }, - { text: "CLI", link: "/cli/install/" }, - { text: "REST API", link: "/api/" }, - { text: "Limits", link: "/limits/" }, - { text: "Security & Privacy", link: "/privacy-and-security/"}, - { text: "Handling Cold Starts", link: "/workflows/settings/#eliminate-cold-starts"}, - ], - }, - ], - right: [ - { - text: "Support", - link: "https://pipedream.com/support", - internal: true, - }, - { - text: "Pricing", - link: "/pricing/", - }, - { - text: "v2", - className: "docs-version", - ariaLabel: "Docs Version Menu", - items: [ - { - text: "v2", - link: "https://pipedream.com/docs", - internal: true, - }, - { - text: "v1", - link: "https://pipedream.com/docs/v1", - internal: true, - badge: "Deprecated", - badgeVariation: "danger", - }, - ], - }, - ] -}; diff --git a/docs/docs/.vuepress/configs/sidebarConfig.js b/docs/docs/.vuepress/configs/sidebarConfig.js deleted file mode 100644 index c430e8813c498..0000000000000 --- a/docs/docs/.vuepress/configs/sidebarConfig.js +++ /dev/null @@ -1,216 +0,0 @@ -// NEW NAV - -const docsNav = [ - { - title: "Quickstart", - children: [ - { - title: "Develop Workflows", - path: "/quickstart/", - }, - { - title: "Use GitHub Sync", - path: "/quickstart/github-sync/", - }, - ] - }, - "/workspaces/", - { - title: "Projects", - children: [ - "/projects/", - "/projects/git/", - { - title: "File Stores", - type: "group", - children: [{ title: "File Stores", path: "/projects/file-stores/" }, { title: "Node.js Reference", path: "/projects/file-stores/reference/" }], - }, - ] - }, - { - title: "Workflows", - children: [ - "/workflows/", - "/workflows/steps/", - "/workflows/steps/triggers/", - "/workflows/steps/actions/", - "/workflows/steps/using-props/", - "/workflows/events/", - "/workflows/events/inspect/", - "/workflows/flow-control/", - "/workflows/errors/", - "/workflows/concurrency-and-throttling/", - "/workflows/settings/", - "/workflows/vpc/", - "/workflows/domains/", - "/workflows/sharing/", - "/migrate-from-v1/", - ], - }, - "/event-history/", - "/sources/", - { - title: "Connected Accounts", - children: [ - "/connected-accounts/", - "/connected-accounts/api/", - "/connected-accounts/external-auth/", - ], - }, - ["/data-stores/", "Data Stores"], - { - title: "Code", - children: [ - "/code/", - { - title: "Node.js", - type: "group", - collapsable: false, - sidebarDepth: 2, - children: [ - "/code/nodejs/", - "/code/nodejs/ai-code-generation/", - "/code/nodejs/auth/", - "/code/nodejs/http-requests/", - "/code/nodejs/working-with-files/", - "/code/nodejs/using-data-stores/", - "/code/nodejs/delay/", - "/code/nodejs/rerun/", - "/environment-variables/", - "/code/nodejs/async/", - "/code/nodejs/sharing-code/", - "/code/nodejs/browser-automation/", - { - title: "Reference", - path: "/components/api/#run" - } - ], - }, - { - title: "Python", - type: "group", - collapsable: false, - sidebarDepth: 2, - children: [ - "/code/python/", - "/code/python/auth/", - "/code/python/http-requests/", - "/code/python/working-with-files/", - "/code/python/using-data-stores/", - "/code/python/delay/", - "/code/python/rerun/", - "/code/python/import-mappings/", - "/code/python/faqs/", - ], - }, - "/code/go/", - { - title: "Bash", - type: "group", - children: ["/code/bash/", "/code/bash/http-requests/"], - }, - "/destinations/", - "/environment-variables/", - ], - }, - "/http/", - { - title: "Integrations", - type: "group", - children: [ - "/apps/", - "/apps/contributing/", - { - title: "Components", - type: "group", - collapsable: false, - children: [ - "/components/", - "/components/quickstart/nodejs/actions/", - "/components/quickstart/nodejs/sources/", - "/pipedream-axios/", - "/components/typescript/", - "/components/guidelines/", - ], - }, - ], - }, - ["/troubleshooting/", "Troubleshooting"], - ["/user-settings/", "Settings"], - { - title: "Single-Sign On (SSO)", - children: [ - "/workspaces/sso/", - "/workspaces/sso/okta/", - "/workspaces/sso/google/", - "/workspaces/sso/saml/", - ], - }, -]; - -const referenceNav = [ - { - title: "Components API", - children: ["/components/api/"], - }, - { - title: "CLI", - type: "group", - children: ["/cli/install/", "/cli/login/", "/cli/reference/"], - }, - { - title: "API", - type: "group", - children: [ - "/api/", - "/api/auth/", - "/api/rest/", - "/api/rest/webhooks/", - "/api/rest/rss/", - "/api/sse/", - ], - }, - "/limits/", - { - title: "Security and Privacy", - children: [ - "/privacy-and-security/", - "/privacy-and-security/best-practices/", - "/abuse/", - "/privacy-and-security/pgp-key/", - "/subprocessors/", - ], - }, - "/workflows/settings/#eliminate-cold-starts", -]; - -const pricingNav = ["/pricing/"]; - -module.exports = { - // reference nav - "/components/api/": referenceNav, - "/pipedream-axios/": referenceNav, - "/api/": referenceNav, - "/api/auth/": referenceNav, - "/api/rest/": referenceNav, - "/api/rest/webhooks/": referenceNav, - "/api/rest/rss/": referenceNav, - "/api/rest/workflow-errors/": referenceNav, - "/api/sse/": referenceNav, - "/scheduling-future-tasks/": referenceNav, - "/cli/install/": referenceNav, - "/cli/login/": referenceNav, - "/cli/reference/": referenceNav, - "/limits/": referenceNav, - // security nav - "/privacy-and-security/": referenceNav, - "/privacy-and-reference/pgp-key/": referenceNav, - "/privacy-and-reference/best-practices/": referenceNav, - "/subprocessors/": referenceNav, - "/workflows/settings/#eliminate-cold-starts": referenceNav, - "/abuse/": referenceNav, - // pricing nav - "/pricing/": pricingNav, - // main nav - "/": docsNav, -}; diff --git a/docs/docs/.vuepress/configs/themeConfig.js b/docs/docs/.vuepress/configs/themeConfig.js deleted file mode 100644 index f858191059a0c..0000000000000 --- a/docs/docs/.vuepress/configs/themeConfig.js +++ /dev/null @@ -1,59 +0,0 @@ -const navConfig = require("./navConfig"); -const sidebarConfig = require("./sidebarConfig"); -const envVars = require("./envVars"); - -module.exports = { - algolia: { - appId: "XY28M447C5", - apiKey: "9d9169458128b3d60c22bb04da4431c7", - indexName: "pipedream", - algoliaOptions: { - facetFilters: ["version:latest"], - }, - }, - searchPlaceholder: "Search...", - logo: "https://res.cloudinary.com/pipedreamin/image/upload/t_logo48x48/v1597038956/docs/HzP2Yhq8_400x400_1_sqhs70.jpg", - repo: "PipedreamHQ/pipedream", - nav: navConfig, - - // if your docs are not at the root of the repo: - docsDir: "docs/docs", - editLinks: true, - // custom text for edit link. Defaults to "Edit this page" - editLinkText: "Improve this page", - sidebarDepth: 3, - sidebar: sidebarConfig, - // languages - icons: { - nodejs: { - only_icon: - "https://res.cloudinary.com/pipedreamin/image/upload/v1646761316/docs/icons/icons8-nodejs_aax6wn.svg", - with_title: - "https://res.cloudinary.com/pipedreamin/image/upload/v1646761316/docs/icons/icons8-nodejs_aax6wn.svg", - }, - python: { - only_icon: - "https://res.cloudinary.com/pipedreamin/image/upload/v1646763734/docs/icons/icons8-python_ypgmya.svg", - with_title: - "https://res.cloudinary.com/pipedreamin/image/upload/v1647356607/docs/icons/python-logo-generic_k3o5w2.svg", - }, - go: { - only_icon: - "https://res.cloudinary.com/pipedreamin/image/upload/v1646763751/docs/icons/Go-Logo_Blue_zhkchv.svg", - with_title: - "https://res.cloudinary.com/pipedreamin/image/upload/v1646763751/docs/icons/Go-Logo_Blue_zhkchv.svg", - }, - bash: { - only_icon: - "https://res.cloudinary.com/pipedreamin/image/upload/v1646763756/docs/icons/full_colored_dark_nllzkl.svg", - with_title: - "https://res.cloudinary.com/pipedreamin/image/upload/v1647356698/docs/icons/full_colored_dark_1_-svg_vyfnv7.svg", - }, - native: { - only_icon: "https://res.cloudinary.com/pipedreamin/image/upload/v1569526159/icons/pipedream_x6plab.svg", - with_title: "https://res.cloudinary.com/pipedreamin/image/upload/v1569526159/icons/pipedream_x6plab.svg" - } - }, - // environment variables - ...envVars, -}; diff --git a/docs/docs/.vuepress/enhanceApp.js b/docs/docs/.vuepress/enhanceApp.js deleted file mode 100644 index e20ecef17fc82..0000000000000 --- a/docs/docs/.vuepress/enhanceApp.js +++ /dev/null @@ -1,114 +0,0 @@ -import VueGtm from "vue-gtm"; - -// fork from vue-router@3.0.2 -// src/util/scroll.js -function getElementPosition(el) { - const docEl = document.documentElement - const docRect = docEl.getBoundingClientRect() - const elRect = el.getBoundingClientRect() - return { - x: elRect.left - docRect.left, - y: elRect.top - docRect.top, - } -} - -/** - * Fix broken Vuepress scrolling to internal #links - * - * @param {String} to - * @returns void - */ -function scrollToAnchor(to) { - const targetAnchor = to.hash.slice(1) - const targetElement = document.getElementById(targetAnchor) || document.querySelector(`[name='${targetAnchor}']`) - - if (targetElement) { - return window.scrollTo({ - top: getElementPosition(targetElement).y, - behavior: 'smooth', - }) - } else { - return false - } -} - -export default ({ - Vue, // the version of Vue being used in the VuePress app - options, // the options for the root Vue instance - router, // the router instance for the app - siteData, // site metadata -}) => { - if (typeof window !== "undefined") { - Vue.use(VueGtm, { - id: "GTM-KBDH3DB", - enabled: true, - debug: false, - vueRouter: router, - }); - } - - // Adapted from https://github.com/vuepress/vuepress-community/blob/7feb5c514090b6901cd7d9998f4dd858e0055b7a/packages/vuepress-plugin-smooth-scroll/src/enhanceApp.ts#L21 - // With a bug fix for handling long pages - router.options.scrollBehavior = (to, from, savedPosition) => { - if (typeof window === "undefined") { - return; - } - - if (savedPosition) { - return window.scrollTo({ - top: savedPosition.y, - behavior: 'smooth', - }) - } else if (to.hash) { - if (Vue.$vuepress.$get('disableScrollBehavior')) { - return false - } - const scrollResult = scrollToAnchor(to) - - if (scrollResult) { - return scrollResult - } else { - window.onload = () => { - scrollToAnchor(to) - } - } - } else { - return window.scrollTo({ - top: 0, - behavior: 'smooth', - }) - } - } - - router.addRoutes([ - { path: "/cron", redirect: "/workflows/steps/triggers" }, - { path: "/notebook", redirect: "/workflows/steps" }, - { path: "/workflows/fork", redirect: "/workflows/copy" }, - { path: "/notebook/fork", redirect: "/workflows/copy" }, - { path: "/notebook/inspector/", redirect: "/workflows/events/inspect/" }, - { path: "/notebook/destinations/s3/", redirect: "/destinations/s3/" }, - { path: "/notebook/destinations/sse/", redirect: "/destinations/sse/" }, - { - path: "/notebook/destinations/snowflake/", - redirect: "/destinations/snowflake/", - }, - { path: "/notebook/destinations/http/", redirect: "/destinations/http/" }, - { path: "/notebook/destinations/email/", redirect: "/destinations/email/" }, - { path: "/notebook/destinations/", redirect: "/destinations/" }, - { path: "/notebook/code/", redirect: "/workflows/steps/code/" }, - { - path: "/notebook/observability/", - redirect: "/workflows/events/inspect/", - }, - { path: "/notebook/actions/", redirect: "/workflows/steps/actions/" }, - { path: "/notebook/sources/", redirect: "/workflows/steps/triggers/" }, - { path: "/notebook/sql/", redirect: "/destinations/triggers/" }, - { path: "/what-is-pipedream/", redirect: "/" }, - { - path: "/docs/apps/all-apps", - redirect: "https://pipedream.com/apps", - }, - { path: "/workflows/steps/code/", redirect: '/code/nodejs/'} - - ]); -}; diff --git a/docs/docs/.vuepress/public/favicon.ico b/docs/docs/.vuepress/public/favicon.ico deleted file mode 100644 index b854b21bb03af..0000000000000 Binary files a/docs/docs/.vuepress/public/favicon.ico and /dev/null differ diff --git a/docs/docs/.vuepress/public/pipedream.svg b/docs/docs/.vuepress/public/pipedream.svg deleted file mode 100644 index ca61e0c2d013e..0000000000000 --- a/docs/docs/.vuepress/public/pipedream.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/docs/docs/.vuepress/styles/index.styl b/docs/docs/.vuepress/styles/index.styl deleted file mode 100644 index a06ac76a0b8bc..0000000000000 --- a/docs/docs/.vuepress/styles/index.styl +++ /dev/null @@ -1,98 +0,0 @@ -@require '~vuepress-plugin-tabs/dist/themes/default.styl' - -body - font-family system-ui,BlinkMacSystemFont,-apple-system, sans-serif, Helvetica, Roboto, "Helvetica Neue", Arial, sans-serif - -$hoverColor = #34d28b -$borderColor = #fff -$bgColor = #fff -$sidebarColor = #000 -$headerColor = #343c56 -$textColor = rgba(0,0,0,.84) -$primaryColor = green; - -html, -body, -.navbar, -.sidebar, -.navbar .links, -.theme-container .navbar, -.theme-container .sidebar - background-color $bgColor - -body .content .default - color $textColor - -.nav-item - color: $headerColor - - @media (max-width: 719px) - color $headerColor - -.nav-item a:hover - color: $hoverColor - - @media (max-width: 719px) - color $hoverColor - -div .sidebar-button svg - color: $sidebarColor - -.navbar .site-name - color $sidebarColor - margin-left: -25px - margin-top: 1px - -p, ul:not(ul ul, ul ol), ol:not(ol ul, ol ol) { - display: block - margin-block-start: 1em - margin-block-end: 1em - margin-inline-start: 0px - margin-inline-end: 0px -} - -*:not(li)>ul { - margin-top: 1em; -} - -/** - * Copy code to clipboard style fixes - */ -.code-copy { - width: 0; - height: 0; - overflow-y: hidden; -} - - -/** - * Fix margin bottom spacing on tips with li's - */ -.custom-block li:last-of-type { - margin-bottom: 1rem; -} - - - -.pd-copy-workflow { - background-color: #35d28b; - size: 1em; - padding: 0.5em 1em 0.5em 1em; - color: #fff; - - display: inline-flex; - align-items: center; - font-weight: 800; - text-decoration: none !important; - - img { - display: inline-block; - } - - border-bottom: none !important; -} - -.pd-copy-workflow:hover { - text-decoration: none !important; - color: #fff !important; -} diff --git a/docs/docs/.vuepress/theme/LICENSE b/docs/docs/.vuepress/theme/LICENSE deleted file mode 100644 index 15f1f7e7a490f..0000000000000 --- a/docs/docs/.vuepress/theme/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018-present, Yuxi (Evan) You - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/docs/docs/.vuepress/theme/components/AlgoliaSearchBox.vue b/docs/docs/.vuepress/theme/components/AlgoliaSearchBox.vue deleted file mode 100644 index 7b2a5807cfbe8..0000000000000 --- a/docs/docs/.vuepress/theme/components/AlgoliaSearchBox.vue +++ /dev/null @@ -1,171 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/theme/components/DropdownLink.vue b/docs/docs/.vuepress/theme/components/DropdownLink.vue deleted file mode 100644 index 4b659a1ffbf1e..0000000000000 --- a/docs/docs/.vuepress/theme/components/DropdownLink.vue +++ /dev/null @@ -1,266 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/theme/components/DropdownTransition.vue b/docs/docs/.vuepress/theme/components/DropdownTransition.vue deleted file mode 100644 index eeaf12b5c3e41..0000000000000 --- a/docs/docs/.vuepress/theme/components/DropdownTransition.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/theme/components/Home.vue b/docs/docs/.vuepress/theme/components/Home.vue deleted file mode 100644 index 8cc0519bc96a4..0000000000000 --- a/docs/docs/.vuepress/theme/components/Home.vue +++ /dev/null @@ -1,175 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/theme/components/NavLink.vue b/docs/docs/.vuepress/theme/components/NavLink.vue deleted file mode 100644 index b2c1ae2be4f71..0000000000000 --- a/docs/docs/.vuepress/theme/components/NavLink.vue +++ /dev/null @@ -1,100 +0,0 @@ - - - diff --git a/docs/docs/.vuepress/theme/components/NavLinks.vue b/docs/docs/.vuepress/theme/components/NavLinks.vue deleted file mode 100644 index bdf1fd3a5d94b..0000000000000 --- a/docs/docs/.vuepress/theme/components/NavLinks.vue +++ /dev/null @@ -1,188 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/theme/components/Navbar.vue b/docs/docs/.vuepress/theme/components/Navbar.vue deleted file mode 100644 index d099067459bfc..0000000000000 --- a/docs/docs/.vuepress/theme/components/Navbar.vue +++ /dev/null @@ -1,184 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/theme/components/NavbarGrid.vue b/docs/docs/.vuepress/theme/components/NavbarGrid.vue deleted file mode 100644 index c4d34d4970986..0000000000000 --- a/docs/docs/.vuepress/theme/components/NavbarGrid.vue +++ /dev/null @@ -1,112 +0,0 @@ - - - - diff --git a/docs/docs/.vuepress/theme/components/Page.vue b/docs/docs/.vuepress/theme/components/Page.vue deleted file mode 100644 index ee548f50e8094..0000000000000 --- a/docs/docs/.vuepress/theme/components/Page.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/theme/components/PageEdit.vue b/docs/docs/.vuepress/theme/components/PageEdit.vue deleted file mode 100644 index de5c39ae650ec..0000000000000 --- a/docs/docs/.vuepress/theme/components/PageEdit.vue +++ /dev/null @@ -1,166 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/theme/components/PageNav.vue b/docs/docs/.vuepress/theme/components/PageNav.vue deleted file mode 100644 index 4c19aae5f88bd..0000000000000 --- a/docs/docs/.vuepress/theme/components/PageNav.vue +++ /dev/null @@ -1,163 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/theme/components/Sidebar.vue b/docs/docs/.vuepress/theme/components/Sidebar.vue deleted file mode 100644 index 93aaff28bd4fa..0000000000000 --- a/docs/docs/.vuepress/theme/components/Sidebar.vue +++ /dev/null @@ -1,89 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/theme/components/SidebarButton.vue b/docs/docs/.vuepress/theme/components/SidebarButton.vue deleted file mode 100644 index 3f54afd5590e0..0000000000000 --- a/docs/docs/.vuepress/theme/components/SidebarButton.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - diff --git a/docs/docs/.vuepress/theme/components/SidebarGroup.vue b/docs/docs/.vuepress/theme/components/SidebarGroup.vue deleted file mode 100644 index d7f192946aed9..0000000000000 --- a/docs/docs/.vuepress/theme/components/SidebarGroup.vue +++ /dev/null @@ -1,141 +0,0 @@ - - - - - diff --git a/docs/docs/.vuepress/theme/components/SidebarLink.vue b/docs/docs/.vuepress/theme/components/SidebarLink.vue deleted file mode 100644 index ec1be898cdb11..0000000000000 --- a/docs/docs/.vuepress/theme/components/SidebarLink.vue +++ /dev/null @@ -1,158 +0,0 @@ - - - diff --git a/docs/docs/.vuepress/theme/components/SidebarLinks.vue b/docs/docs/.vuepress/theme/components/SidebarLinks.vue deleted file mode 100644 index 1096358b001e0..0000000000000 --- a/docs/docs/.vuepress/theme/components/SidebarLinks.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - diff --git a/docs/docs/.vuepress/theme/components/svgs/code-icon.vue b/docs/docs/.vuepress/theme/components/svgs/code-icon.vue deleted file mode 100644 index bf29a02c477f6..0000000000000 --- a/docs/docs/.vuepress/theme/components/svgs/code-icon.vue +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/docs/docs/.vuepress/theme/components/svgs/component-icon.vue b/docs/docs/.vuepress/theme/components/svgs/component-icon.vue deleted file mode 100644 index 74728ed7d7c6c..0000000000000 --- a/docs/docs/.vuepress/theme/components/svgs/component-icon.vue +++ /dev/null @@ -1,19 +0,0 @@ - - diff --git a/docs/docs/.vuepress/theme/components/svgs/integration-icon.vue b/docs/docs/.vuepress/theme/components/svgs/integration-icon.vue deleted file mode 100644 index 003249d2bcca7..0000000000000 --- a/docs/docs/.vuepress/theme/components/svgs/integration-icon.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/docs/docs/.vuepress/theme/components/svgs/step-icon.vue b/docs/docs/.vuepress/theme/components/svgs/step-icon.vue deleted file mode 100644 index 6f5aaddcf64ad..0000000000000 --- a/docs/docs/.vuepress/theme/components/svgs/step-icon.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/docs/docs/.vuepress/theme/components/svgs/trigger-icon.vue b/docs/docs/.vuepress/theme/components/svgs/trigger-icon.vue deleted file mode 100644 index bcc707b7a74fe..0000000000000 --- a/docs/docs/.vuepress/theme/components/svgs/trigger-icon.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/docs/docs/.vuepress/theme/components/svgs/workflow-icon.vue b/docs/docs/.vuepress/theme/components/svgs/workflow-icon.vue deleted file mode 100644 index 8bd7a425e213e..0000000000000 --- a/docs/docs/.vuepress/theme/components/svgs/workflow-icon.vue +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/docs/docs/.vuepress/theme/global-components/Badge.vue b/docs/docs/.vuepress/theme/global-components/Badge.vue deleted file mode 100644 index 53951f9d505df..0000000000000 --- a/docs/docs/.vuepress/theme/global-components/Badge.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - diff --git a/docs/docs/.vuepress/theme/index.js b/docs/docs/.vuepress/theme/index.js deleted file mode 100644 index baaf102ba7767..0000000000000 --- a/docs/docs/.vuepress/theme/index.js +++ /dev/null @@ -1,59 +0,0 @@ -const path = require('path') - -// Theme API. -module.exports = (options, ctx) => { - const { themeConfig, siteConfig } = ctx - - // resolve algolia - const isAlgoliaSearch = ( - themeConfig.algolia - || Object - .keys(siteConfig.locales && themeConfig.locales || {}) - .some(base => themeConfig.locales[base].algolia) - ) - - const enableSmoothScroll = themeConfig.smoothScroll === true - - return { - alias () { - return { - '@AlgoliaSearchBox': isAlgoliaSearch - ? path.resolve(__dirname, 'components/AlgoliaSearchBox.vue') - : path.resolve(__dirname, 'noopModule.js') - } - }, - - plugins: [ - ['@vuepress/active-header-links', options.activeHeaderLinks], - '@vuepress/search', - '@vuepress/plugin-nprogress', - ['container', { - type: 'tip', - defaultTitle: { - '/': 'TIP', - '/zh/': '提示' - } - }], - ['container', { - type: 'warning', - defaultTitle: { - '/': 'WARNING', - '/zh/': '注意' - } - }], - ['container', { - type: 'danger', - defaultTitle: { - '/': 'WARNING', - '/zh/': '警告' - } - }], - ['container', { - type: 'details', - before: info => `
${info ? `${info}` : ''}\n`, - after: () => '
\n' - }], - ['smooth-scroll', enableSmoothScroll] - ] - } -} diff --git a/docs/docs/.vuepress/theme/layouts/404.vue b/docs/docs/.vuepress/theme/layouts/404.vue deleted file mode 100644 index 2cbfa0f179572..0000000000000 --- a/docs/docs/.vuepress/theme/layouts/404.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/docs/docs/.vuepress/theme/layouts/Layout.vue b/docs/docs/.vuepress/theme/layouts/Layout.vue deleted file mode 100644 index 3298070997d0c..0000000000000 --- a/docs/docs/.vuepress/theme/layouts/Layout.vue +++ /dev/null @@ -1,151 +0,0 @@ - - - diff --git a/docs/docs/.vuepress/theme/noopModule.js b/docs/docs/.vuepress/theme/noopModule.js deleted file mode 100644 index b1c6ea436a540..0000000000000 --- a/docs/docs/.vuepress/theme/noopModule.js +++ /dev/null @@ -1 +0,0 @@ -export default {} diff --git a/docs/docs/.vuepress/theme/styles/arrow.styl b/docs/docs/.vuepress/theme/styles/arrow.styl deleted file mode 100644 index 20bffc0dc8733..0000000000000 --- a/docs/docs/.vuepress/theme/styles/arrow.styl +++ /dev/null @@ -1,22 +0,0 @@ -@require './config' - -.arrow - display inline-block - width 0 - height 0 - &.up - border-left 4px solid transparent - border-right 4px solid transparent - border-bottom 6px solid $arrowBgColor - &.down - border-left 4px solid transparent - border-right 4px solid transparent - border-top 6px solid $arrowBgColor - &.right - border-top 4px solid transparent - border-bottom 4px solid transparent - border-left 6px solid $arrowBgColor - &.left - border-top 4px solid transparent - border-bottom 4px solid transparent - border-right 6px solid $arrowBgColor diff --git a/docs/docs/.vuepress/theme/styles/code.styl b/docs/docs/.vuepress/theme/styles/code.styl deleted file mode 100644 index 9d3aa9a54130c..0000000000000 --- a/docs/docs/.vuepress/theme/styles/code.styl +++ /dev/null @@ -1,137 +0,0 @@ -{$contentClass} - code - color lighten($textColor, 20%) - padding 0.25rem 0.5rem - margin 0 - font-size 0.85em - background-color rgba(27,31,35,0.05) - border-radius 3px - .token - &.deleted - color #EC5975 - &.inserted - color $accentColor - -{$contentClass} - pre, pre[class*="language-"] - line-height 1.4 - padding 1.25rem 1.5rem - margin 0.85rem 0 - background-color $codeBgColor - border-radius 6px - overflow auto - code - color #fff - padding 0 - background-color transparent - border-radius 0 - -div[class*="language-"] - position relative - background-color $codeBgColor - border-radius 6px - .highlight-lines - user-select none - padding-top 1.3rem - position absolute - top 0 - left 0 - width 100% - line-height 1.4 - .highlighted - background-color rgba(0, 0, 0, 66%) - pre, pre[class*="language-"] - background transparent - position relative - z-index 1 - &::before - position absolute - z-index 3 - top 0.8em - right 1em - font-size 0.75rem - color rgba(255, 255, 255, 0.4) - &:not(.line-numbers-mode) - .line-numbers-wrapper - display none - &.line-numbers-mode - .highlight-lines .highlighted - position relative - &:before - content ' ' - position absolute - z-index 3 - left 0 - top 0 - display block - width $lineNumbersWrapperWidth - height 100% - background-color rgba(0, 0, 0, 66%) - pre - padding-left $lineNumbersWrapperWidth + 1 rem - vertical-align middle - .line-numbers-wrapper - position absolute - top 0 - width $lineNumbersWrapperWidth - text-align center - color rgba(255, 255, 255, 0.3) - padding 1.25rem 0 - line-height 1.4 - br - user-select none - .line-number - position relative - z-index 4 - user-select none - font-size 0.85em - &::after - content '' - position absolute - z-index 2 - top 0 - left 0 - width $lineNumbersWrapperWidth - height 100% - border-radius 6px 0 0 6px - border-right 1px solid rgba(0, 0, 0, 66%) - background-color $codeBgColor - - -for lang in $codeLang - div{'[class~="language-' + lang + '"]'} - &:before - content ('' + lang) - -div[class~="language-javascript"] - &:before - content "js" - -div[class~="language-typescript"] - &:before - content "ts" - -div[class~="language-markup"] - &:before - content "html" - -div[class~="language-markdown"] - &:before - content "md" - -div[class~="language-json"]:before - content "json" - -div[class~="language-ruby"]:before - content "rb" - -div[class~="language-python"]:before - content "py" - -div[class~="language-bash"]:before - content "sh" - -div[class~="language-php"]:before - content "php" - -@import '~prismjs/themes/prism-tomorrow.css' diff --git a/docs/docs/.vuepress/theme/styles/config.styl b/docs/docs/.vuepress/theme/styles/config.styl deleted file mode 100644 index 9e403210fd385..0000000000000 --- a/docs/docs/.vuepress/theme/styles/config.styl +++ /dev/null @@ -1 +0,0 @@ -$contentClass = '.theme-default-content' diff --git a/docs/docs/.vuepress/theme/styles/custom-blocks.styl b/docs/docs/.vuepress/theme/styles/custom-blocks.styl deleted file mode 100644 index 5b868166a434c..0000000000000 --- a/docs/docs/.vuepress/theme/styles/custom-blocks.styl +++ /dev/null @@ -1,44 +0,0 @@ -.custom-block - .custom-block-title - font-weight 600 - margin-bottom -0.4rem - &.tip, &.warning, &.danger - padding .1rem 1.5rem - border-left-width .5rem - border-left-style solid - margin 1rem 0 - &.tip - background-color #f3f5f7 - border-color #42b983 - &.warning - background-color rgba(255,229,100,.3) - border-color darken(#ffe564, 35%) - color darken(#ffe564, 70%) - .custom-block-title - color darken(#ffe564, 50%) - a - color $textColor - &.danger - background-color #ffe6e6 - border-color darken(red, 20%) - color darken(red, 70%) - .custom-block-title - color darken(red, 40%) - a - color $textColor - &.details - display block - position relative - border-radius 2px - margin 1.6em 0 - padding 1.6em - background-color #eee - h4 - margin-top 0 - figure, p - &:last-child - margin-bottom 0 - padding-bottom 0 - summary - outline none - cursor pointer diff --git a/docs/docs/.vuepress/theme/styles/index.styl b/docs/docs/.vuepress/theme/styles/index.styl deleted file mode 100644 index 7ad6e8f6e44c3..0000000000000 --- a/docs/docs/.vuepress/theme/styles/index.styl +++ /dev/null @@ -1,214 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -@layer base { - ul, ol { - list-style: revert; - } -} - -@require './config' -@require './code' -@require './custom-blocks' -@require './arrow' -@require './wrapper' -@require './toc' -@require './navbar' - -html, body - padding 0 - margin 0 - background-color #fff - -body - font-family -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif - -webkit-font-smoothing antialiased - -moz-osx-font-smoothing grayscale - font-size 16px - color $textColor - -.page - padding-left $sidebarWidth - -.navbar - display flex - justify-content space-between - position fixed - z-index 20 - top 0 - left 0 - right 0 - height $navbarHeight - background-color #fff - box-sizing border-box - border-bottom 1px solid $borderColor - -.sidebar-mask - position fixed - z-index 9 - top 0 - left 0 - width 100vw - height 100vh - display none - -.sidebar - font-size 16px - background-color #fff - width $sidebarWidth - position fixed - z-index 10 - margin 0 - top $navbarHeight - left 0 - bottom 0 - box-sizing border-box - border-right 1px solid $borderColor - overflow-y auto - -{$contentClass}:not(.custom) - @extend $wrapper - > *:first-child - margin-top $navbarHeight - - a:hover - text-decoration underline - - p.demo - padding 1rem 1.5rem - border 1px solid #ddd - border-radius 4px - - img - max-width 100% - -{$contentClass}.custom - padding 0 - margin 0 - - img - max-width 100% - -a - font-weight 500 - color $accentColor - text-decoration none - -p a code - font-weight 400 - color $accentColor - -kbd - background #eee - border solid 0.15rem #ddd - border-bottom solid 0.25rem #ddd - border-radius 0.15rem - padding 0 0.15em - -blockquote - font-size 1rem - color #999; - border-left .2rem solid #dfe2e5 - margin 1rem 0 - padding .25rem 0 .25rem 1rem - - & > p - margin 0 - -ul, ol - padding-left 1.2em - -strong - font-weight 600 - -h1, h2, h3, h4, h5, h6 - font-weight 600 - line-height 1.25 - - {$contentClass}:not(.custom) > & - margin-top (0.5rem - $navbarHeight) - padding-top ($navbarHeight + 1rem) - margin-bottom 0 - - &:first-child - margin-top -1.5rem - margin-bottom 1rem - - + p, + pre, + .custom-block - margin-top 2rem - - &:hover .header-anchor - opacity: 1 - -h1 - font-size 2.2rem - -h2 - font-size 1.65rem - padding-bottom .3rem - border-bottom 1px solid $borderColor - -h3 - font-size 1.35rem - -a.header-anchor - font-size 0.85em - float left - margin-left -0.87em - padding-right 0.23em - margin-top 0.125em - opacity 0 - - &:hover - text-decoration none - -code, kbd, .line-number - font-family source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace - -p, ul, ol - line-height 1.7 - -hr - border 0 - border-top 1px solid $borderColor - -table - border-collapse collapse - margin 1rem 0 - display: block - overflow-x: auto - -tr - border-top 1px solid #dfe2e5 - - &:nth-child(2n) - background-color #f6f8fa - -th, td - border 1px solid #dfe2e5 - padding .6em 1em - -.theme-container - &.sidebar-open - .sidebar-mask - display: block - - &.no-navbar - {$contentClass}:not(.custom) > h1, h2, h3, h4, h5, h6 - margin-top 1.5rem - padding-top 0 - - .sidebar - top 0 - - -@media (min-width: ($MQMobile + 1px)) - .theme-container.no-sidebar - .sidebar - display none - - .page - padding-left 0 - -@require 'mobile.styl' diff --git a/docs/docs/.vuepress/theme/styles/mobile.styl b/docs/docs/.vuepress/theme/styles/mobile.styl deleted file mode 100644 index f5bd32739d774..0000000000000 --- a/docs/docs/.vuepress/theme/styles/mobile.styl +++ /dev/null @@ -1,37 +0,0 @@ -@require './config' - -$mobileSidebarWidth = $sidebarWidth * 0.82 - -// narrow desktop / iPad -@media (max-width: $MQNarrow) - .sidebar - font-size 15px - width $mobileSidebarWidth - .page - padding-left $mobileSidebarWidth - -// wide mobile -@media (max-width: $MQMobile) - .sidebar - top 0 - padding-top $navbarHeight - transform translateX(-100%) - transition transform .2s ease - .page - padding-left 0 - .theme-container - &.sidebar-open - .sidebar - transform translateX(0) - &.no-navbar - .sidebar - padding-top: 0 - -// narrow mobile -@media (max-width: $MQMobileNarrow) - h1 - font-size 1.9rem - {$contentClass} - div[class*="language-"] - margin 0.85rem -1.5rem - border-radius 0 diff --git a/docs/docs/.vuepress/theme/styles/navbar.styl b/docs/docs/.vuepress/theme/styles/navbar.styl deleted file mode 100644 index 597ecd80c0f26..0000000000000 --- a/docs/docs/.vuepress/theme/styles/navbar.styl +++ /dev/null @@ -1,34 +0,0 @@ -.nav-link - .badge - font-size: 0.8em - font-weight: 800 - text-transform: uppercase - - // generated from https://www.cssportal.com/css-text-gradient-generator/ - .primary - background: #3EAF7C; - background: -webkit-linear-gradient(to right, #3EAF7C 25%, #8F33B5 100%); - background: -moz-linear-gradient(to right, #3EAF7C 25%, #8F33B5 100%); - background: linear-gradient(to right, #3EAF7C 25%, #8F33B5 100%); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - -.nav-link.primary - color: #3EAF7C; - // color: #fff - // padding: 0.6em; - // border-radius: 0.375em; - -.nav-link.primary:hover - // text-decoration: none; - // border-bottom: none !important; - // margin-bottom: auto !important; - // color: #fff !important; - -.nav-link.primary:visited - // text-decoration: none; - // border-bottom: none !important; - // margin-bottom: auto !important; - // color: #fff !important; - - diff --git a/docs/docs/.vuepress/theme/styles/toc.styl b/docs/docs/.vuepress/theme/styles/toc.styl deleted file mode 100644 index d3e71069ba79f..0000000000000 --- a/docs/docs/.vuepress/theme/styles/toc.styl +++ /dev/null @@ -1,3 +0,0 @@ -.table-of-contents - .badge - vertical-align middle diff --git a/docs/docs/.vuepress/theme/styles/wrapper.styl b/docs/docs/.vuepress/theme/styles/wrapper.styl deleted file mode 100644 index a99262c71ab37..0000000000000 --- a/docs/docs/.vuepress/theme/styles/wrapper.styl +++ /dev/null @@ -1,9 +0,0 @@ -$wrapper - max-width $contentWidth - margin 0 auto - padding 2rem 2.5rem - @media (max-width: $MQNarrow) - padding 2rem - @media (max-width: $MQMobileNarrow) - padding 1.5rem - diff --git a/docs/docs/.vuepress/theme/util/index.js b/docs/docs/.vuepress/theme/util/index.js deleted file mode 100644 index 92fcd3b311af4..0000000000000 --- a/docs/docs/.vuepress/theme/util/index.js +++ /dev/null @@ -1,244 +0,0 @@ -export const hashRE = /#.*$/ -export const extRE = /\.(md|html)$/ -export const endingSlashRE = /\/$/ -export const outboundRE = /^[a-z]+:/i - -export function normalize (path) { - return decodeURI(path) - .replace(hashRE, '') - .replace(extRE, '') -} - -export function getHash (path) { - const match = path.match(hashRE) - if (match) { - return match[0] - } -} - -export function isExternal (path) { - return outboundRE.test(path) -} - -export function isMailto (path) { - return /^mailto:/.test(path) -} - -export function isTel (path) { - return /^tel:/.test(path) -} - -export function ensureExt (path) { - if (isExternal(path)) { - return path - } - const hashMatch = path.match(hashRE) - const hash = hashMatch ? hashMatch[0] : '' - const normalized = normalize(path) - - if (endingSlashRE.test(normalized)) { - return path - } - return normalized + '.html' + hash -} - -export function isActive (route, path) { - const routeHash = decodeURIComponent(route.hash) - const linkHash = getHash(path) - if (linkHash && routeHash !== linkHash) { - return false - } - const routePath = normalize(route.path) - const pagePath = normalize(path) - return routePath === pagePath -} - -export function resolvePage (pages, rawPath, base) { - if (isExternal(rawPath)) { - return { - type: 'external', - path: rawPath - } - } - if (base) { - rawPath = resolvePath(rawPath, base) - } - const path = normalize(rawPath) - for (let i = 0; i < pages.length; i++) { - if (normalize(pages[i].regularPath) === path) { - return Object.assign({}, pages[i], { - type: 'page', - path: ensureExt(pages[i].path) - }) - } - } - console.error(`[vuepress] No matching page found for sidebar item "${rawPath}"`) - return {} -} - -function resolvePath (relative, base, append) { - const firstChar = relative.charAt(0) - if (firstChar === '/') { - return relative - } - - if (firstChar === '?' || firstChar === '#') { - return base + relative - } - - const stack = base.split('/') - - // remove trailing segment if: - // - not appending - // - appending to trailing slash (last segment is empty) - if (!append || !stack[stack.length - 1]) { - stack.pop() - } - - // resolve relative path - const segments = relative.replace(/^\//, '').split('/') - for (let i = 0; i < segments.length; i++) { - const segment = segments[i] - if (segment === '..') { - stack.pop() - } else if (segment !== '.') { - stack.push(segment) - } - } - - // ensure leading slash - if (stack[0] !== '') { - stack.unshift('') - } - - return stack.join('/') -} - -/** - * @param { Page } page - * @param { string } regularPath - * @param { SiteData } site - * @param { string } localePath - * @returns { SidebarGroup } - */ -export function resolveSidebarItems (page, regularPath, site, localePath) { - const { pages, themeConfig } = site - - const localeConfig = localePath && themeConfig.locales - ? themeConfig.locales[localePath] || themeConfig - : themeConfig - - const pageSidebarConfig = page.frontmatter.sidebar || localeConfig.sidebar || themeConfig.sidebar - if (pageSidebarConfig === 'auto') { - return resolveHeaders(page) - } - - const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar - if (!sidebarConfig) { - return [] - } else { - const { base, config } = resolveMatchingConfig(regularPath, sidebarConfig) - if (config === 'auto') { - return resolveHeaders(page) - } - return config - ? config.map(item => resolveItem(item, pages, base)) - : [] - } -} - -/** - * @param { Page } page - * @returns { SidebarGroup } - */ -function resolveHeaders (page) { - const headers = groupHeaders(page.headers || []) - return [{ - type: 'group', - collapsable: false, - title: page.title, - path: null, - children: headers.map(h => ({ - type: 'auto', - title: h.title, - basePath: page.path, - path: page.path + '#' + h.slug, - children: h.children || [] - })) - }] -} - -export function groupHeaders (headers) { - // group h3s under h2 - headers = headers.map(h => Object.assign({}, h)) - let lastH2 - headers.forEach(h => { - if (h.level === 2) { - lastH2 = h - } else if (lastH2) { - (lastH2.children || (lastH2.children = [])).push(h) - } - }) - return headers.filter(h => h.level === 2) -} - -export function resolveNavLinkItem (linkItem) { - return Object.assign(linkItem, { - type: linkItem.items && linkItem.items.length ? 'links' : 'link' - }) -} - -/** - * @param { Route } route - * @param { Array | Array | [link: string]: SidebarConfig } config - * @returns { base: string, config: SidebarConfig } - */ -export function resolveMatchingConfig (regularPath, config) { - if (Array.isArray(config)) { - return { - base: '/', - config: config - } - } - for (const base in config) { - if (ensureEndingSlash(regularPath).indexOf(encodeURI(base)) === 0) { - return { - base, - config: config[base] - } - } - } - return {} -} - -function ensureEndingSlash (path) { - return /(\.html|\/)$/.test(path) - ? path - : path + '/' -} - -function resolveItem (item, pages, base, groupDepth = 1) { - if (typeof item === 'string') { - return resolvePage(pages, item, base) - } else if (Array.isArray(item)) { - return Object.assign(resolvePage(pages, item[0], base), { - title: item[1] - }) - } else { - const children = item.children || [] - if (children.length === 0 && item.path) { - return Object.assign(resolvePage(pages, item.path, base), { - title: item.title - }) - } - return { - type: 'group', - path: item.path, - title: item.title, - sidebarDepth: item.sidebarDepth, - initialOpenGroupIndex: item.initialOpenGroupIndex, - children: children.map(child => resolveItem(child, pages, base, groupDepth + 1)), - collapsable: item.collapsable !== false - } - } -} diff --git a/docs/docs/README.md b/docs/docs/README.md deleted file mode 100644 index f74adc328c81b..0000000000000 --- a/docs/docs/README.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -prev: false -next: false ---- - -# Introduction to Pipedream - -Pipedream is the fastest way to automate any process that connects APIs. Build and run workflows with code-level control when you need it, and no code when you don't. - -The Pipedream platform includes: - -- A [serverless runtime](/code/) and [workflow service](/workflows/) -- Source-available [triggers](/workflows/steps/triggers/) and [actions](/workflows/steps/actions/) for [hundreds of integrated apps](https://pipedream.com/explore/) -- One-click [OAuth and key-based authentication](/connected-accounts/) for more than 1000 APIs (use tokens directly in code or with pre-built actions) - -Watch a demo or review our [quickstart guide](/quickstart/): - - - -## Getting Started - -To get started, [sign up for a free account](https://pipedream.com/auth/signup) (no credit card required) and follow our [quickstart guide](/quickstart/) to create your first workflow. - -![build, test,deploy](https://res.cloudinary.com/pipedreamin/image/upload/v1672810771/mjckfcgsoxs4vccutdbj.png) - -Once you understand the basics of workflow development, learn how to get more out of Pipedream: - -- [Use code in workflows](/code/) -- [Develop custom actions](/components/quickstart/nodejs/actions/) -- [Develop custom triggers](/components/quickstart/nodejs/sources/) - -## Use Cases - -Pipedream supports use cases from prototype to production and is trusted by 200k+ developers from startups to Fortune 500 companies: - -![logos](https://res.cloudinary.com/pipedreamin/image/upload/v1612919944/homepage/logos_kcbviz.png) - -The platform processes billions of events and is built and [priced](https://pipedream.com/pricing/) for use at scale. [Our team](https://pipedream.com/about) has built internet scale applications and managed data pipelines in excess of 10 million events per second (EPS) at startups and high-growth environments like BrightRoll, Yahoo!, Affirm and Instacart. - -Our [community](https://pipedream.com/community) uses Pipedream for a wide variety of use cases including: - -- Connecting SaaS apps -- General API orchestration and automation -- Database automations ([reach out](https://pipedream.com/community) to learn about connecting to resources behind a firewall) -- Custom notifications and alerting -- Mobile and JAMstack backends -- Rate limiting, request smoothing -- Event queueing and concurrency management -- Webhook inspection and routing -- Prototyping and demos - -## Source-available - -Pipedream maintains a [source-available component registry](https://github.com/pipedreamhq/pipedream/) on GitHub so you can avoid writing boilerplate code for common API integrations. Use components as no code building blocks in workflows, or use them to scaffold code that you can customize. You can also [create a PR to contribute new components](/apps/contributing/#contribution-process) via GitHub. - -## Contributing - -We hope is that by providing a generous free tier, you will not only get value from Pipedream, but you will give back to help us improve the product for the entire community and grow the platform by: - -- [Contributing components](/apps/contributing/) to the [Pipedream registry](https://github.com/pipedreamhq/pipedream) or sharing via your own GitHub repo -- Asking and answering questions in our [public community](https://pipedream.com/community/) -- [Reporting bugs](https://pipedream.com/community/c/bugs/9) and [requesting features](https://github.com/PipedreamHQ/pipedream/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=%5BFEATURE%5D+) that help us build a better product -- Following us on [Twitter](https://twitter.com/pipedream), starring our [GitHub repo](https://github.com/PipedreamHQ/pipedream) and subscribing to our [YouTube channel](https://www.youtube.com/c/pipedreamhq) -- Recommending us to your friends and colleagues - -Learn about [all the ways you can contribute](https://pipedream.com/contributing). - -## Support & Community - -If you have any questions or feedback, please [reach out in our community forum](https://pipedream.com/community). - -## Service Status - -Pipedream operates a status page at [https://status.pipedream.com](https://status.pipedream.com). That page displays the uptime history and current status of every Pipedream service. - -When incidents occur, updates are published to the **#incidents** channel of [Pipedream's Slack Community](https://pipedream.com/support) and to the [@PipedreamStatus](https://twitter.com/PipedreamStatus) account on Twitter. On the status page itself, you can also subscribe to updates directly. diff --git a/docs/docs/abuse/README.md b/docs/docs/abuse/README.md deleted file mode 100644 index decaf96031cb8..0000000000000 --- a/docs/docs/abuse/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Reporting abuse - -If you suspect Pipedream resources are being used for illegal purposes, or otherwise violate [the Pipedream Terms](https://pipedream.com/terms), please reach out to abuse@pipedream.com. - -In your abuse report, please provide as many details as possible, including: - -- The specific issue you're seeing, and what date / time it started / you observed it. -- Relevant Pipedream resources involved in the abuse, for example: the HTTP endpoint to which traffic is being sent. -- Any logs / code involved in the abuse. For example, if you're encountering a Denial-of-service attack, please include any HTTP / networking logs related to the issue. If you're reporting malware that exfiltrates data to Pipedream, please include relevant code from that malware or links to relevant reports. \ No newline at end of file diff --git a/docs/docs/airtable/oauth-migration-2024-02/README.md b/docs/docs/airtable/oauth-migration-2024-02/README.md deleted file mode 100644 index e8657ebf14970..0000000000000 --- a/docs/docs/airtable/oauth-migration-2024-02/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# Update to the Airtable Integration on Pipedream (January 2024) - -Effective February 1st 2024, Airtable's API Key authentication method will be deprecated. To learn more about this change, please visit Airtable’s [dedicated support page](https://support.airtable.com/docs/airtable-api-key-deprecation-notice). - -### How will this impact my workflows? - -Starting February 1st 2024, all Pipedream steps using the legacy Airtable (API Key) integration including triggers and actions will no longer be able to authenticate with Airtable. - -### What do I need to do? -
- -1. **Reconnect your Airtable account**: - -- Visit the [accounts page in Pipedream](https://pipedream.com/accounts) -- Search for Airtable and connect your account -- This newer Pipedream integration uses OAuth instead of an API Key - -![Airtable Account Connection](https://res.cloudinary.com/dpenc2lit/image/upload/v1704392183/Screenshot_2024-01-04_at_10.16.12_AM_le364k.png) - -You can determine which workflows are connected to the legacy Airtable (API Key) app by expanding the account row on your Airtable (API Key) account connection. -![Airtable Accounts](https://res.cloudinary.com/dpenc2lit/image/upload/v1704347928/Screenshot_2024-01-03_at_9.58.43_PM_haaqlb.png) - -2. **Update Your Workflows**: - -- After reconnecting to Airtable via OAuth, you'll need to update your existing workflows that use the legacy Airtable app. -- Remove any legacy Airtable sources and re-add the source using the new Airtable app -- Remove any legacy Airtable actions and re-add them using the new Airtable app - -
- -3. **If you're using Airtable in code:** - -- Change any of your code steps to reference `airtable_oauth` instead of `airtable`. -- Modify your authorization headers accordingly - -In Node.js, you would modify your authorization header from this: - - `"Authorization": ${this.airtable.$auth.api_key}` - - to - -``` Authorization: `Bearer ${this.airtable_oauth.$auth.oauth_access_token}` ``` - -This is what your Node.js code step may have looked like before: - -``` javascript -import { axios } from "@pipedream/platform" -export default defineComponent({ - props: { - airtable: { - type: "app", - app: "airtable", - } - }, - async run({steps, $}) { - return await axios($, { - url: `https://api.airtable.com/v0/meta/whoami`, - headers: { - "Authorization": `${this.airtable.$auth.api_key}`, - "Content-Type": `application/json`, - }, - }) - }, -}) - -``` - -And here's an example of the updated code step that uses the updated app, **`airtable_oauth`** instead with the updated authentication method: - -``` javascript -import { axios } from "@pipedream/platform" -export default defineComponent({ - props: { - airtable_oauth: { - type: "app", - app: "airtable_oauth", - } - }, - async run({steps, $}) { - return await axios($, { - url: `https://api.airtable.com/v0/meta/whoami`, - headers: { - Authorization: `Bearer ${this.airtable_oauth.$auth.oauth_access_token}`, - }, - }) - }, -}) - -``` - -In Python, here's a snippet of what your code step might have looked like before: -``` python -def handler(pd: "pipedream"): - headers = {"X-Airtable-Api-Key": f'{pd.inputs["airtable"]["$auth"]["api_key"]}'} -``` - -And here's the updated Python code step, with **`airtable_oauth`** and the appropriate token and authorization headers: -``` python -def handler(pd: "pipedream"): - token = f'{pd.inputs["airtable_oauth"]["$auth"]["oauth_access_token"]}' - authorization = f'Bearer {token}' - headers = {"Authorization": authorization} -``` - -3. **Test and redeploy your workflows.** \ No newline at end of file diff --git a/docs/docs/api/README.md b/docs/docs/api/README.md deleted file mode 100644 index 7859f2099e54f..0000000000000 --- a/docs/docs/api/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# API Overview - -Pipedream currently offers [REST](/api/rest/) and [Server-sent Events (SSE)](/api/sse/) APIs. - -- Use the [REST API](/api/rest/) to create and manage sources, workflows, and - events -- Use the [SSE API](/api/sse/) to subscribe to real-time event streams for - sources - -