Rebranding
Renaming the whole project to a different brand/publisher (as was done for the Previous Brand → Simple Smooth Safe move) is a single config-driven command, not a manual find-and-replace. This keeps it repeatable for other repos.
How it works
tools/rebrand.mjs applies one ordered replacement map to three things at once:
- File contents — every git-tracked text file (minus excludes).
- File & folder paths — the same map is applied to each path string, then
git mvrenames it. Sosrc/SlDocGen.Api/…andsolution/.../sl_documenttemplate/move automatically; there is no separate rename list to maintain. - The Dataverse publisher block in
solution/src/Other/Solution.xml— a special case, because a publisherUniqueNamemust be prefix-safe (no spaces), so it can't just be the display name.
Because the same map drives content and paths, porting to another project is just a new preset — no code changes.
Usage
npm run rebrand -- --preset sl-to-sss --dry-run # preview every edit/move
npm run rebrand -- --preset sl-to-sss # apply it
npm run rebrand -- --config my-rebrand.json # bring your own map
node tools/rebrand.mjs --self-test # verify the replacement logic
The tool is idempotent — running it (or --dry-run) after a completed
rebrand reports "nothing to change", which doubles as a check that no residual
old-brand tokens remain.
Writing a preset / config
{
// MOST SPECIFIC FIRST — qualified strings before their substrings, so a broad
// rule never eats a narrow one. ("SL DocGen" before "SLDocGen"; "sl_" last.)
"replacements": [
["Previous Brand LLP", "Simple Smooth Safe"],
["Previous Brand", "Simple Smooth Safe"],
["SL DocGen", "SSS DocGen"],
["SLDocGen", "SSSDocGen"],
["SlDocGen", "SssDocGen"], // C# namespace / project / assembly
["sl-docgen", "sss-docgen"], // container image / kebab codename
["sldocgen", "sssdocgen"], // ACR / lowercased resource names
["sl_", "sss_"] // Dataverse schema prefix
],
"publisher": { // omit if not renaming a Dataverse publisher
"uniqueName": "sss", // pull from the target org's publisher table
"prefix": "sss",
"optionValuePrefix": "10000",
"display": "Simple Smooth Safe"
},
"excludes": [ // regexes matched against repo-relative paths
"^docs/legacy/", "^source-material/", "^node_modules/",
"(^|/)(bin|obj)/", "\\.(png|jpg|pdf|zip|dll)quot;
]
}
Get the target publisher's uniqueName / prefix / optionValuePrefix from the
destination environment (e.g. SELECT uniquename, customizationprefix, customizationoptionvalueprefix FROM publisher WHERE customizationprefix = 'sss').
What the tool does not do: visual brand (colors, logo)
Template look-and-feel is deliberately not a text substitution. Each
template centralizes its brand in a single :root token block (semantic roles,
not scattered hex), so a visual rebrand is editing those few variables, not
hunting hex codes across the file. The templates/practice-pro-365/* group
carries the end client's own brand, since those documents go out under the
client's name:
:root {
--brand-primary: #004226; /* client green */
--brand-primary-dark: #375623;
--brand-tint: #EAF2ED;
--brand-accent: #FFC000; /* client gold */
--font-brand: Arial, Helvetica, "Liberation Sans", "DejaVu Sans", sans-serif;
}
The logo is the client's real mark, inlined as a base64 data URI on
.logo img (source: account-statement-openchecks/logo.png). There is no asset
pipeline — a template ships to Dataverse as one HTML string — so an image has to
be embedded, not linked. Remittance details are literal text in
account-statement-openchecks/template.html; see the
Usage & Customization guide.
Rebranding this group to a different firm = swap the five
:rootvalues, swap the data URI, and update the remittance block.tools/rebrand.mjsdoes not touch any of them by design.