datakeen-session-react 1.1.175 → 1.1.176
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/CLAUDE.md +233 -0
- package/dist/cjs/components/legal-consent/LegalConsentNode.js +6 -11
- package/dist/cjs/components/legal-consent/LegalConsentNode.js.map +1 -1
- package/dist/cjs/components/session/UserInputForm/CustomFormFields.js +41 -1
- package/dist/cjs/components/session/UserInputForm/CustomFormFields.js.map +1 -1
- package/dist/cjs/components/signature-electronic/SignatureElectronic.js +4 -5
- package/dist/cjs/components/signature-electronic/SignatureElectronic.js.map +1 -1
- package/dist/cjs/components/template/TemplateNodeRenderer.js +1 -1
- package/dist/cjs/components/template/TemplateNodeRenderer.js.map +1 -1
- package/dist/cjs/i18n/en.json.js +2 -0
- package/dist/cjs/i18n/en.json.js.map +1 -1
- package/dist/cjs/i18n/fr.json.js +2 -0
- package/dist/cjs/i18n/fr.json.js.map +1 -1
- package/dist/cjs/types/session.js.map +1 -1
- package/dist/cjs/utils/conditionEvaluator.js +27 -2
- package/dist/cjs/utils/conditionEvaluator.js.map +1 -1
- package/dist/cjs/utils/renderInlineMarkdown.js +75 -0
- package/dist/cjs/utils/renderInlineMarkdown.js.map +1 -0
- package/dist/esm/components/legal-consent/LegalConsentNode.js +6 -11
- package/dist/esm/components/legal-consent/LegalConsentNode.js.map +1 -1
- package/dist/esm/components/session/UserInputForm/CustomFormFields.js +42 -2
- package/dist/esm/components/session/UserInputForm/CustomFormFields.js.map +1 -1
- package/dist/esm/components/signature-electronic/SignatureElectronic.js +4 -5
- package/dist/esm/components/signature-electronic/SignatureElectronic.js.map +1 -1
- package/dist/esm/components/template/TemplateNodeRenderer.js +1 -1
- package/dist/esm/components/template/TemplateNodeRenderer.js.map +1 -1
- package/dist/esm/i18n/en.json.js +2 -0
- package/dist/esm/i18n/en.json.js.map +1 -1
- package/dist/esm/i18n/fr.json.js +2 -0
- package/dist/esm/i18n/fr.json.js.map +1 -1
- package/dist/esm/types/session.js.map +1 -1
- package/dist/esm/utils/conditionEvaluator.js +27 -2
- package/dist/esm/utils/conditionEvaluator.js.map +1 -1
- package/dist/esm/utils/renderInlineMarkdown.js +73 -0
- package/dist/esm/utils/renderInlineMarkdown.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fr.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fr.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sources":["../../../../src/types/session.ts"],"sourcesContent":["import type React from \"react\";\n\nexport interface SessionConfig {\n selfie?: boolean;\n requireMobile?: boolean;\n}\n\nexport interface DatakeenSessionProps {\n sessionId: string;\n sessionConfig?: SessionConfig;\n apiBaseUrl?: string; // Optional API base URL for dynamic environment configuration\n}\n\nexport interface UseSessionReturn {\n SessionComponent: React.ReactElement;\n}\n\nexport type stepObject = {\n setStep: (step: number) => void;\n goBack: () => void;\n /** Retour arrière vers un nœud précis (ex: \"Corriger ma saisie\") :\n * tronque l'historique jusqu'à `targetStep` au lieu de l'empiler. */\n goBackToStep: (targetStep: number) => void;\n goToNextStep: (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n ) => void;\n step: number;\n canGoBack: boolean;\n};\n\nexport interface ProcessingStep {\n title: string;\n subtitle: string;\n hasError?: boolean;\n}\n\nexport type ConditionTokenType = \"variable\" | \"control\" | \"operator\" | \"input\";\n\nexport interface ConditionToken {\n type: ConditionTokenType;\n value: string;\n label?: string;\n sourceNodeId?: string;\n}\n\n/**\n * Type for custom field value types\n */\nexport type CustomFieldValueType =\n | \"text\"\n | \"enum\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"email\"\n | \"address\"\n | \"list\";\n\n/**\n * Display formats supported for date fields (top-level and list columns).\n */\nexport type DateDisplayFormat = \"dd/mm/yyyy\" | \"mm/dd/yyyy\" | \"yyyy-mm-dd\";\n\nexport const DEFAULT_DATE_DISPLAY_FORMAT: DateDisplayFormat = \"dd/mm/yyyy\";\n\n/**\n * Column definition for a list-type custom field\n */\nexport interface ListColumn {\n label: string;\n type: \"text\" | \"enum\" | \"date\" | \"email\";\n options?: string[]; // required when type === 'enum'\n placeholder?: string; // text/email/date — shown to the end user\n regex?: string; // text — JS regex source (without slashes)\n regexErrorMessage?: string; // text — message displayed when regex fails\n dateFormat?: DateDisplayFormat; // date — display format expected\n}\n\n/**\n * Interface for custom field definition\n */\nexport interface CustomField {\n id: string;\n label: string;\n placeholder?: string;\n description?: string;\n valueType: CustomFieldValueType;\n enumOptions?: string[];\n listColumns?: ListColumn[]; // for list type: column definitions\n minRows?: number; // for list type: minimum rows expected\n required?: boolean;\n regex?: string; // text — JS regex source (without slashes)\n regexErrorMessage?: string; // text — message displayed when regex fails\n dateFormat?: DateDisplayFormat; // date — display format expected\n lockedFromApi?: boolean;\n userInputKey?: string;\n}\n\n/**\n * Interface for session template node\n */\nexport interface SessionTemplateNode {\n id: string;\n type: string;\n title: string;\n description: string;\n informationType?:\n | \"identity\"\n | \"identity-legal\"\n | \"contact\"\n | \"address\"\n | \"nationality\"\n | \"custom\";\n position: {\n x: number;\n y: number;\n };\n options: unknown[];\n selectedOptions: string[];\n requiredDocumentType?: string;\n isRequired: boolean;\n order: number;\n optionalFields?: string[];\n requiredFields?: string[];\n pageTitle?: string;\n pageDescription?: string;\n // Properties for document-collection node type\n allowedDocumentTypes?: Array<{\n id: string;\n name: string;\n /**\n * Optional side information coming from the template.\n * When provided and equals to two (\"two\", 2, \"double\", \"recto-verso\"),\n * consumers should allow uploading two sides (front/back).\n */\n side?: string | number;\n }>;\n allowedAddingMethods?: string[];\n introductionPage?: {\n title?: string;\n description?: string;\n };\n documentSelection?: {\n title?: string;\n description?: string;\n };\n // Start node specific properties\n welcomeTitle?: string;\n welcomeSubtitle?: string;\n welcomeDescription?: string;\n welcomeImage?: string;\n qrCodeTitle?: string;\n qrCodeDescription?: string;\n showLegacyCGU?: boolean; // default: true — rétrocompatibilité\n\n // Legal consent node specific properties\n consentDescription?: string;\n consentDescription2?: string;\n cguUrl?: string;\n privacyPolicyUrl?: string;\n checkboxText?: string;\n // Identity control specific properties\n automaticPhotoCapture?: boolean;\n acceptedCountries?: AcceptedCountry[];\n // End node specific properties\n callbackURL?: string | null;\n // Résultat forcé par le nœud `end` (configuré dans le builder). Sert au SDK à\n // afficher la variante « erreur conservée » de l'écran de fin quand la branche\n // fausse d'une condition pointe directement vers un end non_compliant.\n expectedResult?: string;\n // Condition node specific properties\n conditionExpression?: string;\n conditionTokens?: ConditionToken[];\n conditionFalseErrorMessage?: string;\n conditionMaxRetries?: number;\n conditionMaxRetryAction?: \"end-journey\" | \"force-true\";\n // Undefined is treated as \"loop\" by the SDK for legacy templates.\n conditionFalseMode?: \"retry\" | \"loop\";\n\n // External verification specific properties\n targetApi?: \"INSEE\";\n referenceNodeId?: string;\n referenceNodeType?:\n | \"information-input\"\n | \"document-collection\"\n | \"identity-control\";\n referenceField?: \"siren\" | \"siret\";\n referenceVariable?: string;\n // Custom form fields (for information-input with type 'custom')\n customFields?: CustomField[];\n\n // Electronic signature specific properties\n templateId?: string;\n external_id?: string;\n fieldMappings?: Array<{\n sourceFieldId: string;\n label: string;\n docusealType: string;\n readonly: boolean;\n role?: string;\n sourceNodeId?: string;\n }>;\n /** If set, the generated PDF from this upstream pdf-generation node will be used as the document to sign */\n sourcePdfNodeId?: string;\n\n // PDF generation node specific properties\n // Note: htmlTemplate is intentionally NOT included — it is server-side only and never sent to the client\n pdfMode?: \"upload\" | \"html-template\";\n sourceNodeIds?: string[];\n\n // retry properties\n allowResubmission: boolean;\n maxResubmissionAttempts?: number;\n}\n\n/**\n * Interface for accepted countries\n */\nexport interface AcceptedCountry {\n code: string;\n documents: {\n passport: string[];\n idCard: string[];\n driverLicense: string[];\n residencePermit: string[];\n pinkDriverLicense: string[];\n };\n}\n\n/**\n * Interface for session template edge\n */\nexport interface SessionTemplateEdge {\n id: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n conditionValue?: string;\n}\n\n/**\n * Interface for platform information\n */\nexport interface PlatformInfo {\n mobile: boolean;\n desktop: boolean;\n backoffice: boolean;\n}\n\n/**\n * Interface for session template\n */\n/** Clé du catalogue d'icônes des écrans de fin (mappée vers lucide-react au rendu). */\nexport type EndScreenIcon =\n | \"thanks\"\n | \"send\"\n | \"mail\"\n | \"check\"\n | \"clock\"\n | \"shield\"\n | \"user\"\n | \"info\";\n\nexport interface EndScreenItem {\n icon: EndScreenIcon;\n text: string;\n}\n\nexport interface EndScreenCase {\n title?: string;\n items: EndScreenItem[];\n}\n\n/** Textes de fin personnalisés (config globale du journey). Vide → fallback standard. */\nexport interface EndScreenConfig {\n compliant?: EndScreenCase;\n nonCompliant?: EndScreenCase;\n}\n\nexport interface SessionTemplate {\n id: string;\n name: string;\n description: string;\n version: string;\n languages: string[];\n nodes: SessionTemplateNode[];\n edges: SessionTemplateEdge[];\n groupId: string;\n userId: string | null;\n created_at: string;\n updated_at: string;\n platforms?: PlatformInfo;\n logo?: string;\n showQRCode?: boolean;\n buttonBgColor?: string;\n buttonTextColor?: string;\n endScreenConfig?: EndScreenConfig;\n}\n\n/**\n * Interface for session data\n */\nexport interface SessionData {\n id: string;\n userId: string | null;\n token: string;\n templateId: string;\n templateKey: string;\n expireTime: number;\n status: string;\n result: Record<string, unknown>;\n landingPage: unknown;\n withSelfie: boolean | null;\n groupId: string | null;\n userInput: Record<string, unknown>;\n contactInfo?: {\n email: string;\n phoneNumber: string;\n };\n callbackURL?: string | null;\n webhookURL: string;\n analysisTemplateId: string | null;\n userAgent: unknown[];\n mobile: boolean;\n analysisId: string | null;\n currentStep?: number;\n createdAt: string;\n updatedAt: string;\n auditTrail: unknown[];\n user: unknown | null;\n analysis: unknown[];\n documents: unknown[];\n template: SessionTemplate;\n retryCounts?: Record<string, number>; // nodeId -> retry count\n}\n\nexport interface ClientInfo {\n ip?: string;\n location?: string;\n device: string;\n browser: string;\n os: string;\n}\n"],"names":[],"mappings":"AAiEO,IAAM,2BAA2B,GAAsB;;;;"}
|
|
1
|
+
{"version":3,"file":"session.js","sources":["../../../../src/types/session.ts"],"sourcesContent":["import type React from \"react\";\n\nexport interface SessionConfig {\n selfie?: boolean;\n requireMobile?: boolean;\n}\n\nexport interface DatakeenSessionProps {\n sessionId: string;\n sessionConfig?: SessionConfig;\n apiBaseUrl?: string; // Optional API base URL for dynamic environment configuration\n}\n\nexport interface UseSessionReturn {\n SessionComponent: React.ReactElement;\n}\n\nexport type stepObject = {\n setStep: (step: number) => void;\n goBack: () => void;\n /** Retour arrière vers un nœud précis (ex: \"Corriger ma saisie\") :\n * tronque l'historique jusqu'à `targetStep` au lieu de l'empiler. */\n goBackToStep: (targetStep: number) => void;\n goToNextStep: (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n ) => void;\n step: number;\n canGoBack: boolean;\n};\n\nexport interface ProcessingStep {\n title: string;\n subtitle: string;\n hasError?: boolean;\n}\n\nexport type ConditionTokenType = \"variable\" | \"control\" | \"operator\" | \"input\";\n\nexport interface ConditionToken {\n type: ConditionTokenType;\n value: string;\n label?: string;\n sourceNodeId?: string;\n}\n\n/**\n * Type for custom field value types\n */\nexport type CustomFieldValueType =\n | \"text\"\n | \"enum\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"email\"\n | \"address\"\n | \"list\";\n\n/**\n * Display formats supported for date fields (top-level and list columns).\n */\nexport type DateDisplayFormat = \"dd/mm/yyyy\" | \"mm/dd/yyyy\" | \"yyyy-mm-dd\";\n\nexport const DEFAULT_DATE_DISPLAY_FORMAT: DateDisplayFormat = \"dd/mm/yyyy\";\n\n/**\n * Column definition for a list-type custom field\n */\nexport interface ListColumn {\n label: string;\n type: \"text\" | \"enum\" | \"date\" | \"email\";\n options?: string[]; // required when type === 'enum'\n placeholder?: string; // text/email/date — shown to the end user\n regex?: string; // text — JS regex source (without slashes)\n regexErrorMessage?: string; // text — message displayed when regex fails\n dateFormat?: DateDisplayFormat; // date — display format expected\n}\n\n/**\n * Interface for custom field definition\n */\nexport interface CustomField {\n id: string;\n label: string;\n placeholder?: string;\n description?: string;\n valueType: CustomFieldValueType;\n enumOptions?: string[];\n listColumns?: ListColumn[]; // for list type: column definitions\n minRows?: number; // for list type: minimum rows expected\n required?: boolean;\n regex?: string; // text — JS regex source (without slashes)\n regexErrorMessage?: string; // text — message displayed when regex fails\n dateFormat?: DateDisplayFormat; // date — display format expected\n lockedFromApi?: boolean;\n editableIfMissing?: boolean; // soft lock — éditable si la valeur API est absente\n userInputKey?: string;\n}\n\n/**\n * Interface for session template node\n */\nexport interface SessionTemplateNode {\n id: string;\n type: string;\n title: string;\n description: string;\n informationType?:\n | \"identity\"\n | \"identity-legal\"\n | \"contact\"\n | \"address\"\n | \"nationality\"\n | \"custom\";\n position: {\n x: number;\n y: number;\n };\n options: unknown[];\n selectedOptions: string[];\n requiredDocumentType?: string;\n isRequired: boolean;\n order: number;\n optionalFields?: string[];\n requiredFields?: string[];\n pageTitle?: string;\n pageDescription?: string;\n // Properties for document-collection node type\n allowedDocumentTypes?: Array<{\n id: string;\n name: string;\n /**\n * Optional side information coming from the template.\n * When provided and equals to two (\"two\", 2, \"double\", \"recto-verso\"),\n * consumers should allow uploading two sides (front/back).\n */\n side?: string | number;\n }>;\n allowedAddingMethods?: string[];\n introductionPage?: {\n title?: string;\n description?: string;\n };\n documentSelection?: {\n title?: string;\n description?: string;\n };\n // Start node specific properties\n welcomeTitle?: string;\n welcomeSubtitle?: string;\n welcomeDescription?: string;\n welcomeImage?: string;\n qrCodeTitle?: string;\n qrCodeDescription?: string;\n showLegacyCGU?: boolean; // default: true — rétrocompatibilité\n\n // Legal consent node specific properties\n consentDescription?: string;\n consentDescription2?: string;\n cguUrl?: string;\n privacyPolicyUrl?: string;\n cguLinkLabel?: string;\n privacyLinkLabel?: string;\n checkboxText?: string;\n // Identity control specific properties\n automaticPhotoCapture?: boolean;\n acceptedCountries?: AcceptedCountry[];\n // End node specific properties\n callbackURL?: string | null;\n // Résultat forcé par le nœud `end` (configuré dans le builder). Sert au SDK à\n // afficher la variante « erreur conservée » de l'écran de fin quand la branche\n // fausse d'une condition pointe directement vers un end non_compliant.\n expectedResult?: string;\n // Condition node specific properties\n conditionExpression?: string;\n conditionTokens?: ConditionToken[];\n conditionFalseErrorMessage?: string;\n conditionMaxRetries?: number;\n conditionMaxRetryAction?: \"end-journey\" | \"force-true\";\n // Undefined is treated as \"loop\" by the SDK for legacy templates.\n conditionFalseMode?: \"retry\" | \"loop\";\n\n // External verification specific properties\n targetApi?: \"INSEE\";\n referenceNodeId?: string;\n referenceNodeType?:\n | \"information-input\"\n | \"document-collection\"\n | \"identity-control\";\n referenceField?: \"siren\" | \"siret\";\n referenceVariable?: string;\n // Custom form fields (for information-input with type 'custom')\n customFields?: CustomField[];\n\n // Electronic signature specific properties\n templateId?: string;\n external_id?: string;\n fieldMappings?: Array<{\n sourceFieldId: string;\n label: string;\n docusealType: string;\n readonly: boolean;\n role?: string;\n sourceNodeId?: string;\n }>;\n /** If set, the generated PDF from this upstream pdf-generation node will be used as the document to sign */\n sourcePdfNodeId?: string;\n\n // PDF generation node specific properties\n // Note: htmlTemplate is intentionally NOT included — it is server-side only and never sent to the client\n pdfMode?: \"upload\" | \"html-template\";\n sourceNodeIds?: string[];\n\n // retry properties\n allowResubmission: boolean;\n maxResubmissionAttempts?: number;\n}\n\n/**\n * Interface for accepted countries\n */\nexport interface AcceptedCountry {\n code: string;\n documents: {\n passport: string[];\n idCard: string[];\n driverLicense: string[];\n residencePermit: string[];\n pinkDriverLicense: string[];\n };\n}\n\n/**\n * Interface for session template edge\n */\nexport interface SessionTemplateEdge {\n id: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n conditionValue?: string;\n}\n\n/**\n * Interface for platform information\n */\nexport interface PlatformInfo {\n mobile: boolean;\n desktop: boolean;\n backoffice: boolean;\n}\n\n/**\n * Interface for session template\n */\n/** Clé du catalogue d'icônes des écrans de fin (mappée vers lucide-react au rendu). */\nexport type EndScreenIcon =\n | \"thanks\"\n | \"send\"\n | \"mail\"\n | \"check\"\n | \"clock\"\n | \"shield\"\n | \"user\"\n | \"info\";\n\nexport interface EndScreenItem {\n icon: EndScreenIcon;\n text: string;\n}\n\nexport interface EndScreenCase {\n title?: string;\n items: EndScreenItem[];\n}\n\n/** Textes de fin personnalisés (config globale du journey). Vide → fallback standard. */\nexport interface EndScreenConfig {\n compliant?: EndScreenCase;\n nonCompliant?: EndScreenCase;\n}\n\nexport interface SessionTemplate {\n id: string;\n name: string;\n description: string;\n version: string;\n languages: string[];\n nodes: SessionTemplateNode[];\n edges: SessionTemplateEdge[];\n groupId: string;\n userId: string | null;\n created_at: string;\n updated_at: string;\n platforms?: PlatformInfo;\n logo?: string;\n showQRCode?: boolean;\n buttonBgColor?: string;\n buttonTextColor?: string;\n endScreenConfig?: EndScreenConfig;\n}\n\n/**\n * Interface for session data\n */\nexport interface SessionData {\n id: string;\n userId: string | null;\n token: string;\n templateId: string;\n templateKey: string;\n expireTime: number;\n status: string;\n result: Record<string, unknown>;\n landingPage: unknown;\n withSelfie: boolean | null;\n groupId: string | null;\n userInput: Record<string, unknown>;\n contactInfo?: {\n email: string;\n phoneNumber: string;\n };\n callbackURL?: string | null;\n webhookURL: string;\n analysisTemplateId: string | null;\n userAgent: unknown[];\n mobile: boolean;\n analysisId: string | null;\n currentStep?: number;\n createdAt: string;\n updatedAt: string;\n auditTrail: unknown[];\n user: unknown | null;\n analysis: unknown[];\n documents: unknown[];\n template: SessionTemplate;\n retryCounts?: Record<string, number>; // nodeId -> retry count\n}\n\nexport interface ClientInfo {\n ip?: string;\n location?: string;\n device: string;\n browser: string;\n os: string;\n}\n"],"names":[],"mappings":"AAiEO,IAAM,2BAA2B,GAAsB;;;;"}
|
|
@@ -2,6 +2,9 @@ import { __spreadArray } from '../node_modules/tslib/tslib.es6.js';
|
|
|
2
2
|
|
|
3
3
|
var LOGICAL_OPERATORS = new Set(["&&", "||"]);
|
|
4
4
|
var COMPARISON_OPERATORS = new Set(["==", "===", "!=", "!==", ">", ">=", "<", "<="]);
|
|
5
|
+
// Valeurs sentinelles reconnues comme opérande droite pour tester la présence d'une valeur.
|
|
6
|
+
// Syntaxe builder : « variable == isEmpty » ou « variable != isEmpty »
|
|
7
|
+
var PRESENCE_SENTINELS = new Set(["isEmpty", "isNotEmpty"]);
|
|
5
8
|
var parseConditionExpression = function (expression) {
|
|
6
9
|
if (!expression) {
|
|
7
10
|
return [];
|
|
@@ -10,7 +13,7 @@ var parseConditionExpression = function (expression) {
|
|
|
10
13
|
if (!cleanedExpression) {
|
|
11
14
|
return [];
|
|
12
15
|
}
|
|
13
|
-
var regex = /(
|
|
16
|
+
var regex = /(===|!==|==|!=|<=|>=|&&|\|\||<|>)|("(?:[^"\\]|\\.)*")|([^\s]+)/g;
|
|
14
17
|
var tokens = [];
|
|
15
18
|
var match;
|
|
16
19
|
while ((match = regex.exec(cleanedExpression)) !== null) {
|
|
@@ -115,6 +118,19 @@ var evaluateComparison = function (term, context) {
|
|
|
115
118
|
return false;
|
|
116
119
|
}
|
|
117
120
|
var leftValue = resolveTokenValue(term.left, context);
|
|
121
|
+
// Sentinel « isEmpty » / « isNotEmpty » en opérande droite — teste la présence de la valeur gauche.
|
|
122
|
+
// Syntaxe : « variable == isEmpty » → vide ; « variable != isEmpty » → non vide.
|
|
123
|
+
// De même avec « variable == isNotEmpty » / « variable != isNotEmpty » (sens inversé).
|
|
124
|
+
if (term.right && PRESENCE_SENTINELS.has(term.right.value)) {
|
|
125
|
+
var empty = isEmptyValue(leftValue);
|
|
126
|
+
var sentinelMeansEmpty = term.right.value === "isEmpty";
|
|
127
|
+
if (term.operator === "==" || term.operator === "===") {
|
|
128
|
+
return sentinelMeansEmpty ? empty : !empty;
|
|
129
|
+
}
|
|
130
|
+
if (term.operator === "!=" || term.operator === "!==") {
|
|
131
|
+
return sentinelMeansEmpty ? !empty : empty;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
118
134
|
var rightValue = resolveTokenValue(term.right, context);
|
|
119
135
|
if (leftValue === undefined || rightValue === undefined) {
|
|
120
136
|
console.warn("[EvaluateComparison] Undefined value - left:", leftValue, "right:", rightValue);
|
|
@@ -177,6 +193,15 @@ var isTruthy = function (value) {
|
|
|
177
193
|
return false;
|
|
178
194
|
return true;
|
|
179
195
|
};
|
|
196
|
+
var isEmptyValue = function (value) {
|
|
197
|
+
if (value === null || value === undefined)
|
|
198
|
+
return true;
|
|
199
|
+
if (typeof value === "string")
|
|
200
|
+
return value.trim() === "";
|
|
201
|
+
if (Array.isArray(value))
|
|
202
|
+
return value.length === 0;
|
|
203
|
+
return false;
|
|
204
|
+
};
|
|
180
205
|
var resolveTokenValue = function (token, context) {
|
|
181
206
|
switch (token.type) {
|
|
182
207
|
case "input":
|
|
@@ -437,7 +462,7 @@ var compareValues = function (left, right, comparator) {
|
|
|
437
462
|
return false;
|
|
438
463
|
};
|
|
439
464
|
var determineOperandType = function (value) {
|
|
440
|
-
if (isBooleanLiteral(value) || isNumericLiteral(value)) {
|
|
465
|
+
if (isBooleanLiteral(value) || isNumericLiteral(value) || PRESENCE_SENTINELS.has(value)) {
|
|
441
466
|
return "input";
|
|
442
467
|
}
|
|
443
468
|
return "variable";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conditionEvaluator.js","sources":["../../../../src/utils/conditionEvaluator.ts"],"sourcesContent":["import type { ConditionToken, ConditionTokenType, SessionData } from \"../types/session\";\nimport type { UserInput } from \"../types/userInput\";\nimport type { ContactInfo } from \"../types/contactInfo\";\n\nexport interface ConditionEvaluationContext {\n session: SessionData;\n userInput?: UserInput | Record<string, unknown>;\n contactInfo?: ContactInfo | Record<string, unknown>;\n}\n\nconst LOGICAL_OPERATORS = new Set([\"&&\", \"||\"]);\nconst COMPARISON_OPERATORS = new Set([\"==\", \"===\", \"!=\", \"!==\", \">\", \">=\", \"<\", \"<=\"]);\n\ninterface ComparisonTerm {\n left?: ConditionToken;\n operator?: string;\n right?: ConditionToken;\n}\n\nexport const parseConditionExpression = (expression?: string): ConditionToken[] => {\n if (!expression) {\n return [];\n }\n\n const cleanedExpression = expression.replace(/\\s+/g, \" \").trim();\n if (!cleanedExpression) {\n return [];\n }\n\n const regex = /(===|!==|==|!=|<=|>=|\\&\\&|\\|\\||<|>)|(\"(?:[^\"\\\\]|\\\\.)*\")|([^\\s]+)/g;\n const tokens: ConditionToken[] = [];\n let match: RegExpExecArray | null;\n while ((match = regex.exec(cleanedExpression)) !== null) {\n const value = match[0];\n\n if (LOGICAL_OPERATORS.has(value) || COMPARISON_OPERATORS.has(value)) {\n tokens.push({ type: \"operator\", value });\n } else {\n const isQuoted = value.startsWith(\"\\\"\") && value.endsWith(\"\\\"\");\n const literal = isQuoted ? value.slice(1, -1) : value;\n const tokenType: ConditionTokenType = isQuoted\n ? \"input\"\n : determineOperandType(literal);\n tokens.push({ type: tokenType, value: literal });\n }\n }\n\n return tokens;\n};\n\nexport const evaluateConditionTokens = (\n tokens: ConditionToken[] = [],\n context: ConditionEvaluationContext\n): boolean => {\n if (!tokens || tokens.length === 0) {\n console.warn(\"[ConditionEvaluator] No tokens provided\");\n return false;\n }\n\n const { terms, logicalOperators } = buildComparisonTerms(tokens);\n\n if (terms.length === 0) {\n console.warn(\"[ConditionEvaluator] No comparison terms built\");\n return false;\n }\n\n const termResults = terms.map((term) => evaluateComparison(term, context));\n\n if (termResults.length === 1) {\n return termResults[0];\n }\n\n const finalResult = termResults.reduce((acc, result, index) => {\n if (index === 0) {\n return result;\n }\n const logicalOperator = logicalOperators[index - 1] || \"&&\";\n return logicalOperator === \"||\" ? acc || result : acc && result;\n }, true);\n\n return finalResult;\n};\n\nconst buildComparisonTerms = (tokens: ConditionToken[]) => {\n const terms: ComparisonTerm[] = [];\n const logicalOperators: string[] = [];\n let currentTerm: ComparisonTerm = {};\n\n tokens.forEach((token) => {\n if (token.type === \"operator\") {\n if (LOGICAL_OPERATORS.has(token.value)) {\n // If we have a left operand without comparison operator, treat it as a boolean term\n if (currentTerm.left && !currentTerm.operator) {\n terms.push({ left: currentTerm.left, operator: \"truthy\", right: undefined });\n logicalOperators.push(token.value);\n currentTerm = {};\n } else if (currentTerm.left && currentTerm.operator && currentTerm.right) {\n terms.push(currentTerm);\n logicalOperators.push(token.value);\n currentTerm = {};\n }\n } else if (COMPARISON_OPERATORS.has(token.value)) {\n currentTerm.operator = token.value;\n }\n } else {\n if (!currentTerm.left) {\n currentTerm.left = token;\n } else if (!currentTerm.right) {\n currentTerm.right = token;\n } else {\n currentTerm = { left: token };\n }\n }\n });\n\n // Handle the last term\n if (currentTerm.left) {\n if (!currentTerm.operator) {\n terms.push({ left: currentTerm.left, operator: \"truthy\", right: undefined });\n } else if (currentTerm.right) {\n terms.push(currentTerm);\n }\n }\n\n return { terms, logicalOperators };\n};\n\nconst evaluateComparison = (\n term: ComparisonTerm,\n context: ConditionEvaluationContext\n): boolean => {\n if (!term.left || !term.operator) {\n console.warn(\"[EvaluateComparison] Incomplete term - missing left or operator\");\n return false;\n }\n\n // Handle boolean/truthy evaluation (no right operand)\n if (term.operator === \"truthy\") {\n const leftValue = resolveTokenValue(term.left, context);\n return isTruthy(leftValue);\n }\n\n // Standard comparison requires both operands\n if (!term.right) {\n console.warn(\"[EvaluateComparison] Comparison operator requires right operand\");\n return false;\n }\n\n const leftValue = resolveTokenValue(term.left, context);\n const rightValue = resolveTokenValue(term.right, context);\n\n if (leftValue === undefined || rightValue === undefined) {\n console.warn(\"[EvaluateComparison] Undefined value - left:\", leftValue, \"right:\", rightValue);\n return false;\n }\n\n const trimIfString = (v: unknown) =>\n typeof v === \"string\" ? v.trim() : v;\n\n const leftComparable = trimIfString(coerceValue(leftValue));\n const rightComparable = trimIfString(coerceValue(rightValue));\n\n console.log(\"[EvaluateComparison]\", leftComparable, term.operator, rightComparable);\n\n let result: boolean;\n switch (term.operator) {\n case \"==\":\n result = leftComparable == rightComparable; // eslint-disable-line eqeqeq\n break;\n case \"===\":\n result = leftComparable === rightComparable;\n break;\n case \"!=\":\n result = leftComparable != rightComparable; // eslint-disable-line eqeqeq\n break;\n case \"!==\":\n result = leftComparable !== rightComparable;\n break;\n case \">\":\n result = compareValues(leftComparable, rightComparable, (a, b) => a > b);\n break;\n case \">=\":\n result = compareValues(leftComparable, rightComparable, (a, b) => a >= b);\n break;\n case \"<\":\n result = compareValues(leftComparable, rightComparable, (a, b) => a < b);\n break;\n case \"<=\":\n result = compareValues(leftComparable, rightComparable, (a, b) => a <= b);\n break;\n default:\n console.warn(\"[EvaluateComparison] Unknown operator:\", term.operator);\n result = false;\n }\n\n console.log(\"[EvaluateComparison] Result:\", result);\n return result;\n};\n\nconst isTruthy = (value: unknown): boolean => {\n if (typeof value === \"boolean\") return value;\n if (typeof value === \"string\") {\n const lower = value.toLowerCase();\n if (lower === \"true\") return true;\n if (lower === \"false\") return false;\n }\n if (typeof value === \"number\") return value !== 0;\n if (value === null || value === undefined) return false;\n if (value === \"\") return false;\n return true;\n};\n\nconst resolveTokenValue = (\n token: ConditionToken,\n context: ConditionEvaluationContext\n): unknown => {\n switch (token.type) {\n case \"input\":\n return parseLiteral(token.value);\n case \"variable\":\n case \"control\":\n return resolvePathValue(token.value, context, token.sourceNodeId);\n default:\n console.warn(\"[ResolveTokenValue] Unknown token type:\", token.type);\n return undefined;\n }\n};\n\nconst FIELD_ALIASES: Record<string, string[]> = {\n nom: [\"lastName\", \"companyName\"],\n prenom: [\"firstName\"],\n email: [\"email\"],\n sms: [\"phoneNumber\"],\n date_naissance: [\"birthDate\"],\n adresse: [\"addressLine1\"],\n ville: [\"city\"],\n code_postal: [\"postalCode\"],\n pays: [\"countryCode\", \"country\"],\n nationalite: [\"nationality\"],\n};\n\nconst resolvePathValue = (\n path: string,\n context: ConditionEvaluationContext,\n sourceNodeId?: string\n): unknown => {\n if (!path) {\n console.warn(\"[ResolvePathValue] Empty path provided\");\n return undefined;\n }\n\n const segments = path.split(\".\").filter(Boolean);\n\n if (segments.length === 0) {\n console.warn(\"[ResolvePathValue] No segments after splitting path\");\n return undefined;\n }\n\n const sources: Array<Record<string, unknown> | undefined> = [\n context.session?.result as Record<string, unknown>,\n context.session?.userInput as Record<string, unknown>,\n context.session?.contactInfo as Record<string, unknown>,\n context.userInput as Record<string, unknown>,\n context.contactInfo as Record<string, unknown>,\n context.session as unknown as Record<string, unknown>,\n ];\n\n // Helper to resolve aliases\n const getPossibleKeys = (key: string): string[] => {\n return [key, ...(FIELD_ALIASES[key] || [])];\n };\n\n // 1. Try direct/nested resolution with alias support for the last segment\n for (const source of sources) {\n if (!source) continue;\n\n const parentPath = segments.slice(0, -1);\n const lastSegment = segments[segments.length - 1];\n const parent = parentPath.length > 0 ? getNestedValue(source, parentPath) : source;\n\n if (parent && typeof parent === \"object\") {\n for (const key of getPossibleKeys(lastSegment)) {\n const value = (parent as Record<string, unknown>)[key];\n if (value !== undefined) {\n console.log(`[ResolvePathValue] Found ${path} (as ${key}) in direct sources`);\n return extractValue(value);\n }\n }\n }\n }\n\n // 2. Handle nodeId prefixes and fallbacks\n if (segments.length > 1) {\n const [root, ...rest] = segments;\n const lastSegment = segments[segments.length - 1];\n\n // Check in contextual userInput (structured by node or flat)\n if (context.userInput && typeof context.userInput === \"object\") {\n const userInput = context.userInput as Record<string, unknown>;\n\n // A. Try structured by nodeId\n const nodeData = userInput[root];\n if (nodeData && typeof nodeData === \"object\") {\n const value = getNestedValue(nodeData as Record<string, unknown>, rest);\n if (value !== undefined) {\n console.log(`[ResolvePathValue] Found ${path} in contextual userInput (nested)`);\n return extractValue(value);\n }\n }\n\n // B. Flat fallback: search for the property directly if it's a node-ID.property\n for (const key of getPossibleKeys(lastSegment)) {\n if (userInput[key] !== undefined) {\n console.log(`[ResolvePathValue] Found ${lastSegment} (as ${key}) in flat userInput`);\n return extractValue(userInput[key]);\n }\n\n // C. Check in customFormData\n const customFormData = userInput[\"customFormData\"] as Record<string, unknown> | undefined;\n if (customFormData && customFormData[key] !== undefined) {\n console.log(`[ResolvePathValue] Found ${lastSegment} (as ${key}) in customFormData`);\n return extractValue(customFormData[key]);\n }\n }\n }\n\n const analysisEntries = Array.isArray(context.session?.analysis)\n ? (context.session.analysis as Array<Record<string, unknown>>)\n : [];\n\n // If sourceNodeId is provided, use it to find the relevant analysis entry\n if (sourceNodeId || segments.length > 1) {\n const targetNodeId = sourceNodeId || root;\n const relevantEntries = analysisEntries.filter((entry) => {\n const entryRecord = entry as Record<string, unknown>;\n return entryRecord[\"nodeId\"] === targetNodeId || entryRecord[\"id\"] === targetNodeId;\n });\n\n if (relevantEntries.length > 0) {\n // Use the most recent entry (last one in array)\n const targetEntry = relevantEntries[relevantEntries.length - 1];\n\n // Check if the first segment is a hash/identifier that should be skipped\n const isHashLikeId = /^[a-f0-9]{24}$/i.test(root);\n const pathToResolve = isHashLikeId ? rest : [root, ...rest];\n\n // For control tokens, look in the documents array associated with this analysis entry\n if (pathToResolve.length > 0) {\n const propertyName = pathToResolve[pathToResolve.length - 1];\n const propertyKeys = getPossibleKeys(propertyName);\n\n const documents = Array.isArray(context.session?.documents)\n ? (context.session.documents as Array<Record<string, unknown>>)\n : [];\n\n if (documents.length > 0) {\n const analysisId = targetEntry[\"id\"] as string;\n const relevantDocs = documents.filter((doc) => doc[\"analysisId\"] === analysisId);\n\n if (relevantDocs.length > 0) {\n const doc = relevantDocs[0];\n\n // Look in controlCategories for control properties\n const controlCategories = doc[\"controlCategories\"] as Record<string, unknown> | undefined;\n if (controlCategories) {\n for (const categoryData of Object.values(controlCategories)) {\n const category = categoryData as Record<string, unknown>;\n const controls = category[\"controls\"] as Record<string, unknown> | undefined;\n\n if (controls) {\n for (const key of propertyKeys) {\n if (key in controls) {\n const control = controls[key] as Record<string, unknown>;\n return extractValue(control[\"value\"]);\n }\n }\n }\n }\n }\n\n // Also check in extractedInformations\n const extractedInformations = doc[\"extractedInformations\"] as Record<string, unknown> | undefined;\n if (extractedInformations) {\n for (const key of propertyKeys) {\n const valueFromExtracted = getNestedValue(extractedInformations, [key]);\n if (valueFromExtracted !== undefined) {\n return extractValue(valueFromExtracted);\n }\n }\n }\n }\n }\n }\n\n // Try direct access on analysis entry with aliases\n const propertyName = segments[segments.length - 1];\n for (const key of getPossibleKeys(propertyName)) {\n const valueFromEntry = (targetEntry as Record<string, unknown>)[key];\n if (valueFromEntry !== undefined) {\n return extractValue(valueFromEntry);\n }\n\n const extractedInfo = (targetEntry as Record<string, unknown>)[\n \"extractedInformation\"\n ] as Record<string, unknown> | undefined;\n if (extractedInfo && extractedInfo[key] !== undefined) {\n return extractValue(extractedInfo[key]);\n }\n\n const resultInfo = (targetEntry as Record<string, unknown>)[\n \"result\"\n ] as Record<string, unknown> | undefined;\n if (resultInfo && resultInfo[key] !== undefined) {\n return extractValue(resultInfo[key]);\n }\n }\n }\n }\n }\n\n console.warn(\"⚠️ [ResolvePathValue] Could not resolve path:\", path);\n return undefined;\n};\n\n/**\n * Extracts the actual value from objects with {confidence, value} structure.\n * This is common in extractedInformations from the API.\n */\nconst extractValue = (value: unknown): unknown => {\n // If it's an object with both 'value' and 'confidence' properties, extract the value\n if (\n value &&\n typeof value === \"object\" &&\n \"value\" in value &&\n \"confidence\" in value\n ) {\n return (value as Record<string, unknown>)[\"value\"];\n }\n return value;\n};\n\nconst getNestedValue = (\n source: Record<string, unknown> | undefined,\n path: string[]\n): unknown => {\n if (!source) {\n return undefined;\n }\n\n return path.reduce<unknown>((acc, key) => {\n if (acc === undefined || acc === null) {\n return undefined;\n }\n if (Array.isArray(acc)) {\n const index = Number(key);\n if (Number.isNaN(index)) {\n return undefined;\n }\n return acc[index];\n }\n if (typeof acc === \"object\") {\n return (acc as Record<string, unknown>)[key];\n }\n return undefined;\n }, source);\n};\n\nconst parseLiteral = (value: string): unknown => {\n const trimmed = value?.trim();\n if (!trimmed) {\n return \"\";\n }\n\n if (trimmed.toLowerCase() === \"true\") {\n return true;\n }\n if (trimmed.toLowerCase() === \"false\") {\n return false;\n }\n\n const numericValue = Number(trimmed);\n if (!Number.isNaN(numericValue)) {\n return numericValue;\n }\n\n const timestamp = Date.parse(trimmed);\n if (!Number.isNaN(timestamp)) {\n return new Date(timestamp).getTime();\n }\n return trimmed.replace(/\"/g, '');\n};\n\nconst coerceValue = (value: unknown): unknown => {\n if (value instanceof Date) {\n return value.getTime();\n }\n if (typeof value === \"string\") {\n const literal = parseLiteral(value);\n if (literal !== value) {\n return literal;\n }\n }\n return value;\n};\n\nconst compareValues = (\n left: unknown,\n right: unknown,\n comparator: (a: number | string, b: number | string) => boolean\n): boolean => {\n if (typeof left === \"number\" && typeof right === \"number\") {\n return comparator(left, right);\n }\n\n if (typeof left === \"string\" && typeof right === \"string\") {\n // Normalize case for better string matching\n return comparator(left.trim().toLowerCase(), right.trim().toLowerCase());\n }\n\n console.warn(`[CompareValues] Type mismatch: left=${typeof left}, right=${typeof right}`);\n return false;\n};\n\nconst determineOperandType = (value: string): ConditionTokenType => {\n if (isBooleanLiteral(value) || isNumericLiteral(value)) {\n return \"input\";\n }\n\n return \"variable\";\n};\n\nconst isNumericLiteral = (value: string): boolean => {\n return /^-?\\d+(?:\\.\\d+)?$/.test(value);\n};\n\nconst isBooleanLiteral = (value: string): boolean => {\n return value.toLowerCase() === \"true\" || value.toLowerCase() === \"false\";\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"conditionEvaluator.js","sources":["../../../../src/utils/conditionEvaluator.ts"],"sourcesContent":["import type { ConditionToken, ConditionTokenType, SessionData } from \"../types/session\";\nimport type { UserInput } from \"../types/userInput\";\nimport type { ContactInfo } from \"../types/contactInfo\";\n\nexport interface ConditionEvaluationContext {\n session: SessionData;\n userInput?: UserInput | Record<string, unknown>;\n contactInfo?: ContactInfo | Record<string, unknown>;\n}\n\nconst LOGICAL_OPERATORS = new Set([\"&&\", \"||\"]);\nconst COMPARISON_OPERATORS = new Set([\"==\", \"===\", \"!=\", \"!==\", \">\", \">=\", \"<\", \"<=\"]);\n\n// Valeurs sentinelles reconnues comme opérande droite pour tester la présence d'une valeur.\n// Syntaxe builder : « variable == isEmpty » ou « variable != isEmpty »\nconst PRESENCE_SENTINELS = new Set([\"isEmpty\", \"isNotEmpty\"]);\n\ninterface ComparisonTerm {\n left?: ConditionToken;\n operator?: string;\n right?: ConditionToken;\n}\n\nexport const parseConditionExpression = (expression?: string): ConditionToken[] => {\n if (!expression) {\n return [];\n }\n\n const cleanedExpression = expression.replace(/\\s+/g, \" \").trim();\n if (!cleanedExpression) {\n return [];\n }\n\n const regex = /(===|!==|==|!=|<=|>=|&&|\\|\\||<|>)|(\"(?:[^\"\\\\]|\\\\.)*\")|([^\\s]+)/g;\n const tokens: ConditionToken[] = [];\n let match: RegExpExecArray | null;\n while ((match = regex.exec(cleanedExpression)) !== null) {\n const value = match[0];\n\n if (LOGICAL_OPERATORS.has(value) || COMPARISON_OPERATORS.has(value)) {\n tokens.push({ type: \"operator\", value });\n } else {\n const isQuoted = value.startsWith(\"\\\"\") && value.endsWith(\"\\\"\");\n const literal = isQuoted ? value.slice(1, -1) : value;\n const tokenType: ConditionTokenType = isQuoted\n ? \"input\"\n : determineOperandType(literal);\n tokens.push({ type: tokenType, value: literal });\n }\n }\n\n return tokens;\n};\n\nexport const evaluateConditionTokens = (\n tokens: ConditionToken[] = [],\n context: ConditionEvaluationContext\n): boolean => {\n if (!tokens || tokens.length === 0) {\n console.warn(\"[ConditionEvaluator] No tokens provided\");\n return false;\n }\n\n const { terms, logicalOperators } = buildComparisonTerms(tokens);\n\n if (terms.length === 0) {\n console.warn(\"[ConditionEvaluator] No comparison terms built\");\n return false;\n }\n\n const termResults = terms.map((term) => evaluateComparison(term, context));\n\n if (termResults.length === 1) {\n return termResults[0];\n }\n\n const finalResult = termResults.reduce((acc, result, index) => {\n if (index === 0) {\n return result;\n }\n const logicalOperator = logicalOperators[index - 1] || \"&&\";\n return logicalOperator === \"||\" ? acc || result : acc && result;\n }, true);\n\n return finalResult;\n};\n\nconst buildComparisonTerms = (tokens: ConditionToken[]) => {\n const terms: ComparisonTerm[] = [];\n const logicalOperators: string[] = [];\n let currentTerm: ComparisonTerm = {};\n\n tokens.forEach((token) => {\n if (token.type === \"operator\") {\n if (LOGICAL_OPERATORS.has(token.value)) {\n // If we have a left operand without comparison operator, treat it as a boolean term\n if (currentTerm.left && !currentTerm.operator) {\n terms.push({ left: currentTerm.left, operator: \"truthy\", right: undefined });\n logicalOperators.push(token.value);\n currentTerm = {};\n } else if (currentTerm.left && currentTerm.operator && currentTerm.right) {\n terms.push(currentTerm);\n logicalOperators.push(token.value);\n currentTerm = {};\n }\n } else if (COMPARISON_OPERATORS.has(token.value)) {\n currentTerm.operator = token.value;\n }\n } else {\n if (!currentTerm.left) {\n currentTerm.left = token;\n } else if (!currentTerm.right) {\n currentTerm.right = token;\n } else {\n currentTerm = { left: token };\n }\n }\n });\n\n // Handle the last term\n if (currentTerm.left) {\n if (!currentTerm.operator) {\n terms.push({ left: currentTerm.left, operator: \"truthy\", right: undefined });\n } else if (currentTerm.right) {\n terms.push(currentTerm);\n }\n }\n\n return { terms, logicalOperators };\n};\n\nconst evaluateComparison = (\n term: ComparisonTerm,\n context: ConditionEvaluationContext\n): boolean => {\n if (!term.left || !term.operator) {\n console.warn(\"[EvaluateComparison] Incomplete term - missing left or operator\");\n return false;\n }\n\n // Handle boolean/truthy evaluation (no right operand)\n if (term.operator === \"truthy\") {\n const leftValue = resolveTokenValue(term.left, context);\n return isTruthy(leftValue);\n }\n\n // Standard comparison requires both operands\n if (!term.right) {\n console.warn(\"[EvaluateComparison] Comparison operator requires right operand\");\n return false;\n }\n\n const leftValue = resolveTokenValue(term.left, context);\n\n // Sentinel « isEmpty » / « isNotEmpty » en opérande droite — teste la présence de la valeur gauche.\n // Syntaxe : « variable == isEmpty » → vide ; « variable != isEmpty » → non vide.\n // De même avec « variable == isNotEmpty » / « variable != isNotEmpty » (sens inversé).\n if (term.right && PRESENCE_SENTINELS.has(term.right.value)) {\n const empty = isEmptyValue(leftValue);\n const sentinelMeansEmpty = term.right.value === \"isEmpty\";\n if (term.operator === \"==\" || term.operator === \"===\") {\n return sentinelMeansEmpty ? empty : !empty;\n }\n if (term.operator === \"!=\" || term.operator === \"!==\") {\n return sentinelMeansEmpty ? !empty : empty;\n }\n }\n\n const rightValue = resolveTokenValue(term.right, context);\n\n if (leftValue === undefined || rightValue === undefined) {\n console.warn(\"[EvaluateComparison] Undefined value - left:\", leftValue, \"right:\", rightValue);\n return false;\n }\n\n const trimIfString = (v: unknown) =>\n typeof v === \"string\" ? v.trim() : v;\n\n const leftComparable = trimIfString(coerceValue(leftValue));\n const rightComparable = trimIfString(coerceValue(rightValue));\n\n console.log(\"[EvaluateComparison]\", leftComparable, term.operator, rightComparable);\n\n let result: boolean;\n switch (term.operator) {\n case \"==\":\n result = leftComparable == rightComparable; // eslint-disable-line eqeqeq\n break;\n case \"===\":\n result = leftComparable === rightComparable;\n break;\n case \"!=\":\n result = leftComparable != rightComparable; // eslint-disable-line eqeqeq\n break;\n case \"!==\":\n result = leftComparable !== rightComparable;\n break;\n case \">\":\n result = compareValues(leftComparable, rightComparable, (a, b) => a > b);\n break;\n case \">=\":\n result = compareValues(leftComparable, rightComparable, (a, b) => a >= b);\n break;\n case \"<\":\n result = compareValues(leftComparable, rightComparable, (a, b) => a < b);\n break;\n case \"<=\":\n result = compareValues(leftComparable, rightComparable, (a, b) => a <= b);\n break;\n default:\n console.warn(\"[EvaluateComparison] Unknown operator:\", term.operator);\n result = false;\n }\n\n console.log(\"[EvaluateComparison] Result:\", result);\n return result;\n};\n\nconst isTruthy = (value: unknown): boolean => {\n if (typeof value === \"boolean\") return value;\n if (typeof value === \"string\") {\n const lower = value.toLowerCase();\n if (lower === \"true\") return true;\n if (lower === \"false\") return false;\n }\n if (typeof value === \"number\") return value !== 0;\n if (value === null || value === undefined) return false;\n if (value === \"\") return false;\n return true;\n};\n\nconst isEmptyValue = (value: unknown): boolean => {\n if (value === null || value === undefined) return true;\n if (typeof value === \"string\") return value.trim() === \"\";\n if (Array.isArray(value)) return value.length === 0;\n return false;\n};\n\nconst resolveTokenValue = (\n token: ConditionToken,\n context: ConditionEvaluationContext\n): unknown => {\n switch (token.type) {\n case \"input\":\n return parseLiteral(token.value);\n case \"variable\":\n case \"control\":\n return resolvePathValue(token.value, context, token.sourceNodeId);\n default:\n console.warn(\"[ResolveTokenValue] Unknown token type:\", token.type);\n return undefined;\n }\n};\n\nconst FIELD_ALIASES: Record<string, string[]> = {\n nom: [\"lastName\", \"companyName\"],\n prenom: [\"firstName\"],\n email: [\"email\"],\n sms: [\"phoneNumber\"],\n date_naissance: [\"birthDate\"],\n adresse: [\"addressLine1\"],\n ville: [\"city\"],\n code_postal: [\"postalCode\"],\n pays: [\"countryCode\", \"country\"],\n nationalite: [\"nationality\"],\n};\n\nconst resolvePathValue = (\n path: string,\n context: ConditionEvaluationContext,\n sourceNodeId?: string\n): unknown => {\n if (!path) {\n console.warn(\"[ResolvePathValue] Empty path provided\");\n return undefined;\n }\n\n const segments = path.split(\".\").filter(Boolean);\n\n if (segments.length === 0) {\n console.warn(\"[ResolvePathValue] No segments after splitting path\");\n return undefined;\n }\n\n const sources: Array<Record<string, unknown> | undefined> = [\n context.session?.result as Record<string, unknown>,\n context.session?.userInput as Record<string, unknown>,\n context.session?.contactInfo as Record<string, unknown>,\n context.userInput as Record<string, unknown>,\n context.contactInfo as Record<string, unknown>,\n context.session as unknown as Record<string, unknown>,\n ];\n\n // Helper to resolve aliases\n const getPossibleKeys = (key: string): string[] => {\n return [key, ...(FIELD_ALIASES[key] || [])];\n };\n\n // 1. Try direct/nested resolution with alias support for the last segment\n for (const source of sources) {\n if (!source) continue;\n\n const parentPath = segments.slice(0, -1);\n const lastSegment = segments[segments.length - 1];\n const parent = parentPath.length > 0 ? getNestedValue(source, parentPath) : source;\n\n if (parent && typeof parent === \"object\") {\n for (const key of getPossibleKeys(lastSegment)) {\n const value = (parent as Record<string, unknown>)[key];\n if (value !== undefined) {\n console.log(`[ResolvePathValue] Found ${path} (as ${key}) in direct sources`);\n return extractValue(value);\n }\n }\n }\n }\n\n // 2. Handle nodeId prefixes and fallbacks\n if (segments.length > 1) {\n const [root, ...rest] = segments;\n const lastSegment = segments[segments.length - 1];\n\n // Check in contextual userInput (structured by node or flat)\n if (context.userInput && typeof context.userInput === \"object\") {\n const userInput = context.userInput as Record<string, unknown>;\n\n // A. Try structured by nodeId\n const nodeData = userInput[root];\n if (nodeData && typeof nodeData === \"object\") {\n const value = getNestedValue(nodeData as Record<string, unknown>, rest);\n if (value !== undefined) {\n console.log(`[ResolvePathValue] Found ${path} in contextual userInput (nested)`);\n return extractValue(value);\n }\n }\n\n // B. Flat fallback: search for the property directly if it's a node-ID.property\n for (const key of getPossibleKeys(lastSegment)) {\n if (userInput[key] !== undefined) {\n console.log(`[ResolvePathValue] Found ${lastSegment} (as ${key}) in flat userInput`);\n return extractValue(userInput[key]);\n }\n\n // C. Check in customFormData\n const customFormData = userInput[\"customFormData\"] as Record<string, unknown> | undefined;\n if (customFormData && customFormData[key] !== undefined) {\n console.log(`[ResolvePathValue] Found ${lastSegment} (as ${key}) in customFormData`);\n return extractValue(customFormData[key]);\n }\n }\n }\n\n const analysisEntries = Array.isArray(context.session?.analysis)\n ? (context.session.analysis as Array<Record<string, unknown>>)\n : [];\n\n // If sourceNodeId is provided, use it to find the relevant analysis entry\n if (sourceNodeId || segments.length > 1) {\n const targetNodeId = sourceNodeId || root;\n const relevantEntries = analysisEntries.filter((entry) => {\n const entryRecord = entry as Record<string, unknown>;\n return entryRecord[\"nodeId\"] === targetNodeId || entryRecord[\"id\"] === targetNodeId;\n });\n\n if (relevantEntries.length > 0) {\n // Use the most recent entry (last one in array)\n const targetEntry = relevantEntries[relevantEntries.length - 1];\n\n // Check if the first segment is a hash/identifier that should be skipped\n const isHashLikeId = /^[a-f0-9]{24}$/i.test(root);\n const pathToResolve = isHashLikeId ? rest : [root, ...rest];\n\n // For control tokens, look in the documents array associated with this analysis entry\n if (pathToResolve.length > 0) {\n const propertyName = pathToResolve[pathToResolve.length - 1];\n const propertyKeys = getPossibleKeys(propertyName);\n\n const documents = Array.isArray(context.session?.documents)\n ? (context.session.documents as Array<Record<string, unknown>>)\n : [];\n\n if (documents.length > 0) {\n const analysisId = targetEntry[\"id\"] as string;\n const relevantDocs = documents.filter((doc) => doc[\"analysisId\"] === analysisId);\n\n if (relevantDocs.length > 0) {\n const doc = relevantDocs[0];\n\n // Look in controlCategories for control properties\n const controlCategories = doc[\"controlCategories\"] as Record<string, unknown> | undefined;\n if (controlCategories) {\n for (const categoryData of Object.values(controlCategories)) {\n const category = categoryData as Record<string, unknown>;\n const controls = category[\"controls\"] as Record<string, unknown> | undefined;\n\n if (controls) {\n for (const key of propertyKeys) {\n if (key in controls) {\n const control = controls[key] as Record<string, unknown>;\n return extractValue(control[\"value\"]);\n }\n }\n }\n }\n }\n\n // Also check in extractedInformations\n const extractedInformations = doc[\"extractedInformations\"] as Record<string, unknown> | undefined;\n if (extractedInformations) {\n for (const key of propertyKeys) {\n const valueFromExtracted = getNestedValue(extractedInformations, [key]);\n if (valueFromExtracted !== undefined) {\n return extractValue(valueFromExtracted);\n }\n }\n }\n }\n }\n }\n\n // Try direct access on analysis entry with aliases\n const propertyName = segments[segments.length - 1];\n for (const key of getPossibleKeys(propertyName)) {\n const valueFromEntry = (targetEntry as Record<string, unknown>)[key];\n if (valueFromEntry !== undefined) {\n return extractValue(valueFromEntry);\n }\n\n const extractedInfo = (targetEntry as Record<string, unknown>)[\n \"extractedInformation\"\n ] as Record<string, unknown> | undefined;\n if (extractedInfo && extractedInfo[key] !== undefined) {\n return extractValue(extractedInfo[key]);\n }\n\n const resultInfo = (targetEntry as Record<string, unknown>)[\n \"result\"\n ] as Record<string, unknown> | undefined;\n if (resultInfo && resultInfo[key] !== undefined) {\n return extractValue(resultInfo[key]);\n }\n }\n }\n }\n }\n\n console.warn(\"⚠️ [ResolvePathValue] Could not resolve path:\", path);\n return undefined;\n};\n\n/**\n * Extracts the actual value from objects with {confidence, value} structure.\n * This is common in extractedInformations from the API.\n */\nconst extractValue = (value: unknown): unknown => {\n // If it's an object with both 'value' and 'confidence' properties, extract the value\n if (\n value &&\n typeof value === \"object\" &&\n \"value\" in value &&\n \"confidence\" in value\n ) {\n return (value as Record<string, unknown>)[\"value\"];\n }\n return value;\n};\n\nconst getNestedValue = (\n source: Record<string, unknown> | undefined,\n path: string[]\n): unknown => {\n if (!source) {\n return undefined;\n }\n\n return path.reduce<unknown>((acc, key) => {\n if (acc === undefined || acc === null) {\n return undefined;\n }\n if (Array.isArray(acc)) {\n const index = Number(key);\n if (Number.isNaN(index)) {\n return undefined;\n }\n return acc[index];\n }\n if (typeof acc === \"object\") {\n return (acc as Record<string, unknown>)[key];\n }\n return undefined;\n }, source);\n};\n\nconst parseLiteral = (value: string): unknown => {\n const trimmed = value?.trim();\n if (!trimmed) {\n return \"\";\n }\n\n if (trimmed.toLowerCase() === \"true\") {\n return true;\n }\n if (trimmed.toLowerCase() === \"false\") {\n return false;\n }\n\n const numericValue = Number(trimmed);\n if (!Number.isNaN(numericValue)) {\n return numericValue;\n }\n\n const timestamp = Date.parse(trimmed);\n if (!Number.isNaN(timestamp)) {\n return new Date(timestamp).getTime();\n }\n return trimmed.replace(/\"/g, '');\n};\n\nconst coerceValue = (value: unknown): unknown => {\n if (value instanceof Date) {\n return value.getTime();\n }\n if (typeof value === \"string\") {\n const literal = parseLiteral(value);\n if (literal !== value) {\n return literal;\n }\n }\n return value;\n};\n\nconst compareValues = (\n left: unknown,\n right: unknown,\n comparator: (a: number | string, b: number | string) => boolean\n): boolean => {\n if (typeof left === \"number\" && typeof right === \"number\") {\n return comparator(left, right);\n }\n\n if (typeof left === \"string\" && typeof right === \"string\") {\n // Normalize case for better string matching\n return comparator(left.trim().toLowerCase(), right.trim().toLowerCase());\n }\n\n console.warn(`[CompareValues] Type mismatch: left=${typeof left}, right=${typeof right}`);\n return false;\n};\n\nconst determineOperandType = (value: string): ConditionTokenType => {\n if (isBooleanLiteral(value) || isNumericLiteral(value) || PRESENCE_SENTINELS.has(value)) {\n return \"input\";\n }\n\n return \"variable\";\n};\n\nconst isNumericLiteral = (value: string): boolean => {\n return /^-?\\d+(?:\\.\\d+)?$/.test(value);\n};\n\nconst isBooleanLiteral = (value: string): boolean => {\n return value.toLowerCase() === \"true\" || value.toLowerCase() === \"false\";\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Mini-renderer Markdown *inline* et sûr, pour les textes de consentement.
|
|
5
|
+
*
|
|
6
|
+
* Volontairement limité (pas de lib externe, SDK publié npm) :
|
|
7
|
+
* - liens `[libellé](url)` — uniquement http(s) et mailto, ouverts en nouvel onglet ;
|
|
8
|
+
* - gras `**texte**` ;
|
|
9
|
+
* - paragraphes (lignes vides) et sauts de ligne simples.
|
|
10
|
+
*
|
|
11
|
+
* Aucune injection de HTML brut : on ne produit que des éléments React, le texte
|
|
12
|
+
* reste du texte. Les URLs non http(s)/mailto sont rendues en texte (pas de lien).
|
|
13
|
+
*/
|
|
14
|
+
var SAFE_URL = /^(https?:|mailto:)/i;
|
|
15
|
+
// Capture **gras** ou [libellé](url) ; le reste est du texte simple.
|
|
16
|
+
var INLINE_PATTERN = /(\*\*([^*]+)\*\*)|(\[([^\]]+)\]\(([^)\s]+)\))/g;
|
|
17
|
+
function renderInlineSegments(text, keyPrefix) {
|
|
18
|
+
var nodes = [];
|
|
19
|
+
var lastIndex = 0;
|
|
20
|
+
var match;
|
|
21
|
+
var i = 0;
|
|
22
|
+
INLINE_PATTERN.lastIndex = 0;
|
|
23
|
+
while ((match = INLINE_PATTERN.exec(text)) !== null) {
|
|
24
|
+
if (match.index > lastIndex) {
|
|
25
|
+
nodes.push(text.slice(lastIndex, match.index));
|
|
26
|
+
}
|
|
27
|
+
if (match[2] !== undefined) {
|
|
28
|
+
// **gras**
|
|
29
|
+
nodes.push(jsx("strong", { children: match[2] }, "".concat(keyPrefix, "-b-").concat(i)));
|
|
30
|
+
}
|
|
31
|
+
else if (match[4] !== undefined && match[5] !== undefined) {
|
|
32
|
+
// [libellé](url)
|
|
33
|
+
var label = match[4];
|
|
34
|
+
var url = match[5];
|
|
35
|
+
if (SAFE_URL.test(url)) {
|
|
36
|
+
nodes.push(jsx("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: "underline text-blue-600 hover:text-blue-800", children: label }, "".concat(keyPrefix, "-a-").concat(i)));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// URL non sûre : on retombe sur le libellé en texte simple.
|
|
40
|
+
nodes.push(label);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
lastIndex = INLINE_PATTERN.lastIndex;
|
|
44
|
+
i += 1;
|
|
45
|
+
}
|
|
46
|
+
if (lastIndex < text.length) {
|
|
47
|
+
nodes.push(text.slice(lastIndex));
|
|
48
|
+
}
|
|
49
|
+
return nodes;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Rend une chaîne markdown en paragraphes React. Les blocs séparés par une ligne
|
|
53
|
+
* vide deviennent des `<p>` ; les sauts de ligne simples deviennent des `<br/>`.
|
|
54
|
+
*/
|
|
55
|
+
function renderInlineMarkdown(text) {
|
|
56
|
+
if (!text)
|
|
57
|
+
return null;
|
|
58
|
+
var blocks = text.split(/\n\s*\n/);
|
|
59
|
+
return blocks.map(function (block, blockIndex) {
|
|
60
|
+
var lines = block.split("\n");
|
|
61
|
+
var content = [];
|
|
62
|
+
lines.forEach(function (line, lineIndex) {
|
|
63
|
+
if (lineIndex > 0) {
|
|
64
|
+
content.push(jsx("br", {}, "br-".concat(blockIndex, "-").concat(lineIndex)));
|
|
65
|
+
}
|
|
66
|
+
content.push.apply(content, renderInlineSegments(line, "".concat(blockIndex, "-").concat(lineIndex)));
|
|
67
|
+
});
|
|
68
|
+
return jsx("p", { children: content }, "p-".concat(blockIndex));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { renderInlineMarkdown };
|
|
73
|
+
//# sourceMappingURL=renderInlineMarkdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderInlineMarkdown.js","sources":["../../../../src/utils/renderInlineMarkdown.tsx"],"sourcesContent":["import React from \"react\";\n\n/**\n * Mini-renderer Markdown *inline* et sûr, pour les textes de consentement.\n *\n * Volontairement limité (pas de lib externe, SDK publié npm) :\n * - liens `[libellé](url)` — uniquement http(s) et mailto, ouverts en nouvel onglet ;\n * - gras `**texte**` ;\n * - paragraphes (lignes vides) et sauts de ligne simples.\n *\n * Aucune injection de HTML brut : on ne produit que des éléments React, le texte\n * reste du texte. Les URLs non http(s)/mailto sont rendues en texte (pas de lien).\n */\n\nconst SAFE_URL = /^(https?:|mailto:)/i;\n\n// Capture **gras** ou [libellé](url) ; le reste est du texte simple.\nconst INLINE_PATTERN = /(\\*\\*([^*]+)\\*\\*)|(\\[([^\\]]+)\\]\\(([^)\\s]+)\\))/g;\n\nfunction renderInlineSegments(text: string, keyPrefix: string): React.ReactNode[] {\n const nodes: React.ReactNode[] = [];\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n let i = 0;\n\n INLINE_PATTERN.lastIndex = 0;\n while ((match = INLINE_PATTERN.exec(text)) !== null) {\n if (match.index > lastIndex) {\n nodes.push(text.slice(lastIndex, match.index));\n }\n\n if (match[2] !== undefined) {\n // **gras**\n nodes.push(<strong key={`${keyPrefix}-b-${i}`}>{match[2]}</strong>);\n } else if (match[4] !== undefined && match[5] !== undefined) {\n // [libellé](url)\n const label = match[4];\n const url = match[5];\n if (SAFE_URL.test(url)) {\n nodes.push(\n <a\n key={`${keyPrefix}-a-${i}`}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"underline text-blue-600 hover:text-blue-800\"\n >\n {label}\n </a>,\n );\n } else {\n // URL non sûre : on retombe sur le libellé en texte simple.\n nodes.push(label);\n }\n }\n\n lastIndex = INLINE_PATTERN.lastIndex;\n i += 1;\n }\n\n if (lastIndex < text.length) {\n nodes.push(text.slice(lastIndex));\n }\n\n return nodes;\n}\n\n/**\n * Rend une chaîne markdown en paragraphes React. Les blocs séparés par une ligne\n * vide deviennent des `<p>` ; les sauts de ligne simples deviennent des `<br/>`.\n */\nexport function renderInlineMarkdown(\n text: string | undefined,\n): React.ReactNode {\n if (!text) return null;\n\n const blocks = text.split(/\\n\\s*\\n/);\n\n return blocks.map((block, blockIndex) => {\n const lines = block.split(\"\\n\");\n const content: React.ReactNode[] = [];\n\n lines.forEach((line, lineIndex) => {\n if (lineIndex > 0) {\n content.push(<br key={`br-${blockIndex}-${lineIndex}`} />);\n }\n content.push(\n ...renderInlineSegments(line, `${blockIndex}-${lineIndex}`),\n );\n });\n\n return <p key={`p-${blockIndex}`}>{content}</p>;\n });\n}\n"],"names":["_jsx"],"mappings":"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"}
|