Skip to content

Commit

Permalink
feat: handy transformer for an object of properties
Browse files Browse the repository at this point in the history
  • Loading branch information
moontai0724 committed Oct 7, 2024
1 parent 6d1b0ee commit 710981c
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 0 deletions.
4 changes: 4 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export default typedConfig(
...tsConfigs.strictTypeChecked,
...tsConfigs.stylisticTypeChecked,
],
rules: {
// causing error when passing empty object as initial value
"@typescript-eslint/prefer-reduce-type-parameter": "off",
},
},
{
plugins: {
Expand Down
24 changes: 24 additions & 0 deletions src/transformers/get-options.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Type } from "@sinclair/typebox";
import { beforeAll, beforeEach, expect, it, vi } from "vitest";

const getOption = vi.fn().mockReturnValue({ type: "mocked" });

let component: typeof import("./get-options");

beforeAll(async () => {
vi.doMock("./get-option", () => ({ getOption }));
component = await import("./get-options");
});

beforeEach(() => {
vi.clearAllMocks();
});

it("should pass schemas of props in a TObject to get-option", () => {
const schema = Type.Object({
foo: Type.String(),
});
const result = component.getOptions(schema);
expect(getOption).toBeCalledWith(schema.properties.foo);
expect(result).toEqual({ foo: { type: "mocked" } });
});
24 changes: 24 additions & 0 deletions src/transformers/get-options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { Static, TObject } from "@sinclair/typebox";
import type { Options } from "yargs";

import { getOption } from "./get-option";

export function getOptions<Schema extends TObject>(
schema: Schema,
): Record<keyof Static<Schema>, Options> {
const options = Object.entries(schema.properties).reduce(
(acc, [key, value]) => {
const option = getOption(value);
const result = {
[key]: option,
};

Object.assign(acc, result);

return acc;
},
{} as Record<keyof Static<Schema>, Options>,
);

return options;
}
1 change: 1 addition & 0 deletions src/transformers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export * from "./array";
export * from "./boolean";
export * from "./choice";
export * from "./get-option";
export * from "./get-options";
export * from "./number";
export * from "./string";
46 changes: 46 additions & 0 deletions tests/get-options.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Type } from "@sinclair/typebox";
import { beforeAll, beforeEach, expect, it, vi } from "vitest";

let component: typeof import("@/index");

beforeAll(async () => {
component = await import("@/index");
});

beforeEach(() => {
vi.clearAllMocks();
});

it("should transform schemas of props in a TObject to yargs options", () => {
const schema = Type.Object({
page: Type.Number({ description: "page number" }),
size: Type.Number({ description: "page size", default: 10 }),
query: Type.Optional(Type.String()),
sort: Type.Optional(
Type.Array(Type.Union([Type.Literal("id"), Type.Literal("createdAt")])),
),
order: Type.Union([Type.Literal("asc"), Type.Literal("desc")], {
default: "asc",
}),
pretty: Type.Boolean({ description: "pretty print" }),
});
const result = component.getOptions(schema);
expect(result).toEqual({
page: { type: "number", requiresArg: true, description: "page number" },
size: {
type: "number",
requiresArg: false,
default: 10,
description: "page size",
},
query: { type: "string", requiresArg: false },
sort: { type: "array", requiresArg: false, choices: ["id", "createdAt"] },
order: {
type: "string",
requiresArg: false,
choices: ["asc", "desc"],
default: "asc",
},
pretty: { type: "boolean", requiresArg: true, description: "pretty print" },
});
});

0 comments on commit 710981c

Please sign in to comment.