{"_id":"@duabalabs/reviews-sdk","_rev":"2-ea89b59b031123918e6c5b9627b6a4e1","name":"@duabalabs/reviews-sdk","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@duabalabs/reviews-sdk","version":"0.1.0","keywords":["reviews","ratings","3y3anaa","duabalabs","trust"],"license":"MIT","_id":"@duabalabs/reviews-sdk@0.1.0","maintainers":[{"name":"bobokeke","email":"duabalabs@gmail.com"}],"homepage":"https://github.com/duabalabs/3y3anaa/tree/main/packages/reviews-sdk","bugs":{"url":"https://github.com/duabalabs/3y3anaa/issues"},"dist":{"shasum":"5eb9d7a0af59a38cb21ebea8dc1b62726099debd","tarball":"https://registry.npmjs.org/@duabalabs/reviews-sdk/-/reviews-sdk-0.1.0.tgz","fileCount":6,"integrity":"sha512-G57RfAjythvhCf49KieBHTpTB9GK7WiKSH8mIldDDRjmDRZ5u82UkAMG8sSGy4JSuyGEYUwz+bYvnjezgMEE1g==","signatures":[{"sig":"MEQCIFVRZdhoqAOxH8h6Bm8mqqU2158zDrZjWQF65t5/o35sAiA5K6tf5X4ER8Qk3lZvd4LLjaD9/UTmOItxxVCBN+wIEA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14869},"main":"dist/index.js","type":"commonjs","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"scripts":{"build":"tsup src/index.ts --format cjs,esm --dts --clean --minify","build:tsc":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"bobokeke","email":"duabalabs@gmail.com"},"repository":{"url":"git+https://github.com/duabalabs/3y3anaa.git","type":"git","directory":"packages/reviews-sdk"},"_npmVersion":"10.9.3","description":"Framework-agnostic client for the centralized 3y3anaa reviews platform.","directories":{},"sideEffects":false,"_nodeVersion":"22.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.4.0"},"_npmOperationalInternal":{"tmp":"tmp/reviews-sdk_0.1.0_1782485358503_0.1796438389521715","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@duabalabs/reviews-sdk","version":"0.2.0","description":"Framework-agnostic client for the centralized 3y3anaa reviews platform.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/duabalabs/3y3anaa.git","directory":"packages/reviews-sdk"},"homepage":"https://github.com/duabalabs/3y3anaa/tree/main/packages/reviews-sdk","type":"commonjs","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"sideEffects":false,"scripts":{"build":"tsup src/index.ts --format cjs,esm --dts --clean --minify","build:tsc":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"keywords":["reviews","ratings","3y3anaa","duabalabs","trust"],"publishConfig":{"access":"public"},"devDependencies":{"tsup":"^8.0.0","typescript":"^5.4.0"},"gitHead":"105b3cb46cb71fe97cdff300ad1186bdcc390848","_id":"@duabalabs/reviews-sdk@0.2.0","bugs":{"url":"https://github.com/duabalabs/3y3anaa/issues"},"_nodeVersion":"20.20.2","_npmVersion":"11.18.0","dist":{"integrity":"sha512-B3YMKOr/00u9Ygu8kiZrGVMobbPsvVeMYqK5I+U9Lyz99ZAslwB8ObkWeqGV8WDyM04MNIzwS/teeBklZQATsg==","shasum":"5c8972e62a3b33df3d4279426b373ec305297903","tarball":"https://registry.npmjs.org/@duabalabs/reviews-sdk/-/reviews-sdk-0.2.0.tgz","fileCount":6,"unpackedSize":18812,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDbnY9rgyasT8nvuk9nsZTbjihiu/jZxADTS/Jn0hygtAIgd2/Lu7XFj5VRvhs82KeqtAbEBJNTfylT+P0ikRJG7ZI="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0b923a15-26c4-405b-944c-2af3868ecd8c"}},"directories":{},"maintainers":[{"name":"bobokeke","email":"duabalabs@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/reviews-sdk_0.2.0_1783448732525_0.03776561085490582"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-26T14:49:18.329Z","modified":"2026-07-07T18:25:32.819Z","0.1.0":"2026-06-26T14:49:18.623Z","0.2.0":"2026-07-07T18:25:32.682Z"},"bugs":{"url":"https://github.com/duabalabs/3y3anaa/issues"},"license":"MIT","homepage":"https://github.com/duabalabs/3y3anaa/tree/main/packages/reviews-sdk","keywords":["reviews","ratings","3y3anaa","duabalabs","trust"],"repository":{"type":"git","url":"git+https://github.com/duabalabs/3y3anaa.git","directory":"packages/reviews-sdk"},"description":"Framework-agnostic client for the centralized 3y3anaa reviews platform.","maintainers":[{"name":"bobokeke","email":"duabalabs@gmail.com"}],"readme":"# @duabalabs/reviews-sdk\n\nFramework-agnostic client for the **centralized 3y3anaa reviews platform** — the shared review/rating store for Duabalabs subsidiaries. Reviews target a **subject** namespaced by `(sourceApp, subjectType, externalId)`; reviewers are **external identities** (no Parse account needed). Your app authenticates with a per-app key.\n\n> Call this **server-side** — the app key must stay secret.\n\n## Install\n```bash\nnpm i @duabalabs/reviews-sdk\n```\n\n## Usage\n```ts\nimport { createReviewsClient } from \"@duabalabs/reviews-sdk\";\n\nconst reviews = createReviewsClient({\n  appKey: process.env.THREEYANAA_APP_KEY!, // your per-app key (rk_<app>_…), sent as Bearer\n  // baseUrl defaults to https://api.3y3anaa.com — override for self-host/staging\n});\n\n// Submit (one review per subject+author; re-submitting edits it)\nawait reviews.submitReview({\n  subjectType: \"product\",\n  externalId: \"prod_123\",\n  subjectDisplayName: \"Kente Tote Bag\",\n  author: { externalUserId: \"user_42\", displayName: \"Ama\", role: \"buyer\" },\n  rating: 5,\n  body: \"Beautiful craftsmanship, fast delivery.\",\n  verified: true,\n});\n\n// Read a subject's reviews + aggregate\nconst { items, aggregate } = await reviews.getReviews({ subjectType: \"product\", externalId: \"prod_123\" });\n\n// Batch aggregates (product grids / cards)\nconst aggs = await reviews.getAggregates([\n  { subjectType: \"product\", externalId: \"prod_123\" },\n  { subjectType: \"product\", externalId: \"prod_456\" },\n]);\n```\n\n## Proxyfidelity model — artisans, clients & businesses review each other\n\nReviews are not just buyer→product. The same `subjectType` + `author.role` pair\nmodels any party reviewing any other. Canonical subjects/roles:\n`artisan`, `business`, `client` (plus commerce: `product`, `shop`, `supplier`,\n`courier`). Any string is accepted, but these are typed for autocomplete.\n\n```ts\n// A client reviews a business\nawait reviews.submitReview({\n  subjectType: \"business\", externalId: \"biz_001\",\n  author: { externalUserId: \"client_77\", displayName: \"Kwame\", role: \"client\" },\n  rating: 5, body: \"Reliable and professional.\",\n});\n\n// A business reviews an artisan it hired\nawait reviews.submitReview({\n  subjectType: \"artisan\", externalId: \"artisan_9\",\n  author: { externalUserId: \"biz_001\", displayName: \"Accra Tiles Ltd\", role: \"business\" },\n  rating: 4, body: \"Great tiling work, slightly late.\",\n});\n\n// An artisan reviews a client\nawait reviews.submitReview({\n  subjectType: \"client\", externalId: \"client_77\",\n  author: { externalUserId: \"artisan_9\", displayName: \"Kofi\", role: \"artisan\" },\n  rating: 5, body: \"Clear brief, paid on time.\",\n});\n```\n\nYour app reads back its own reviews with `getReviews(...)`. **3y3anaa** surfaces\nthe *whole network's* reviews for a subject — across every integrated app — on\nthat business/artisan's profile (its host `getSubjectReviews` aggregates them).\n\n**Provisioning** — give your app credential the subject scopes it needs\n(empty scopes = all allowed):\n```\nprovisionAppCredential({ appName: \"sellub\",\n  scopes: [\"product\",\"shop\",\"supplier\",\"courier\",\"artisan\",\"business\",\"client\"] })\n```\n\n## API\n- `submitReview(input)` → `{ review, aggregate }`\n- `getReviews({ subjectType, externalId, limit?, skip?, sort? })` → `{ items, total, hasMore, aggregate }`\n- `getAggregate({ subjectType, externalId })` → `{ avgRating, reviewCount, ratingBreakdown }`\n- `getAggregates([{subjectType, externalId}, …])` → aggregates[]\n- `markHelpful({ reviewId, voterExternalUserId })`\n- `respondToReview({ reviewId, responderExternalUserId, responderDisplayName?, text })`\n- `getReviewsByAuthor({ authorExternalUserId, limit?, skip? })`\n\n## Provisioning an app key\nGet your key either self-serve (the 3y3anaa portal → Settings → API Keys) or, for admins, by running the master-key `provisionAppCredential` cloud function with `{ appName: \"sellub\", scopes: [\"product\",\"shop\",\"supplier\",\"courier\"] }`. It returns the plaintext key **once** — store it in the subsidiary's server env as `THREEYANAA_APP_KEY`. That single key is all the SDK needs.\n\n## Build\n```bash\nnpm run build      # tsup → CJS + ESM + .d.ts\n```\n","readmeFilename":"README.md"}