@wise/dynamic-flow-client 5.6.0 → 5.6.2
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/i18n/ja.json +1 -1
- package/build/main.js +772 -738
- package/build/main.mjs +772 -738
- 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 +2 -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 +9 -9
package/build/main.mjs
CHANGED
|
@@ -386,7 +386,7 @@ var ja_default = {
|
|
|
386
386
|
"dynamicFlows.FileUploadSchema.maxFileSizeError": "\u5927\u5909\u7533\u3057\u8A33\u3054\u3056\u3044\u307E\u305B\u3093\u304C\u3001\u30D5\u30A1\u30A4\u30EB\u304C\u5927\u304D\u3059\u304E\u307E\u3059\u3002\u3053\u308C\u3088\u308A\u5C0F\u3055\u3044\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
387
387
|
"dynamicFlows.FileUploadSchema.wrongFileTypeError": "\u305D\u306E\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u5225\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
388
388
|
"dynamicFlows.Help.ariaLabel": "\u8A73\u7D30\u306F\u3053\u3061\u3089\u3092\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
389
|
-
"dynamicFlows.MultiSelect.summary": "{first}\u3068\u305D\u306E\u4ED6{count}",
|
|
389
|
+
"dynamicFlows.MultiSelect.summary": "{first}\u3068\u305D\u306E\u4ED6{count}\u30AA\u30D7\u30B7\u30E7\u30F3",
|
|
390
390
|
"dynamicFlows.MultipleFileUploadSchema.maxFileSizeError": "\u5927\u5909\u7533\u3057\u8A33\u3054\u3056\u3044\u307E\u305B\u3093\u304C\u3001\u30D5\u30A1\u30A4\u30EB\u304C\u5927\u304D\u3059\u304E\u307E\u3059\u3002\u3053\u308C\u3088\u308A\u5C0F\u3055\u3044\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
391
391
|
"dynamicFlows.MultipleFileUploadSchema.maxItemsError": "{maxItems}\u500B\u4EE5\u4E0B\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
392
392
|
"dynamicFlows.MultipleFileUploadSchema.minItemsError": "{minItems}\u500B\u4EE5\u4E0A\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
@@ -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)) {
|
|
@@ -5646,6 +5377,7 @@ var mapStringSchemaSuggestions = (suggestions, logEvent) => {
|
|
|
5646
5377
|
|
|
5647
5378
|
// src/domain/mappers/schema/stringSchemaToComponent/stringSchemaToDateInputComponent.ts
|
|
5648
5379
|
var stringSchemaToDateInputComponent = (schemaMapperProps, mapperProps) => {
|
|
5380
|
+
var _a;
|
|
5649
5381
|
const { schema, localValue, model, required = false, onPersistAsync } = schemaMapperProps;
|
|
5650
5382
|
const {
|
|
5651
5383
|
autocompleteHint,
|
|
@@ -5661,7 +5393,7 @@ var stringSchemaToDateInputComponent = (schemaMapperProps, mapperProps) => {
|
|
|
5661
5393
|
mapperProps
|
|
5662
5394
|
);
|
|
5663
5395
|
const validLocalValue = isString(localValue) ? localValue : null;
|
|
5664
|
-
const validModel =
|
|
5396
|
+
const validModel = (_a = getValidDate(model)) != null ? _a : getValidDate(defaultValue != null ? defaultValue : null);
|
|
5665
5397
|
const value = onPersistAsync ? validLocalValue : validModel;
|
|
5666
5398
|
return createDateInputComponent(
|
|
5667
5399
|
__spreadProps(__spreadValues({}, mapCommonSchemaProps(schemaMapperProps)), {
|
|
@@ -5684,6 +5416,21 @@ var stringSchemaToDateInputComponent = (schemaMapperProps, mapperProps) => {
|
|
|
5684
5416
|
onComponentUpdate
|
|
5685
5417
|
);
|
|
5686
5418
|
};
|
|
5419
|
+
var getValidDate = (model) => {
|
|
5420
|
+
if (!isString(model)) {
|
|
5421
|
+
return null;
|
|
5422
|
+
}
|
|
5423
|
+
if (/^\d{4}-\d{2}$/.test(model)) {
|
|
5424
|
+
return model;
|
|
5425
|
+
}
|
|
5426
|
+
try {
|
|
5427
|
+
const date = new Date(model);
|
|
5428
|
+
const stringDate = date.toISOString();
|
|
5429
|
+
return stringDate.split("T")[0];
|
|
5430
|
+
} catch (e) {
|
|
5431
|
+
return null;
|
|
5432
|
+
}
|
|
5433
|
+
};
|
|
5687
5434
|
|
|
5688
5435
|
// src/domain/mappers/schema/stringSchemaToComponent/stringSchemaToUploadInputComponent.ts
|
|
5689
5436
|
var stringSchemaToUploadInputComponent = (schemaMapperProps, mapperProps) => {
|
|
@@ -5799,235 +5546,544 @@ var createTextInputComponent = (textInputProps, onComponentUpdate) => {
|
|
|
5799
5546
|
this._update((draft) => {
|
|
5800
5547
|
draft.errors = errors;
|
|
5801
5548
|
});
|
|
5802
|
-
return errors.length === 0;
|
|
5803
|
-
}
|
|
5804
|
-
}, rest);
|
|
5805
|
-
return inputComponent;
|
|
5549
|
+
return errors.length === 0;
|
|
5550
|
+
}
|
|
5551
|
+
}, rest);
|
|
5552
|
+
return inputComponent;
|
|
5553
|
+
};
|
|
5554
|
+
|
|
5555
|
+
// src/domain/mappers/schema/stringSchemaToComponent/stringSchemaToTextInputComponent.ts
|
|
5556
|
+
var stringSchemaToTextInputComponent = (schemaMapperProps, mapperProps) => {
|
|
5557
|
+
const { schema, localValue, model, required = false, onPersistAsync } = schemaMapperProps;
|
|
5558
|
+
const {
|
|
5559
|
+
autocapitalization,
|
|
5560
|
+
autocompleteHint,
|
|
5561
|
+
control,
|
|
5562
|
+
default: defaultValue,
|
|
5563
|
+
displayFormat,
|
|
5564
|
+
format,
|
|
5565
|
+
maxLength,
|
|
5566
|
+
minLength,
|
|
5567
|
+
suggestions,
|
|
5568
|
+
validationMessages
|
|
5569
|
+
} = schema;
|
|
5570
|
+
const { getErrorMessageFunctions, onComponentUpdate, onBehavior, onValueChange, logEvent } = mapperProps;
|
|
5571
|
+
const controlForLegacyFormat = getControlForLegacyFormat(format);
|
|
5572
|
+
const errorMessageFunctions = getErrorMessageFunctions(validationMessages);
|
|
5573
|
+
const { performValidationAsync, validationAsyncState } = getValidationAsyncInitialState(
|
|
5574
|
+
schemaMapperProps,
|
|
5575
|
+
mapperProps
|
|
5576
|
+
);
|
|
5577
|
+
const validLocalValue = isString(localValue) ? localValue : null;
|
|
5578
|
+
const validModel = isString(model) ? model : defaultValue != null ? defaultValue : null;
|
|
5579
|
+
const value = onPersistAsync ? validLocalValue : validModel;
|
|
5580
|
+
return createTextInputComponent(
|
|
5581
|
+
__spreadProps(__spreadValues({}, mapCommonSchemaProps(schemaMapperProps)), {
|
|
5582
|
+
autocapitalization,
|
|
5583
|
+
autoComplete: getAutocompleteString(autocompleteHint),
|
|
5584
|
+
checks: schema.hidden ? [] : [
|
|
5585
|
+
getRequiredCheck(required, errorMessageFunctions),
|
|
5586
|
+
getAboveMaxLengthCheck(schema, errorMessageFunctions),
|
|
5587
|
+
getBelowMinLengthCheck(schema, errorMessageFunctions),
|
|
5588
|
+
getNotAdheringToPatternCheck(schema, errorMessageFunctions, { logEvent })
|
|
5589
|
+
],
|
|
5590
|
+
control: control != null ? control : controlForLegacyFormat,
|
|
5591
|
+
displayFormat,
|
|
5592
|
+
maxLength,
|
|
5593
|
+
minLength,
|
|
5594
|
+
suggestions: mapStringSchemaSuggestions(suggestions, mapperProps.logEvent),
|
|
5595
|
+
value,
|
|
5596
|
+
validationAsyncState,
|
|
5597
|
+
schemaOnChange: getSchemaOnChange(schema, onBehavior),
|
|
5598
|
+
performValidationAsync,
|
|
5599
|
+
onValueChange
|
|
5600
|
+
}),
|
|
5601
|
+
onComponentUpdate
|
|
5602
|
+
);
|
|
5603
|
+
};
|
|
5604
|
+
var getControlForLegacyFormat = (format) => {
|
|
5605
|
+
if (format && ["numeric", "phone-number", "email", "password"].includes(format)) {
|
|
5606
|
+
return format;
|
|
5607
|
+
}
|
|
5608
|
+
return void 0;
|
|
5609
|
+
};
|
|
5610
|
+
|
|
5611
|
+
// src/domain/mappers/schema/stringSchemaToComponent/stringSchemaToComponent.ts
|
|
5612
|
+
var stringSchemaToComponent = (schemaMapperProps, mapperProps) => {
|
|
5613
|
+
const { schema } = schemaMapperProps;
|
|
5614
|
+
if (isStringSchemaWithBase64(schema)) {
|
|
5615
|
+
return stringSchemaToUploadInputComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5616
|
+
}
|
|
5617
|
+
switch (schema.format) {
|
|
5618
|
+
case "date":
|
|
5619
|
+
return stringSchemaToDateInputComponent(schemaMapperProps, mapperProps);
|
|
5620
|
+
default:
|
|
5621
|
+
return stringSchemaToTextInputComponent(schemaMapperProps, mapperProps);
|
|
5622
|
+
}
|
|
5623
|
+
};
|
|
5624
|
+
var isStringSchemaWithBase64 = (schema) => {
|
|
5625
|
+
return schema.format === "base64url" && !("persistAsync" in schema);
|
|
5626
|
+
};
|
|
5627
|
+
|
|
5628
|
+
// src/domain/mappers/mapSchemaToComponent.ts
|
|
5629
|
+
var mapSchemaToComponent = (schemaMapperProps, mapperProps) => {
|
|
5630
|
+
const { uid, schema } = schemaMapperProps;
|
|
5631
|
+
if (isConstSchema(schema)) {
|
|
5632
|
+
return constSchemaToComponent(uid, __spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5633
|
+
}
|
|
5634
|
+
if (isSchemaWithPersistAsync(schema)) {
|
|
5635
|
+
return persistAsyncSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5636
|
+
}
|
|
5637
|
+
if (isAllOfSchema(schema)) {
|
|
5638
|
+
return allOfSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5639
|
+
}
|
|
5640
|
+
if (isOneOfSchema(schema)) {
|
|
5641
|
+
return oneOfSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5642
|
+
}
|
|
5643
|
+
if (isBooleanSchema(schema)) {
|
|
5644
|
+
return booleanSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5645
|
+
}
|
|
5646
|
+
if (isObjectSchema(schema)) {
|
|
5647
|
+
const { format } = schema;
|
|
5648
|
+
if (format === "money") {
|
|
5649
|
+
return objectSchemaToMoneyInputComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5650
|
+
}
|
|
5651
|
+
if (format != null && Object.keys(schema.properties).length === 0) {
|
|
5652
|
+
return objectSchemaToFormattedValueComponent(
|
|
5653
|
+
__spreadProps(__spreadValues({}, schemaMapperProps), { schema: __spreadProps(__spreadValues({}, schema), { format }) }),
|
|
5654
|
+
mapperProps
|
|
5655
|
+
);
|
|
5656
|
+
}
|
|
5657
|
+
return objectSchemaToObjectComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5658
|
+
}
|
|
5659
|
+
if (isIntegerSchema(schema)) {
|
|
5660
|
+
return integerSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5661
|
+
}
|
|
5662
|
+
if (isNumberSchema(schema)) {
|
|
5663
|
+
return numberSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5664
|
+
}
|
|
5665
|
+
if (isStringSchema(schema)) {
|
|
5666
|
+
return stringSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5667
|
+
}
|
|
5668
|
+
if (isArraySchema(schema)) {
|
|
5669
|
+
return arraySchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5670
|
+
}
|
|
5671
|
+
if (isBlobSchema(schema)) {
|
|
5672
|
+
if (!schemaMapperProps.onPersistAsync) {
|
|
5673
|
+
throw new Error(
|
|
5674
|
+
"Blob schemas can only be used as the schema of a persist async configuration."
|
|
5675
|
+
);
|
|
5676
|
+
}
|
|
5677
|
+
return blobSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5678
|
+
}
|
|
5679
|
+
throw new Error("Not yet supported");
|
|
5680
|
+
};
|
|
5681
|
+
|
|
5682
|
+
// src/domain/mappers/mapStepSchemas.ts
|
|
5683
|
+
var mapStepSchemas = (uid, step, stepLocalValue, mapperProps, referencedSchemaIds) => {
|
|
5684
|
+
const isReferenced = (schemaId) => schemaId != null && referencedSchemaIds.includes(schemaId);
|
|
5685
|
+
return step.schemas.map((schema, i) => {
|
|
5686
|
+
var _a, _b;
|
|
5687
|
+
const schemaComponent = mapSchemaToComponent(
|
|
5688
|
+
{
|
|
5689
|
+
uid: `${uid}.schemas-${i}.${schema.$id}`,
|
|
5690
|
+
schemaId: schema.$id,
|
|
5691
|
+
schema,
|
|
5692
|
+
model: (_a = step.model) != null ? _a : null,
|
|
5693
|
+
localValue: stepLocalValue,
|
|
5694
|
+
validationErrors: (_b = step.errors) == null ? void 0 : _b.validation,
|
|
5695
|
+
required: true
|
|
5696
|
+
},
|
|
5697
|
+
mapperProps
|
|
5698
|
+
);
|
|
5699
|
+
return __spreadProps(__spreadValues({}, schemaComponent), {
|
|
5700
|
+
isSchemaReferencedInStep: isReferenced(schema.$id)
|
|
5701
|
+
});
|
|
5702
|
+
});
|
|
5703
|
+
};
|
|
5704
|
+
|
|
5705
|
+
// src/domain/mappers/mapToolbarToComponent.ts
|
|
5706
|
+
var mapToolbarToComponent = (uid, toolbar, mapperProps) => {
|
|
5707
|
+
if (!toolbar) {
|
|
5708
|
+
return void 0;
|
|
5709
|
+
}
|
|
5710
|
+
const { onBehavior } = mapperProps;
|
|
5711
|
+
return __spreadProps(__spreadValues({}, toolbar), {
|
|
5712
|
+
type: "toolbar",
|
|
5713
|
+
uid: `${uid}.toolbar`,
|
|
5714
|
+
tags: toolbar.tags,
|
|
5715
|
+
items: toolbar.items.map((item) => {
|
|
5716
|
+
const context = item.context ? mapLegacyContext(item.context) : void 0;
|
|
5717
|
+
const behavior = getDomainLayerBehavior(
|
|
5718
|
+
{ behavior: item.behavior },
|
|
5719
|
+
[],
|
|
5720
|
+
mapperProps.registerSubmissionBehavior
|
|
5721
|
+
);
|
|
5722
|
+
return __spreadProps(__spreadValues({}, item), {
|
|
5723
|
+
context: context ? mapLegacyContext(context) : void 0,
|
|
5724
|
+
disabled: !!item.disabled,
|
|
5725
|
+
tags: item.tags,
|
|
5726
|
+
onClick: () => {
|
|
5727
|
+
void onBehavior(behavior);
|
|
5728
|
+
}
|
|
5729
|
+
});
|
|
5730
|
+
})
|
|
5731
|
+
});
|
|
5806
5732
|
};
|
|
5807
5733
|
|
|
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
|
-
);
|
|
5734
|
+
// src/domain/mappers/utils/groupLayoutByPinned.ts
|
|
5735
|
+
var groupLayoutByPinned = (layouts) => {
|
|
5736
|
+
return layouts.reduce(groupLayout, { pinned: [], nonPinned: [] });
|
|
5856
5737
|
};
|
|
5857
|
-
var
|
|
5858
|
-
if (
|
|
5859
|
-
return
|
|
5738
|
+
var groupLayout = (acc, layout) => {
|
|
5739
|
+
if (layout.type === "button" && layout.pinOrder !== void 0) {
|
|
5740
|
+
return {
|
|
5741
|
+
pinned: [...acc.pinned, layout],
|
|
5742
|
+
nonPinned: acc.nonPinned
|
|
5743
|
+
};
|
|
5860
5744
|
}
|
|
5861
|
-
|
|
5745
|
+
if (hasColumns(layout)) {
|
|
5746
|
+
const leftChildren = groupLayoutByPinned(layout.left);
|
|
5747
|
+
const rightChildren = groupLayoutByPinned(layout.right);
|
|
5748
|
+
return {
|
|
5749
|
+
pinned: [...acc.pinned, ...leftChildren.pinned, ...rightChildren.pinned],
|
|
5750
|
+
nonPinned: [
|
|
5751
|
+
...acc.nonPinned,
|
|
5752
|
+
__spreadProps(__spreadValues({}, layout), {
|
|
5753
|
+
left: leftChildren.nonPinned,
|
|
5754
|
+
right: rightChildren.nonPinned
|
|
5755
|
+
})
|
|
5756
|
+
]
|
|
5757
|
+
};
|
|
5758
|
+
}
|
|
5759
|
+
if (hasChildren(layout)) {
|
|
5760
|
+
const childComponents = groupLayoutByPinned(layout.components);
|
|
5761
|
+
return {
|
|
5762
|
+
pinned: [...acc.pinned, ...childComponents.pinned],
|
|
5763
|
+
nonPinned: [
|
|
5764
|
+
...acc.nonPinned,
|
|
5765
|
+
__spreadProps(__spreadValues({}, layout), {
|
|
5766
|
+
components: childComponents.nonPinned
|
|
5767
|
+
})
|
|
5768
|
+
]
|
|
5769
|
+
};
|
|
5770
|
+
}
|
|
5771
|
+
return {
|
|
5772
|
+
pinned: [...acc.pinned],
|
|
5773
|
+
nonPinned: [...acc.nonPinned, layout]
|
|
5774
|
+
};
|
|
5862
5775
|
};
|
|
5776
|
+
var hasChildren = (component) => "components" in component;
|
|
5777
|
+
var hasColumns = (component) => "right" in component && "left" in component;
|
|
5863
5778
|
|
|
5864
|
-
// src/
|
|
5865
|
-
var
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5779
|
+
// src/controller/getErrorMessage.ts
|
|
5780
|
+
var getErrorMessage = (error) => {
|
|
5781
|
+
return error instanceof Error ? error.message : typeof error === "string" ? error : `Unknown Error: type is ${typeof error}`;
|
|
5782
|
+
};
|
|
5783
|
+
|
|
5784
|
+
// src/controller/handleErrorResponse.ts
|
|
5785
|
+
var handleErrorResponse = async (response, actionId, trackEvent) => {
|
|
5786
|
+
const body = await parseResponseBodyAsJsonElement(response.clone());
|
|
5787
|
+
if (isErrorResponseBody(body)) {
|
|
5788
|
+
const refreshUrl = body.refreshUrl || body.refreshFormUrl;
|
|
5789
|
+
const { error, validation, analytics } = body;
|
|
5790
|
+
trackEvent("Action Failed", __spreadProps(__spreadValues({}, analytics), { actionId, statusCode: response.status }));
|
|
5791
|
+
const errors = { error, validation };
|
|
5792
|
+
return refreshUrl ? { type: "refresh", body: { refreshUrl, errors } } : {
|
|
5793
|
+
type: "error",
|
|
5794
|
+
body: { errors, analytics },
|
|
5795
|
+
httpError: { statusCode: response.status }
|
|
5796
|
+
};
|
|
5869
5797
|
}
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5798
|
+
trackEvent("Action Failed", { actionId, statusCode: response.status });
|
|
5799
|
+
const errorMessage = await parseResponseBodyAsText(response);
|
|
5800
|
+
return {
|
|
5801
|
+
type: "error",
|
|
5802
|
+
httpError: {
|
|
5803
|
+
message: errorMessage || void 0,
|
|
5804
|
+
statusCode: response.status
|
|
5805
|
+
}
|
|
5806
|
+
};
|
|
5807
|
+
};
|
|
5808
|
+
|
|
5809
|
+
// src/controller/getResponseType.ts
|
|
5810
|
+
var responseTypes = ["step", "action", "exit", "modal", "subflow"];
|
|
5811
|
+
var getResponseType = (headers, body) => {
|
|
5812
|
+
const headerResponseType = getResponseTypeFromHeader(headers);
|
|
5813
|
+
if (headerResponseType) {
|
|
5814
|
+
return headerResponseType;
|
|
5815
|
+
}
|
|
5816
|
+
if (isObject(body) && body.action) {
|
|
5817
|
+
return "action";
|
|
5875
5818
|
}
|
|
5819
|
+
return "step";
|
|
5876
5820
|
};
|
|
5877
|
-
var
|
|
5878
|
-
|
|
5821
|
+
var getResponseTypeFromHeader = (headers) => {
|
|
5822
|
+
if (headers == null ? void 0 : headers.has("X-Df-Response-Type")) {
|
|
5823
|
+
const type = headers.get("X-Df-Response-Type");
|
|
5824
|
+
assertDFResponseType(type);
|
|
5825
|
+
return type;
|
|
5826
|
+
}
|
|
5827
|
+
if (headers == null ? void 0 : headers.has("X-Df-Exit")) {
|
|
5828
|
+
return "exit";
|
|
5829
|
+
}
|
|
5830
|
+
return void 0;
|
|
5879
5831
|
};
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
return constSchemaToComponent(uid, __spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5832
|
+
function assertDFResponseType(type) {
|
|
5833
|
+
if (!responseTypes.includes(type)) {
|
|
5834
|
+
throw new Error(
|
|
5835
|
+
"Unsupported X-Df-Response-Type. Allowed values are 'step', 'action', 'exit', 'error', 'modal', 'subflow'."
|
|
5836
|
+
);
|
|
5886
5837
|
}
|
|
5887
|
-
|
|
5888
|
-
|
|
5838
|
+
}
|
|
5839
|
+
|
|
5840
|
+
// src/controller/makeSafeHttpClient.ts
|
|
5841
|
+
var makeSafeHttpClient = (httpClient) => async (...props) => {
|
|
5842
|
+
try {
|
|
5843
|
+
return await httpClient(...props);
|
|
5844
|
+
} catch (e) {
|
|
5845
|
+
return null;
|
|
5889
5846
|
}
|
|
5890
|
-
|
|
5891
|
-
|
|
5847
|
+
};
|
|
5848
|
+
|
|
5849
|
+
// src/controller/executeRequest.ts
|
|
5850
|
+
var executeRequest = async (props) => {
|
|
5851
|
+
const { exit, request, requestCache, httpClient, trackEvent, logEvent } = props;
|
|
5852
|
+
const { url, method, body } = request;
|
|
5853
|
+
const response = await getCachedOrFetch(
|
|
5854
|
+
[
|
|
5855
|
+
url,
|
|
5856
|
+
{
|
|
5857
|
+
method,
|
|
5858
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
5859
|
+
headers: { "Content-Type": "application/json" }
|
|
5860
|
+
}
|
|
5861
|
+
],
|
|
5862
|
+
requestCache,
|
|
5863
|
+
httpClient
|
|
5864
|
+
);
|
|
5865
|
+
if (!response) {
|
|
5866
|
+
const extra = { errorMessage: "Network Error" };
|
|
5867
|
+
trackEvent("Request Failed", extra);
|
|
5868
|
+
logEvent("error", "Dynamic Flow - Request Failed Unexpectedly", extra);
|
|
5869
|
+
return { type: "error" };
|
|
5892
5870
|
}
|
|
5893
|
-
if (
|
|
5894
|
-
return
|
|
5871
|
+
if (!response.ok) {
|
|
5872
|
+
return handleErrorResponse(response, void 0, trackEvent);
|
|
5895
5873
|
}
|
|
5896
|
-
|
|
5897
|
-
|
|
5874
|
+
const responseBody = await parseResponseBodyAsJsonElement(response);
|
|
5875
|
+
const responseType = getResponseType(response.headers, responseBody);
|
|
5876
|
+
if (exit) {
|
|
5877
|
+
return { type: "complete", result: responseBody };
|
|
5898
5878
|
}
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5879
|
+
switch (responseType) {
|
|
5880
|
+
case "step": {
|
|
5881
|
+
const etag = response.headers.get("etag") || null;
|
|
5882
|
+
assertStepResponseBody(responseBody);
|
|
5883
|
+
return { type: "replace-step", step: responseBody, etag };
|
|
5884
|
+
}
|
|
5885
|
+
case "exit": {
|
|
5886
|
+
return { type: "complete", result: responseBody };
|
|
5887
|
+
}
|
|
5888
|
+
case "action": {
|
|
5889
|
+
assertActionResponseBody(responseBody);
|
|
5890
|
+
return {
|
|
5891
|
+
type: "behavior",
|
|
5892
|
+
behavior: {
|
|
5893
|
+
type: "action",
|
|
5894
|
+
action: responseBody.action
|
|
5895
|
+
}
|
|
5896
|
+
};
|
|
5897
|
+
}
|
|
5898
|
+
case "subflow": {
|
|
5899
|
+
assertSubflowResponseBody(responseBody);
|
|
5900
|
+
return {
|
|
5901
|
+
type: "behavior",
|
|
5902
|
+
behavior: __spreadProps(__spreadValues({}, responseBody), {
|
|
5903
|
+
type: "subflow",
|
|
5904
|
+
onCompletion: responseBody.onCompletion ? normaliseBehavior(responseBody.onCompletion, []) : void 0,
|
|
5905
|
+
onError: responseBody.onError ? normaliseBehavior(responseBody.onError, []) : void 0
|
|
5906
|
+
})
|
|
5907
|
+
};
|
|
5908
|
+
}
|
|
5909
|
+
case "modal": {
|
|
5910
|
+
assertModalResponseBody(responseBody);
|
|
5911
|
+
return { type: "behavior", behavior: __spreadProps(__spreadValues({}, responseBody), { type: "modal" }) };
|
|
5903
5912
|
}
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
__spreadProps(__spreadValues({}, schemaMapperProps), { schema: __spreadProps(__spreadValues({}, schema), { format }) }),
|
|
5907
|
-
mapperProps
|
|
5908
|
-
);
|
|
5913
|
+
default: {
|
|
5914
|
+
throw new Error(`Unsupported response type: ${String(responseType)}`);
|
|
5909
5915
|
}
|
|
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
5916
|
}
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
if (
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
);
|
|
5917
|
+
};
|
|
5918
|
+
var getCachedOrFetch = async (requestParams, requestCache, httpClient) => {
|
|
5919
|
+
const cachedPromise = requestCache.get(requestParams);
|
|
5920
|
+
if (cachedPromise) {
|
|
5921
|
+
const cachedResponse = await cachedPromise;
|
|
5922
|
+
if (cachedResponse == null ? void 0 : cachedResponse.ok) {
|
|
5923
|
+
return cachedResponse;
|
|
5929
5924
|
}
|
|
5930
|
-
return blobSchemaToComponent(__spreadProps(__spreadValues({}, schemaMapperProps), { schema }), mapperProps);
|
|
5931
5925
|
}
|
|
5932
|
-
|
|
5926
|
+
return makeSafeHttpClient(httpClient)(...requestParams);
|
|
5933
5927
|
};
|
|
5934
5928
|
|
|
5935
|
-
// src/
|
|
5936
|
-
var
|
|
5937
|
-
const
|
|
5938
|
-
|
|
5929
|
+
// src/controller/executeSubmission.ts
|
|
5930
|
+
var executeSubmission = async (props) => {
|
|
5931
|
+
const { httpClient, requestCache, trackEvent, logEvent } = props;
|
|
5932
|
+
const triggerAction = async (action, model, isInitial) => {
|
|
5939
5933
|
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
|
-
}
|
|
5934
|
+
const { exit, url, result = null, id: actionId } = action;
|
|
5935
|
+
const trackSubmissionEvent = !isInitial ? trackEvent : () => {
|
|
5936
|
+
};
|
|
5937
|
+
trackSubmissionEvent("Action Triggered", { actionId });
|
|
5938
|
+
if (exit && !url) {
|
|
5939
|
+
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
5940
|
+
return { type: "complete", result };
|
|
5941
|
+
}
|
|
5942
|
+
try {
|
|
5943
|
+
const command = await executeRequest({
|
|
5944
|
+
exit,
|
|
5945
|
+
request: createRequestFromAction(action, model),
|
|
5946
|
+
requestCache,
|
|
5947
|
+
httpClient,
|
|
5948
|
+
trackEvent: (name, properties) => {
|
|
5949
|
+
trackSubmissionEvent(name, __spreadProps(__spreadValues({}, properties), { actionId }));
|
|
5950
|
+
},
|
|
5951
|
+
logEvent
|
|
5982
5952
|
});
|
|
5983
|
-
|
|
5953
|
+
switch (command.type) {
|
|
5954
|
+
case "error": {
|
|
5955
|
+
trackSubmissionEvent("Action Failed", __spreadValues({
|
|
5956
|
+
actionId,
|
|
5957
|
+
statusCode: (_a = command.httpError) == null ? void 0 : _a.statusCode
|
|
5958
|
+
}, (_b = command.body) == null ? void 0 : _b.analytics));
|
|
5959
|
+
return command;
|
|
5960
|
+
}
|
|
5961
|
+
case "behavior": {
|
|
5962
|
+
if (command.behavior.type === "action") {
|
|
5963
|
+
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
5964
|
+
return await executeSubmission({
|
|
5965
|
+
action: command.behavior.action,
|
|
5966
|
+
isInitial: false,
|
|
5967
|
+
model: null,
|
|
5968
|
+
requestCache,
|
|
5969
|
+
httpClient,
|
|
5970
|
+
trackEvent,
|
|
5971
|
+
logEvent
|
|
5972
|
+
});
|
|
5973
|
+
}
|
|
5974
|
+
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
5975
|
+
return command;
|
|
5976
|
+
}
|
|
5977
|
+
case "complete": {
|
|
5978
|
+
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
5979
|
+
return __spreadProps(__spreadValues({}, command), { result: recursiveMerge(command.result, result) });
|
|
5980
|
+
}
|
|
5981
|
+
default: {
|
|
5982
|
+
trackSubmissionEvent("Action Succeeded", { actionId });
|
|
5983
|
+
return command;
|
|
5984
|
+
}
|
|
5985
|
+
}
|
|
5986
|
+
} catch (error) {
|
|
5987
|
+
const errorMessage = getErrorMessage(error);
|
|
5988
|
+
trackSubmissionEvent("Action Failed", { actionId, errorMessage });
|
|
5989
|
+
logEvent("error", "Dynamic Flow - Action Failed Unexpectedly", { actionId, errorMessage });
|
|
5990
|
+
throw error;
|
|
5991
|
+
}
|
|
5992
|
+
};
|
|
5993
|
+
return triggerAction(props.action, props.model, props.isInitial);
|
|
5994
|
+
};
|
|
5995
|
+
var createRequestFromAction = (action, model) => {
|
|
5996
|
+
var _a, _b, _c;
|
|
5997
|
+
return __spreadProps(__spreadValues({}, action), {
|
|
5998
|
+
url: (_a = action.url) != null ? _a : "",
|
|
5999
|
+
method: (_b = action.method) != null ? _b : "POST",
|
|
6000
|
+
body: action.method === "GET" ? void 0 : recursiveMerge(model, (_c = action.data) != null ? _c : null)
|
|
5984
6001
|
});
|
|
5985
6002
|
};
|
|
5986
6003
|
|
|
5987
|
-
// src/domain/
|
|
5988
|
-
var
|
|
5989
|
-
|
|
6004
|
+
// src/domain/features/prefetch/request-cache.ts
|
|
6005
|
+
var makeRequestCacheWithParent = (parent) => {
|
|
6006
|
+
const map = /* @__PURE__ */ new Map();
|
|
6007
|
+
const cache = {
|
|
6008
|
+
get: (requestParams) => {
|
|
6009
|
+
var _a;
|
|
6010
|
+
const key = makeRequestCacheKey(requestParams);
|
|
6011
|
+
const promise = (_a = map.get(key)) != null ? _a : parent == null ? void 0 : parent.get(requestParams);
|
|
6012
|
+
map.delete(key);
|
|
6013
|
+
return promise;
|
|
6014
|
+
},
|
|
6015
|
+
set: (requestParams, responsePromise) => {
|
|
6016
|
+
return map.set(makeRequestCacheKey(requestParams), responsePromise);
|
|
6017
|
+
}
|
|
6018
|
+
};
|
|
6019
|
+
return cache;
|
|
5990
6020
|
};
|
|
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
|
-
};
|
|
6021
|
+
var makeRequestCache = (initialValues = []) => {
|
|
6022
|
+
const cache = makeRequestCacheWithParent(void 0);
|
|
6023
|
+
initialValues.forEach(([requestParams, responsePromise]) => {
|
|
6024
|
+
cache.set(requestParams, responsePromise);
|
|
6025
|
+
});
|
|
6026
|
+
return cache;
|
|
6027
|
+
};
|
|
6028
|
+
var normaliseRequestCache = (cache) => {
|
|
6029
|
+
if (cache === void 0) {
|
|
6030
|
+
return makeRequestCache();
|
|
6011
6031
|
}
|
|
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
|
-
};
|
|
6032
|
+
if (isRequestCacheInstance(cache)) {
|
|
6033
|
+
return cache;
|
|
6023
6034
|
}
|
|
6024
|
-
return
|
|
6025
|
-
|
|
6026
|
-
|
|
6035
|
+
return makeRequestCache(cache);
|
|
6036
|
+
};
|
|
6037
|
+
var isRequestCacheInstance = (cache) => {
|
|
6038
|
+
return !cache || !Array.isArray(cache);
|
|
6039
|
+
};
|
|
6040
|
+
var makeRequestCacheKey = (requestParams) => {
|
|
6041
|
+
var _a, _b;
|
|
6042
|
+
const [input, init] = requestParams;
|
|
6043
|
+
const url = typeof input === "string" || input instanceof URL ? input.toString() : input.url;
|
|
6044
|
+
const key = JSON.stringify({
|
|
6045
|
+
url,
|
|
6046
|
+
method: (_a = init == null ? void 0 : init.method) != null ? _a : "GET",
|
|
6047
|
+
headers: (init == null ? void 0 : init.headers) ? Array.from(new Headers(init.headers).entries()) : [],
|
|
6048
|
+
body: (_b = init == null ? void 0 : init.body) != null ? _b : null
|
|
6049
|
+
});
|
|
6050
|
+
return key;
|
|
6051
|
+
};
|
|
6052
|
+
|
|
6053
|
+
// src/domain/features/prefetch/getStepPrefetch.ts
|
|
6054
|
+
var getStepPrefetch = (httpClient, flowRequestCache, submissionBehaviors) => {
|
|
6055
|
+
const requestCache = makeRequestCacheWithParent(flowRequestCache);
|
|
6056
|
+
const keys = /* @__PURE__ */ new Set();
|
|
6057
|
+
const start = (model) => {
|
|
6058
|
+
if (keys.size > 0) {
|
|
6059
|
+
return;
|
|
6060
|
+
}
|
|
6061
|
+
submissionBehaviors.forEach((behavior) => {
|
|
6062
|
+
const request = behavior.type === "action" ? createRequestFromAction(behavior.action, model) : behavior.launchConfig.request;
|
|
6063
|
+
const requestParams = [
|
|
6064
|
+
request.url,
|
|
6065
|
+
{
|
|
6066
|
+
body: JSON.stringify(request.body),
|
|
6067
|
+
method: request.method,
|
|
6068
|
+
headers: { "Content-Type": "application/json" }
|
|
6069
|
+
}
|
|
6070
|
+
];
|
|
6071
|
+
try {
|
|
6072
|
+
const key = makeRequestCacheKey(requestParams);
|
|
6073
|
+
if (keys.has(key)) {
|
|
6074
|
+
return;
|
|
6075
|
+
}
|
|
6076
|
+
const responsePromise = httpClient(...requestParams).catch(() => null);
|
|
6077
|
+
requestCache.set(requestParams, responsePromise);
|
|
6078
|
+
keys.add(key);
|
|
6079
|
+
} catch (e) {
|
|
6080
|
+
}
|
|
6081
|
+
});
|
|
6027
6082
|
};
|
|
6083
|
+
const stop = () => {
|
|
6084
|
+
};
|
|
6085
|
+
return { requestCache, start, stop };
|
|
6028
6086
|
};
|
|
6029
|
-
var hasChildren = (component) => "components" in component;
|
|
6030
|
-
var hasColumns = (component) => "right" in component && "left" in component;
|
|
6031
6087
|
|
|
6032
6088
|
// src/domain/mappers/mapStepToComponent.ts
|
|
6033
6089
|
var mapStepToComponent = (_a) => {
|
|
@@ -6061,7 +6117,6 @@ var mapStepToComponent = (_a) => {
|
|
|
6061
6117
|
title,
|
|
6062
6118
|
tags
|
|
6063
6119
|
} = step;
|
|
6064
|
-
const requestCache = makeRequestCacheWithParent(flowRequestCache);
|
|
6065
6120
|
const submissionBehaviors = [];
|
|
6066
6121
|
const registerSubmissionBehavior = (behavior) => {
|
|
6067
6122
|
if (behavior.type === "action" && behavior.action.prefetch) {
|
|
@@ -6085,6 +6140,7 @@ var mapStepToComponent = (_a) => {
|
|
|
6085
6140
|
registerSubmissionBehavior
|
|
6086
6141
|
}) : void 0;
|
|
6087
6142
|
const stepRefreshAfter = refreshAfter ? getStepRefreshAfter({ refreshAfter, logEvent, onBehavior }) : void 0;
|
|
6143
|
+
const stepPrefetch = getStepPrefetch(restProps.httpClient, flowRequestCache, submissionBehaviors);
|
|
6088
6144
|
const externalConfirmation = (external == null ? void 0 : external.url) ? createExternalConfirmation(`${uid}-external-confirmation`, external == null ? void 0 : external.url, onComponentUpdate) : void 0;
|
|
6089
6145
|
const mapperProps = __spreadProps(__spreadValues({}, restProps), { trackEvent, onBehavior, registerSubmissionBehavior });
|
|
6090
6146
|
const referencedSchemaIds = getReferencedSchemaId(step);
|
|
@@ -6121,18 +6177,12 @@ var mapStepToComponent = (_a) => {
|
|
|
6121
6177
|
title,
|
|
6122
6178
|
tags,
|
|
6123
6179
|
stackBehavior: (_a2 = navigation == null ? void 0 : navigation.stackBehavior) != null ? _a2 : "default",
|
|
6124
|
-
|
|
6180
|
+
stepPrefetch,
|
|
6125
6181
|
step,
|
|
6126
6182
|
onComponentUpdate,
|
|
6127
6183
|
trackEvent,
|
|
6128
6184
|
onBehavior
|
|
6129
6185
|
});
|
|
6130
|
-
executePrefetch({
|
|
6131
|
-
httpClient: mapperProps.httpClient,
|
|
6132
|
-
model: stepComponent.getSubmittableValueSync(),
|
|
6133
|
-
behaviors: submissionBehaviors,
|
|
6134
|
-
requestCache
|
|
6135
|
-
});
|
|
6136
6186
|
return stepComponent;
|
|
6137
6187
|
};
|
|
6138
6188
|
var getReferencedSchemaId = (step) => {
|
|
@@ -6153,25 +6203,6 @@ var mapBackNavigation = (navigation, onBehavior, isNativeBackEnabled) => {
|
|
|
6153
6203
|
}
|
|
6154
6204
|
} : void 0;
|
|
6155
6205
|
};
|
|
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
6206
|
var getLayoutAndFooter = (step, features) => {
|
|
6176
6207
|
var _a;
|
|
6177
6208
|
if (step.footer) {
|
|
@@ -6777,21 +6808,24 @@ var createFlowController = (props) => {
|
|
|
6777
6808
|
return false;
|
|
6778
6809
|
}
|
|
6779
6810
|
};
|
|
6780
|
-
let
|
|
6811
|
+
let initState = "initial";
|
|
6781
6812
|
if (initialStep) {
|
|
6782
|
-
|
|
6813
|
+
initState = "created";
|
|
6783
6814
|
trackEvent("Initiated");
|
|
6784
6815
|
createStep(initialStep, null);
|
|
6785
6816
|
trackEvent("Step Shown", { isFirstStep: true });
|
|
6786
6817
|
}
|
|
6787
6818
|
const start = () => {
|
|
6788
|
-
if (
|
|
6789
|
-
|
|
6819
|
+
if (initState === "initial" && initialAction) {
|
|
6820
|
+
initState = "created";
|
|
6790
6821
|
trackEvent("Initiated");
|
|
6791
6822
|
rootComponent.setLoadingState("submitting");
|
|
6792
6823
|
void onAction(__spreadValues({ method: "GET" }, initialAction), null);
|
|
6793
6824
|
}
|
|
6794
|
-
|
|
6825
|
+
if (initState === "created") {
|
|
6826
|
+
initState = "started";
|
|
6827
|
+
rootComponent.start();
|
|
6828
|
+
}
|
|
6795
6829
|
};
|
|
6796
6830
|
return {
|
|
6797
6831
|
rootComponent,
|