@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,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"registrations": {
|
|
4
|
+
"wordpress": {
|
|
5
|
+
"source": "own",
|
|
6
|
+
"clientId": "YOUR_ASSIGNED_CLIENT_ID",
|
|
7
|
+
"clientSecretRef": "env:WORDPRESS_COM_CLIENT_SECRET",
|
|
8
|
+
"callbackUrlRef": "env:WORDPRESS_COM_CALLBACK_URL"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"integrations": {
|
|
12
|
+
"publishing": {
|
|
13
|
+
"provider": "wordpress-com",
|
|
14
|
+
"displayName": "Publishing account",
|
|
15
|
+
"accountMode": "per-user",
|
|
16
|
+
"scopes": ["users", "sites", "posts"],
|
|
17
|
+
"authentication": { "method": "oauth2", "registrationRef": "wordpress" }
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: connectors/paddle-catalogue
|
|
3
|
+
title: Create Paddle products with prices
|
|
4
|
+
summary: Compose a sequential catalogue batch and preserve partial success for application-owned recovery.
|
|
5
|
+
keywords: paddle, products, prices, batch, payments
|
|
6
|
+
requires: @jskit-ai/connectors-core, @jskit-ai/connectors-catalog
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Create Paddle products with prices
|
|
10
|
+
|
|
11
|
+
## Use when
|
|
12
|
+
|
|
13
|
+
Use the [Paddle setup guide](https://github.com/mobily-enterprises/jskit-ai/blob/main/packages/connectors-catalog/docs/paddle.md) to configure and verify the
|
|
14
|
+
application's merchant key. This recipe creates catalogue entries only.
|
|
15
|
+
Checkout, subscriptions and charging customers are separate application work.
|
|
16
|
+
|
|
17
|
+
## Do not use when
|
|
18
|
+
|
|
19
|
+
Use the payments-core reviewed catalogue workflow when the application requires
|
|
20
|
+
durable publication recovery. This bounded recipe is not that workflow.
|
|
21
|
+
|
|
22
|
+
## Framework APIs
|
|
23
|
+
|
|
24
|
+
Adapt [create-products.js](example/create-products.js) into the application's
|
|
25
|
+
backend. Replace its repository-relative provider import with
|
|
26
|
+
`@jskit-ai/connectors-catalog/server/paddle`. Pass the application's connection
|
|
27
|
+
runtime, authenticated context, integration ID and an array of `{ product,
|
|
28
|
+
price }` inputs described in the guide. The newly created product supplies the
|
|
29
|
+
price's product_id. One item implements product-with-price; several implement
|
|
30
|
+
batch creation. The limit of 100 items is this recipe's bounded workload choice,
|
|
31
|
+
not a Paddle API limit. It executes serially and does not invent a remote batch
|
|
32
|
+
API or transaction.
|
|
33
|
+
|
|
34
|
+
## Invariants
|
|
35
|
+
|
|
36
|
+
The recipe validates the entire cloned batch before the first write. It calls
|
|
37
|
+
the ordinary runtime for each request, preserving authorization and the
|
|
38
|
+
connection's configured sandbox/live environment. The sandbox setting used for
|
|
39
|
+
local schema validation sends no request and does not override runtime routing.
|
|
40
|
+
|
|
41
|
+
## Product decisions
|
|
42
|
+
|
|
43
|
+
For assistant use, authorize the complete cloned request with
|
|
44
|
+
`authorizeAssistantAction`, action `products.create` for one item or
|
|
45
|
+
`products.batchCreate` for several, before calling the recipe. The host must
|
|
46
|
+
bind approval to that exact snapshot and caller. Individual runtime invocations
|
|
47
|
+
still enforce their policies; do not turn off runtime authorization to bypass
|
|
48
|
+
an additional required approval. Application use instead enforces its normal
|
|
49
|
+
administrator permissions. This file does not supply a public HTTP endpoint.
|
|
50
|
+
|
|
51
|
+
## Avoid
|
|
52
|
+
|
|
53
|
+
Retain `completed` and `failed` in app-owned operation state. A failed price
|
|
54
|
+
step includes the newly created product ID. No later items run after failure,
|
|
55
|
+
and no failed call is retried. An interrupted request may have succeeded at
|
|
56
|
+
Paddle; inspect the merchant catalogue before repeating any write. Process
|
|
57
|
+
termination can prevent the returned report from being saved, so an application
|
|
58
|
+
needing crash recovery must record each completed step durably. This small
|
|
59
|
+
recipe does not promise crash recovery, rollback or exactly-once execution.
|
|
60
|
+
|
|
61
|
+
## Variation points
|
|
62
|
+
|
|
63
|
+
CLI users can call this same JavaScript recipe with their own runtime. Vibe64
|
|
64
|
+
configures the project; it does not execute catalogue writes on configuration
|
|
65
|
+
save. Laravel applications implement this composition with their own framework
|
|
66
|
+
and Paddle client, without importing JavaScript or depending on Vibe64.
|
|
67
|
+
|
|
68
|
+
## Example files
|
|
69
|
+
|
|
70
|
+
- [create-products.js](example/create-products.js): sequential product/price
|
|
71
|
+
composition with input validation and a partial-success report.
|
|
72
|
+
|
|
73
|
+
## Verification
|
|
74
|
+
|
|
75
|
+
Exercise the recipe with controlled provider responses. Verify whole-batch
|
|
76
|
+
validation before writes, authorization for each operation, product-to-price
|
|
77
|
+
identity, stop-on-failure behavior and preservation of completed IDs. A returned
|
|
78
|
+
report does not prove durable recovery or live merchant acceptance.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { paddleProvider } from "../../../src/server/paddle.js";
|
|
2
|
+
|
|
3
|
+
// Application-owned composition: pass an application-mode connection runtime.
|
|
4
|
+
// An assistant host must approve the complete batch before calling this recipe.
|
|
5
|
+
async function createProductsWithPrices({ runtime, context, integrationId, items, signal }) {
|
|
6
|
+
if (!Array.isArray(items) || !items.length || items.length > 100) {
|
|
7
|
+
throw new TypeError("Supply between 1 and 100 products with prices.");
|
|
8
|
+
}
|
|
9
|
+
const batch = structuredClone(items);
|
|
10
|
+
// Validate every item before the first write, using the adapter's own schema.
|
|
11
|
+
for (const item of batch) {
|
|
12
|
+
if (!item || typeof item !== "object" || Object.keys(item).some((key) => !["product", "price"].includes(key)) ||
|
|
13
|
+
!item.product || !item.price || Object.hasOwn(item.price, "product_id")) {
|
|
14
|
+
throw new TypeError("Each item needs product and price inputs; the new product supplies product_id.");
|
|
15
|
+
}
|
|
16
|
+
paddleProvider.operations["products.create"].request(item.product, { environment: "sandbox" });
|
|
17
|
+
paddleProvider.operations["prices.create"].request({ ...item.price, product_id: `pro_${"a".repeat(26)}` }, { environment: "sandbox" });
|
|
18
|
+
}
|
|
19
|
+
const completed = [];
|
|
20
|
+
for (const [index, item] of batch.entries()) {
|
|
21
|
+
let productId;
|
|
22
|
+
let stage = "product";
|
|
23
|
+
try {
|
|
24
|
+
const product = await runtime.invoke({ context, integrationId, signal, operation: "products.create", input: item.product });
|
|
25
|
+
productId = product.data.id;
|
|
26
|
+
stage = "price";
|
|
27
|
+
const price = await runtime.invoke({ context, integrationId, signal, operation: "prices.create", input: { ...item.price, product_id: productId } });
|
|
28
|
+
completed.push({ index, productId, priceId: price.data.id });
|
|
29
|
+
} catch {
|
|
30
|
+
// Do not replay the batch: a failed request may have reached Paddle.
|
|
31
|
+
// Do not include raw provider errors or credential-bearing diagnostics.
|
|
32
|
+
return { completed, failed: { index, stage, ...(productId ? { productId } : {}), outcome: "requires-review" } };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return { completed, failed: null };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { createProductsWithPrices };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: connectors/public-image
|
|
3
|
+
title: Public logo images from portable integration configuration
|
|
4
|
+
summary: Resolve a publishable image key deliberately and use the shared URL library in a browser, backend or CLI.
|
|
5
|
+
keywords: connectors, integrations, logo-dev, images, public-key, cli, files
|
|
6
|
+
requires: @jskit-ai/connectors-core, @jskit-ai/connectors-catalog
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Public logo images from portable integration configuration
|
|
10
|
+
|
|
11
|
+
## Use when
|
|
12
|
+
|
|
13
|
+
Use for Logo.dev's public image service. `createLogoDevImageUrl` is implemented
|
|
14
|
+
in the library; the example owns only application configuration and wiring.
|
|
15
|
+
This path does not need a server connection grant or a database.
|
|
16
|
+
|
|
17
|
+
## Do not use when
|
|
18
|
+
|
|
19
|
+
Private JSON API keys, user OAuth tokens and managed service credentials must
|
|
20
|
+
not be placed in public image URLs. Logo.dev search/describe use different
|
|
21
|
+
credentials and are outside this pattern.
|
|
22
|
+
|
|
23
|
+
## Product decisions
|
|
24
|
+
|
|
25
|
+
Choose the domains that may load images, attribution placement and missing-image
|
|
26
|
+
behavior. Choose whether a build step publishes the permitted key in public
|
|
27
|
+
configuration or an authorized backend returns image URLs. The application's
|
|
28
|
+
existing access policy applies before exposing its configured resources.
|
|
29
|
+
|
|
30
|
+
## Invariants
|
|
31
|
+
|
|
32
|
+
- CLI and Vibe64 edit the same reference-only `integrations.json`.
|
|
33
|
+
- Only a `pk_` key enters an image URL; a private key fails validation.
|
|
34
|
+
- URL creation is local and does not establish a verified account connection.
|
|
35
|
+
- Browser load/error events report delivery. A monogram is not proof of a brand logo.
|
|
36
|
+
- Domain restrictions concern the app that loads the image, including previews
|
|
37
|
+
and custom domains. The editor VM may have a different origin.
|
|
38
|
+
|
|
39
|
+
## Framework APIs
|
|
40
|
+
|
|
41
|
+
Use `parseIntegrationConfiguration` from connectors-core/shared/configuration,
|
|
42
|
+
`logoDevDefinition` from connectors-catalog/shared, and
|
|
43
|
+
`createLogoDevImageUrl` from connectors-catalog/client/logo-dev. The latter is
|
|
44
|
+
portable to Node and browsers and exposes `logoDevImageSchema` for input fields.
|
|
45
|
+
Use the application's reference resolver; no environment object goes to the
|
|
46
|
+
browser. See [provider setup](https://github.com/mobily-enterprises/jskit-ai/blob/main/packages/connectors-catalog/docs/logo-dev.md) for inputs and limitations.
|
|
47
|
+
|
|
48
|
+
## Example files
|
|
49
|
+
|
|
50
|
+
`integrations.json` is ordinary application source. `logo-url.js` demonstrates
|
|
51
|
+
resolving its chosen integration and producing a public URL from the library.
|
|
52
|
+
Supply authorized configuration, a resolver and the desired image input:
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
const url = await logoUrlFromConfiguration({
|
|
56
|
+
configurationText, integrationId: "logos", resolveReference,
|
|
57
|
+
image: { domain: "example.com", fallback: "404" }
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
In Vue, compute the URL from approved public configuration and bind `:src` on
|
|
62
|
+
an `<img>` with `alt`, `referrerpolicy="origin"` and an `@error` fallback. A CLI
|
|
63
|
+
can print or embed the same URL without generating an application. Treat the
|
|
64
|
+
returned URL as containing a public key; do not substitute a private credential.
|
|
65
|
+
|
|
66
|
+
## Variation points
|
|
67
|
+
|
|
68
|
+
Application code owns public configuration delivery, allowed domains, display
|
|
69
|
+
size, theme and fallback. Use explicit permanent-hosting arrangements if the
|
|
70
|
+
product needs to retain or redistribute provider assets.
|
|
71
|
+
|
|
72
|
+
## Verification
|
|
73
|
+
|
|
74
|
+
Library tests cover key and domain validation, option bounds and fixed-origin
|
|
75
|
+
URL construction. Browser fixtures exercise simulated image success and error.
|
|
76
|
+
Source-pattern tests use a supplied resolver and reject a different provider
|
|
77
|
+
slot. Editor tests verify reference-only source, field errors and reload.
|
|
78
|
+
These checks need neither live credentials nor generated sample applications.
|
|
79
|
+
|
|
80
|
+
## Avoid
|
|
81
|
+
|
|
82
|
+
Do not call server `connectApiKey` to manufacture a Connected receipt for this
|
|
83
|
+
image flow. Do not send a secret key, an environment dump or a caller-selected
|
|
84
|
+
service origin to the browser. Do not treat key naming as provider quota isolation.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"registrations": {},
|
|
4
|
+
"integrations": {
|
|
5
|
+
"logos": {
|
|
6
|
+
"provider": "logo-dev",
|
|
7
|
+
"displayName": "Company logos",
|
|
8
|
+
"accountMode": "shared",
|
|
9
|
+
"scopes": [],
|
|
10
|
+
"authentication": { "method": "api-key", "secretRef": "env:LOGO_DEV_PUBLISHABLE_KEY" }
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { parseIntegrationConfiguration } from "@jskit-ai/connectors-core/shared/configuration";
|
|
2
|
+
import { logoDevDefinition } from "@jskit-ai/connectors-catalog/shared";
|
|
3
|
+
import { createLogoDevImageUrl } from "@jskit-ai/connectors-catalog/client/logo-dev";
|
|
4
|
+
|
|
5
|
+
// The application authorizes access before passing its configuration and resolver.
|
|
6
|
+
async function logoUrlFromConfiguration({ configurationText, integrationId, resolveReference, image }) {
|
|
7
|
+
const configuration = parseIntegrationConfiguration(configurationText, { providers: [logoDevDefinition], allowUnknownProviders: true });
|
|
8
|
+
const integration = configuration.integrations[integrationId];
|
|
9
|
+
if (!Object.hasOwn(configuration.integrations, integrationId) || integration.provider !== "logo-dev") {
|
|
10
|
+
throw new Error("Select a configured Logo.dev integration.");
|
|
11
|
+
}
|
|
12
|
+
const publishableKey = await resolveReference(integration.authentication.secretRef);
|
|
13
|
+
return createLogoDevImageUrl({ ...image, publishableKey });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { logoUrlFromConfiguration };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: connectors/redshift-queries
|
|
3
|
+
title: Redshift queries with shared AWS credentials
|
|
4
|
+
summary: Compose file configuration, Redshift Data API operations and application query ownership.
|
|
5
|
+
keywords: redshift, aws, sql, warehouse, serverless, provisioned, iam, connectors, cli, files
|
|
6
|
+
requires: @jskit-ai/connectors-core, @jskit-ai/connectors-catalog
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Redshift queries with shared AWS credentials
|
|
10
|
+
|
|
11
|
+
## Use when
|
|
12
|
+
|
|
13
|
+
A CLI operator or application backend needs database/schema/table metadata or authorized SQL in
|
|
14
|
+
one configured Redshift warehouse. JSKIT owns configuration validation, AWS SDK
|
|
15
|
+
signing, operation input validation, target checks and response parsing. The
|
|
16
|
+
application owns which user may submit a query or access its result.
|
|
17
|
+
|
|
18
|
+
## Do not use when
|
|
19
|
+
|
|
20
|
+
This fragment does not provide application login, per-user IAM Identity Center
|
|
21
|
+
federation, warehouse provisioning or a managed paid/public allocation. Never
|
|
22
|
+
turn a shared AWS key into an unrestricted SQL endpoint for application users.
|
|
23
|
+
SQL can modify data; read-only behavior requires appropriate database grants.
|
|
24
|
+
|
|
25
|
+
## Product decisions
|
|
26
|
+
|
|
27
|
+
Select serverless or provisioned in the same JSON edited by Vibe64. Serverless
|
|
28
|
+
requires a workgroup name; provisioned requires a cluster identifier and may use
|
|
29
|
+
an explicit database user. Both require a database and region. Store AWS secrets
|
|
30
|
+
outside the file. Temporary credentials additionally need `sessionTokenRef` and
|
|
31
|
+
host renewal. See the [Redshift guide](https://github.com/mobily-enterprises/jskit-ai/blob/main/packages/connectors-catalog/docs/amazon-redshift.md) for setup,
|
|
32
|
+
field names, automation feasibility and remaining federation work.
|
|
33
|
+
|
|
34
|
+
## Invariants
|
|
35
|
+
|
|
36
|
+
Use the application's existing authentication and authorization policy to build
|
|
37
|
+
the trusted context. Bind logical query tokens and returned statement IDs to
|
|
38
|
+
the actual application/user in application-owned state; a text file can hold
|
|
39
|
+
that state. Authorize exact SQL, parameter values and statement ownership before
|
|
40
|
+
invoking the service. Matching the configured warehouse is only a target check.
|
|
41
|
+
|
|
42
|
+
The library does not resolve ambient AWS profiles or switch to a more privileged
|
|
43
|
+
account after a denial. The application resolves its own credential bindings; editable references do
|
|
44
|
+
not grant AWS permissions. This shared credential mode has no provider callback
|
|
45
|
+
URL and does not depend on an Online registration or allocation.
|
|
46
|
+
|
|
47
|
+
## Framework APIs
|
|
48
|
+
|
|
49
|
+
Follow the [API-key connection pattern](../api-key-connection/PATTERN.md) to read
|
|
50
|
+
configuration, create protected file connection storage, resolve explicit
|
|
51
|
+
bindings and implement `authorize`. Register this runtime export:
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
import { amazonRedshiftProvider } from "@jskit-ai/connectors-catalog/server/amazon-redshift";
|
|
55
|
+
const providers = [amazonRedshiftProvider];
|
|
56
|
+
// Pass providers with configuration, store, resolveReference and authorize
|
|
57
|
+
// to createConnectionService or the ordinary connector Feature.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The library's `connectApiKey({context, integrationId})` reads a table metadata
|
|
61
|
+
page. It does not submit SQL or grant future query permission. Use
|
|
62
|
+
`databases.list` for visible database names, `schemas.list` for schemas in the
|
|
63
|
+
configured database, `tables.list` for tables and `table.describe` for columns.
|
|
64
|
+
Each listing accepts `maxResults` (1–1000) and an opaque `nextToken`; schema
|
|
65
|
+
listing also accepts `schemaPattern`. An absent or empty NextToken ends paging.
|
|
66
|
+
Database names returned by discovery do not change this connection's configured
|
|
67
|
+
target or authorize another database. Use another project-owned configuration
|
|
68
|
+
slot for another database and authorize metadata visibility before invocation.
|
|
69
|
+
|
|
70
|
+
## Example files
|
|
71
|
+
|
|
72
|
+
[example/integrations.json](example/integrations.json) has two independent
|
|
73
|
+
configuration slots demonstrating both deployment types. Actual resource names
|
|
74
|
+
and environment bindings must come from the owner. Do not generate a new app to
|
|
75
|
+
use these libraries; compose them in the existing backend or CLI entry point.
|
|
76
|
+
|
|
77
|
+
After the application has authorized the statement and stored its logical
|
|
78
|
+
request token, call:
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
const submitted = await service.invoke({
|
|
82
|
+
context, integrationId: "serverless-reports", operation: "query.start",
|
|
83
|
+
input: {
|
|
84
|
+
sql: "select order_id::varchar, total from reporting.orders where customer_id = :customer limit 100",
|
|
85
|
+
parameters: [{ name: "customer", value: authorizedCustomerId }],
|
|
86
|
+
clientToken: storedLogicalRequestToken
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
// Persist submitted.Id with the authorized application's query owner.
|
|
90
|
+
const status = await service.invoke({
|
|
91
|
+
context, integrationId: "serverless-reports", operation: "query.status",
|
|
92
|
+
input: { statementId: submitted.Id }
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Use parameters for values; do not concatenate user input into the SQL. Tokens
|
|
97
|
+
are required, case-sensitive and 1–64 characters. Reuse the same token only for
|
|
98
|
+
the same logical request and identical input within AWS's deduplication window.
|
|
99
|
+
An ambiguous response must not trigger an automatic submission with a new token.
|
|
100
|
+
|
|
101
|
+
A returned ID is submission, not completion. `query.status` reports SUBMITTED,
|
|
102
|
+
PICKED, STARTED, FINISHED, ABORTED or FAILED. The application controls bounded
|
|
103
|
+
polling and cancellation. When status is FINISHED with a result set:
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
const page = await service.invoke({
|
|
107
|
+
context, integrationId: "serverless-reports", operation: "query.results",
|
|
108
|
+
input: { statementId: authorizedStatementId }
|
|
109
|
+
});
|
|
110
|
+
// ColumnMetadata describes each position in Records. Preserve typed cells.
|
|
111
|
+
// If another page is needed, pass page.NextToken unchanged as nextToken.
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Result cells retain AWS's tags: `stringValue`, `longValue`, `doubleValue`,
|
|
115
|
+
`booleanValue`, `isNull` and `blobValue`. Do not collapse empty strings, zero or
|
|
116
|
+
false into null. Binary values are Uint8Array; explicitly encode them in an
|
|
117
|
+
application JSON response. Large integers outside JavaScript's safe range are
|
|
118
|
+
rejected: select them as VARCHAR for exact text. Results are one AWS page;
|
|
119
|
+
there is no `maxResults` parameter for `query.results`.
|
|
120
|
+
|
|
121
|
+
For explicit remote cancellation, authorize the statement owner then invoke
|
|
122
|
+
`query.cancel` with its ID. The returned boolean receipt does not establish
|
|
123
|
+
rollback or a final job state. Read status if the final outcome is needed.
|
|
124
|
+
Closing a UI, aborting local HTTP or disconnecting does not cancel remote SQL.
|
|
125
|
+
|
|
126
|
+
## Variation points
|
|
127
|
+
|
|
128
|
+
Change only the configured resource slot when targeting a provisioned cluster.
|
|
129
|
+
The operation interface stays the same. An explicit `databaseUser` uses that
|
|
130
|
+
database identity; omit it for the IAM-derived identity. Table listing and
|
|
131
|
+
description accept a bounded page size and opaque cursors. Metadata filters
|
|
132
|
+
support AWS's SQL-style patterns.
|
|
133
|
+
|
|
134
|
+
## Avoid
|
|
135
|
+
|
|
136
|
+
Do not expose arbitrary database/workgroup overrides, use query IDs as bearer
|
|
137
|
+
authorization, log SQL/result metadata indiscriminately, assume that a table
|
|
138
|
+
listing proves every SELECT permission, or reimplement AWS signing in scaffolding.
|
|
139
|
+
The runtime does not enforce SELECT-only SQL by parsing or matching prefixes.
|
|
140
|
+
|
|
141
|
+
## Verification
|
|
142
|
+
|
|
143
|
+
Run the single focused `test/amazon-redshift.test.js` file in the catalogue
|
|
144
|
+
package. It uses real SDK signing with controlled responses and file storage.
|
|
145
|
+
It covers both targets, input validation, SQL parameters, statement checks,
|
|
146
|
+
typed result pages, credentials, errors and local cancellation. Shared-form
|
|
147
|
+
browser checks pass at phone, tablet and desktop sizes; Public editor checks
|
|
148
|
+
pass at phone/desktop sizes for both deployment types, region selection,
|
|
149
|
+
validation, inactive-field removal and save/reload.
|
|
150
|
+
No live AWS account, executed SQL or generated application is claimed.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"registrations": {},
|
|
4
|
+
"integrations": {
|
|
5
|
+
"serverless-reports": {
|
|
6
|
+
"provider": "amazon-redshift",
|
|
7
|
+
"accountMode": "shared",
|
|
8
|
+
"scopes": [],
|
|
9
|
+
"authentication": { "method": "api-key", "secretRef": "env:REPORTING_AWS_SECRET_ACCESS_KEY" },
|
|
10
|
+
"settings": {
|
|
11
|
+
"deploymentType": "serverless",
|
|
12
|
+
"region": "us-east-1",
|
|
13
|
+
"accessKeyIdRef": "env:REPORTING_AWS_ACCESS_KEY_ID",
|
|
14
|
+
"workgroup": "analytics",
|
|
15
|
+
"database": "dev"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"cluster-reports": {
|
|
19
|
+
"provider": "amazon-redshift",
|
|
20
|
+
"accountMode": "shared",
|
|
21
|
+
"scopes": [],
|
|
22
|
+
"authentication": { "method": "api-key", "secretRef": "env:CLUSTER_AWS_SECRET_ACCESS_KEY" },
|
|
23
|
+
"settings": {
|
|
24
|
+
"deploymentType": "provisioned",
|
|
25
|
+
"region": "us-east-1",
|
|
26
|
+
"accessKeyIdRef": "env:CLUSTER_AWS_ACCESS_KEY_ID",
|
|
27
|
+
"clusterIdentifier": "analytics-cluster",
|
|
28
|
+
"database": "dev",
|
|
29
|
+
"databaseUser": "report_reader"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: connectors/source-scanning
|
|
3
|
+
title: Authorised project source scans with Wiz
|
|
4
|
+
summary: Use the shared scanner runtime from a CLI or a host worker with portable configuration and explicit source ownership.
|
|
5
|
+
keywords: connectors, integrations, wiz, security, source, scanning, cli, worker, cancellation
|
|
6
|
+
requires: @jskit-ai/connectors-core, @jskit-ai/connectors-catalog
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Authorised project source scans with Wiz
|
|
10
|
+
|
|
11
|
+
## Use when
|
|
12
|
+
|
|
13
|
+
A CLI or host needs to scan an authorised source snapshot with its own Wiz account.
|
|
14
|
+
`createWizScanner` implements configuration checks, command construction,
|
|
15
|
+
credential isolation, bounded process execution, report validation and cleanup.
|
|
16
|
+
The example wires that library to application-owned authority and snapshot lookup.
|
|
17
|
+
|
|
18
|
+
## Do not use when
|
|
19
|
+
|
|
20
|
+
This is not an HTTP application-data connector, user login, a managed gateway,
|
|
21
|
+
or an implementation of Vibe64's coding agents. It does not generate an app.
|
|
22
|
+
Auth0 and native Windows execution are not implemented in the current runner.
|
|
23
|
+
|
|
24
|
+
## Product decisions
|
|
25
|
+
|
|
26
|
+
The host chooses which principals may scan which projects, the stable application
|
|
27
|
+
and shared subject identities, snapshot lifetime, worker resource/network limits,
|
|
28
|
+
Wiz policies and authorised report readers. It decides how to display findings
|
|
29
|
+
and whether a blocking verdict prevents a later operation.
|
|
30
|
+
|
|
31
|
+
## Invariants
|
|
32
|
+
|
|
33
|
+
- CLI and UI edit the same reference-only `integrations.json`.
|
|
34
|
+
- Browser input never supplies a source path, executable, environment or identity.
|
|
35
|
+
- The host checks access before resolving source and credentials.
|
|
36
|
+
- The snapshot must remain immutable while the scan runs; keep its revision with
|
|
37
|
+
the findings and mark the result stale when current source differs.
|
|
38
|
+
- A passed policy verdict is not a proof that there are no vulnerabilities.
|
|
39
|
+
- Missing/invalid reports, cancellation and failed scans never become clean scans.
|
|
40
|
+
- Provider credentials are isolated from coding-agent sessions and credentials.
|
|
41
|
+
- The host supplies its own authorized provider credentials; editor edition does
|
|
42
|
+
not select a shared Vibe64 provider account.
|
|
43
|
+
|
|
44
|
+
## Framework APIs
|
|
45
|
+
|
|
46
|
+
Use `parseIntegrationConfiguration` from connectors-core/shared/configuration,
|
|
47
|
+
`wizDefinition` from connectors-catalog/shared, and `createWizScanner` from
|
|
48
|
+
connectors-catalog/server/wiz. Supply the host's `authorize`, `resolveReference`,
|
|
49
|
+
`resolveScanTarget` and installed CLI absolute path. The runtime's `scan` operation
|
|
50
|
+
accepts only context, integration ID and an optional AbortSignal.
|
|
51
|
+
See [Wiz setup and limits](https://github.com/mobily-enterprises/jskit-ai/blob/main/packages/connectors-catalog/docs/wiz.md).
|
|
52
|
+
|
|
53
|
+
## Example files
|
|
54
|
+
|
|
55
|
+
`source-scanner.js` reads a normal text configuration file and returns the scanner.
|
|
56
|
+
Both an authenticated HTTP handler and an ordinary CLI command can call it.
|
|
57
|
+
Its callbacks belong to the application; do not replace them with unconditional
|
|
58
|
+
approval in a multi-user service. Do not run this example merely to validate source.
|
|
59
|
+
|
|
60
|
+
## Variation points
|
|
61
|
+
|
|
62
|
+
CLI commands can use local user authority; a server uses its workspace/project
|
|
63
|
+
policy. Hosts may set the deadline, report-size limit, proxy and CA environment
|
|
64
|
+
for an isolated worker. Snapshot creation and findings storage stay host-owned.
|
|
65
|
+
|
|
66
|
+
A Laravel application can use a PHP worker to invoke the same installed Wiz CLI
|
|
67
|
+
or call an explicitly configured scan worker over HTTP. It reads ordinary JSON
|
|
68
|
+
and needs no Node/JSKIT runtime. That PHP or HTTP implementation owns its process
|
|
69
|
+
and identity boundary; this package supplies a working JavaScript implementation
|
|
70
|
+
and documents the protocol, not an already implemented PHP library or gateway.
|
|
71
|
+
|
|
72
|
+
## Verification
|
|
73
|
+
|
|
74
|
+
Use a controlled executable and temporary source to verify command arguments,
|
|
75
|
+
isolated credentials, policy results, malformed reports, cancellation and cleanup.
|
|
76
|
+
Editor checks cover all configuration fields and persistence. Actual authentication
|
|
77
|
+
and findings require separately authorised provider acceptance.
|
|
78
|
+
|
|
79
|
+
## Avoid
|
|
80
|
+
|
|
81
|
+
Do not infer workspace grants from a shared slot, return raw provider stderr,
|
|
82
|
+
replay scans automatically, pass arbitrary CLI flags, use a mutable working tree
|
|
83
|
+
as if it were a fixed revision, or substitute a generic API reader for source scans.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { parseIntegrationConfiguration } from "@jskit-ai/connectors-core/shared/configuration";
|
|
3
|
+
import { wizDefinition } from "@jskit-ai/connectors-catalog/shared";
|
|
4
|
+
import { createWizScanner } from "@jskit-ai/connectors-catalog/server/wiz";
|
|
5
|
+
|
|
6
|
+
export async function projectSourceScanner({ configFile = "integrations.json", installedWizCliPath,
|
|
7
|
+
authorize, resolveReference, resolveScanTarget, environment }) {
|
|
8
|
+
const configuration = parseIntegrationConfiguration(await readFile(configFile, "utf8"), {
|
|
9
|
+
providers: [wizDefinition], allowUnknownProviders: true
|
|
10
|
+
});
|
|
11
|
+
return createWizScanner({ configuration, executable: installedWizCliPath,
|
|
12
|
+
authorize, resolveReference, resolveScanTarget, environment });
|
|
13
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { validateSchemaPayload } from "@jskit-ai/kernel/shared/validators";
|
|
2
|
+
import { firebaseCloudMessagingDefinition } from "../shared/firebase-cloud-messaging.js";
|
|
3
|
+
|
|
4
|
+
function firebaseCloudMessagingWebConfiguration(settings) {
|
|
5
|
+
if (settings?.clientMode !== "web") throw new TypeError("Select Include web push before configuring browser registration.");
|
|
6
|
+
const values = validateSchemaPayload({ schema: firebaseCloudMessagingDefinition.settingsSchema(settings), mode: "replace" }, settings);
|
|
7
|
+
return { firebaseConfig: { projectId: values.projectId, apiKey: values.apiKey, appId: values.appId, messagingSenderId: values.appId.split(":")[1] }, vapidKey: values.vapidKey };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { firebaseCloudMessagingWebConfiguration };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Optional browser implementation. The application owns consent and route hooks.
|
|
2
|
+
const installations = new WeakMap();
|
|
3
|
+
|
|
4
|
+
function createGoogleAnalytics({ measurementId, window: browser = globalThis.window } = {}) {
|
|
5
|
+
if (typeof measurementId !== "string" || !/^G-[A-Z0-9]+$/.test(measurementId) || measurementId.length > 64) throw new TypeError("Supply a valid GA4 Measurement ID.");
|
|
6
|
+
if (!browser?.document) throw new TypeError("Initialize Google Analytics in the browser after hydration.");
|
|
7
|
+
const existing = installations.get(browser);
|
|
8
|
+
if (existing) {
|
|
9
|
+
if (existing.measurementId !== measurementId) throw new Error("This page already has an Analytics owner. Reload to change the Measurement ID.");
|
|
10
|
+
return existing.controller;
|
|
11
|
+
}
|
|
12
|
+
if (browser.gtag || browser.document.querySelector('script[src*="googletagmanager.com/"]')) throw new Error("Use the application's existing Google tag or Tag Manager instead of installing a second tracker.");
|
|
13
|
+
if (browser.dataLayer !== undefined && !Array.isArray(browser.dataLayer)) throw new TypeError("The existing dataLayer must be an array.");
|
|
14
|
+
let enabled = false, initialized = false, disposed = false, script, lastPage;
|
|
15
|
+
const disabledKey = `ga-disable-${measurementId}`;
|
|
16
|
+
browser[disabledKey] = true;
|
|
17
|
+
function active() { if (disposed) throw new Error("Analytics has been disposed. Reload before configuring tracking again."); }
|
|
18
|
+
function queue(...args) { browser.gtag(...args); }
|
|
19
|
+
const controller = Object.freeze({
|
|
20
|
+
setConsent(granted) {
|
|
21
|
+
active();
|
|
22
|
+
if (typeof granted !== "boolean") throw new TypeError("Pass an explicit consent boolean.");
|
|
23
|
+
enabled = granted;
|
|
24
|
+
browser[disabledKey] = !granted;
|
|
25
|
+
if (!granted) { lastPage = undefined; return; }
|
|
26
|
+
if (initialized) return;
|
|
27
|
+
// Check again: another integration may have installed a tag since creation.
|
|
28
|
+
if (browser.gtag || browser.document.querySelector('script[src*="googletagmanager.com/"]')) {
|
|
29
|
+
enabled = false; browser[disabledKey] = true;
|
|
30
|
+
throw new Error("Use the application's existing Google tracking installation.");
|
|
31
|
+
}
|
|
32
|
+
browser.dataLayer ||= [];
|
|
33
|
+
browser.gtag = function () { browser.dataLayer.push(arguments); };
|
|
34
|
+
queue("js", new Date());
|
|
35
|
+
queue("config", measurementId, { send_page_view: false });
|
|
36
|
+
script = browser.document.createElement("script");
|
|
37
|
+
script.async = true;
|
|
38
|
+
script.src = `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(measurementId)}`;
|
|
39
|
+
browser.document.head.appendChild(script);
|
|
40
|
+
initialized = true;
|
|
41
|
+
},
|
|
42
|
+
pageView({ location = browser.location.href, title = browser.document.title } = {}) {
|
|
43
|
+
active();
|
|
44
|
+
if (!enabled) return false;
|
|
45
|
+
const url = new URL(location);
|
|
46
|
+
if (!["https:", "http:"].includes(url.protocol) || url.username || url.password) throw new TypeError("Supply a public HTTP(S) page URL without credentials.");
|
|
47
|
+
if (typeof title !== "string") throw new TypeError("Supply a page title.");
|
|
48
|
+
if (lastPage === url.href) return false;
|
|
49
|
+
const previous = lastPage;
|
|
50
|
+
lastPage = url.href;
|
|
51
|
+
queue("event", "page_view", { send_to: measurementId, page_location: url.href, page_title: title, ...(previous ? { page_referrer: previous } : {}) });
|
|
52
|
+
return true;
|
|
53
|
+
},
|
|
54
|
+
event(name, parameters = {}) {
|
|
55
|
+
active();
|
|
56
|
+
if (!enabled) return false;
|
|
57
|
+
if (typeof name !== "string" || !/^[A-Za-z][A-Za-z0-9_]{0,39}$/.test(name) || /^(?:google_|ga_|firebase_)/.test(name) || name === "page_view") throw new TypeError("Use a valid event name; page views use pageView.");
|
|
58
|
+
if (!parameters || typeof parameters !== "object" || Array.isArray(parameters)) throw new TypeError("Supply an event parameter object.");
|
|
59
|
+
queue("event", name, { ...parameters, send_to: measurementId });
|
|
60
|
+
return true;
|
|
61
|
+
},
|
|
62
|
+
dispose() {
|
|
63
|
+
enabled = false; disposed = true; browser[disabledKey] = true;
|
|
64
|
+
script?.remove();
|
|
65
|
+
// Loaded Google code cannot be unloaded. Keep ownership until page reload.
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
installations.set(browser, { measurementId, controller });
|
|
69
|
+
return controller;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { createGoogleAnalytics };
|