Allow variables with dots and keys (#17361)

Fixes
https://github.com/twentyhq/private-issues/issues/410#issuecomment-3781085655

Currently, JSON keys with spaces like { "toto toto": 123 } are rejected
with "JSON keys cannot contain spaces" error. This is problematic for
HTTP requests and webhook triggers where users cannot control the
response structure.

We use Handlebars to eval variables, segment-literal bracket notation to
escape keys with special characters:
Normal: {{step.normalKey}}
With spaces: `{{step.[key with space]}}`

So we simply need to wrap segments with spaces with brackets.

This PR: 
- Create shared path utilities to wrap the variable segments when needed
- Use it in all variable generation places
- Remove the restrictions

This body is now supported:
<img width="609" height="457" alt="Capture d’écran 2026-01-22 à 16 10
13"
src="https://github.com/user-attachments/assets/e7653c0a-df1e-49af-9c9a-4b7d59a99726"
/>
This commit is contained in:
Thomas Trompette
2026-01-22 17:06:53 +01:00
committed by GitHub
parent 29c12c0ffd
commit c008e874e5
14 changed files with 317 additions and 67 deletions
@@ -71,53 +71,6 @@ describe('parseAndValidateVariableFriendlyStringifiedJson', () => {
});
});
describe('Invalid keys with whitespace', () => {
it('should reject key with space', () => {
const result = parseAndValidateVariableFriendlyStringifiedJson(
'{"key with space": "value"}',
);
expect(result.isValid).toBe(false);
expect(result.error).toBe('JSON keys cannot contain spaces');
});
it('should reject key with leading space', () => {
const result = parseAndValidateVariableFriendlyStringifiedJson(
'{" leadingSpace": "value"}',
);
expect(result.isValid).toBe(false);
expect(result.error).toBe('JSON keys cannot contain spaces');
});
it('should reject key with trailing space', () => {
const result = parseAndValidateVariableFriendlyStringifiedJson(
'{"trailingSpace ": "value"}',
);
expect(result.isValid).toBe(false);
expect(result.error).toBe('JSON keys cannot contain spaces');
});
it('should reject key with tab character', () => {
const result = parseAndValidateVariableFriendlyStringifiedJson(
'{"key\\twith\\ttab": "value"}',
);
expect(result.isValid).toBe(false);
expect(result.error).toBe('JSON keys cannot contain spaces');
});
it('should reject when one of multiple keys has space', () => {
const result = parseAndValidateVariableFriendlyStringifiedJson(
'{"validKey": "value", "invalid key": "another"}',
);
expect(result.isValid).toBe(false);
expect(result.error).toBe('JSON keys cannot contain spaces');
});
});
describe('Malformed JSON', () => {
it('should reject invalid JSON syntax', () => {
const result =
@@ -1,10 +1,6 @@
import { z } from 'zod';
const schema = z
.record(z.string(), z.any())
.refine((data) => Object.keys(data).every((key) => !key.match(/\s/)), {
error: 'JSON keys cannot contain spaces',
});
const schema = z.record(z.string(), z.any());
export const parseAndValidateVariableFriendlyStringifiedJson = (
expectedJson: string,