Skip to content

feat(js): register constraints and transformers in a Svaroh namespace - #19

Merged
66Ton99 merged 1 commit into
mainfrom
feat/issue-129-js-namespace
Aug 24, 2026
Merged

66Ton99 merged 1 commit into
mainfrom
feat/issue-129-js-namespace

Conversation

@66Ton99

@66Ton99 66Ton99 commented Aug 22, 2026

Copy link
Copy Markdown

Fixes formapro#129 — "Add namespace in JS lib": Validation Constraints should not be in global scope.

What was broken

Every constraint and every view transformer ended with a line like

window.SymfonyComponentValidatorConstraintsNotBlank = SymfonyComponentValidatorConstraintsNotBlank;

which is about thirty unprefixed names on window for a library that needs one.

Root cause

Those globals are not decorative. JsFormValidatorFactory serialises the PHP class
name of each constraint (getConstraintsData()) and of each transformer
(parseTransformers()) into the form model, and the browser side instantiated the
class by that name read straight off window:

var className = name.replace(/\\/g, '');
if (undefined !== window[className]) {
    var constraint = new window[className]();

So the global scope was the class registry. Moving the classes without moving the
lookup would break validation at runtime.

What changed

  • New src/Resources/public/js/namespace.js creates a single namespace object with
    constraints and transformers registries. It is merged into an existing
    window.Svaroh rather than overwriting it.
  • constraints/index.js and transformers/index.js now import the default exports
    and register them in that namespace under the name the PHP side serialises. The
    pre-2.7 False, Null and True constraint names are registered as aliases of
    IsFalse, IsNull and IsTrue, matching what the modules already put on window.
  • SvarohJsFormValidator.resolveClass() is the new single lookup point, used by both
    parseConstraints() and parseTransformers(): the namespace first, the global
    scope as a fallback.
  • Docs: doc/3_7.md and doc/3_8.md now register custom constraints and transformers
    in the namespace, and the README gained a "JavaScript Namespace" section.

Why Svaroh

It mirrors the Svaroh\JsFormValidatorBundle PHP namespace — the JS side already
carries that rebrand in SvarohJsFormValidator, SvarohJsFormError and
SvarohJsFormElement, so a vendor-scoped Svaroh object reads as the same library.
It is one short name for user code to type, and it is created by merging into
whatever window.Svaroh already holds, so an application that owns a Svaroh
object of its own is not clobbered.

Compatibility

This is deliberately not a breaking change. The extension story of this library is
global functions, so:

  • every bundled class keeps its global name as a deprecated alias — the modules
    still assign window.<GlobalName>, untouched by this PR;
  • a constraint, transformer or Callback handler an application defines as a global
    is still found, because resolveClass() falls back to the global scope.

One behaviour does change: because the namespace is consulted first, assigning a
global with the name of a bundled class no longer overrides it. Replace a bundled
class through Svaroh.constraints / Svaroh.transformers instead. This is noted in
doc/3_7.md.

Follow-up (not this PR): drop the window.<GlobalName> lines from the constraint
and transformer modules, and drop the global-scope fallback in resolveClass(), in a
release that can carry a BC break. The library's own core objects
(SvarohJsFormValidator, SvarohJsBaseConstraint, SvarohJsFormError,
SvarohJsFormElement) are still globals and could move under the namespace at the
same time.

Tests

jest: 34 suites / 347 tests → 35 suites / 400 tests, all green.
composer test: 43 tests / 151 assertions. phpstan: clean.

  • constraints/globals.test.js and transformers/globals.test.js define the contract
    for this surface, so they keep their name lists and now assert both halves of it:
    each name is registered in the namespace, and the deprecated global points at the
    very same constructor. Nothing was removed or weakened.
  • New namespace.test.js covers the lookup: a bundled constraint and a nested
    transformer chain are still instantiated after their globals are deleted (these fail
    without the resolveClass() change), an application class defined only as a global is
    still instantiated, one registered only in the namespace is instantiated, and an
    unknown name is still skipped.

Merge order

This branch is written to coexist with the bug-fix branches in flight: it does not
touch the individual constraint or transformer modules at all, and in
SvarohJsFormValidator.js it only adds an import and rewrites the two lookup lines,
none of which is near the hunks of formapro#59, formapro#61, formapro#67, formapro#72, formapro#81, formapro#87, formapro#90, formapro#120, formapro#126, formapro#135
or formapro#148. git merge-tree reports no conflict against any of them, and the merged
tree of this branch with formapro#148, formapro#90, formapro#59, formapro#72, formapro#81 and formapro#135 runs 467 Jest tests green.
Merging it last is still the safest order, but it should not require conflict
resolution.

Every constraint and every view transformer exported its class name as a
separate property of "window", about thirty unprefixed globals for a library
that only needs one name. They are now registered in a single "Svaroh"
namespace object, and parseConstraints() and parseTransformers() resolve the
class name the PHP side serialises there instead of on "window".

The old global names are kept as deprecated aliases, and a class an application
defines as a global is still resolved from the global scope, so custom
constraints, custom transformers and Callback handlers written against them keep
working.

Fixes formapro#129
@66Ton99
66Ton99 force-pushed the feat/issue-129-js-namespace branch from dca52d2 to 4e956d8 Compare August 24, 2026 19:38
@66Ton99
66Ton99 merged commit 82a1c6d into main Aug 24, 2026
6 checks passed
@66Ton99
66Ton99 deleted the feat/issue-129-js-namespace branch August 26, 2026 06:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add namespace in JS lib

1 participant