@wise/dynamic-flow-client 5.6.0 → 5.6.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/build/main.js +745 -736
- package/build/main.mjs +745 -736
- package/build/types/controller/executeRequest.d.ts +1 -1
- package/build/types/controller/executeSubmission.d.ts +1 -1
- package/build/types/domain/components/RootDomainComponent.d.ts +1 -1
- package/build/types/domain/components/SubflowDomainComponent.d.ts +1 -1
- package/build/types/domain/components/step/StepDomainComponent.d.ts +4 -2
- package/build/types/domain/features/prefetch/getStepPrefetch.d.ts +12 -0
- package/build/types/domain/{prefetching → features/prefetch}/request-cache.d.ts +1 -1
- package/build/types/domain/mappers/mapStepToComponent.d.ts +1 -1
- package/build/types/index.d.ts +1 -1
- package/build/types/types.d.ts +1 -1
- package/package.json +1 -1
package/build/main.js
CHANGED
|
@@ -2317,6 +2317,35 @@ var modalToComponent = (uid, { content, title }, mapperProps, schemaComponents)
|
|
|
2317
2317
|
mapperProps.onComponentUpdate
|
|
2318
2318
|
);
|
|
2319
2319
|
|
|
2320
|
+
// src/domain/components/step/ExternalConfirmationComponent.ts
|
|
2321
|
+
var createExternalConfirmation = (uid, url, onComponentUpdate) => {
|
|
2322
|
+
const update = getInputUpdateFunction(onComponentUpdate);
|
|
2323
|
+
return {
|
|
2324
|
+
type: "external-confirmation",
|
|
2325
|
+
kind: "layout",
|
|
2326
|
+
uid,
|
|
2327
|
+
url,
|
|
2328
|
+
status: "initial",
|
|
2329
|
+
onSuccess() {
|
|
2330
|
+
update(this, (draft) => {
|
|
2331
|
+
draft.status = "success";
|
|
2332
|
+
});
|
|
2333
|
+
},
|
|
2334
|
+
onFailure() {
|
|
2335
|
+
if (this.status === "initial") {
|
|
2336
|
+
update(this, (draft) => {
|
|
2337
|
+
draft.status = "failure";
|
|
2338
|
+
});
|
|
2339
|
+
}
|
|
2340
|
+
},
|
|
2341
|
+
onCancel() {
|
|
2342
|
+
update(this, (draft) => {
|
|
2343
|
+
draft.status = "dismissed";
|
|
2344
|
+
});
|
|
2345
|
+
}
|
|
2346
|
+
};
|
|
2347
|
+
};
|
|
2348
|
+
|
|
2320
2349
|
// src/utils/recursiveMerge.ts
|
|
2321
2350
|
function recursiveMerge(valueA, valueB) {
|
|
2322
2351
|
if (valueA === null) {
|
|
@@ -2356,526 +2385,162 @@ function mergeArrays(valueA, valueB) {
|
|
|
2356
2385
|
);
|
|
2357
2386
|
}
|
|
2358
2387
|
|
|
2359
|
-
// src/
|
|
2360
|
-
var
|
|
2361
|
-
|
|
2362
|
-
|
|
2388
|
+
// src/utils/component-utils.ts
|
|
2389
|
+
var getSubmittableData = async (components) => Promise.all(components.map(async (component) => component.getSubmittableValue())).then(
|
|
2390
|
+
(values) => values.reduce((acc, value) => recursiveMerge(acc, value), null)
|
|
2391
|
+
);
|
|
2392
|
+
var getSubmittableDataSync = (components) => components.map((component) => component.getSubmittableValueSync()).reduce((acc, value) => recursiveMerge(acc, value), null);
|
|
2393
|
+
var getLocalValues = (components) => components.map((component) => component.getLocalValue()).reduce((acc, value) => recursiveMerge(acc, value), null);
|
|
2363
2394
|
|
|
2364
|
-
// src/
|
|
2365
|
-
var
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
}
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2395
|
+
// src/domain/components/step/StepDomainComponent.ts
|
|
2396
|
+
var createStepComponent = (stepProps) => {
|
|
2397
|
+
const _a = stepProps, { uid, stepPolling, stepRefreshAfter, stepPrefetch, onComponentUpdate } = _a, rest = __objRest(_a, ["uid", "stepPolling", "stepRefreshAfter", "stepPrefetch", "onComponentUpdate"]);
|
|
2398
|
+
const update = getInputUpdateFunction(onComponentUpdate);
|
|
2399
|
+
const component = __spreadProps(__spreadValues({
|
|
2400
|
+
uid
|
|
2401
|
+
}, rest), {
|
|
2402
|
+
type: "step",
|
|
2403
|
+
kind: "step",
|
|
2404
|
+
modals: [],
|
|
2405
|
+
requestCache: stepPrefetch.requestCache,
|
|
2406
|
+
dismissModal() {
|
|
2407
|
+
var _a2;
|
|
2408
|
+
(_a2 = this.modals.at(-1)) == null ? void 0 : _a2.close();
|
|
2409
|
+
},
|
|
2410
|
+
dismissAllModals() {
|
|
2411
|
+
this._update((draft) => {
|
|
2412
|
+
draft.modals = draft.modals.map((m) => __spreadProps(__spreadValues({}, m), { open: false }));
|
|
2413
|
+
});
|
|
2414
|
+
},
|
|
2415
|
+
showModal(modal) {
|
|
2416
|
+
this._update((draft) => {
|
|
2417
|
+
draft.modals = [...draft.modals, modal];
|
|
2418
|
+
});
|
|
2419
|
+
},
|
|
2420
|
+
_update(updateFn) {
|
|
2421
|
+
update(this, updateFn);
|
|
2422
|
+
},
|
|
2423
|
+
getChildren() {
|
|
2424
|
+
return this.externalConfirmation ? [...this.layoutComponents, this.externalConfirmation] : this.layoutComponents;
|
|
2425
|
+
},
|
|
2426
|
+
getModals() {
|
|
2427
|
+
return this.modals;
|
|
2428
|
+
},
|
|
2429
|
+
async getSubmittableValue() {
|
|
2430
|
+
return getSubmittableData(this.schemaComponents);
|
|
2431
|
+
},
|
|
2432
|
+
getSubmittableValueSync() {
|
|
2433
|
+
return getSubmittableDataSync(this.schemaComponents);
|
|
2434
|
+
},
|
|
2435
|
+
getLocalValue() {
|
|
2436
|
+
return getLocalValues(this.schemaComponents);
|
|
2437
|
+
},
|
|
2438
|
+
validate() {
|
|
2439
|
+
return this.schemaComponents.every(
|
|
2440
|
+
(inputComponent) => inputComponent.isSchemaReferencedInStep ? inputComponent.validate() : true
|
|
2441
|
+
);
|
|
2442
|
+
},
|
|
2443
|
+
setLoadingState(loadingState) {
|
|
2444
|
+
this._update((draft) => {
|
|
2445
|
+
draft.loadingState = loadingState;
|
|
2446
|
+
});
|
|
2447
|
+
},
|
|
2448
|
+
start() {
|
|
2449
|
+
stepPolling == null ? void 0 : stepPolling.start();
|
|
2450
|
+
stepRefreshAfter == null ? void 0 : stepRefreshAfter.start();
|
|
2451
|
+
stepPrefetch.start(this.getSubmittableValueSync());
|
|
2452
|
+
},
|
|
2453
|
+
stop() {
|
|
2454
|
+
stepPolling == null ? void 0 : stepPolling.stop();
|
|
2455
|
+
stepRefreshAfter == null ? void 0 : stepRefreshAfter.stop();
|
|
2456
|
+
stepPrefetch.stop();
|
|
2457
|
+
this._update((draft) => {
|
|
2458
|
+
draft.modals = [];
|
|
2459
|
+
});
|
|
2460
|
+
}
|
|
2461
|
+
});
|
|
2462
|
+
return component;
|
|
2380
2463
|
};
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2464
|
+
|
|
2465
|
+
// src/domain/features/polling/getStepPolling.ts
|
|
2466
|
+
var getStepPolling = ({
|
|
2467
|
+
pollingConfig,
|
|
2468
|
+
logEvent,
|
|
2469
|
+
onBehavior,
|
|
2470
|
+
onPoll,
|
|
2471
|
+
registerSubmissionBehavior
|
|
2472
|
+
}) => {
|
|
2473
|
+
const { interval, delay = interval, maxAttempts, url, onError } = pollingConfig;
|
|
2474
|
+
let abortController = new AbortController();
|
|
2475
|
+
let intervalRef = null;
|
|
2476
|
+
if (delay == null) {
|
|
2477
|
+
throw new Error("Polling configuration must include delay or interval");
|
|
2389
2478
|
}
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2479
|
+
const onErrorBehavior = getDomainLayerBehavior(onError, [], registerSubmissionBehavior);
|
|
2480
|
+
let attempts = 0;
|
|
2481
|
+
const poll = () => {
|
|
2482
|
+
attempts += 1;
|
|
2483
|
+
abortController.abort();
|
|
2484
|
+
abortController = new AbortController();
|
|
2485
|
+
const { signal } = abortController;
|
|
2486
|
+
onPoll(url, onErrorBehavior, signal).then((result) => {
|
|
2487
|
+
if (result) {
|
|
2488
|
+
stop();
|
|
2489
|
+
return;
|
|
2490
|
+
}
|
|
2491
|
+
if (attempts >= maxAttempts && !signal.aborted) {
|
|
2492
|
+
void onBehavior(onErrorBehavior);
|
|
2493
|
+
stop();
|
|
2494
|
+
}
|
|
2495
|
+
}).catch(() => {
|
|
2496
|
+
});
|
|
2497
|
+
};
|
|
2498
|
+
const start = () => {
|
|
2499
|
+
attempts = 0;
|
|
2500
|
+
intervalRef = setInterval(poll, delay * 1e3);
|
|
2501
|
+
poll();
|
|
2502
|
+
};
|
|
2503
|
+
const stop = () => {
|
|
2504
|
+
if (!intervalRef) {
|
|
2505
|
+
logEvent("warning", "Attempted to stop polling but it was not started");
|
|
2394
2506
|
return;
|
|
2395
2507
|
}
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
}
|
|
2401
|
-
function assertSubflowResponseBody(body) {
|
|
2402
|
-
const { valid } = (0, import_spec.validateSubflowResponse)(body);
|
|
2403
|
-
if (valid) {
|
|
2404
|
-
return;
|
|
2405
|
-
}
|
|
2406
|
-
throw new Error("Incorrect response body in subflow response.");
|
|
2407
|
-
}
|
|
2408
|
-
function isErrorResponseBody(body) {
|
|
2409
|
-
return Boolean(
|
|
2410
|
-
isObject(body) && (body.refreshFormUrl || body.refreshUrl || body.validation || body.error || body.analytics)
|
|
2411
|
-
);
|
|
2412
|
-
}
|
|
2413
|
-
function assertStepResponseBody(body) {
|
|
2414
|
-
if (!isObject(body)) {
|
|
2415
|
-
throw new Error("Incorrect response body in step response. Expected an object.");
|
|
2416
|
-
}
|
|
2417
|
-
}
|
|
2418
|
-
var assertResponseIsValid = (response) => {
|
|
2419
|
-
if (!isResponse(response)) {
|
|
2420
|
-
throw new Error("Incorrect type of response from fetch. Expected object of type Response.");
|
|
2421
|
-
}
|
|
2422
|
-
if (response.bodyUsed) {
|
|
2423
|
-
throw new Error(
|
|
2424
|
-
"The body of the provided Response object has already been used. Every request must respond with a new Response object."
|
|
2425
|
-
);
|
|
2426
|
-
}
|
|
2508
|
+
clearTimeout(intervalRef);
|
|
2509
|
+
abortController.abort();
|
|
2510
|
+
};
|
|
2511
|
+
return { start, stop };
|
|
2427
2512
|
};
|
|
2428
|
-
var isResponse = (response) => typeof response === "object" && response !== null && "clone" in response && "bodyUsed" in response;
|
|
2429
2513
|
|
|
2430
|
-
// src/
|
|
2431
|
-
var
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
httpError: { statusCode: response.status }
|
|
2442
|
-
};
|
|
2514
|
+
// src/domain/features/refreshAfter/getStepRefreshAfter.ts
|
|
2515
|
+
var ONE_SECOND = 1e3;
|
|
2516
|
+
var getStepRefreshAfter = ({
|
|
2517
|
+
refreshAfter,
|
|
2518
|
+
logEvent,
|
|
2519
|
+
onBehavior
|
|
2520
|
+
}) => {
|
|
2521
|
+
let timeout = null;
|
|
2522
|
+
const targetTime = new Date(refreshAfter).getTime();
|
|
2523
|
+
if (typeof refreshAfter !== "string" || Number.isNaN(targetTime)) {
|
|
2524
|
+
throw new Error(`Invalid refreshAfter value: ${String(refreshAfter)}`);
|
|
2443
2525
|
}
|
|
2444
|
-
|
|
2445
|
-
|
|
2526
|
+
const start = () => {
|
|
2527
|
+
const timeLeft = Math.max(targetTime - Date.now(), ONE_SECOND);
|
|
2528
|
+
timeout = setTimeout(() => {
|
|
2529
|
+
void onBehavior({ type: "refresh", analytics: { schema: "refreshAfter" } });
|
|
2530
|
+
}, timeLeft);
|
|
2531
|
+
};
|
|
2446
2532
|
return {
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2533
|
+
start,
|
|
2534
|
+
stop: () => {
|
|
2535
|
+
if (!timeout) {
|
|
2536
|
+
logEvent("warning", "Attempted to stop refreshAfter but it was not started");
|
|
2537
|
+
return;
|
|
2538
|
+
}
|
|
2539
|
+
clearTimeout(timeout);
|
|
2451
2540
|
}
|
|
2452
2541
|
};
|
|
2453
2542
|
};
|
|
2454
2543
|
|
|
2455
|
-
// src/controller/getResponseType.ts
|
|
2456
|
-
var responseTypes = ["step", "action", "exit", "modal", "subflow"];
|
|
2457
|
-
var getResponseType = (headers, body) => {
|
|
2458
|
-
const headerResponseType = getResponseTypeFromHeader(headers);
|
|
2459
|
-
if (headerResponseType) {
|
|
2460
|
-
return headerResponseType;
|
|
2461
|
-
}
|
|
2462
|
-
if (isObject(body) && body.action) {
|
|
2463
|
-
return "action";
|
|
2464
|
-
}
|
|
2465
|
-
return "step";
|
|
2466
|
-
};
|
|
2467
|
-
var getResponseTypeFromHeader = (headers) => {
|
|
2468
|
-
if (headers == null ? void 0 : headers.has("X-Df-Response-Type")) {
|
|
2469
|
-
const type = headers.get("X-Df-Response-Type");
|
|
2470
|
-
assertDFResponseType(type);
|
|
2471
|
-
return type;
|
|
2472
|
-
}
|
|
2473
|
-
if (headers == null ? void 0 : headers.has("X-Df-Exit")) {
|
|
2474
|
-
return "exit";
|
|
2475
|
-
}
|
|
2476
|
-
return void 0;
|
|
2477
|
-
};
|
|
2478
|
-
function assertDFResponseType(type) {
|
|
2479
|
-
if (!responseTypes.includes(type)) {
|
|
2480
|
-
throw new Error(
|
|
2481
|
-
"Unsupported X-Df-Response-Type. Allowed values are 'step', 'action', 'exit', 'error', 'modal', 'subflow'."
|
|
2482
|
-
);
|
|
2483
|
-
}
|
|
2484
|
-
}
|
|
2485
|
-
|
|
2486
|
-
// src/controller/makeSafeHttpClient.ts
|
|
2487
|
-
var makeSafeHttpClient = (httpClient) => async (...props) => {
|
|
2488
|
-
try {
|
|
2489
|
-
return await httpClient(...props);
|
|
2490
|
-
} catch (e) {
|
|
2491
|
-
return null;
|
|
2492
|
-
}
|
|
2493
|
-
};
|
|
2494
|
-
|
|
2495
|
-
// src/controller/executeRequest.ts
|
|
2496
|
-
var executeRequest = async (props) => {
|
|
2497
|
-
const { exit, request, requestCache, httpClient, trackEvent, logEvent } = props;
|
|
2498
|
-
const { url, method, body } = request;
|
|
2499
|
-
const response = await getCachedOrFetch(
|
|
2500
|
-
[
|
|
2501
|
-
url,
|
|
2502
|
-
{
|
|
2503
|
-
method,
|
|
2504
|
-
body: body ? JSON.stringify(body) : void 0,
|
|
2505
|
-
headers: { "Content-Type": "application/json" }
|
|
2506
|
-
}
|
|
2507
|
-
],
|
|
2508
|
-
requestCache,
|
|
2509
|
-
httpClient
|
|
2510
|
-
);
|
|
2511
|
-
if (!response) {
|
|
2512
|
-
const extra = { errorMessage: "Network Error" };
|
|
2513
|
-
trackEvent("Request Failed", extra);
|
|
2514
|
-
logEvent("error", "Dynamic Flow - Request Failed Unexpectedly", extra);
|
|
2515
|
-
return { type: "error" };
|
|
2516
|
-
}
|
|
2517
|
-
if (!response.ok) {
|
|
2518
|
-
return handleErrorResponse(response, void 0, trackEvent);
|
|
2519
|
-
}
|
|
2520
|
-
const responseBody = await parseResponseBodyAsJsonElement(response);
|
|
2521
|
-
const responseType = getResponseType(response.headers, responseBody);
|
|
2522
|
-
if (exit) {
|
|
2523
|
-
return { type: "complete", result: responseBody };
|
|
2524
|
-
}
|
|
2525
|
-
switch (responseType) {
|
|
2526
|
-
case "step": {
|
|
2527
|
-
const etag = response.headers.get("etag") || null;
|
|
2528
|
-
assertStepResponseBody(responseBody);
|
|
2529
|
-
return { type: "replace-step", step: responseBody, etag };
|
|
2530
|
-
}
|
|
2531
|
-
case "exit": {
|
|
2532
|
-
return { type: "complete", result: responseBody };
|
|
2533
|
-
}
|
|
2534
|
-
case "action": {
|
|
2535
|
-
assertActionResponseBody(responseBody);
|
|
2536
|
-
return {
|
|
2537
|
-
type: "behavior",
|
|
2538
|
-
behavior: {
|
|
2539
|
-
type: "action",
|
|
2540
|
-
action: responseBody.action
|
|
2541
|
-
}
|
|
2542
|
-
};
|
|
2543
|
-
}
|
|
2544
|
-
case "subflow": {
|
|
2545
|
-
assertSubflowResponseBody(responseBody);
|
|
2546
|
-
return {
|
|
2547
|
-
type: "behavior",
|
|
2548
|
-
behavior: __spreadProps(__spreadValues({}, responseBody), {
|
|
2549
|
-
type: "subflow",
|
|
2550
|
-
onCompletion: responseBody.onCompletion ? normaliseBehavior(responseBody.onCompletion, []) : void 0,
|
|
2551
|
-
onError: responseBody.onError ? normaliseBehavior(responseBody.onError, []) : void 0
|
|
2552
|
-
})
|
|
2553
|
-
};
|
|
2554
|
-
}
|
|
2555
|
-
case "modal": {
|
|
2556
|
-
assertModalResponseBody(responseBody);
|
|
2557
|
-
return { type: "behavior", behavior: __spreadProps(__spreadValues({}, responseBody), { type: "modal" }) };
|
|
2558
|
-
}
|
|
2559
|
-
default: {
|
|
2560
|
-
throw new Error(`Unsupported response type: ${String(responseType)}`);
|
|
2561
|
-
}
|
|
2562
|
-
}
|
|
2563
|
-
};
|
|
2564
|
-
var getCachedOrFetch = async (requestParams, requestCache, httpClient) => {
|
|
2565
|
-
const cachedPromise = requestCache.get(requestParams);
|
|
2566
|
-
if (cachedPromise) {
|
|
2567
|
-
const cachedResponse = await cachedPromise;
|
|
2568
|
-
if (cachedResponse == null ? void 0 : cachedResponse.ok) {
|
|
2569
|
-
return cachedResponse;
|
|
2570
|
-
}
|
|
2571
|
-
}
|
|
2572
|
-
return makeSafeHttpClient(httpClient)(...requestParams);
|
|
2573
|
-
};
|
|
2574
|
-
|
|
2575
|
-
// src/controller/executeSubmission.ts
|
|
2576
|
-
var executeSubmission = async (props) => {
|
|
2577
|
-
const { httpClient, requestCache, trackEvent, logEvent } = props;
|
|
2578
|
-
const triggerAction = async (action, model, isInitial) => {
|
|
2579
|
-
var _a, _b;
|
|
2580
|
-
const { exit, url, result = null, id: actionId } = action;
|
|
2581
|
-
const trackSubmissionEvent = !isInitial ? trackEvent : () => {
|
|
2582
|
-
};
|
|
2583
|
-
trackSubmissionEvent("Action Triggered", { actionId });
|
|
2584
|
-
if (exit && !url) {
|
|
2585
|
-
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
2586
|
-
return { type: "complete", result };
|
|
2587
|
-
}
|
|
2588
|
-
try {
|
|
2589
|
-
const command = await executeRequest({
|
|
2590
|
-
exit,
|
|
2591
|
-
request: createRequestFromAction(action, model),
|
|
2592
|
-
requestCache,
|
|
2593
|
-
httpClient,
|
|
2594
|
-
trackEvent: (name, properties) => {
|
|
2595
|
-
trackSubmissionEvent(name, __spreadProps(__spreadValues({}, properties), { actionId }));
|
|
2596
|
-
},
|
|
2597
|
-
logEvent
|
|
2598
|
-
});
|
|
2599
|
-
switch (command.type) {
|
|
2600
|
-
case "error": {
|
|
2601
|
-
trackSubmissionEvent("Action Failed", __spreadValues({
|
|
2602
|
-
actionId,
|
|
2603
|
-
statusCode: (_a = command.httpError) == null ? void 0 : _a.statusCode
|
|
2604
|
-
}, (_b = command.body) == null ? void 0 : _b.analytics));
|
|
2605
|
-
return command;
|
|
2606
|
-
}
|
|
2607
|
-
case "behavior": {
|
|
2608
|
-
if (command.behavior.type === "action") {
|
|
2609
|
-
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
2610
|
-
return await executeRequest({
|
|
2611
|
-
request: createRequestFromAction(command.behavior.action, null),
|
|
2612
|
-
requestCache,
|
|
2613
|
-
httpClient,
|
|
2614
|
-
trackEvent,
|
|
2615
|
-
logEvent
|
|
2616
|
-
});
|
|
2617
|
-
}
|
|
2618
|
-
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
2619
|
-
return command;
|
|
2620
|
-
}
|
|
2621
|
-
case "complete": {
|
|
2622
|
-
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
2623
|
-
return __spreadProps(__spreadValues({}, command), { result: recursiveMerge(command.result, result) });
|
|
2624
|
-
}
|
|
2625
|
-
default: {
|
|
2626
|
-
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
2627
|
-
return command;
|
|
2628
|
-
}
|
|
2629
|
-
}
|
|
2630
|
-
} catch (error) {
|
|
2631
|
-
const errorMessage = getErrorMessage(error);
|
|
2632
|
-
trackSubmissionEvent("Action Failed", { actionId, errorMessage });
|
|
2633
|
-
logEvent("error", "Dynamic Flow - Action Failed Unexpectedly", { actionId, errorMessage });
|
|
2634
|
-
throw error;
|
|
2635
|
-
}
|
|
2636
|
-
};
|
|
2637
|
-
return triggerAction(props.action, props.model, props.isInitial);
|
|
2638
|
-
};
|
|
2639
|
-
var createRequestFromAction = (action, model) => {
|
|
2640
|
-
var _a, _b, _c;
|
|
2641
|
-
return __spreadProps(__spreadValues({}, action), {
|
|
2642
|
-
url: (_a = action.url) != null ? _a : "",
|
|
2643
|
-
method: (_b = action.method) != null ? _b : "POST",
|
|
2644
|
-
body: action.method === "GET" ? void 0 : recursiveMerge(model, (_c = action.data) != null ? _c : null)
|
|
2645
|
-
});
|
|
2646
|
-
};
|
|
2647
|
-
|
|
2648
|
-
// src/domain/components/step/ExternalConfirmationComponent.ts
|
|
2649
|
-
var createExternalConfirmation = (uid, url, onComponentUpdate) => {
|
|
2650
|
-
const update = getInputUpdateFunction(onComponentUpdate);
|
|
2651
|
-
return {
|
|
2652
|
-
type: "external-confirmation",
|
|
2653
|
-
kind: "layout",
|
|
2654
|
-
uid,
|
|
2655
|
-
url,
|
|
2656
|
-
status: "initial",
|
|
2657
|
-
onSuccess() {
|
|
2658
|
-
update(this, (draft) => {
|
|
2659
|
-
draft.status = "success";
|
|
2660
|
-
});
|
|
2661
|
-
},
|
|
2662
|
-
onFailure() {
|
|
2663
|
-
if (this.status === "initial") {
|
|
2664
|
-
update(this, (draft) => {
|
|
2665
|
-
draft.status = "failure";
|
|
2666
|
-
});
|
|
2667
|
-
}
|
|
2668
|
-
},
|
|
2669
|
-
onCancel() {
|
|
2670
|
-
update(this, (draft) => {
|
|
2671
|
-
draft.status = "dismissed";
|
|
2672
|
-
});
|
|
2673
|
-
}
|
|
2674
|
-
};
|
|
2675
|
-
};
|
|
2676
|
-
|
|
2677
|
-
// src/utils/component-utils.ts
|
|
2678
|
-
var getSubmittableData = async (components) => Promise.all(components.map(async (component) => component.getSubmittableValue())).then(
|
|
2679
|
-
(values) => values.reduce((acc, value) => recursiveMerge(acc, value), null)
|
|
2680
|
-
);
|
|
2681
|
-
var getSubmittableDataSync = (components) => components.map((component) => component.getSubmittableValueSync()).reduce((acc, value) => recursiveMerge(acc, value), null);
|
|
2682
|
-
var getLocalValues = (components) => components.map((component) => component.getLocalValue()).reduce((acc, value) => recursiveMerge(acc, value), null);
|
|
2683
|
-
|
|
2684
|
-
// src/domain/components/step/StepDomainComponent.ts
|
|
2685
|
-
var createStepComponent = (stepProps) => {
|
|
2686
|
-
const _a = stepProps, { uid, stepPolling, stepRefreshAfter, onComponentUpdate } = _a, rest = __objRest(_a, ["uid", "stepPolling", "stepRefreshAfter", "onComponentUpdate"]);
|
|
2687
|
-
const update = getInputUpdateFunction(onComponentUpdate);
|
|
2688
|
-
const component = __spreadProps(__spreadValues({
|
|
2689
|
-
uid
|
|
2690
|
-
}, rest), {
|
|
2691
|
-
type: "step",
|
|
2692
|
-
kind: "step",
|
|
2693
|
-
modals: [],
|
|
2694
|
-
dismissModal() {
|
|
2695
|
-
var _a2;
|
|
2696
|
-
(_a2 = this.modals.at(-1)) == null ? void 0 : _a2.close();
|
|
2697
|
-
},
|
|
2698
|
-
dismissAllModals() {
|
|
2699
|
-
this._update((draft) => {
|
|
2700
|
-
draft.modals = draft.modals.map((m) => __spreadProps(__spreadValues({}, m), { open: false }));
|
|
2701
|
-
});
|
|
2702
|
-
},
|
|
2703
|
-
showModal(modal) {
|
|
2704
|
-
this._update((draft) => {
|
|
2705
|
-
draft.modals = [...draft.modals, modal];
|
|
2706
|
-
});
|
|
2707
|
-
},
|
|
2708
|
-
_update(updateFn) {
|
|
2709
|
-
update(this, updateFn);
|
|
2710
|
-
},
|
|
2711
|
-
getChildren() {
|
|
2712
|
-
return this.externalConfirmation ? [...this.layoutComponents, this.externalConfirmation] : this.layoutComponents;
|
|
2713
|
-
},
|
|
2714
|
-
getModals() {
|
|
2715
|
-
return this.modals;
|
|
2716
|
-
},
|
|
2717
|
-
async getSubmittableValue() {
|
|
2718
|
-
return getSubmittableData(this.schemaComponents);
|
|
2719
|
-
},
|
|
2720
|
-
getSubmittableValueSync() {
|
|
2721
|
-
return getSubmittableDataSync(this.schemaComponents);
|
|
2722
|
-
},
|
|
2723
|
-
getLocalValue() {
|
|
2724
|
-
return getLocalValues(this.schemaComponents);
|
|
2725
|
-
},
|
|
2726
|
-
validate() {
|
|
2727
|
-
return this.schemaComponents.every(
|
|
2728
|
-
(inputComponent) => inputComponent.isSchemaReferencedInStep ? inputComponent.validate() : true
|
|
2729
|
-
);
|
|
2730
|
-
},
|
|
2731
|
-
setLoadingState(loadingState) {
|
|
2732
|
-
this._update((draft) => {
|
|
2733
|
-
draft.loadingState = loadingState;
|
|
2734
|
-
});
|
|
2735
|
-
},
|
|
2736
|
-
start() {
|
|
2737
|
-
stepPolling == null ? void 0 : stepPolling.start();
|
|
2738
|
-
stepRefreshAfter == null ? void 0 : stepRefreshAfter.start();
|
|
2739
|
-
},
|
|
2740
|
-
stop() {
|
|
2741
|
-
stepPolling == null ? void 0 : stepPolling.stop();
|
|
2742
|
-
stepRefreshAfter == null ? void 0 : stepRefreshAfter.stop();
|
|
2743
|
-
this._update((draft) => {
|
|
2744
|
-
draft.modals = [];
|
|
2745
|
-
});
|
|
2746
|
-
}
|
|
2747
|
-
});
|
|
2748
|
-
return component;
|
|
2749
|
-
};
|
|
2750
|
-
|
|
2751
|
-
// src/domain/features/polling/getStepPolling.ts
|
|
2752
|
-
var getStepPolling = ({
|
|
2753
|
-
pollingConfig,
|
|
2754
|
-
logEvent,
|
|
2755
|
-
onBehavior,
|
|
2756
|
-
onPoll,
|
|
2757
|
-
registerSubmissionBehavior
|
|
2758
|
-
}) => {
|
|
2759
|
-
const { interval, delay = interval, maxAttempts, url, onError } = pollingConfig;
|
|
2760
|
-
let abortController = new AbortController();
|
|
2761
|
-
let intervalRef = null;
|
|
2762
|
-
if (delay == null) {
|
|
2763
|
-
throw new Error("Polling configuration must include delay or interval");
|
|
2764
|
-
}
|
|
2765
|
-
const onErrorBehavior = getDomainLayerBehavior(onError, [], registerSubmissionBehavior);
|
|
2766
|
-
let attempts = 0;
|
|
2767
|
-
const poll = () => {
|
|
2768
|
-
attempts += 1;
|
|
2769
|
-
abortController.abort();
|
|
2770
|
-
abortController = new AbortController();
|
|
2771
|
-
const { signal } = abortController;
|
|
2772
|
-
onPoll(url, onErrorBehavior, signal).then((result) => {
|
|
2773
|
-
if (result) {
|
|
2774
|
-
stop();
|
|
2775
|
-
return;
|
|
2776
|
-
}
|
|
2777
|
-
if (attempts >= maxAttempts && !signal.aborted) {
|
|
2778
|
-
void onBehavior(onErrorBehavior);
|
|
2779
|
-
stop();
|
|
2780
|
-
}
|
|
2781
|
-
}).catch(() => {
|
|
2782
|
-
});
|
|
2783
|
-
};
|
|
2784
|
-
const start = () => {
|
|
2785
|
-
attempts = 0;
|
|
2786
|
-
intervalRef = setInterval(poll, delay * 1e3);
|
|
2787
|
-
poll();
|
|
2788
|
-
};
|
|
2789
|
-
const stop = () => {
|
|
2790
|
-
if (!intervalRef) {
|
|
2791
|
-
logEvent("warning", "Attempted to stop polling but it was not started");
|
|
2792
|
-
return;
|
|
2793
|
-
}
|
|
2794
|
-
clearTimeout(intervalRef);
|
|
2795
|
-
abortController.abort();
|
|
2796
|
-
};
|
|
2797
|
-
return { start, stop };
|
|
2798
|
-
};
|
|
2799
|
-
|
|
2800
|
-
// src/domain/features/refreshAfter/getStepRefreshAfter.ts
|
|
2801
|
-
var ONE_SECOND = 1e3;
|
|
2802
|
-
var getStepRefreshAfter = ({
|
|
2803
|
-
refreshAfter,
|
|
2804
|
-
logEvent,
|
|
2805
|
-
onBehavior
|
|
2806
|
-
}) => {
|
|
2807
|
-
let timeout = null;
|
|
2808
|
-
const targetTime = new Date(refreshAfter).getTime();
|
|
2809
|
-
if (typeof refreshAfter !== "string" || Number.isNaN(targetTime)) {
|
|
2810
|
-
throw new Error(`Invalid refreshAfter value: ${String(refreshAfter)}`);
|
|
2811
|
-
}
|
|
2812
|
-
const start = () => {
|
|
2813
|
-
const timeLeft = Math.max(targetTime - Date.now(), ONE_SECOND);
|
|
2814
|
-
timeout = setTimeout(() => {
|
|
2815
|
-
void onBehavior({ type: "refresh", analytics: { schema: "refreshAfter" } });
|
|
2816
|
-
}, timeLeft);
|
|
2817
|
-
};
|
|
2818
|
-
return {
|
|
2819
|
-
start,
|
|
2820
|
-
stop: () => {
|
|
2821
|
-
if (!timeout) {
|
|
2822
|
-
logEvent("warning", "Attempted to stop refreshAfter but it was not started");
|
|
2823
|
-
return;
|
|
2824
|
-
}
|
|
2825
|
-
clearTimeout(timeout);
|
|
2826
|
-
}
|
|
2827
|
-
};
|
|
2828
|
-
};
|
|
2829
|
-
|
|
2830
|
-
// src/domain/prefetching/request-cache.ts
|
|
2831
|
-
var makeRequestCacheWithParent = (parent) => {
|
|
2832
|
-
const map = /* @__PURE__ */ new Map();
|
|
2833
|
-
const cache = {
|
|
2834
|
-
get: (requestParams) => {
|
|
2835
|
-
var _a;
|
|
2836
|
-
const key = makeKey(requestParams);
|
|
2837
|
-
const promise = (_a = map.get(key)) != null ? _a : parent == null ? void 0 : parent.get(requestParams);
|
|
2838
|
-
map.delete(key);
|
|
2839
|
-
return promise;
|
|
2840
|
-
},
|
|
2841
|
-
set: (requestParams, responsePromise) => {
|
|
2842
|
-
return map.set(makeKey(requestParams), responsePromise);
|
|
2843
|
-
}
|
|
2844
|
-
};
|
|
2845
|
-
return cache;
|
|
2846
|
-
};
|
|
2847
|
-
var makeRequestCache = (initialValues = []) => {
|
|
2848
|
-
const cache = makeRequestCacheWithParent(void 0);
|
|
2849
|
-
initialValues.forEach(([requestParams, responsePromise]) => {
|
|
2850
|
-
cache.set(requestParams, responsePromise);
|
|
2851
|
-
});
|
|
2852
|
-
return cache;
|
|
2853
|
-
};
|
|
2854
|
-
var normaliseRequestCache = (cache) => {
|
|
2855
|
-
if (cache === void 0) {
|
|
2856
|
-
return makeRequestCache();
|
|
2857
|
-
}
|
|
2858
|
-
if (isRequestCacheInstance(cache)) {
|
|
2859
|
-
return cache;
|
|
2860
|
-
}
|
|
2861
|
-
return makeRequestCache(cache);
|
|
2862
|
-
};
|
|
2863
|
-
var isRequestCacheInstance = (cache) => {
|
|
2864
|
-
return !cache || !Array.isArray(cache);
|
|
2865
|
-
};
|
|
2866
|
-
var makeKey = (requestParams) => {
|
|
2867
|
-
var _a, _b;
|
|
2868
|
-
const [input, init] = requestParams;
|
|
2869
|
-
const url = typeof input === "string" || input instanceof URL ? input.toString() : input.url;
|
|
2870
|
-
const key = JSON.stringify({
|
|
2871
|
-
url,
|
|
2872
|
-
method: (_a = init == null ? void 0 : init.method) != null ? _a : "GET",
|
|
2873
|
-
headers: (init == null ? void 0 : init.headers) ? Array.from(new Headers(init.headers).entries()) : [],
|
|
2874
|
-
body: (_b = init == null ? void 0 : init.body) != null ? _b : null
|
|
2875
|
-
});
|
|
2876
|
-
return key;
|
|
2877
|
-
};
|
|
2878
|
-
|
|
2879
2544
|
// src/domain/components/utils/isOrWasValid.ts
|
|
2880
2545
|
var isOrWasValid = (getErrors, previous, current) => {
|
|
2881
2546
|
const wasValid = getErrors(previous).length === 0 && previous !== null;
|
|
@@ -3354,6 +3019,72 @@ var getInitialValidationAsyncState = () => ({
|
|
|
3354
3019
|
messages: {}
|
|
3355
3020
|
});
|
|
3356
3021
|
|
|
3022
|
+
// src/controller/response-utils.ts
|
|
3023
|
+
var import_spec = require("@wise/dynamic-flow-types/spec");
|
|
3024
|
+
var parseResponseBodyAsJsonElement = async (response) => {
|
|
3025
|
+
assertResponseIsValid(response);
|
|
3026
|
+
try {
|
|
3027
|
+
return await response.json();
|
|
3028
|
+
} catch (e) {
|
|
3029
|
+
return null;
|
|
3030
|
+
}
|
|
3031
|
+
};
|
|
3032
|
+
var parseResponseBodyAsText = async (response) => {
|
|
3033
|
+
try {
|
|
3034
|
+
return await response.text();
|
|
3035
|
+
} catch (e) {
|
|
3036
|
+
return null;
|
|
3037
|
+
}
|
|
3038
|
+
};
|
|
3039
|
+
function isActionResponseBody(body) {
|
|
3040
|
+
return (0, import_spec.validateActionResponse)(body).valid;
|
|
3041
|
+
}
|
|
3042
|
+
function assertActionResponseBody(body) {
|
|
3043
|
+
if (!isObject(body) || !isObject(body.action)) {
|
|
3044
|
+
throw new Error(
|
|
3045
|
+
"Incorrect response body in action response. Expected an object satisfying the type { action: Action }."
|
|
3046
|
+
);
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
function assertModalResponseBody(body) {
|
|
3050
|
+
if (isObject(body)) {
|
|
3051
|
+
if ("content" in body && isArray(body.content)) {
|
|
3052
|
+
return;
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
3055
|
+
throw new Error(
|
|
3056
|
+
"Incorrect response body in modal response. Expected an object satisfying the type { title?: string, components: Layout[] }."
|
|
3057
|
+
);
|
|
3058
|
+
}
|
|
3059
|
+
function assertSubflowResponseBody(body) {
|
|
3060
|
+
const { valid } = (0, import_spec.validateSubflowResponse)(body);
|
|
3061
|
+
if (valid) {
|
|
3062
|
+
return;
|
|
3063
|
+
}
|
|
3064
|
+
throw new Error("Incorrect response body in subflow response.");
|
|
3065
|
+
}
|
|
3066
|
+
function isErrorResponseBody(body) {
|
|
3067
|
+
return Boolean(
|
|
3068
|
+
isObject(body) && (body.refreshFormUrl || body.refreshUrl || body.validation || body.error || body.analytics)
|
|
3069
|
+
);
|
|
3070
|
+
}
|
|
3071
|
+
function assertStepResponseBody(body) {
|
|
3072
|
+
if (!isObject(body)) {
|
|
3073
|
+
throw new Error("Incorrect response body in step response. Expected an object.");
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
var assertResponseIsValid = (response) => {
|
|
3077
|
+
if (!isResponse(response)) {
|
|
3078
|
+
throw new Error("Incorrect type of response from fetch. Expected object of type Response.");
|
|
3079
|
+
}
|
|
3080
|
+
if (response.bodyUsed) {
|
|
3081
|
+
throw new Error(
|
|
3082
|
+
"The body of the provided Response object has already been used. Every request must respond with a new Response object."
|
|
3083
|
+
);
|
|
3084
|
+
}
|
|
3085
|
+
};
|
|
3086
|
+
var isResponse = (response) => typeof response === "object" && response !== null && "clone" in response && "bodyUsed" in response;
|
|
3087
|
+
|
|
3357
3088
|
// src/domain/features/utils/response-utils.ts
|
|
3358
3089
|
var getAnalyticsFromErrorResponse = (json) => {
|
|
3359
3090
|
if (!isErrorResponseBody(json)) {
|
|
@@ -5829,235 +5560,535 @@ var createTextInputComponent = (textInputProps, onComponentUpdate) => {
|
|
|
5829
5560
|
this._update((draft) => {
|
|
5830
5561
|
draft.errors = errors;
|
|
5831
5562
|
});
|
|
5832
|
-
return errors.length === 0;
|
|
5833
|
-
}
|
|
5834
|
-
}, rest);
|
|
5835
|
-
return inputComponent;
|
|
5563
|
+
return errors.length === 0;
|
|
5564
|
+
}
|
|
5565
|
+
}, rest);
|
|
5566
|
+
return inputComponent;
|
|
5567
|
+
};
|
|
5568
|
+
|
|
5569
|
+
// src/domain/mappers/schema/stringSchemaToComponent/stringSchemaToTextInputComponent.ts
|
|
5570
|
+
var stringSchemaToTextInputComponent = (schemaMapperProps, mapperProps) => {
|
|
5571
|
+
const { schema, localValue, model, required = false, onPersistAsync } = schemaMapperProps;
|
|
5572
|
+
const {
|
|
5573
|
+
autocapitalization,
|
|
5574
|
+
autocompleteHint,
|
|
5575
|
+
control,
|
|
5576
|
+
default: defaultValue,
|
|
5577
|
+
displayFormat,
|
|
5578
|
+
format,
|
|
5579
|
+
maxLength,
|
|
5580
|
+
minLength,
|
|
5581
|
+
suggestions,
|
|
5582
|
+
validationMessages
|
|
5583
|
+
} = schema;
|
|
5584
|
+
const { getErrorMessageFunctions, onComponentUpdate, onBehavior, onValueChange, logEvent } = mapperProps;
|
|
5585
|
+
const controlForLegacyFormat = getControlForLegacyFormat(format);
|
|
5586
|
+
const errorMessageFunctions = getErrorMessageFunctions(validationMessages);
|
|
5587
|
+
const { performValidationAsync, validationAsyncState } = getValidationAsyncInitialState(
|
|
5588
|
+
schemaMapperProps,
|
|
5589
|
+
mapperProps
|
|
5590
|
+
);
|
|
5591
|
+
const validLocalValue = isString(localValue) ? localValue : null;
|
|
5592
|
+
const validModel = isString(model) ? model : defaultValue != null ? defaultValue : null;
|
|
5593
|
+
const value = onPersistAsync ? validLocalValue : validModel;
|
|
5594
|
+
return createTextInputComponent(
|
|
5595
|
+
__spreadProps(__spreadValues({}, mapCommonSchemaProps(schemaMapperProps)), {
|
|
5596
|
+
autocapitalization,
|
|
5597
|
+
autoComplete: getAutocompleteString(autocompleteHint),
|
|
5598
|
+
checks: schema.hidden ? [] : [
|
|
5599
|
+
getRequiredCheck(required, errorMessageFunctions),
|
|
5600
|
+
getAboveMaxLengthCheck(schema, errorMessageFunctions),
|
|
5601
|
+
getBelowMinLengthCheck(schema, errorMessageFunctions),
|
|
5602
|
+
getNotAdheringToPatternCheck(schema, errorMessageFunctions, { logEvent })
|
|
5603
|
+
],
|
|
5604
|
+
control: control != null ? control : controlForLegacyFormat,
|
|
5605
|
+
displayFormat,
|
|
5606
|
+
maxLength,
|
|
5607
|
+
minLength,
|
|
5608
|
+
suggestions: mapStringSchemaSuggestions(suggestions, mapperProps.logEvent),
|
|
5609
|
+
value,
|
|
5610
|
+
validationAsyncState,
|
|
5611
|
+
schemaOnChange: getSchemaOnChange(schema, onBehavior),
|
|
5612
|
+
performValidationAsync,
|
|
5613
|
+
onValueChange
|
|
5614
|
+
}),
|
|
5615
|
+
onComponentUpdate
|
|
5616
|
+
);
|
|
5617
|
+
};
|
|
5618
|
+
var getControlForLegacyFormat = (format) => {
|
|
5619
|
+
if (format && ["numeric", "phone-number", "email", "password"].includes(format)) {
|
|
5620
|
+
return format;
|
|
5621
|
+
}
|
|
5622
|
+
return void 0;
|
|
5623
|
+
};
|
|
5624
|
+
|
|
5625
|
+
// src/domain/mappers/schema/stringSchemaToComponent/stringSchemaToComponent.ts
|
|
5626
|
+
var stringSchemaToComponent = (schemaMapperProps, mapperProps) => {
|
|
5627
|
+
const { schema } = schemaMapperProps;
|
|
5628
|
+
if (isStringSchemaWithBase64(schema)) {
|
|
5629
|
+
return stringSchemaToUploadInputComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5630
|
+
}
|
|
5631
|
+
switch (schema.format) {
|
|
5632
|
+
case "date":
|
|
5633
|
+
return stringSchemaToDateInputComponent(schemaMapperProps, mapperProps);
|
|
5634
|
+
default:
|
|
5635
|
+
return stringSchemaToTextInputComponent(schemaMapperProps, mapperProps);
|
|
5636
|
+
}
|
|
5637
|
+
};
|
|
5638
|
+
var isStringSchemaWithBase64 = (schema) => {
|
|
5639
|
+
return schema.format === "base64url" && !("persistAsync" in schema);
|
|
5640
|
+
};
|
|
5641
|
+
|
|
5642
|
+
// src/domain/mappers/mapSchemaToComponent.ts
|
|
5643
|
+
var mapSchemaToComponent = (schemaMapperProps, mapperProps) => {
|
|
5644
|
+
const { uid, schema } = schemaMapperProps;
|
|
5645
|
+
if (isConstSchema(schema)) {
|
|
5646
|
+
return constSchemaToComponent(uid, __spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5647
|
+
}
|
|
5648
|
+
if (isSchemaWithPersistAsync(schema)) {
|
|
5649
|
+
return persistAsyncSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5650
|
+
}
|
|
5651
|
+
if (isAllOfSchema(schema)) {
|
|
5652
|
+
return allOfSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5653
|
+
}
|
|
5654
|
+
if (isOneOfSchema(schema)) {
|
|
5655
|
+
return oneOfSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5656
|
+
}
|
|
5657
|
+
if (isBooleanSchema(schema)) {
|
|
5658
|
+
return booleanSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5659
|
+
}
|
|
5660
|
+
if (isObjectSchema(schema)) {
|
|
5661
|
+
const { format } = schema;
|
|
5662
|
+
if (format === "money") {
|
|
5663
|
+
return objectSchemaToMoneyInputComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5664
|
+
}
|
|
5665
|
+
if (format != null && Object.keys(schema.properties).length === 0) {
|
|
5666
|
+
return objectSchemaToFormattedValueComponent(
|
|
5667
|
+
__spreadProps(__spreadValues({}, schemaMapperProps), { schema: __spreadProps(__spreadValues({}, schema), { format }) }),
|
|
5668
|
+
mapperProps
|
|
5669
|
+
);
|
|
5670
|
+
}
|
|
5671
|
+
return objectSchemaToObjectComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5672
|
+
}
|
|
5673
|
+
if (isIntegerSchema(schema)) {
|
|
5674
|
+
return integerSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5675
|
+
}
|
|
5676
|
+
if (isNumberSchema(schema)) {
|
|
5677
|
+
return numberSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5678
|
+
}
|
|
5679
|
+
if (isStringSchema(schema)) {
|
|
5680
|
+
return stringSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5681
|
+
}
|
|
5682
|
+
if (isArraySchema(schema)) {
|
|
5683
|
+
return arraySchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5684
|
+
}
|
|
5685
|
+
if (isBlobSchema(schema)) {
|
|
5686
|
+
if (!schemaMapperProps.onPersistAsync) {
|
|
5687
|
+
throw new Error(
|
|
5688
|
+
"Blob schemas can only be used as the schema of a persist async configuration."
|
|
5689
|
+
);
|
|
5690
|
+
}
|
|
5691
|
+
return blobSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5692
|
+
}
|
|
5693
|
+
throw new Error("Not yet supported");
|
|
5694
|
+
};
|
|
5695
|
+
|
|
5696
|
+
// src/domain/mappers/mapStepSchemas.ts
|
|
5697
|
+
var mapStepSchemas = (uid, step, stepLocalValue, mapperProps, referencedSchemaIds) => {
|
|
5698
|
+
const isReferenced = (schemaId) => schemaId != null && referencedSchemaIds.includes(schemaId);
|
|
5699
|
+
return step.schemas.map((schema, i) => {
|
|
5700
|
+
var _a, _b;
|
|
5701
|
+
const schemaComponent = mapSchemaToComponent(
|
|
5702
|
+
{
|
|
5703
|
+
uid: `${uid}.schemas-${i}.${schema.$id}`,
|
|
5704
|
+
schemaId: schema.$id,
|
|
5705
|
+
schema,
|
|
5706
|
+
model: (_a = step.model) != null ? _a : null,
|
|
5707
|
+
localValue: stepLocalValue,
|
|
5708
|
+
validationErrors: (_b = step.errors) == null ? void 0 : _b.validation,
|
|
5709
|
+
required: true
|
|
5710
|
+
},
|
|
5711
|
+
mapperProps
|
|
5712
|
+
);
|
|
5713
|
+
return __spreadProps(__spreadValues({}, schemaComponent), {
|
|
5714
|
+
isSchemaReferencedInStep: isReferenced(schema.$id)
|
|
5715
|
+
});
|
|
5716
|
+
});
|
|
5717
|
+
};
|
|
5718
|
+
|
|
5719
|
+
// src/domain/mappers/mapToolbarToComponent.ts
|
|
5720
|
+
var mapToolbarToComponent = (uid, toolbar, mapperProps) => {
|
|
5721
|
+
if (!toolbar) {
|
|
5722
|
+
return void 0;
|
|
5723
|
+
}
|
|
5724
|
+
const { onBehavior } = mapperProps;
|
|
5725
|
+
return __spreadProps(__spreadValues({}, toolbar), {
|
|
5726
|
+
type: "toolbar",
|
|
5727
|
+
uid: `${uid}.toolbar`,
|
|
5728
|
+
tags: toolbar.tags,
|
|
5729
|
+
items: toolbar.items.map((item) => {
|
|
5730
|
+
const context = item.context ? mapLegacyContext(item.context) : void 0;
|
|
5731
|
+
const behavior = getDomainLayerBehavior(
|
|
5732
|
+
{ behavior: item.behavior },
|
|
5733
|
+
[],
|
|
5734
|
+
mapperProps.registerSubmissionBehavior
|
|
5735
|
+
);
|
|
5736
|
+
return __spreadProps(__spreadValues({}, item), {
|
|
5737
|
+
context: context ? mapLegacyContext(context) : void 0,
|
|
5738
|
+
disabled: !!item.disabled,
|
|
5739
|
+
tags: item.tags,
|
|
5740
|
+
onClick: () => {
|
|
5741
|
+
void onBehavior(behavior);
|
|
5742
|
+
}
|
|
5743
|
+
});
|
|
5744
|
+
})
|
|
5745
|
+
});
|
|
5836
5746
|
};
|
|
5837
5747
|
|
|
5838
|
-
// src/domain/mappers/
|
|
5839
|
-
var
|
|
5840
|
-
|
|
5841
|
-
const {
|
|
5842
|
-
autocapitalization,
|
|
5843
|
-
autocompleteHint,
|
|
5844
|
-
control,
|
|
5845
|
-
default: defaultValue,
|
|
5846
|
-
displayFormat,
|
|
5847
|
-
format,
|
|
5848
|
-
maxLength,
|
|
5849
|
-
minLength,
|
|
5850
|
-
suggestions,
|
|
5851
|
-
validationMessages
|
|
5852
|
-
} = schema;
|
|
5853
|
-
const { getErrorMessageFunctions, onComponentUpdate, onBehavior, onValueChange, logEvent } = mapperProps;
|
|
5854
|
-
const controlForLegacyFormat = getControlForLegacyFormat(format);
|
|
5855
|
-
const errorMessageFunctions = getErrorMessageFunctions(validationMessages);
|
|
5856
|
-
const { performValidationAsync, validationAsyncState } = getValidationAsyncInitialState(
|
|
5857
|
-
schemaMapperProps,
|
|
5858
|
-
mapperProps
|
|
5859
|
-
);
|
|
5860
|
-
const validLocalValue = isString(localValue) ? localValue : null;
|
|
5861
|
-
const validModel = isString(model) ? model : defaultValue != null ? defaultValue : null;
|
|
5862
|
-
const value = onPersistAsync ? validLocalValue : validModel;
|
|
5863
|
-
return createTextInputComponent(
|
|
5864
|
-
__spreadProps(__spreadValues({}, mapCommonSchemaProps(schemaMapperProps)), {
|
|
5865
|
-
autocapitalization,
|
|
5866
|
-
autoComplete: getAutocompleteString(autocompleteHint),
|
|
5867
|
-
checks: schema.hidden ? [] : [
|
|
5868
|
-
getRequiredCheck(required, errorMessageFunctions),
|
|
5869
|
-
getAboveMaxLengthCheck(schema, errorMessageFunctions),
|
|
5870
|
-
getBelowMinLengthCheck(schema, errorMessageFunctions),
|
|
5871
|
-
getNotAdheringToPatternCheck(schema, errorMessageFunctions, { logEvent })
|
|
5872
|
-
],
|
|
5873
|
-
control: control != null ? control : controlForLegacyFormat,
|
|
5874
|
-
displayFormat,
|
|
5875
|
-
maxLength,
|
|
5876
|
-
minLength,
|
|
5877
|
-
suggestions: mapStringSchemaSuggestions(suggestions, mapperProps.logEvent),
|
|
5878
|
-
value,
|
|
5879
|
-
validationAsyncState,
|
|
5880
|
-
schemaOnChange: getSchemaOnChange(schema, onBehavior),
|
|
5881
|
-
performValidationAsync,
|
|
5882
|
-
onValueChange
|
|
5883
|
-
}),
|
|
5884
|
-
onComponentUpdate
|
|
5885
|
-
);
|
|
5748
|
+
// src/domain/mappers/utils/groupLayoutByPinned.ts
|
|
5749
|
+
var groupLayoutByPinned = (layouts) => {
|
|
5750
|
+
return layouts.reduce(groupLayout, { pinned: [], nonPinned: [] });
|
|
5886
5751
|
};
|
|
5887
|
-
var
|
|
5888
|
-
if (
|
|
5889
|
-
return
|
|
5752
|
+
var groupLayout = (acc, layout) => {
|
|
5753
|
+
if (layout.type === "button" && layout.pinOrder !== void 0) {
|
|
5754
|
+
return {
|
|
5755
|
+
pinned: [...acc.pinned, layout],
|
|
5756
|
+
nonPinned: acc.nonPinned
|
|
5757
|
+
};
|
|
5890
5758
|
}
|
|
5891
|
-
|
|
5759
|
+
if (hasColumns(layout)) {
|
|
5760
|
+
const leftChildren = groupLayoutByPinned(layout.left);
|
|
5761
|
+
const rightChildren = groupLayoutByPinned(layout.right);
|
|
5762
|
+
return {
|
|
5763
|
+
pinned: [...acc.pinned, ...leftChildren.pinned, ...rightChildren.pinned],
|
|
5764
|
+
nonPinned: [
|
|
5765
|
+
...acc.nonPinned,
|
|
5766
|
+
__spreadProps(__spreadValues({}, layout), {
|
|
5767
|
+
left: leftChildren.nonPinned,
|
|
5768
|
+
right: rightChildren.nonPinned
|
|
5769
|
+
})
|
|
5770
|
+
]
|
|
5771
|
+
};
|
|
5772
|
+
}
|
|
5773
|
+
if (hasChildren(layout)) {
|
|
5774
|
+
const childComponents = groupLayoutByPinned(layout.components);
|
|
5775
|
+
return {
|
|
5776
|
+
pinned: [...acc.pinned, ...childComponents.pinned],
|
|
5777
|
+
nonPinned: [
|
|
5778
|
+
...acc.nonPinned,
|
|
5779
|
+
__spreadProps(__spreadValues({}, layout), {
|
|
5780
|
+
components: childComponents.nonPinned
|
|
5781
|
+
})
|
|
5782
|
+
]
|
|
5783
|
+
};
|
|
5784
|
+
}
|
|
5785
|
+
return {
|
|
5786
|
+
pinned: [...acc.pinned],
|
|
5787
|
+
nonPinned: [...acc.nonPinned, layout]
|
|
5788
|
+
};
|
|
5892
5789
|
};
|
|
5790
|
+
var hasChildren = (component) => "components" in component;
|
|
5791
|
+
var hasColumns = (component) => "right" in component && "left" in component;
|
|
5893
5792
|
|
|
5894
|
-
// src/
|
|
5895
|
-
var
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5793
|
+
// src/controller/getErrorMessage.ts
|
|
5794
|
+
var getErrorMessage = (error) => {
|
|
5795
|
+
return error instanceof Error ? error.message : typeof error === "string" ? error : `Unknown Error: type is ${typeof error}`;
|
|
5796
|
+
};
|
|
5797
|
+
|
|
5798
|
+
// src/controller/handleErrorResponse.ts
|
|
5799
|
+
var handleErrorResponse = async (response, actionId, trackEvent) => {
|
|
5800
|
+
const body = await parseResponseBodyAsJsonElement(response.clone());
|
|
5801
|
+
if (isErrorResponseBody(body)) {
|
|
5802
|
+
const refreshUrl = body.refreshUrl || body.refreshFormUrl;
|
|
5803
|
+
const { error, validation, analytics } = body;
|
|
5804
|
+
trackEvent("Action Failed", __spreadProps(__spreadValues({}, analytics), { actionId, statusCode: response.status }));
|
|
5805
|
+
const errors = { error, validation };
|
|
5806
|
+
return refreshUrl ? { type: "refresh", body: { refreshUrl, errors } } : {
|
|
5807
|
+
type: "error",
|
|
5808
|
+
body: { errors, analytics },
|
|
5809
|
+
httpError: { statusCode: response.status }
|
|
5810
|
+
};
|
|
5899
5811
|
}
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
|
|
5812
|
+
trackEvent("Action Failed", { actionId, statusCode: response.status });
|
|
5813
|
+
const errorMessage = await parseResponseBodyAsText(response);
|
|
5814
|
+
return {
|
|
5815
|
+
type: "error",
|
|
5816
|
+
httpError: {
|
|
5817
|
+
message: errorMessage || void 0,
|
|
5818
|
+
statusCode: response.status
|
|
5819
|
+
}
|
|
5820
|
+
};
|
|
5821
|
+
};
|
|
5822
|
+
|
|
5823
|
+
// src/controller/getResponseType.ts
|
|
5824
|
+
var responseTypes = ["step", "action", "exit", "modal", "subflow"];
|
|
5825
|
+
var getResponseType = (headers, body) => {
|
|
5826
|
+
const headerResponseType = getResponseTypeFromHeader(headers);
|
|
5827
|
+
if (headerResponseType) {
|
|
5828
|
+
return headerResponseType;
|
|
5829
|
+
}
|
|
5830
|
+
if (isObject(body) && body.action) {
|
|
5831
|
+
return "action";
|
|
5905
5832
|
}
|
|
5833
|
+
return "step";
|
|
5906
5834
|
};
|
|
5907
|
-
var
|
|
5908
|
-
|
|
5835
|
+
var getResponseTypeFromHeader = (headers) => {
|
|
5836
|
+
if (headers == null ? void 0 : headers.has("X-Df-Response-Type")) {
|
|
5837
|
+
const type = headers.get("X-Df-Response-Type");
|
|
5838
|
+
assertDFResponseType(type);
|
|
5839
|
+
return type;
|
|
5840
|
+
}
|
|
5841
|
+
if (headers == null ? void 0 : headers.has("X-Df-Exit")) {
|
|
5842
|
+
return "exit";
|
|
5843
|
+
}
|
|
5844
|
+
return void 0;
|
|
5909
5845
|
};
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
return constSchemaToComponent(uid, __spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5846
|
+
function assertDFResponseType(type) {
|
|
5847
|
+
if (!responseTypes.includes(type)) {
|
|
5848
|
+
throw new Error(
|
|
5849
|
+
"Unsupported X-Df-Response-Type. Allowed values are 'step', 'action', 'exit', 'error', 'modal', 'subflow'."
|
|
5850
|
+
);
|
|
5916
5851
|
}
|
|
5917
|
-
|
|
5918
|
-
|
|
5852
|
+
}
|
|
5853
|
+
|
|
5854
|
+
// src/controller/makeSafeHttpClient.ts
|
|
5855
|
+
var makeSafeHttpClient = (httpClient) => async (...props) => {
|
|
5856
|
+
try {
|
|
5857
|
+
return await httpClient(...props);
|
|
5858
|
+
} catch (e) {
|
|
5859
|
+
return null;
|
|
5919
5860
|
}
|
|
5920
|
-
|
|
5921
|
-
|
|
5861
|
+
};
|
|
5862
|
+
|
|
5863
|
+
// src/controller/executeRequest.ts
|
|
5864
|
+
var executeRequest = async (props) => {
|
|
5865
|
+
const { exit, request, requestCache, httpClient, trackEvent, logEvent } = props;
|
|
5866
|
+
const { url, method, body } = request;
|
|
5867
|
+
const response = await getCachedOrFetch(
|
|
5868
|
+
[
|
|
5869
|
+
url,
|
|
5870
|
+
{
|
|
5871
|
+
method,
|
|
5872
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
5873
|
+
headers: { "Content-Type": "application/json" }
|
|
5874
|
+
}
|
|
5875
|
+
],
|
|
5876
|
+
requestCache,
|
|
5877
|
+
httpClient
|
|
5878
|
+
);
|
|
5879
|
+
if (!response) {
|
|
5880
|
+
const extra = { errorMessage: "Network Error" };
|
|
5881
|
+
trackEvent("Request Failed", extra);
|
|
5882
|
+
logEvent("error", "Dynamic Flow - Request Failed Unexpectedly", extra);
|
|
5883
|
+
return { type: "error" };
|
|
5922
5884
|
}
|
|
5923
|
-
if (
|
|
5924
|
-
return
|
|
5885
|
+
if (!response.ok) {
|
|
5886
|
+
return handleErrorResponse(response, void 0, trackEvent);
|
|
5925
5887
|
}
|
|
5926
|
-
|
|
5927
|
-
|
|
5888
|
+
const responseBody = await parseResponseBodyAsJsonElement(response);
|
|
5889
|
+
const responseType = getResponseType(response.headers, responseBody);
|
|
5890
|
+
if (exit) {
|
|
5891
|
+
return { type: "complete", result: responseBody };
|
|
5928
5892
|
}
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5893
|
+
switch (responseType) {
|
|
5894
|
+
case "step": {
|
|
5895
|
+
const etag = response.headers.get("etag") || null;
|
|
5896
|
+
assertStepResponseBody(responseBody);
|
|
5897
|
+
return { type: "replace-step", step: responseBody, etag };
|
|
5898
|
+
}
|
|
5899
|
+
case "exit": {
|
|
5900
|
+
return { type: "complete", result: responseBody };
|
|
5901
|
+
}
|
|
5902
|
+
case "action": {
|
|
5903
|
+
assertActionResponseBody(responseBody);
|
|
5904
|
+
return {
|
|
5905
|
+
type: "behavior",
|
|
5906
|
+
behavior: {
|
|
5907
|
+
type: "action",
|
|
5908
|
+
action: responseBody.action
|
|
5909
|
+
}
|
|
5910
|
+
};
|
|
5911
|
+
}
|
|
5912
|
+
case "subflow": {
|
|
5913
|
+
assertSubflowResponseBody(responseBody);
|
|
5914
|
+
return {
|
|
5915
|
+
type: "behavior",
|
|
5916
|
+
behavior: __spreadProps(__spreadValues({}, responseBody), {
|
|
5917
|
+
type: "subflow",
|
|
5918
|
+
onCompletion: responseBody.onCompletion ? normaliseBehavior(responseBody.onCompletion, []) : void 0,
|
|
5919
|
+
onError: responseBody.onError ? normaliseBehavior(responseBody.onError, []) : void 0
|
|
5920
|
+
})
|
|
5921
|
+
};
|
|
5933
5922
|
}
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5923
|
+
case "modal": {
|
|
5924
|
+
assertModalResponseBody(responseBody);
|
|
5925
|
+
return { type: "behavior", behavior: __spreadProps(__spreadValues({}, responseBody), { type: "modal" }) };
|
|
5926
|
+
}
|
|
5927
|
+
default: {
|
|
5928
|
+
throw new Error(`Unsupported response type: ${String(responseType)}`);
|
|
5939
5929
|
}
|
|
5940
|
-
return objectSchemaToObjectComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5941
|
-
}
|
|
5942
|
-
if (isIntegerSchema(schema)) {
|
|
5943
|
-
return integerSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5944
|
-
}
|
|
5945
|
-
if (isNumberSchema(schema)) {
|
|
5946
|
-
return numberSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5947
|
-
}
|
|
5948
|
-
if (isStringSchema(schema)) {
|
|
5949
|
-
return stringSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5950
|
-
}
|
|
5951
|
-
if (isArraySchema(schema)) {
|
|
5952
|
-
return arraySchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5953
5930
|
}
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5931
|
+
};
|
|
5932
|
+
var getCachedOrFetch = async (requestParams, requestCache, httpClient) => {
|
|
5933
|
+
const cachedPromise = requestCache.get(requestParams);
|
|
5934
|
+
if (cachedPromise) {
|
|
5935
|
+
const cachedResponse = await cachedPromise;
|
|
5936
|
+
if (cachedResponse == null ? void 0 : cachedResponse.ok) {
|
|
5937
|
+
return cachedResponse;
|
|
5959
5938
|
}
|
|
5960
|
-
return blobSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5961
5939
|
}
|
|
5962
|
-
|
|
5940
|
+
return makeSafeHttpClient(httpClient)(...requestParams);
|
|
5963
5941
|
};
|
|
5964
5942
|
|
|
5965
|
-
// src/
|
|
5966
|
-
var
|
|
5967
|
-
const
|
|
5968
|
-
|
|
5943
|
+
// src/controller/executeSubmission.ts
|
|
5944
|
+
var executeSubmission = async (props) => {
|
|
5945
|
+
const { httpClient, requestCache, trackEvent, logEvent } = props;
|
|
5946
|
+
const triggerAction = async (action, model, isInitial) => {
|
|
5969
5947
|
var _a, _b;
|
|
5970
|
-
const
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
}
|
|
5987
|
-
|
|
5988
|
-
// src/domain/mappers/mapToolbarToComponent.ts
|
|
5989
|
-
var mapToolbarToComponent = (uid, toolbar, mapperProps) => {
|
|
5990
|
-
if (!toolbar) {
|
|
5991
|
-
return void 0;
|
|
5992
|
-
}
|
|
5993
|
-
const { onBehavior } = mapperProps;
|
|
5994
|
-
return __spreadProps(__spreadValues({}, toolbar), {
|
|
5995
|
-
type: "toolbar",
|
|
5996
|
-
uid: `${uid}.toolbar`,
|
|
5997
|
-
tags: toolbar.tags,
|
|
5998
|
-
items: toolbar.items.map((item) => {
|
|
5999
|
-
const context = item.context ? mapLegacyContext(item.context) : void 0;
|
|
6000
|
-
const behavior = getDomainLayerBehavior(
|
|
6001
|
-
{ behavior: item.behavior },
|
|
6002
|
-
[],
|
|
6003
|
-
mapperProps.registerSubmissionBehavior
|
|
6004
|
-
);
|
|
6005
|
-
return __spreadProps(__spreadValues({}, item), {
|
|
6006
|
-
context: context ? mapLegacyContext(context) : void 0,
|
|
6007
|
-
disabled: !!item.disabled,
|
|
6008
|
-
tags: item.tags,
|
|
6009
|
-
onClick: () => {
|
|
6010
|
-
void onBehavior(behavior);
|
|
6011
|
-
}
|
|
5948
|
+
const { exit, url, result = null, id: actionId } = action;
|
|
5949
|
+
const trackSubmissionEvent = !isInitial ? trackEvent : () => {
|
|
5950
|
+
};
|
|
5951
|
+
trackSubmissionEvent("Action Triggered", { actionId });
|
|
5952
|
+
if (exit && !url) {
|
|
5953
|
+
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
5954
|
+
return { type: "complete", result };
|
|
5955
|
+
}
|
|
5956
|
+
try {
|
|
5957
|
+
const command = await executeRequest({
|
|
5958
|
+
exit,
|
|
5959
|
+
request: createRequestFromAction(action, model),
|
|
5960
|
+
requestCache,
|
|
5961
|
+
httpClient,
|
|
5962
|
+
trackEvent: (name, properties) => {
|
|
5963
|
+
trackSubmissionEvent(name, __spreadProps(__spreadValues({}, properties), { actionId }));
|
|
5964
|
+
},
|
|
5965
|
+
logEvent
|
|
6012
5966
|
});
|
|
6013
|
-
|
|
5967
|
+
switch (command.type) {
|
|
5968
|
+
case "error": {
|
|
5969
|
+
trackSubmissionEvent("Action Failed", __spreadValues({
|
|
5970
|
+
actionId,
|
|
5971
|
+
statusCode: (_a = command.httpError) == null ? void 0 : _a.statusCode
|
|
5972
|
+
}, (_b = command.body) == null ? void 0 : _b.analytics));
|
|
5973
|
+
return command;
|
|
5974
|
+
}
|
|
5975
|
+
case "behavior": {
|
|
5976
|
+
if (command.behavior.type === "action") {
|
|
5977
|
+
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
5978
|
+
return await executeSubmission({
|
|
5979
|
+
action: command.behavior.action,
|
|
5980
|
+
isInitial: false,
|
|
5981
|
+
model: null,
|
|
5982
|
+
requestCache,
|
|
5983
|
+
httpClient,
|
|
5984
|
+
trackEvent,
|
|
5985
|
+
logEvent
|
|
5986
|
+
});
|
|
5987
|
+
}
|
|
5988
|
+
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
5989
|
+
return command;
|
|
5990
|
+
}
|
|
5991
|
+
case "complete": {
|
|
5992
|
+
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
5993
|
+
return __spreadProps(__spreadValues({}, command), { result: recursiveMerge(command.result, result) });
|
|
5994
|
+
}
|
|
5995
|
+
default: {
|
|
5996
|
+
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
5997
|
+
return command;
|
|
5998
|
+
}
|
|
5999
|
+
}
|
|
6000
|
+
} catch (error) {
|
|
6001
|
+
const errorMessage = getErrorMessage(error);
|
|
6002
|
+
trackSubmissionEvent("Action Failed", { actionId, errorMessage });
|
|
6003
|
+
logEvent("error", "Dynamic Flow - Action Failed Unexpectedly", { actionId, errorMessage });
|
|
6004
|
+
throw error;
|
|
6005
|
+
}
|
|
6006
|
+
};
|
|
6007
|
+
return triggerAction(props.action, props.model, props.isInitial);
|
|
6008
|
+
};
|
|
6009
|
+
var createRequestFromAction = (action, model) => {
|
|
6010
|
+
var _a, _b, _c;
|
|
6011
|
+
return __spreadProps(__spreadValues({}, action), {
|
|
6012
|
+
url: (_a = action.url) != null ? _a : "",
|
|
6013
|
+
method: (_b = action.method) != null ? _b : "POST",
|
|
6014
|
+
body: action.method === "GET" ? void 0 : recursiveMerge(model, (_c = action.data) != null ? _c : null)
|
|
6014
6015
|
});
|
|
6015
6016
|
};
|
|
6016
6017
|
|
|
6017
|
-
// src/domain/
|
|
6018
|
-
var
|
|
6019
|
-
|
|
6018
|
+
// src/domain/features/prefetch/request-cache.ts
|
|
6019
|
+
var makeRequestCacheWithParent = (parent) => {
|
|
6020
|
+
const map = /* @__PURE__ */ new Map();
|
|
6021
|
+
const cache = {
|
|
6022
|
+
get: (requestParams) => {
|
|
6023
|
+
var _a;
|
|
6024
|
+
const key = makeKey(requestParams);
|
|
6025
|
+
const promise = (_a = map.get(key)) != null ? _a : parent == null ? void 0 : parent.get(requestParams);
|
|
6026
|
+
map.delete(key);
|
|
6027
|
+
return promise;
|
|
6028
|
+
},
|
|
6029
|
+
set: (requestParams, responsePromise) => {
|
|
6030
|
+
return map.set(makeKey(requestParams), responsePromise);
|
|
6031
|
+
}
|
|
6032
|
+
};
|
|
6033
|
+
return cache;
|
|
6020
6034
|
};
|
|
6021
|
-
var
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
return {
|
|
6032
|
-
pinned: [...acc.pinned, ...leftChildren.pinned, ...rightChildren.pinned],
|
|
6033
|
-
nonPinned: [
|
|
6034
|
-
...acc.nonPinned,
|
|
6035
|
-
__spreadProps(__spreadValues({}, layout), {
|
|
6036
|
-
left: leftChildren.nonPinned,
|
|
6037
|
-
right: rightChildren.nonPinned
|
|
6038
|
-
})
|
|
6039
|
-
]
|
|
6040
|
-
};
|
|
6035
|
+
var makeRequestCache = (initialValues = []) => {
|
|
6036
|
+
const cache = makeRequestCacheWithParent(void 0);
|
|
6037
|
+
initialValues.forEach(([requestParams, responsePromise]) => {
|
|
6038
|
+
cache.set(requestParams, responsePromise);
|
|
6039
|
+
});
|
|
6040
|
+
return cache;
|
|
6041
|
+
};
|
|
6042
|
+
var normaliseRequestCache = (cache) => {
|
|
6043
|
+
if (cache === void 0) {
|
|
6044
|
+
return makeRequestCache();
|
|
6041
6045
|
}
|
|
6042
|
-
if (
|
|
6043
|
-
|
|
6044
|
-
return {
|
|
6045
|
-
pinned: [...acc.pinned, ...childComponents.pinned],
|
|
6046
|
-
nonPinned: [
|
|
6047
|
-
...acc.nonPinned,
|
|
6048
|
-
__spreadProps(__spreadValues({}, layout), {
|
|
6049
|
-
components: childComponents.nonPinned
|
|
6050
|
-
})
|
|
6051
|
-
]
|
|
6052
|
-
};
|
|
6046
|
+
if (isRequestCacheInstance(cache)) {
|
|
6047
|
+
return cache;
|
|
6053
6048
|
}
|
|
6054
|
-
return
|
|
6055
|
-
|
|
6056
|
-
|
|
6049
|
+
return makeRequestCache(cache);
|
|
6050
|
+
};
|
|
6051
|
+
var isRequestCacheInstance = (cache) => {
|
|
6052
|
+
return !cache || !Array.isArray(cache);
|
|
6053
|
+
};
|
|
6054
|
+
var makeKey = (requestParams) => {
|
|
6055
|
+
var _a, _b;
|
|
6056
|
+
const [input, init] = requestParams;
|
|
6057
|
+
const url = typeof input === "string" || input instanceof URL ? input.toString() : input.url;
|
|
6058
|
+
const key = JSON.stringify({
|
|
6059
|
+
url,
|
|
6060
|
+
method: (_a = init == null ? void 0 : init.method) != null ? _a : "GET",
|
|
6061
|
+
headers: (init == null ? void 0 : init.headers) ? Array.from(new Headers(init.headers).entries()) : [],
|
|
6062
|
+
body: (_b = init == null ? void 0 : init.body) != null ? _b : null
|
|
6063
|
+
});
|
|
6064
|
+
return key;
|
|
6065
|
+
};
|
|
6066
|
+
|
|
6067
|
+
// src/domain/features/prefetch/getStepPrefetch.ts
|
|
6068
|
+
var getStepPrefetch = (httpClient, flowRequestCache, submissionBehaviors) => {
|
|
6069
|
+
const requestCache = makeRequestCacheWithParent(flowRequestCache);
|
|
6070
|
+
const start = (model) => {
|
|
6071
|
+
submissionBehaviors.forEach((behavior) => {
|
|
6072
|
+
const request = behavior.type === "action" ? createRequestFromAction(behavior.action, model) : behavior.launchConfig.request;
|
|
6073
|
+
const requestParams = [
|
|
6074
|
+
request.url,
|
|
6075
|
+
{
|
|
6076
|
+
body: JSON.stringify(request.body),
|
|
6077
|
+
method: request.method,
|
|
6078
|
+
headers: { "Content-Type": "application/json" }
|
|
6079
|
+
}
|
|
6080
|
+
];
|
|
6081
|
+
try {
|
|
6082
|
+
const responsePromise = httpClient(...requestParams).catch(() => null);
|
|
6083
|
+
requestCache.set(requestParams, responsePromise);
|
|
6084
|
+
} catch (e) {
|
|
6085
|
+
}
|
|
6086
|
+
});
|
|
6057
6087
|
};
|
|
6088
|
+
const stop = () => {
|
|
6089
|
+
};
|
|
6090
|
+
return { requestCache, start, stop };
|
|
6058
6091
|
};
|
|
6059
|
-
var hasChildren = (component) => "components" in component;
|
|
6060
|
-
var hasColumns = (component) => "right" in component && "left" in component;
|
|
6061
6092
|
|
|
6062
6093
|
// src/domain/mappers/mapStepToComponent.ts
|
|
6063
6094
|
var mapStepToComponent = (_a) => {
|
|
@@ -6091,7 +6122,6 @@ var mapStepToComponent = (_a) => {
|
|
|
6091
6122
|
title,
|
|
6092
6123
|
tags
|
|
6093
6124
|
} = step;
|
|
6094
|
-
const requestCache = makeRequestCacheWithParent(flowRequestCache);
|
|
6095
6125
|
const submissionBehaviors = [];
|
|
6096
6126
|
const registerSubmissionBehavior = (behavior) => {
|
|
6097
6127
|
if (behavior.type === "action" && behavior.action.prefetch) {
|
|
@@ -6115,6 +6145,7 @@ var mapStepToComponent = (_a) => {
|
|
|
6115
6145
|
registerSubmissionBehavior
|
|
6116
6146
|
}) : void 0;
|
|
6117
6147
|
const stepRefreshAfter = refreshAfter ? getStepRefreshAfter({ refreshAfter, logEvent, onBehavior }) : void 0;
|
|
6148
|
+
const stepPrefetch = getStepPrefetch(restProps.httpClient, flowRequestCache, submissionBehaviors);
|
|
6118
6149
|
const externalConfirmation = (external == null ? void 0 : external.url) ? createExternalConfirmation(`${uid}-external-confirmation`, external == null ? void 0 : external.url, onComponentUpdate) : void 0;
|
|
6119
6150
|
const mapperProps = __spreadProps(__spreadValues({}, restProps), { trackEvent, onBehavior, registerSubmissionBehavior });
|
|
6120
6151
|
const referencedSchemaIds = getReferencedSchemaId(step);
|
|
@@ -6151,18 +6182,12 @@ var mapStepToComponent = (_a) => {
|
|
|
6151
6182
|
title,
|
|
6152
6183
|
tags,
|
|
6153
6184
|
stackBehavior: (_a2 = navigation == null ? void 0 : navigation.stackBehavior) != null ? _a2 : "default",
|
|
6154
|
-
|
|
6185
|
+
stepPrefetch,
|
|
6155
6186
|
step,
|
|
6156
6187
|
onComponentUpdate,
|
|
6157
6188
|
trackEvent,
|
|
6158
6189
|
onBehavior
|
|
6159
6190
|
});
|
|
6160
|
-
executePrefetch({
|
|
6161
|
-
httpClient: mapperProps.httpClient,
|
|
6162
|
-
model: stepComponent.getSubmittableValueSync(),
|
|
6163
|
-
behaviors: submissionBehaviors,
|
|
6164
|
-
requestCache
|
|
6165
|
-
});
|
|
6166
6191
|
return stepComponent;
|
|
6167
6192
|
};
|
|
6168
6193
|
var getReferencedSchemaId = (step) => {
|
|
@@ -6183,25 +6208,6 @@ var mapBackNavigation = (navigation, onBehavior, isNativeBackEnabled) => {
|
|
|
6183
6208
|
}
|
|
6184
6209
|
} : void 0;
|
|
6185
6210
|
};
|
|
6186
|
-
var executePrefetch = (props) => {
|
|
6187
|
-
const { httpClient, behaviors: submissionBehaviors, model, requestCache } = props;
|
|
6188
|
-
submissionBehaviors.forEach((behavior) => {
|
|
6189
|
-
const request = behavior.type === "action" ? createRequestFromAction(behavior.action, model) : behavior.launchConfig.request;
|
|
6190
|
-
const requestParams = [
|
|
6191
|
-
request.url,
|
|
6192
|
-
{
|
|
6193
|
-
body: JSON.stringify(request.body),
|
|
6194
|
-
method: request.method,
|
|
6195
|
-
headers: { "Content-Type": "application/json" }
|
|
6196
|
-
}
|
|
6197
|
-
];
|
|
6198
|
-
try {
|
|
6199
|
-
const responsePromise = httpClient(...requestParams).catch(() => null);
|
|
6200
|
-
requestCache.set(requestParams, responsePromise);
|
|
6201
|
-
} catch (e) {
|
|
6202
|
-
}
|
|
6203
|
-
});
|
|
6204
|
-
};
|
|
6205
6211
|
var getLayoutAndFooter = (step, features) => {
|
|
6206
6212
|
var _a;
|
|
6207
6213
|
if (step.footer) {
|
|
@@ -6807,21 +6813,24 @@ var createFlowController = (props) => {
|
|
|
6807
6813
|
return false;
|
|
6808
6814
|
}
|
|
6809
6815
|
};
|
|
6810
|
-
let
|
|
6816
|
+
let initState = "initial";
|
|
6811
6817
|
if (initialStep) {
|
|
6812
|
-
|
|
6818
|
+
initState = "created";
|
|
6813
6819
|
trackEvent("Initiated");
|
|
6814
6820
|
createStep(initialStep, null);
|
|
6815
6821
|
trackEvent("Step Shown", { isFirstStep: true });
|
|
6816
6822
|
}
|
|
6817
6823
|
const start = () => {
|
|
6818
|
-
if (
|
|
6819
|
-
|
|
6824
|
+
if (initState === "initial" && initialAction) {
|
|
6825
|
+
initState = "created";
|
|
6820
6826
|
trackEvent("Initiated");
|
|
6821
6827
|
rootComponent.setLoadingState("submitting");
|
|
6822
6828
|
void onAction(__spreadValues({ method: "GET" }, initialAction), null);
|
|
6823
6829
|
}
|
|
6824
|
-
|
|
6830
|
+
if (initState === "created") {
|
|
6831
|
+
initState = "started";
|
|
6832
|
+
rootComponent.start();
|
|
6833
|
+
}
|
|
6825
6834
|
};
|
|
6826
6835
|
return {
|
|
6827
6836
|
rootComponent,
|