Skip to content

Commit

Permalink
Improving type safety for fetch results (#7)
Browse files Browse the repository at this point in the history
Improving type safety for fetch results (#7)
  • Loading branch information
zemd authored Aug 24, 2024
1 parent d82718a commit 3772bdf
Show file tree
Hide file tree
Showing 25 changed files with 951 additions and 392 deletions.
7 changes: 7 additions & 0 deletions .changeset/lucky-peas-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@zemd/http-client": major
"@zemd/flickr-rest-api": major
"@zemd/figma-rest-api": major
---

improving type safety for getting results instead Response, adding tests
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: CI

on:
pull_request:
branches:
- main

jobs:
test:
name: "Build & Test: ${{ matrix.os }}"
runs-on: ${{ matrix.os }}

strategy:
fail-fast: true
matrix:
os: [ubuntu-latest]

steps:
- name: Checkout Repo
uses: actions/checkout@v3

- name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node_version }}

- name: Setup bun
uses: oven-sh/setup-bun@v2

- name: Install Dependencies
run: bun install

- name: Run tests
run: bun run test
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
node-version: 20.x

- name: Setup bun
uses: oven-sh/setup-bun@v1
uses: oven-sh/setup-bun@v2

- name: Install Dependencies
run: bun install
Expand Down
96 changes: 66 additions & 30 deletions apis/figma/src/api/comments.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { z } from "zod";
import { body, method, query, type TEndpointDecTuple } from "@zemd/http-client";
import { body, method, query } from "@zemd/http-client";

const GetCommentsQuerySchema = z.object({
as_md: z.coerce.boolean().optional(),
});

export interface GetCommentsQuery extends z.infer<typeof GetCommentsQuerySchema> {}
export interface GetCommentsQuery
extends z.infer<typeof GetCommentsQuerySchema> {}

/**
* Gets a list of comments left on the file.
*/
export const getComments = (key: string, options?: GetCommentsQuery): TEndpointDecTuple => {
export const getComments = (key: string, options?: GetCommentsQuery) => {
const transformers = [method("GET")];
if (options) {
transformers.push(query(GetCommentsQuerySchema.passthrough().parse(options)));
transformers.push(
query(GetCommentsQuerySchema.passthrough().parse(options)),
);
}
return [`/v1/files/${key}/comments`, transformers];
return { url: `/v1/files/${key}/comments`, transformers };
};

const VectorSchema = z.object({
Expand All @@ -28,7 +31,9 @@ const FrameOffsetSchema = z.object({
node_offset: VectorSchema,
});

const CommentPinCornerSchema = z.enum(["bottom-right", "bottom-left", "top-right", "top-left"]).default("bottom-right");
const CommentPinCornerSchema = z
.enum(["bottom-right", "bottom-left", "top-right", "top-left"])
.default("bottom-right");

const RegionSchema = z.object({
x: z.number(),
Expand All @@ -49,33 +54,48 @@ const FrameOffsetRegionSchema = z.object({
export const PostCommentsQuerySchema = z.object({
message: z.string(),
comment_id: z.string().optional(),
client_meta: z.union([VectorSchema, FrameOffsetSchema, RegionSchema, FrameOffsetRegionSchema]),
client_meta: z.union([
VectorSchema,
FrameOffsetSchema,
RegionSchema,
FrameOffsetRegionSchema,
]),
});

export interface PostCommentsQuery extends z.infer<typeof PostCommentsQuerySchema> {}
export interface PostCommentsQuery
extends z.infer<typeof PostCommentsQuerySchema> {}

/**
* Posts a new comment on the file.
*/
export const postComments = (key: string, message: PostCommentsQuery): TEndpointDecTuple => {
return [
`/v1/files/${key}/comments`,
[method("POST"), body(JSON.stringify(PostCommentsQuerySchema.passthrough().parse(message)))],
];
export const postComments = (key: string, message: PostCommentsQuery) => {
return {
url: `/v1/files/${key}/comments`,
transformers: [
method("POST"),
body(
JSON.stringify(PostCommentsQuerySchema.passthrough().parse(message)),
),
],
};
};

/**
* Deletes a specific comment. Only the person who made the comment is allowed to delete it.
*/
export const deleteComments = (key: string, commendId: string): TEndpointDecTuple => {
return [`/v1/files/${key}/comments/${commendId}`, [method("DELETE")]];
export const deleteComments = (key: string, commendId: string) => {
return {
url: `/v1/files/${key}/comments/${commendId}`,
transformers: [method("DELETE")],
};
};

export const GetCommentsReactionsQuerySchema = z.object({
cursor: z.string().optional(),
});

export interface GetCommentsReactionsQuery extends z.infer<typeof GetCommentsReactionsQuerySchema> {}
export interface GetCommentsReactionsQuery
extends z.infer<typeof GetCommentsReactionsQuerySchema> {}

/**
* Gets a paginated list of reactions left on the comment.
Expand All @@ -84,19 +104,25 @@ export const getCommentsReactions = (
key: string,
commentId: string,
options?: GetCommentsReactionsQuery,
): TEndpointDecTuple => {
) => {
const transformers = [method("GET")];
if (options) {
transformers.push(query(GetCommentsReactionsQuerySchema.passthrough().parse(options)));
transformers.push(
query(GetCommentsReactionsQuerySchema.passthrough().parse(options)),
);
}
return [`/v1/files/${key}/comments/${commentId}/reactions`, transformers];
return {
url: `/v1/files/${key}/comments/${commentId}/reactions`,
transformers,
};
};

export const PostCommentsReactionsQuerySchema = z.object({
emoji: z.string(),
});

export interface PostCommentsReactionsQuery extends z.infer<typeof PostCommentsReactionsQuerySchema> {}
export interface PostCommentsReactionsQuery
extends z.infer<typeof PostCommentsReactionsQuerySchema> {}

/**
* Posts a new comment reaction on a file comment.
Expand All @@ -105,11 +131,18 @@ export const postCommentsReactions = (
key: string,
commentId: string,
options: PostCommentsReactionsQuery,
): TEndpointDecTuple => {
return [
`/v1/files/${key}/comments/${commentId}/reactions`,
[method("POST"), body(JSON.stringify(PostCommentsReactionsQuerySchema.passthrough().parse(options)))],
];
) => {
return {
url: `/v1/files/${key}/comments/${commentId}/reactions`,
transformers: [
method("POST"),
body(
JSON.stringify(
PostCommentsReactionsQuerySchema.passthrough().parse(options),
),
),
],
};
};

/**
Expand All @@ -120,9 +153,12 @@ export const deleteCommentsReactions = (
key: string,
commentId: string,
options: PostCommentsReactionsQuery,
): TEndpointDecTuple => {
return [
`/v1/files/${key}/comments/${commentId}/reactions`,
[method("DELETE"), query(PostCommentsReactionsQuerySchema.passthrough().parse(options))],
];
) => {
return {
url: `/v1/files/${key}/comments/${commentId}/reactions`,
transformers: [
method("DELETE"),
query(PostCommentsReactionsQuerySchema.passthrough().parse(options)),
],
};
};
92 changes: 67 additions & 25 deletions apis/figma/src/api/components.ts
Original file line number Diff line number Diff line change
@@ -1,79 +1,121 @@
import { z } from "zod";
import { method, query, type TEndpointDecTuple } from "@zemd/http-client";
import { method, query } from "@zemd/http-client";

export const PaginationQuerySchema = z.object({
page_size: z.number().optional(),
after: z.number().optional(),
before: z.number().optional(),
});

export interface GetTeamComponentsQuery extends z.infer<typeof PaginationQuerySchema> {}
export interface GetTeamComponentsQuery
extends z.infer<typeof PaginationQuerySchema> {}

/**
* Get a paginated list of published components within a team library
*/
export const getTeamComponents = (teamId: string, options: GetTeamComponentsQuery): TEndpointDecTuple => {
return [`/v1/teams/${teamId}/components`, [method("GET"), query(PaginationQuerySchema.passthrough().parse(options))]];
export const getTeamComponents = (
teamId: string,
options: GetTeamComponentsQuery,
) => {
return {
url: `/v1/teams/${teamId}/components`,
transformers: [
method("GET"),
query(PaginationQuerySchema.passthrough().parse(options)),
],
};
};

/**
* Get a list of published components within a file library
*/
export const getFileComponents = (key: string): TEndpointDecTuple => {
return [`/v1/files/${key}/components`, [method("GET")]];
export const getFileComponents = (key: string) => {
return {
url: `/v1/files/${key}/components`,
transformers: [method("GET")],
};
};

/**
* Get metadata on a component by key.
*/
export const getComponent = (key: string): TEndpointDecTuple => {
return [`/v1/components/${key}`, [method("GET")]];
export const getComponent = (key: string) => {
return {
url: `/v1/components/${key}`,
transformers: [method("GET")],
};
};

export interface GetTeamComponentSetsQuery extends z.infer<typeof PaginationQuerySchema> {}
export interface GetTeamComponentSetsQuery
extends z.infer<typeof PaginationQuerySchema> {}
/**
* Get a paginated list of published component sets within a team library
*/
export const getTeamComponentSets = (teamId: string, options: GetTeamComponentSetsQuery): TEndpointDecTuple => {
return [
`/v1/teams/${teamId}/component_sets`,
[method("GET"), query(PaginationQuerySchema.passthrough().parse(options))],
];
export const getTeamComponentSets = (
teamId: string,
options: GetTeamComponentSetsQuery,
) => {
return {
url: `/v1/teams/${teamId}/component_sets`,
transformers: [
method("GET"),
query(PaginationQuerySchema.passthrough().parse(options)),
],
};
};

/**
* Get a list of published component sets within a file library
*/
export const getFileComponentSets = (key: string): TEndpointDecTuple => {
return [`/v1/files/${key}/component_sets`, [method("GET")]];
export const getFileComponentSets = (key: string) => {
return {
url: `/v1/files/${key}/component_sets`,
transformers: [method("GET")],
};
};

/**
* Get metadata on a component set by key.
*/
export const getComponentSet = (key: string): TEndpointDecTuple => {
return [`/v1/component_sets/${key}`, [method("GET")]];
export const getComponentSet = (key: string) => {
return {
url: `/v1/component_sets/${key}`,
transformers: [method("GET")],
};
};

export interface GetTeamStylesQuery extends z.infer<typeof PaginationQuerySchema> {}
export interface GetTeamStylesQuery
extends z.infer<typeof PaginationQuerySchema> {}

/**
* Get a paginated list of published styles within a team library
*/
export const getTeamStyles = (teamId: string, options: GetTeamStylesQuery): TEndpointDecTuple => {
return [`/v1/teams/${teamId}/styles`, [method("GET"), query(PaginationQuerySchema.passthrough().parse(options))]];
export const getTeamStyles = (teamId: string, options: GetTeamStylesQuery) => {
return {
url: `/v1/teams/${teamId}/styles`,
transformers: [
method("GET"),
query(PaginationQuerySchema.passthrough().parse(options)),
],
};
};

/**
* Get a list of published styles within a file library
*/
export const getFileStyles = (key: string): TEndpointDecTuple => {
return [`/v1/files/${key}/styles`, [method("GET")]];
export const getFileStyles = (key: string) => {
return {
url: `/v1/files/${key}/styles`,
transformers: [method("GET")],
};
};

/**
* Get metadata on a style by key.
*/
export const getStyle = (key: string): TEndpointDecTuple => {
return [`/v1/styles/${key}`, [method("GET")]];
export const getStyle = (key: string) => {
return {
url: `/v1/styles/${key}`,
transformers: [method("GET")],
};
};
Loading

0 comments on commit 3772bdf

Please sign in to comment.