@hipnation-truth/sdk 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +76 -0
- package/dist/index.d.ts +76 -0
- package/dist/index.js +148 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +148 -12
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.ts +72 -79
- package/dist/react.js +142 -148
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -168,6 +168,65 @@ var AttachmentsResource = class {
|
|
|
168
168
|
}
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* One-shot upload: presign → PUT to S3 → record in Convex → return a
|
|
173
|
+
* 7-day signed download URL ready to embed in an outbound SMS. Caller
|
|
174
|
+
* passes the resulting `downloadUrl` to `messages.dialpad.sendSms` (or
|
|
175
|
+
* the new `messages.sendAttachmentMessage`) to actually deliver it.
|
|
176
|
+
*
|
|
177
|
+
* Replaces CommHub's NestJS `/send-attachment` controller in a single
|
|
178
|
+
* SDK call — no base64 round-trip, no legacy `/attachments/:id/download`
|
|
179
|
+
* REST endpoint required.
|
|
180
|
+
*/
|
|
181
|
+
upload(input) {
|
|
182
|
+
return __async(this, null, function* () {
|
|
183
|
+
var _a;
|
|
184
|
+
const presigned = yield this.createUploadUrl({
|
|
185
|
+
fileName: input.fileName,
|
|
186
|
+
mimeType: input.mimeType,
|
|
187
|
+
size: input.size,
|
|
188
|
+
conversationId: input.conversationId
|
|
189
|
+
});
|
|
190
|
+
const body = input.file instanceof Blob ? input.file : input.file instanceof Uint8Array ? input.file : new Uint8Array(input.file);
|
|
191
|
+
const abort = new AbortController();
|
|
192
|
+
const timer = setTimeout(() => abort.abort(), 3e4);
|
|
193
|
+
let putRes;
|
|
194
|
+
try {
|
|
195
|
+
putRes = yield fetch(presigned.uploadUrl, {
|
|
196
|
+
method: "PUT",
|
|
197
|
+
headers: { "Content-Type": input.mimeType },
|
|
198
|
+
body,
|
|
199
|
+
signal: abort.signal
|
|
200
|
+
});
|
|
201
|
+
} finally {
|
|
202
|
+
clearTimeout(timer);
|
|
203
|
+
}
|
|
204
|
+
if (!putRes.ok) {
|
|
205
|
+
throw new AttachmentsError(
|
|
206
|
+
"s3-put",
|
|
207
|
+
putRes.status,
|
|
208
|
+
`S3 PUT ${putRes.status} for ${presigned.s3Key}`
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
const recorded = yield this.record({
|
|
212
|
+
s3Key: presigned.s3Key,
|
|
213
|
+
fileName: input.fileName,
|
|
214
|
+
mimeType: input.mimeType,
|
|
215
|
+
size: input.size,
|
|
216
|
+
conversationId: input.conversationId,
|
|
217
|
+
uploadedBy: input.uploadedBy
|
|
218
|
+
});
|
|
219
|
+
const signed = yield this.getDownloadUrl(
|
|
220
|
+
presigned.s3Key,
|
|
221
|
+
(_a = input.downloadExpiresIn) != null ? _a : 7 * 24 * 3600
|
|
222
|
+
);
|
|
223
|
+
return {
|
|
224
|
+
attachmentId: recorded.attachmentId,
|
|
225
|
+
s3Key: presigned.s3Key,
|
|
226
|
+
downloadUrl: signed.url
|
|
227
|
+
};
|
|
228
|
+
});
|
|
229
|
+
}
|
|
171
230
|
};
|
|
172
231
|
|
|
173
232
|
// src/resources/dialpad.ts
|
|
@@ -398,6 +457,36 @@ var DialpadResource = class {
|
|
|
398
457
|
var MessagesResource = class {
|
|
399
458
|
constructor(apiBaseUrl, apiKey) {
|
|
400
459
|
this.dialpad = new DialpadResource(apiBaseUrl, apiKey);
|
|
460
|
+
this.baseUrl = apiBaseUrl;
|
|
461
|
+
this.apiKey = apiKey;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* End a Dialpad call via the typed oRPC procedure (POST hangup, with
|
|
465
|
+
* 404→`alreadyEnded` so the UI doesn't flash an error on a natural
|
|
466
|
+
* race). Replaces CommHub's `useEndCallMutation` Hasura action.
|
|
467
|
+
*
|
|
468
|
+
* Prefer this over `messages.dialpad.endCall` which goes through the
|
|
469
|
+
* generic proxy (PUT, no 404 handling).
|
|
470
|
+
*/
|
|
471
|
+
endCall(callId) {
|
|
472
|
+
return __async(this, null, function* () {
|
|
473
|
+
const res = yield fetch(`${this.baseUrl}/api/conversations/calls/end`, {
|
|
474
|
+
method: "POST",
|
|
475
|
+
headers: {
|
|
476
|
+
"Content-Type": "application/json",
|
|
477
|
+
Accept: "application/json",
|
|
478
|
+
"X-API-Key": this.apiKey
|
|
479
|
+
},
|
|
480
|
+
body: JSON.stringify({ callId })
|
|
481
|
+
});
|
|
482
|
+
if (!res.ok) {
|
|
483
|
+
const text = yield res.text().catch(() => "");
|
|
484
|
+
throw new Error(
|
|
485
|
+
`messages.endCall failed (HTTP ${res.status}): ${text.slice(0, 200)}`
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
return yield res.json();
|
|
489
|
+
});
|
|
401
490
|
}
|
|
402
491
|
};
|
|
403
492
|
var DialpadProxyError = class extends Error {
|
|
@@ -547,30 +636,77 @@ var NotesError = class extends Error {
|
|
|
547
636
|
this.status = status;
|
|
548
637
|
}
|
|
549
638
|
};
|
|
550
|
-
var
|
|
639
|
+
var _NotesResource = class _NotesResource {
|
|
551
640
|
constructor(apiBaseUrl, apiKey) {
|
|
552
641
|
this.baseUrl = apiBaseUrl;
|
|
553
642
|
this.apiKey = apiKey;
|
|
554
643
|
}
|
|
555
|
-
|
|
644
|
+
post(path, body) {
|
|
556
645
|
return __async(this, null, function* () {
|
|
557
|
-
const
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
646
|
+
const controller = new AbortController();
|
|
647
|
+
const timeout = setTimeout(
|
|
648
|
+
() => controller.abort(),
|
|
649
|
+
_NotesResource.REQUEST_TIMEOUT_MS
|
|
650
|
+
);
|
|
651
|
+
let res;
|
|
652
|
+
try {
|
|
653
|
+
res = yield fetch(`${this.baseUrl}/api${path}`, {
|
|
654
|
+
method: "POST",
|
|
655
|
+
headers: {
|
|
656
|
+
"Content-Type": "application/json",
|
|
657
|
+
Accept: "application/json",
|
|
658
|
+
"X-API-Key": this.apiKey
|
|
659
|
+
},
|
|
660
|
+
body: JSON.stringify(body),
|
|
661
|
+
signal: controller.signal
|
|
662
|
+
});
|
|
663
|
+
} catch (err) {
|
|
664
|
+
const isAbort = err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError");
|
|
665
|
+
const message = isAbort ? `Notes ${path} timed out after ${_NotesResource.REQUEST_TIMEOUT_MS}ms` : err instanceof Error ? err.message : "Notes request failed before response";
|
|
666
|
+
throw new NotesError(path, 0, message);
|
|
667
|
+
} finally {
|
|
668
|
+
clearTimeout(timeout);
|
|
669
|
+
}
|
|
566
670
|
if (!res.ok) {
|
|
567
671
|
const text = yield res.text().catch(() => "");
|
|
568
|
-
throw new NotesError(
|
|
672
|
+
throw new NotesError(path, res.status, text.slice(0, 200));
|
|
569
673
|
}
|
|
570
674
|
return yield res.json();
|
|
571
675
|
});
|
|
572
676
|
}
|
|
677
|
+
/**
|
|
678
|
+
* Low-level — caller has already resolved Elation patient / physician
|
|
679
|
+
* / practice. Use `pushConversationToElation` if you only have a
|
|
680
|
+
* conversation handle.
|
|
681
|
+
*/
|
|
682
|
+
pushToElation(input) {
|
|
683
|
+
return __async(this, null, function* () {
|
|
684
|
+
return yield this.post(
|
|
685
|
+
"/notes/push-to-elation",
|
|
686
|
+
input
|
|
687
|
+
);
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Orchestrator — pass a conversation handle + pre-assembled note text.
|
|
692
|
+
* Truth resolves the linked patient via Convex, looks up
|
|
693
|
+
* physician/practice in Elation, posts the note, and writes an audit
|
|
694
|
+
* row to `elationSyncEvents`. Replaces CommHub's `pushNotesToElation`
|
|
695
|
+
* Hasura action.
|
|
696
|
+
*/
|
|
697
|
+
pushConversationToElation(input) {
|
|
698
|
+
return __async(this, null, function* () {
|
|
699
|
+
return yield this.post(
|
|
700
|
+
"/notes/push-conversation-to-elation",
|
|
701
|
+
input
|
|
702
|
+
);
|
|
703
|
+
});
|
|
704
|
+
}
|
|
573
705
|
};
|
|
706
|
+
/** 30s upstream timeout — Elation API has occasional slow hops; we
|
|
707
|
+
* don't want a pending mutation to hold the UI thread indefinitely. */
|
|
708
|
+
_NotesResource.REQUEST_TIMEOUT_MS = 3e4;
|
|
709
|
+
var NotesResource = _NotesResource;
|
|
574
710
|
|
|
575
711
|
// src/resources/notifications.ts
|
|
576
712
|
var NotificationsError = class extends Error {
|