Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .bumpy/fix-port-integer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
varlock: patch
---

Reject non-integer values for @type=port
11 changes: 10 additions & 1 deletion packages/varlock/src/env-graph/lib/data-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -545,9 +545,18 @@ const PortDataType = createEnvGraphDataType(
if (rawVal.includes('.')) throw new CoercionError('Port number must be an integer');
if (rawVal.includes('e')) throw new CoercionError('Port number should be an integer, not in exponential notation');
}
return coerceToNumber(rawVal);
const numVal = coerceToNumber(rawVal);
// Unquoted schema values like 80.5 are already numbers after parse auto-coerce;
// the string '.' check above does not cover that path.
if (!Number.isInteger(numVal)) {
throw new CoercionError('Port number must be an integer');
}
return numVal;
},
validate(val) {
if (!Number.isInteger(val)) {
return new ValidationError('Port number must be an integer');
}
if (settings?.min !== undefined && val < settings?.min) {
return new ValidationError(`Min value is ${settings?.min}`);
}
Expand Down
27 changes: 27 additions & 0 deletions packages/varlock/src/env-graph/test/data-types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,33 @@ describe('number data type - Infinity coercion', () => {
});
});

describe('port data type', () => {
it('accepts integer ports', async () => {
const g = await loadAndResolve(outdent`
# @type=port
P=8080
`);
expect(g.configSchema.P.isValid).toBe(true);
expect(g.configSchema.P.resolvedValue).toBe(8080);
});

it('rejects non-integer numeric ports from schema auto-coerce', async () => {
const g = await loadAndResolve(outdent`
# @type=port
P=80.5
`);
expect(g.configSchema.P.isValid).toBe(false);
});

it('rejects non-integer string ports', async () => {
const g = await loadAndResolve(outdent`
# @type=port
P="80.5"
`);
expect(g.configSchema.P.isValid).toBe(false);
});
});

describe('url data type', () => {
describe('prependHttps', () => {
it('prepends https:// when missing', async () => {
Expand Down
Loading