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