{"_id":"@broberg/complimenta-sdk","_rev":"3-289f565dc281a5a6b8ed2854c2f8e6ae","name":"@broberg/complimenta-sdk","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@broberg/complimenta-sdk","version":"0.1.0","license":"MIT","_id":"@broberg/complimenta-sdk@0.1.0","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/fdaa#readme","bugs":{"url":"https://github.com/broberg-ai/fdaa/issues"},"dist":{"shasum":"811b54f7480df420ead48cb67bbb0fa9fddd492f","tarball":"https://registry.npmjs.org/@broberg/complimenta-sdk/-/complimenta-sdk-0.1.0.tgz","fileCount":14,"integrity":"sha512-+gKrU5qT/YHFGdvK5FVfTQKvuGyv/PSQI4TZP2AM04L1/2J6nbPB2WPOKGBf0W7JomTB9o2bKM09m2llWqOM/A==","signatures":[{"sig":"MEUCIQDdYkB2W2FwPhwfFUKYqDOZ0KKXAj29w8i1IXuFNSVUzgIgJnjSkXcT7+jz/+TGIsun+nY53OIsnRSUcAiqe7jKpCk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":253721},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"71671f61207cf58fb31654da88663d33f02e49c9","scripts":{"test":"tsc -p tsconfig.json --noEmit","build":"tsc -p tsconfig.json","smoke":"bun scripts/smoke.ts","generate":"openapi-typescript openapi/complimenta-external.json -o src/schema.ts","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"cbroberg","email":"cb@webhouse.dk"},"repository":{"url":"git+https://github.com/broberg-ai/fdaa.git","type":"git","directory":"packages/complimenta"},"_npmVersion":"11.10.1","description":"Typed SDK for the Complimenta (ComplimentaWork) booking API — read therapists/services/clinics/calendar-slots and create/cancel bookings. Generated from Complimenta's OpenAPI spec; OAuth2 client-credentials; runs in Next.js and Bun.","directories":{},"sideEffects":false,"_nodeVersion":"25.7.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","openapi-typescript":"^7.13.0"},"_npmOperationalInternal":{"tmp":"tmp/complimenta-sdk_0.1.0_1781619408230_0.6180577751873098","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@broberg/complimenta-sdk","version":"0.2.0","license":"MIT","_id":"@broberg/complimenta-sdk@0.2.0","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"homepage":"https://github.com/broberg-ai/fdaa#readme","bugs":{"url":"https://github.com/broberg-ai/fdaa/issues"},"dist":{"shasum":"130538534ff58a16c0482e32ff8c5ef32e9bd7c9","tarball":"https://registry.npmjs.org/@broberg/complimenta-sdk/-/complimenta-sdk-0.2.0.tgz","fileCount":14,"integrity":"sha512-vsXIq/OoX+r0UAByJNht/EukSwIDiVsznRbCHJ8pWLcji2BMtgXkfdXpZwB2by31zXrg9pyG/HUw3GBoWaYISA==","signatures":[{"sig":"MEUCIQDlStO/m+lMQcbemXQXtwxuYsYIJPHnyTd6dh4cmBJ6UAIgB+Q0Xnv1dkn0JUfh9HIveY96BFkkyb/NCWq1OZ+CSpk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":256399},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"225b1a9e8bdfeac73fe286fab54b1a9c4a08e2d1","scripts":{"test":"tsc -p tsconfig.json --noEmit","build":"tsc -p tsconfig.json","smoke":"bun scripts/smoke.ts","generate":"openapi-typescript openapi/complimenta-external.json -o src/schema.ts","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d814c804-fe77-4ef5-b46b-e9a0129b344f"}},"repository":{"url":"git+https://github.com/broberg-ai/fdaa.git","type":"git","directory":"packages/complimenta"},"_npmVersion":"11.17.0","description":"Typed SDK for the Complimenta (ComplimentaWork) booking API — read therapists/services/clinics/calendar-slots and create/cancel bookings. Generated from Complimenta's OpenAPI spec; OAuth2 client-credentials; runs in Next.js and Bun.","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","openapi-typescript":"^7.13.0"},"_npmOperationalInternal":{"tmp":"tmp/complimenta-sdk_0.2.0_1781805081683_0.20171236048639085","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@broberg/complimenta-sdk","version":"0.3.0","description":"Typed SDK for the Complimenta (ComplimentaWork) booking API — read therapists/services/clinics/calendar-slots and create/cancel bookings. Generated from Complimenta's OpenAPI spec; OAuth2 client-credentials; runs in Next.js and Bun.","type":"module","license":"MIT","sideEffects":false,"repository":{"type":"git","url":"git+https://github.com/broberg-ai/fdaa.git","directory":"packages/complimenta"},"publishConfig":{"access":"public"},"main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"generate":"openapi-typescript openapi/complimenta-external.json -o src/schema.ts","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test":"tsc -p tsconfig.json --noEmit","smoke":"bun scripts/smoke.ts"},"devDependencies":{"openapi-typescript":"^7.13.0","typescript":"^5.6.0"},"gitHead":"4ef76bcfea06f503ab02d66b0c66d6fb8147cfa4","_id":"@broberg/complimenta-sdk@0.3.0","bugs":{"url":"https://github.com/broberg-ai/fdaa/issues"},"homepage":"https://github.com/broberg-ai/fdaa#readme","_nodeVersion":"22.23.1","_npmVersion":"12.0.2","dist":{"integrity":"sha512-k0qq21DgjbNnBMzJwGTr6FiJ+bgst0cwNVA4WFP+k59plowvWT53sq9mOP71N7fVpw5k/418qBfdjtZHRvV6qg==","shasum":"7bc20586dbd938063eefae0c65cb6ef9109b7d0f","tarball":"https://registry.npmjs.org/@broberg/complimenta-sdk/-/complimenta-sdk-0.3.0.tgz","fileCount":14,"unpackedSize":254620,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCkU/Z5+wVtv9YyAxGaRI9HeUxrf/lh+tCfHZfcfJ9C4QIhAIUa3rFIfksMJ6/XkOA5nn9V9dqkONsdGa/pKy1jrnVx"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d814c804-fe77-4ef5-b46b-e9a0129b344f"}},"directories":{},"maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/complimenta-sdk_0.3.0_1786436735211_0.5869986594285104"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-16T14:16:48.057Z","modified":"2026-08-11T08:25:35.527Z","0.1.0":"2026-06-16T14:16:48.373Z","0.2.0":"2026-06-18T17:51:21.810Z","0.3.0":"2026-08-11T08:25:35.357Z"},"bugs":{"url":"https://github.com/broberg-ai/fdaa/issues"},"license":"MIT","homepage":"https://github.com/broberg-ai/fdaa#readme","repository":{"type":"git","url":"git+https://github.com/broberg-ai/fdaa.git","directory":"packages/complimenta"},"description":"Typed SDK for the Complimenta (ComplimentaWork) booking API — read therapists/services/clinics/calendar-slots and create/cancel bookings. Generated from Complimenta's OpenAPI spec; OAuth2 client-credentials; runs in Next.js and Bun.","maintainers":[{"name":"cbroberg","email":"cb@webhouse.dk"}],"readme":"# @broberg/complimenta-sdk\n\nTyped SDK for the **Complimenta** (ComplimentaWork) booking system — read\ntherapists / services / clinics / calendar-slots and create + cancel bookings.\nTypes are **generated from Complimenta's own OpenAPI spec**, so the contract is\nexact and complete. Zero runtime dependencies, native `fetch` → runs unchanged\nin **Next.js** and **Bun**.\n\nBuilt in the **fdaa monorepo** (`packages/complimenta`), published to npm as\n`@broberg/complimenta-sdk`. One SDK, consumed across the FysioDanmark Aalborg\nfleet: the `fdaa` platform, the future `fdaa-sundhed` repo, and the native apps.\n\n## Auth\n\nOAuth2 **client-credentials**: the SDK exchanges `clientId`+`clientSecret` at the\nauth host's `/oauth2/token` for a Bearer JWT (cached + auto-refreshed) and sends\nit on every `/api/v1/*` call.\n\n```ts\nimport { createComplimentaClient } from \"@broberg/complimenta-sdk\";\n\nconst cam = createComplimentaClient({\n  baseUrl: process.env.COMPLIMENTA_BASE_URL!,        // scheme+host, no path\n  clientId: process.env.COMPLIMENTA_CLIENT_ID!,\n  clientSecret: process.env.COMPLIMENTA_CLIENT_SECRET!,\n});\n\nconst therapists = await cam.listUsers();                 // GET /api/v1/users\nconst services   = await cam.listClinicServices();        // GET /api/v1/clinic-services\nconst slots      = await cam.listUserCalendarSlots(        // GET /api/v1/users/{userId}/calendar-slots\n  therapists.items[0].id,\n  { endsOnOrAfter: \"2026-06-16T08:00:00\", endsBefore: \"2026-06-23T17:00:00\" }, // end-time window (required)\n);\nconst bookings   = await cam.listBookings({               // GET /api/v1/bookings\n  startsAtOrAfter: \"2026-06-16T00:00:00\",                 // from-date window (required, ≤ 3 months)\n  startsBefore:    \"2026-06-23T00:00:00\",\n});\n// also: listClinics/getClinic · listPublicServices · getBooking ·\n//       createBooking(body) · cancelBooking(id)\n```\n\n`cam.request(method, path, { query, body })` is the typed escape hatch for any of\nthe ~40 endpoints not yet wrapped in a convenience method.\n\n## Three traps the types can't express\n\n**Timestamps are UTC — always.** `fromTime`/`toTime` are naive (no zone) but the\nAPI reads them as UTC, which the spec now says outright (*\"Must be UTC\"*).\nA Danish 09:00 is `07:00` in summer and `08:00` in winter. Send local time and\nthe booking silently lands two hours off.\n\n**`confirmationSmsMessage` bypasses the clinic's template completely** — nothing\nis merged in, so the text must be COMPLETE on its own (clinic, therapist, date,\ntime). `maxLength: 160` is enforced server-side, **but it counts characters, not\nmessages** — and that is the whole trap. 160 characters is one SMS only if every\ncharacter is in the **GSM 03.38** basic alphabet. æ, ø and å are — but a\ntypographic dash (—), a curly apostrophe (’) or an ellipsis (…) flips the entire\nmessage to UCS-2 at 67 characters per part, so a 160-character string sails\nthrough Complimenta's check and arrives as **three** SMS. Nothing on the server\nside can catch that.\n\nThe SDK deliberately does NOT validate it either: this is a pure generated\ntransport, and a hand-written check here would be deleted by the next\n`pnpm generate` — a safeguard that disappears silently is worse than none. The\ncheck belongs where the text is composed. Validate before you call; it is the\nonly validation that exists.\n\n**`notes` is deprecated** in favour of `bookingDescription` (marked\n`@deprecated` in the generated types). Both still send; only one has a future.\n\n## Types generated from the spec\n\nThe full contract lives in `openapi/complimenta-external.json`, vendored from\n**production** — `GET https://api.complimentawork.dk/v3/api-docs/external`.\n\nVendor production, not demo. The file was originally taken from `api-demo`, and\ndemo lags: for a while `confirmationSmsMessage` existed in production and not in\ndemo, so the generated types simply did not have it and no consumer could see\nit. (The two specs are byte-identical today apart from the auth host — but that\nis a coincidence of timing, not a guarantee.)\n\nRegenerate whenever Complimenta updates their API:\n\n```sh\npnpm generate      # openapi-typescript → src/schema.ts (paths · components · operations)\n```\n\n`src/schema.ts` is **generated — do not hand-edit.** The convenience methods\nderive their request/response types from it, so a spec change surfaces as a\ntype error at the call-site.\n\n## Smoke test (proves the live connection)\n\n```sh\ncp .env.example .env     # COMPLIMENTA_BASE_URL + COMPLIMENTA_CLIENT_ID + COMPLIMENTA_CLIENT_SECRET\nbun scripts/smoke.ts     # token exchange + GET /calendar-slots\n```\n","readmeFilename":"README.md"}