### Get Entities From a Business Source: https://docs.sardine.ai/guides/public/risk/overview Retrieves a list of all entities associated with a specific business. ```APIDOC ## GET /business/get-entities-from-a-business ### Description Fetches all entities (individuals, organizations) linked to a given business. ### Method GET ### Endpoint /business/get-entities-from-a-business ### Parameters #### Query Parameters - **business_id** (string) - Required - The unique identifier of the business. ### Response #### Success Response (200) - **entities** (array) - A list of entity objects associated with the business. - **entity_id** (string) - The unique identifier for the entity. - **entity_type** (string) - Type of entity (e.g., "individual", "organization"). - **entity_data** (object) - Data specific to the entity type. - **relationship_type** (string) - The relationship of the entity to the business. #### Response Example { "entities": [ { "entity_id": "person_456", "entity_type": "individual", "entity_data": { "first_name": "John", "last_name": "Doe", "dob": "1980-01-01" }, "relationship_type": "CEO" }, { "entity_id": "org_789", "entity_type": "organization", "entity_data": { "name": "Subsidiary LLC", "registration_number": "SUB12345" }, "relationship_type": "subsidiary" } ] } ``` -------------------------------- ### File System Utilities for Documentation Source: https://docs.sardine.ai/guides/public/getting-started/integration-overview Utility functions for finding documentation files and checking capitalization. Includes functions for logging, finding files recursively, and validating heading capitalization based on specific rules. ```javascript const SKIP_HEADING_CASE_FILES = [ 'industry-terminology-and-typologies.mdx', 'glossary.mdx', ]; // Colors for terminal output const colors = { red: '\x1b[31m', yellow: '\x1b[33m', green: '\x1b[32m', reset: '\x1b[0m', bold: '\x1b[1m', }; function log(message, color = '') { console.log(`${color}${message}${colors.reset}`); } function logError(message) { log(`ERROR: ${message}`, colors.red); } function logWarning(message) { log(`WARNING: ${message}`, colors.yellow); } function logSuccess(message) { log(message, colors.green); } /** * Recursively find all MDX/MD files in a directory */ function findDocFiles(dir, files = []) { if (!fs.existsSync(dir)) { return files; } const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { if (!SKIP_DIRS.includes(entry.name)) { findDocFiles(fullPath, files); } } else if (entry.isFile()) { const ext = path.extname(entry.name).toLowerCase(); if (FILE_EXTENSIONS.includes(ext)) { files.push(fullPath); } } } return files; } /** * GEN-004: Check heading capitalization (should be sentence case) */ function checkHeadingCapitalization(content, filePath) { const violations = []; const lines = content.split('\n'); // Words that should not be capitalized in sentence case (unless first word) const lowercaseWords = ['the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with', 'by']; const PROPER_WORDS = new Set([ 'Sardine','Fastly','Config','Store','WorkOS','Okta','Ping','Microsoft','Google','Stripe','VGS','Snowflake', 'BigQuery','Sumsub','Onfido','Socure','Plaid','Persona','Middesk','Marqeta','Lithic','Galileo','Unit', 'ACH','AML','KYC','KYB','SSN','API','SDK','iOS','Android','Webview','Web','Mintlify','OpenAPI','Java','Node.js', 'React','Next.js','Flutter','Swift','Kotlin','Xamarin','Jetpack','Compose','Cordova','Expo','SCIM','SAML', 'CDN','CDNs','OFAC','PEP','PCI','DSS','SOC','EDD','SAR','SARs','CTR','CTRs','CAR','CARs', 'JSON','CSV','HTTP','HTTPS','URL','URLs','REST','GraphQL','OAuth','JWT','SSO','MFA','OTP','PIN', 'Visa','Mastercard','Amex','PayPal','Venmo','Zelle','Wire','Crypto','Bitcoin','Ethereum', 'Dashboard','Sandbox','Production','Rule','Rules','Queue','Queues','Alert Queue','Alert Queues', 'IP','DNS','TLS','SSL','AWS','GCP','Azure','Docker','Kubernetes', 'SardineQL','JavaScript','TypeScript','Python','Ruby','PHP','Go','Rust', 'Chrome','Firefox','Safari','Edge','Opera', 'Cloudflare','Worker','Workers', 'Twilio','SendGrid','Segment','Datadog','Slack','Jira','Asana','Linear','Ashby', 'Americas','Europe','Asia','Africa','Australia','US','UK','EU','GDPR','CCPA', 'Sofort','Bancontact','Giropay','iDEAL', 'Native','Studio','Enterprise','Professional','Business','Premium', 'Checkpoint','Checkpoints','Signal','Signals','Score','Scores', 'Directory','Sync','True','Location','Visitor','Fingerprint','Fingerprints', 'Lambda','Authorizer','Agent','Agents', 'Businesses','Analytics','Routines','Builder','Entity','Attributes', ]); function isProperWord(w) { const core = w.replace(/^[^A-Za-z]+|[^A-Za-z0-9.+-\]+$/g, ''); return PROPER_WORDS.has(core); } lines.forEach((line, index) => { // Match markdown headings const headingMatch = line.match(/^(#{1,6})\s+(.+)$/); if (headingMatch) { const headingText = headingMatch[2]; const words = headingText.split(/\s+/); const firstAlphaIndex = words.findIndex(w => /^[A-Za-z]/.test(w.replace(/^[^A-Za-z]+/, ''))); // Check if multiple words are capitalized (Title Case instead of Sentence case) let capitalizedCount = 0; words.forEach((word, wordIndex) => { if (wordIndex === firstAlphaIndex || word.startsWith('`') || word.startsWith('[')) { return; } if (/^[A-Z][a-z]/.test(word) && !lowercaseWords.includes(word.toLowerCase()) && !isProperWord(word)) { capitalizedCount++; } }); // If more than half the non-proper words are capitalized, it's likely Title Case if (words.length > 2 && capitalizedCount >= Math.floor(words.length / 2)) { violations.push({ type: 'warning', rule: 'GEN-004', message: `Heading may be using Title Case instead of sentence case in "${filePath}" at line ${index + 1}: "${headingText}"`, line: index + 1, suggestion: 'Use sentence-style capitalization (only capitalize first word and proper nouns)', }); } } }); return violations; } /** * GEN-007: Check for missing Oxford comma */ function checkOxfordComma(content, filePath) { const violations = []; const ``` -------------------------------- ### Initialize and Configure Card Spending Risk Banner Source: https://docs.sardine.ai/guides/public/risk/card-spending-risk/card-spending This script initializes the Sardine AI risk banner. It determines the user's language and preferred content, then checks local storage for previous dismissals. The banner's visibility is set based on whether it has been dismissed. ```javascript function(a,b,c,d,e){let f,g;try{let h=window.location.pathname.split(\"/\").filter(a=>a!==\"\"&&a!==\"global\").slice(0,2);let i=h.find(a=>c.includes(a));let j=[];for(let c of(i?j.push(i):j.push(b),j.push(\"global\"),j)){if(!c)continue;let b=a[c];if(b?.content){f=b.content,g=c;break}}}catch(a){console.error(a),document.documentElement.setAttribute(d,\"hidden\")}}if(!f)return void document.documentElement.setAttribute(d,\"hidden\");let k=!0,l=0;for(;l""!==a&&"global"!==a).slice(0,2)}catch{h=[]}let i=h.find(a=>c.includes(a)),j=[];for(let c of(i?j.push(i):j.push(b),j.push("global"),j)){if(!c)continue;let b=a[c];if(b?.content){f=b.content,g=c;break}}if(!f)return void document.documentElement.setAttribute(d,"hidden");let k=!0,l=0;for(;l 2000) { warnings.push({ rule: 'LongFile', message: 'File is too long', file, line: 1, suggestion: 'Consider splitting the file.' }); } if (!content.includes('# ')) { infos.push({ rule: 'NoH1', message: 'File missing H1 header', file, line: 1, suggestion: 'Add an H1 header (e.g., # My Title).' }); } } } // Report Errors if (errors.length > 0) { log(` ${colors.bold}Errors (${errors.length}):${colors.reset}\n"); const displayErrors = errors.slice(0, 10); for (const violation of displayErrors) { log(`[${violation.rule}] ${violation.message} `); log(` File: ${violation.file} `); log( ` Line: ${violation.line} ` ); log(` Suggestion: ${violation.suggestion}\n `); } if (errors.length > 10) { log(` ... and ${errors.length - 10} more errors.\n"); } } // Report Warnings if (warnings.length > 0) { log(`${colors.yellow}${colors.bold}Warnings (${warnings.length}):${colors.reset}\n"); const displayWarnings = warnings.slice(0, 15); for (const violation of displayWarnings) { log(`[${violation.rule}] ${violation.message} `); log(` File: ${violation.file} `); log( ` Line: ${violation.line} ` ); log(` Suggestion: ${violation.suggestion}\n `); } if (warnings.length > 15) { log(` ... and ${warnings.length - 15} more warnings.\n"); } } if (infos.length > 0) { log(`${colors.blue}${colors.bold}Info (${infos.length}):${colors.reset}\n"); const displayInfos = infos.slice(0, 10); for (const violation of displayInfos) { log(`[${violation.rule}] ${violation.message} `); log(` File: ${violation.file} `); log( ` Line: ${violation.line} ` ); log(` Suggestion: ${violation.suggestion}\n `); } if (infos.length > 10) { log(` ... and ${infos.length - 10} more info messages.\n"); } } // Summary log(`${colors.bold}Summary:${colors.reset} `); log(` Files checked: ${files.length} `); log(` Errors: ${errors.length} `); log(` Warnings: ${warnings.length} `); log(` Info: ${infos.length}\n `); // Determine exit code const hasBlockingErrors = ERRORS_ARE_BLOCKING && errors.length > 0; const hasBlockingWarnings = WARNINGS_ARE_BLOCKING && warnings.length > 0; if (hasBlockingErrors || hasBlockingWarnings) { logError('Validation failed. Please fix the errors above.\n'); process.exit(1); } else if (errors.length === 0 && warnings.length === 0 && infos.length === 0) { logSuccess('All style checks passed!\n'); } else { logSuccess('Validation passed (issues are non-blocking).\n'); } process.exit(0); } // Run the validator const docsPathArg = process.argv[2] || DEFAULT_DOCS_PATH; const fullPath = path.resolve(process.cwd(), docsPathArg); if (!fs.existsSync(fullPath)) { logError(`Directory not found: ${fullPath}\n`); process.exit(1); } validateDocStyle(fullPath); ``` -------------------------------- ### Theme Management with Local Storage Source: https://docs.sardine.ai/guides/public/risk/card-spending-risk/card-spending This JavaScript code handles theme switching (light/dark/system) and applies it to the document element's class or attribute. It prioritizes local storage settings and falls back to system preferences. ```javascript ((a,b,c,d,e,f,g,h)=>{let i=document.documentElement,j=["light","dark"];function k(b){var c;(Array.isArray(a)?a:a).forEach(a=>{let c="class"===a,d=c&&f?e.map(a=>f[a]||a):e;c?(i.classList.remove(...d),i.classList.add(f&&f[b]?f[b]:b)):i.setAttribute(a,b)}),c=b,h&&j.includes(c)&&(i.style.colorScheme=c)}if(d)k(d);else try{let a=localStorage.getItem(b)||c,d=g&&"system"===a?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":a;k(d)}catch(a){document.documentElement.setAttribute(b,"hidden")}})("class","isDarkMode","light",null,["dark","light","true","false","system"],{"true":"dark","false":"light","dark":"dark","light":"light"},true,false) ``` -------------------------------- ### Theme and Color Scheme Management Source: https://docs.sardine.ai/guides/public/risk/transaction-monitoring/transaction-monitoring This script handles theme switching (light/dark mode) and sets the 'color-scheme' CSS property. It supports direct setting, local storage persistence, and system preference. ```javascript ((a,b,c,d,e,f,g,h)=>{let i=document.documentElement,j=["light","dark"];function k(b){var c;(Array.isArray(a)?a:[a]).forEach(a=>{let c="class"===a,d=c&&f?e.map(a=>f[a]||a):e;c?(i.classList.remove(...d),i.classList.add(f&&f[b]?f[b]:b)):i.setAttribute(a,b)}),c=b,h&&j.includes(c)&&(i.style.colorScheme=c)}if(d)k(d);else try{let a=localStorage.getItem(b)||c,d=g&&"system"===a?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":a;k(d)}catch(a){document.documentElement.setAttribute(b,"hidden")}})("class","isDarkMode","light",null,["dark","light","true","false","system"],{"true":"dark","false":"light","dark":"dark","light":"light"},true,false) ``` -------------------------------- ### Mintlify Banner Script Source: https://docs.sardine.ai/guides/public/risk/account-risk/account-risk Initializes a banner script for Mintlify, managing its visibility based on language, path, and local storage. It ensures the banner is shown only once per session or language. ```javascript (function g(a,b,c,d,e){try{let f,g,h=[];try{h=window.location.pathname.split("/").filter(a=>""!==a&&"global"!==a).slice(0,2)}catch{h=[]}let i=h.find(a=>c.includes(a)),j=[];for(let c of(i?j.push(i):j.push(b),j.push("global"),j)){if(!c)continue;let b=a[c];if(b?.content){f=b.content,g=c;break}}if(!f)return void document.documentElement.setAttribute(d,"hidden");let k=!0,l=0;for(;l