@jskit-ai/connectors-catalog 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +192 -0
- package/docs/ai-upstream-notices.md +51 -0
- package/docs/ai.md +191 -0
- package/docs/airtable.md +130 -0
- package/docs/algolia.md +190 -0
- package/docs/amazon-redshift.md +229 -0
- package/docs/amplitude.md +210 -0
- package/docs/apify.md +162 -0
- package/docs/apollo-io.md +200 -0
- package/docs/asana.md +126 -0
- package/docs/ashby.md +188 -0
- package/docs/atlassian.md +224 -0
- package/docs/attention.md +162 -0
- package/docs/aws-athena.md +150 -0
- package/docs/aws-credentials.md +75 -0
- package/docs/aws-s3.md +193 -0
- package/docs/bigquery.md +146 -0
- package/docs/brevo.md +122 -0
- package/docs/calendly.md +158 -0
- package/docs/canva.md +191 -0
- package/docs/chargebee.md +192 -0
- package/docs/clay.md +194 -0
- package/docs/clickhouse.md +242 -0
- package/docs/confidence-exp.md +74 -0
- package/docs/confidence-flags.md +75 -0
- package/docs/confidence-oauth.md +137 -0
- package/docs/contentful.md +123 -0
- package/docs/databricks.md +180 -0
- package/docs/dbt-semantic-layer.md +175 -0
- package/docs/elevenlabs.md +102 -0
- package/docs/figma.md +132 -0
- package/docs/firebase-cloud-messaging.md +262 -0
- package/docs/firecrawl.md +137 -0
- package/docs/fireflies.md +95 -0
- package/docs/fireworks-ai.md +53 -0
- package/docs/gatewayapi.md +113 -0
- package/docs/gemini-enterprise.md +224 -0
- package/docs/github-api.md +133 -0
- package/docs/gitlab-api.md +138 -0
- package/docs/gmail.md +133 -0
- package/docs/gong.md +205 -0
- package/docs/google-ads.md +156 -0
- package/docs/google-analytics.md +202 -0
- package/docs/google-docs.md +105 -0
- package/docs/google-drive.md +108 -0
- package/docs/google-maps-platform.md +208 -0
- package/docs/google-oauth.md +123 -0
- package/docs/google-search-console.md +124 -0
- package/docs/google-sheets.md +94 -0
- package/docs/google-slides.md +95 -0
- package/docs/granola.md +178 -0
- package/docs/hex.md +161 -0
- package/docs/heygen.md +124 -0
- package/docs/hubspot.md +142 -0
- package/docs/incident-io.md +118 -0
- package/docs/inngest.md +178 -0
- package/docs/klipy.md +149 -0
- package/docs/lexware.md +144 -0
- package/docs/lightspeed.md +193 -0
- package/docs/linear.md +137 -0
- package/docs/linkedin.md +196 -0
- package/docs/logo-dev.md +152 -0
- package/docs/mailgun.md +153 -0
- package/docs/mapbox.md +174 -0
- package/docs/microsoft-excel.md +97 -0
- package/docs/microsoft-fabric.md +249 -0
- package/docs/microsoft-oauth.md +143 -0
- package/docs/microsoft-onedrive.md +76 -0
- package/docs/microsoft-onenote.md +75 -0
- package/docs/microsoft-outlook.md +90 -0
- package/docs/microsoft-powerpoint.md +119 -0
- package/docs/microsoft-sharepoint.md +75 -0
- package/docs/microsoft-teams.md +72 -0
- package/docs/microsoft-word.md +119 -0
- package/docs/miro.md +117 -0
- package/docs/n8n.md +169 -0
- package/docs/notion.md +137 -0
- package/docs/oura.md +161 -0
- package/docs/paddle.md +168 -0
- package/docs/perplexity.md +85 -0
- package/docs/pipedrive.md +120 -0
- package/docs/polar.md +63 -0
- package/docs/posthog.md +227 -0
- package/docs/prestashop.md +151 -0
- package/docs/replicate.md +60 -0
- package/docs/resend.md +153 -0
- package/docs/salesforce.md +234 -0
- package/docs/sanity.md +122 -0
- package/docs/semrush.md +276 -0
- package/docs/sentry.md +112 -0
- package/docs/sevdesk.md +107 -0
- package/docs/shopify.md +206 -0
- package/docs/slack.md +257 -0
- package/docs/snowflake.md +271 -0
- package/docs/storyblok.md +130 -0
- package/docs/stripe.md +77 -0
- package/docs/supabase.md +51 -0
- package/docs/tally.md +105 -0
- package/docs/telegram.md +165 -0
- package/docs/tiktok.md +201 -0
- package/docs/twilio.md +284 -0
- package/docs/twitch.md +428 -0
- package/docs/wave.md +440 -0
- package/docs/wix.md +1249 -0
- package/docs/wiz.md +177 -0
- package/docs/woocommerce.md +400 -0
- package/docs/wordpress-com.md +358 -0
- package/docs/wordpress-self-hosted.md +252 -0
- package/docs/workday.md +292 -0
- package/docs/x-twitter.md +188 -0
- package/docs/xero.md +429 -0
- package/docs/zoho-books.md +214 -0
- package/docs/zoho-crm.md +192 -0
- package/package.json +153 -0
- package/patterns/ai-connections/PATTERN.md +84 -0
- package/patterns/ai-connections/example/ai-model.js +11 -0
- package/patterns/ai-connections/example/perplexity-answer.js +29 -0
- package/patterns/api-key-connection/PATTERN.md +368 -0
- package/patterns/api-key-connection/example/connections.js +18 -0
- package/patterns/api-key-connection/example/integrations.json +19 -0
- package/patterns/assistant-mcp/PATTERN.md +110 -0
- package/patterns/assistant-mcp/example/integrations.json +13 -0
- package/patterns/assistant-mcp-oauth/PATTERN.md +235 -0
- package/patterns/assistant-mcp-oauth/example/integrations.json +102 -0
- package/patterns/aws-storage-queries/PATTERN.md +169 -0
- package/patterns/aws-storage-queries/example/formats/data-formats.js +35 -0
- package/patterns/aws-storage-queries/example/formats/package-lock.json +49 -0
- package/patterns/aws-storage-queries/example/formats/package.json +12 -0
- package/patterns/aws-storage-queries/example/formats/verify-formats.mjs +37 -0
- package/patterns/aws-storage-queries/example/integrations.json +38 -0
- package/patterns/aws-storage-queries/example/s3-transfer.js +34 -0
- package/patterns/event-delivery/PATTERN.md +151 -0
- package/patterns/event-delivery/example/integrations.json +17 -0
- package/patterns/firebase-messaging/PATTERN.md +156 -0
- package/patterns/firebase-messaging/example/server/notifications.js +23 -0
- package/patterns/google-ads-search/PATTERN.md +92 -0
- package/patterns/google-ads-search/example/ads-setup.js +25 -0
- package/patterns/oauth-connection/PATTERN.md +724 -0
- package/patterns/oauth-connection/example/integrations.json +20 -0
- package/patterns/paddle-catalogue/PATTERN.md +78 -0
- package/patterns/paddle-catalogue/example/create-products.js +38 -0
- package/patterns/public-image/PATTERN.md +84 -0
- package/patterns/public-image/example/integrations.json +13 -0
- package/patterns/public-image/example/logo-url.js +16 -0
- package/patterns/redshift-queries/PATTERN.md +150 -0
- package/patterns/redshift-queries/example/integrations.json +33 -0
- package/patterns/source-scanning/PATTERN.md +83 -0
- package/patterns/source-scanning/example/source-scanner.js +13 -0
- package/src/client/firebase-cloud-messaging.js +10 -0
- package/src/client/google-analytics.js +72 -0
- package/src/client/google-maps-platform.js +39 -0
- package/src/client/logo-dev.js +36 -0
- package/src/server/ai.js +46 -0
- package/src/server/airtable.js +67 -0
- package/src/server/algolia.js +63 -0
- package/src/server/amazon-redshift.js +96 -0
- package/src/server/amplitude.js +31 -0
- package/src/server/apify.js +68 -0
- package/src/server/apollo-io.js +85 -0
- package/src/server/asana.js +64 -0
- package/src/server/ashby.js +61 -0
- package/src/server/atlassian.js +32 -0
- package/src/server/attention.js +93 -0
- package/src/server/aws-athena.js +82 -0
- package/src/server/aws-s3.js +49 -0
- package/src/server/awsTransport.js +75 -0
- package/src/server/bigquery.js +97 -0
- package/src/server/brevo.js +97 -0
- package/src/server/calendly.js +77 -0
- package/src/server/canva.js +13 -0
- package/src/server/chargebee.js +88 -0
- package/src/server/clay.js +78 -0
- package/src/server/clickhouse.js +66 -0
- package/src/server/confidence.js +29 -0
- package/src/server/contentful.js +40 -0
- package/src/server/databricks.js +55 -0
- package/src/server/dbt-semantic-layer.js +95 -0
- package/src/server/elevenlabs.js +81 -0
- package/src/server/figma.js +24 -0
- package/src/server/firebase-cloud-messaging.js +111 -0
- package/src/server/firecrawl.js +70 -0
- package/src/server/fireflies.js +31 -0
- package/src/server/fireworks-ai.js +16 -0
- package/src/server/gatewayapi.js +48 -0
- package/src/server/gemini-enterprise.js +47 -0
- package/src/server/github-api.js +90 -0
- package/src/server/gitlab-api.js +67 -0
- package/src/server/gmail.js +60 -0
- package/src/server/gong.js +52 -0
- package/src/server/google-ads-search.js +134 -0
- package/src/server/google-ads.js +80 -0
- package/src/server/google-docs.js +36 -0
- package/src/server/google-drive.js +71 -0
- package/src/server/google-maps-platform.js +90 -0
- package/src/server/google-search-console.js +31 -0
- package/src/server/google-sheets.js +60 -0
- package/src/server/google-slides.js +36 -0
- package/src/server/google.js +61 -0
- package/src/server/granola.js +115 -0
- package/src/server/graphqlOperation.js +15 -0
- package/src/server/hex.js +29 -0
- package/src/server/heygen.js +54 -0
- package/src/server/hubspot.js +85 -0
- package/src/server/incident-io.js +68 -0
- package/src/server/inngest.js +86 -0
- package/src/server/jsonOperation.js +34 -0
- package/src/server/klipy.js +34 -0
- package/src/server/lexware.js +59 -0
- package/src/server/lightspeed.js +82 -0
- package/src/server/linear.js +52 -0
- package/src/server/linkedin.js +74 -0
- package/src/server/mailgun.js +76 -0
- package/src/server/mapbox.js +46 -0
- package/src/server/mcpRegistration.js +41 -0
- package/src/server/mcpTransport.js +60 -0
- package/src/server/microsoft-excel.js +67 -0
- package/src/server/microsoft-fabric.js +81 -0
- package/src/server/microsoft-onedrive.js +58 -0
- package/src/server/microsoft-onenote.js +52 -0
- package/src/server/microsoft-outlook.js +58 -0
- package/src/server/microsoft-powerpoint.js +5 -0
- package/src/server/microsoft-sharepoint.js +46 -0
- package/src/server/microsoft-teams.js +29 -0
- package/src/server/microsoft-word.js +5 -0
- package/src/server/microsoft.js +88 -0
- package/src/server/miro.js +29 -0
- package/src/server/n8n.js +78 -0
- package/src/server/notion.js +76 -0
- package/src/server/oura.js +48 -0
- package/src/server/paddle.js +83 -0
- package/src/server/perplexity.js +15 -0
- package/src/server/pipedrive.js +95 -0
- package/src/server/polar.js +20 -0
- package/src/server/posthog.js +44 -0
- package/src/server/prestashop.js +42 -0
- package/src/server/replicate.js +42 -0
- package/src/server/resend.js +93 -0
- package/src/server/salesforce.js +84 -0
- package/src/server/sanity.js +31 -0
- package/src/server/semrush.js +359 -0
- package/src/server/sentry.js +30 -0
- package/src/server/sevdesk.js +20 -0
- package/src/server/shopify.js +99 -0
- package/src/server/slack.js +143 -0
- package/src/server/snowflake.js +139 -0
- package/src/server/storyblok.js +49 -0
- package/src/server/stripe.js +13 -0
- package/src/server/supabase.js +13 -0
- package/src/server/tally.js +78 -0
- package/src/server/telegram.js +55 -0
- package/src/server/tiktok.js +86 -0
- package/src/server/twilio.js +90 -0
- package/src/server/twitch.js +409 -0
- package/src/server/wave.js +520 -0
- package/src/server/wix.js +1048 -0
- package/src/server/wiz.js +117 -0
- package/src/server/woocommerce.js +412 -0
- package/src/server/wordpress-com.js +236 -0
- package/src/server/wordpress-self-hosted.js +134 -0
- package/src/server/workday.js +136 -0
- package/src/server/x-twitter.js +110 -0
- package/src/server/xero.js +397 -0
- package/src/server/zoho-books.js +90 -0
- package/src/server/zoho-crm.js +89 -0
- package/src/server/zohoOAuth.js +21 -0
- package/src/shared/ai-models.json +8049 -0
- package/src/shared/ai.js +63 -0
- package/src/shared/algolia.js +29 -0
- package/src/shared/amazon-redshift.js +51 -0
- package/src/shared/amplitude.js +28 -0
- package/src/shared/atlassian.js +43 -0
- package/src/shared/aws.js +72 -0
- package/src/shared/canva.js +66 -0
- package/src/shared/chargebee.js +26 -0
- package/src/shared/clickhouse.js +38 -0
- package/src/shared/confidence.js +28 -0
- package/src/shared/databricks.js +33 -0
- package/src/shared/dbt-semantic-layer.js +32 -0
- package/src/shared/definitions.js +140 -0
- package/src/shared/figma.js +21 -0
- package/src/shared/firebase-cloud-messaging.js +45 -0
- package/src/shared/gemini-enterprise.js +33 -0
- package/src/shared/gong.js +33 -0
- package/src/shared/google-ads-search.js +31 -0
- package/src/shared/google-ads.js +28 -0
- package/src/shared/google-maps-platform.js +28 -0
- package/src/shared/google.js +133 -0
- package/src/shared/granola.js +25 -0
- package/src/shared/hex.js +28 -0
- package/src/shared/inngest.js +35 -0
- package/src/shared/lightspeed.js +75 -0
- package/src/shared/linkedin.js +27 -0
- package/src/shared/logo-dev.js +21 -0
- package/src/shared/mapbox.js +38 -0
- package/src/shared/mcp.js +92 -0
- package/src/shared/microsoft-fabric.js +47 -0
- package/src/shared/microsoft.js +231 -0
- package/src/shared/miro.js +27 -0
- package/src/shared/oura.js +23 -0
- package/src/shared/posthog.js +33 -0
- package/src/shared/prestashop.js +23 -0
- package/src/shared/salesforce.js +36 -0
- package/src/shared/semrush.js +24 -0
- package/src/shared/shopify.js +51 -0
- package/src/shared/siteUrl.js +12 -0
- package/src/shared/slack.js +88 -0
- package/src/shared/snowflake.js +55 -0
- package/src/shared/tiktok.js +22 -0
- package/src/shared/tokens.js +747 -0
- package/src/shared/twilio.js +41 -0
- package/src/shared/twitch.js +49 -0
- package/src/shared/wave.js +52 -0
- package/src/shared/wix.js +40 -0
- package/src/shared/wiz.js +41 -0
- package/src/shared/wordpress-com.js +30 -0
- package/src/shared/wordpress.js +69 -0
- package/src/shared/workday.js +50 -0
- package/src/shared/x-twitter.js +19 -0
- package/src/shared/xero.js +46 -0
- package/src/shared/zoho-books.js +39 -0
- package/src/shared/zoho-crm.js +43 -0
- package/src/shared/zoho-regions.js +12 -0
- package/test/ai.test.js +136 -0
- package/test/airtable.test.js +125 -0
- package/test/algolia.test.js +207 -0
- package/test/amazon-redshift.test.js +272 -0
- package/test/amplitude.test.js +239 -0
- package/test/apify.test.js +93 -0
- package/test/apollo-io.test.js +125 -0
- package/test/asana.test.js +99 -0
- package/test/ashby.test.js +97 -0
- package/test/atlassian.test.js +249 -0
- package/test/attention.test.js +79 -0
- package/test/aws.test.js +405 -0
- package/test/brevo.test.js +71 -0
- package/test/calendly.test.js +136 -0
- package/test/canva.test.js +258 -0
- package/test/chargebee.test.js +195 -0
- package/test/clickhouse.test.js +278 -0
- package/test/confidence.test.js +205 -0
- package/test/databricks.test.js +253 -0
- package/test/dbt-semantic-layer.test.js +221 -0
- package/test/designMcp.test.js +336 -0
- package/test/elevenlabs.test.js +52 -0
- package/test/firebase-cloud-messaging.test.js +242 -0
- package/test/firecrawl.test.js +66 -0
- package/test/gemini-enterprise.test.js +218 -0
- package/test/github-api.test.js +167 -0
- package/test/gitlab-api.test.js +160 -0
- package/test/gong.test.js +192 -0
- package/test/google-ads.test.js +350 -0
- package/test/google-maps-platform.test.js +191 -0
- package/test/google.test.js +710 -0
- package/test/granola.test.js +240 -0
- package/test/hex.test.js +253 -0
- package/test/heygen.test.js +121 -0
- package/test/hubspot.test.js +103 -0
- package/test/inngest.test.js +219 -0
- package/test/lightspeed.test.js +250 -0
- package/test/linear.test.js +146 -0
- package/test/linkedin.test.js +243 -0
- package/test/logo-dev.test.js +79 -0
- package/test/mailgun.test.js +107 -0
- package/test/mapbox.test.js +181 -0
- package/test/mcp.test.js +227 -0
- package/test/microsoft-fabric.test.js +258 -0
- package/test/microsoft.test.js +554 -0
- package/test/n8nOAuth.test.js +188 -0
- package/test/notionOAuth.test.js +183 -0
- package/test/oura.test.js +211 -0
- package/test/paddleCatalogue.test.js +51 -0
- package/test/paddlePermissions.test.js +101 -0
- package/test/perplexityComposition.test.js +39 -0
- package/test/pipedriveOAuth.test.js +140 -0
- package/test/posthog.test.js +200 -0
- package/test/prestashop.test.js +207 -0
- package/test/resend.test.js +163 -0
- package/test/salesforce.test.js +276 -0
- package/test/semrush.test.js +479 -0
- package/test/sentry.test.js +35 -0
- package/test/shopify.test.js +247 -0
- package/test/slack.test.js +320 -0
- package/test/snowflake.test.js +391 -0
- package/test/tally.test.js +75 -0
- package/test/telegram.test.js +58 -0
- package/test/tiktok.test.js +243 -0
- package/test/tokens.test.js +1079 -0
- package/test/twilio.test.js +221 -0
- package/test/twitch.test.js +573 -0
- package/test/wave.test.js +678 -0
- package/test/wix.test.js +1099 -0
- package/test/wiz.test.js +185 -0
- package/test/wordpress-com.test.js +469 -0
- package/test/wordpress.test.js +660 -0
- package/test/workday.test.js +314 -0
- package/test/x-twitter.test.js +256 -0
- package/test/xero.test.js +700 -0
- package/test/zoho-books.test.js +253 -0
- package/test/zoho-crm.test.js +223 -0
|
@@ -0,0 +1,724 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: connectors/oauth-connection
|
|
3
|
+
title: OAuth connections with portable files
|
|
4
|
+
summary: Compose provider consent, verification and encrypted file persistence from an application server or CLI.
|
|
5
|
+
keywords: connectors, integrations, oauth, shopify, assistant permissions, workday, staffing, tiktok, linkedin, google ads, gaql, developer token, salesforce, soql, databricks, fabric, graphql, service principal, client credentials, wordpress, twitch, microsoft, word, powerpoint, xero, wave, zoho, crm, books, accounting, files, cli, consent
|
|
6
|
+
requires: @jskit-ai/connectors-core, @jskit-ai/connectors-catalog
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# OAuth connections with portable files
|
|
10
|
+
|
|
11
|
+
## Use when
|
|
12
|
+
|
|
13
|
+
Use an own OAuth web-client registration to connect accounts from an existing
|
|
14
|
+
application or operator CLI. The same library owns state, code exchange,
|
|
15
|
+
verification and token handling. WordPress.com illustrates composition here;
|
|
16
|
+
follow each selected provider's setup guide and scopes.
|
|
17
|
+
|
|
18
|
+
## Do not use when
|
|
19
|
+
|
|
20
|
+
This runtime accepts application-owned registrations; managed gateway
|
|
21
|
+
assignments are invalid configuration. Native public clients are not covered by
|
|
22
|
+
this pattern. A shared provider account is not each user's personal
|
|
23
|
+
account. An OAuth data connection does not create the application's login.
|
|
24
|
+
|
|
25
|
+
## Product decisions
|
|
26
|
+
|
|
27
|
+
Choose the integration's ownership mode, scopes and callback owner. Shared
|
|
28
|
+
connections require membership checks before mapping to a stable shared subject.
|
|
29
|
+
Personal connections use the existing authenticated user's stable identity.
|
|
30
|
+
The callback must recover that same owner; do not accept owner IDs from a URL.
|
|
31
|
+
An operator CLI can use its trusted process-owner policy and a registered local
|
|
32
|
+
callback listener. Never copy that identity policy into a public web route.
|
|
33
|
+
|
|
34
|
+
## Invariants
|
|
35
|
+
|
|
36
|
+
- The UI and CLI edit the same `integrations.json` and shared validation schema.
|
|
37
|
+
- Client secrets, tokens and pending attempts stay outside exported source.
|
|
38
|
+
- File runtime state is encrypted with a durable operator-owned key.
|
|
39
|
+
- Saving configuration is not consent; provider verification precedes Connected.
|
|
40
|
+
- Callbacks must match their registered destination, pending state and owner.
|
|
41
|
+
- Failed or cancelled replacement consent preserves an existing grant.
|
|
42
|
+
- Reduced permission grants remain reduced; source edits do not grant access.
|
|
43
|
+
|
|
44
|
+
## Shopify product operations and assistant permissions
|
|
45
|
+
|
|
46
|
+
Import `shopifyProvider` from `@jskit-ai/connectors-catalog/server/shopify` and read
|
|
47
|
+
the packaged `docs/shopify.md`. The supported new-app flow is an installed app in
|
|
48
|
+
the **same Shopify organization** as its store, with `grantType: "client_credentials"`.
|
|
49
|
+
There is no callback in this flow. Put the client secret in an environment
|
|
50
|
+
reference and configure the permanent `shopDomain`, not a custom storefront URL.
|
|
51
|
+
Call `connectClientCredentials` before the named product operations. Existing
|
|
52
|
+
Admin API tokens use `connectApiKey` instead. Other merchants need the unfinished
|
|
53
|
+
Shopify installation/consent flow; do not pretend client credentials cover them.
|
|
54
|
+
|
|
55
|
+
The runtime sends Shopify's header and GraphQL Admin API 2026-07 requests. It
|
|
56
|
+
supports bounded product listing, creation, update and deletion. Create defaults
|
|
57
|
+
to draft. Use Product GIDs; price/SKU/variants and publication are separate work.
|
|
58
|
+
Do not retry a mutation blindly after timeout. A store connection is not shopper
|
|
59
|
+
login or an individual staff member's authorized session.
|
|
60
|
+
|
|
61
|
+
Construct assistant-facing services with `executionMode: "assistant"`; the
|
|
62
|
+
host's trusted authorization callback receives `{ assistantPermission, input }`.
|
|
63
|
+
It must verify real human approval and return `approved: true` for `ask`, together
|
|
64
|
+
with the checked owner identity. The shared runtime denies `never` and does not
|
|
65
|
+
accept a browser-supplied approval flag. `always` still checks application access.
|
|
66
|
+
The host must bind approval to the exact request and supply its existing decision
|
|
67
|
+
UI/storage; the library does not create another approval system.
|
|
68
|
+
|
|
69
|
+
The portable `assistantPolicy` holds enablement, a default and action overrides.
|
|
70
|
+
It is independent of credentials, provider scopes and connection sharing. Host
|
|
71
|
+
workspace policy may further restrict it. Use `authorizeAssistantAction` only
|
|
72
|
+
before a host-owned lifecycle operation such as enabling or claiming a store;
|
|
73
|
+
it authorizes but does not execute that action. The captured remaining action
|
|
74
|
+
choices do not mean variant/discount/store lifecycle adapters are implemented.
|
|
75
|
+
The application owns its registration and token storage. The editor's
|
|
76
|
+
Connect/approval journey must invoke that application's setup operations.
|
|
77
|
+
|
|
78
|
+
## HubSpot account connections
|
|
79
|
+
|
|
80
|
+
Import `hubspotProvider` from `@jskit-ai/connectors-catalog/server/hubspot`.
|
|
81
|
+
Use the packaged `docs/hubspot.md` registration instructions. Configure an own
|
|
82
|
+
registration with `clientId`, `clientSecretRef: "env:HUBSPOT_CLIENT_SECRET"`,
|
|
83
|
+
`callbackUrlRef: "env:HUBSPOT_CALLBACK_URL"` and
|
|
84
|
+
`tokenEndpointAuthMethod: "client_secret_post"`. Select scopes `oauth` and
|
|
85
|
+
`crm.objects.contacts.read`; the integration's authentication is
|
|
86
|
+
`{ "method": "oauth2", "registrationRef": "hubspot" }` when that registration
|
|
87
|
+
is named `hubspot`.
|
|
88
|
+
|
|
89
|
+
Use `beginAuthorization`, the existing application's callback route and
|
|
90
|
+
`completeAuthorization`, then `contacts.list` with optional `limit`, `after`
|
|
91
|
+
and `archived`. Verification reads contacts. The provider implements confidential
|
|
92
|
+
code exchange, scope-array normalization and refresh through HubSpot's current
|
|
93
|
+
token endpoint; do not build another token exchange or gateway.
|
|
94
|
+
|
|
95
|
+
For `per-user`, the application's authenticated identity owns each local grant.
|
|
96
|
+
HubSpot installations normally expose account-level CRM access; this mode does
|
|
97
|
+
not itself enforce HubSpot record ownership or implement application login.
|
|
98
|
+
For `shared`, only authorized app administrators can connect the shared account.
|
|
99
|
+
Use the API-key pattern instead for a static/private token, retaining the
|
|
100
|
+
`crm.objects.contacts.read` configuration permission. Disconnect is local;
|
|
101
|
+
provider installation removal is separate.
|
|
102
|
+
|
|
103
|
+
## Linear account connections
|
|
104
|
+
|
|
105
|
+
Import `linearProvider` from `@jskit-ai/connectors-catalog/server/linear` and
|
|
106
|
+
follow `docs/linear.md` to create the project's own registration. Store its
|
|
107
|
+
Client ID in configuration, Client Secret in `env:LINEAR_CLIENT_SECRET`, and
|
|
108
|
+
callback in `env:LINEAR_CALLBACK_URL`; select `client_secret_post`.
|
|
109
|
+
Use authentication `{ "method": "oauth2", "registrationRef": "linear" }`
|
|
110
|
+
when the registration is named `linear`, and keep `scopes: ["read"]`.
|
|
111
|
+
|
|
112
|
+
The application calls `beginAuthorization`, handles its registered callback with
|
|
113
|
+
`completeAuthorization`, then invokes `profile.read` or `issues.list` (optional
|
|
114
|
+
`first` and `after`). The provider owns S256, scope delimiter normalization and
|
|
115
|
+
rotating refresh. The caller owns authorization and subject identity. Shared
|
|
116
|
+
connections belong to the application's authorized administrator; per-user
|
|
117
|
+
connections belong to the signed-in application user. Connecting Linear does not
|
|
118
|
+
implement application login. This flow acts as the consenting Linear user.
|
|
119
|
+
|
|
120
|
+
The same grant supports `tools.list` and `tools.call` against Linear's fixed MCP
|
|
121
|
+
endpoint. Authorize each tool and its arguments before invocation; tools can
|
|
122
|
+
write if the provider permissions allow it. No second MCP registration or Vibe64
|
|
123
|
+
gateway is needed. For personal keys use the API-key pattern, keep the `read`
|
|
124
|
+
configuration scope and restrict the actual key in Linear. Disconnect deletes
|
|
125
|
+
the local grant; provider revocation remains a separate account action.
|
|
126
|
+
|
|
127
|
+
## Framework APIs
|
|
128
|
+
|
|
129
|
+
Import configuration validation, `createConnectionService`, environment
|
|
130
|
+
resolution and the file storage/protection exports from connectors-core.
|
|
131
|
+
The selected catalogue provider supplies the protocol and operation contracts.
|
|
132
|
+
|
|
133
|
+
## Example files
|
|
134
|
+
|
|
135
|
+
Use the packaged `docs/wordpress-com.md` guide in `@jskit-ai/connectors-catalog`.
|
|
136
|
+
`example/integrations.json` supplies its portable configuration. Replace the
|
|
137
|
+
placeholder with the provider's assigned Client ID, then compose the ordinary
|
|
138
|
+
package APIs in an application module:
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
import { readFile } from "node:fs/promises";
|
|
142
|
+
import { parseIntegrationConfiguration } from "@jskit-ai/connectors-core/shared/configuration";
|
|
143
|
+
import { createConnectionService, createEnvironmentReferenceResolver } from "@jskit-ai/connectors-core/server";
|
|
144
|
+
import { createFileConnectionStore, createCredentialProtection } from "@jskit-ai/connectors-core/server/file-storage";
|
|
145
|
+
import { wordpressComProvider } from "@jskit-ai/connectors-catalog/server/wordpress-com";
|
|
146
|
+
|
|
147
|
+
const providers = [wordpressComProvider];
|
|
148
|
+
const configuration = parseIntegrationConfiguration(await readFile("integrations.json", "utf8"), { providers });
|
|
149
|
+
const protection = createCredentialProtection({
|
|
150
|
+
keys: { current: Buffer.from(process.env.CONNECTOR_STORAGE_KEY, "base64") }, activeKeyId: "current"
|
|
151
|
+
});
|
|
152
|
+
const connections = createConnectionService({
|
|
153
|
+
configuration, providers,
|
|
154
|
+
store: createFileConnectionStore({ directory: process.env.CONNECTOR_STATE_DIRECTORY, protection }),
|
|
155
|
+
resolveReference: createEnvironmentReferenceResolver(), authorize: applicationConnectionPolicy
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`applicationConnectionPolicy` checks the authenticated caller and requested
|
|
160
|
+
operation, then returns `{ applicationId, subjectId }`. Keep the state directory
|
|
161
|
+
outside source and preserve its encryption key across restarts/backups.
|
|
162
|
+
|
|
163
|
+
1. Call `beginAuthorization({ context, integrationId })` and open the returned
|
|
164
|
+
`authorizationUrl` in the user's browser. A resource-specific provider may
|
|
165
|
+
also require `verificationInput`, validated before consent starts.
|
|
166
|
+
2. At the application's registered callback, recover authenticated `context`
|
|
167
|
+
and call `completeAuthorization({ context, integrationId, callbackUrl })`.
|
|
168
|
+
Route errors through ordinary application error handling.
|
|
169
|
+
3. Call `invoke({ context, integrationId, operation, input })` for a named
|
|
170
|
+
provider operation. Provider responses stay subject to application policy.
|
|
171
|
+
4. `cancelAuthorization({ context, integrationId, state })` abandons a pending
|
|
172
|
+
attempt. `disconnect({ context, integrationId })` removes local access and
|
|
173
|
+
pending attempts. It does not revoke provider-wide access.
|
|
174
|
+
|
|
175
|
+
## Variation points
|
|
176
|
+
|
|
177
|
+
Google, Microsoft, Oura and WordPress.com have different scope and token
|
|
178
|
+
contracts. Use their provider exports instead of inferring these from fields.
|
|
179
|
+
WordPress.com verifies token ownership/scopes from its profile and requests
|
|
180
|
+
comma-separated permissions. Oura handles reduced callback scopes and rotated
|
|
181
|
+
refresh tokens. Some providers do not return a refresh token; expired access
|
|
182
|
+
then needs consent again. Provider PKCE enforcement needs provider evidence.
|
|
183
|
+
|
|
184
|
+
## Twitch composition
|
|
185
|
+
|
|
186
|
+
Use `twitchProvider` from `@jskit-ai/connectors-catalog/server/twitch` in the
|
|
187
|
+
provider array above and the portable JSON in `docs/twitch.md`. Start with
|
|
188
|
+
`user:read:email` and `user:read:follows` for `profile.read` and
|
|
189
|
+
`channels.followed`; remove any permission whose operation is not used.
|
|
190
|
+
Its normal operations verify the token before data access. The provider also
|
|
191
|
+
exposes `token.validate` for Twitch's required startup/hourly validation of
|
|
192
|
+
maintained sessions, including idle connections:
|
|
193
|
+
|
|
194
|
+
```js
|
|
195
|
+
// Run from the host's startup and scheduled-job paths. Contexts are derived
|
|
196
|
+
// by its existing authorization owner, never from caller-supplied user IDs.
|
|
197
|
+
for (const context of maintainedTwitchContexts) {
|
|
198
|
+
try {
|
|
199
|
+
await connections.invoke({ context, integrationId: "twitch", operation: "token.validate" });
|
|
200
|
+
} catch (error) {
|
|
201
|
+
await reportConnectionFailure(context, error);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The host supplies `maintainedTwitchContexts` and `reportConnectionFailure`;
|
|
207
|
+
these are not JSKIT exports. Its scheduler must prevent overlapping runs and
|
|
208
|
+
surface reconnect state. Merely saving configuration installs no scheduled
|
|
209
|
+
job. Neither the provider nor this composition implements application login.
|
|
210
|
+
Twitch requires an application-specific registration: do not reuse one editor
|
|
211
|
+
client ID across independent generated apps. Register the application's own callback URL. The runtime handles array/string token
|
|
212
|
+
scopes and Client-ID headers; do not duplicate those details in app scaffolding.
|
|
213
|
+
|
|
214
|
+
## Slack composition
|
|
215
|
+
|
|
216
|
+
Import `slackProvider` from `@jskit-ai/connectors-catalog/server/slack` and include
|
|
217
|
+
it in the provider array used for parsing and `createConnectionService`.
|
|
218
|
+
Set `settings.actor` to `user` or `bot`, independently of application ownership.
|
|
219
|
+
Use an own confidential registration and a real registered HTTPS callback;
|
|
220
|
+
plain HTTP loopback is not supported by Slack. The [Slack guide](https://github.com/mobily-enterprises/jskit-ai/blob/main/packages/connectors-catalog/docs/slack.md)
|
|
221
|
+
contains a complete portable JSON file and manual/API registration instructions.
|
|
222
|
+
|
|
223
|
+
For channel listing, request `channels:read` and call:
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
const firstPage = await connections.invoke({
|
|
227
|
+
context: authenticatedContext,
|
|
228
|
+
integrationId: "slack",
|
|
229
|
+
operation: "channels.list",
|
|
230
|
+
input: { limit: 50, exclude_archived: true }
|
|
231
|
+
});
|
|
232
|
+
// Retain next_cursor even when filtering leaves this page empty.
|
|
233
|
+
const nextCursor = firstPage.response_metadata?.next_cursor;
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
The host supplies `authenticatedContext`; user request parameters cannot select
|
|
237
|
+
another owner. The library selects `user_scope` versus `scope`, extracts the
|
|
238
|
+
requested token identity, checks Slack's HTTP-200 errors and refreshes rotating
|
|
239
|
+
grants under the file lock. Do not duplicate that code in generated handlers.
|
|
240
|
+
Add the corresponding read permission before using `groups.list`,
|
|
241
|
+
`directMessages.list` or `groupMessages.list`. `auth.test` returns identity.
|
|
242
|
+
|
|
243
|
+
An individually owned bot connection still acts as the installed workspace bot.
|
|
244
|
+
It is not a personal account or an application login. Actor changes require
|
|
245
|
+
reconnection and remove incompatible form scopes. Captured permission choices
|
|
246
|
+
do not imply implemented operations: history, sends, events, organization-wide
|
|
247
|
+
installs and Sign in with Slack remain outside this fragment. The application implements and registers its own callback.
|
|
248
|
+
|
|
249
|
+
## Microsoft document composition
|
|
250
|
+
|
|
251
|
+
Import `microsoftWordProvider` or `microsoftPowerPointProvider` from the matching
|
|
252
|
+
`@jskit-ai/connectors-catalog/server/microsoft-word` or
|
|
253
|
+
`@jskit-ai/connectors-catalog/server/microsoft-powerpoint` export. Use that provider
|
|
254
|
+
in the composition above and its packaged guide's JSON. A `files` slot requests
|
|
255
|
+
`Files.Read` and, for refresh capability, `offline_access`. Set `settings.tenantId`
|
|
256
|
+
to an allowed audience or directory GUID matching the registration. The shared
|
|
257
|
+
library uses it for authorization, token exchange and refresh; changing the
|
|
258
|
+
tenant requires reconnecting. Never build token URLs from unvalidated user input.
|
|
259
|
+
|
|
260
|
+
After consent and verification, the host can call the same service:
|
|
261
|
+
|
|
262
|
+
```js
|
|
263
|
+
const page = await connections.invoke({
|
|
264
|
+
context, integrationId: "files", operation: "items.list",
|
|
265
|
+
input: { folderId, pageSize: 25, nextLink }
|
|
266
|
+
});
|
|
267
|
+
const file = await connections.invoke({
|
|
268
|
+
context, integrationId: "files", operation: "items.get", input: { itemId }
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
The host supplies authenticated `context`, an optional `folderId`/`nextLink`
|
|
273
|
+
and the chosen `itemId`. Pass the original folder ID with every continuation.
|
|
274
|
+
Keep `page["@odata.nextLink"]` even if `page.value` is empty: the adapter filters
|
|
275
|
+
an upstream page by file extension, so the next page can contain matching files.
|
|
276
|
+
Display folder and file metadata through the app's existing UI. The returned
|
|
277
|
+
`file` is metadata, not document contents; returned web URLs do not authorize
|
|
278
|
+
additional downloads. These adapters implement no document editing, recursive
|
|
279
|
+
crawl or app login. Leave paging and named-operation HTTP ownership in JSKIT;
|
|
280
|
+
the app owns its file selection, presentation and access policy.
|
|
281
|
+
|
|
282
|
+
## Xero composition
|
|
283
|
+
|
|
284
|
+
Import `xeroProvider` from `@jskit-ai/connectors-catalog/server/xero` and use
|
|
285
|
+
the exact portable configuration in `docs/xero.md`. Its registration requires
|
|
286
|
+
`tokenEndpointAuthMethod: "client_secret_basic"`; code exchange and refresh
|
|
287
|
+
stay in JSKIT. Use an HTTPS callback or Xero's permitted `http://localhost`
|
|
288
|
+
callback for local CLI work; `127.0.0.1` is not accepted by this provider.
|
|
289
|
+
|
|
290
|
+
```js
|
|
291
|
+
const tenants = await connections.invoke({
|
|
292
|
+
context, integrationId: "xero", operation: "connections.list"
|
|
293
|
+
});
|
|
294
|
+
// The app displays permitted ORGANISATION entries, takes an explicit choice,
|
|
295
|
+
// and authorises that choice against its own workspace/account policy.
|
|
296
|
+
const tenantId = await choosePermittedOrganisation(tenants, context);
|
|
297
|
+
const contacts = await connections.invoke({
|
|
298
|
+
context, integrationId: "xero", operation: "contacts.list",
|
|
299
|
+
input: { tenantId, page: 1, pageSize: 50 }
|
|
300
|
+
});
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
`choosePermittedOrganisation` is application-owned selection and policy, not a
|
|
304
|
+
JSKIT export. Never select the first tenant automatically or trust a submitted
|
|
305
|
+
ID merely because it has UUID syntax. Runtime reads additionally check that the
|
|
306
|
+
current token still has an ORGANISATION connection before sending a tenant
|
|
307
|
+
header. This does not replace the application's own authorisation boundary.
|
|
308
|
+
The same pattern applies to `organisation.read` and `invoices.list` with their
|
|
309
|
+
required read scopes. Follow page numbers explicitly; the library performs no
|
|
310
|
+
automatic crawl, calculations, writes or login. Present private data only to
|
|
311
|
+
the authorised caller. Refresh and encrypted file state remain library code.
|
|
312
|
+
|
|
313
|
+
The guide covers the manual developer-app setup, connection tiers and
|
|
314
|
+
application callback requirements. The application supplies its own registration.
|
|
315
|
+
|
|
316
|
+
## Wave composition
|
|
317
|
+
|
|
318
|
+
Import `waveProvider` from `@jskit-ai/connectors-catalog/server/wave` into the
|
|
319
|
+
same provider array and use `docs/wave.md` for portable JSON and registration
|
|
320
|
+
setup. Keep `client_secret_post` authentication. Grant `user:read` for verification,
|
|
321
|
+
`business:read` for selection, and the matching customer/invoice read permission.
|
|
322
|
+
|
|
323
|
+
```js
|
|
324
|
+
const businesses = await connections.invoke({
|
|
325
|
+
context, integrationId: "wave", operation: "businesses.list",
|
|
326
|
+
input: { page: 1, pageSize: 20 }
|
|
327
|
+
});
|
|
328
|
+
const businessId = await choosePermittedBusiness(businesses.data.businesses, context);
|
|
329
|
+
const customers = await connections.invoke({
|
|
330
|
+
context, integrationId: "wave", operation: "customers.list",
|
|
331
|
+
input: { businessId, page: 1, pageSize: 20 }
|
|
332
|
+
});
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
`choosePermittedBusiness` is the host's selection and authorization function,
|
|
336
|
+
not a JSKIT export. Do not default to the first business or trust an incoming
|
|
337
|
+
business ID without policy checks. Preserve `pageInfo` and nullable edge nodes;
|
|
338
|
+
advance only when the caller requests another page. `invoice:write` alone cannot
|
|
339
|
+
authorize invoice reads. Results with GraphQL errors are rejected even if they
|
|
340
|
+
contain partial data. The library sends fixed queries and owns token refresh,
|
|
341
|
+
including Wave's original redirect URI, under encrypted file storage.
|
|
342
|
+
|
|
343
|
+
Wave OAuth business access requires Pro or Advisor, and use for other customers
|
|
344
|
+
requires provider approval. This is a data connection, not login. The application must implement and register an actual
|
|
345
|
+
served callback. Do not replace OAuth with a personal full-access token for
|
|
346
|
+
customer applications or copy protocol logic into generated routes.
|
|
347
|
+
|
|
348
|
+
## Verification
|
|
349
|
+
|
|
350
|
+
Focused tests simulate consent and provider responses with real temporary
|
|
351
|
+
encrypted text storage. They cover restart, cancellation, scope reduction,
|
|
352
|
+
ownership, refresh/reconnect and errors. Editor tests verify JSON fields and
|
|
353
|
+
persistence. These checks do not generate or run sample applications or use
|
|
354
|
+
real provider credentials.
|
|
355
|
+
|
|
356
|
+
## Avoid
|
|
357
|
+
|
|
358
|
+
Do not implement OAuth protocol logic in copied scaffolding, put client secrets
|
|
359
|
+
in browser code, assume requested permissions were all granted, or label a
|
|
360
|
+
saved registration as a connected account. Do not create a database solely
|
|
361
|
+
for connector configuration or runtime state.
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
## Zoho CRM composition
|
|
365
|
+
|
|
366
|
+
Import `zohoCrmProvider` from `@jskit-ai/connectors-catalog/server/zoho-crm` and
|
|
367
|
+
pass it to the existing connection service. Follow the packaged
|
|
368
|
+
`docs/zoho-crm.md` for registration, references and portable configuration.
|
|
369
|
+
Choose the account's data center and CRM environment explicitly. Do not follow
|
|
370
|
+
callback-supplied hosts or choose another organisation on the user's behalf.
|
|
371
|
+
|
|
372
|
+
```js
|
|
373
|
+
const page = await connections.invoke({
|
|
374
|
+
context: authenticatedOwner,
|
|
375
|
+
integrationId: "crm",
|
|
376
|
+
operation: "leads.list",
|
|
377
|
+
input: { fields: "Last_Name,Email", per_page: 50, page: 1 }
|
|
378
|
+
});
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
The library owns comma-separated scopes, PKCE, token exchange/refresh, API-domain
|
|
382
|
+
validation and `Zoho-oauthtoken` headers. `users.current` verifies the connection;
|
|
383
|
+
`contacts.list`, `accounts.list` and `deals.list` are also available. Keep page
|
|
384
|
+
tokens associated with the same authenticated owner and query, and request later
|
|
385
|
+
pages explicitly. HTTP204 becomes an empty page. The host owns data presentation,
|
|
386
|
+
record access policy and the OAuth callback. Reference secrets instead of putting
|
|
387
|
+
them in JSON; use the same file and connection service for a trusted CLI.
|
|
388
|
+
|
|
389
|
+
A shared connection shares one organisation's CRM access. Personal connections
|
|
390
|
+
require the host's per-user policy. The application owns its registration and callback. These data scopes do not
|
|
391
|
+
implement app sign-in or promise independent provider quotas.
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
## Zoho Books composition
|
|
395
|
+
|
|
396
|
+
Import `zohoBooksProvider` from `@jskit-ai/connectors-catalog/server/zoho-books`
|
|
397
|
+
and use the same connection service, file store and owner policy above. See
|
|
398
|
+
`docs/zoho-books.md` for the JSON and regional client setup. Match the selected
|
|
399
|
+
region to the account. Keep `ZohoBooks.settings.READ` for verification.
|
|
400
|
+
|
|
401
|
+
```js
|
|
402
|
+
const result = await connections.invoke({
|
|
403
|
+
context: authenticatedOwner, integrationId: "books", operation: "organizations.list"
|
|
404
|
+
});
|
|
405
|
+
// Present active organisations from result.organizations. The application
|
|
406
|
+
// validates the user's choice and any narrower organisation access policy.
|
|
407
|
+
const invoices = await connections.invoke({
|
|
408
|
+
context: authenticatedOwner, integrationId: "books", operation: "invoices.list",
|
|
409
|
+
input: { organization_id: selectedOrganizationId, page: 1, per_page: 50 }
|
|
410
|
+
});
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Never pick the first or default organisation automatically. A configured
|
|
414
|
+
`settings.organizationId` fixes the organisation and can supply the operation's
|
|
415
|
+
ID; an input attempting to override it fails. With no configured ID the caller
|
|
416
|
+
must supply one. Zoho enforces resource access; the host must enforce any
|
|
417
|
+
narrower per-user policy, especially when deliberately sharing one connection.
|
|
418
|
+
`organizations.list` verifies access to a configured active organisation but
|
|
419
|
+
returns the account's organisation list for discovery. It does not select one.
|
|
420
|
+
|
|
421
|
+
The library owns regional OAuth, PKCE, refresh, API-domain validation and token
|
|
422
|
+
headers. Lists make one request and preserve `page_context`; use its
|
|
423
|
+
`has_more_page` value for explicit continued paging. IDs stay strings. The host
|
|
424
|
+
owns callbacks, presentation and selection. Configuration save does not grant
|
|
425
|
+
provider access or implement app login. Registrations remain application-owned.
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
## Lightspeed X-Series composition
|
|
429
|
+
|
|
430
|
+
Import `lightspeedProvider` from `@jskit-ai/connectors-catalog/server/lightspeed`
|
|
431
|
+
and give it to the existing connection service. Use the JSON and provider setup
|
|
432
|
+
in `docs/lightspeed.md`. The store prefix is required and fixed before consent;
|
|
433
|
+
never route credentials using a callback-supplied domain. Keep `products:read`
|
|
434
|
+
for verification and pass `verificationInput: { page_size: 1 }` when starting it.
|
|
435
|
+
|
|
436
|
+
```js
|
|
437
|
+
const products = await connections.invoke({
|
|
438
|
+
context: authenticatedOwner, integrationId: "retail", operation: "products.list",
|
|
439
|
+
input: { page_size: 50, deleted: false }
|
|
440
|
+
});
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
`customers.list` and `outlets.list` use the same paging inputs with their own read
|
|
444
|
+
scopes. Request subsequent pages explicitly with version bounds. Preserve null
|
|
445
|
+
customer values and avoid assuming a full page means more records certainly exist.
|
|
446
|
+
The library pins the current API version, validates store-bound token responses,
|
|
447
|
+
and persists each rotated refresh token before reading data. It sends PKCE;
|
|
448
|
+
provider enforcement has not been proven with a live client. Do not add retries
|
|
449
|
+
around authorization codes, refresh or interrupted requests.
|
|
450
|
+
|
|
451
|
+
The host owns authenticated subjects, shared-store access, callback routes and
|
|
452
|
+
rendering. CLI and UI use the same configuration; no database is required for
|
|
453
|
+
editor configuration. Each application supplies its own registration and callback; app sign-in is a separate concern. Extra
|
|
454
|
+
scope selections do not create write operations or independent provider quotas.
|
|
455
|
+
## Databricks user consent and service accounts
|
|
456
|
+
|
|
457
|
+
Import `databricksProvider` from `@jskit-ai/connectors-catalog/server/databricks`.
|
|
458
|
+
Read `docs/databricks.md` for the two portable configurations. A custom OAuth app
|
|
459
|
+
uses `authorization_code`, `client_secret_post`, a callback reference and
|
|
460
|
+
`all-apis offline_access`. A service principal uses `client_credentials`,
|
|
461
|
+
`client_secret_basic` and its Databricks OAuth secret reference; it has no
|
|
462
|
+
callback or user refresh token. Use `jobs` for a suitably scoped service secret.
|
|
463
|
+
Service principals cannot use `per-user` ownership.
|
|
464
|
+
|
|
465
|
+
Compose the ordinary connections service/Feature and file store. Call
|
|
466
|
+
`connectClientCredentials` or the `connectors.verifyClientCredentials` action
|
|
467
|
+
to verify a service principal. User access still uses `beginAuthorization` and
|
|
468
|
+
`completeAuthorization`. The library owns token requests, renewal, secret
|
|
469
|
+
resolution, state, grant checks and persistence; do not generate replacements
|
|
470
|
+
in the application. The app owns routes, binding values and trusted identity.
|
|
471
|
+
|
|
472
|
+
`jobs.list` reads one page with `limit`, `name`, `expand_tasks` and `page_token`.
|
|
473
|
+
`jobs.get` reads one job with a safe numeric `job_id` and optional continuation
|
|
474
|
+
token. Empty lists may omit `jobs`; nested job arrays may need further pages.
|
|
475
|
+
No job execution, SQL query, compute startup or write operation is implemented.
|
|
476
|
+
Source permission changes to a service account require reconnecting. The
|
|
477
|
+
runtime renews only its prior grant and commits renewal even if a later API
|
|
478
|
+
read fails. Never supply an arbitrary request URL or reuse a service grant as
|
|
479
|
+
an app user's connection.
|
|
480
|
+
|
|
481
|
+
Both flows pin requests to the configured per-workspace origin. The application
|
|
482
|
+
implements and registers its own user-consent callback. Its registration belongs
|
|
483
|
+
to its Databricks account; it is not automatically universal across customer
|
|
484
|
+
accounts. Follow the guide for admin provisioning and direct CLI wiring.
|
|
485
|
+
Application login remains separate.
|
|
486
|
+
|
|
487
|
+
## Microsoft Fabric GraphQL
|
|
488
|
+
|
|
489
|
+
Import `microsoftFabricProvider` from
|
|
490
|
+
`@jskit-ai/connectors-catalog/server/microsoft-fabric`. Read the package's
|
|
491
|
+
`docs/microsoft-fabric.md` before wiring it. Use its portable configuration with
|
|
492
|
+
an exact directory GUID, Application (client) ID, secret reference and the
|
|
493
|
+
existing GraphQL API endpoint. Do not reuse the ordinary Microsoft Graph
|
|
494
|
+
providers or their permissions: Fabric uses a different resource.
|
|
495
|
+
|
|
496
|
+
User consent uses `authorization_code`, the confidential `client_secret_post`
|
|
497
|
+
method, a callback reference, delegated
|
|
498
|
+
`https://analysis.windows.net/powerbi/api/GraphQLApi.Execute.All` and optional
|
|
499
|
+
`offline_access`. Service accounts use `client_credentials`, the same client
|
|
500
|
+
authentication method, and `https://api.fabric.microsoft.com/.default`. They
|
|
501
|
+
have no callback, user refresh token or per-user ownership. Switching grants
|
|
502
|
+
in the shared UI removes incompatible scopes; choose the new permission before
|
|
503
|
+
saving. The CLI parser enforces the same contract.
|
|
504
|
+
|
|
505
|
+
Reuse `createConnectionService` or `ConnectorsFeature`, the file connection store
|
|
506
|
+
and existing authorization/reference resolver. Call `connectClientCredentials`
|
|
507
|
+
or `connectors.verifyClientCredentials` for a service account; use the ordinary
|
|
508
|
+
authorization start/callback methods for user consent. The library owns token
|
|
509
|
+
exchange, renewal, locking, scope validation and encrypted storage. The app owns
|
|
510
|
+
the authenticated owner mapping and its allowed GraphQL documents.
|
|
511
|
+
|
|
512
|
+
Verification runs `connection.check`, a fixed root `__typename` query. It does
|
|
513
|
+
not establish access to every table. `schema.types` uses explicit introspection,
|
|
514
|
+
which a Fabric workspace administrator must enable; an exported SDL is an
|
|
515
|
+
alternative for authoring. `graphql.execute` accepts a document, optional JSON
|
|
516
|
+
variables and an operation name and returns one response. It can execute writes.
|
|
517
|
+
Keep documents in app server code, validate the permitted variables, and use
|
|
518
|
+
the shared authorization callback to restrict each operation. Do not present
|
|
519
|
+
this as a read-only proxy or accept arbitrary documents from app users. Request
|
|
520
|
+
pagination in the app's chosen document; no automatic traversal is implemented.
|
|
521
|
+
|
|
522
|
+
GraphQL errors, including partial successes, fail without exposing provider
|
|
523
|
+
messages. A failed mutation may have changed data; the runtime does not replay
|
|
524
|
+
it. Cancellation is local interruption, not proof of remote rollback. Token
|
|
525
|
+
renewal persists before the document executes, including when that execution
|
|
526
|
+
fails. Changing tenant, API endpoint, client or grant requires reconnecting.
|
|
527
|
+
|
|
528
|
+
User consent returns to the application's own implemented and registered callback.
|
|
529
|
+
Service access has no callback. Entra registrations, tenant enablement, API
|
|
530
|
+
permissions and source access remain administrator-owned provisioning. Distinct registration names do not isolate Fabric capacity. The application
|
|
531
|
+
owns login separately and keeps its client secret in private Env.
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
## Salesforce composition
|
|
535
|
+
|
|
536
|
+
Use `salesforceProvider` from `@jskit-ai/connectors-catalog/server/salesforce`
|
|
537
|
+
and the portable JSON in `docs/salesforce.md`. Read that guide before provisioning
|
|
538
|
+
an External Client App. Production/Developer Edition and Sandbox have distinct
|
|
539
|
+
My Domain formats. Client credentials remain in references; the runtime pins
|
|
540
|
+
consent, token exchange and APIs to that org and handles undated/rotating grants.
|
|
541
|
+
The ordinary file service, Env resolver and application owner policy above apply.
|
|
542
|
+
|
|
543
|
+
After consent, `limits.read` verifies API access. A server action can expose an
|
|
544
|
+
approved query through the same library:
|
|
545
|
+
|
|
546
|
+
```js
|
|
547
|
+
const result = await connections.invoke({
|
|
548
|
+
context: authenticatedContext, integrationId: "crm", operation: "query.read",
|
|
549
|
+
input: { q: "SELECT Id, Name FROM Account ORDER BY Id LIMIT 20" }, signal
|
|
550
|
+
});
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
The application supplies the trusted context and abort signal. It authorizes
|
|
554
|
+
objects, fields and any query parameters in its existing action/policy; avoid
|
|
555
|
+
an unrestricted query endpoint. `api` can authorize writes even though these
|
|
556
|
+
operations only read. Do not use provider connection identity as application
|
|
557
|
+
login. For metadata, call `objects.list` and `objects.describe` with an object
|
|
558
|
+
API name. Keep a returned `nextRecordsUrl` with its original owner/query and pass
|
|
559
|
+
it only to `query.next`. No automatic paging is installed.
|
|
560
|
+
|
|
561
|
+
Map `connector_cursor_expired` to restarting the authorized query and
|
|
562
|
+
`connector_reconnect_required` to the existing connection UI. Do not retry a
|
|
563
|
+
failed operation in a loop. Register the application's implemented callback and
|
|
564
|
+
follow provider requirements for distributing an app across customer orgs.
|
|
565
|
+
Separate registrations do not divide an org's API allocation.
|
|
566
|
+
|
|
567
|
+
## Google Ads composition
|
|
568
|
+
|
|
569
|
+
Use `googleAdsProvider` from `@jskit-ai/connectors-catalog/server/google-ads`
|
|
570
|
+
with the same file service and owner policy. Start from the actual portable JSON
|
|
571
|
+
in `docs/google-ads.md`. Setup needs a Web OAuth client in a Cloud project
|
|
572
|
+
with the required Google Ads API access level. Developer tokens were retired
|
|
573
|
+
on September 9, 2026; do not add a developer-token reference or pilot selector.
|
|
574
|
+
The app owns its registration and grants. This does not establish app login
|
|
575
|
+
or make arbitrary reports public.
|
|
576
|
+
|
|
577
|
+
`customers.listAccessible` verifies the grant and returns directly accessible
|
|
578
|
+
customer resource names. It does not list every manager descendant. Use
|
|
579
|
+
`customers.listClients` for an authorized manager's hierarchy metadata, keeping
|
|
580
|
+
the operation customer ID separate from optional `settings.loginCustomerId`.
|
|
581
|
+
For a useful campaign report, the existing server action can call:
|
|
582
|
+
|
|
583
|
+
```js
|
|
584
|
+
const report = await connections.invoke({
|
|
585
|
+
context: authenticatedContext,
|
|
586
|
+
integrationId: "ads",
|
|
587
|
+
operation: "reports.search",
|
|
588
|
+
input: {
|
|
589
|
+
customerId: authorizedCustomerId,
|
|
590
|
+
query: "SELECT campaign.id, campaign.name, metrics.impressions, metrics.clicks, metrics.cost_micros FROM campaign WHERE segments.date DURING LAST_7_DAYS LIMIT 100"
|
|
591
|
+
},
|
|
592
|
+
signal
|
|
593
|
+
});
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
Derive `authorizedCustomerId` from the app's existing account-access policy.
|
|
597
|
+
Authorize fields, date ranges and filters too; do not send arbitrary browser/AI
|
|
598
|
+
GAQL to a public server route. The library passes the operation and input
|
|
599
|
+
snapshot to the host policy before credentials or API requests. Google's
|
|
600
|
+
`adwords` permission may allow writes, despite this operation set's reads.
|
|
601
|
+
|
|
602
|
+
Render `report.results ?? []`; retain integer strings and cost micros without
|
|
603
|
+
rounding. Keep `nextPageToken` with the exact query/customer/owner for an explicit
|
|
604
|
+
next call. No automatic page loop or SearchStream endpoint is installed. API
|
|
605
|
+
errors can reflect developer approval, account relationships or quotas even
|
|
606
|
+
after valid OAuth consent. Map `connector_api_access_invalid` to API setup,
|
|
607
|
+
`connector_scope_missing` and `connector_reconnect_required` to consent recovery,
|
|
608
|
+
and `connector_rate_limited` to the app's bounded usage policy. Never solve API
|
|
609
|
+
approval by repeatedly asking the user to reconnect.
|
|
610
|
+
|
|
611
|
+
The provider guide includes console clicks, API/CLI automation feasibility,
|
|
612
|
+
application-owned callback configuration and account quota boundaries.
|
|
613
|
+
Different client IDs do not automatically separate developer-token capacity;
|
|
614
|
+
approved pilot projects can have usage caps while organization/account limits
|
|
615
|
+
still apply. The CLI uses exactly this library and file configuration without
|
|
616
|
+
Vibe64. No generated app or live provider operation is required to validate the
|
|
617
|
+
configuration, run the focused provider tests or read this source pattern.
|
|
618
|
+
|
|
619
|
+
## LinkedIn composition
|
|
620
|
+
|
|
621
|
+
Use `linkedinProvider` from `@jskit-ai/connectors-catalog/server/linkedin` and
|
|
622
|
+
`docs/linkedin.md`. Both `openid` and `profile` are required; request `email`
|
|
623
|
+
only when needed. `profile.read` accepts no input and reads the connected
|
|
624
|
+
member's userinfo. Optional email fields may be absent. The fragment discards
|
|
625
|
+
ID tokens and does not implement app login or member posting; preserving
|
|
626
|
+
`w_member_social` in configuration does not provide a publishing operation.
|
|
627
|
+
Ordinary expiry requires reconnect unless LinkedIn approved programmatic
|
|
628
|
+
refresh. Keep the confidential client secret on the backend, including when
|
|
629
|
+
composing a CLI; the separately enabled native flow is not implemented.
|
|
630
|
+
Implement and register the application's callback using its assigned app URL
|
|
631
|
+
or explicit host override. Operator setup belongs to the application developer.
|
|
632
|
+
|
|
633
|
+
## TikTok composition
|
|
634
|
+
|
|
635
|
+
Use `tiktokProvider` from `@jskit-ai/connectors-catalog/server/tiktok` and the
|
|
636
|
+
packaged `docs/tiktok.md`. The portable `clientId` field stores TikTok's Client
|
|
637
|
+
key. The adapter sends `client_key` during authorize/token exchanges, comma
|
|
638
|
+
separated scopes, and requires a static HTTPS Web callback under 512 characters.
|
|
639
|
+
The CLI uses that same callback-owning backend and file runtime; do not embed
|
|
640
|
+
its secret into distributed clients or assume HTTP loopback/native support.
|
|
641
|
+
|
|
642
|
+
`profile.read` verifies basic access. `profile.extended`, `profile.stats` and
|
|
643
|
+
`videos.list` require their respective optional permissions. Handle declined
|
|
644
|
+
permissions as unavailable operations; never substitute the builder's account
|
|
645
|
+
for an app user's connection. Video reads use explicit pages with string IDs;
|
|
646
|
+
the runtime implements no posting or Research API. Refresh rotates credentials
|
|
647
|
+
and may reduce permissions. Local disconnect does not revoke access at TikTok.
|
|
648
|
+
The application owns its callback and allowed return destination. App login
|
|
649
|
+
remains a separate concern from this data connection.
|
|
650
|
+
|
|
651
|
+
## Snowflake account OAuth
|
|
652
|
+
|
|
653
|
+
Use `snowflakeProvider` from `@jskit-ai/connectors-catalog/server/snowflake` and
|
|
654
|
+
`docs/snowflake.md`. Its portable settings are `accountUrl` and optional `role`.
|
|
655
|
+
The shared form and CLI parser derive compatible scope choices from the role.
|
|
656
|
+
Omit the role for the connected user's default and retain `refresh_token`;
|
|
657
|
+
otherwise include the exact required role scope returned by `getProviderScopes`.
|
|
658
|
+
Do not hand-encode a space-containing role twice. Changing role/account requires
|
|
659
|
+
new consent. The registration supports confidential client secret POST or Basic;
|
|
660
|
+
PKCE remains enabled for both.
|
|
661
|
+
|
|
662
|
+
The useful operation is `databases.list` with `showLimit`, `like`, `startsWith`,
|
|
663
|
+
`fromName` and `history`. It reads one metadata page and pins the configured role
|
|
664
|
+
in the request header. Do not turn user text into SQL or infer table access from
|
|
665
|
+
successful metadata verification. HTTP 202 remains an explicit incomplete
|
|
666
|
+
response, with no polling implementation in this fragment.
|
|
667
|
+
|
|
668
|
+
An administrator creates the custom OAuth integration inside each customer's
|
|
669
|
+
Snowflake account. AI can assist through authorized SQL/CLI provisioning, but
|
|
670
|
+
reader credentials do not grant that authority. Keep secret results out of chat.
|
|
671
|
+
Register the application's callback and update that registration and its
|
|
672
|
+
environment binding when the callback domain changes. Compute billing belongs
|
|
673
|
+
to the Snowflake account. Use application authorization, reference resolution
|
|
674
|
+
and durable storage; the editor does not hold the grant.
|
|
675
|
+
|
|
676
|
+
## Gemini Enterprise search
|
|
677
|
+
|
|
678
|
+
Use `geminiEnterpriseProvider` from
|
|
679
|
+
`@jskit-ai/connectors-catalog/server/gemini-enterprise` with the existing core
|
|
680
|
+
connection service. `docs/gemini-enterprise.md` contains the portable file and
|
|
681
|
+
provider setup worksheet. Store `projectId`, `location` (`global`, `us`, `eu`)
|
|
682
|
+
and `engineId` as settings, with a confidential Google OAuth registration and
|
|
683
|
+
the `https://www.googleapis.com/auth/cloud-platform` scope. The settings choose
|
|
684
|
+
the API origin and the engine under `default_collection`; callers cannot change
|
|
685
|
+
the target or supply a source identity in an operation request.
|
|
686
|
+
|
|
687
|
+
`engine.get` checks metadata access. `search` accepts `query`, `pageSize` (1–25,
|
|
688
|
+
default 10) and optional `pageToken`. Reuse the same query/page size while
|
|
689
|
+
paginating. The result is Google's JSON envelope, not a generated answer. Treat
|
|
690
|
+
document snippets and `redirectUri` as untrusted data; do not follow returned URLs
|
|
691
|
+
automatically. Search permission and source access are separate from engine
|
|
692
|
+
metadata permission. Shared and assistant modes act as one connected Google
|
|
693
|
+
account, so authorize every caller before exposing that account's search results.
|
|
694
|
+
This fragment implements no per-user Google identity, Workforce Identity, widget,
|
|
695
|
+
resource ingestion, app login or chat sessions.
|
|
696
|
+
|
|
697
|
+
The application implements and registers its own callback. A callback domain
|
|
698
|
+
change requires updating its provider registration and environment binding.
|
|
699
|
+
Independent Google Cloud registration projects can separate some quotas, but
|
|
700
|
+
engine billing and limits also depend on the project hosting the engine. Don't
|
|
701
|
+
claim two OAuth client IDs isolate all paid/free consumption. An authorized AI
|
|
702
|
+
can help prepare resource/IAM configuration; Google Auth Platform client setup,
|
|
703
|
+
verification, consent and licensing remain explicit operator/provider tasks.
|
|
704
|
+
|
|
705
|
+
## Workday composition
|
|
706
|
+
|
|
707
|
+
Import `workdayProvider` from `@jskit-ai/connectors-catalog/server/workday` and
|
|
708
|
+
use the portable file and administrator steps in `docs/workday.md`. This is a
|
|
709
|
+
per-user tenant connection with three endpoint fields, Client ID and secret and
|
|
710
|
+
callback references. Its confidential flow omits PKCE and URL scope strings;
|
|
711
|
+
Staffing functional areas and user domain permissions are configured in Workday.
|
|
712
|
+
Keep that provider exception inside the library. Other providers retain S256.
|
|
713
|
+
|
|
714
|
+
Use `workers.me` for the connected worker and `workers.list` for explicit pages
|
|
715
|
+
with limit, offset, optional name/worker-ID search and visibility flags. The
|
|
716
|
+
library selects Staffing v7 on the configured API host, path prefix and tenant;
|
|
717
|
+
never substitute another user's token or derive ownership from request input.
|
|
718
|
+
An account without a visible worker record cannot pass the initial check.
|
|
719
|
+
|
|
720
|
+
Every customer tenant needs its own registration and the application's actual
|
|
721
|
+
callback URL. Distinct client IDs do not imply separate tenant quotas.
|
|
722
|
+
The CLI composes the same server APIs and encrypted file store. App login,
|
|
723
|
+
Workday Extend, ISU, SOAP, writes and bulk sync are outside
|
|
724
|
+
this initial fragment. Consent and live tenant testing require separate access.
|