From 4e7795a9d0019ceb05d1f03894d9a4fb810e15ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kris=20Kr=C3=BCg?= <140290088+WalksWithASwagger@users.noreply.github.com> Date: Fri, 31 Jul 2026 03:56:25 +0000 Subject: [PATCH] fix(varlock): accept uppercase hex for @type=md5 MD5 hashes from tools are often uppercase; UUID already used a case-insensitive regex. Accept A-F and normalize to lowercase. --- .bumpy/fix-md5-uppercase.md | 5 +++++ .../varlock/src/env-graph/lib/data-types.ts | 6 +++++- .../src/env-graph/test/data-types.test.ts | 20 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 .bumpy/fix-md5-uppercase.md diff --git a/.bumpy/fix-md5-uppercase.md b/.bumpy/fix-md5-uppercase.md new file mode 100644 index 000000000..5bf6fe47d --- /dev/null +++ b/.bumpy/fix-md5-uppercase.md @@ -0,0 +1,5 @@ +--- +varlock: patch +--- + +Accept uppercase hex for @type=md5 diff --git a/packages/varlock/src/env-graph/lib/data-types.ts b/packages/varlock/src/env-graph/lib/data-types.ts index ecf7fb680..5ff14bc51 100644 --- a/packages/varlock/src/env-graph/lib/data-types.ts +++ b/packages/varlock/src/env-graph/lib/data-types.ts @@ -608,12 +608,16 @@ const UuidDataType = createEnvGraphDataType({ }, }); -const MD5_REGEX = /^[a-f0-9]{32}$/; +const MD5_REGEX = /^[a-f0-9]{32}$/i; const Md5DataType = createEnvGraphDataType({ name: 'md5', typeDescription: 'MD5 hash string', // A deterministic, unique, valid 32-hex string derived from the seed. generatePlaceholder: (seed) => hexFromSeed(seed).slice(0, 32), + coerce(rawVal) { + // Accept uppercase hex (common from tools) and normalize like typical hash handling + return coerceToString(rawVal).toLowerCase(); + }, validate(val) { const result = MD5_REGEX.test(val); if (result) return true; diff --git a/packages/varlock/src/env-graph/test/data-types.test.ts b/packages/varlock/src/env-graph/test/data-types.test.ts index 2aac08f93..494095dba 100644 --- a/packages/varlock/src/env-graph/test/data-types.test.ts +++ b/packages/varlock/src/env-graph/test/data-types.test.ts @@ -189,6 +189,26 @@ describe('url data type - path values', () => { }); }); +describe('md5 data type', () => { + it('accepts lowercase md5', async () => { + const g = await loadAndResolve(outdent` + # @type=md5 + H=d41d8cd98f00b204e9800998ecf8427e + `); + expect(g.configSchema.H.isValid).toBe(true); + expect(g.configSchema.H.resolvedValue).toBe('d41d8cd98f00b204e9800998ecf8427e'); + }); + + it('accepts uppercase md5 and normalizes to lowercase', async () => { + const g = await loadAndResolve(outdent` + # @type=md5 + H=D41D8CD98F00B204E9800998ECF8427E + `); + expect(g.configSchema.H.isValid).toBe(true); + expect(g.configSchema.H.resolvedValue).toBe('d41d8cd98f00b204e9800998ecf8427e'); + }); +}); + describe('string data type - matches option', () => { it('accepts string matching regex literal', async () => { const g = await loadAndResolve(outdent`