@incodetech/core 0.0.0-dev-20260813-ad5ea9e1 → 0.0.0-dev-20260813-c65eff54
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/dist/{BrowserDiagnosticsCryptoProvider-CNisE_Zn.esm.js → BrowserDiagnosticsCryptoProvider-BEU3LQrd.esm.js} +1 -1
- package/dist/ae-signature.esm.js +1 -1
- package/dist/{apiError-DlT6yqH7.esm.js → apiError-B2GL2Tqr.esm.js} +1 -1
- package/dist/authentication.esm.js +2 -2
- package/dist/{authenticationManager-BQ4rf5cd.esm.js → authenticationManager-BC1PdEvT.esm.js} +2 -2
- package/dist/{authenticationStateMachine-pgQiyE-Q.esm.js → authenticationStateMachine-B61pxYbF.esm.js} +2 -2
- package/dist/custom-fields.d.ts +2 -114
- package/dist/custom-fields.esm.js +2 -232
- package/dist/customFieldsManager-6mtAzlY2.esm.js +264 -0
- package/dist/customFieldsManager-8-W2KY4n.d.ts +141 -0
- package/dist/{deepsightLoader-DhTeVa0Y.esm.js → deepsightLoader-BUwe2wdM.esm.js} +3 -3
- package/dist/dynamic-forms.esm.js +2 -2
- package/dist/{dynamicFormsManager-XCS1M8YD.esm.js → dynamicFormsManager-DyjyvuMd.esm.js} +1 -1
- package/dist/{dynamicFormsStateMachine-DPrVti5t.esm.js → dynamicFormsStateMachine-CmW--4wk.esm.js} +1 -1
- package/dist/ekyb.esm.js +3 -3
- package/dist/{ekybManager-DDY0Dv48.esm.js → ekybManager-Drca7lok.esm.js} +1 -1
- package/dist/{ekybStateMachine-DPoE6ZWY.esm.js → ekybStateMachine-Dt_2E9Ng.esm.js} +1 -1
- package/dist/electronic-signature.esm.js +1 -1
- package/dist/{electronicSignatureManager-BF4fB4Ja.esm.js → electronicSignatureManager-DSk0n0ls.esm.js} +1 -1
- package/dist/extensibility.d.ts +2 -1
- package/dist/extensibility.esm.js +11 -10
- package/dist/{faceCaptureManagerFactory-z9XGOFC1.esm.js → faceCaptureManagerFactory-BuvPvQ0p.esm.js} +1 -1
- package/dist/{faceCaptureSetup-h9c2vAKc.esm.js → faceCaptureSetup-D_DBaXp8.esm.js} +2 -2
- package/dist/flow.esm.js +3 -3
- package/dist/{flowCompletionService-CgDm6jHE.esm.js → flowCompletionService-DaDLcGR3.esm.js} +1 -1
- package/dist/{flowServices-bFtIDlJ6.esm.js → flowServices-BusXh9Y_.esm.js} +3 -3
- package/dist/geolocation.esm.js +2 -2
- package/dist/{geolocationManager-Cd2K6jyW.esm.js → geolocationManager-QrhafoWh.esm.js} +1 -1
- package/dist/{geolocationStateMachine-bwz1ij99.esm.js → geolocationStateMachine-DcSRzE31.esm.js} +1 -1
- package/dist/id-selfie-flow.esm.js +6 -6
- package/dist/id.esm.js +3 -3
- package/dist/{idCaptureManager-DQSHRvTm.esm.js → idCaptureManager-C_L_HQIA.esm.js} +2 -2
- package/dist/{idCaptureServices-mELMLbTy.esm.js → idCaptureServices-cVZgxNor.esm.js} +2 -2
- package/dist/{idCaptureStateMachine-CfPaYLOP.esm.js → idCaptureStateMachine-BVSn_TpQ.esm.js} +7 -7
- package/dist/index.esm.js +1 -1
- package/dist/{onDeviceFaceResults-COsSZ7zf.esm.js → onDeviceFaceResults-Cun-5wgv.esm.js} +3 -3
- package/dist/personhood.esm.js +3 -3
- package/dist/qe-signature.esm.js +1 -1
- package/dist/{recordingService-k20vRkRy.esm.js → recordingService-wr5gR-KC.esm.js} +1 -1
- package/dist/{runChildModule-pfy5gQAk.esm.js → runChildModule-Bq14P9iI.esm.js} +1 -1
- package/dist/selfie.esm.js +4 -4
- package/dist/{selfieManager-DmB7C0-a.esm.js → selfieManager-BO4WCips.esm.js} +2 -2
- package/dist/{selfieStateMachine-Dle0Z1Wf.esm.js → selfieStateMachine-C9Y3KmdC.esm.js} +2 -2
- package/dist/{session-D8x2baio.esm.js → session-CETURITF.esm.js} +4 -4
- package/dist/session.esm.js +4 -4
- package/dist/{sessionInitializer-CbssHeS5.esm.js → sessionInitializer-CHQerRj-.esm.js} +2 -2
- package/dist/{setup-DJmnbb1a.esm.js → setup-r19cxUoE.esm.js} +4 -4
- package/dist/trueSight-BWfKWHV-.esm.js +1 -0
- package/dist/{trueSightService-CWCUUzQD.esm.js → trueSightService-BPZPbOJ4.esm.js} +2 -2
- package/dist/video-selfie.esm.js +3 -3
- package/dist/{videoSelfieCameraWarmer-B91eHP6E.esm.js → videoSelfieCameraWarmer-DMtSa_S8.esm.js} +2 -2
- package/dist/wasm.esm.js +1 -1
- package/dist/workflow.esm.js +14 -14
- package/package.json +1 -1
- package/dist/trueSight-Dx71WyQJ.esm.js +0 -1
|
@@ -18,7 +18,7 @@ function decodeTruesightKey(s0Base64, s1Base64) {
|
|
|
18
18
|
*/
|
|
19
19
|
function getTruesightKey() {
|
|
20
20
|
try {
|
|
21
|
-
const key = decodeTruesightKey("
|
|
21
|
+
const key = decodeTruesightKey("w7SCIF0cnZ+IVbZJrfnO9EYMGeGoqG2hVv6JoqCc2JU=", "Psir8Zu7q2bv0sc0lkvz8mD7qFA/ab83HPNlqwlvXss=");
|
|
22
22
|
return key.length === KEY_LENGTH_BYTES ? key : null;
|
|
23
23
|
} catch {
|
|
24
24
|
return null;
|
package/dist/ae-signature.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as getDefaultConsentChecks, i as AE_CONSENT_KEYS, o as areAllConsented, r as electronicSignatureMachine, t as createElectronicSignatureManager } from "./electronicSignatureManager-
|
|
1
|
+
import { c as getDefaultConsentChecks, i as AE_CONSENT_KEYS, o as areAllConsented, r as electronicSignatureMachine, t as createElectronicSignatureManager } from "./electronicSignatureManager-DSk0n0ls.esm.js";
|
|
2
2
|
//#region src/modules/ae-signature/index.ts
|
|
3
3
|
function createAeSignatureManager(options) {
|
|
4
4
|
return createElectronicSignatureManager({ config: {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as authenticationMachine } from "./authenticationStateMachine-
|
|
2
|
-
import { r as createAuthenticationActor, t as createAuthenticationManager } from "./authenticationManager-
|
|
1
|
+
import { t as authenticationMachine } from "./authenticationStateMachine-B61pxYbF.esm.js";
|
|
2
|
+
import { r as createAuthenticationActor, t as createAuthenticationManager } from "./authenticationManager-BC1PdEvT.esm.js";
|
|
3
3
|
export { authenticationMachine, createAuthenticationActor, createAuthenticationManager };
|
package/dist/{authenticationManager-BQ4rf5cd.esm.js → authenticationManager-BC1PdEvT.esm.js}
RENAMED
|
@@ -2,8 +2,8 @@ import { r as WasmUtilProvider } from "./safeStorage-Ep56I-f_.esm.js";
|
|
|
2
2
|
import { t as BrowserStorageProvider } from "./BrowserStorageProvider-k-FDkC4W.esm.js";
|
|
3
3
|
import { n as eventModuleNames } from "./events-CxfNJVZW.esm.js";
|
|
4
4
|
import { o as createActor } from "./xstate.esm-Cf4e0Cfd.esm.js";
|
|
5
|
-
import { t as createFaceCaptureManagerFromActor } from "./faceCaptureManagerFactory-
|
|
6
|
-
import { t as authenticationMachine } from "./authenticationStateMachine-
|
|
5
|
+
import { t as createFaceCaptureManagerFromActor } from "./faceCaptureManagerFactory-BuvPvQ0p.esm.js";
|
|
6
|
+
import { t as authenticationMachine } from "./authenticationStateMachine-B61pxYbF.esm.js";
|
|
7
7
|
//#region src/modules/authentication/authenticationActor.ts
|
|
8
8
|
function createAuthenticationActor(options) {
|
|
9
9
|
const dependencies = options.dependencies ?? {
|
|
@@ -3,8 +3,8 @@ import { t as endpoints } from "./endpoints-CCzL3XD_.esm.js";
|
|
|
3
3
|
import { t as addDeviceStats } from "./stats-B0nFKawG.esm.js";
|
|
4
4
|
import { r as assign } from "./xstate.esm-Cf4e0Cfd.esm.js";
|
|
5
5
|
import { n as fromPromise } from "./xstate-actors.esm-CtI5S0f4.esm.js";
|
|
6
|
-
import { t as faceCaptureMachine } from "./faceCaptureSetup-
|
|
7
|
-
import { i as prepareOnDeviceFaceUpload, n as isOnDeviceMode, r as postOnDeviceFaceResults, t as defaultPrepareFaceUpload } from "./onDeviceFaceResults-
|
|
6
|
+
import { t as faceCaptureMachine } from "./faceCaptureSetup-D_DBaXp8.esm.js";
|
|
7
|
+
import { i as prepareOnDeviceFaceUpload, n as isOnDeviceMode, r as postOnDeviceFaceResults, t as defaultPrepareFaceUpload } from "./onDeviceFaceResults-Cun-5wgv.esm.js";
|
|
8
8
|
import { t as getDeviceClass } from "./getDeviceClass-Sh0zhEv7.esm.js";
|
|
9
9
|
import { t as FACE_ERROR_CODES } from "./types-BN5RPPIZ.esm.js";
|
|
10
10
|
//#region src/modules/authentication/authenticationErrorUtils.ts
|
package/dist/custom-fields.d.ts
CHANGED
|
@@ -1,114 +1,2 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
|
|
3
|
-
//#region src/modules/custom-fields/types.d.ts
|
|
4
|
-
type CustomFieldType = 'INTEGER' | 'DOUBLE' | 'BOOLEAN' | 'STRING' | 'DATE';
|
|
5
|
-
type CustomField = {
|
|
6
|
-
name: string;
|
|
7
|
-
alias: string;
|
|
8
|
-
type: CustomFieldType;
|
|
9
|
-
};
|
|
10
|
-
type CustomFieldsConfig = {
|
|
11
|
-
title: string;
|
|
12
|
-
customFields: CustomField[];
|
|
13
|
-
};
|
|
14
|
-
//#endregion
|
|
15
|
-
//#region src/modules/custom-fields/customFieldsStateMachine.d.ts
|
|
16
|
-
type CustomFieldsResult = 'success' | 'failed';
|
|
17
|
-
declare const customFieldsMachine: any;
|
|
18
|
-
//#endregion
|
|
19
|
-
//#region src/modules/custom-fields/customFieldsActor.d.ts
|
|
20
|
-
type CreateCustomFieldsActorOptions = {
|
|
21
|
-
config: CustomFieldsConfig;
|
|
22
|
-
};
|
|
23
|
-
//#endregion
|
|
24
|
-
//#region src/modules/custom-fields/customFieldsManager.d.ts
|
|
25
|
-
/**
|
|
26
|
-
* A `CustomField` enriched with a computed `label` for display.
|
|
27
|
-
* Label is derived from `alias` when present, otherwise auto-formatted from `name`.
|
|
28
|
-
*/
|
|
29
|
-
type MappedCustomField = CustomField & {
|
|
30
|
-
label: string;
|
|
31
|
-
};
|
|
32
|
-
/** Custom fields manager is in initial state, waiting for `load()` to be called */
|
|
33
|
-
type CustomFieldsIdleState = {
|
|
34
|
-
status: 'idle';
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Ready for field input — use `setField()` and `submit()`
|
|
38
|
-
* @property title - Form title from configuration
|
|
39
|
-
* @property customFields - Field definitions with computed display labels
|
|
40
|
-
* @property canSubmit - True when all non-boolean fields have a non-empty value
|
|
41
|
-
*/
|
|
42
|
-
type CustomFieldsInputtingState = {
|
|
43
|
-
status: 'inputting';
|
|
44
|
-
title: string;
|
|
45
|
-
customFields: MappedCustomField[];
|
|
46
|
-
canSubmit: boolean;
|
|
47
|
-
};
|
|
48
|
-
/** Fields are being submitted to the backend */
|
|
49
|
-
type CustomFieldsSubmittingState = {
|
|
50
|
-
status: 'submitting';
|
|
51
|
-
title: string;
|
|
52
|
-
};
|
|
53
|
-
/** API call succeeded — success page is visible for ~3 s before finishing */
|
|
54
|
-
type CustomFieldsSuccessState = {
|
|
55
|
-
status: 'success';
|
|
56
|
-
};
|
|
57
|
-
/** Custom fields flow complete. `result` indicates whether the API call succeeded or failed. */
|
|
58
|
-
type CustomFieldsFinishedState = {
|
|
59
|
-
status: 'finished';
|
|
60
|
-
result: CustomFieldsResult | null;
|
|
61
|
-
};
|
|
62
|
-
/**
|
|
63
|
-
* Union of all possible custom fields manager states.
|
|
64
|
-
*/
|
|
65
|
-
type CustomFieldsState = CustomFieldsIdleState | CustomFieldsInputtingState | CustomFieldsSubmittingState | CustomFieldsSuccessState | CustomFieldsFinishedState;
|
|
66
|
-
/**
|
|
67
|
-
* Creates a custom fields manager for headless or UI-driven usage.
|
|
68
|
-
*
|
|
69
|
-
* @param options - Configuration options
|
|
70
|
-
* @param options.config - Custom fields configuration (title + field definitions)
|
|
71
|
-
*
|
|
72
|
-
* @returns Custom fields manager with state, API methods, and subscription
|
|
73
|
-
*
|
|
74
|
-
* @example Headless usage
|
|
75
|
-
* ```typescript
|
|
76
|
-
* const manager = createCustomFieldsManager({
|
|
77
|
-
* config: {
|
|
78
|
-
* title: 'Additional Information',
|
|
79
|
-
* customFields: [{ name: 'company', alias: 'Company', type: 'STRING' }],
|
|
80
|
-
* },
|
|
81
|
-
* });
|
|
82
|
-
*
|
|
83
|
-
* manager.subscribe((state) => console.log(state.status));
|
|
84
|
-
* manager.load();
|
|
85
|
-
* manager.setField('company', 'Incode');
|
|
86
|
-
* manager.submit();
|
|
87
|
-
* manager.stop();
|
|
88
|
-
* ```
|
|
89
|
-
*/
|
|
90
|
-
declare function createCustomFieldsManager(options: CreateCustomFieldsActorOptions): Manager<CustomFieldsState> & {
|
|
91
|
-
/**
|
|
92
|
-
* Initializes the custom fields flow.
|
|
93
|
-
* Transitions from 'idle' to 'inputting'.
|
|
94
|
-
* Must be called before any other method.
|
|
95
|
-
*/
|
|
96
|
-
load(): void;
|
|
97
|
-
/**
|
|
98
|
-
* Updates the value of a single field.
|
|
99
|
-
* Should be called when state is 'inputting'.
|
|
100
|
-
*
|
|
101
|
-
* @param name - The field name (matches CustomField.name)
|
|
102
|
-
* @param value - The field value (string, number, or boolean)
|
|
103
|
-
*/
|
|
104
|
-
setField(name: string, value: string | number | boolean): void;
|
|
105
|
-
/**
|
|
106
|
-
* Submits all custom field values to the backend.
|
|
107
|
-
* Transitions to 'submitting', then 'finished' regardless of outcome.
|
|
108
|
-
*/
|
|
109
|
-
submit(): void;
|
|
110
|
-
};
|
|
111
|
-
/** Type representing a custom fields manager instance. */
|
|
112
|
-
type CustomFieldsManager = ReturnType<typeof createCustomFieldsManager>;
|
|
113
|
-
//#endregion
|
|
114
|
-
export { type CustomField, type CustomFieldType, type CustomFieldsConfig, type CustomFieldsManager, type CustomFieldsState, type MappedCustomField, createCustomFieldsManager, customFieldsMachine };
|
|
1
|
+
import { a as createCustomFieldsManagerFromActor, c as customFieldsMachine, d as CustomFieldsConfig, i as createCustomFieldsManager, l as CustomField, n as CustomFieldsState, o as CustomFieldsActor, r as MappedCustomField, s as CustomFieldsValidationErrors, t as CustomFieldsManager, u as CustomFieldType } from "./customFieldsManager-8-W2KY4n.js";
|
|
2
|
+
export { type CustomField, type CustomFieldType, type CustomFieldsActor, type CustomFieldsConfig, type CustomFieldsManager, type CustomFieldsState, type CustomFieldsValidationErrors, type MappedCustomField, createCustomFieldsManager, createCustomFieldsManagerFromActor, customFieldsMachine };
|
|
@@ -1,232 +1,2 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
|
|
3
|
-
import { t as topLevelStateName } from "./topLevelStateName-B5i2avbh.esm.js";
|
|
4
|
-
import { t as endpoints } from "./endpoints-CCzL3XD_.esm.js";
|
|
5
|
-
import { c as createManager, o as createActor, r as assign, t as setup } from "./xstate.esm-Cf4e0Cfd.esm.js";
|
|
6
|
-
import { n as fromPromise } from "./xstate-actors.esm-CtI5S0f4.esm.js";
|
|
7
|
-
import { t as isoDateToMs } from "./dateUtils-CvG0FvK8.esm.js";
|
|
8
|
-
//#region src/modules/custom-fields/customFieldsServices.ts
|
|
9
|
-
async function submitCustomFields(params, signal) {
|
|
10
|
-
const res = await api.post(endpoints.addCustomFields, params.fields, { signal });
|
|
11
|
-
if (!res.ok) throw new Error(`POST ${endpoints.addCustomFields} failed: ${res.status} ${res.statusText}`);
|
|
12
|
-
return res.data;
|
|
13
|
-
}
|
|
14
|
-
//#endregion
|
|
15
|
-
//#region src/modules/custom-fields/customFieldsStateMachine.ts
|
|
16
|
-
function transformFields(fields, customFields) {
|
|
17
|
-
const result = {};
|
|
18
|
-
for (const [key, value] of Object.entries(fields)) if (customFields.find((f) => f.name === key)?.type === "DATE" && typeof value === "string" && value !== "") result[key] = isoDateToMs(value);
|
|
19
|
-
else result[key] = value;
|
|
20
|
-
return result;
|
|
21
|
-
}
|
|
22
|
-
const customFieldsMachine = setup({
|
|
23
|
-
types: {
|
|
24
|
-
context: {},
|
|
25
|
-
events: {},
|
|
26
|
-
input: {}
|
|
27
|
-
},
|
|
28
|
-
actors: { submitFields: fromPromise(async ({ input, signal }) => {
|
|
29
|
-
return submitCustomFields({ fields: transformFields(input.fields, input.customFields) }, signal);
|
|
30
|
-
}) },
|
|
31
|
-
actions: {
|
|
32
|
-
setField: assign(({ context, event }) => {
|
|
33
|
-
const e = event;
|
|
34
|
-
return { fields: {
|
|
35
|
-
...context.fields,
|
|
36
|
-
[e.name]: e.value
|
|
37
|
-
} };
|
|
38
|
-
}),
|
|
39
|
-
markSuccess: assign({ result: "success" }),
|
|
40
|
-
markFailed: assign({ result: "failed" })
|
|
41
|
-
},
|
|
42
|
-
guards: { apiSucceeded: ({ event }) => event.output.success }
|
|
43
|
-
}).createMachine({
|
|
44
|
-
id: "customFields",
|
|
45
|
-
initial: "idle",
|
|
46
|
-
context: ({ input }) => ({
|
|
47
|
-
config: input.config,
|
|
48
|
-
fields: {},
|
|
49
|
-
result: null
|
|
50
|
-
}),
|
|
51
|
-
states: {
|
|
52
|
-
idle: { on: { LOAD: { target: "inputting" } } },
|
|
53
|
-
inputting: { on: {
|
|
54
|
-
FIELD_CHANGED: { actions: "setField" },
|
|
55
|
-
SUBMIT: { target: "submitting" }
|
|
56
|
-
} },
|
|
57
|
-
submitting: { invoke: {
|
|
58
|
-
id: "submitFields",
|
|
59
|
-
src: "submitFields",
|
|
60
|
-
input: ({ context }) => ({
|
|
61
|
-
fields: context.fields,
|
|
62
|
-
customFields: context.config.customFields
|
|
63
|
-
}),
|
|
64
|
-
onDone: [{
|
|
65
|
-
target: "success",
|
|
66
|
-
guard: "apiSucceeded"
|
|
67
|
-
}, {
|
|
68
|
-
target: "finished",
|
|
69
|
-
actions: "markFailed"
|
|
70
|
-
}],
|
|
71
|
-
onError: {
|
|
72
|
-
target: "finished",
|
|
73
|
-
actions: "markFailed"
|
|
74
|
-
}
|
|
75
|
-
} },
|
|
76
|
-
success: { after: { 3e3: {
|
|
77
|
-
target: "finished",
|
|
78
|
-
actions: "markSuccess"
|
|
79
|
-
} } },
|
|
80
|
-
finished: { type: "final" }
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
//#endregion
|
|
84
|
-
//#region src/modules/custom-fields/customFieldsActor.ts
|
|
85
|
-
function createCustomFieldsActor(options) {
|
|
86
|
-
return createActor(customFieldsMachine, { input: { config: options.config } }).start();
|
|
87
|
-
}
|
|
88
|
-
//#endregion
|
|
89
|
-
//#region src/modules/custom-fields/customFieldsManager.ts
|
|
90
|
-
/**
|
|
91
|
-
* Maps a custom-fields state-machine snapshot to the exact Figma "Tracked
|
|
92
|
-
* Events" screen name. Returned strings are the Figma-verbatim absolute
|
|
93
|
-
* analytics path emitted as-is on `event.screen` by
|
|
94
|
-
* `createManagerInstrumentation`'s `getEventScreenName` path. See
|
|
95
|
-
* `docs/patterns/INSTRUMENTATION.md`.
|
|
96
|
-
*
|
|
97
|
-
* Source of truth: Custom Fields Figma file → Tracked Events canvas
|
|
98
|
-
* (`https://www.figma.com/design/Fb4Jp6kal8clAD05Kh6l4e/Custom-fields---Latest-Design?node-id=2026-30075`).
|
|
99
|
-
* The canvas mixes two casings — sections name the input surfaces
|
|
100
|
-
* `Customfield.{empty,filled}` (capital `C`) and the post-input surfaces
|
|
101
|
-
* `customfield.{processing,complete}` (lowercase `c`). Both spellings are
|
|
102
|
-
* preserved verbatim as Figma is the source of truth.
|
|
103
|
-
*
|
|
104
|
-
* State → screen mapping rationale:
|
|
105
|
-
*
|
|
106
|
-
* - `idle`/`inputting` collapse to `Customfield.empty` — the SM stays in
|
|
107
|
-
* `inputting` throughout typing (field-level `FIELD_CHANGED` events are
|
|
108
|
-
* context-only and don't fire a new `screenOpened`). The Figma
|
|
109
|
-
* `Customfield.filled` surface is therefore a UI sub-state of `inputting`
|
|
110
|
-
* (computed in `mapState` as `canSubmit`), not a discrete SM state, and
|
|
111
|
-
* collapses onto the section's primary `Customfield.empty` screen.
|
|
112
|
-
* - `submitting` → `customfield.processing` — submit in-flight.
|
|
113
|
-
* - `success` → `customfield.complete` — happy-path success surface (auto-
|
|
114
|
-
* advances to `finished` after 3 s).
|
|
115
|
-
* - `finished` is intentionally unmapped: it is dual-outcome (success or
|
|
116
|
-
* failed — failures route here with `result: 'failed'` since the machine
|
|
117
|
-
* has no `error` state) and Figma defines no failure screen. Mapping
|
|
118
|
-
* `finished` onto `customfield.complete` would mis-report failures, so the
|
|
119
|
-
* adapter falls back to the generic `<module>.finished` default.
|
|
120
|
-
*/
|
|
121
|
-
function getCustomFieldsScreenName(snapshot) {
|
|
122
|
-
const stateName = topLevelStateName(snapshot.value);
|
|
123
|
-
if (stateName === void 0) return void 0;
|
|
124
|
-
switch (stateName) {
|
|
125
|
-
case "idle":
|
|
126
|
-
case "inputting": return "Customfield.empty";
|
|
127
|
-
case "submitting": return "customfield.processing";
|
|
128
|
-
case "success": return "customfield.complete";
|
|
129
|
-
default: return;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
function toDisplayLabel(field) {
|
|
133
|
-
if (field.alias) return field.alias;
|
|
134
|
-
return field.name.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase());
|
|
135
|
-
}
|
|
136
|
-
function isFormComplete(fields, customFields) {
|
|
137
|
-
return customFields.every((f) => {
|
|
138
|
-
if (f.type === "BOOLEAN") return true;
|
|
139
|
-
const value = fields[f.name];
|
|
140
|
-
return value !== void 0 && value !== "";
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
function mapState(snapshot) {
|
|
144
|
-
const typedSnapshot = snapshot;
|
|
145
|
-
const { context } = typedSnapshot;
|
|
146
|
-
if (typedSnapshot.matches("idle")) return { status: "idle" };
|
|
147
|
-
if (typedSnapshot.matches("inputting")) return {
|
|
148
|
-
status: "inputting",
|
|
149
|
-
title: context.config.title,
|
|
150
|
-
customFields: context.config.customFields.map((f) => ({
|
|
151
|
-
...f,
|
|
152
|
-
label: toDisplayLabel(f)
|
|
153
|
-
})),
|
|
154
|
-
canSubmit: isFormComplete(context.fields, context.config.customFields)
|
|
155
|
-
};
|
|
156
|
-
if (typedSnapshot.matches("submitting")) return {
|
|
157
|
-
status: "submitting",
|
|
158
|
-
title: context.config.title
|
|
159
|
-
};
|
|
160
|
-
if (typedSnapshot.matches("success")) return { status: "success" };
|
|
161
|
-
return {
|
|
162
|
-
status: "finished",
|
|
163
|
-
result: typedSnapshot.context.result
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
function createApi({ actor }) {
|
|
167
|
-
return {
|
|
168
|
-
/**
|
|
169
|
-
* Initializes the custom fields flow.
|
|
170
|
-
* Transitions from 'idle' to 'inputting'.
|
|
171
|
-
* Must be called before any other method.
|
|
172
|
-
*/
|
|
173
|
-
load() {
|
|
174
|
-
actor.send({ type: "LOAD" });
|
|
175
|
-
},
|
|
176
|
-
/**
|
|
177
|
-
* Updates the value of a single field.
|
|
178
|
-
* Should be called when state is 'inputting'.
|
|
179
|
-
*
|
|
180
|
-
* @param name - The field name (matches CustomField.name)
|
|
181
|
-
* @param value - The field value (string, number, or boolean)
|
|
182
|
-
*/
|
|
183
|
-
setField(name, value) {
|
|
184
|
-
actor.send({
|
|
185
|
-
type: "FIELD_CHANGED",
|
|
186
|
-
name,
|
|
187
|
-
value
|
|
188
|
-
});
|
|
189
|
-
},
|
|
190
|
-
/**
|
|
191
|
-
* Submits all custom field values to the backend.
|
|
192
|
-
* Transitions to 'submitting', then 'finished' regardless of outcome.
|
|
193
|
-
*/
|
|
194
|
-
submit() {
|
|
195
|
-
actor.send({ type: "SUBMIT" });
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Creates a custom fields manager for headless or UI-driven usage.
|
|
201
|
-
*
|
|
202
|
-
* @param options - Configuration options
|
|
203
|
-
* @param options.config - Custom fields configuration (title + field definitions)
|
|
204
|
-
*
|
|
205
|
-
* @returns Custom fields manager with state, API methods, and subscription
|
|
206
|
-
*
|
|
207
|
-
* @example Headless usage
|
|
208
|
-
* ```typescript
|
|
209
|
-
* const manager = createCustomFieldsManager({
|
|
210
|
-
* config: {
|
|
211
|
-
* title: 'Additional Information',
|
|
212
|
-
* customFields: [{ name: 'company', alias: 'Company', type: 'STRING' }],
|
|
213
|
-
* },
|
|
214
|
-
* });
|
|
215
|
-
*
|
|
216
|
-
* manager.subscribe((state) => console.log(state.status));
|
|
217
|
-
* manager.load();
|
|
218
|
-
* manager.setField('company', 'Incode');
|
|
219
|
-
* manager.submit();
|
|
220
|
-
* manager.stop();
|
|
221
|
-
* ```
|
|
222
|
-
*/
|
|
223
|
-
function createCustomFieldsManager(options) {
|
|
224
|
-
return createManager({
|
|
225
|
-
actor: createCustomFieldsActor(options),
|
|
226
|
-
mapState,
|
|
227
|
-
createApi,
|
|
228
|
-
instrumentation: createManagerInstrumentation(eventModuleNames.customFields, { getEventScreenName: getCustomFieldsScreenName })
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
//#endregion
|
|
232
|
-
export { createCustomFieldsManager, customFieldsMachine };
|
|
1
|
+
import { n as createCustomFieldsManagerFromActor, r as customFieldsMachine, t as createCustomFieldsManager } from "./customFieldsManager-6mtAzlY2.esm.js";
|
|
2
|
+
export { createCustomFieldsManager, createCustomFieldsManagerFromActor, customFieldsMachine };
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { t as api } from "./api-Bx3gKW_y.esm.js";
|
|
2
|
+
import { n as eventModuleNames, o as createManagerInstrumentation } from "./events-CxfNJVZW.esm.js";
|
|
3
|
+
import { t as topLevelStateName } from "./topLevelStateName-B5i2avbh.esm.js";
|
|
4
|
+
import { t as endpoints } from "./endpoints-CCzL3XD_.esm.js";
|
|
5
|
+
import { c as createManager, o as createActor, r as assign, t as setup } from "./xstate.esm-Cf4e0Cfd.esm.js";
|
|
6
|
+
import { n as fromPromise } from "./xstate-actors.esm-CtI5S0f4.esm.js";
|
|
7
|
+
import { t as isoDateToMs } from "./dateUtils-CvG0FvK8.esm.js";
|
|
8
|
+
//#region src/modules/custom-fields/customFieldsServices.ts
|
|
9
|
+
async function submitCustomFields(params, signal) {
|
|
10
|
+
const res = await api.post(endpoints.addCustomFields, params.fields, { signal });
|
|
11
|
+
if (!res.ok) throw new Error(`POST ${endpoints.addCustomFields} failed: ${res.status} ${res.statusText}`);
|
|
12
|
+
return res.data;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/modules/custom-fields/customFieldsStateMachine.ts
|
|
16
|
+
const REQUIRED_FIELD_ERROR = "dynamicForms.fieldRequired";
|
|
17
|
+
function transformFields(fields, customFields) {
|
|
18
|
+
const result = {};
|
|
19
|
+
for (const [key, value] of Object.entries(fields)) if (customFields.find((f) => f.name === key)?.type === "DATE" && typeof value === "string" && value !== "") result[key] = isoDateToMs(value);
|
|
20
|
+
else result[key] = value;
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
function isFormComplete(fields, customFields) {
|
|
24
|
+
return customFields.every((field) => {
|
|
25
|
+
if (field.type === "BOOLEAN") return true;
|
|
26
|
+
const value = fields[field.name];
|
|
27
|
+
return value !== void 0 && value !== "";
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function validateRequiredFields(fields, customFields) {
|
|
31
|
+
const errors = {};
|
|
32
|
+
for (const field of customFields) {
|
|
33
|
+
if (field.type === "BOOLEAN") continue;
|
|
34
|
+
const value = fields[field.name];
|
|
35
|
+
if (value === void 0 || value === "") errors[field.name] = REQUIRED_FIELD_ERROR;
|
|
36
|
+
}
|
|
37
|
+
return Object.keys(errors).length > 0 ? errors : void 0;
|
|
38
|
+
}
|
|
39
|
+
const customFieldsMachine = setup({
|
|
40
|
+
types: {
|
|
41
|
+
context: {},
|
|
42
|
+
events: {},
|
|
43
|
+
input: {}
|
|
44
|
+
},
|
|
45
|
+
actors: { submitFields: fromPromise(async ({ input, signal }) => {
|
|
46
|
+
return submitCustomFields({ fields: transformFields(input.fields, input.customFields) }, signal);
|
|
47
|
+
}) },
|
|
48
|
+
actions: {
|
|
49
|
+
setField: assign(({ context, event }) => {
|
|
50
|
+
const e = event;
|
|
51
|
+
const validationErrors = { ...context.validationErrors };
|
|
52
|
+
delete validationErrors[e.name];
|
|
53
|
+
return {
|
|
54
|
+
fields: {
|
|
55
|
+
...context.fields,
|
|
56
|
+
[e.name]: e.value
|
|
57
|
+
},
|
|
58
|
+
validationErrors: Object.keys(validationErrors).length > 0 ? validationErrors : void 0
|
|
59
|
+
};
|
|
60
|
+
}),
|
|
61
|
+
setValidationErrors: assign(({ context }) => ({ validationErrors: validateRequiredFields(context.fields, context.config.customFields) })),
|
|
62
|
+
markSuccess: assign({ result: "success" }),
|
|
63
|
+
markFailed: assign({ result: "failed" })
|
|
64
|
+
},
|
|
65
|
+
guards: {
|
|
66
|
+
apiSucceeded: ({ event }) => event.output.success,
|
|
67
|
+
isFormComplete: ({ context }) => isFormComplete(context.fields, context.config.customFields)
|
|
68
|
+
}
|
|
69
|
+
}).createMachine({
|
|
70
|
+
id: "customFields",
|
|
71
|
+
initial: "idle",
|
|
72
|
+
context: ({ input }) => ({
|
|
73
|
+
config: input.config,
|
|
74
|
+
fields: {},
|
|
75
|
+
validationErrors: void 0,
|
|
76
|
+
result: null
|
|
77
|
+
}),
|
|
78
|
+
states: {
|
|
79
|
+
idle: { on: { LOAD: { target: "inputting" } } },
|
|
80
|
+
inputting: { on: {
|
|
81
|
+
FIELD_CHANGED: { actions: "setField" },
|
|
82
|
+
SUBMIT: [{
|
|
83
|
+
guard: "isFormComplete",
|
|
84
|
+
target: "submitting"
|
|
85
|
+
}, { actions: "setValidationErrors" }]
|
|
86
|
+
} },
|
|
87
|
+
submitting: { invoke: {
|
|
88
|
+
id: "submitFields",
|
|
89
|
+
src: "submitFields",
|
|
90
|
+
input: ({ context }) => ({
|
|
91
|
+
fields: context.fields,
|
|
92
|
+
customFields: context.config.customFields
|
|
93
|
+
}),
|
|
94
|
+
onDone: [{
|
|
95
|
+
target: "success",
|
|
96
|
+
guard: "apiSucceeded"
|
|
97
|
+
}, {
|
|
98
|
+
target: "finished",
|
|
99
|
+
actions: "markFailed"
|
|
100
|
+
}],
|
|
101
|
+
onError: {
|
|
102
|
+
target: "finished",
|
|
103
|
+
actions: "markFailed"
|
|
104
|
+
}
|
|
105
|
+
} },
|
|
106
|
+
success: { after: { 3e3: {
|
|
107
|
+
target: "finished",
|
|
108
|
+
actions: "markSuccess"
|
|
109
|
+
} } },
|
|
110
|
+
finished: { type: "final" }
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/modules/custom-fields/customFieldsActor.ts
|
|
115
|
+
function createCustomFieldsActor(options) {
|
|
116
|
+
return createActor(customFieldsMachine, { input: { config: options.config } }).start();
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/modules/custom-fields/customFieldsManager.ts
|
|
120
|
+
/**
|
|
121
|
+
* Maps a custom-fields state-machine snapshot to the exact Figma "Tracked
|
|
122
|
+
* Events" screen name. Returned strings are the Figma-verbatim absolute
|
|
123
|
+
* analytics path emitted as-is on `event.screen` by
|
|
124
|
+
* `createManagerInstrumentation`'s `getEventScreenName` path. See
|
|
125
|
+
* `docs/patterns/INSTRUMENTATION.md`.
|
|
126
|
+
*
|
|
127
|
+
* Source of truth: Custom Fields Figma file → Tracked Events canvas
|
|
128
|
+
* (`https://www.figma.com/design/Fb4Jp6kal8clAD05Kh6l4e/Custom-fields---Latest-Design?node-id=2026-30075`).
|
|
129
|
+
* The canvas mixes two casings — sections name the input surfaces
|
|
130
|
+
* `Customfield.{empty,filled}` (capital `C`) and the post-input surfaces
|
|
131
|
+
* `customfield.{processing,complete}` (lowercase `c`). Both spellings are
|
|
132
|
+
* preserved verbatim as Figma is the source of truth.
|
|
133
|
+
*
|
|
134
|
+
* State → screen mapping rationale:
|
|
135
|
+
*
|
|
136
|
+
* - `idle`/`inputting` collapse to `Customfield.empty` — the SM stays in
|
|
137
|
+
* `inputting` throughout typing (field-level `FIELD_CHANGED` events are
|
|
138
|
+
* context-only and don't fire a new `screenOpened`). The Figma
|
|
139
|
+
* `Customfield.filled` surface is therefore a UI sub-state of `inputting`,
|
|
140
|
+
* not a discrete SM state, and collapses onto the section's primary
|
|
141
|
+
* `Customfield.empty` screen.
|
|
142
|
+
* - `submitting` → `customfield.processing` — submit in-flight.
|
|
143
|
+
* - `success` → `customfield.complete` — happy-path success surface (auto-
|
|
144
|
+
* advances to `finished` after 3 s).
|
|
145
|
+
* - `finished` is intentionally unmapped: it is dual-outcome (success or
|
|
146
|
+
* failed — failures route here with `result: 'failed'` since the machine
|
|
147
|
+
* has no `error` state) and Figma defines no failure screen. Mapping
|
|
148
|
+
* `finished` onto `customfield.complete` would mis-report failures, so the
|
|
149
|
+
* adapter falls back to the generic `<module>.finished` default.
|
|
150
|
+
*/
|
|
151
|
+
function getCustomFieldsScreenName(snapshot) {
|
|
152
|
+
const stateName = topLevelStateName(snapshot.value);
|
|
153
|
+
if (stateName === void 0) return void 0;
|
|
154
|
+
switch (stateName) {
|
|
155
|
+
case "idle":
|
|
156
|
+
case "inputting": return "Customfield.empty";
|
|
157
|
+
case "submitting": return "customfield.processing";
|
|
158
|
+
case "success": return "customfield.complete";
|
|
159
|
+
default: return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function toDisplayLabel(field) {
|
|
163
|
+
if (field.alias) return field.alias;
|
|
164
|
+
return field.name.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase());
|
|
165
|
+
}
|
|
166
|
+
function mapState(snapshot) {
|
|
167
|
+
const typedSnapshot = snapshot;
|
|
168
|
+
const { context } = typedSnapshot;
|
|
169
|
+
if (typedSnapshot.matches("idle")) return { status: "idle" };
|
|
170
|
+
if (typedSnapshot.matches("inputting")) return {
|
|
171
|
+
status: "inputting",
|
|
172
|
+
title: context.config.title,
|
|
173
|
+
customFields: context.config.customFields.map((f) => ({
|
|
174
|
+
...f,
|
|
175
|
+
label: toDisplayLabel(f)
|
|
176
|
+
})),
|
|
177
|
+
validationErrors: context.validationErrors,
|
|
178
|
+
canSubmit: Object.keys(context.validationErrors ?? {}).length === 0
|
|
179
|
+
};
|
|
180
|
+
if (typedSnapshot.matches("submitting")) return {
|
|
181
|
+
status: "submitting",
|
|
182
|
+
title: context.config.title
|
|
183
|
+
};
|
|
184
|
+
if (typedSnapshot.matches("success")) return { status: "success" };
|
|
185
|
+
return {
|
|
186
|
+
status: "finished",
|
|
187
|
+
result: typedSnapshot.context.result
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function createApi({ actor }) {
|
|
191
|
+
return {
|
|
192
|
+
/**
|
|
193
|
+
* Initializes the custom fields flow.
|
|
194
|
+
* Transitions from 'idle' to 'inputting'.
|
|
195
|
+
* Must be called before any other method.
|
|
196
|
+
*/
|
|
197
|
+
load() {
|
|
198
|
+
actor.send({ type: "LOAD" });
|
|
199
|
+
},
|
|
200
|
+
/**
|
|
201
|
+
* Updates the value of a single field.
|
|
202
|
+
* Should be called when state is 'inputting'.
|
|
203
|
+
*
|
|
204
|
+
* @param name - The field name (matches CustomField.name)
|
|
205
|
+
* @param value - The field value (string, number, or boolean)
|
|
206
|
+
*/
|
|
207
|
+
setField(name, value) {
|
|
208
|
+
actor.send({
|
|
209
|
+
type: "FIELD_CHANGED",
|
|
210
|
+
name,
|
|
211
|
+
value
|
|
212
|
+
});
|
|
213
|
+
},
|
|
214
|
+
/**
|
|
215
|
+
* Submits all custom field values to the backend.
|
|
216
|
+
* Transitions to 'submitting', then 'finished' regardless of outcome.
|
|
217
|
+
*/
|
|
218
|
+
submit() {
|
|
219
|
+
actor.send({ type: "SUBMIT" });
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Creates a custom fields manager for headless or UI-driven usage.
|
|
225
|
+
*
|
|
226
|
+
* @param options - Configuration options
|
|
227
|
+
* @param options.config - Custom fields configuration (title + field definitions)
|
|
228
|
+
*
|
|
229
|
+
* @returns Custom fields manager with state, API methods, and subscription
|
|
230
|
+
*
|
|
231
|
+
* @example Headless usage
|
|
232
|
+
* ```typescript
|
|
233
|
+
* const manager = createCustomFieldsManager({
|
|
234
|
+
* config: {
|
|
235
|
+
* title: 'Additional Information',
|
|
236
|
+
* customFields: [{ name: 'company', alias: 'Company', type: 'STRING' }],
|
|
237
|
+
* },
|
|
238
|
+
* });
|
|
239
|
+
*
|
|
240
|
+
* manager.subscribe((state) => console.log(state.status));
|
|
241
|
+
* manager.load();
|
|
242
|
+
* manager.setField('company', 'Incode');
|
|
243
|
+
* manager.submit();
|
|
244
|
+
* manager.stop();
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
function createCustomFieldsManager(options) {
|
|
248
|
+
return createManager({
|
|
249
|
+
actor: createCustomFieldsActor(options),
|
|
250
|
+
mapState,
|
|
251
|
+
createApi,
|
|
252
|
+
instrumentation: createManagerInstrumentation(eventModuleNames.customFields, { getEventScreenName: getCustomFieldsScreenName })
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
function createCustomFieldsManagerFromActor(actor) {
|
|
256
|
+
return createManager({
|
|
257
|
+
actor,
|
|
258
|
+
mapState,
|
|
259
|
+
createApi,
|
|
260
|
+
instrumentation: createManagerInstrumentation(eventModuleNames.customFields, { getEventScreenName: getCustomFieldsScreenName })
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
//#endregion
|
|
264
|
+
export { createCustomFieldsManagerFromActor as n, customFieldsMachine as r, createCustomFieldsManager as t };
|