@tagadapay/headless-sdk 1.18.0 → 1.20.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/CHANGELOG.md +164 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/modules/payment.d.ts +5 -0
- package/dist/core/modules/payment.d.ts.map +1 -1
- package/dist/core/modules/payment.js +53 -0
- package/dist/core/modules/payment.js.map +1 -1
- package/dist/core/modules/portal/types.d.ts +8 -1
- package/dist/core/modules/portal/types.d.ts.map +1 -1
- package/dist/core/modules/rx.d.ts +134 -4
- package/dist/core/modules/rx.d.ts.map +1 -1
- package/dist/core/modules/rx.js +87 -2
- package/dist/core/modules/rx.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/tagada-headless-commerce.min.js +1 -1
- package/dist/tagada-headless-react.min.js +2 -2
- package/dist/tagada-headless-react.min.js.map +3 -3
- package/dist/tagada-headless.js +133 -7
- package/dist/tagada-headless.min.js +2 -2
- package/dist/tagada-headless.min.js.map +3 -3
- package/dist/tagada-pixels.min.js +1 -1
- package/package.json +3 -2
|
@@ -16,14 +16,26 @@ import type { HttpClient } from '../http.js';
|
|
|
16
16
|
* (productId is public; case routes require the checkoutToken the
|
|
17
17
|
* storefront already received when it bootstrapped the checkout).
|
|
18
18
|
*
|
|
19
|
+
* Rules: the server enforces the clinical network's contract on every
|
|
20
|
+
* submit (US address and phone, required questions, offered options, MDI
|
|
21
|
+
* demographics). Use `validateIntake` before payment and `isQuestionActive`
|
|
22
|
+
* / `toIntakeAnswers` to render and send the questionnaire the same way.
|
|
23
|
+
*
|
|
19
24
|
* @example
|
|
20
25
|
* ```ts
|
|
21
26
|
* const { required } = await tagada.rx.isRequiredForProduct(productId);
|
|
22
27
|
* if (required) {
|
|
23
|
-
*
|
|
28
|
+
* // Before payment: US address, phone, ZIP, age.
|
|
29
|
+
* const pre = await tagada.rx.validateIntake({ productId, patient });
|
|
30
|
+
* if (!pre.valid) return showErrors(pre.issues);
|
|
31
|
+
* // After payment: render the network questionnaire.
|
|
32
|
+
* const { questions } = await tagada.rx.getQuestionsForProduct(productId, variantId);
|
|
33
|
+
* const ctx = { state: patient.address.state, sexAtBirth: patient.sexAtBirth };
|
|
34
|
+
* const shown = questions.filter((q) => isQuestionActive(q, answers, ctx));
|
|
35
|
+
* // …collect `answers` keyed by externalQuestionId…
|
|
24
36
|
* const res = await tagada.rx.submitCase({
|
|
25
37
|
* orderId, checkoutToken, productId,
|
|
26
|
-
* patient, intakeAnswers:
|
|
38
|
+
* patient, intakeAnswers: toIntakeAnswers(questions, answers, ctx),
|
|
27
39
|
* });
|
|
28
40
|
* router.push(`/thank-you?rxCase=${res.rxCaseId}`);
|
|
29
41
|
* }
|
|
@@ -83,6 +95,16 @@ export interface RxIntakeAnswer {
|
|
|
83
95
|
/** Options presented for MCQ questions. */
|
|
84
96
|
displayedOptions?: string[];
|
|
85
97
|
}
|
|
98
|
+
/** Display rule copied from the clinical network (see `isQuestionActive`). */
|
|
99
|
+
export interface RxClinicalQuestionRule {
|
|
100
|
+
op: 'and' | 'or';
|
|
101
|
+
requirements: Array<{
|
|
102
|
+
/** `question`: answer to another question; `state`: shipping state; `other` + `patient_sex`: sex at birth. */
|
|
103
|
+
basedOn: 'question' | 'state' | 'other';
|
|
104
|
+
questionId: string | null;
|
|
105
|
+
answer: string | null;
|
|
106
|
+
}>;
|
|
107
|
+
}
|
|
86
108
|
export interface RxClinicalQuestion {
|
|
87
109
|
externalQuestionId: string;
|
|
88
110
|
title: string;
|
|
@@ -94,7 +116,59 @@ export interface RxClinicalQuestion {
|
|
|
94
116
|
options: {
|
|
95
117
|
value: string;
|
|
96
118
|
label: string;
|
|
119
|
+
important?: boolean;
|
|
120
|
+
critical?: boolean;
|
|
97
121
|
}[];
|
|
122
|
+
/** `false` = clinician-side question: never show it, never ask it. */
|
|
123
|
+
visible?: boolean;
|
|
124
|
+
/** Show the question only when one rule matches (`isQuestionActive`). */
|
|
125
|
+
rules?: RxClinicalQuestionRule[];
|
|
126
|
+
important?: boolean;
|
|
127
|
+
critical?: boolean;
|
|
128
|
+
label?: string | null;
|
|
129
|
+
/** Value the network fills itself for hidden questions; send it as is. */
|
|
130
|
+
defaultValue?: string | null;
|
|
131
|
+
}
|
|
132
|
+
/** Answers keyed by `externalQuestionId`, as a storefront collects them. */
|
|
133
|
+
export type RxQuestionAnswers = Record<string, string | number | boolean | string[] | undefined>;
|
|
134
|
+
export interface RxIntakeContext {
|
|
135
|
+
/** Shipping state, 2-letter code. */
|
|
136
|
+
state?: string;
|
|
137
|
+
sexAtBirth?: 'male' | 'female' | 'unspecified';
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Whether the patient must see (and answer) a question. Same rules the
|
|
141
|
+
* server enforces on `submitCase`: hidden and file questions are never
|
|
142
|
+
* shown; a question with rules shows when one rule matches the answers so
|
|
143
|
+
* far, the shipping state or the patient's sex (e.g. "Drug Allergies" only
|
|
144
|
+
* after "Yes", pregnancy only for women).
|
|
145
|
+
*/
|
|
146
|
+
export declare function isQuestionActive(question: RxClinicalQuestion, answers: RxQuestionAnswers, context?: RxIntakeContext): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Turn the answers a storefront collected into the `intakeAnswers` to
|
|
149
|
+
* submit: active questions only, keyed by title (what the clinician
|
|
150
|
+
* reads), with the options that were shown, and the network's default for
|
|
151
|
+
* hidden questions. Plug and play with `submitCase` / `validateIntake`.
|
|
152
|
+
*/
|
|
153
|
+
export declare function toIntakeAnswers(questions: RxClinicalQuestion[], answers: RxQuestionAnswers, context?: RxIntakeContext): RxIntakeAnswer[];
|
|
154
|
+
export interface RxIntakeIssue {
|
|
155
|
+
field: string;
|
|
156
|
+
message: string;
|
|
157
|
+
}
|
|
158
|
+
export interface RxValidateIntakeInput {
|
|
159
|
+
productId: string;
|
|
160
|
+
variantId?: string;
|
|
161
|
+
patient: {
|
|
162
|
+
phone?: string | null;
|
|
163
|
+
dateOfBirth: string;
|
|
164
|
+
sexAtBirth: 'male' | 'female' | 'unspecified';
|
|
165
|
+
address: {
|
|
166
|
+
state: string;
|
|
167
|
+
zip: string;
|
|
168
|
+
country: string;
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
intakeAnswers?: RxIntakeAnswer[];
|
|
98
172
|
}
|
|
99
173
|
export interface RxQuestionsForProduct {
|
|
100
174
|
required: boolean;
|
|
@@ -116,6 +190,35 @@ export interface RxSubmitCaseResult {
|
|
|
116
190
|
accrualAmountMinor: number;
|
|
117
191
|
accrualCurrency: string;
|
|
118
192
|
}
|
|
193
|
+
/** Basics Tagada already holds on the order. Never date of birth or sex at birth. */
|
|
194
|
+
export interface RxIntakeContextPatient {
|
|
195
|
+
firstName: string | null;
|
|
196
|
+
lastName: string | null;
|
|
197
|
+
email: string | null;
|
|
198
|
+
phone: string | null;
|
|
199
|
+
address: {
|
|
200
|
+
line1: string | null;
|
|
201
|
+
line2: string | null;
|
|
202
|
+
city: string | null;
|
|
203
|
+
state: string | null;
|
|
204
|
+
zip: string | null;
|
|
205
|
+
country: string | null;
|
|
206
|
+
} | null;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* What a thank-you page needs to resume an unfinished intake, or
|
|
210
|
+
* `{ caseExists: true }` once a case is in (show its status instead).
|
|
211
|
+
*/
|
|
212
|
+
export type RxIntakeContextResult = {
|
|
213
|
+
caseExists: true;
|
|
214
|
+
} | {
|
|
215
|
+
caseExists: false;
|
|
216
|
+
orderId: string;
|
|
217
|
+
storeId: string;
|
|
218
|
+
productId: string;
|
|
219
|
+
variantId: string | null;
|
|
220
|
+
patient: RxIntakeContextPatient;
|
|
221
|
+
};
|
|
119
222
|
export interface RxCaseSummary {
|
|
120
223
|
id: string;
|
|
121
224
|
status: RxCaseStatus;
|
|
@@ -178,6 +281,20 @@ export declare class RxModule {
|
|
|
178
281
|
}): Promise<{
|
|
179
282
|
cases: RxCaseSummary[];
|
|
180
283
|
}>;
|
|
284
|
+
/**
|
|
285
|
+
* Resume an unfinished intake from `(orderId, checkoutToken)` alone: the
|
|
286
|
+
* patient paid (card on hold) but the identity collected at checkout is
|
|
287
|
+
* gone (tab closed, recovery email link, other device). Returns the Rx
|
|
288
|
+
* line (`productId`, `variantId`) and the basics on the order; ask date of
|
|
289
|
+
* birth and sex at birth again, render the questionnaire, then
|
|
290
|
+
* `submitCase`. `{ caseExists: true }` means a case is already in: show
|
|
291
|
+
* `getCasesForOrder`. Fails with 401 on a wrong token, 404 when the order
|
|
292
|
+
* has no Rx line.
|
|
293
|
+
*/
|
|
294
|
+
getIntakeContext(input: {
|
|
295
|
+
orderId: string;
|
|
296
|
+
checkoutToken: string;
|
|
297
|
+
}): Promise<RxIntakeContextResult>;
|
|
181
298
|
/**
|
|
182
299
|
* Submit a fresh clinical case for a freshly-paid order. PHI is
|
|
183
300
|
* forwarded to the clinical network and never persisted on
|
|
@@ -185,8 +302,21 @@ export declare class RxModule {
|
|
|
185
302
|
*/
|
|
186
303
|
submitCase(input: RxSubmitCaseInput): Promise<RxSubmitCaseResult>;
|
|
187
304
|
/**
|
|
188
|
-
*
|
|
189
|
-
*
|
|
305
|
+
* Check the patient (and, once filled, the intake) against the clinical
|
|
306
|
+
* network rules before paying / submitting: US address in the 50 states
|
|
307
|
+
* or DC, US phone, 5 digit ZIP, adult, every active required question
|
|
308
|
+
* answered with an offered option. `submitCase` enforces the same rules
|
|
309
|
+
* and fails with 422 otherwise. Nothing is created.
|
|
310
|
+
*/
|
|
311
|
+
validateIntake(input: RxValidateIntakeInput): Promise<{
|
|
312
|
+
valid: boolean;
|
|
313
|
+
issues: RxIntakeIssue[];
|
|
314
|
+
}>;
|
|
315
|
+
/**
|
|
316
|
+
* Fetch the network-authored intake questions for a product. Render
|
|
317
|
+
* every question for which `isQuestionActive` is true, build the payload
|
|
318
|
+
* with `toIntakeAnswers`. Empty `questions` means the product has no
|
|
319
|
+
* clinical questionnaire: never replace a network questionnaire with your own.
|
|
190
320
|
*/
|
|
191
321
|
getQuestionsForProduct(productId: string, variantId?: string): Promise<RxQuestionsForProduct>;
|
|
192
322
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rx.d.ts","sourceRoot":"","sources":["../../../src/core/modules/rx.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C
|
|
1
|
+
{"version":3,"file":"rx.d.ts","sourceRoot":"","sources":["../../../src/core/modules/rx.ts"],"names":[],"mappings":"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"}
|
package/dist/core/modules/rx.js
CHANGED
|
@@ -1,3 +1,63 @@
|
|
|
1
|
+
const sameText = (a, b) => b !== null && String(a).trim().toLowerCase() === b.trim().toLowerCase();
|
|
2
|
+
/**
|
|
3
|
+
* Whether the patient must see (and answer) a question. Same rules the
|
|
4
|
+
* server enforces on `submitCase`: hidden and file questions are never
|
|
5
|
+
* shown; a question with rules shows when one rule matches the answers so
|
|
6
|
+
* far, the shipping state or the patient's sex (e.g. "Drug Allergies" only
|
|
7
|
+
* after "Yes", pregnancy only for women).
|
|
8
|
+
*/
|
|
9
|
+
export function isQuestionActive(question, answers, context = {}) {
|
|
10
|
+
if (question.visible === false || question.type === 'file')
|
|
11
|
+
return false;
|
|
12
|
+
const rules = question.rules ?? [];
|
|
13
|
+
if (rules.length === 0)
|
|
14
|
+
return true;
|
|
15
|
+
return rules.some((rule) => {
|
|
16
|
+
const check = (req) => {
|
|
17
|
+
if (req.basedOn === 'state')
|
|
18
|
+
return sameText(context.state ?? '', req.answer);
|
|
19
|
+
if (req.basedOn === 'other' && req.questionId === 'patient_sex')
|
|
20
|
+
return sameText(context.sexAtBirth ?? '', req.answer);
|
|
21
|
+
if (req.basedOn === 'question' && req.questionId) {
|
|
22
|
+
const v = answers[req.questionId];
|
|
23
|
+
if (v === undefined)
|
|
24
|
+
return false;
|
|
25
|
+
return Array.isArray(v) ? v.some((x) => sameText(x, req.answer)) : sameText(v, req.answer);
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
};
|
|
29
|
+
return rule.op === 'and' ? rule.requirements.every(check) : rule.requirements.some(check);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Turn the answers a storefront collected into the `intakeAnswers` to
|
|
34
|
+
* submit: active questions only, keyed by title (what the clinician
|
|
35
|
+
* reads), with the options that were shown, and the network's default for
|
|
36
|
+
* hidden questions. Plug and play with `submitCase` / `validateIntake`.
|
|
37
|
+
*/
|
|
38
|
+
export function toIntakeAnswers(questions, answers, context = {}) {
|
|
39
|
+
const out = [];
|
|
40
|
+
for (const q of questions) {
|
|
41
|
+
if (q.visible === false) {
|
|
42
|
+
if (q.defaultValue)
|
|
43
|
+
out.push({ questionId: q.title, question: q.title, value: q.defaultValue, type: 'string' });
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (!isQuestionActive(q, answers, context))
|
|
47
|
+
continue;
|
|
48
|
+
const value = answers[q.externalQuestionId];
|
|
49
|
+
if (value === undefined || (typeof value === 'string' && value.trim() === ''))
|
|
50
|
+
continue;
|
|
51
|
+
out.push({
|
|
52
|
+
questionId: q.title,
|
|
53
|
+
question: q.title,
|
|
54
|
+
value,
|
|
55
|
+
type: q.type === 'number' ? 'number' : q.type === 'boolean' ? 'boolean' : 'string',
|
|
56
|
+
...(q.options.length > 0 ? { displayedOptions: q.options.map((o) => o.label) } : {}),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
1
61
|
export class RxModule {
|
|
2
62
|
constructor(http, storeId) {
|
|
3
63
|
this.http = http;
|
|
@@ -41,6 +101,19 @@ export class RxModule {
|
|
|
41
101
|
async getCasesForOrder(input) {
|
|
42
102
|
return this.http.post('/api/public/v1/rx/cases/lookup', input);
|
|
43
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Resume an unfinished intake from `(orderId, checkoutToken)` alone: the
|
|
106
|
+
* patient paid (card on hold) but the identity collected at checkout is
|
|
107
|
+
* gone (tab closed, recovery email link, other device). Returns the Rx
|
|
108
|
+
* line (`productId`, `variantId`) and the basics on the order; ask date of
|
|
109
|
+
* birth and sex at birth again, render the questionnaire, then
|
|
110
|
+
* `submitCase`. `{ caseExists: true }` means a case is already in: show
|
|
111
|
+
* `getCasesForOrder`. Fails with 401 on a wrong token, 404 when the order
|
|
112
|
+
* has no Rx line.
|
|
113
|
+
*/
|
|
114
|
+
async getIntakeContext(input) {
|
|
115
|
+
return this.http.post('/api/public/v1/rx/intake/context', input);
|
|
116
|
+
}
|
|
44
117
|
/**
|
|
45
118
|
* Submit a fresh clinical case for a freshly-paid order. PHI is
|
|
46
119
|
* forwarded to the clinical network and never persisted on
|
|
@@ -50,8 +123,20 @@ export class RxModule {
|
|
|
50
123
|
return this.http.post('/api/public/v1/rx/cases/submit', input);
|
|
51
124
|
}
|
|
52
125
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
126
|
+
* Check the patient (and, once filled, the intake) against the clinical
|
|
127
|
+
* network rules before paying / submitting: US address in the 50 states
|
|
128
|
+
* or DC, US phone, 5 digit ZIP, adult, every active required question
|
|
129
|
+
* answered with an offered option. `submitCase` enforces the same rules
|
|
130
|
+
* and fails with 422 otherwise. Nothing is created.
|
|
131
|
+
*/
|
|
132
|
+
async validateIntake(input) {
|
|
133
|
+
return this.http.post('/api/public/v1/rx/intake/validate', input);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Fetch the network-authored intake questions for a product. Render
|
|
137
|
+
* every question for which `isQuestionActive` is true, build the payload
|
|
138
|
+
* with `toIntakeAnswers`. Empty `questions` means the product has no
|
|
139
|
+
* clinical questionnaire: never replace a network questionnaire with your own.
|
|
55
140
|
*/
|
|
56
141
|
async getQuestionsForProduct(productId, variantId) {
|
|
57
142
|
return this.http.get('/api/public/v1/rx/questions-for-product', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rx.js","sourceRoot":"","sources":["../../../src/core/modules/rx.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rx.js","sourceRoot":"","sources":["../../../src/core/modules/rx.ts"],"names":[],"mappings":"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"}
|
package/dist/core/version.d.ts
CHANGED
package/dist/core/version.js
CHANGED