diff --git a/src/libs/config-validation.test.ts b/src/libs/config-validation.test.ts index 6df209f..2206bfd 100644 --- a/src/libs/config-validation.test.ts +++ b/src/libs/config-validation.test.ts @@ -1,28 +1,27 @@ import { describe, expect, test } from "bun:test"; import { - arraysEqual, + hasExactKeys, isCloudflareConfig, isEnviromentTokenPlaceholder, isZoneConfig, parseEnvironmentTokenPlaceholderName, } from "./config-validation"; -describe("arraysEqual", () => { - test("returns true for identical arrays", () => { - expect(arraysEqual(["a", "b"], ["a", "b"])).toBe(true); +describe("hasExactKeys", () => { + test("returns true when the object has exactly the given keys", () => { + expect(hasExactKeys({ a: 1, b: 2 }, ["a", "b"])).toBe(true); }); - test("returns false for different length arrays", () => { - expect(arraysEqual(["a"], ["a", "b"])).toBe(false); + test("is order independent", () => { + expect(hasExactKeys({ b: 2, a: 1 }, ["a", "b"])).toBe(true); }); - test("returns false for different order", () => { - expect(arraysEqual(["a", "b"], ["b", "a"])).toBe(false); + test("returns false when a key is missing", () => { + expect(hasExactKeys({ a: 1 }, ["a", "b"])).toBe(false); }); - test("returns false when either input is nullish", () => { - expect(arraysEqual(null, ["a"])).toBe(false); - expect(arraysEqual(["a"], undefined)).toBe(false); + test("returns false when there is an extra key", () => { + expect(hasExactKeys({ a: 1, b: 2, c: 3 }, ["a", "b"])).toBe(false); }); }); @@ -74,6 +73,11 @@ describe("isZoneConfig", () => { expect(isZoneConfig(null)).toBe(false); expect(isZoneConfig("not-an-object")).toBe(false); }); + + test("accepts a zone config whose keys are in a different order", () => { + const { proxied, ttl, ...rest } = validZone; + expect(isZoneConfig({ ...rest, proxied, ttl })).toBe(true); + }); }); describe("isCloudflareConfig", () => { @@ -113,6 +117,11 @@ describe("isCloudflareConfig", () => { expect(isCloudflareConfig("not-an-object")).toBe(false); }); + test("accepts a config whose top-level keys are in a different order", () => { + const { zone, ...rest } = validConfig; + expect(isCloudflareConfig({ zone, ...rest })).toBe(true); + }); + test("rejects an env token placeholder whose variable is unset", () => { delete process.env.MISSING_TOKEN_VAR; const onMissing = () => {}; diff --git a/src/libs/config-validation.ts b/src/libs/config-validation.ts index 83232fa..3dcdd11 100644 --- a/src/libs/config-validation.ts +++ b/src/libs/config-validation.ts @@ -13,18 +13,11 @@ export interface CloudflareConfig { zone: Array; } -export function arraysEqual( - a: unknown[] | null | undefined, - b: unknown[] | null | undefined, -): boolean { - if (a === b) return true; - if (a == null || b == null) return false; - if (a.length !== b.length) return false; +export function hasExactKeys(object: Record, keys: string[]): boolean { + const objectKeys = Object.keys(object); + if (objectKeys.length !== keys.length) return false; - for (let i = 0; i < a.length; ++i) { - if (a[i] !== b[i]) return false; - } - return true; + return keys.every((key) => objectKeys.includes(key)); } export function isEnviromentTokenPlaceholder(token: string): boolean { @@ -41,8 +34,7 @@ export function isZoneConfig(input: unknown): input is ZoneConfig { const object = input as Record; - if (!arraysEqual(Object.keys(object), ["id", "type", "name", "content", "ttl", "proxied"])) - return false; + if (!hasExactKeys(object, ["id", "type", "name", "content", "ttl", "proxied"])) return false; return ( !!object.id && @@ -67,7 +59,7 @@ export function isCloudflareConfig( const object = input as Record; - if (!arraysEqual(Object.keys(object), ["token", "updateInterval", "zone"])) return false; + if (!hasExactKeys(object, ["token", "updateInterval", "zone"])) return false; const res = !!object.token && diff --git a/src/providers/updater.ts b/src/providers/updater.ts index 9506a67..2dbe933 100644 --- a/src/providers/updater.ts +++ b/src/providers/updater.ts @@ -97,13 +97,13 @@ class Updater { .createRecord({ type: zone.type, name: zone.name, - content: IPv4, + content: newContent, ttl: zone.ttl, proxied: zone.proxied, }) .catch((err) => { Logger.error(`Unable to create record: ${err.message}`); - return err; + return undefined; }); if (result) Logger.info(`Created [${zone.type}] (${zone.name} -> ${newContent})`); @@ -129,7 +129,7 @@ class Updater { }) .catch((err) => { Logger.error(`Unable to update record: ${err.message}`); - return err; + return undefined; }); if (updateResult) @@ -148,8 +148,7 @@ class Updater { }) .catch((err) => { Logger.error(`Unable to update record: ${err.message}`); - console.log(err); - return; + return undefined; }); if (updateResult)