@yannelli/nextvisit-sdk 1.0.1

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.js ADDED
@@ -0,0 +1,953 @@
1
+ 'use strict';
2
+
3
+ // src/errors.ts
4
+ var NextvisitError = class _NextvisitError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = "NextvisitError";
8
+ Object.setPrototypeOf(this, _NextvisitError.prototype);
9
+ }
10
+ };
11
+ var NextvisitApiError = class _NextvisitApiError extends NextvisitError {
12
+ constructor(status, error) {
13
+ super(error.message);
14
+ this.name = "NextvisitApiError";
15
+ this.status = status;
16
+ this.errors = error.errors;
17
+ Object.setPrototypeOf(this, _NextvisitApiError.prototype);
18
+ }
19
+ };
20
+ var UnauthorizedError = class _UnauthorizedError extends NextvisitApiError {
21
+ constructor(error) {
22
+ super(401, error);
23
+ this.name = "UnauthorizedError";
24
+ Object.setPrototypeOf(this, _UnauthorizedError.prototype);
25
+ }
26
+ };
27
+ var ForbiddenError = class _ForbiddenError extends NextvisitApiError {
28
+ constructor(error) {
29
+ super(403, error);
30
+ this.name = "ForbiddenError";
31
+ Object.setPrototypeOf(this, _ForbiddenError.prototype);
32
+ }
33
+ };
34
+ var NotFoundError = class _NotFoundError extends NextvisitApiError {
35
+ constructor(error) {
36
+ super(404, error);
37
+ this.name = "NotFoundError";
38
+ Object.setPrototypeOf(this, _NotFoundError.prototype);
39
+ }
40
+ };
41
+ var ValidationError = class _ValidationError extends NextvisitApiError {
42
+ constructor(error) {
43
+ super(422, error);
44
+ this.name = "ValidationError";
45
+ Object.setPrototypeOf(this, _ValidationError.prototype);
46
+ }
47
+ };
48
+ var NetworkError = class _NetworkError extends NextvisitError {
49
+ constructor(message, cause) {
50
+ super(message);
51
+ this.name = "NetworkError";
52
+ this.cause = cause;
53
+ Object.setPrototypeOf(this, _NetworkError.prototype);
54
+ }
55
+ };
56
+
57
+ // src/http.ts
58
+ var HttpClient = class {
59
+ constructor(config) {
60
+ this.baseUrl = config.baseUrl.replace(/\/$/, "");
61
+ this.token = config.token;
62
+ this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);
63
+ this.timeout = config.timeout ?? 3e4;
64
+ }
65
+ /**
66
+ * Set the authentication token
67
+ */
68
+ setToken(token) {
69
+ this.token = token;
70
+ }
71
+ /**
72
+ * Get the current authentication token
73
+ */
74
+ getToken() {
75
+ return this.token;
76
+ }
77
+ /**
78
+ * Build URL with query parameters
79
+ */
80
+ buildUrl(path, params) {
81
+ const url = new URL(`${this.baseUrl}${path}`);
82
+ if (params) {
83
+ for (const [key, value] of Object.entries(params)) {
84
+ if (value !== void 0) {
85
+ url.searchParams.set(key, String(value));
86
+ }
87
+ }
88
+ }
89
+ return url.toString();
90
+ }
91
+ /**
92
+ * Build request headers
93
+ */
94
+ buildHeaders(options, contentType) {
95
+ const headers = {
96
+ Accept: "application/json",
97
+ ...options?.headers
98
+ };
99
+ if (contentType) {
100
+ headers["Content-Type"] = contentType;
101
+ }
102
+ if (this.token) {
103
+ headers["Authorization"] = `Bearer ${this.token}`;
104
+ }
105
+ return headers;
106
+ }
107
+ /**
108
+ * Handle API error responses
109
+ */
110
+ async handleError(response) {
111
+ let error;
112
+ try {
113
+ error = await response.json();
114
+ } catch {
115
+ error = { message: response.statusText || "Unknown error" };
116
+ }
117
+ switch (response.status) {
118
+ case 401:
119
+ throw new UnauthorizedError(error);
120
+ case 403:
121
+ throw new ForbiddenError(error);
122
+ case 404:
123
+ throw new NotFoundError(error);
124
+ case 422:
125
+ throw new ValidationError(error);
126
+ default:
127
+ throw new NextvisitApiError(response.status, error);
128
+ }
129
+ }
130
+ /**
131
+ * Execute a fetch request with timeout
132
+ */
133
+ async executeFetch(url, init, signal) {
134
+ const controller = new AbortController();
135
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
136
+ const combinedSignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;
137
+ try {
138
+ const response = await this.fetchFn(url, {
139
+ ...init,
140
+ signal: combinedSignal
141
+ });
142
+ clearTimeout(timeoutId);
143
+ return response;
144
+ } catch (err) {
145
+ clearTimeout(timeoutId);
146
+ if (err instanceof Error) {
147
+ if (err.name === "AbortError") {
148
+ throw new NetworkError("Request was aborted or timed out", err);
149
+ }
150
+ throw new NetworkError(`Network request failed: ${err.message}`, err);
151
+ }
152
+ throw new NetworkError("Network request failed");
153
+ }
154
+ }
155
+ /**
156
+ * Make a GET request
157
+ */
158
+ async get(path, options) {
159
+ const url = this.buildUrl(path, options?.params);
160
+ const headers = this.buildHeaders(options);
161
+ const response = await this.executeFetch(
162
+ url,
163
+ { method: "GET", headers },
164
+ options?.signal
165
+ );
166
+ if (!response.ok) {
167
+ await this.handleError(response);
168
+ }
169
+ return await response.json();
170
+ }
171
+ /**
172
+ * Make a POST request with JSON body
173
+ */
174
+ async post(path, body, options) {
175
+ const url = this.buildUrl(path, options?.params);
176
+ const headers = this.buildHeaders(options, "application/json");
177
+ const response = await this.executeFetch(
178
+ url,
179
+ {
180
+ method: "POST",
181
+ headers,
182
+ body: body ? JSON.stringify(body) : void 0
183
+ },
184
+ options?.signal
185
+ );
186
+ if (!response.ok) {
187
+ await this.handleError(response);
188
+ }
189
+ return await response.json();
190
+ }
191
+ /**
192
+ * Make a POST request with FormData body (for file uploads)
193
+ */
194
+ async postForm(path, formData, options) {
195
+ const url = this.buildUrl(path, options?.params);
196
+ const headers = this.buildHeaders(options);
197
+ const response = await this.executeFetch(
198
+ url,
199
+ {
200
+ method: "POST",
201
+ headers,
202
+ body: formData
203
+ },
204
+ options?.signal
205
+ );
206
+ if (!response.ok) {
207
+ await this.handleError(response);
208
+ }
209
+ return await response.json();
210
+ }
211
+ /**
212
+ * Make a PUT request with JSON body
213
+ */
214
+ async put(path, body, options) {
215
+ const url = this.buildUrl(path, options?.params);
216
+ const headers = this.buildHeaders(options, "application/json");
217
+ const response = await this.executeFetch(
218
+ url,
219
+ {
220
+ method: "PUT",
221
+ headers,
222
+ body: body ? JSON.stringify(body) : void 0
223
+ },
224
+ options?.signal
225
+ );
226
+ if (!response.ok) {
227
+ await this.handleError(response);
228
+ }
229
+ return await response.json();
230
+ }
231
+ /**
232
+ * Make a DELETE request
233
+ */
234
+ async delete(path, options) {
235
+ const url = this.buildUrl(path, options?.params);
236
+ const headers = this.buildHeaders(options);
237
+ const response = await this.executeFetch(
238
+ url,
239
+ { method: "DELETE", headers },
240
+ options?.signal
241
+ );
242
+ if (!response.ok) {
243
+ await this.handleError(response);
244
+ }
245
+ return await response.json();
246
+ }
247
+ };
248
+
249
+ // src/resources/base.ts
250
+ var BaseResource = class {
251
+ constructor(http) {
252
+ this.http = http;
253
+ }
254
+ };
255
+
256
+ // src/resources/auth.ts
257
+ var AuthResource = class extends BaseResource {
258
+ /**
259
+ * Create a new access token (login)
260
+ *
261
+ * Authenticates a user with email and password, returning an access token
262
+ * that can be used for subsequent API requests.
263
+ *
264
+ * @param credentials - Login credentials
265
+ * @returns Token response with access token and user info
266
+ *
267
+ * @example
268
+ * ```typescript
269
+ * const response = await client.auth.createToken({
270
+ * email: "user@example.com",
271
+ * password: "password123",
272
+ * device_name: "My App"
273
+ * });
274
+ *
275
+ * console.log(response.token); // Use this token for authentication
276
+ * ```
277
+ */
278
+ async createToken(credentials) {
279
+ return this.http.post("/v1/auth/tokens", credentials);
280
+ }
281
+ /**
282
+ * Authenticate with Google Sign-In
283
+ *
284
+ * Authenticates a user using a Google ID token obtained from Google Sign-In SDK.
285
+ * Supports tokens from web applications, Chrome extensions, iOS apps, and Android apps.
286
+ * If the user doesn't exist, a new account is automatically created.
287
+ *
288
+ * @param params - Google authentication parameters
289
+ * @returns Authentication response with access token and user info
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * // Web application
294
+ * const response = await client.auth.googleAuth({
295
+ * id_token: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
296
+ * device_name: "Web Browser"
297
+ * });
298
+ *
299
+ * if (response.is_new_user) {
300
+ * console.log("Welcome! Your account has been created.");
301
+ * }
302
+ *
303
+ * // Use response.token for subsequent requests
304
+ * client.setToken(response.token);
305
+ * ```
306
+ */
307
+ async googleAuth(params) {
308
+ return this.http.post("/v1/auth/google", params);
309
+ }
310
+ /**
311
+ * Revoke the current access token (logout)
312
+ *
313
+ * Invalidates the current authentication token. After calling this method,
314
+ * the token can no longer be used for API requests.
315
+ *
316
+ * @returns Confirmation message
317
+ *
318
+ * @example
319
+ * ```typescript
320
+ * await client.auth.revokeCurrentToken();
321
+ * // Token is now invalid
322
+ * ```
323
+ */
324
+ async revokeCurrentToken() {
325
+ return this.http.delete("/v1/auth/tokens/current");
326
+ }
327
+ /**
328
+ * List all tokens for the authenticated user
329
+ *
330
+ * Returns a list of all active tokens associated with the current user,
331
+ * including information about when each token was created and last used.
332
+ *
333
+ * @returns List of tokens
334
+ *
335
+ * @example
336
+ * ```typescript
337
+ * const response = await client.auth.listTokens();
338
+ *
339
+ * for (const token of response.tokens) {
340
+ * console.log(`${token.name} - Created: ${token.created_at}`);
341
+ * }
342
+ * ```
343
+ */
344
+ async listTokens() {
345
+ return this.http.get("/v1/auth/tokens");
346
+ }
347
+ /**
348
+ * Revoke a specific token by ID
349
+ *
350
+ * Invalidates a specific token by its ID. This can be used to revoke
351
+ * tokens on other devices or applications.
352
+ *
353
+ * @param id - The unique identifier of the token to revoke
354
+ * @returns Confirmation message
355
+ *
356
+ * @example
357
+ * ```typescript
358
+ * // List tokens and revoke a specific one
359
+ * const { tokens } = await client.auth.listTokens();
360
+ * const oldToken = tokens.find(t => t.name === "Old Device");
361
+ *
362
+ * if (oldToken) {
363
+ * await client.auth.revokeToken(oldToken.id);
364
+ * console.log("Token revoked");
365
+ * }
366
+ * ```
367
+ */
368
+ async revokeToken(id) {
369
+ return this.http.delete(`/v1/auth/tokens/${id}`);
370
+ }
371
+ };
372
+
373
+ // src/resources/users.ts
374
+ var UsersResource = class extends BaseResource {
375
+ /**
376
+ * Get the currently authenticated user
377
+ *
378
+ * Retrieves the full profile of the user associated with the current
379
+ * authentication token.
380
+ *
381
+ * @returns The authenticated user's details
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * const user = await client.users.getCurrentUser();
386
+ * console.log(`Logged in as ${user.name} (${user.email})`);
387
+ * ```
388
+ */
389
+ async getCurrentUser() {
390
+ return this.http.get("/user");
391
+ }
392
+ };
393
+
394
+ // src/resources/patients.ts
395
+ var PatientsResource = class extends BaseResource {
396
+ /**
397
+ * List patients
398
+ *
399
+ * Returns a paginated list of patients with optional filtering
400
+ * and customizable pagination/sorting.
401
+ *
402
+ * @param params - Optional filtering and pagination parameters
403
+ * @returns Paginated list of patients
404
+ *
405
+ * @example
406
+ * ```typescript
407
+ * // Get all patients
408
+ * const patients = await client.patients.list();
409
+ *
410
+ * // Filter and sort patients
411
+ * const filtered = await client.patients.list({
412
+ * "filter[last_name]": "Smith",
413
+ * sort: "-created_at",
414
+ * per_page: 25
415
+ * });
416
+ *
417
+ * // Include soft-deleted patients
418
+ * const withTrashed = await client.patients.list({
419
+ * "filter[trashed]": "with"
420
+ * });
421
+ * ```
422
+ */
423
+ async list(params) {
424
+ return this.http.get("/v1/patients", {
425
+ params
426
+ });
427
+ }
428
+ /**
429
+ * Get a specific patient
430
+ *
431
+ * Retrieves detailed information about a single patient by their ID.
432
+ *
433
+ * @param id - The patient ID
434
+ * @returns The patient details wrapped in a response object
435
+ *
436
+ * @example
437
+ * ```typescript
438
+ * const response = await client.patients.get(123);
439
+ * console.log(response.data.first_name);
440
+ * console.log(response.data.date_of_birth);
441
+ * ```
442
+ */
443
+ async get(id) {
444
+ return this.http.get(`/v1/patients/${id}`);
445
+ }
446
+ /**
447
+ * Create a new patient
448
+ *
449
+ * Creates a new patient record with the provided information.
450
+ *
451
+ * @param params - The patient data
452
+ * @returns The created patient wrapped in a response object
453
+ *
454
+ * @example
455
+ * ```typescript
456
+ * const response = await client.patients.create({
457
+ * first_name: "John",
458
+ * last_name: "Doe",
459
+ * date_of_birth: "1990-05-15",
460
+ * notes: "New patient referral",
461
+ * allergies: "Penicillin"
462
+ * });
463
+ *
464
+ * console.log(response.data.id);
465
+ * ```
466
+ */
467
+ async create(params) {
468
+ return this.http.post("/v1/patients", params);
469
+ }
470
+ /**
471
+ * Update a patient
472
+ *
473
+ * Updates an existing patient's information.
474
+ *
475
+ * @param id - The patient ID
476
+ * @param params - The fields to update
477
+ * @returns The updated patient wrapped in a response object
478
+ *
479
+ * @example
480
+ * ```typescript
481
+ * const response = await client.patients.update(123, {
482
+ * first_name: "Jonathan",
483
+ * notes: "Updated contact information"
484
+ * });
485
+ *
486
+ * console.log(response.data.first_name); // "Jonathan"
487
+ * ```
488
+ */
489
+ async update(id, params) {
490
+ return this.http.put(`/v1/patients/${id}`, params);
491
+ }
492
+ /**
493
+ * Delete a patient (soft delete)
494
+ *
495
+ * Soft deletes a patient record. The patient can be restored or
496
+ * permanently deleted later. Use the trashed filter to view deleted patients.
497
+ *
498
+ * @param id - The patient ID
499
+ * @returns Confirmation message
500
+ *
501
+ * @example
502
+ * ```typescript
503
+ * await client.patients.delete(123);
504
+ * console.log("Patient soft deleted successfully");
505
+ *
506
+ * // View deleted patients
507
+ * const deleted = await client.patients.list({
508
+ * "filter[trashed]": "only"
509
+ * });
510
+ * ```
511
+ */
512
+ async delete(id) {
513
+ return this.http.delete(`/v1/patients/${id}`);
514
+ }
515
+ /**
516
+ * Search patients
517
+ *
518
+ * Searches for patients matching the query string within the authenticated
519
+ * user's current team.
520
+ *
521
+ * @param params - Search parameters including query string
522
+ * @returns Paginated list of matching patients
523
+ *
524
+ * @example
525
+ * ```typescript
526
+ * // Search for patients by name
527
+ * const results = await client.patients.search({
528
+ * query: "John",
529
+ * per_page: 10,
530
+ * sort_by: "desc"
531
+ * });
532
+ *
533
+ * console.log(`Found ${results.meta.total} patients`);
534
+ * results.data.forEach(patient => {
535
+ * console.log(`${patient.first_name} ${patient.last_name}`);
536
+ * });
537
+ * ```
538
+ */
539
+ async search(params) {
540
+ return this.http.get(
541
+ `/v1/patients/search`,
542
+ {
543
+ params
544
+ }
545
+ );
546
+ }
547
+ };
548
+
549
+ // src/resources/progress-notes.ts
550
+ var ProgressNotesResource = class extends BaseResource {
551
+ /**
552
+ * List progress notes
553
+ *
554
+ * Returns a paginated list of progress notes with optional filtering
555
+ * by patient and customizable pagination/sorting.
556
+ *
557
+ * @param params - Optional filtering and pagination parameters
558
+ * @returns Paginated list of progress notes
559
+ *
560
+ * @example
561
+ * ```typescript
562
+ * // Get latest notes
563
+ * const notes = await client.progressNotes.list();
564
+ *
565
+ * // Filter by patient
566
+ * const patientNotes = await client.progressNotes.list({
567
+ * patient_id: 123,
568
+ * per_page: 25,
569
+ * sort_by: "oldest"
570
+ * });
571
+ * ```
572
+ */
573
+ async list(params) {
574
+ return this.http.get("/v1/progress-notes", {
575
+ params
576
+ });
577
+ }
578
+ /**
579
+ * Get a specific progress note
580
+ *
581
+ * Retrieves detailed information about a single progress note by its ID.
582
+ *
583
+ * @param id - The progress note ID
584
+ * @returns The progress note details
585
+ *
586
+ * @example
587
+ * ```typescript
588
+ * const note = await client.progressNotes.get(123);
589
+ * console.log(note.name);
590
+ * console.log(note.transcription);
591
+ * ```
592
+ */
593
+ async get(id) {
594
+ return this.http.get(`/v1/progress-notes/${id}`);
595
+ }
596
+ /**
597
+ * Get audio URL for a progress note
598
+ *
599
+ * Retrieves a temporary URL to access the audio file associated with
600
+ * a progress note. The URL is time-limited and will expire.
601
+ *
602
+ * @param id - The progress note ID
603
+ * @returns Object containing the temporary audio URL
604
+ *
605
+ * @example
606
+ * ```typescript
607
+ * const response = await client.progressNotes.getAudioUrl(123);
608
+ * console.log(response.url); // Temporary URL to audio file
609
+ * ```
610
+ */
611
+ async getAudioUrl(id) {
612
+ return this.http.get(`/v1/progress-notes/${id}/audio-url`);
613
+ }
614
+ /**
615
+ * Create a new progress note
616
+ *
617
+ * Creates a new progress note with either an audio file or text content.
618
+ * For audio files, the audio will be transcribed and analyzed asynchronously.
619
+ * For text-only notes, provide the note content directly.
620
+ *
621
+ * @param params - The progress note data (audio file or text-only)
622
+ * @returns The created progress note
623
+ *
624
+ * @example
625
+ * ```typescript
626
+ * // With audio file
627
+ * const audioFile = new File([audioBlob], "recording.mp3", {
628
+ * type: "audio/mpeg"
629
+ * });
630
+ *
631
+ * const note = await client.progressNotes.create({
632
+ * name: "Follow-up Visit - John Doe",
633
+ * patient_id: 456,
634
+ * file: audioFile,
635
+ * model_id: 1 // Optional template
636
+ * });
637
+ *
638
+ * // Text-only note
639
+ * const textNote = await client.progressNotes.create({
640
+ * name: "Patient Consultation",
641
+ * note: "Patient presented with symptoms of...",
642
+ * model_id: 1,
643
+ * patient_id: 456
644
+ * });
645
+ * ```
646
+ */
647
+ async create(params) {
648
+ const formData = new FormData();
649
+ formData.append("name", params.name);
650
+ if (params.patient_id !== void 0) {
651
+ formData.append("patient_id", String(params.patient_id));
652
+ }
653
+ if (params.context !== void 0) {
654
+ formData.append("context", params.context);
655
+ }
656
+ if ("file" in params) {
657
+ const fileParams = params;
658
+ formData.append("file", fileParams.file);
659
+ if (fileParams.model_id !== void 0) {
660
+ formData.append("model_id", String(fileParams.model_id));
661
+ }
662
+ } else {
663
+ const textParams = params;
664
+ formData.append("note", textParams.note);
665
+ formData.append("model_id", String(textParams.model_id));
666
+ if (textParams.documents !== void 0 && textParams.documents.length > 0) {
667
+ for (const docId of textParams.documents) {
668
+ formData.append("documents[]", String(docId));
669
+ }
670
+ }
671
+ }
672
+ return this.http.postForm("/v1/progress-notes", formData);
673
+ }
674
+ /**
675
+ * Update a progress note
676
+ *
677
+ * Updates an existing progress note's metadata, transcription, or analysis.
678
+ *
679
+ * @param id - The progress note ID
680
+ * @param params - The fields to update
681
+ * @returns The updated progress note
682
+ *
683
+ * @example
684
+ * ```typescript
685
+ * const updated = await client.progressNotes.update(123, {
686
+ * name: "Updated Visit Name",
687
+ * transcription: "Corrected transcription text..."
688
+ * });
689
+ * ```
690
+ */
691
+ async update(id, params) {
692
+ return this.http.put(`/v1/progress-notes/${id}`, params);
693
+ }
694
+ /**
695
+ * Delete a progress note
696
+ *
697
+ * Permanently deletes a progress note and its associated audio files.
698
+ * This action cannot be undone.
699
+ *
700
+ * @param id - The progress note ID
701
+ * @returns Confirmation message
702
+ *
703
+ * @example
704
+ * ```typescript
705
+ * await client.progressNotes.delete(123);
706
+ * console.log("Note deleted successfully");
707
+ * ```
708
+ */
709
+ async delete(id) {
710
+ return this.http.delete(`/v1/progress-notes/${id}`);
711
+ }
712
+ /**
713
+ * Sign a progress note
714
+ *
715
+ * Marks a progress note as reviewed and signed. A note can only be signed
716
+ * after transcription and analysis have been completed.
717
+ *
718
+ * @param id - The progress note ID
719
+ * @returns The signed progress note
720
+ *
721
+ * @example
722
+ * ```typescript
723
+ * const signedNote = await client.progressNotes.sign(123);
724
+ * console.log(signedNote.has?.signed); // true
725
+ * ```
726
+ */
727
+ async sign(id) {
728
+ return this.http.put(`/v1/progress-notes/${id}/sign`);
729
+ }
730
+ };
731
+
732
+ // src/resources/billing.ts
733
+ var BillingResource = class extends BaseResource {
734
+ /**
735
+ * List available billing plans
736
+ *
737
+ * Retrieves all available billing plans that can be subscribed to,
738
+ * including pricing information and features.
739
+ *
740
+ * @returns List of available billing plans
741
+ *
742
+ * @example
743
+ * ```typescript
744
+ * const response = await client.billing.listPlans();
745
+ *
746
+ * for (const plan of response.plans) {
747
+ * console.log(`${plan.name}: ${plan.price_prefix}${plan.price}${plan.price_suffix}`);
748
+ * if (plan.features) {
749
+ * plan.features.forEach(feature => console.log(` - ${feature}`));
750
+ * }
751
+ * }
752
+ * ```
753
+ */
754
+ async listPlans() {
755
+ return this.http.get("/v1/billing/plans");
756
+ }
757
+ /**
758
+ * Get billing cost estimate
759
+ *
760
+ * Calculates the estimated billing cost based on the current number
761
+ * of users in the team and any child teams.
762
+ *
763
+ * @returns Billing cost estimate with user count and formatted total
764
+ *
765
+ * @example
766
+ * ```typescript
767
+ * const estimate = await client.billing.getEstimate();
768
+ *
769
+ * console.log(`Users: ${estimate.users}`);
770
+ * console.log(`Estimated cost: ${estimate.total_formatted}`);
771
+ * console.log(`Next renewal: ${estimate.renewal_date}`);
772
+ * ```
773
+ */
774
+ async getEstimate() {
775
+ return this.http.get("/v1/billing/estimate");
776
+ }
777
+ /**
778
+ * Get billing usage statistics
779
+ *
780
+ * Retrieves usage statistics for a specific billing module, including
781
+ * the current subscription plan status and detailed usage metrics.
782
+ *
783
+ * @param module - The billing module to get usage for (e.g., 'notes')
784
+ * @returns Billing usage with plan status and usage statistics
785
+ *
786
+ * @example
787
+ * ```typescript
788
+ * const usage = await client.billing.getUsage("notes");
789
+ *
790
+ * console.log(`Plan: ${usage.plan.name} (${usage.plan.status})`);
791
+ * console.log(`Usage: ${usage.usage.used} / ${usage.usage.limit}`);
792
+ * console.log(`Period: ${usage.usage.period_start} to ${usage.usage.period_end}`);
793
+ *
794
+ * if (usage.plan.trial.on_trial) {
795
+ * console.log(`Trial ends: ${usage.plan.trial.trial_ends_at}`);
796
+ * }
797
+ * ```
798
+ */
799
+ async getUsage(module) {
800
+ return this.http.get(`/v1/billing/usage/${module}`);
801
+ }
802
+ };
803
+
804
+ // src/resources/transcription.ts
805
+ var TranscriptionResource = class extends BaseResource {
806
+ /**
807
+ * Transcribe an audio file
808
+ *
809
+ * Uploads an audio file and returns the transcribed text using AI-powered speech recognition.
810
+ * Supported formats: mp3, mp4, m4a, wav, ogg, webm, flac, aac, pcm, opus
811
+ * Maximum file size: 200MB
812
+ *
813
+ * @param params - The transcription parameters including the audio file
814
+ * @returns Transcription response with the transcribed text
815
+ *
816
+ * @example
817
+ * ```typescript
818
+ * // Transcribe an audio file from a file input
819
+ * const fileInput = document.querySelector('input[type="file"]');
820
+ * const file = fileInput.files[0];
821
+ *
822
+ * const response = await client.transcription.transcribeFile({ file });
823
+ *
824
+ * if (response.success) {
825
+ * console.log(response.text); // The transcribed text
826
+ * }
827
+ * ```
828
+ *
829
+ * @example
830
+ * ```typescript
831
+ * // Transcribe a Blob from recorded audio
832
+ * const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
833
+ *
834
+ * const response = await client.transcription.transcribeFile({
835
+ * file: audioBlob
836
+ * });
837
+ *
838
+ * console.log(response.message); // Status message
839
+ * ```
840
+ */
841
+ async transcribeFile(params) {
842
+ const formData = new FormData();
843
+ formData.append("file", params.file);
844
+ return this.http.postForm(
845
+ "/v1/transcribe/file",
846
+ formData
847
+ );
848
+ }
849
+ /**
850
+ * Get a temporary transcription token
851
+ *
852
+ * Returns a temporary Deepgram API token for client-side audio transcription.
853
+ * The token is short-lived and should be used immediately.
854
+ *
855
+ * @returns Token response with the temporary API token
856
+ *
857
+ * @example
858
+ * ```typescript
859
+ * const response = await client.transcription.getToken();
860
+ *
861
+ * if (response.success && response.token) {
862
+ * // Use the token for client-side Deepgram SDK
863
+ * const deepgram = createClient(response.token);
864
+ * }
865
+ * ```
866
+ */
867
+ async getToken() {
868
+ return this.http.get("/v1/transcribe/token");
869
+ }
870
+ };
871
+
872
+ // src/client.ts
873
+ var DEFAULT_BASE_URL = "https://nextvisit.app/api";
874
+ var NextvisitClient = class {
875
+ /**
876
+ * Create a new Nextvisit API client
877
+ *
878
+ * @param config - Client configuration options
879
+ */
880
+ constructor(config = {}) {
881
+ const httpConfig = {
882
+ baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,
883
+ token: config.token,
884
+ fetch: config.fetch,
885
+ timeout: config.timeout
886
+ };
887
+ this.http = new HttpClient(httpConfig);
888
+ this.auth = new AuthResource(this.http);
889
+ this.users = new UsersResource(this.http);
890
+ this.progressNotes = new ProgressNotesResource(this.http);
891
+ this.billing = new BillingResource(this.http);
892
+ this.transcription = new TranscriptionResource(this.http);
893
+ this.patients = new PatientsResource(this.http);
894
+ }
895
+ /**
896
+ * Set the authentication token
897
+ *
898
+ * Updates the token used for API requests. Call this after
899
+ * authenticating with `auth.createToken()`.
900
+ *
901
+ * @param token - The authentication token
902
+ *
903
+ * @example
904
+ * ```typescript
905
+ * const { token } = await client.auth.createToken(credentials);
906
+ * client.setToken(token);
907
+ * ```
908
+ */
909
+ setToken(token) {
910
+ this.http.setToken(token);
911
+ }
912
+ /**
913
+ * Clear the authentication token
914
+ *
915
+ * Removes the current token. Subsequent requests will be
916
+ * unauthenticated.
917
+ *
918
+ * @example
919
+ * ```typescript
920
+ * await client.auth.revokeCurrentToken();
921
+ * client.clearToken();
922
+ * ```
923
+ */
924
+ clearToken() {
925
+ this.http.setToken(void 0);
926
+ }
927
+ /**
928
+ * Check if the client has an authentication token set
929
+ *
930
+ * @returns `true` if a token is set, `false` otherwise
931
+ */
932
+ hasToken() {
933
+ return this.http.getToken() !== void 0;
934
+ }
935
+ };
936
+
937
+ exports.AuthResource = AuthResource;
938
+ exports.BillingResource = BillingResource;
939
+ exports.DEFAULT_BASE_URL = DEFAULT_BASE_URL;
940
+ exports.ForbiddenError = ForbiddenError;
941
+ exports.NetworkError = NetworkError;
942
+ exports.NextvisitApiError = NextvisitApiError;
943
+ exports.NextvisitClient = NextvisitClient;
944
+ exports.NextvisitError = NextvisitError;
945
+ exports.NotFoundError = NotFoundError;
946
+ exports.PatientsResource = PatientsResource;
947
+ exports.ProgressNotesResource = ProgressNotesResource;
948
+ exports.TranscriptionResource = TranscriptionResource;
949
+ exports.UnauthorizedError = UnauthorizedError;
950
+ exports.UsersResource = UsersResource;
951
+ exports.ValidationError = ValidationError;
952
+ //# sourceMappingURL=index.js.map
953
+ //# sourceMappingURL=index.js.map