diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c21aa4f..1d1298a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,20 @@ # Contributing -Thank you for thinking about contributing to this project. This document will help you to get started. + +Thank you for thinking about contributing to this project. This document will +help you to get started. ## Adding a feature -If you'd like to add a feature to Avatar (or modify its existing behaviour), please start by [creating an issue][create_issue] so we can discuss it. -Don't go straight to a pull request in case it's something I don't wish to accept; I don't want to waste your time. + +If you'd like to add a feature to Avatar (or modify its existing behaviour), +please start by [creating an issue][create_issue] so we can discuss it. Don't go +straight to a pull request in case it's something I don't wish to accept; I +don't want to waste your time. ## Fixing a bug -If you've found a bug, please start by [creating an issue][create_issue]. If you'd like to [make a pull request][create_pr] for the fix once I've confirmed it's a bug in Avatar, that would be great. + +If you've found a bug, please start by [creating an issue][create_issue]. If +you'd like to [make a pull request][create_pr] for the fix once I've confirmed +it's a bug in Avatar, that would be great. [create_issue]: https://github.com/monooso/avatar/issues/new [create_pr]: https://github.com/monooso/avatar/compare - diff --git a/README.md b/README.md index 3c8792e..044ada3 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,7 @@ avatars based on usernames or ids. ## Usage ```typescript -import { - generatePng, - generateSvg, -} from "https://deno.land/x/avatar@v1.3.0/mod.ts"; +import { generatePng, generateSvg } from "https://deno.land/x/avatar/mod.ts"; // Generate an SVG avatar with the default options. let avatar = await generateSvg("jimbob"); @@ -31,6 +28,7 @@ avatar = await generatePng("cleetus", { radius: 20, size: 256 }); ``` ## License + Avatar is open source software, released under [the MIT license](./LICENSE.txt). ## Credits diff --git a/lib/options.ts b/lib/options.ts index 25926b5..9754722 100644 --- a/lib/options.ts +++ b/lib/options.ts @@ -1,18 +1,21 @@ import { z } from "https://deno.land/x/zod@v3.22.4/mod.ts"; +const defaults = { radius: 0, size: 64 }; + const validator = z.object({ - radius: z.number().int().min(0).default(0), - size: z.number().int().min(1).default(64), + radius: z.number().int().min(0).default(defaults.radius), + size: z.number().int().min(1).default(defaults.size), }); -type Options = z.input; +type InputOptions = z.input; +type OutputOptions = z.output; /** * Validates and normalizes the given options. Raises if validation fails. */ -function validate(opts: Options): Options { +function validate(opts: InputOptions): OutputOptions { return validator.parse(opts); } -export { validate }; -export type { Options }; +export { defaults, validate }; +export type { InputOptions, OutputOptions }; diff --git a/lib/png.ts b/lib/png.ts index 320838d..013a586 100644 --- a/lib/png.ts +++ b/lib/png.ts @@ -1,12 +1,15 @@ import { resvg } from "../deps.ts"; import * as svg from "./svg.ts"; -import type { Options } from "./options.ts"; +import type { InputOptions } from "./options.ts"; /** * Generates a reproducible PNG image from a given seed. * Renders the image as an SVG, and then converts it to a PNG using resvg. */ -async function generate(seed: string, opts?: Options): Promise { +async function generate( + seed: string, + opts?: InputOptions, +): Promise { const svgString = await svg.generate(seed, opts); return resvg.render(svgString); } diff --git a/lib/svg.ts b/lib/svg.ts index f8db26d..56d1cd8 100644 --- a/lib/svg.ts +++ b/lib/svg.ts @@ -1,19 +1,20 @@ import * as keys from "./keys.ts"; import miniavs from "./collections/miniavs/index.ts"; -import * as options from "./options.ts"; -import type { Options } from "./options.ts"; +import { defaults, validate } from "./options.ts"; +import type { InputOptions } from "./options.ts"; /** * Generates a reproducible SVG image for the given seed. */ -async function generate(seed: string, opts?: Options): Promise { +async function generate(seed: string, opts?: InputOptions): Promise { const key = await keys.generate(seed); - opts = options.validate(opts || {}); + const { radius, size } = validate(opts || {}); + const scaledRadius = (defaults.size / size) * radius; return ` - + - + diff --git a/tests/lib/svg_test.ts b/tests/lib/svg_test.ts index f5dfdeb..9ac107d 100644 --- a/tests/lib/svg_test.ts +++ b/tests/lib/svg_test.ts @@ -53,6 +53,14 @@ Deno.test("svg", async (t) => { }, ); + await t.step("it treats the radius as an absolute value", async () => { + // 64 is the default size, 256 is the given size, 10 is the desired radius. + const radius = (64 / 256) * 10; + const regex = new RegExp(`]+ rx="${radius}" ry="${radius}"`, "is"); + const svg = (await generate("test", { size: 256, radius: 10 })).trim(); + assert(regex.test(svg)); + }); + // keys_test.ts covers the seed validation, this is just a sanity check. await t.step("it raises if the seed is invalid", () => { assertRejects(() => generate(1));