diff --git a/src/json/index.test.ts b/src/json/index.test.ts index 3e96d7639..825bbc0e7 100644 --- a/src/json/index.test.ts +++ b/src/json/index.test.ts @@ -10,8 +10,8 @@ const testSchema = { requiredKey: json.string, }; -const optionalOrNullSchema = { - optionalKey: json.optionalOrNull(json.string), +const optionalSchema = { + optionalKey: json.optional(json.string), }; test("validateSchema - required properties are required", async (t) => { @@ -30,34 +30,11 @@ test("validateSchema - required properties are required", async (t) => { test("validateSchema - optional properties are optional", async (t) => { // Optional fields may be absent - t.true(json.validateSchema(optionalOrNullSchema, {})); - t.true(json.validateSchema(optionalOrNullSchema, { optionalKey: undefined })); - t.true(json.validateSchema(optionalOrNullSchema, { optionalKey: null })); - - // But, if present, should have the expected type - t.false(json.validateSchema(optionalOrNullSchema, { optionalKey: 0 })); - t.false(json.validateSchema(optionalOrNullSchema, { optionalKey: 123 })); - t.false(json.validateSchema(optionalOrNullSchema, { optionalKey: false })); - t.false(json.validateSchema(optionalOrNullSchema, { optionalKey: true })); - t.false(json.validateSchema(optionalOrNullSchema, { optionalKey: [] })); - t.false(json.validateSchema(optionalOrNullSchema, { optionalKey: {} })); - t.true(json.validateSchema(optionalOrNullSchema, { optionalKey: "" })); - t.true(json.validateSchema(optionalOrNullSchema, { optionalKey: "foo" })); -}); - -const optionalSchema = { - optionalKey: json.optional(json.string), -}; - -test("validateSchema - optional properties may be absent or undefined, but reject null", async (t) => { - // Optional fields may be absent or explicitly undefined t.true(json.validateSchema(optionalSchema, {})); t.true(json.validateSchema(optionalSchema, { optionalKey: undefined })); + t.true(json.validateSchema(optionalSchema, { optionalKey: null })); - // But should reject null - t.false(json.validateSchema(optionalSchema, { optionalKey: null })); - - // And, if present, should have the expected type + // But, if present, should have the expected type t.false(json.validateSchema(optionalSchema, { optionalKey: 0 })); t.false(json.validateSchema(optionalSchema, { optionalKey: 123 })); t.false(json.validateSchema(optionalSchema, { optionalKey: false })); diff --git a/src/json/index.ts b/src/json/index.ts index 66adc606b..8a1b60a17 100644 --- a/src/json/index.ts +++ b/src/json/index.ts @@ -30,11 +30,6 @@ export function isString(value: unknown): value is string { return typeof value === "string"; } -/** Asserts that `value` is a number. */ -export function isNumber(value: unknown): value is number { - return typeof value === "number"; -} - /** Asserts that `value` is either a string or undefined. */ export function isStringOrUndefined( value: unknown, @@ -60,23 +55,8 @@ export const string = { required: true, } as const satisfies Validator; -/** A validator for number fields in schemas. */ -export const number = { - validate: isNumber, - required: true, -} as const satisfies Validator; - -/** A validator for object fields in schemas. */ -export const object = { - validate: isObject, - required: true, -} as const satisfies Validator>; - -/** - * Transforms a validator to be optional, accepting `undefined` or `null` for an - * absent value. - */ -export function optionalOrNull(validator: Validator) { +/** Transforms a validator to be optional. */ +export function optional(validator: Validator) { return { validate: (val: unknown) => { return val === undefined || val === null || validator.validate(val); @@ -85,19 +65,6 @@ export function optionalOrNull(validator: Validator) { } as const satisfies Validator; } -/** - * Transforms a validator to be optional, accepting `undefined` for an absent - * value but, unlike `optionalOrNull`, rejecting `null`. - */ -export function optional(validator: Validator) { - return { - validate: (val: unknown): val is T | undefined => { - return val === undefined || validator.validate(val); - }, - required: false, - } as const satisfies Validator; -} - /** Represents an arbitrary object schema. */ export type Schema = Record>; diff --git a/src/start-proxy/types.ts b/src/start-proxy/types.ts index 13369edbf..13a4ce0e8 100644 --- a/src/start-proxy/types.ts +++ b/src/start-proxy/types.ts @@ -12,7 +12,7 @@ export type RawCredential = UnvalidatedObject; /** A schema for credential objects with a username. */ export const usernameSchema = { /** The username needed to authenticate to the package registry, if any. */ - username: json.optionalOrNull(json.string), + username: json.optional(json.string), } as const satisfies json.Schema; /** Usernames may be present for both authentication with tokens or passwords. */ @@ -29,7 +29,7 @@ export function hasUsername(config: AuthConfig): config is Username { /** A schema for credential objects with a username and password. */ export const usernamePasswordSchema = { /** The password needed to authenticate to the package registry, if any. */ - password: json.optionalOrNull(json.string), + password: json.optional(json.string), ...usernameSchema, } as const satisfies json.Schema; @@ -52,7 +52,7 @@ export function hasUsernameAndPassword( /** A schema for credential objects for token-based authentication. */ export const tokenSchema = { /** The token needed to authenticate to the package registry, if any. */ - token: json.optionalOrNull(json.string), + token: json.optional(json.string), ...usernameSchema, } as const satisfies json.Schema; @@ -100,7 +100,7 @@ export const awsConfigSchema = { "role-name": json.string, domain: json.string, "domain-owner": json.string, - audience: json.optionalOrNull(json.string), + audience: json.optional(json.string), } as const satisfies json.Schema; /** Configuration for AWS OIDC. */ @@ -116,8 +116,8 @@ export function isAWSConfig( /** A schema for JFrog OIDC configurations. */ export const jfrogConfigSchema = { "jfrog-oidc-provider-name": json.string, - audience: json.optionalOrNull(json.string), - "identity-mapping-name": json.optionalOrNull(json.string), + audience: json.optional(json.string), + "identity-mapping-name": json.optional(json.string), } as const satisfies json.Schema; /** Configuration for JFrog OIDC. */ @@ -150,8 +150,8 @@ export function isCloudsmithConfig( /** A schema for GCP OIDC configurations. */ export const gcpConfigSchema = { "workload-identity-provider": json.string, - "service-account": json.optionalOrNull(json.string), - audience: json.optionalOrNull(json.string), + "service-account": json.optional(json.string), + audience: json.optional(json.string), } as const satisfies json.Schema; /** Configuration for GCP OIDC. */