Skip to content

Commit ae00903

Browse files
committed
Use unionType to validate sensitive strings and urls
1 parent 1395977 commit ae00903

File tree

3 files changed

+19
-15
lines changed

3 files changed

+19
-15
lines changed

v-next/hardhat-zod-utils/src/index.ts

+12-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { ZodTypeDef, ZodType } from "zod";
22

3-
import { isObject } from "@ignored/hardhat-vnext-utils/lang";
43
import { z } from "zod";
54

65
/**
@@ -138,29 +137,32 @@ export const incompatibleFieldType = (errorMessage = "Unexpected field") =>
138137
/**
139138
* A Zod type to validate Hardhat's ConfigurationVariable objects.
140139
*/
141-
export const configurationVariableType = z.object({
140+
export const configurationVariableSchema = z.object({
142141
_type: z.literal("ConfigurationVariable"),
143142
name: z.string(),
144143
});
145144

146145
/**
147146
* A Zod type to validate Hardhat's SensitiveString values.
148147
*/
149-
export const sensitiveStringType = conditionalUnionType(
150-
[
151-
[(data) => typeof data === "string", z.string()],
152-
[isObject, configurationVariableType],
153-
],
148+
export const sensitiveStringSchema = unionType(
149+
[z.string(), configurationVariableSchema],
154150
"Expected a string or a Configuration Variable",
155151
);
156152

157153
/**
158154
* A Zod type to validate Hardhat's SensitiveString values that expect a URL.
155+
*
156+
* TODO: The custom error message in the unionType function doesn't work
157+
* correctly when using string().url() for validation, see:
158+
* https://github.com/colinhacks/zod/issues/2940
159+
* As a workaround, we provide the error message directly in the url() call.
160+
* We should remove this when the issue is fixed.
159161
*/
160-
export const sensitiveUrlType = conditionalUnionType(
162+
export const sensitiveUrlSchema = unionType(
161163
[
162-
[(data) => typeof data === "string", z.string().url()],
163-
[isObject, configurationVariableType],
164+
z.string().url("Expected a URL or a Configuration Variable"),
165+
configurationVariableSchema,
164166
],
165167
"Expected a URL or a Configuration Variable",
166168
);

v-next/hardhat/src/internal/builtin-plugins/network-manager/type-validation.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type { HardhatUserConfigValidationError } from "../../../types/hooks.js";
66

77
import {
88
conditionalUnionType,
9-
sensitiveUrlType,
9+
sensitiveUrlSchema,
1010
unionType,
1111
validateUserConfigZodType,
1212
} from "@ignored/hardhat-vnext-zod-utils";
@@ -36,7 +36,7 @@ const httpNetworkUserConfigSchema = z.object({
3636
gasPrice: z.optional(userGasSchema),
3737

3838
// HTTP network specific
39-
url: sensitiveUrlType,
39+
url: sensitiveUrlSchema,
4040
timeout: z.optional(z.number()),
4141
httpHeaders: z.optional(z.record(z.string())),
4242
});
@@ -80,7 +80,7 @@ const httpNetworkConfigSchema = z.object({
8080
gasPrice: gasSchema,
8181

8282
// HTTP network specific
83-
url: sensitiveUrlType,
83+
url: sensitiveUrlSchema,
8484
timeout: z.number(),
8585
httpHeaders: z.record(z.string()),
8686
});

v-next/hardhat/test/internal/builtin-plugins/network-manager/hook-handlers/config.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,10 @@ describe("network-manager/hook-handlers/config", () => {
519519
validationErrors.length > 0,
520520
"validation errors should be present",
521521
);
522-
// TODO: the error message should be "Expected a URL or a Configuration Variable"
523-
assert.equal(validationErrors[0].message, "Invalid url");
522+
assert.equal(
523+
validationErrors[0].message,
524+
"Expected a URL or a Configuration Variable",
525+
);
524526
});
525527

526528
it("should throw if the timeout is invalid", async () => {

0 commit comments

Comments
 (0)