@rinse-dental/open-dental 0.0.6

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.
@@ -0,0 +1,34 @@
1
+ # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3
+
4
+ name: Node.js Package
5
+
6
+ on:
7
+ release:
8
+ types: [created]
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-node@v4
16
+ with:
17
+ node-version: 20
18
+ - run: npm ci
19
+ - run: npm test
20
+
21
+ publish-npm:
22
+ needs: build
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ - uses: actions/setup-node@v4
27
+ with:
28
+ node-version: 20
29
+ registry-url: https://registry.npmjs.org/
30
+ scope: '@rinse-dental'
31
+ - run: npm ci
32
+ - run: npm publish
33
+ env:
34
+ NODE_AUTH_TOKEN: ${{secrets.npm_token}}
package/README.md ADDED
@@ -0,0 +1 @@
1
+ #Hello World
@@ -0,0 +1,6 @@
1
+ describe('Example Test', () => {
2
+ it('should pass', () => {
3
+ expect(1 + 1).toBe(2);
4
+ });
5
+ });
6
+
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class Appointments {
4
+ httpClient;
5
+ constructor(httpClient) {
6
+ this.httpClient = httpClient;
7
+ }
8
+ /**
9
+ * Fetch a specific appointment by its ID.
10
+ * @param {number} AptNum - The ID of the appointment.
11
+ * @returns {Promise<Appointment>} - The appointment data.
12
+ * @throws {Error} - If `AptNum` is not provided.
13
+ */
14
+ async getAppointment(AptNum) {
15
+ if (!AptNum) {
16
+ throw new Error("AptNum is required.");
17
+ }
18
+ return this.httpClient.get(`/appointments/${AptNum}`);
19
+ }
20
+ async getAppointments(params) {
21
+ return this.httpClient.get("/appointments", params);
22
+ }
23
+ async createAppointment(data) {
24
+ if (!data) {
25
+ throw new Error("Appointment data is required.");
26
+ }
27
+ return this.httpClient.post("/appointments", data);
28
+ }
29
+ }
30
+ exports.default = Appointments;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Appointments = exports.Patients = void 0;
7
+ var patients_1 = require("./patients");
8
+ Object.defineProperty(exports, "Patients", { enumerable: true, get: function () { return __importDefault(patients_1).default; } });
9
+ var appointments_1 = require("./appointments");
10
+ Object.defineProperty(exports, "Appointments", { enumerable: true, get: function () { return __importDefault(appointments_1).default; } });
11
+ //export { default as ProcedureLogs } from "./procedureLogs";
12
+ // Add other APIs as needed
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class Patients {
4
+ httpClient;
5
+ constructor(httpClient) {
6
+ this.httpClient = httpClient;
7
+ }
8
+ async getPatient(params) {
9
+ if (!params.PatNum) {
10
+ throw new Error("PatNum is required.");
11
+ }
12
+ return this.httpClient.get(`/patients/${params.PatNum}`);
13
+ }
14
+ async getPatients() {
15
+ return this.httpClient.get("/patients");
16
+ }
17
+ }
18
+ exports.default = Patients;
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenDental = void 0;
4
+ var openDental_1 = require("./openDental");
5
+ Object.defineProperty(exports, "OpenDental", { enumerable: true, get: function () { return openDental_1.OpenDental; } });
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.OpenDental = void 0;
7
+ const httpClient_1 = __importDefault(require("./utils/httpClient"));
8
+ const patients_1 = __importDefault(require("./api/patients"));
9
+ const appointments_1 = __importDefault(require("./api/appointments"));
10
+ class OpenDental {
11
+ static httpClient;
12
+ /**
13
+ * Initialize the OpenDental library with the base URL and auth token.
14
+ */
15
+ static initialize(baseURL, authToken) {
16
+ if (!baseURL || !authToken) {
17
+ throw new Error("Both baseURL and authToken are required.");
18
+ }
19
+ //to manage future versions of the API
20
+ baseURL = baseURL + "/api/v1";
21
+ this.httpClient = new httpClient_1.default(baseURL, authToken);
22
+ }
23
+ /**
24
+ * Create a new instance of the Patients API.
25
+ */
26
+ static Patients() {
27
+ if (!this.httpClient) {
28
+ throw new Error("OpenDental not initialized. Call OpenDental.initialize() first.");
29
+ }
30
+ return new patients_1.default(this.httpClient);
31
+ }
32
+ /**
33
+ * Create a new instance of the Appointments API.
34
+ */
35
+ static Appointments() {
36
+ if (!this.httpClient) {
37
+ throw new Error("OpenDental not initialized. Call OpenDental.initialize() first.");
38
+ }
39
+ return new appointments_1.default(this.httpClient);
40
+ }
41
+ }
42
+ exports.OpenDental = OpenDental;
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const axios_1 = __importDefault(require("axios"));
7
+ class HttpClient {
8
+ client;
9
+ constructor(baseURL, authToken) {
10
+ this.client = axios_1.default.create({
11
+ baseURL,
12
+ headers: {
13
+ Authorization: authToken,
14
+ "Content-Type": "application/json",
15
+ },
16
+ });
17
+ }
18
+ /**
19
+ * GET request
20
+ * @param {string} url - The endpoint URL
21
+ * @param {object} params - Optional query parameters
22
+ * @returns {Promise<T>} - The API response
23
+ */
24
+ async get(url, params) {
25
+ try {
26
+ const response = await this.client.get(url, { params });
27
+ return response.data;
28
+ }
29
+ catch (error) {
30
+ this.handleError(error);
31
+ }
32
+ }
33
+ /**
34
+ * POST request
35
+ * @param {string} url - The endpoint URL
36
+ * @param {object} data - The payload to send
37
+ * @returns {Promise<T>} - The API response
38
+ */
39
+ async post(url, data) {
40
+ try {
41
+ const response = await this.client.post(url, data);
42
+ return response.data;
43
+ }
44
+ catch (error) {
45
+ this.handleError(error);
46
+ }
47
+ }
48
+ /**
49
+ * PUT request
50
+ * @param {string} url - The endpoint URL
51
+ * @param {object} data - The payload to update
52
+ * @returns {Promise<T>} - The API response
53
+ */
54
+ async put(url, data) {
55
+ try {
56
+ const response = await this.client.put(url, data);
57
+ return response.data;
58
+ }
59
+ catch (error) {
60
+ this.handleError(error);
61
+ }
62
+ }
63
+ /**
64
+ * DELETE request
65
+ * @param {string} url - The endpoint URL
66
+ * @returns {Promise<T>} - The API response
67
+ */
68
+ async delete(url) {
69
+ try {
70
+ const response = await this.client.delete(url);
71
+ return response.data;
72
+ }
73
+ catch (error) {
74
+ this.handleError(error);
75
+ }
76
+ }
77
+ /**
78
+ * Error handler to provide detailed error information
79
+ * @param {AxiosError} error - The error object from Axios
80
+ */
81
+ handleError(error) {
82
+ if (axios_1.default.isAxiosError(error)) {
83
+ // Handle Axios-specific error
84
+ if (error.response) {
85
+ // The request was made, and the server responded with a status code
86
+ console.error("API Response Error:", {
87
+ status: error.response.status,
88
+ data: error.response.data,
89
+ headers: error.response.headers,
90
+ });
91
+ throw new Error(`Request failed with status ${error.response.status}: ${JSON.stringify(error.response.data)}`);
92
+ }
93
+ else if (error.request) {
94
+ // The request was made, but no response was received
95
+ console.error("No Response Error:", error.request);
96
+ throw new Error("No response received from the server.");
97
+ }
98
+ else {
99
+ // Something happened in setting up the request
100
+ console.error("Request Setup Error:", error.message);
101
+ throw new Error(`Request setup failed: ${error.message}`);
102
+ }
103
+ }
104
+ else {
105
+ // Handle non-Axios errors
106
+ console.error("Unexpected Error:", error);
107
+ throw new Error("An unexpected error occurred.");
108
+ }
109
+ }
110
+ }
111
+ exports.default = HttpClient;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@rinse-dental/open-dental",
3
+ "version": "0.0.6",
4
+ "description": "A TypeScript library for easily accessing Open Dental APIs.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "author": "Rinse Dental Inc.",
8
+ "license": "MIT",
9
+ "publishConfig": {
10
+ "registry": "https://registry.npmjs.org/",
11
+ "access": "public"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/getrinsed/open-dental.git"
16
+ },
17
+ "dependencies": {
18
+ "axios": "^1.7.7",
19
+ "moment-timezone": "^0.5.46"
20
+ },
21
+ "devDependencies": {
22
+ "@types/jest": "^29.5.14",
23
+ "@types/node": "^22.9.3",
24
+ "jest": "^29.7.0",
25
+ "prettier": "^3.3.3",
26
+ "typescript": "^5.7.2"
27
+ },
28
+ "scripts": {
29
+ "build": "tsc",
30
+ "prepare": "npm run build",
31
+ "test": "jest"
32
+ }
33
+ }
@@ -0,0 +1,40 @@
1
+ import HttpClient from "../utils/httpClient";
2
+ import { Appointment } from "../utils/types";
3
+
4
+ export interface IAppointments {
5
+ getAppointment(AptNum: number): Promise<Appointment>;
6
+ getAppointments(params?: object): Promise<Appointment[]>;
7
+ createAppointment(data: Partial<Appointment>): Promise<Appointment>;
8
+ }
9
+
10
+ export default class Appointments implements IAppointments {
11
+ private httpClient: HttpClient;
12
+
13
+ constructor(httpClient: HttpClient) {
14
+ this.httpClient = httpClient;
15
+ }
16
+
17
+ /**
18
+ * Fetch a specific appointment by its ID.
19
+ * @param {number} AptNum - The ID of the appointment.
20
+ * @returns {Promise<Appointment>} - The appointment data.
21
+ * @throws {Error} - If `AptNum` is not provided.
22
+ */
23
+ public async getAppointment(AptNum: number): Promise<Appointment> {
24
+ if (!AptNum) {
25
+ throw new Error("AptNum is required.");
26
+ }
27
+ return this.httpClient.get<Appointment>(`/appointments/${AptNum}`);
28
+ }
29
+
30
+ public async getAppointments(params?: object): Promise<Appointment[]> {
31
+ return this.httpClient.get<Appointment[]>("/appointments", params);
32
+ }
33
+
34
+ public async createAppointment(data: Partial<Appointment>): Promise<Appointment> {
35
+ if (!data) {
36
+ throw new Error("Appointment data is required.");
37
+ }
38
+ return this.httpClient.post<Appointment>("/appointments", data);
39
+ }
40
+ }
@@ -0,0 +1,4 @@
1
+ export { default as Patients } from "./patients";
2
+ export { default as Appointments } from "./appointments";
3
+ //export { default as ProcedureLogs } from "./procedureLogs";
4
+ // Add other APIs as needed
@@ -0,0 +1,26 @@
1
+ import HttpClient from "../utils/httpClient";
2
+ import { Patient } from "../utils/types";
3
+
4
+ export interface IPatients {
5
+ getPatient(params: { PatNum: number }): Promise<Patient>;
6
+ getPatients(): Promise<Patient[]>;
7
+ }
8
+
9
+ export default class Patients implements IPatients {
10
+ private httpClient: HttpClient;
11
+
12
+ constructor(httpClient: HttpClient) {
13
+ this.httpClient = httpClient;
14
+ }
15
+
16
+ public async getPatient(params: { PatNum: number }): Promise<Patient> {
17
+ if (!params.PatNum) {
18
+ throw new Error("PatNum is required.");
19
+ }
20
+ return this.httpClient.get<Patient>(`/patients/${params.PatNum}`);
21
+ }
22
+
23
+ public async getPatients(): Promise<Patient[]> {
24
+ return this.httpClient.get<Patient[]>("/patients");
25
+ }
26
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { OpenDental } from "./openDental";
@@ -0,0 +1,43 @@
1
+ import HttpClient from "./utils/httpClient";
2
+ import Patients, { IPatients } from "./api/patients";
3
+ import Appointments, { IAppointments } from "./api/appointments";
4
+
5
+ class OpenDental {
6
+ private static httpClient: HttpClient;
7
+
8
+ /**
9
+ * Initialize the OpenDental library with the base URL and auth token.
10
+ */
11
+ public static initialize(baseURL: string, authToken: string): void {
12
+ if (!baseURL || !authToken) {
13
+ throw new Error("Both baseURL and authToken are required.");
14
+ }
15
+
16
+ //to manage future versions of the API
17
+ baseURL = baseURL + "/api/v1";
18
+
19
+ this.httpClient = new HttpClient(baseURL, authToken);
20
+ }
21
+
22
+ /**
23
+ * Create a new instance of the Patients API.
24
+ */
25
+ public static Patients(): IPatients {
26
+ if (!this.httpClient) {
27
+ throw new Error("OpenDental not initialized. Call OpenDental.initialize() first.");
28
+ }
29
+ return new Patients(this.httpClient);
30
+ }
31
+
32
+ /**
33
+ * Create a new instance of the Appointments API.
34
+ */
35
+ public static Appointments(): IAppointments {
36
+ if (!this.httpClient) {
37
+ throw new Error("OpenDental not initialized. Call OpenDental.initialize() first.");
38
+ }
39
+ return new Appointments(this.httpClient);
40
+ }
41
+ }
42
+
43
+ export { OpenDental };
File without changes
@@ -0,0 +1,109 @@
1
+ import axios, { AxiosInstance, AxiosResponse, AxiosError } from "axios";
2
+
3
+ class HttpClient {
4
+ private client: AxiosInstance;
5
+
6
+ constructor(baseURL: string, authToken: string) {
7
+ this.client = axios.create({
8
+ baseURL,
9
+ headers: {
10
+ Authorization: authToken,
11
+ "Content-Type": "application/json",
12
+ },
13
+ });
14
+ }
15
+
16
+ /**
17
+ * GET request
18
+ * @param {string} url - The endpoint URL
19
+ * @param {object} params - Optional query parameters
20
+ * @returns {Promise<T>} - The API response
21
+ */
22
+ public async get<T>(url: string, params?: object): Promise<T> {
23
+ try {
24
+ const response: AxiosResponse<T> = await this.client.get<T>(url, { params });
25
+ return response.data;
26
+ } catch (error) {
27
+ this.handleError(error);
28
+ }
29
+ }
30
+
31
+ /**
32
+ * POST request
33
+ * @param {string} url - The endpoint URL
34
+ * @param {object} data - The payload to send
35
+ * @returns {Promise<T>} - The API response
36
+ */
37
+ public async post<T>(url: string, data: object): Promise<T> {
38
+ try {
39
+ const response: AxiosResponse<T> = await this.client.post<T>(url, data);
40
+ return response.data;
41
+ } catch (error) {
42
+ this.handleError(error);
43
+ }
44
+ }
45
+
46
+ /**
47
+ * PUT request
48
+ * @param {string} url - The endpoint URL
49
+ * @param {object} data - The payload to update
50
+ * @returns {Promise<T>} - The API response
51
+ */
52
+ public async put<T>(url: string, data: object): Promise<T> {
53
+ try {
54
+ const response: AxiosResponse<T> = await this.client.put<T>(url, data);
55
+ return response.data;
56
+ } catch (error) {
57
+ this.handleError(error);
58
+ }
59
+ }
60
+
61
+ /**
62
+ * DELETE request
63
+ * @param {string} url - The endpoint URL
64
+ * @returns {Promise<T>} - The API response
65
+ */
66
+ public async delete<T>(url: string): Promise<T> {
67
+ try {
68
+ const response: AxiosResponse<T> = await this.client.delete<T>(url);
69
+ return response.data;
70
+ } catch (error) {
71
+ this.handleError(error);
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Error handler to provide detailed error information
77
+ * @param {AxiosError} error - The error object from Axios
78
+ */
79
+ private handleError(error: unknown): never {
80
+ if (axios.isAxiosError(error)) {
81
+ // Handle Axios-specific error
82
+ if (error.response) {
83
+ // The request was made, and the server responded with a status code
84
+ console.error("API Response Error:", {
85
+ status: error.response.status,
86
+ data: error.response.data,
87
+ headers: error.response.headers,
88
+ });
89
+ throw new Error(
90
+ `Request failed with status ${error.response.status}: ${JSON.stringify(error.response.data)}`
91
+ );
92
+ } else if (error.request) {
93
+ // The request was made, but no response was received
94
+ console.error("No Response Error:", error.request);
95
+ throw new Error("No response received from the server.");
96
+ } else {
97
+ // Something happened in setting up the request
98
+ console.error("Request Setup Error:", error.message);
99
+ throw new Error(`Request setup failed: ${error.message}`);
100
+ }
101
+ } else {
102
+ // Handle non-Axios errors
103
+ console.error("Unexpected Error:", error);
104
+ throw new Error("An unexpected error occurred.");
105
+ }
106
+ }
107
+ }
108
+
109
+ export default HttpClient;
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Represents a patient in the Open Dental system.
3
+ * @see https://www.opendental.com/site/apipatients.html
4
+ */
5
+ export interface Patient {
6
+ PatNum: number; // Unique patient identifier
7
+ LName: string; // Last name
8
+ FName: string; // First name
9
+ MiddleI?: string; // Middle initial
10
+ Preferred?: string; // Preferred name
11
+ PatStatus: 'Patient' | 'NonPatient' | 'Inactive' | 'Archived' | 'Deceased' | 'Prospective'; // Patient status
12
+ Gender: 'Male' | 'Female' | 'Unknown' | 'Other'; // Gender
13
+ Position: 'Single' | 'Married' | 'Child' | 'Widowed' | 'Divorced'; // Marital status
14
+ Birthdate: string; // Date of birth in 'yyyy-MM-dd' format
15
+ SSN?: string; // Social Security Number
16
+ Address?: string; // Primary address
17
+ Address2?: string; // Secondary address
18
+ City?: string; // City
19
+ State?: string; // State
20
+ Zip?: string; // ZIP code
21
+ HmPhone?: string; // Home phone number
22
+ WkPhone?: string; // Work phone number
23
+ WirelessPhone?: string; // Mobile phone number
24
+ Guarantor: number; // Guarantor's PatNum
25
+ Email?: string; // Email address
26
+ EstBalance: number; // Estimated balance
27
+ PriProv: number; // Primary provider number
28
+ priProvAbbr?: string; // Primary provider abbreviation
29
+ SecProv?: number; // Secondary provider number
30
+ secProvAbbr?: string; // Secondary provider abbreviation
31
+ BillingType?: string; // Billing type description
32
+ ImageFolder?: string; // Image folder name
33
+ FamFinUrgNote?: string; // Family financial urgent note
34
+ ChartNumber?: string; // Chart number
35
+ MedicaidID?: string; // Medicaid ID
36
+ BalTotal: number; // Total balance
37
+ DateFirstVisit?: string; // Date of first visit in 'yyyy-MM-dd' format
38
+ ClinicNum?: number; // Clinic number
39
+ clinicAbbr?: string; // Clinic abbreviation
40
+ Ward?: string; // Ward
41
+ PreferConfirmMethod?: 'None' | 'Email' | 'TextMessage' | 'PhoneCall'; // Preferred confirmation method
42
+ PreferContactMethod?: 'None' | 'Email' | 'TextMessage' | 'PhoneCall' | 'Mail'; // Preferred contact method
43
+ PreferRecallMethod?: 'None' | 'Email' | 'TextMessage' | 'PhoneCall' | 'Mail'; // Preferred recall method
44
+ Language?: string; // Language code (ISO 639-2 format)
45
+ AdmitDate?: string; // Admission date in 'yyyy-MM-dd' format
46
+ siteDesc?: string; // Site description
47
+ DateTStamp: string; // Timestamp of the last update in 'yyyy-MM-dd HH:mm:ss' format
48
+ SuperFamily?: number; // Super family number
49
+ TxtMsgOk?: 'Unknown' | 'Yes' | 'No'; // Text message consent
50
+ SecDateEntry?: string; // Secondary date entry in 'yyyy-MM-dd' format
51
+ }
52
+
53
+ /**
54
+ * Represents an appointment in the Open Dental system.
55
+ * @see https://www.opendental.com/site/apiappointments.html
56
+ */
57
+ export interface Appointment {
58
+ AptNum: number; // Unique appointment identifier
59
+ PatNum: number; // Patient's PatNum
60
+ AptStatus: 'Scheduled' | 'Complete' | 'UnschedList' | 'ASAP' | 'Broken' | 'Planned' | 'PtNote' | 'PtNoteCompleted'; // Appointment status
61
+ Pattern: string; // Time pattern
62
+ Confirmed: number; // Confirmation status code
63
+ confirmed?: string; // Confirmation status description
64
+ TimeLocked: boolean; // Indicates if the time is locked
65
+ Op: number; // Operatory number
66
+ Note?: string; // Appointment note
67
+ ProvNum: number; // Provider number
68
+ provAbbr?: string; // Provider abbreviation
69
+ ProvHyg?: number; // Hygienist provider number
70
+ AptDateTime: string; // Appointment date and time in 'yyyy-MM-dd HH:mm:ss' format
71
+ NextAptNum?: number; // Next appointment number
72
+ UnschedStatus?: number; // Unscheduled status code
73
+ unschedStatus?: string; // Unscheduled status description
74
+ IsNewPatient: boolean; // Indicates if the patient is new
75
+ ProcDescript?: string; // Procedure description
76
+ ClinicNum?: number; // Clinic number
77
+ IsHygiene: boolean; // Indicates if it's a hygiene appointment
78
+ DateTStamp: string; // Timestamp of the last update in 'yyyy-MM-dd HH:mm:ss' format
79
+ DateTimeArrived?: string; // Arrival time in 'yyyy-MM-dd HH:mm:ss' format
80
+ DateTimeSeated?: string; // Seated time in 'yyyy-MM-dd HH:mm:ss' format
81
+ DateTimeDismissed?: string; // Dismissed time in 'yyyy-MM-dd HH:mm:ss' format
82
+ InsPlan1?: number; // Primary insurance plan number
83
+ InsPlan2?: number; // Secondary insurance plan number
84
+ DateTimeAskedToArrive?: string; // Requested arrival time in 'yyyy-MM-dd HH:mm:ss' format
85
+ colorOverride?: string; // Color override in 'R,G,B' format
86
+ AppointmentTypeNum?: number; // Appointment type number
87
+ SecDateTEntry?: string; // Secondary date entry in 'yyyy-MM-dd' format
88
+ Priority?: 'Normal' | 'ASAP'; // Appointment priority
89
+ PatternSecondary?: string; // Secondary time pattern
90
+ ItemOrderPlanned?: number; // Planned item order
91
+ }
92
+
93
+ /**
94
+ * Represents a procedure log entry in the Open Dental system.
95
+ * @see https://www.opendental.com/site/apiprocedurelogs.html
96
+ */
97
+ export interface ProcedureLog {
98
+ ProcNum: number; // Unique procedure identifier
99
+ PatNum: number; // Patient's PatNum
100
+ AptNum?: number; // Associated appointment number
101
+ ProcDate: string; // Procedure date in 'yyyy-MM-dd' format
102
+ ProcFee: number; // Procedure fee
103
+ Surf?: string; // Tooth surface
104
+ ToothNum?: string; // Tooth number
105
+ ToothRange?: string; // Tooth range
106
+ Priority?: number; // Priority code
107
+ priority?: string; // Priority description
108
+ ProcStatus: 'TP' | 'C' | 'EO' | 'R' | 'D' | 'E'; // Procedure status: Treatment Planned (TP), Complete (C), Existing Other Provider (EO), Referred (R), Deleted (D), or Existing Current Provider (E)
109
+ ProvNum: number; // Provider number
110
+ provAbbr?: string; // Provider abbreviation
111
+ Dx?: string; // Diagnosis code
112
+ dxName?: string; // Diagnosis name
113
+ PlannedAptNum?: number; // Planned appointment number
114
+ DateEntryC?: string; // Date the procedure was created in 'yyyy-MM-dd HH:mm:ss' format
115
+ ClinicNum?: number; // Clinic number
116
+ MedicalCode?: string; // Medical procedure code
117
+ DiagnosticCode?: string; // Diagnostic code
118
+ CodeNum: number; // Procedure code number
119
+ codeText?: string; // Procedure code description
120
+ ProcNote?: string; // Procedure note
121
+ ToothColor?: string; // Tooth color (if applicable)
122
+ LabFee?: number; // Lab fee
123
+ IsProsth?: boolean; // Indicates if it's a prosthodontic procedure
124
+ ProcTime?: string; // Time taken for the procedure
125
+ PriorityNum?: number; // Priority number
126
+ Prosthesis?: 'None' | 'Crown' | 'Denture' | 'Bridge'; // Type of prosthesis
127
+ ProsthesisDate?: string; // Prosthesis delivery date in 'yyyy-MM-dd' format
128
+ UnitQty?: number; // Quantity of units
129
+ DateTStamp: string; // Timestamp of the last update in 'yyyy-MM-dd HH:mm:ss' format
130
+ SecDateTEntry?: string; // Secondary date entry in 'yyyy-MM-dd HH:mm:ss' format
131
+ MedicalOrderNum?: number; // Medical order number
132
+ PlaceService?: 'Office' | 'InpatientHospital' | 'OutpatientHospital'; // Place of service
133
+ }
134
+
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "CommonJS",
5
+ "outDir": "./dist",
6
+ "rootDir": "./src",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true
10
+ },
11
+ "include": ["src/**/*"],
12
+ "exclude": ["node_modules", "dist"]
13
+ }