From 00d9d2d4b16054ca7b83d7e173562f8ccb5683f7 Mon Sep 17 00:00:00 2001 From: JiriUhlir <149317995+JiriUhlir@users.noreply.github.com> Date: Fri, 28 Aug 2026 11:25:08 +0200 Subject: [PATCH] Ukazka tela webhooku shazovala builder pri psani cesty parametru Zapisovalo se do retezce: `exampleValue` vraci u obycejneho parametru text 'text', a kdyz cesta jineho parametru vedla skrz nej, `target[key] = ...` skoncilo na "Cannot create property 'data' on string 'text'" a spadl cely builder. Neni to okrajovy stav. Prijde cely objekt a vedle nej se vytahuje konkretni hodnota z jeho nitra, takze parametr, kterym vede cesta jineho parametru, je bezna vec - a pri psani cesty `zprava.data` je `zprava` chvili hotovy parametr sam o sobe, takze to padalo pri kazdem stisku klavesy. Dve zmeny: - do cesty se da zanorit vzdy. Kdyz na miste je skalar, nahradi se schrankou - parametr, kterym vede cesta jineho parametru, uz nedostane zastupnou hodnotu podle typu. Plati vnitrni struktura, protoze prave tu ma ukazka ukazat - zastupna hodnota by ji prepsala, a u objektu a poli je to to podstatne Overeno na obou poradich (skalar driv i pozdeji nez hlubsi cesta), na objektu s vnitrkem a na poli s ciselnym indexem. Co-Authored-By: Claude Opus 5 (1M context) --- .../dashboard/flow/TriggerConfig.tsx | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/web/src/components/dashboard/flow/TriggerConfig.tsx b/web/src/components/dashboard/flow/TriggerConfig.tsx index da4c54f..189df39 100644 --- a/web/src/components/dashboard/flow/TriggerConfig.tsx +++ b/web/src/components/dashboard/flow/TriggerConfig.tsx @@ -286,20 +286,52 @@ function exampleBody(fields: TriggerField[]): string { if (fields.length === 0) return '{\n "cokoliv": "co pošle odesílatel"\n}'; const body: Record = {}; + const paths = fields.map((field) => field.path ?? field.name); for (const field of fields) { - const path = (field.path ?? field.name).split('.'); + const full = field.path ?? field.name; + const path = full.split('.'); let target = body; + /* + * Parametr, kterym vede cesta jineho parametru. + * + * Deje se to bezne: prijde cely objekt a vedle nej se vytahuje konkretni + * hodnota z jeho nitra. Pak plati ta vnitrni struktura, ne zastupna + * hodnota typu - ta by prepsala presne to, co ma ukazka ukazat. + */ + const isParent = paths.some((other) => other !== full && other.startsWith(`${full}.`)); + for (let i = 0; i < path.length - 1; i += 1) { const key = path[i]; const next = path[i + 1]; - // Cislo v ceste znamena pole, ne objekt s klicem "0". - if (target[key] === undefined) target[key] = /^\d+$/.test(next) ? [] : {}; + const current = target[key]; + /* + * Do cesty se musi dat zanorit. Kdyz uz na tom miste hodnota je, protoze + * jiny parametr konci tam, kde tenhle pokracuje, prepise se schrankou. + * + * Bez toho by se zapisovalo do retezce a **spadl by cely builder**. Neni + * to okrajovy stav: pri psani cesty `zprava.data` je `zprava` chvili + * hotovy parametr sam o sobe, takze staci mit oba a ukazka se rozbije + * pri kazdem stisku klavesy. + * + * Cislo v ceste znamena pole, ne objekt s klicem "0". + */ + if (current === null || typeof current !== 'object') { + target[key] = /^\d+$/.test(next) ? [] : {}; + } target = target[key] as Record; } - target[path[path.length - 1]] = exampleValue(field.type); + const last = path[path.length - 1]; + if (isParent) { + // Schranku nechat, at uz ji postavily vnorene parametry, nebo teprve + // prijdou na radu. Prepsat ji zastupnou hodnotou znamena je zahodit. + const current = target[last]; + if (current === null || typeof current !== 'object') target[last] = {}; + } else { + target[last] = exampleValue(field.type); + } } return JSON.stringify(body, null, 2);