chore: drop `@rocket.chat/string-helpers` in favor of `@rocket.chat/tools`
Proposed changes (including videos or screenshots)
@rocket.chat/string-helpers was a Fuselage package with four exports, all of them tiny pure string functions: escapeRegExp, escapeHTML, unescapeHTML and capitalize. This repo already has a home for exactly that kind of function — @rocket.chat/tools — and most of the files importing from string-helpers were already importing from tools on the line above.
So rather than moving the package here as its own workspace package, this PR absorbs it into @rocket.chat/tools and deletes the dependency. See Further comments for why this deviates from what ARCH-2361 describes.
Two commits do the work, and they are worth reading in order:
-
feat(tools): embed functions from @rocket.chat/string-helpers— the four functions are copied intopackages/tools/src, each with a spec file. The implementations are the published0.32.0ones, with the types tightened where the originals were loose:capitalizeis now generic, so it returnsCapitalize<T>instead ofstring.escapeHTML/unescapeHTMLnow takestringinstead ofany; the runtime coercion they relied on is kept, moved into a small internaltoStringhelper, so a nullish value passed from untyped JS still becomes''rather than"undefined".escapeRegExpkeeps its behavior exactly (the spec pins the full escaped character set).
-
chore: drop @rocket.chat/string-helpers in favor of @rocket.chat/tools— 122 files, almost entirely one-line import rewrites: 67escapeRegExp, 29escapeHTML, 14capitalize, 2unescapeHTML. The dependency is removed from ninepackage.jsons —apps/meteor,apps/meteor/ee/server/services,packages/models,ee/packages/omnichannel-servicesand the fouree/apps/*services (account,authorization,ddp-streamer,presence) — and@rocket.chat/toolsis added topackages/modelsandpackages/ui-client, the two consumers that did not already depend on it.fuselage.shstops bumping the package, and it is gone fromyarn.lockentirely — it was not a transitive dependency of anything else.Because the embedded signatures are tighter, a handful of type assertions that only existed to work around the old ones could go:
capitalize(this.name) as Capitalize<TServiceName>inCustomOAuth,indexOf(_emoji as never)in the emoji helpers, and similar casts inpackages/models. Those are the only non-import changes in the commit.
Issue(s)
Steps to test or reproduce
Nothing should change for the user — the functions are the same code, called from the same places.
yarn workspace @rocket.chat/tools test— 14 suites, 118 tests, with the four new files at 100% coverage.yarn workspace @rocket.chat/meteor typecheck— clean. Same for@rocket.chat/models,@rocket.chat/ui-clientand@rocket.chat/abac, the packages whose diffs are more than import rewrites.- Anything that goes through the touched paths: search (spotlight, message search), emoji and custom emoji, mentions, markdown, highlighted words, message previews, OAuth service names in the login buttons, and the omnichannel admin tables.
Further comments
This is not the migration the ticket describes. ARCH-2361 is written as step 8 of 19 in the Fuselage migration: copy packages/string-helpers in, add the workspaces glob entry, keep the dual ESM/CJS build and the API report, flip consumers to workspace:^. It also owns repointing the package's npm trusted publisher from RocketChat/fuselage to RocketChat/Rocket.Chat.
Absorbing the package instead makes all of that unnecessary: there is no new workspace package to build, no API report to maintain, and the npm trusted-publishing repoint can be dropped from the migration plan — this package will never be published again from either repo. The tradeoff is that @rocket.chat/string-helpers stops existing as a published package after 0.32.0. Nothing outside Rocket.Chat and Fuselage consumes it, and Fuselage froze it in ARCH-2350, so I think that is the right call — but it is a plan change, not just an implementation detail, so flagging it explicitly for review. If we would rather keep the package alive as a published artifact, this PR should be replaced with the literal migration.
One follow-up is needed, not done here. apps/meteor/tests/end-to-end/api/http-response-truncation.ts replays a captured dynamic-import request whose body hardcodes a client module tree containing node_modules/@rocket.chat/string-helpers. That path no longer exists in the bundle. The test's own comment warns that these fixtures are build-dependent — if the tree changes, the response shrinks below the gzip threshold and loses the chunked+gzip shape the race needs, which is what its first assertion checks. The fixture has to be recaptured. I left it alone because it only runs under the specific traefik configuration it was written for, and recapturing it means reproducing that setup.
Summary by CodeRabbit
-
New Features
- Added shared utilities for capitalizing text, converting values to strings, and escaping or unescaping HTML and regular expressions.
- Expanded shared tooling exports for consistent text handling across the application.
-
Refactor
- Consolidated text and escaping helpers without changing existing behavior.
- Simplified internal type handling and removed obsolete helper usage.
-
Tests
- Added comprehensive coverage for text conversion, capitalization, and HTML and regular-expression escaping utilities.