@wise/dynamic-flow-client 5.5.1 → 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 +776 -759
- package/build/main.mjs +776 -759
- package/build/types/controller/FlowController.d.ts +1 -0
- 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/domain/mappers/utils/layout-utils.d.ts +6 -1
- package/build/types/index.d.ts +1 -1
- package/build/types/types.d.ts +1 -1
- package/package.json +4 -4
package/build/main.js
CHANGED
|
@@ -1337,9 +1337,10 @@ var createBoxComponent = (boxProps) => __spreadProps(__spreadValues({}, boxProps
|
|
|
1337
1337
|
});
|
|
1338
1338
|
|
|
1339
1339
|
// src/domain/mappers/utils/layout-utils.ts
|
|
1340
|
-
var
|
|
1341
|
-
return
|
|
1342
|
-
margin
|
|
1340
|
+
var normaliseMarginInLastComponent = (container) => {
|
|
1341
|
+
return container.map((component, index) => {
|
|
1342
|
+
const shouldRemoveMargin = index === container.length - 1 && component.margin === void 0;
|
|
1343
|
+
return shouldRemoveMargin ? __spreadProps(__spreadValues({}, component), { margin: "xs" }) : component;
|
|
1343
1344
|
});
|
|
1344
1345
|
};
|
|
1345
1346
|
|
|
@@ -1352,16 +1353,9 @@ var boxLayoutToComponent = (uid, { border = false, components, control, margin,
|
|
|
1352
1353
|
margin: margin != null ? margin : "md",
|
|
1353
1354
|
width: width != null ? width : "xl",
|
|
1354
1355
|
tags,
|
|
1355
|
-
components: components.map(
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
return mapLayoutToComponent(
|
|
1359
|
-
`${uid}.box-${index}`,
|
|
1360
|
-
componentWithAdjustedMargin,
|
|
1361
|
-
mapperProps,
|
|
1362
|
-
schemaComponents
|
|
1363
|
-
);
|
|
1364
|
-
})
|
|
1356
|
+
components: normaliseMarginInLastComponent(components).map(
|
|
1357
|
+
(component, index) => mapLayoutToComponent(`${uid}.box-${index}`, component, mapperProps, schemaComponents)
|
|
1358
|
+
)
|
|
1365
1359
|
});
|
|
1366
1360
|
|
|
1367
1361
|
// src/domain/components/ButtonComponent.ts
|
|
@@ -2323,6 +2317,35 @@ var modalToComponent = (uid, { content, title }, mapperProps, schemaComponents)
|
|
|
2323
2317
|
mapperProps.onComponentUpdate
|
|
2324
2318
|
);
|
|
2325
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
|
+
|
|
2326
2349
|
// src/utils/recursiveMerge.ts
|
|
2327
2350
|
function recursiveMerge(valueA, valueB) {
|
|
2328
2351
|
if (valueA === null) {
|
|
@@ -2362,526 +2385,162 @@ function mergeArrays(valueA, valueB) {
|
|
|
2362
2385
|
);
|
|
2363
2386
|
}
|
|
2364
2387
|
|
|
2365
|
-
// src/
|
|
2366
|
-
var
|
|
2367
|
-
|
|
2368
|
-
|
|
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);
|
|
2369
2394
|
|
|
2370
|
-
// src/
|
|
2371
|
-
var
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
}
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
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;
|
|
2386
2463
|
};
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
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");
|
|
2395
2478
|
}
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
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");
|
|
2400
2506
|
return;
|
|
2401
2507
|
}
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
}
|
|
2407
|
-
function assertSubflowResponseBody(body) {
|
|
2408
|
-
const { valid } = (0, import_spec.validateSubflowResponse)(body);
|
|
2409
|
-
if (valid) {
|
|
2410
|
-
return;
|
|
2411
|
-
}
|
|
2412
|
-
throw new Error("Incorrect response body in subflow response.");
|
|
2413
|
-
}
|
|
2414
|
-
function isErrorResponseBody(body) {
|
|
2415
|
-
return Boolean(
|
|
2416
|
-
isObject(body) && (body.refreshFormUrl || body.refreshUrl || body.validation || body.error || body.analytics)
|
|
2417
|
-
);
|
|
2418
|
-
}
|
|
2419
|
-
function assertStepResponseBody(body) {
|
|
2420
|
-
if (!isObject(body)) {
|
|
2421
|
-
throw new Error("Incorrect response body in step response. Expected an object.");
|
|
2422
|
-
}
|
|
2423
|
-
}
|
|
2424
|
-
var assertResponseIsValid = (response) => {
|
|
2425
|
-
if (!isResponse(response)) {
|
|
2426
|
-
throw new Error("Incorrect type of response from fetch. Expected object of type Response.");
|
|
2427
|
-
}
|
|
2428
|
-
if (response.bodyUsed) {
|
|
2429
|
-
throw new Error(
|
|
2430
|
-
"The body of the provided Response object has already been used. Every request must respond with a new Response object."
|
|
2431
|
-
);
|
|
2432
|
-
}
|
|
2508
|
+
clearTimeout(intervalRef);
|
|
2509
|
+
abortController.abort();
|
|
2510
|
+
};
|
|
2511
|
+
return { start, stop };
|
|
2433
2512
|
};
|
|
2434
|
-
var isResponse = (response) => typeof response === "object" && response !== null && "clone" in response && "bodyUsed" in response;
|
|
2435
2513
|
|
|
2436
|
-
// src/
|
|
2437
|
-
var
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
httpError: { statusCode: response.status }
|
|
2448
|
-
};
|
|
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)}`);
|
|
2449
2525
|
}
|
|
2450
|
-
|
|
2451
|
-
|
|
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
|
+
};
|
|
2452
2532
|
return {
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
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);
|
|
2457
2540
|
}
|
|
2458
2541
|
};
|
|
2459
2542
|
};
|
|
2460
2543
|
|
|
2461
|
-
// src/controller/getResponseType.ts
|
|
2462
|
-
var responseTypes = ["step", "action", "exit", "modal", "subflow"];
|
|
2463
|
-
var getResponseType = (headers, body) => {
|
|
2464
|
-
const headerResponseType = getResponseTypeFromHeader(headers);
|
|
2465
|
-
if (headerResponseType) {
|
|
2466
|
-
return headerResponseType;
|
|
2467
|
-
}
|
|
2468
|
-
if (isObject(body) && body.action) {
|
|
2469
|
-
return "action";
|
|
2470
|
-
}
|
|
2471
|
-
return "step";
|
|
2472
|
-
};
|
|
2473
|
-
var getResponseTypeFromHeader = (headers) => {
|
|
2474
|
-
if (headers == null ? void 0 : headers.has("X-Df-Response-Type")) {
|
|
2475
|
-
const type = headers.get("X-Df-Response-Type");
|
|
2476
|
-
assertDFResponseType(type);
|
|
2477
|
-
return type;
|
|
2478
|
-
}
|
|
2479
|
-
if (headers == null ? void 0 : headers.has("X-Df-Exit")) {
|
|
2480
|
-
return "exit";
|
|
2481
|
-
}
|
|
2482
|
-
return void 0;
|
|
2483
|
-
};
|
|
2484
|
-
function assertDFResponseType(type) {
|
|
2485
|
-
if (!responseTypes.includes(type)) {
|
|
2486
|
-
throw new Error(
|
|
2487
|
-
"Unsupported X-Df-Response-Type. Allowed values are 'step', 'action', 'exit', 'error', 'modal', 'subflow'."
|
|
2488
|
-
);
|
|
2489
|
-
}
|
|
2490
|
-
}
|
|
2491
|
-
|
|
2492
|
-
// src/controller/makeSafeHttpClient.ts
|
|
2493
|
-
var makeSafeHttpClient = (httpClient) => async (...props) => {
|
|
2494
|
-
try {
|
|
2495
|
-
return await httpClient(...props);
|
|
2496
|
-
} catch (e) {
|
|
2497
|
-
return null;
|
|
2498
|
-
}
|
|
2499
|
-
};
|
|
2500
|
-
|
|
2501
|
-
// src/controller/executeRequest.ts
|
|
2502
|
-
var executeRequest = async (props) => {
|
|
2503
|
-
const { exit, request, requestCache, httpClient, trackEvent, logEvent } = props;
|
|
2504
|
-
const { url, method, body } = request;
|
|
2505
|
-
const response = await getCachedOrFetch(
|
|
2506
|
-
[
|
|
2507
|
-
url,
|
|
2508
|
-
{
|
|
2509
|
-
method,
|
|
2510
|
-
body: body ? JSON.stringify(body) : void 0,
|
|
2511
|
-
headers: { "Content-Type": "application/json" }
|
|
2512
|
-
}
|
|
2513
|
-
],
|
|
2514
|
-
requestCache,
|
|
2515
|
-
httpClient
|
|
2516
|
-
);
|
|
2517
|
-
if (!response) {
|
|
2518
|
-
const extra = { errorMessage: "Network Error" };
|
|
2519
|
-
trackEvent("Request Failed", extra);
|
|
2520
|
-
logEvent("error", "Dynamic Flow - Request Failed Unexpectedly", extra);
|
|
2521
|
-
return { type: "error" };
|
|
2522
|
-
}
|
|
2523
|
-
if (!response.ok) {
|
|
2524
|
-
return handleErrorResponse(response, void 0, trackEvent);
|
|
2525
|
-
}
|
|
2526
|
-
const responseBody = await parseResponseBodyAsJsonElement(response);
|
|
2527
|
-
const responseType = getResponseType(response.headers, responseBody);
|
|
2528
|
-
if (exit) {
|
|
2529
|
-
return { type: "complete", result: responseBody };
|
|
2530
|
-
}
|
|
2531
|
-
switch (responseType) {
|
|
2532
|
-
case "step": {
|
|
2533
|
-
const etag = response.headers.get("etag") || null;
|
|
2534
|
-
assertStepResponseBody(responseBody);
|
|
2535
|
-
return { type: "replace-step", step: responseBody, etag };
|
|
2536
|
-
}
|
|
2537
|
-
case "exit": {
|
|
2538
|
-
return { type: "complete", result: responseBody };
|
|
2539
|
-
}
|
|
2540
|
-
case "action": {
|
|
2541
|
-
assertActionResponseBody(responseBody);
|
|
2542
|
-
return {
|
|
2543
|
-
type: "behavior",
|
|
2544
|
-
behavior: {
|
|
2545
|
-
type: "action",
|
|
2546
|
-
action: responseBody.action
|
|
2547
|
-
}
|
|
2548
|
-
};
|
|
2549
|
-
}
|
|
2550
|
-
case "subflow": {
|
|
2551
|
-
assertSubflowResponseBody(responseBody);
|
|
2552
|
-
return {
|
|
2553
|
-
type: "behavior",
|
|
2554
|
-
behavior: __spreadProps(__spreadValues({}, responseBody), {
|
|
2555
|
-
type: "subflow",
|
|
2556
|
-
onCompletion: responseBody.onCompletion ? normaliseBehavior(responseBody.onCompletion, []) : void 0,
|
|
2557
|
-
onError: responseBody.onError ? normaliseBehavior(responseBody.onError, []) : void 0
|
|
2558
|
-
})
|
|
2559
|
-
};
|
|
2560
|
-
}
|
|
2561
|
-
case "modal": {
|
|
2562
|
-
assertModalResponseBody(responseBody);
|
|
2563
|
-
return { type: "behavior", behavior: __spreadProps(__spreadValues({}, responseBody), { type: "modal" }) };
|
|
2564
|
-
}
|
|
2565
|
-
default: {
|
|
2566
|
-
throw new Error(`Unsupported response type: ${String(responseType)}`);
|
|
2567
|
-
}
|
|
2568
|
-
}
|
|
2569
|
-
};
|
|
2570
|
-
var getCachedOrFetch = async (requestParams, requestCache, httpClient) => {
|
|
2571
|
-
const cachedPromise = requestCache.get(requestParams);
|
|
2572
|
-
if (cachedPromise) {
|
|
2573
|
-
const cachedResponse = await cachedPromise;
|
|
2574
|
-
if (cachedResponse == null ? void 0 : cachedResponse.ok) {
|
|
2575
|
-
return cachedResponse;
|
|
2576
|
-
}
|
|
2577
|
-
}
|
|
2578
|
-
return makeSafeHttpClient(httpClient)(...requestParams);
|
|
2579
|
-
};
|
|
2580
|
-
|
|
2581
|
-
// src/controller/executeSubmission.ts
|
|
2582
|
-
var executeSubmission = async (props) => {
|
|
2583
|
-
const { httpClient, requestCache, trackEvent, logEvent } = props;
|
|
2584
|
-
const triggerAction = async (action, model, isInitial) => {
|
|
2585
|
-
var _a, _b;
|
|
2586
|
-
const { exit, url, result = null, id: actionId } = action;
|
|
2587
|
-
const trackSubmissionEvent = !isInitial ? trackEvent : () => {
|
|
2588
|
-
};
|
|
2589
|
-
trackSubmissionEvent("Action Triggered", { actionId });
|
|
2590
|
-
if (exit && !url) {
|
|
2591
|
-
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
2592
|
-
return { type: "complete", result };
|
|
2593
|
-
}
|
|
2594
|
-
try {
|
|
2595
|
-
const command = await executeRequest({
|
|
2596
|
-
exit,
|
|
2597
|
-
request: createRequestFromAction(action, model),
|
|
2598
|
-
requestCache,
|
|
2599
|
-
httpClient,
|
|
2600
|
-
trackEvent: (name, properties) => {
|
|
2601
|
-
trackSubmissionEvent(name, __spreadProps(__spreadValues({}, properties), { actionId }));
|
|
2602
|
-
},
|
|
2603
|
-
logEvent
|
|
2604
|
-
});
|
|
2605
|
-
switch (command.type) {
|
|
2606
|
-
case "error": {
|
|
2607
|
-
trackSubmissionEvent("Action Failed", __spreadValues({
|
|
2608
|
-
actionId,
|
|
2609
|
-
statusCode: (_a = command.httpError) == null ? void 0 : _a.statusCode
|
|
2610
|
-
}, (_b = command.body) == null ? void 0 : _b.analytics));
|
|
2611
|
-
return command;
|
|
2612
|
-
}
|
|
2613
|
-
case "behavior": {
|
|
2614
|
-
if (command.behavior.type === "action") {
|
|
2615
|
-
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
2616
|
-
return await executeRequest({
|
|
2617
|
-
request: createRequestFromAction(command.behavior.action, null),
|
|
2618
|
-
requestCache,
|
|
2619
|
-
httpClient,
|
|
2620
|
-
trackEvent,
|
|
2621
|
-
logEvent
|
|
2622
|
-
});
|
|
2623
|
-
}
|
|
2624
|
-
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
2625
|
-
return command;
|
|
2626
|
-
}
|
|
2627
|
-
case "complete": {
|
|
2628
|
-
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
2629
|
-
return __spreadProps(__spreadValues({}, command), { result: recursiveMerge(command.result, result) });
|
|
2630
|
-
}
|
|
2631
|
-
default: {
|
|
2632
|
-
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
2633
|
-
return command;
|
|
2634
|
-
}
|
|
2635
|
-
}
|
|
2636
|
-
} catch (error) {
|
|
2637
|
-
const errorMessage = getErrorMessage(error);
|
|
2638
|
-
trackSubmissionEvent("Action Failed", { actionId, errorMessage });
|
|
2639
|
-
logEvent("error", "Dynamic Flow - Action Failed Unexpectedly", { actionId, errorMessage });
|
|
2640
|
-
throw error;
|
|
2641
|
-
}
|
|
2642
|
-
};
|
|
2643
|
-
return triggerAction(props.action, props.model, props.isInitial);
|
|
2644
|
-
};
|
|
2645
|
-
var createRequestFromAction = (action, model) => {
|
|
2646
|
-
var _a, _b, _c;
|
|
2647
|
-
return __spreadProps(__spreadValues({}, action), {
|
|
2648
|
-
url: (_a = action.url) != null ? _a : "",
|
|
2649
|
-
method: (_b = action.method) != null ? _b : "POST",
|
|
2650
|
-
body: action.method === "GET" ? void 0 : recursiveMerge(model, (_c = action.data) != null ? _c : null)
|
|
2651
|
-
});
|
|
2652
|
-
};
|
|
2653
|
-
|
|
2654
|
-
// src/domain/components/step/ExternalConfirmationComponent.ts
|
|
2655
|
-
var createExternalConfirmation = (uid, url, onComponentUpdate) => {
|
|
2656
|
-
const update = getInputUpdateFunction(onComponentUpdate);
|
|
2657
|
-
return {
|
|
2658
|
-
type: "external-confirmation",
|
|
2659
|
-
kind: "layout",
|
|
2660
|
-
uid,
|
|
2661
|
-
url,
|
|
2662
|
-
status: "initial",
|
|
2663
|
-
onSuccess() {
|
|
2664
|
-
update(this, (draft) => {
|
|
2665
|
-
draft.status = "success";
|
|
2666
|
-
});
|
|
2667
|
-
},
|
|
2668
|
-
onFailure() {
|
|
2669
|
-
if (this.status === "initial") {
|
|
2670
|
-
update(this, (draft) => {
|
|
2671
|
-
draft.status = "failure";
|
|
2672
|
-
});
|
|
2673
|
-
}
|
|
2674
|
-
},
|
|
2675
|
-
onCancel() {
|
|
2676
|
-
update(this, (draft) => {
|
|
2677
|
-
draft.status = "dismissed";
|
|
2678
|
-
});
|
|
2679
|
-
}
|
|
2680
|
-
};
|
|
2681
|
-
};
|
|
2682
|
-
|
|
2683
|
-
// src/utils/component-utils.ts
|
|
2684
|
-
var getSubmittableData = async (components) => Promise.all(components.map(async (component) => component.getSubmittableValue())).then(
|
|
2685
|
-
(values) => values.reduce((acc, value) => recursiveMerge(acc, value), null)
|
|
2686
|
-
);
|
|
2687
|
-
var getSubmittableDataSync = (components) => components.map((component) => component.getSubmittableValueSync()).reduce((acc, value) => recursiveMerge(acc, value), null);
|
|
2688
|
-
var getLocalValues = (components) => components.map((component) => component.getLocalValue()).reduce((acc, value) => recursiveMerge(acc, value), null);
|
|
2689
|
-
|
|
2690
|
-
// src/domain/components/step/StepDomainComponent.ts
|
|
2691
|
-
var createStepComponent = (stepProps) => {
|
|
2692
|
-
const _a = stepProps, { uid, stepPolling, stepRefreshAfter, onComponentUpdate } = _a, rest = __objRest(_a, ["uid", "stepPolling", "stepRefreshAfter", "onComponentUpdate"]);
|
|
2693
|
-
const update = getInputUpdateFunction(onComponentUpdate);
|
|
2694
|
-
const component = __spreadProps(__spreadValues({
|
|
2695
|
-
uid
|
|
2696
|
-
}, rest), {
|
|
2697
|
-
type: "step",
|
|
2698
|
-
kind: "step",
|
|
2699
|
-
modals: [],
|
|
2700
|
-
dismissModal() {
|
|
2701
|
-
var _a2;
|
|
2702
|
-
(_a2 = this.modals.at(-1)) == null ? void 0 : _a2.close();
|
|
2703
|
-
},
|
|
2704
|
-
dismissAllModals() {
|
|
2705
|
-
this._update((draft) => {
|
|
2706
|
-
draft.modals = draft.modals.map((m) => __spreadProps(__spreadValues({}, m), { open: false }));
|
|
2707
|
-
});
|
|
2708
|
-
},
|
|
2709
|
-
showModal(modal) {
|
|
2710
|
-
this._update((draft) => {
|
|
2711
|
-
draft.modals = [...draft.modals, modal];
|
|
2712
|
-
});
|
|
2713
|
-
},
|
|
2714
|
-
_update(updateFn) {
|
|
2715
|
-
update(this, updateFn);
|
|
2716
|
-
},
|
|
2717
|
-
getChildren() {
|
|
2718
|
-
return this.externalConfirmation ? [...this.layoutComponents, this.externalConfirmation] : this.layoutComponents;
|
|
2719
|
-
},
|
|
2720
|
-
getModals() {
|
|
2721
|
-
return this.modals;
|
|
2722
|
-
},
|
|
2723
|
-
async getSubmittableValue() {
|
|
2724
|
-
return getSubmittableData(this.schemaComponents);
|
|
2725
|
-
},
|
|
2726
|
-
getSubmittableValueSync() {
|
|
2727
|
-
return getSubmittableDataSync(this.schemaComponents);
|
|
2728
|
-
},
|
|
2729
|
-
getLocalValue() {
|
|
2730
|
-
return getLocalValues(this.schemaComponents);
|
|
2731
|
-
},
|
|
2732
|
-
validate() {
|
|
2733
|
-
return this.schemaComponents.every(
|
|
2734
|
-
(inputComponent) => inputComponent.isSchemaReferencedInStep ? inputComponent.validate() : true
|
|
2735
|
-
);
|
|
2736
|
-
},
|
|
2737
|
-
setLoadingState(loadingState) {
|
|
2738
|
-
this._update((draft) => {
|
|
2739
|
-
draft.loadingState = loadingState;
|
|
2740
|
-
});
|
|
2741
|
-
},
|
|
2742
|
-
start() {
|
|
2743
|
-
stepPolling == null ? void 0 : stepPolling.start();
|
|
2744
|
-
stepRefreshAfter == null ? void 0 : stepRefreshAfter.start();
|
|
2745
|
-
},
|
|
2746
|
-
stop() {
|
|
2747
|
-
stepPolling == null ? void 0 : stepPolling.stop();
|
|
2748
|
-
stepRefreshAfter == null ? void 0 : stepRefreshAfter.stop();
|
|
2749
|
-
this._update((draft) => {
|
|
2750
|
-
draft.modals = [];
|
|
2751
|
-
});
|
|
2752
|
-
}
|
|
2753
|
-
});
|
|
2754
|
-
return component;
|
|
2755
|
-
};
|
|
2756
|
-
|
|
2757
|
-
// src/domain/features/polling/getStepPolling.ts
|
|
2758
|
-
var getStepPolling = ({
|
|
2759
|
-
pollingConfig,
|
|
2760
|
-
logEvent,
|
|
2761
|
-
onBehavior,
|
|
2762
|
-
onPoll,
|
|
2763
|
-
registerSubmissionBehavior
|
|
2764
|
-
}) => {
|
|
2765
|
-
const { interval, delay = interval, maxAttempts, url, onError } = pollingConfig;
|
|
2766
|
-
let abortController = new AbortController();
|
|
2767
|
-
let intervalRef = null;
|
|
2768
|
-
if (delay == null) {
|
|
2769
|
-
throw new Error("Polling configuration must include delay or interval");
|
|
2770
|
-
}
|
|
2771
|
-
const onErrorBehavior = getDomainLayerBehavior(onError, [], registerSubmissionBehavior);
|
|
2772
|
-
let attempts = 0;
|
|
2773
|
-
const poll = () => {
|
|
2774
|
-
attempts += 1;
|
|
2775
|
-
abortController.abort();
|
|
2776
|
-
abortController = new AbortController();
|
|
2777
|
-
const { signal } = abortController;
|
|
2778
|
-
onPoll(url, onErrorBehavior, signal).then((result) => {
|
|
2779
|
-
if (result) {
|
|
2780
|
-
stop();
|
|
2781
|
-
return;
|
|
2782
|
-
}
|
|
2783
|
-
if (attempts >= maxAttempts && !signal.aborted) {
|
|
2784
|
-
void onBehavior(onErrorBehavior);
|
|
2785
|
-
stop();
|
|
2786
|
-
}
|
|
2787
|
-
}).catch(() => {
|
|
2788
|
-
});
|
|
2789
|
-
};
|
|
2790
|
-
const start = () => {
|
|
2791
|
-
attempts = 0;
|
|
2792
|
-
intervalRef = setInterval(poll, delay * 1e3);
|
|
2793
|
-
poll();
|
|
2794
|
-
};
|
|
2795
|
-
const stop = () => {
|
|
2796
|
-
if (!intervalRef) {
|
|
2797
|
-
logEvent("warning", "Attempted to stop polling but it was not started");
|
|
2798
|
-
return;
|
|
2799
|
-
}
|
|
2800
|
-
clearTimeout(intervalRef);
|
|
2801
|
-
abortController.abort();
|
|
2802
|
-
};
|
|
2803
|
-
return { start, stop };
|
|
2804
|
-
};
|
|
2805
|
-
|
|
2806
|
-
// src/domain/features/refreshAfter/getStepRefreshAfter.ts
|
|
2807
|
-
var ONE_SECOND = 1e3;
|
|
2808
|
-
var getStepRefreshAfter = ({
|
|
2809
|
-
refreshAfter,
|
|
2810
|
-
logEvent,
|
|
2811
|
-
onBehavior
|
|
2812
|
-
}) => {
|
|
2813
|
-
let timeout = null;
|
|
2814
|
-
const targetTime = new Date(refreshAfter).getTime();
|
|
2815
|
-
if (typeof refreshAfter !== "string" || Number.isNaN(targetTime)) {
|
|
2816
|
-
throw new Error(`Invalid refreshAfter value: ${String(refreshAfter)}`);
|
|
2817
|
-
}
|
|
2818
|
-
const start = () => {
|
|
2819
|
-
const timeLeft = Math.max(targetTime - Date.now(), ONE_SECOND);
|
|
2820
|
-
timeout = setTimeout(() => {
|
|
2821
|
-
void onBehavior({ type: "refresh", analytics: { schema: "refreshAfter" } });
|
|
2822
|
-
}, timeLeft);
|
|
2823
|
-
};
|
|
2824
|
-
return {
|
|
2825
|
-
start,
|
|
2826
|
-
stop: () => {
|
|
2827
|
-
if (!timeout) {
|
|
2828
|
-
logEvent("warning", "Attempted to stop refreshAfter but it was not started");
|
|
2829
|
-
return;
|
|
2830
|
-
}
|
|
2831
|
-
clearTimeout(timeout);
|
|
2832
|
-
}
|
|
2833
|
-
};
|
|
2834
|
-
};
|
|
2835
|
-
|
|
2836
|
-
// src/domain/prefetching/request-cache.ts
|
|
2837
|
-
var makeRequestCacheWithParent = (parent) => {
|
|
2838
|
-
const map = /* @__PURE__ */ new Map();
|
|
2839
|
-
const cache = {
|
|
2840
|
-
get: (requestParams) => {
|
|
2841
|
-
var _a;
|
|
2842
|
-
const key = makeKey(requestParams);
|
|
2843
|
-
const promise = (_a = map.get(key)) != null ? _a : parent == null ? void 0 : parent.get(requestParams);
|
|
2844
|
-
map.delete(key);
|
|
2845
|
-
return promise;
|
|
2846
|
-
},
|
|
2847
|
-
set: (requestParams, responsePromise) => {
|
|
2848
|
-
return map.set(makeKey(requestParams), responsePromise);
|
|
2849
|
-
}
|
|
2850
|
-
};
|
|
2851
|
-
return cache;
|
|
2852
|
-
};
|
|
2853
|
-
var makeRequestCache = (initialValues = []) => {
|
|
2854
|
-
const cache = makeRequestCacheWithParent(void 0);
|
|
2855
|
-
initialValues.forEach(([requestParams, responsePromise]) => {
|
|
2856
|
-
cache.set(requestParams, responsePromise);
|
|
2857
|
-
});
|
|
2858
|
-
return cache;
|
|
2859
|
-
};
|
|
2860
|
-
var normaliseRequestCache = (cache) => {
|
|
2861
|
-
if (cache === void 0) {
|
|
2862
|
-
return makeRequestCache();
|
|
2863
|
-
}
|
|
2864
|
-
if (isRequestCacheInstance(cache)) {
|
|
2865
|
-
return cache;
|
|
2866
|
-
}
|
|
2867
|
-
return makeRequestCache(cache);
|
|
2868
|
-
};
|
|
2869
|
-
var isRequestCacheInstance = (cache) => {
|
|
2870
|
-
return !cache || !Array.isArray(cache);
|
|
2871
|
-
};
|
|
2872
|
-
var makeKey = (requestParams) => {
|
|
2873
|
-
var _a, _b;
|
|
2874
|
-
const [input, init] = requestParams;
|
|
2875
|
-
const url = typeof input === "string" || input instanceof URL ? input.toString() : input.url;
|
|
2876
|
-
const key = JSON.stringify({
|
|
2877
|
-
url,
|
|
2878
|
-
method: (_a = init == null ? void 0 : init.method) != null ? _a : "GET",
|
|
2879
|
-
headers: (init == null ? void 0 : init.headers) ? Array.from(new Headers(init.headers).entries()) : [],
|
|
2880
|
-
body: (_b = init == null ? void 0 : init.body) != null ? _b : null
|
|
2881
|
-
});
|
|
2882
|
-
return key;
|
|
2883
|
-
};
|
|
2884
|
-
|
|
2885
2544
|
// src/domain/components/utils/isOrWasValid.ts
|
|
2886
2545
|
var isOrWasValid = (getErrors, previous, current) => {
|
|
2887
2546
|
const wasValid = getErrors(previous).length === 0 && previous !== null;
|
|
@@ -3360,6 +3019,72 @@ var getInitialValidationAsyncState = () => ({
|
|
|
3360
3019
|
messages: {}
|
|
3361
3020
|
});
|
|
3362
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
|
+
|
|
3363
3088
|
// src/domain/features/utils/response-utils.ts
|
|
3364
3089
|
var getAnalyticsFromErrorResponse = (json) => {
|
|
3365
3090
|
if (!isErrorResponseBody(json)) {
|
|
@@ -5841,229 +5566,529 @@ var createTextInputComponent = (textInputProps, onComponentUpdate) => {
|
|
|
5841
5566
|
return inputComponent;
|
|
5842
5567
|
};
|
|
5843
5568
|
|
|
5844
|
-
// src/domain/mappers/schema/stringSchemaToComponent/stringSchemaToTextInputComponent.ts
|
|
5845
|
-
var stringSchemaToTextInputComponent = (schemaMapperProps, mapperProps) => {
|
|
5846
|
-
const { schema, localValue, model, required = false, onPersistAsync } = schemaMapperProps;
|
|
5847
|
-
const {
|
|
5848
|
-
autocapitalization,
|
|
5849
|
-
autocompleteHint,
|
|
5850
|
-
control,
|
|
5851
|
-
default: defaultValue,
|
|
5852
|
-
displayFormat,
|
|
5853
|
-
format,
|
|
5854
|
-
maxLength,
|
|
5855
|
-
minLength,
|
|
5856
|
-
suggestions,
|
|
5857
|
-
validationMessages
|
|
5858
|
-
} = schema;
|
|
5859
|
-
const { getErrorMessageFunctions, onComponentUpdate, onBehavior, onValueChange, logEvent } = mapperProps;
|
|
5860
|
-
const controlForLegacyFormat = getControlForLegacyFormat(format);
|
|
5861
|
-
const errorMessageFunctions = getErrorMessageFunctions(validationMessages);
|
|
5862
|
-
const { performValidationAsync, validationAsyncState } = getValidationAsyncInitialState(
|
|
5863
|
-
schemaMapperProps,
|
|
5864
|
-
mapperProps
|
|
5865
|
-
);
|
|
5866
|
-
const validLocalValue = isString(localValue) ? localValue : null;
|
|
5867
|
-
const validModel = isString(model) ? model : defaultValue != null ? defaultValue : null;
|
|
5868
|
-
const value = onPersistAsync ? validLocalValue : validModel;
|
|
5869
|
-
return createTextInputComponent(
|
|
5870
|
-
__spreadProps(__spreadValues({}, mapCommonSchemaProps(schemaMapperProps)), {
|
|
5871
|
-
autocapitalization,
|
|
5872
|
-
autoComplete: getAutocompleteString(autocompleteHint),
|
|
5873
|
-
checks: schema.hidden ? [] : [
|
|
5874
|
-
getRequiredCheck(required, errorMessageFunctions),
|
|
5875
|
-
getAboveMaxLengthCheck(schema, errorMessageFunctions),
|
|
5876
|
-
getBelowMinLengthCheck(schema, errorMessageFunctions),
|
|
5877
|
-
getNotAdheringToPatternCheck(schema, errorMessageFunctions, { logEvent })
|
|
5878
|
-
],
|
|
5879
|
-
control: control != null ? control : controlForLegacyFormat,
|
|
5880
|
-
displayFormat,
|
|
5881
|
-
maxLength,
|
|
5882
|
-
minLength,
|
|
5883
|
-
suggestions: mapStringSchemaSuggestions(suggestions, mapperProps.logEvent),
|
|
5884
|
-
value,
|
|
5885
|
-
validationAsyncState,
|
|
5886
|
-
schemaOnChange: getSchemaOnChange(schema, onBehavior),
|
|
5887
|
-
performValidationAsync,
|
|
5888
|
-
onValueChange
|
|
5889
|
-
}),
|
|
5890
|
-
onComponentUpdate
|
|
5891
|
-
);
|
|
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
|
+
});
|
|
5746
|
+
};
|
|
5747
|
+
|
|
5748
|
+
// src/domain/mappers/utils/groupLayoutByPinned.ts
|
|
5749
|
+
var groupLayoutByPinned = (layouts) => {
|
|
5750
|
+
return layouts.reduce(groupLayout, { pinned: [], nonPinned: [] });
|
|
5892
5751
|
};
|
|
5893
|
-
var
|
|
5894
|
-
if (
|
|
5895
|
-
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
|
+
};
|
|
5896
5758
|
}
|
|
5897
|
-
|
|
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
|
+
};
|
|
5898
5789
|
};
|
|
5790
|
+
var hasChildren = (component) => "components" in component;
|
|
5791
|
+
var hasColumns = (component) => "right" in component && "left" in component;
|
|
5899
5792
|
|
|
5900
|
-
// src/
|
|
5901
|
-
var
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
|
|
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
|
+
};
|
|
5905
5811
|
}
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
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;
|
|
5911
5829
|
}
|
|
5830
|
+
if (isObject(body) && body.action) {
|
|
5831
|
+
return "action";
|
|
5832
|
+
}
|
|
5833
|
+
return "step";
|
|
5912
5834
|
};
|
|
5913
|
-
var
|
|
5914
|
-
|
|
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;
|
|
5915
5845
|
};
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
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
|
+
);
|
|
5922
5851
|
}
|
|
5923
|
-
|
|
5924
|
-
|
|
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;
|
|
5925
5860
|
}
|
|
5926
|
-
|
|
5927
|
-
|
|
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" };
|
|
5928
5884
|
}
|
|
5929
|
-
if (
|
|
5930
|
-
return
|
|
5885
|
+
if (!response.ok) {
|
|
5886
|
+
return handleErrorResponse(response, void 0, trackEvent);
|
|
5931
5887
|
}
|
|
5932
|
-
|
|
5933
|
-
|
|
5888
|
+
const responseBody = await parseResponseBodyAsJsonElement(response);
|
|
5889
|
+
const responseType = getResponseType(response.headers, responseBody);
|
|
5890
|
+
if (exit) {
|
|
5891
|
+
return { type: "complete", result: responseBody };
|
|
5934
5892
|
}
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
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 };
|
|
5939
5898
|
}
|
|
5940
|
-
|
|
5941
|
-
return
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
);
|
|
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
|
+
};
|
|
5922
|
+
}
|
|
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)}`);
|
|
5945
5929
|
}
|
|
5946
|
-
return objectSchemaToObjectComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5947
|
-
}
|
|
5948
|
-
if (isIntegerSchema(schema)) {
|
|
5949
|
-
return integerSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5950
|
-
}
|
|
5951
|
-
if (isNumberSchema(schema)) {
|
|
5952
|
-
return numberSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5953
|
-
}
|
|
5954
|
-
if (isStringSchema(schema)) {
|
|
5955
|
-
return stringSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5956
|
-
}
|
|
5957
|
-
if (isArraySchema(schema)) {
|
|
5958
|
-
return arraySchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5959
5930
|
}
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
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;
|
|
5965
5938
|
}
|
|
5966
|
-
return blobSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5967
5939
|
}
|
|
5968
|
-
|
|
5940
|
+
return makeSafeHttpClient(httpClient)(...requestParams);
|
|
5969
5941
|
};
|
|
5970
5942
|
|
|
5971
|
-
// src/
|
|
5972
|
-
var
|
|
5973
|
-
const
|
|
5974
|
-
|
|
5943
|
+
// src/controller/executeSubmission.ts
|
|
5944
|
+
var executeSubmission = async (props) => {
|
|
5945
|
+
const { httpClient, requestCache, trackEvent, logEvent } = props;
|
|
5946
|
+
const triggerAction = async (action, model, isInitial) => {
|
|
5975
5947
|
var _a, _b;
|
|
5976
|
-
const
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
}
|
|
5993
|
-
|
|
5994
|
-
// src/domain/mappers/mapToolbarToComponent.ts
|
|
5995
|
-
var mapToolbarToComponent = (uid, toolbar, mapperProps) => {
|
|
5996
|
-
if (!toolbar) {
|
|
5997
|
-
return void 0;
|
|
5998
|
-
}
|
|
5999
|
-
const { onBehavior } = mapperProps;
|
|
6000
|
-
return __spreadProps(__spreadValues({}, toolbar), {
|
|
6001
|
-
type: "toolbar",
|
|
6002
|
-
uid: `${uid}.toolbar`,
|
|
6003
|
-
tags: toolbar.tags,
|
|
6004
|
-
items: toolbar.items.map((item) => {
|
|
6005
|
-
const context = item.context ? mapLegacyContext(item.context) : void 0;
|
|
6006
|
-
const behavior = getDomainLayerBehavior(
|
|
6007
|
-
{ behavior: item.behavior },
|
|
6008
|
-
[],
|
|
6009
|
-
mapperProps.registerSubmissionBehavior
|
|
6010
|
-
);
|
|
6011
|
-
return __spreadProps(__spreadValues({}, item), {
|
|
6012
|
-
context: context ? mapLegacyContext(context) : void 0,
|
|
6013
|
-
disabled: !!item.disabled,
|
|
6014
|
-
tags: item.tags,
|
|
6015
|
-
onClick: () => {
|
|
6016
|
-
void onBehavior(behavior);
|
|
6017
|
-
}
|
|
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
|
|
6018
5966
|
});
|
|
6019
|
-
|
|
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)
|
|
6020
6015
|
});
|
|
6021
6016
|
};
|
|
6022
6017
|
|
|
6023
|
-
// src/domain/
|
|
6024
|
-
var
|
|
6025
|
-
|
|
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;
|
|
6026
6034
|
};
|
|
6027
|
-
var
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
return {
|
|
6038
|
-
pinned: [...acc.pinned, ...leftChildren.pinned, ...rightChildren.pinned],
|
|
6039
|
-
nonPinned: [
|
|
6040
|
-
...acc.nonPinned,
|
|
6041
|
-
__spreadProps(__spreadValues({}, layout), {
|
|
6042
|
-
left: leftChildren.nonPinned,
|
|
6043
|
-
right: rightChildren.nonPinned
|
|
6044
|
-
})
|
|
6045
|
-
]
|
|
6046
|
-
};
|
|
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();
|
|
6047
6045
|
}
|
|
6048
|
-
if (
|
|
6049
|
-
|
|
6050
|
-
return {
|
|
6051
|
-
pinned: [...acc.pinned, ...childComponents.pinned],
|
|
6052
|
-
nonPinned: [
|
|
6053
|
-
...acc.nonPinned,
|
|
6054
|
-
__spreadProps(__spreadValues({}, layout), {
|
|
6055
|
-
components: childComponents.nonPinned
|
|
6056
|
-
})
|
|
6057
|
-
]
|
|
6058
|
-
};
|
|
6046
|
+
if (isRequestCacheInstance(cache)) {
|
|
6047
|
+
return cache;
|
|
6059
6048
|
}
|
|
6060
|
-
return
|
|
6061
|
-
|
|
6062
|
-
|
|
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
|
+
});
|
|
6087
|
+
};
|
|
6088
|
+
const stop = () => {
|
|
6063
6089
|
};
|
|
6090
|
+
return { requestCache, start, stop };
|
|
6064
6091
|
};
|
|
6065
|
-
var hasChildren = (component) => "components" in component;
|
|
6066
|
-
var hasColumns = (component) => "right" in component && "left" in component;
|
|
6067
6092
|
|
|
6068
6093
|
// src/domain/mappers/mapStepToComponent.ts
|
|
6069
6094
|
var mapStepToComponent = (_a) => {
|
|
@@ -6091,14 +6116,12 @@ var mapStepToComponent = (_a) => {
|
|
|
6091
6116
|
errors,
|
|
6092
6117
|
external,
|
|
6093
6118
|
key,
|
|
6094
|
-
layout = [],
|
|
6095
6119
|
navigation,
|
|
6096
6120
|
polling,
|
|
6097
6121
|
refreshAfter,
|
|
6098
6122
|
title,
|
|
6099
6123
|
tags
|
|
6100
6124
|
} = step;
|
|
6101
|
-
const requestCache = makeRequestCacheWithParent(flowRequestCache);
|
|
6102
6125
|
const submissionBehaviors = [];
|
|
6103
6126
|
const registerSubmissionBehavior = (behavior) => {
|
|
6104
6127
|
if (behavior.type === "action" && behavior.action.prefetch) {
|
|
@@ -6122,6 +6145,7 @@ var mapStepToComponent = (_a) => {
|
|
|
6122
6145
|
registerSubmissionBehavior
|
|
6123
6146
|
}) : void 0;
|
|
6124
6147
|
const stepRefreshAfter = refreshAfter ? getStepRefreshAfter({ refreshAfter, logEvent, onBehavior }) : void 0;
|
|
6148
|
+
const stepPrefetch = getStepPrefetch(restProps.httpClient, flowRequestCache, submissionBehaviors);
|
|
6125
6149
|
const externalConfirmation = (external == null ? void 0 : external.url) ? createExternalConfirmation(`${uid}-external-confirmation`, external == null ? void 0 : external.url, onComponentUpdate) : void 0;
|
|
6126
6150
|
const mapperProps = __spreadProps(__spreadValues({}, restProps), { trackEvent, onBehavior, registerSubmissionBehavior });
|
|
6127
6151
|
const referencedSchemaIds = getReferencedSchemaId(step);
|
|
@@ -6132,21 +6156,12 @@ var mapStepToComponent = (_a) => {
|
|
|
6132
6156
|
mapperProps,
|
|
6133
6157
|
referencedSchemaIds
|
|
6134
6158
|
);
|
|
6135
|
-
const
|
|
6136
|
-
const
|
|
6137
|
-
const layoutComponents = nonPinned.map(
|
|
6159
|
+
const { layout, footer } = getLayoutAndFooter(step, features);
|
|
6160
|
+
const layoutComponents = layout.map(
|
|
6138
6161
|
(layoutComponent, index) => mapLayoutToComponent(`${uid}.layout-${index}`, layoutComponent, mapperProps, schemaComponents)
|
|
6139
6162
|
);
|
|
6140
|
-
const footerComponents =
|
|
6141
|
-
|
|
6142
|
-
return shouldRemoveMargin ? removeMarginFromLayout(footerComponent) : footerComponent;
|
|
6143
|
-
}).map(
|
|
6144
|
-
(footerComponent, index) => mapLayoutToComponent(
|
|
6145
|
-
`${uid}.footer-${index}`,
|
|
6146
|
-
footerComponent,
|
|
6147
|
-
mapperProps,
|
|
6148
|
-
schemaComponents
|
|
6149
|
-
)
|
|
6163
|
+
const footerComponents = normaliseMarginInLastComponent(footer).map(
|
|
6164
|
+
(footerComponent, index) => mapLayoutToComponent(`${uid}.footer-${index}`, footerComponent, mapperProps, schemaComponents)
|
|
6150
6165
|
);
|
|
6151
6166
|
const toolbar = mapToolbarToComponent(uid, step.toolbar, mapperProps);
|
|
6152
6167
|
const stepComponent = createStepComponent({
|
|
@@ -6167,18 +6182,12 @@ var mapStepToComponent = (_a) => {
|
|
|
6167
6182
|
title,
|
|
6168
6183
|
tags,
|
|
6169
6184
|
stackBehavior: (_a2 = navigation == null ? void 0 : navigation.stackBehavior) != null ? _a2 : "default",
|
|
6170
|
-
|
|
6185
|
+
stepPrefetch,
|
|
6171
6186
|
step,
|
|
6172
6187
|
onComponentUpdate,
|
|
6173
6188
|
trackEvent,
|
|
6174
6189
|
onBehavior
|
|
6175
6190
|
});
|
|
6176
|
-
executePrefetch({
|
|
6177
|
-
httpClient: mapperProps.httpClient,
|
|
6178
|
-
model: stepComponent.getSubmittableValueSync(),
|
|
6179
|
-
behaviors: submissionBehaviors,
|
|
6180
|
-
requestCache
|
|
6181
|
-
});
|
|
6182
6191
|
return stepComponent;
|
|
6183
6192
|
};
|
|
6184
6193
|
var getReferencedSchemaId = (step) => {
|
|
@@ -6199,24 +6208,18 @@ var mapBackNavigation = (navigation, onBehavior, isNativeBackEnabled) => {
|
|
|
6199
6208
|
}
|
|
6200
6209
|
} : void 0;
|
|
6201
6210
|
};
|
|
6202
|
-
var
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
const
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
try {
|
|
6215
|
-
const responsePromise = httpClient(...requestParams).catch(() => null);
|
|
6216
|
-
requestCache.set(requestParams, responsePromise);
|
|
6217
|
-
} catch (e) {
|
|
6218
|
-
}
|
|
6219
|
-
});
|
|
6211
|
+
var getLayoutAndFooter = (step, features) => {
|
|
6212
|
+
var _a;
|
|
6213
|
+
if (step.footer) {
|
|
6214
|
+
const { layout: layout2 = [], footer = [] } = step;
|
|
6215
|
+
return { layout: layout2, footer };
|
|
6216
|
+
}
|
|
6217
|
+
if (features.isEnabled("pinnedButtons")) {
|
|
6218
|
+
const { pinned: footer, nonPinned: layout2 } = groupLayoutByPinned((_a = step.layout) != null ? _a : []);
|
|
6219
|
+
return { layout: layout2, footer };
|
|
6220
|
+
}
|
|
6221
|
+
const { layout = [] } = step;
|
|
6222
|
+
return { layout, footer: [] };
|
|
6220
6223
|
};
|
|
6221
6224
|
|
|
6222
6225
|
// src/getSubflowCallbacks.ts
|
|
@@ -6810,17 +6813,28 @@ var createFlowController = (props) => {
|
|
|
6810
6813
|
return false;
|
|
6811
6814
|
}
|
|
6812
6815
|
};
|
|
6813
|
-
|
|
6816
|
+
let initState = "initial";
|
|
6814
6817
|
if (initialStep) {
|
|
6818
|
+
initState = "created";
|
|
6819
|
+
trackEvent("Initiated");
|
|
6815
6820
|
createStep(initialStep, null);
|
|
6816
6821
|
trackEvent("Step Shown", { isFirstStep: true });
|
|
6817
|
-
} else if (initialAction) {
|
|
6818
|
-
rootComponent.setLoadingState("submitting");
|
|
6819
|
-
void onAction(__spreadValues({ method: "GET" }, initialAction), null);
|
|
6820
6822
|
}
|
|
6821
|
-
|
|
6823
|
+
const start = () => {
|
|
6824
|
+
if (initState === "initial" && initialAction) {
|
|
6825
|
+
initState = "created";
|
|
6826
|
+
trackEvent("Initiated");
|
|
6827
|
+
rootComponent.setLoadingState("submitting");
|
|
6828
|
+
void onAction(__spreadValues({ method: "GET" }, initialAction), null);
|
|
6829
|
+
}
|
|
6830
|
+
if (initState === "created") {
|
|
6831
|
+
initState = "started";
|
|
6832
|
+
rootComponent.start();
|
|
6833
|
+
}
|
|
6834
|
+
};
|
|
6822
6835
|
return {
|
|
6823
6836
|
rootComponent,
|
|
6837
|
+
start,
|
|
6824
6838
|
cancel: closeWithCancellation
|
|
6825
6839
|
};
|
|
6826
6840
|
};
|
|
@@ -8218,7 +8232,10 @@ var useRerender = () => {
|
|
|
8218
8232
|
};
|
|
8219
8233
|
var useFlowController = (props) => {
|
|
8220
8234
|
const df = (0, import_react3.useMemo)(() => createFlowController(props), []);
|
|
8221
|
-
(0, import_react3.useEffect)(() =>
|
|
8235
|
+
(0, import_react3.useEffect)(() => {
|
|
8236
|
+
df.start();
|
|
8237
|
+
return () => df.rootComponent.stop();
|
|
8238
|
+
}, []);
|
|
8222
8239
|
return df;
|
|
8223
8240
|
};
|
|
8224
8241
|
|