{"_id":"@adopt-tech/provisioning","_rev":"5-a5f1a047f076a6d24007f0c4571588f3","name":"@adopt-tech/provisioning","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@adopt-tech/provisioning","version":"1.0.0","keywords":["adopt","goadopt","provisioning","compliance","cookies","lgpd","gdpr"],"author":{"name":"AdOpt","email":"dev@goadopt.io"},"license":"MIT","_id":"@adopt-tech/provisioning@1.0.0","maintainers":[{"name":"axeptiotech","email":"tech@axeptio.eu"}],"dist":{"shasum":"c66b1c6eb619ff678d9780cd8cc142248a7bcbdd","tarball":"https://registry.npmjs.org/@adopt-tech/provisioning/-/provisioning-1.0.0.tgz","fileCount":446,"integrity":"sha512-X88iRSWKnsQZTflR3/9+72zPPmmEJRMdj9V5Dmxsjm+1mfBXBiJJL87QuqRFko8FUoAAY43ayQB76xkkn5yLhQ==","signatures":[{"sig":"MEYCIQDVG/9pE0AubjhivFe2zJ9JIyCq2sW+nosWDbeSXvdv4QIhALnZqpqOCE+dlPThMh/0r2yYYkRCJPU3EYhhb0FEXCyt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":641877},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"8684038500ac3cab2c74c244079a6cc2bcac7d3d","scripts":{"cli":"ts-node src/cli.ts","dev":"tsc --watch","lint":"eslint 'src/**/*.ts'","test":"jest --selectProjects unit","build":"tsc","format":"eslint 'src/**/*.ts' --fix","prepare":"husky","test:live":"jest --selectProjects live","test:watch":"jest --selectProjects unit --watch","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"jest --selectProjects unit --coverage"},"_npmUser":{"name":"axeptiotech","email":"tech@axeptio.eu"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.","_npmVersion":"10.8.2","description":"Type-safe JS toolkit for creating and managing Adopt entities, configurations, and subscriptions","directories":{},"_nodeVersion":"20.20.0","dependencies":{"pino":"^10.3.1","graphql":"^16.9.0","fs-extra":"^11.2.0","graphql-request":"^6.1.0"},"_hasShrinkwrap":false,"devDependencies":{"ora":"^5.4.1","jest":"^29.7.0","chalk":"^4.1.2","husky":"^9.0.0","yargs":"^17.7.2","eslint":"^8.57.0","ts-jest":"^29.1.0","ts-node":"^10.9.1","prettier":"^3.2.0","cli-table3":"^0.6.3","commitlint":"^19.0.0","typescript":"^5.3.2","@types/jest":"^29.5.0","@types/node":"^20.10.0","pino-pretty":"^13.1.3","@types/yargs":"^17.0.32","@commitlint/cli":"^19.0.0","@types/fs-extra":"^11.0.4","semantic-release":"^24.0.0","@semantic-release/git":"^10.0.0","eslint-plugin-sonarjs":"^0.25.0","@semantic-release/github":"^10.0.0","@typescript-eslint/parser":"^7.0.0","@semantic-release/changelog":"^6.0.0","@commitlint/config-conventional":"^19.8.1","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/provisioning_1.0.0_1777299149488_0.9195486959525974","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@adopt-tech/provisioning","version":"1.0.1","keywords":["adopt","goadopt","provisioning","compliance","cookies","lgpd","gdpr"],"author":{"name":"AdOpt","email":"dev@goadopt.io"},"license":"MIT","_id":"@adopt-tech/provisioning@1.0.1","maintainers":[{"name":"axeptiotech","email":"tech@axeptio.eu"}],"dist":{"shasum":"0453f6c430cd4e292ae357ab7e877586834a8e59","tarball":"https://registry.npmjs.org/@adopt-tech/provisioning/-/provisioning-1.0.1.tgz","fileCount":446,"integrity":"sha512-sxeZl6n/85rnhN5zMzPbFreA8SInKx62peAeXlWYcHYyE7/UXp3jStMeHz7AsuWkd3orSSdc6OyFkzrxchq5eA==","signatures":[{"sig":"MEYCIQCoMJxa2ia1Kdn5/YgqAexjxZISDx72rKIqEvZuLazr5gIhAJZ6gQFXTR1ouSBY+9xjwAQofrNPhqAcGzrZDQ+LVDM9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":641901},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"b7b60e5fd5513ab030a9a4adc8341f7cc55a5a5e","scripts":{"cli":"ts-node src/cli.ts","dev":"tsc --watch","lint":"eslint 'src/**/*.ts'","test":"jest --selectProjects unit","build":"tsc","format":"eslint 'src/**/*.ts' --fix","prepare":"husky","test:live":"jest --selectProjects live","test:watch":"jest --selectProjects unit --watch","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"jest --selectProjects unit --coverage"},"_npmUser":{"name":"axeptiotech","email":"tech@axeptio.eu"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.","_npmVersion":"10.8.2","description":"Type-safe JS toolkit for creating and managing Adopt entities, configurations, and subscriptions","directories":{},"_nodeVersion":"20.20.0","dependencies":{"pino":"^10.3.1","graphql":"^16.9.0","fs-extra":"^11.2.0","graphql-request":"^6.1.0"},"_hasShrinkwrap":false,"devDependencies":{"ora":"^5.4.1","jest":"^29.7.0","chalk":"^4.1.2","husky":"^9.0.0","yargs":"^17.7.2","eslint":"^8.57.0","ts-jest":"^29.1.0","ts-node":"^10.9.1","prettier":"^3.2.0","cli-table3":"^0.6.3","commitlint":"^19.0.0","typescript":"^5.3.2","@types/jest":"^29.5.0","@types/node":"^20.10.0","pino-pretty":"^13.1.3","@types/yargs":"^17.0.32","@commitlint/cli":"^19.0.0","@types/fs-extra":"^11.0.4","semantic-release":"^24.0.0","@semantic-release/git":"^10.0.0","eslint-plugin-sonarjs":"^0.25.0","@semantic-release/github":"^10.0.0","@typescript-eslint/parser":"^7.0.0","@semantic-release/changelog":"^6.0.0","@commitlint/config-conventional":"^19.8.1","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/provisioning_1.0.1_1777299396797_0.521121585212929","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@adopt-tech/provisioning","version":"1.0.5","keywords":["adopt","goadopt","provisioning","compliance","cookies","lgpd","gdpr"],"author":{"name":"AdOpt","email":"dev@goadopt.io"},"license":"MIT","_id":"@adopt-tech/provisioning@1.0.5","maintainers":[{"name":"axeptiotech","email":"tech@axeptio.eu"}],"dist":{"shasum":"527f3a906e870637b3c3a6f375fd2c8dfaa2d254","tarball":"https://registry.npmjs.org/@adopt-tech/provisioning/-/provisioning-1.0.5.tgz","fileCount":434,"integrity":"sha512-zB+tvZVNYjZk6+iF+tHXcC+4A1CiKEHx5ojNHNYCl5sETZ7754LghJn9DnmrLRQc7mSvhB0DFsMkq/z68yWcgQ==","signatures":[{"sig":"MEUCIBq1BTZtMwR9L+JaofF5tpdpJv80Yd+3MG/PRAAh9bq2AiEAjIb9mTs8HPOMIQ8n7GOWSO+Qa/C+uvVmpSdi+uuP4uY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":620777},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"a819282fa5ddc719825bb903f7cf70928990b95d","scripts":{"cli":"ts-node src/cli.ts","dev":"tsc --watch","lint":"eslint 'src/**/*.ts'","test":"jest --selectProjects unit","build":"tsc","format":"eslint 'src/**/*.ts' --fix","prepare":"husky","test:live":"jest --selectProjects live","test:watch":"jest --selectProjects unit --watch","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"jest --selectProjects unit --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:df576ad2-86ad-424a-b7f6-c2a29e2d7c11"}},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.","_npmVersion":"11.13.0","description":"Type-safe JS toolkit for creating and managing Adopt entities, configurations, and subscriptions","directories":{},"_nodeVersion":"22.22.2","dependencies":{"pino":"^10.3.1","graphql":"^16.9.0","fs-extra":"^11.2.0","graphql-request":"^6.1.0"},"_hasShrinkwrap":false,"devDependencies":{"ora":"^5.4.1","jest":"^29.7.0","chalk":"^4.1.2","husky":"^9.0.0","yargs":"^17.7.2","eslint":"^8.57.0","ts-jest":"^29.1.0","ts-node":"^10.9.1","prettier":"^3.2.0","cli-table3":"^0.6.3","commitlint":"^19.0.0","typescript":"^5.3.2","@types/jest":"^29.5.0","@types/node":"^20.10.0","pino-pretty":"^13.1.3","@types/yargs":"^17.0.32","@commitlint/cli":"^19.0.0","@types/fs-extra":"^11.0.4","semantic-release":"^24.0.0","@semantic-release/git":"^10.0.0","eslint-plugin-sonarjs":"^0.25.0","@semantic-release/github":"^10.0.0","@typescript-eslint/parser":"^7.0.0","@semantic-release/changelog":"^6.0.0","@commitlint/config-conventional":"^19.8.1","@typescript-eslint/eslint-plugin":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/provisioning_1.0.5_1777310739242_0.8798805251352022","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@adopt-tech/provisioning","version":"1.1.0","description":"Type-safe JS toolkit for creating and managing Adopt entities, configurations, and subscriptions","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","dev":"tsc --watch","cli":"ts-node src/cli.ts","test":"jest --selectProjects unit","test:watch":"jest --selectProjects unit --watch","test:coverage":"jest --selectProjects unit --coverage","test:live":"jest --selectProjects live","lint":"eslint 'src/**/*.ts'","format":"eslint 'src/**/*.ts' --fix","format:check":"prettier --check 'src/**/*.ts'","prepare":"husky"},"dependencies":{"fs-extra":"^11.2.0","graphql":"^16.9.0","graphql-request":"^6.1.0","pino":"^10.3.1"},"devDependencies":{"@commitlint/cli":"^19.0.0","@commitlint/config-conventional":"^19.8.1","@semantic-release/changelog":"^6.0.0","@semantic-release/git":"^10.0.0","@semantic-release/github":"^10.0.0","@types/fs-extra":"^11.0.4","@types/jest":"^29.5.0","@types/node":"^20.10.0","@types/yargs":"^17.0.32","chalk":"^4.1.2","cli-table3":"^0.6.3","ora":"^5.4.1","yargs":"^17.7.2","@typescript-eslint/eslint-plugin":"^7.0.0","@typescript-eslint/parser":"^7.0.0","commitlint":"^19.0.0","eslint":"^8.57.0","eslint-plugin-sonarjs":"^0.25.0","husky":"^9.0.0","jest":"^29.7.0","pino-pretty":"^13.1.3","prettier":"^3.2.0","semantic-release":"^24.0.0","ts-jest":"^29.1.0","ts-node":"^10.9.1","typescript":"^5.3.2"},"keywords":["adopt","goadopt","provisioning","compliance","cookies","lgpd","gdpr"],"author":{"name":"AdOpt","email":"dev@goadopt.io"},"license":"MIT","engines":{"node":">=18"},"gitHead":"1a47eeee3a89dd35047d6b3036a459634d9732cf","_id":"@adopt-tech/provisioning@1.1.0","_nodeVersion":"22.22.2","_npmVersion":"11.13.0","dist":{"integrity":"sha512-lHjmFHpx4V/hZ3IZCfvx+4VseQpf61HbD4sB8jYRCKv6Q0TSJEZT202BFheJADzHn1Ak4LtSeQSS4P2KMr9Yog==","shasum":"a813669fd122df6f7eca8803c6e05ca17ac4553f","tarball":"https://registry.npmjs.org/@adopt-tech/provisioning/-/provisioning-1.1.0.tgz","fileCount":478,"unpackedSize":842080,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDpEklVd/MTgMHOATvD+FFoy3u8Zbf3C45FyfRVfUifSAIgVJfqhETmdTctRPw/q+TtDekSwJMdI+OsYpA3RcWsu+o="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:df576ad2-86ad-424a-b7f6-c2a29e2d7c11"}},"directories":{},"maintainers":[{"name":"axeptiotech","email":"tech@axeptio.eu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/provisioning_1.1.0_1778034737670_0.9719853843976107"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-27T14:12:29.407Z","modified":"2026-05-06T02:32:18.038Z","1.0.0":"2026-04-27T14:12:29.651Z","1.0.1":"2026-04-27T14:16:36.944Z","1.0.5":"2026-04-27T17:25:39.389Z","1.1.0":"2026-05-06T02:32:17.897Z"},"author":{"name":"AdOpt","email":"dev@goadopt.io"},"license":"MIT","keywords":["adopt","goadopt","provisioning","compliance","cookies","lgpd","gdpr"],"description":"Type-safe JS toolkit for creating and managing Adopt entities, configurations, and subscriptions","maintainers":[{"name":"axeptiotech","email":"tech@axeptio.eu"}],"readme":"# @adopt-tech/provisioning\n\n[![npm](https://img.shields.io/npm/v/@adopt-tech/provisioning)](https://www.npmjs.com/package/@adopt-tech/provisioning)\n[![npm downloads](https://img.shields.io/npm/dm/@adopt-tech/provisioning)](https://www.npmjs.com/package/@adopt-tech/provisioning)\n\n> Type-safe JS/TS toolkit for programmatic provisioning of Adopt CMP entities via the Hasura GraphQL Actions API.\n\n## Prerequisites\n\nTo use this SDK you need an API account on the Adopt platform. Contact the AdOpt team at [sos@goadopt.io](mailto:sos@goadopt.io) to request access.\n\n## Overview\n\n`adopt-provisioning` lets you create and configure the full Adopt entity hierarchy in a single idempotent run:\n\n```\nOrganization\n└── Disclaimer\n    ├── Options (GCM, consent TTL, languages)\n    ├── Style (colors, theme, position)\n    ├── Terms document\n    ├── Privacy document\n    ├── Cookie document (URL, upload, or auto-generated from scan)\n    ├── Optout / DSAR page\n    ├── Vendors\n    ├── TCF\n    └── Scan\nMembers (per organization)\n```\n\n**Key features**\n\n- Idempotent runs — re-running with the same state ID resumes from where it left off\n- Rollback on error — deletes every entity created in the run on failure\n- `maxConcurrency: 1` — controls execution order of sibling provisioners\n- Fetcher API — read back any provisioned entity for verification\n- `getInstallationSnippet(disclaimerId)` — generates the `<head>` snippet for banner installation\n\n## Partner integration\n\nFor the complete end-to-end provisioning flow (login, org, member, disclaimer, style, docs, scan, cookie doc auto-generation) see **[`examples/partner-integration.ts`](./examples/partner-integration.ts)**.\n\n```bash\nexport ADOPT_USER_EMAIL=you@example.com\nexport ADOPT_USER_PASSWORD=yourpassword\n\n# Dry-run — no API calls, shows planned tree\nnpx ts-node examples/partner-integration.ts --dry-run\n\n# Real provisioning\nnpx ts-node examples/partner-integration.ts\n```\n\nEdit `ORG_NAME`, `ORG_PATH`, `DOMAIN`, and `ADMIN_EMAIL` at the top of the file per tenant. Each run auto-generates a unique state ID — no risk of skipping provisioners from a previous run.\n\n## One-call provisioning (`createFullDisclaimer`)\n\nThe fastest way to provision a fully configured disclaimer. A single server-side call creates the org, disclaimer, style, documents, and optionally a DSAR portal — returning the IDs and install snippet immediately.\n\n```typescript\nconst client = new AdoptProvisioningClient({\n  environment: 'staging',\n  username: process.env.ADOPT_USER_EMAIL!,\n  password: process.env.ADOPT_USER_PASSWORD!,\n})\n\nconst [result] = await client.createFullDisclaimer({\n  urls: ['https://yoursite.com'],\n  immediateAvailable: true,   // banner loads without waiting for a scan\n  skipBranding: true,         // return immediately, trigger scan in background\n\n  org: {\n    orgPathname: 'your-org',  // unique slug; auto-derived from hostname if omitted\n    orgName: 'Your Company',\n    // orgId: 'existing-uuid',  // use an existing org instead of creating one\n  },\n\n  style: {\n    mainColor: '#00DD80',\n    textColor: '#000000',\n    backgroundColor: '#ffffff',\n  },\n\n  documents: {\n    privacyUrl: 'https://yoursite.com/privacy',\n    cookieUrl:  'https://yoursite.com/cookies',\n    termsUrl:   'https://yoursite.com/terms',\n    // omit any URL to auto-generate the document from a questionnaire\n  },\n\n  dsar: {\n    createDsar:       true,\n    // dpo: 'dpo@yoursite.com',  // defaults to authenticated user when omitted\n    inviteDpoAsAdmin: true,     // invite the DPO to the org as admin if not already a member\n  },\n})\n\nconsole.log(result.disclaimerId)  // UUID\nconsole.log(result.dashboardUrl)  // https://app.goadopt.io/org/…/disclaimer/…\nconsole.log(result.installCode)   // <meta …/> + <script …/>\n```\n\n> **When to use `createFullDisclaimer` vs the provisioner tree**\n> - Use `createFullDisclaimer` for simple, one-shot onboarding (e.g. partner integrations that spin up a banner per customer).\n> - Use the provisioner tree (`ResumableProvisioningExecutor`) for complex scenarios that need resume, rollback, incremental updates, or fine-grained control over each entity.\n\nFull runnable example: [`examples/create-full-disclaimer.ts`](./examples/create-full-disclaimer.ts)\n\n## Installation\n\n```bash\nnpm install @adopt-tech/provisioning\n```\n\n## Authentication\n\nTwo modes are supported:\n\n```typescript\n// Token mode — provide a pre-existing JWT (no auto-refresh)\nconst client = new AdoptProvisioningClient({\n  environment: 'staging', // or 'production'\n  token: process.env.ADOPT_USER_TOKEN,\n})\n\n// Credentials mode — auto-refreshes when JWT expires (recommended for long runs)\nconst client = new AdoptProvisioningClient({\n  environment: 'staging',\n  username: process.env.ADOPT_USER_EMAIL,\n  password: process.env.ADOPT_USER_PASSWORD,\n})\n```\n\n## Environment variables\n\n| Variable | Required | Description |\n|---|---|---|\n| `ADOPT_USER_EMAIL` | credentials mode | User email for auto-login |\n| `ADOPT_USER_PASSWORD` | credentials mode | User password for auto-login |\n| `ADOPT_USER_TOKEN` | token mode | Pre-existing Cognito JWT |\n| `ADOPT_HASURA_URL` | if no `environment` | Hasura GraphQL endpoint |\n| `ADOPT_BACKEND_URL` | if no `environment` | Backend URL for credentials login |\n| `ADOPT_HASURA_ROLE` | No | Hasura role (default: `api`) |\n| `ADOPT_HUB_URL` | No | Hub base URL (auto-set by `environment`) |\n\n`environment: 'staging'` or `'production'` sets all URLs automatically (`hasuraUrl`, `backendUrl`, `hubUrl`).\n\n## Quick start\n\n```typescript\nimport {\n  AdoptProvisioningClient,\n  ResumableProvisioningExecutor,\n  OrganizationProvisioner,\n  DisclaimerProvisioner,\n  DisclaimerStyleProvisioner,\n  TermsDocumentProvisioner,\n  ScanProvisioner,\n  CookieDocumentProvisioner,\n} from '@adopt-tech/provisioning'\n\nconst client = new AdoptProvisioningClient({\n  environment: 'staging',\n  username: process.env.ADOPT_USER_EMAIL!,\n  password: process.env.ADOPT_USER_PASSWORD!,\n})\n\nconst org = new OrganizationProvisioner('my-org', {\n  name: 'Acme Corp',\n  pathName: 'acme-corp',\n})\n\nconst disclaimer = new DisclaimerProvisioner('my-disclaimer', {\n  name: 'Cookie Banner',\n  domains: ['https://acme.com'],\n})\n\ndisclaimer.addChild(\n  new DisclaimerStyleProvisioner('my-style', {\n    primaryColorLight: '#00DD80',\n    positionController: 'left',\n    disclaimerTheme: 'modern',\n  }),\n)\n\ndisclaimer.addChild(\n  new TermsDocumentProvisioner('my-terms', {\n    language: 'pt',\n    organizationId: '', // resolved from parent org at runtime\n    url: 'https://acme.com/terms.pdf',\n  }),\n)\n\n// Scan runs before cookie doc so autoGenerate can resolve the scan ID\ndisclaimer.addChild(new ScanProvisioner('my-scan', { mode: 'fire-and-forget' }))\ndisclaimer.addChild(\n  new CookieDocumentProvisioner('my-cookie', {\n    language: 'pt',\n    organizationId: '',\n    autoGenerate: true,\n    documentName: 'Cookie Policy',\n  }),\n)\n\norg.addChild(disclaimer)\n\nconst executor = new ResumableProvisioningExecutor({\n  client,\n  config: { rollbackOnError: true, maxConcurrency: 1 },\n})\n\nconst result = await executor.execute({ organizations: [org] })\n```\n\n## Installation snippet\n\nAfter provisioning, get the HTML snippet to inject on the tenant's website:\n\n```typescript\nimport { getInstallationSnippet } from '@adopt-tech/provisioning'\n\nconst { html } = getInstallationSnippet(disclaimerId)\n// <meta name=\"adopt-website-id\" content=\"...\" />\n// <script src=\"//tag.goadopt.io/injector.js?website_code=...\" class=\"adopt-injector\"></script>\n```\n\n## Executor shortcuts\n\nInstead of building full provisioner trees, update a single entity on an existing disclaimer or org:\n\n```typescript\nconst executor = new ResumableProvisioningExecutor({ client, config: {} })\n\n// Update style on an existing disclaimer\nawait executor.executeForDisclaimer(disclaimerId, [\n  new DisclaimerStyleProvisioner('style', { primaryColorLight: '#00DD80' }),\n])\n\n// Update options on an existing disclaimer\nawait executor.executeForDisclaimer(disclaimerId, [\n  new DisclaimerOptionsProvisioner('opts', { googleConsentMode: true, consentTTLDays: 30 }),\n])\n\n// Provision a new member on an existing org\nawait executor.executeForOrganization(organizationId, [\n  new MemberProvisioner('admin', { email: 'admin@acme.com', role: MemberRole.Admin }),\n])\n```\n\n## Fetcher API\n\nRead back any entity after provisioning:\n\n```typescript\nconst fetcher = createFetcher(client)\nconst discFetcher = fetcher.disclaimers({ id: disclaimerId })\n\n// Style\nconst style = await discFetcher.getStyle()\n// style.primary_color_light, style.disclaimer_css.styles.web.card (fonts)\n\n// Options\nconst opts = await discFetcher.getOptions()\n// opts.consent_ttl_in_days, opts.hide_disclaimer, opts.google_consent_mode\n\n// Linked documents (privacy, cookies, terms master IDs)\nconst docs = await discFetcher.getDocuments()\n\n// Document content URL (the URL the user configured)\nconst url = await fetcher.documentContentUrl(docs.document_master_privacy_id!)\n// → 'https://example.com/privacy-policy'\n\n// Hub public links\nfetcher.documentUrl(docs.document_master_privacy_id!)  // hub.goadopt.io/document/{id}\nfetcher.dsarPortalUrl(requestsPageMasterId)            // hub.goadopt.io/privacy-hub/{id}\n\n// DSAR portal\nconst dsar = await discFetcher.getLinkedDsar()\n// dsar.requestsPageMasterId, dsar.page (texts, requests, documents, style)\n\n// Last linked DSAR master (even after unlink)\nconst masterId = await discFetcher.getLastLinkedDsarMasterId()\n\n// Platform default texts for DSAR portal (pre-populate UI forms)\nconst [pt] = await fetcher.dsarDefaults('pt')\n// pt.texts.title, pt.texts.requests.dataAccess, pt.texts.fields.name.name\n```\n\n## DSAR portal management\n\n```typescript\n// Create portal\nawait executor.executeForDisclaimer(disclaimerId, [\n  new RequestsPageProvisioner('dsar', {\n    name:      'Requests Portal',\n    dpoUserId: process.env.DPO_USER_ID!,\n    languages: { fallback: 'pt', languages: ['pt', 'en'] },\n    requests:  [{ legislation: Legislation.LGPD, requests: Object.values(DsarRequestType) }],\n    style:     { colors: { background: '#FFFFFF', button: '#00DD80' } }, // typed RequestsPageStyle\n  }),\n])\n\n// Disable (soft — reversible)\nawait client.disableDsarPage(disclaimerId)\n\n// Re-enable\nawait client.linkRequestPage(disclaimerId, requestsPageMasterId)\n\n// Permanently delete\nawait client.unlinkRequestPage(disclaimerId)\nawait client.deleteRequestsPage(requestsPageMasterId)\n```\n\n## Document management\n\n```typescript\n// Link documents to disclaimer\nawait executor.executeForDisclaimer(disclaimerId, [\n  new PrivacyDocumentProvisioner('privacy', { language: 'pt', url: 'https://example.com/privacy' }),\n  new CookieDocumentProvisioner('cookies',  { language: 'pt', url: 'https://example.com/cookies' }),\n  new TermsDocumentProvisioner('terms',     { language: 'pt', url: 'https://example.com/terms'   }),\n])\n\n// Update existing document (creates new version of same master)\nawait executor.executeForDisclaimer(disclaimerId, [\n  new PrivacyDocumentProvisioner('privacy-v2', {\n    language:         'pt',\n    url:              'https://example.com/privacy-v2',\n    masterDocumentId: existingMasterId,   // ← targets existing master\n  }),\n])\n\n// Disable document toggle without deleting\nawait executor.executeForDisclaimer(disclaimerId, [\n  new PrivacyDocumentProvisioner('privacy-off', { language: 'pt', noDoc: true }),\n])\n\n// Permanently delete document master\nawait client.deleteDocument(docMasterId)\n```\n\n## Resume & rollback\n\n```typescript\n// Fixed stateId enables resume on interrupted runs\nconst executor = new ResumableProvisioningExecutor({\n  client,\n  stateId: 'my-tenant-run',   // omit to auto-generate (fresh run every time)\n  config: { rollbackOnError: true },\n})\n\n// Rollback a previous run by state ID\nimport { FreshProvisionerFactory } from '@adopt-tech/provisioning'\nconst { organizations } = await FreshProvisionerFactory.fromDefaultStorage('my-tenant-run')\nawait executor.rollback(organizations)\n```\n\n> **Note:** Only reuse a `stateId` to resume an interrupted run. For a new tenant, omit it or use a unique ID — reusing a completed state will skip provisioners that ran before.\n\n## Examples\n\n> Full, runnable examples are available at **[goadopt/adopt-provisioning-examples](https://github.com/goadopt/adopt-provisioning-examples)**.\n\n### Provisioning\n\n```bash\n# Full partner onboarding: org, member, disclaimer, style, docs, scan\nnpx ts-node examples/partner-integration.ts --dry-run   # preview tree\nnpx ts-node examples/partner-integration.ts             # run\n\n# Minimal disclaimer (all required documents)\nnpx ts-node examples/create-functional-disclaimer.ts\n```\n\n### Banner configuration\n\n```bash\n# Style — colors, position, fonts\nnpx ts-node examples/api-estilo.ts          # apply\nMODE=read npx ts-node examples/api-estilo.ts  # read current\n\n# Texts — title, body, button labels (per language + legislation)\nnpx ts-node examples/api-textos.ts\n\n# Options — Google Consent Mode, hide after consent, TTL\nnpx ts-node examples/api-options.ts\nMODE=read npx ts-node examples/api-options.ts\n\n# Documents — privacy policy, cookie policy, terms of service\nnpx ts-node examples/api-documentos.ts           # create/link via URL\nMODE=read   npx ts-node examples/api-documentos.ts  # read current + hub links\nMODE=update DOC_MASTER_ID=uuid npx ts-node examples/api-documentos.ts\nMODE=nodoc  npx ts-node examples/api-documentos.ts  # disable toggles\n```\n\n### DSAR / Requests page (LGPD)\n\n```bash\n# Create/update portal with all 11 LGPD rights\nnpx ts-node examples/api-dsar.ts\n\n# Read current portal config + public link\nMODE=read npx ts-node examples/api-dsar.ts\n\n# Platform default texts (pre-populate your UI forms)\nMODE=defaults LANGUAGE=en npx ts-node examples/api-dsar.ts\n\n# Full LGPD configuration — style, documents, all request types\nnpx ts-node examples/api-requisicoes.ts\n\n# Disable / re-enable portal\nMODE=unlink npx ts-node examples/api-dsar.ts\nMODE=delete npx ts-node examples/api-dsar.ts\n```\n\n### Metrics & scanning\n\n```bash\n# Consent metrics for current month\nnpx ts-node examples/api-metricas.ts\nMONTH=3 YEAR=2025 npx ts-node examples/api-metricas.ts\n\n# Scan + recategorize tags\nnpx ts-node examples/scan-and-recategorize.ts\n\n# TCF setup\nnpx ts-node examples/tcf-setup.ts\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}