{"_id":"@41devs/naya-id-js","_rev":"4-a100044953326949dfea76dd38888a58","name":"@41devs/naya-id-js","dist-tags":{"latest":"0.3.2"},"versions":{"0.1.0":{"name":"@41devs/naya-id-js","version":"0.1.0","keywords":["kyc","ekyc","identity-verification","javascript","browser","vanilla","naya","cedeao"],"author":{"name":"41Devs"},"license":"SEE LICENSE IN LICENSE","_id":"@41devs/naya-id-js@0.1.0","maintainers":[{"name":"devs41","email":"contact@41devs.com"},{"name":"khaliq","email":"alikhaliq66@gmail.com"}],"homepage":"https://naya.41devs.com","bugs":{"url":"https://github.com/41devs/naya-js-sdk/issues"},"dist":{"shasum":"3491f16a0d3bb0a14219bae5ab8be441e4ff6db6","tarball":"https://registry.npmjs.org/@41devs/naya-id-js/-/naya-id-js-0.1.0.tgz","fileCount":11,"integrity":"sha512-zwSVikqGnS4WKvbTRZINeshHbE+eIZz42PN/oA1Htiiasy2nk5VOVum8I1rMxnkbYrqGZF/UMwWMujtMsrvcwQ==","signatures":[{"sig":"MEYCIQDadaVA10RSQ6sm4kkCy8DA+Gdw1LRui46dRAqQ+JJQ9gIhAJqxDLFtPzo4J8tABMp8305CBbjdVBV8hKIG8cBujRO3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":669765},"main":"./dist/naya-id.cjs","type":"module","types":"./dist/naya-id.d.ts","unpkg":"./dist/naya-id.min.js","module":"./dist/naya-id.mjs","exports":{".":{"types":"./dist/naya-id.d.ts","import":"./dist/naya-id.mjs","require":"./dist/naya-id.cjs"},"./dist/*":"./dist/*"},"gitHead":"8aadbae8a62465d93361221489a25c63adf630ed","scripts":{"dev":"tsup --watch","build":"tsup","serve":"npx --yes serve .","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"khaliq","email":"alikhaliq66@gmail.com"},"jsdelivr":"./dist/naya-id.min.js","repository":{"url":"git+https://github.com/41devs/naya-js-sdk.git","type":"git"},"_npmVersion":"8.19.4","description":"SDK JavaScript officiel de Naya ID — vérification d'identité (eKYC) clé en main pour l'Afrique de l'Ouest, chargeable en une balise <script>.","directories":{},"sideEffects":false,"_nodeVersion":"16.20.2","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","typescript":"^5.6.3"},"_npmOperationalInternal":{"tmp":"tmp/naya-id-js_0.1.0_1788177192520_0.1646227848386752","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@41devs/naya-id-js","version":"0.3.0","keywords":["kyc","ekyc","identity-verification","javascript","browser","vanilla","naya","cedeao"],"author":{"name":"41Devs"},"license":"SEE LICENSE IN LICENSE","_id":"@41devs/naya-id-js@0.3.0","maintainers":[{"name":"devs41","email":"contact@41devs.com"},{"name":"khaliq","email":"alikhaliq66@gmail.com"}],"homepage":"https://naya.41devs.com","bugs":{"url":"https://github.com/41devs/naya-js-sdk/issues"},"dist":{"shasum":"b708fe8640790807a563809b7d142cdab1ba9a9d","tarball":"https://registry.npmjs.org/@41devs/naya-id-js/-/naya-id-js-0.3.0.tgz","fileCount":11,"integrity":"sha512-qYYfT+Ta7mJh6/3jCOx+sDOYmc4aXCyF8Yx61htScjz2cDaepAwUX4DOVp/eO/Y/RPrlvBPym73LkCEuXsMsAQ==","signatures":[{"sig":"MEYCIQD3ijF0A8/Kp5viHFJhvPIyBOo3KEd0inQwZ6fUTImtggIhAINCvGSnyK2swWTO2JmtLqiRiSkQthPMzUPtfzQGAqzI","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1796755},"main":"./dist/naya-id.cjs","type":"module","types":"./dist/naya-id.d.ts","unpkg":"./dist/naya-id.min.js","module":"./dist/naya-id.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./dist/naya-id.d.ts","import":"./dist/naya-id.mjs","require":"./dist/naya-id.cjs"},"./dist/*":"./dist/*"},"gitHead":"0cc6b177b407fe0551e973d98ca846248ebb7534","scripts":{"dev":"tsup --watch","sri":"node scripts/sri.mjs","lint":"eslint src tests","size":"node scripts/check-size.mjs","test":"vitest run","build":"tsup","serve":"npx --yes serve .","format":"prettier --check .","release":"npm publish --access public","test:e2e":"playwright test","typecheck":"tsc --noEmit","test:watch":"vitest","assets:fetch":"node scripts/fetch-liveness-assets.mjs","format:write":"prettier --write .","prepublishOnly":"npm run typecheck && npm run test && npm run build && npm run size"},"_npmUser":{"name":"khaliq","email":"alikhaliq66@gmail.com"},"jsdelivr":"./dist/naya-id.min.js","repository":{"url":"git+https://github.com/41devs/naya-js-sdk.git","type":"git"},"_npmVersion":"10.9.8","description":"SDK JavaScript officiel de Naya ID — vérification d'identité (eKYC) clé en main pour l'Afrique de l'Ouest : consentement, capture guidée, défi de vivacité imposé par le serveur, confirmation des données, résultat expliqué. Une balise <script>, un Web Comp","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","browserslist":["defaults","not dead","iOS >= 15","Safari >= 15","Chrome >= 90","Firefox >= 90","Edge >= 90"],"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","jsdom":"^30.0.1","eslint":"^10.10.0","vitest":"^5.0.0","prettier":"^3.9.6","typescript":"^5.6.3","@playwright/test":"^1.63.0","typescript-eslint":"^8.69.0","@mediapipe/tasks-vision":"^1.0.1"},"_npmOperationalInternal":{"tmp":"tmp/naya-id-js_0.3.0_1788777922086_0.9657676205752161","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@41devs/naya-id-js","version":"0.3.1","keywords":["kyc","ekyc","identity-verification","javascript","browser","vanilla","naya","cedeao"],"author":{"name":"41Devs"},"license":"SEE LICENSE IN LICENSE","_id":"@41devs/naya-id-js@0.3.1","maintainers":[{"name":"devs41","email":"contact@41devs.com"},{"name":"khaliq","email":"alikhaliq66@gmail.com"}],"homepage":"https://naya.41devs.com","bugs":{"url":"https://github.com/41devs/naya-js-sdk/issues"},"dist":{"shasum":"6dc927ef89f2b6e3ec76400881a12cfe0e969b93","tarball":"https://registry.npmjs.org/@41devs/naya-id-js/-/naya-id-js-0.3.1.tgz","fileCount":11,"integrity":"sha512-DpMj8dNcg77qX3U3m9fiFddLUPADQDYcwQZ25HTNsO32b0N0EQ214DkoByohuzdAfHoEM01Pd6ZFrJJOwE+wrw==","signatures":[{"sig":"MEYCIQCXX+YhsAwUDYDARARa1dE16zwcN4ilPYDqqnGREczOSwIhAL+9E2zuGxaMBs3y6uRQEoTSA1UaDG8VimEUlgxSyqi4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1820675},"main":"./dist/naya-id.cjs","type":"module","types":"./dist/naya-id.d.ts","unpkg":"./dist/naya-id.min.js","module":"./dist/naya-id.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./dist/naya-id.d.ts","import":"./dist/naya-id.mjs","require":"./dist/naya-id.cjs"},"./dist/*":"./dist/*","./package.json":"./package.json"},"gitHead":"e57f7bd4b63fec92923c6a2918c36e19640ede2d","scripts":{"dev":"tsup --watch","sri":"node scripts/sri.mjs","lint":"eslint src tests","size":"node scripts/check-size.mjs","test":"vitest run","build":"tsup","serve":"npx --yes serve .","format":"prettier --check .","release":"npm publish --access public","test:e2e":"playwright test","typecheck":"tsc --noEmit","test:watch":"vitest","assets:fetch":"node scripts/fetch-liveness-assets.mjs","format:write":"prettier --write .","prepublishOnly":"npm run typecheck && npm run test && npm run build && npm run size"},"_npmUser":{"name":"khaliq","email":"alikhaliq66@gmail.com"},"jsdelivr":"./dist/naya-id.min.js","repository":{"url":"git+https://github.com/41devs/naya-js-sdk.git","type":"git"},"_npmVersion":"10.9.8","description":"SDK JavaScript officiel de Naya ID — vérification d'identité (eKYC) clé en main pour l'Afrique de l'Ouest : consentement, capture guidée, défi de vivacité imposé par le serveur, confirmation des données, résultat expliqué. Une balise <script>, un Web Comp","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","browserslist":["defaults","not dead","iOS >= 15","Safari >= 15","Chrome >= 90","Firefox >= 90","Edge >= 90"],"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","jsdom":"^30.0.1","eslint":"^10.10.0","vitest":"^5.0.0","prettier":"^3.9.6","typescript":"^5.6.3","@playwright/test":"^1.63.0","typescript-eslint":"^8.69.0","@mediapipe/tasks-vision":"^1.0.1"},"_npmOperationalInternal":{"tmp":"tmp/naya-id-js_0.3.1_1788788831586_0.7463823638434959","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@41devs/naya-id-js","version":"0.3.2","description":"SDK JavaScript officiel de Naya ID — vérification d'identité (eKYC) clé en main pour l'Afrique de l'Ouest : consentement, capture guidée, défi de vivacité imposé par le serveur, confirmation des données, résultat expliqué. Une balise <script>, un Web Comp","keywords":["kyc","ekyc","identity-verification","javascript","browser","vanilla","naya","cedeao"],"homepage":"https://naya.41devs.com","repository":{"type":"git","url":"git+https://github.com/41devs/naya-js-sdk.git"},"bugs":{"url":"https://github.com/41devs/naya-js-sdk/issues"},"license":"SEE LICENSE IN LICENSE","author":{"name":"41Devs"},"type":"module","main":"./dist/naya-id.cjs","module":"./dist/naya-id.mjs","types":"./dist/naya-id.d.ts","unpkg":"./dist/naya-id.min.js","jsdelivr":"./dist/naya-id.min.js","exports":{".":{"types":"./dist/naya-id.d.ts","import":"./dist/naya-id.mjs","require":"./dist/naya-id.cjs"},"./dist/*":"./dist/*","./package.json":"./package.json"},"sideEffects":false,"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","lint":"eslint src tests","format":"prettier --check .","format:write":"prettier --write .","test":"vitest run","test:watch":"vitest","test:e2e":"playwright test","size":"node scripts/check-size.mjs","sri":"node scripts/sri.mjs","assets:fetch":"node scripts/fetch-liveness-assets.mjs","serve":"npx --yes serve .","prepublishOnly":"npm run typecheck && npm run test && npm run build && npm run size","release":"npm publish --access public"},"devDependencies":{"@mediapipe/tasks-vision":"^1.0.1","@playwright/test":"^1.63.0","eslint":"^10.10.0","jsdom":"^30.0.1","prettier":"^3.9.6","tsup":"^8.3.5","typescript":"^5.6.3","typescript-eslint":"^8.69.0","vitest":"^5.0.0"},"engines":{"node":">=20"},"browserslist":["defaults","not dead","iOS >= 15","Safari >= 15","Chrome >= 90","Firefox >= 90","Edge >= 90"],"publishConfig":{"access":"public"},"_id":"@41devs/naya-id-js@0.3.2","gitHead":"026e1773ab219821fae3ab05177072963711faa7","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-TVucwpC1uf/8DXmOU9hdp4+ZCo5WSBVJ0adiODeooHrrq5u4VaB9mojn6lBRDI02ZPET5s3X72QyCFV1gatFIA==","shasum":"3601c24d5c9a6ad8ae5552f04eea7924739ed788","tarball":"https://registry.npmjs.org/@41devs/naya-id-js/-/naya-id-js-0.3.2.tgz","fileCount":11,"unpackedSize":1824299,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDYLEoMSz5/tIG1ztDs5xICo/rifl5QVkYXWas7Zm9w9AiBXkz/im+McdSkPuSK7DLw/GR8K0AxZyFRQHVD3dVuwQA=="}]},"_npmUser":{"name":"khaliq","email":"alikhaliq66@gmail.com"},"directories":{},"maintainers":[{"name":"devs41","email":"contact@41devs.com"},{"name":"khaliq","email":"alikhaliq66@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/naya-id-js_0.3.2_1788878979700_0.26261130563626445"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-31T11:53:12.357Z","modified":"2026-09-08T14:49:40.589Z","0.1.0":"2026-08-31T11:53:12.662Z","0.3.0":"2026-09-07T10:45:22.219Z","0.3.1":"2026-09-07T13:47:11.732Z","0.3.2":"2026-09-08T14:49:39.842Z"},"bugs":{"url":"https://github.com/41devs/naya-js-sdk/issues"},"author":{"name":"41Devs"},"license":"SEE LICENSE IN LICENSE","homepage":"https://naya.41devs.com","keywords":["kyc","ekyc","identity-verification","javascript","browser","vanilla","naya","cedeao"],"repository":{"type":"git","url":"git+https://github.com/41devs/naya-js-sdk.git"},"description":"SDK JavaScript officiel de Naya ID — vérification d'identité (eKYC) clé en main pour l'Afrique de l'Ouest : consentement, capture guidée, défi de vivacité imposé par le serveur, confirmation des données, résultat expliqué. Une balise <script>, un Web Comp","maintainers":[{"name":"devs41","email":"contact@41devs.com"},{"name":"khaliq","email":"alikhaliq66@gmail.com"}],"readme":"# @41devs/naya-id-js\n\nSDK JavaScript officiel de **Naya ID** — vérification d'identité (eKYC) clé en\nmain pour l'Afrique de l'Ouest. Une balise `<script>`, un Web Component ou un\nimport npm ; aucune dépendance à l'exécution ; ~40 Ko compressés.\n\nPièces acceptées : CNI CEDEAO, CIP béninois, passeport, permis de conduire.\n\nLe parcours : consentement → capture guidée du document (recto ; verso pour la\nseule CNI CEDEAO, qui porte sa MRZ au dos) → selfie avec **défi de vivacité imposé par le serveur** → confirmation des\ndonnées lues → décision expliquée. Sur ordinateur, relais vers le téléphone par\nQR code. Trois langues : français, anglais, portugais.\n\n---\n\n## Démarrage rapide\n\n### 1. Votre backend ouvre la session (recommandé)\n\n```bash\ncurl -X POST https://api.naya.41devs.com/v1/verifications/start \\\n  -H \"X-API-Key: naya_live_xxx\" -H \"Content-Type: application/json\" \\\n  -d '{\"documentType\":\"cni\",\"country\":\"BJ\",\"callbackUrl\":\"https://votre-backend.com/naya/hook\"}'\n# → { \"data\": { \"verificationId\": \"…\", \"sessionToken\": \"…\", \"challenge\": [\"blink\",\"turn-left\",\"smile\"] } }\n```\n\nLa clé ne quitte jamais votre serveur. Rendez `verificationId` + `sessionToken`\nau navigateur (voir `docs/backend-session.md` pour Node, PHP, Python).\n\n### 2. Votre page lance le parcours\n\n```html\n<script\n  src=\"https://sdk.naya.41devs.com/sdk/0.3.0/naya-id.min.js\"\n  integrity=\"sha384-…\"\n  crossorigin=\"anonymous\"\n></script>\n<script>\n  const result = await NayaId.startVerification({ verificationId, sessionToken });\n  // result.status : 'approved' | 'review' | 'rejected' | 'cancelled' | 'error'\n</script>\n```\n\nOu avec npm :\n\n```bash\nnpm install @41devs/naya-id-js\n```\n\n```ts\nimport { startVerification } from '@41devs/naya-id-js';\nconst result = await startVerification({ verificationId, sessionToken, config: { locale: 'fr' } });\n```\n\nNe décidez jamais sur le résultat rendu par le navigateur : seul le webhook (ou\n`GET /verifications/:id` avec votre clé) fait foi.\n\n---\n\n## Prérequis\n\n| Élément                       | Détail                                                                                                                                                              |\n| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **Compte Naya vérifié (KYB)** | Sinon l'API répond `403` (`kyb_pending`).                                                                                                                           |\n| **HTTPS**                     | La caméra exige un contexte sécurisé (`http://localhost` en développement).                                                                                         |\n| **Navigateur**                | Chrome, Safari, Firefox, Edge récents. Les navigateurs intégrés (WhatsApp, Facebook, Instagram) sont détectés : le SDK propose d'ouvrir le lien dans le navigateur. |\n| **Origine (mode clé)**        | Une clé **live** transmise au navigateur doit déclarer ses origines dans le dashboard. Sans objet avec le jeton de session.                                         |\n\n---\n\n## API\n\n### `startVerification(params) → Promise<NayaResult>`\n\n| Champ                             | Type         | Rôle                                                                  |\n| --------------------------------- | ------------ | --------------------------------------------------------------------- |\n| `verificationId` + `sessionToken` | `string`     | Session ouverte par votre backend. **Production.**                    |\n| `apiKey`                          | `string`     | Clé d'application transmise au navigateur. Démos et fronts maîtrisés. |\n| `config`                          | `NayaConfig` | Voir ci-dessous.                                                      |\n\nNe rejette jamais : erreurs et annulation reviennent en `NayaResult`.\n\n### `create(params) → NayaVerification`\n\nInstance avec `open()`, `close()`, `on(event, cb)`, `destroy()`, `isOpen` —\npour les enveloppes de framework et l'analytique (`docs/frameworks.md`).\n\n### `isSupported() → NayaSupport`\n\nÀ appeler avant d'afficher votre bouton : `ok`, `code`, `inAppBrowserName`,\n`deviceClass`…\n\n### `<naya-id-verification>`\n\nWeb Component enregistré automatiquement par le bundle `<script>` ;\n`defineElement()` en ESM/CJS.\n\n### Configuration (`config`)\n\n| Champ                                   | Défaut                                                          | Rôle                                                                                                                                                                                                                             |\n| --------------------------------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `country`, `countries`, `documentTypes` | tous                                                            | Pré-sélection ; l'écran de choix est sauté si un seul document et un pays.                                                                                                                                                       |\n| `locale`                                | langue du navigateur                                            | `fr`, `en`, `pt`.                                                                                                                                                                                                                |\n| `consent`                               | `true`                                                          | Écran de consentement ; `{ policyUrl, version }` ou `false` si recueilli en amont.                                                                                                                                               |\n| `confirmOcr`                            | `false`                                                         | Écran des données lues : `'display'` (lecture seule, l'utilisateur dit si c'est exact) ou `'edit'` (corrections saisies). `ocrData` n'est jamais altéré : le déclaré part à part (`declaredData`), un écart plafonne à la revue. |\n| `capture`                               | `{ autoCapture: true, maxDimension: 1600, fileUpload: 'auto' }` | Capture automatique, taille d'image, import de fichier (ordinateur).                                                                                                                                                             |\n| `liveness`                              | `{ timeoutMs: 45000, allowPassive: true, preload: true }`       | Délai avant conseils, parcours sans geste, préchargement.                                                                                                                                                                        |\n| `handoff`                               | `true`                                                          | Relais QR vers mobile sur ordinateur ; `{ baseUrl }` pour une page hébergée par vous.                                                                                                                                            |\n| `container`                             | `null`                                                          | Monte dans un élément au lieu d'un overlay plein écran.                                                                                                                                                                          |\n| `theme`                                 | encre / flamme                                                  | `primaryColor`, `accentColor`, `fontFamily`, `radius`, `mode` (`light`, `dark`, `auto`). Le texte des boutons reste lisible quelle que soit la couleur.                                                                          |\n| `clientLogoUrl`                         | —                                                               | Logo affiché à côté de « Propulsé par Naya ID ».                                                                                                                                                                                 |\n| `strings`                               | —                                                               | Surcharge de libellés par clé.                                                                                                                                                                                                   |\n| `livenessAssets`                        | jsDelivr / Google                                               | Auto-hébergement de MediaPipe, repli, intégrité (`docs/csp-and-self-hosting.md`).                                                                                                                                                |\n| `callbackUrl`                           | —                                                               | Mode clé uniquement ; en session serveur, l'URL est posée à l'ouverture.                                                                                                                                                         |\n| `maxAttempts`                           | `2`                                                             | Nouveaux essais après rejet (mode clé).                                                                                                                                                                                          |\n| `eagerSession`                          | `false`                                                         | Ouvre la session dès le choix du document (latence) — attention à la facturation.                                                                                                                                                |\n| `telemetry`                             | `true`                                                          | Télémétrie anonyme (`docs/telemetry.md`).                                                                                                                                                                                        |\n| `debug`                                 | `false`                                                         | Journal `[NayaId]` dans la console.                                                                                                                                                                                              |\n| `haptics`                               | `true`                                                          | Retour haptique sur mobile.                                                                                                                                                                                                      |\n| `onEvent`                               | —                                                               | Hook d'événements (`ready`, `step`, `session`, `document_captured`, `liveness_step`, `submitted`, `result`, `error`…).                                                                                                           |\n\n### Résultat (`NayaResult`)\n\n| Champ                                                  | Présent                   | Rôle                                                                                                 |\n| ------------------------------------------------------ | ------------------------- | ---------------------------------------------------------------------------------------------------- |\n| `status`                                               | toujours                  | `approved`, `review`, `rejected`, `cancelled`, `error`.                                              |\n| `verificationId`                                       | dès qu'une session existe | À conserver pour rapprocher webhooks et dashboard.                                                   |\n| `reasonCodes`                                          | décision                  | Motifs stables : `DOC_EXPIRED`, `FACE_MISMATCH`, `LIVENESS_LOW`, `AML_SANCTION`… (`docs/errors.md`). |\n| `livenessMode`                                         | décision                  | `active` ou `passive`.                                                                               |\n| `errorCode`, `errorMessage`, `statusCode`, `requestId` | `status: 'error'`         | Catalogue dans `docs/errors.md` ; `requestId` pour le support.                                       |\n| scores, `ocrData`, `note`                              | décision                  | Indicatifs ; la vérité est côté serveur. `ocrData` est l'extraction brute, jamais modifiée.          |\n| `declaredData`, `dataMismatches`, `dataDisputed`       | décision                  | Ce que l'utilisateur a déclaré ou contesté, conservé à part ; à vous de l'afficher ou non.           |\n\n---\n\n## Sécurité, en deux lignes\n\nLe jeton de session n'ouvre qu'une vérification, expire en 4 h et meurt à la\nsoumission. Le défi de vivacité est tiré par le serveur et vérifié par lui ;\nle score calculé sur l'appareil ne décide jamais. Les ressources MediaPipe\nviennent de jsDelivr et Google, téléchargées sans Referer, empreintes\nvérifiées ; auto-hébergement possible.\n\n---\n\n## Documentation\n\n- `docs/backend-session.md` — ouvrir la session côté serveur (Node, PHP, Python)\n- `docs/webhooks.md` — notifications signées\n- `docs/errors.md` — catalogue des `errorCode`\n- `docs/csp-and-self-hosting.md` — CSP, pare-feu, auto-hébergement, SRI\n- `docs/frameworks.md` — Web Component, React, Vue, Angular, conteneur\n- `docs/liveness-challenge-spec.md` — spécification du défi (commune aux SDK)\n- `docs/telemetry.md`, `docs/accessibility.md`, `docs/migration-0.2-to-0.3.md`\n- `hosting/README.md` — CDN `sdk.naya.41devs.com`\n\n---\n\n## Développement\n\n```bash\nnpm ci\nnpm run typecheck && npm run lint && npm test   # unitaires (vitest, jsdom)\nnpm run build && npm run size                   # dist/ + budget de taille\nnpm run assets:fetch                            # MediaPipe local pour le parcours complet e2e\nnpx playwright install chromium && npm run test:e2e   # parcours réel, caméra factice, API simulée\nE2E_PUBLIC_CDN=1 npm run test:e2e                     # + chargement réel depuis jsDelivr/Google (réseau)\nnpm run serve                                   # example/index.html\n```\n\nPublication : tag `vX.Y.Z` → CI → `npm publish --provenance`.\n\n---\n\n## Dépannage\n\n| Symptôme                                  | Cause probable                                                                                                            |\n| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |\n| `errorCode: 'origin_not_allowed'`         | Clé live utilisée depuis une origine non déclarée : dashboard → clé → Origines autorisées, ou passez au jeton de session. |\n| `errorCode: 'network'`                    | Hors-ligne, pare-feu ou proxy qui bloque `api.naya.41devs.com` ; CSP trop stricte (`docs/csp-and-self-hosting.md`).       |\n| `errorCode: 'in_app_browser'`             | Lien ouvert dans WhatsApp/Facebook : le SDK propose de copier le lien.                                                    |\n| `errorCode: 'liveness_assets'`            | MediaPipe injoignable ou altéré : CSP (`connect-src` jsDelivr/Google, `script-src blob:`) ou auto-héberger.               |\n| Décision `review` avec `LIVENESS_PASSIVE` | L'utilisateur a choisi le parcours sans geste : revue humaine attendue.                                                   |\n\nLicence : voir `LICENSE`.\n","readmeFilename":"README.md"}