UNPKG

@openpolicy/sdk

Version:

Public API for defining privacy policies with OpenPolicy

226 lines (166 loc) 8.8 kB
--- name: annotate-third-parties description: > Mark third-party service dependencies in source code using thirdParty() so the autoCollect() Vite plugin can populate the thirdParties sentinel for the privacy policy config. Covers manual annotation, usePackageJson auto-detection from the KNOWN_PACKAGES registry, combining both approaches, and the Providers preset as a static alternative. type: core library: openpolicy library_version: "0.0.19" requires: - openpolicy/vite-setup sources: - jamiedavenport/openpolicy:packages/sdk/src/third-parties.ts - jamiedavenport/openpolicy:packages/vite-auto-collect/src/known-packages.ts --- This skill builds on openpolicy/vite-setup. Read it first. ## How It Works `thirdParty()` is a **runtime no-op**. It is a build-time marker — `autoCollect()` scans source files statically via `oxc-parser` and extracts the three string literal arguments. The plugin then populates the `thirdParties` sentinel exported from `@openpolicy/sdk`. Without the plugin, `thirdParty()` calls have no effect whatsoever. The populated sentinel must be spread into the top-level `thirdParties` field in the config file. Without the spread, the plugin output is discarded and the policy renders with no third parties listed. ## Setup Three moving parts must all be in place: **1. `vite.config.ts` — enable the plugin** ```ts import { defineConfig } from "vite"; import { autoCollect } from "@openpolicy/vite-auto-collect"; export default defineConfig({ plugins: [ autoCollect({ thirdParties: { usePackageJson: true }, // optional — see below }), ], }); ``` **2. Source file — annotate next to the usage** ```ts import { thirdParty } from "@openpolicy/sdk"; // Place next to where you initialise or use the third-party SDK thirdParty("Stripe", "Payment processing", "https://stripe.com/privacy"); // ... rest of your Stripe integration ``` **3. `openpolicy.ts` — spread the sentinel into config** ```ts import { defineConfig, thirdParties } from "@openpolicy/sdk"; export default defineConfig({ company: { name: "Acme", legalName: "Acme, Inc.", address: "123 Main St, San Francisco, CA 94105", contact: "privacy@acme.com", }, effectiveDate: "2026-01-01", thirdParties: [...thirdParties], }); ``` ## Core Patterns ### 1. Manual thirdParty() annotation Call `thirdParty(name, purpose, policyUrl)` with three string literals next to wherever you initialise the third-party integration. All three arguments must be string literals — dynamic values are silently skipped by the static analyser. ```ts import { thirdParty } from "@openpolicy/sdk"; // Correct: all string literals thirdParty("Intercom", "Customer messaging", "https://www.intercom.com/legal/privacy"); // Wrong: variable — silently skipped at build time const name = "Intercom"; thirdParty(name, "Customer messaging", "https://www.intercom.com/legal/privacy"); ``` Deduplication is by `name` — the first occurrence wins when files are walked in sorted alphabetical order. Calling `thirdParty()` with the same name from multiple files is safe. ### 2. usePackageJson auto-detection `autoCollect({ thirdParties: { usePackageJson: true } })` reads `package.json` at build time and cross-references every entry in `dependencies` and `devDependencies` against the built-in KNOWN_PACKAGES registry. Matched packages are merged into `thirdParties` automatically, with deduplication by service name. This is the fastest way to cover common services (Stripe, Sentry, PostHog, Vercel, etc.) without any source annotations. ```ts // vite.config.ts autoCollect({ thirdParties: { usePackageJson: true } }) ``` See [references/known-packages.md](references/known-packages.md) for the full list of ~30 auto-detected packages. ### 3. Combining both approaches `thirdParty()` annotations and `usePackageJson` are merged at build time. The plugin deduplicates by service name — `thirdParty()` entries from source files are added first (sorted file order), then package.json detections fill in any remaining services not already seen. Use this combination when: - Most services are covered by the KNOWN_PACKAGES registry (`usePackageJson: true`) - A few services are not in the registry and need explicit `thirdParty()` calls ```ts // vite.config.ts autoCollect({ thirdParties: { usePackageJson: true } }) // src/lib/custom-analytics.ts import { thirdParty } from "@openpolicy/sdk"; thirdParty("Fathom Analytics", "Privacy-friendly web analytics", "https://usefathom.com/privacy"); ``` ```ts // openpolicy.ts — one spread covers both sources import { defineConfig, thirdParties } from "@openpolicy/sdk"; export default defineConfig({ thirdParties: [...thirdParties], }); ``` ### 4. Providers presets as a static alternative `Providers` from `@openpolicy/sdk` is a collection of pre-filled third-party objects for common services. Use this when you want to declare third parties statically in `openpolicy.ts` without any source annotations or plugin scanning. ```ts import { defineConfig, Providers } from "@openpolicy/sdk"; export default defineConfig({ thirdParties: [ Providers.Stripe, Providers.Sentry, Providers.Vercel, { name: "Custom Service", purpose: "Internal logging", policyUrl: "https://example.com/privacy" }, ], }); ``` Available presets: `Stripe`, `Paddle`, `LemonSqueezy`, `PayPal`, `GoogleAnalytics`, `PostHog`, `Plausible`, `Mixpanel`, `Vercel`, `Cloudflare`, `AWS`, `Auth0`, `Clerk`, `Resend`, `Postmark`, `SendGrid`, `Loops`, `Sentry`, `Datadog`. Note: when using `Providers` statically, you can still spread `thirdParties` alongside it to capture any additional auto-collected services: ```ts thirdParties: [...thirdParties, Providers.Cloudflare], ``` ## Common Mistakes ### HIGH — Using thirdParty() without the autoCollect() plugin and expecting a runtime effect `thirdParty()` is defined as a no-op function that immediately returns `undefined`. It has no runtime behaviour. The only way it produces output in the policy is when `autoCollect()` is present in `vite.config.ts` and scans the file at build time. ```ts // WRONG: calling thirdParty() and expecting it to affect the policy at runtime import { thirdParty } from "@openpolicy/sdk"; thirdParty("Stripe", "Payment processing", "https://stripe.com/privacy"); // Without autoCollect() in vite.config.ts, this does nothing ``` ```ts // Correct: autoCollect() in vite.config.ts is the required prerequisite // vite.config.ts import { autoCollect } from "@openpolicy/vite-auto-collect"; export default defineConfig({ plugins: [autoCollect()] }); // src/lib/stripe.ts — scanned at build time by the plugin import { thirdParty } from "@openpolicy/sdk"; thirdParty("Stripe", "Payment processing", "https://stripe.com/privacy"); ``` ### HIGH — Not spreading thirdParties sentinel into thirdParties Even when `autoCollect()` scans the source and populates the sentinel, the populated value is discarded unless it is imported and spread into the top-level `thirdParties` field in the config. The privacy policy then renders with an empty third-party section, which may be legally invalid. ```ts // WRONG: thirdParties not imported or spread export default defineConfig({ thirdParties: [], // static empty array, discards plugin output }); ``` ```ts // Correct import { defineConfig, thirdParties } from "@openpolicy/sdk"; export default defineConfig({ thirdParties: [...thirdParties], // or combine with static entries: // thirdParties: [...thirdParties, Providers.Cloudflare], }); ``` ### MEDIUM — Not enabling usePackageJson when known packages are used The KNOWN_PACKAGES registry covers ~30 common npm packages. Without `usePackageJson: true`, packages like `@sentry/browser`, `posthog-js`, or `@stripe/stripe-js` are not auto-detected and must each be annotated manually with `thirdParty()`. Enabling the option costs nothing and eliminates this annotation burden for any covered package. ```ts // WRONG: usePackageJson not enabled — known packages not auto-detected autoCollect() ``` ```ts // Correct autoCollect({ thirdParties: { usePackageJson: true } }) ``` ## References - [Known packages registry](references/known-packages.md) — full table of npm packages auto-detected by `usePackageJson: true` - `packages/sdk/src/third-parties.ts` — thirdParty() implementation (runtime no-op) - `packages/sdk/src/providers.ts` — Providers preset objects - `packages/sdk/src/auto-collected.ts` — thirdParties sentinel definition - `packages/vite-auto-collect/src/index.ts` — autoCollect() plugin, AutoCollectOptions type - `packages/vite-auto-collect/src/analyse.ts` — static AST extraction logic - `packages/vite-auto-collect/src/known-packages.ts` — KNOWN_PACKAGES registry source