Giter Site home page Giter Site logo

ardatan / fets Goto Github PK

View Code? Open in Web Editor NEW
615.0 9.0 27.0 9.08 MB

πŸ—Ή TypeScript HTTP Framework focusing on e2e type-safety, easy setup, performance & great developer experience

Home Page: https://the-guild.dev/openapi/fets

License: MIT License

JavaScript 1.86% TypeScript 84.75% HTML 1.39% Shell 0.01% MDX 11.99%
fetch fetch-api json-schema openapi swagger typescript whatwg whatwg-fetch zod

fets's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fets's Issues

Client - Deep objects are sent as empty string in query parameters

Describe the bug

The OpenAPI specification allows objects in query, but they do not appear to be supported by feTS client at the serialization step (typings are fine).

To Reproduce Steps to reproduce the behavior:

const client = createClient({
  endpoint: 'https://postman-echo.com'
});

const response = await client['/get'].get({
  query: {
    foo: {
      bar: 'baz',
    },
  },
});

const json = await response.json();
console.log(json.url);
// Expected: 'https://postman-echo.com/get?foo%5Bbar%5D=baz'
// Actual: 'https://postman-echo.com/get?foo='

Expected behavior

Environment:

  • OS: macOS
  • Package version: 0.4.12:
  • Environment: browser extension

`zod`: provide openapi metadata

Is your feature request related to a problem? Please describe.

We need some way to name types, give examples, etc.

const UserModel = z.object({
  id: z.string().uuid().openapi({ example: 'some-uuid' })
}).openapi({
  "name": "User",
})

https://github.com/asteasolutions/zod-to-openapi/blob/master/src/zod-extensions.ts

Describe the solution you'd like

Zod to openapi does some voodoo magic for embedding metadata: https://github.com/asteasolutions/zod-to-openapi
We might do something similar.

Test again

Is your feature request related to a problem? Please describe.

Describe the solution you'd like

Describe alternatives you've considered

Additional context

Automatic health endpoint at /health

Is your feature request related to a problem? Please describe.
A default health endpoint /health

Describe the solution you'd like
It would be beneficial to have a default /health endpoint integrated into the framework, in addition to the default docs URL. This endpoint could be something like fastify-healthcheck and would automatically modify the status to reflect any detected issues.

comparison to trpc

Especially for the server, we should have a comparison that shows the strengths and drawbacks of using feTS instead of tRPC.

type OASResponseBody is missing

The documentation references type OASResponseBody, so that you can easily refer to the response body type for a particular path and status code, but it does not exist.

I've started recreating it, but this solution only has a union of all possible responses, regardless of status code:

export type ResponseType<
  T extends keyof (typeof oas)['paths'],
  K extends keyof (typeof oas)['paths'][T]
> = Awaited<ReturnType<OASResponse<Mutable<typeof oas>, T, K>['json']>>

What is the best way to get the response type for a certain status code? Do you plan on adding OASResponseBody?

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Warning

These dependencies are deprecated:

Datasource Name Replacement PR?
npm @babel/plugin-proposal-class-properties Unavailable
npm eslint-plugin-standard Unavailable

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): lock file maintenance

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/benchmark.yml
  • actions/checkout v4
.github/workflows/deployment-e2e.yml
  • actions/checkout v4
  • denoland/setup-deno v1
  • actions/cache v4
  • pulumi/setup-pulumi v2
.github/workflows/lint.yml
  • actions/checkout v4
  • actions/checkout v4
.github/workflows/pr.yml
.github/workflows/release.yml
.github/workflows/tests.yml
  • actions/checkout v4
  • actions/checkout v4
  • actions/cache v4
  • nick-fields/retry v3
  • actions/checkout v4
  • actions/cache v4
  • actions/checkout v4
.github/workflows/website.yml
  • actions/checkout v4
npm
benchmark/package.json
  • @types/k6 0.52.0
  • start-server-and-test 2.0.4
e2e/aws-lambda/package.json
  • @whatwg-node/fetch ^0.9.0
  • aws-lambda 1.0.7
  • @pulumi/aws 6.47.0
  • @pulumi/awsx 0.40.1
  • @pulumi/pulumi 3.127.0
  • @types/aws-lambda 8.10.142
  • esbuild 0.23.0
  • ts-node 10.9.2
  • tsconfig-paths 4.2.0
  • typescript 5.5.4
e2e/azure-function/package.json
  • @azure/functions 4.5.0
  • @pulumi/azure-native 2.51.0
  • @pulumi/pulumi 3.127.0
  • esbuild 0.23.0
  • ts-node 10.9.2
  • tsconfig-paths 4.2.0
  • typescript 5.5.4
e2e/bun/package.json
  • bun-types ^1.0.17
  • typescript 5.5.4
e2e/cloudflare-modules/package.json
  • @pulumi/cloudflare 4.16.0
  • @pulumi/pulumi 3.127.0
  • ts-node 10.9.2
  • tsconfig-paths 4.2.0
  • typescript 5.5.4
  • wrangler 3.67.1
e2e/cloudflare-workers/package.json
  • @pulumi/cloudflare 4.16.0
  • @pulumi/pulumi 3.127.0
  • ts-node 10.9.2
  • tsconfig-paths 4.2.0
  • typescript 5.5.4
  • wrangler 3.67.1
e2e/deno/package.json
e2e/shared-scripts/package.json
  • @pulumi/pulumi 3.127.0
  • @types/node 20.14.12
e2e/shared-server/package.json
e2e/vercel/package.json
  • encoding 0.1.13
  • next 14.2.5
  • react 18.3.1
  • react-dom 18.3.1
  • @pulumi/pulumi 3.127.0
  • @types/react 18.3.3
  • esbuild 0.23.0
  • eslint 9.8.0
  • eslint-config-next 14.2.5
  • ts-node 10.9.2
  • tsconfig-paths 4.2.0
  • typescript 5.5.4
examples/auth-example/package.json
  • @types/node 20.14.12
  • ts-node 10.9.2
  • ts-node-dev 2.0.0
  • typescript ^5.5.2
examples/clickhouse/package.json
  • @types/node 20.14.12
  • ts-node 10.9.2
  • ts-node-dev 2.0.0
  • typescript ^5.5.2
examples/fireblocks/package.json
  • @types/node 20.14.12
  • ts-node 10.9.2
  • ts-node-dev 2.0.0
  • typescript ^5.5.2
  • @types/js-yaml 4.0.9
  • js-yaml 4.1.0
examples/navitia/package.json
  • @types/node 20.14.12
  • ts-node 10.9.2
  • ts-node-dev 2.0.0
  • typescript ^5.5.2
  • @types/js-yaml 4.0.9
  • js-yaml 4.1.0
examples/nextjs-example/package.json
  • @types/node 20.14.12
  • @types/react 18.3.3
  • @types/react-dom 18.3.0
  • next 14.2.5
  • react 18.3.1
  • react-dom 18.3.1
  • typescript 5.5.4
examples/soccer-stats/package.json
  • @types/node 20.14.12
  • ts-node 10.9.2
  • ts-node-dev 2.0.0
  • typescript ^5.5.2
examples/spotify/package.json
  • @types/node 20.14.12
  • dotenv 16.4.5
  • ts-node 10.9.2
  • ts-node-dev 2.0.0
  • typescript ^5.5.2
  • @types/js-yaml 4.0.9
  • js-yaml 4.1.0
examples/todolist/package.json
  • @types/node 20.14.12
  • ts-node 10.9.2
  • ts-node-dev 2.0.0
  • typescript ^5.5.2
examples/trpc-openapi/package.json
  • @trpc/server ^10.44.0
  • jsonwebtoken ^9.0.0
  • next ^14.0.4
  • nextjs-cors ^2.1.2
  • react ^18.2.0
  • react-dom ^18.2.0
  • swagger-ui-react ^5.0.0
  • trpc-openapi ^1.1.2
  • zod ^3.22.4
  • @types/jsonwebtoken ^9.0.1
  • @types/node ^20.14.12
  • @types/react ^18.2.38
  • @types/react-dom ^18.2.8
  • @types/swagger-ui-react ^4.11.0
  • @types/uuid ^10.0.0
  • typescript ^5.5.2
examples/typebox-example/package.json
  • @types/node 20.14.12
  • ts-node 10.9.2
  • ts-node-dev 2.0.0
  • typescript ^5.5.2
package.json
  • @babel/core 7.24.9
  • @babel/plugin-proposal-class-properties 7.18.6
  • @babel/preset-env 7.25.0
  • @babel/preset-typescript 7.24.7
  • @changesets/changelog-github 0.5.0
  • @changesets/cli 2.27.7
  • @theguild/prettier-config 2.0.6
  • @types/jest 29.5.12
  • @types/node 20.14.12
  • @types/react-dom 18.3.0
  • @typescript-eslint/eslint-plugin 7.17.0
  • @typescript-eslint/parser 7.17.0
  • babel-jest 29.7.0
  • bob-the-bundler 7.0.1
  • cross-env 7.0.3
  • eslint 9.8.0
  • eslint-config-prettier 9.1.0
  • eslint-config-standard 17.1.0
  • eslint-plugin-import 2.29.1
  • eslint-plugin-n 17.10.1
  • eslint-plugin-promise 7.0.0
  • eslint-plugin-standard 5.0.0
  • eslint-plugin-tailwindcss 3.17.4
  • husky 9.1.3
  • jest 29.7.0
  • lint-staged 15.2.7
  • patch-package 8.0.0
  • prettier 3.3.3
  • prettier-plugin-tailwindcss 0.6.5
  • ts-jest 29.2.3
  • typescript 5.5.4
  • @pulumi/pulumi 3.127.0
  • next 14.2.5
packages/dummy/package.json
  • node >=16.0.0
packages/fets/package.json
  • @sinclair/typebox ^0.32.0
  • @whatwg-node/cookie-store ^0.2.0
  • @whatwg-node/fetch ^0.9.4
  • @whatwg-node/server ^0.9.15
  • hotscript ^1.0.11
  • json-schema-to-ts ^3.0.0
  • qs ^6.11.2
  • ts-toolbelt ^9.6.0
  • tslib ^2.3.1
  • @types/express ^4.17.16
  • @types/qs ^6.9.8
  • express ^4.18.2
  • html-minifier-terser 7.2.0
  • node >=16.0.0
website/package.json
  • @theguild/components ^6.5.3
  • clsx ^2.1.1
  • next ^14.1.4
  • next-sitemap ^4.2.3
  • react ^18.2.0
  • react-dom ^18.2.0
  • react-icons ^5.0.1
  • @svgr/webpack ^8.0.1
  • @theguild/tailwind-config 0.4.2
  • @types/node 20.14.12
  • @types/react 18.3.3
  • @typescript/sandbox ^0.1.0
  • monaco-editor 0.50.0
  • tailwindcss 3.4.7
  • typescript 5.5.4

  • Check this box to trigger a request for Renovate to run again on this repository

[FeTS client] json body is typed as "never" when using POST requests

Bug description

When using the post() method provided by the feTS client on the "/users/{user_id}/playlists" route of the Spotify API, the json field is incorrectly typed as never even though the Spotify open API schema provides informations about the required json structure for such a request.

Screenshot that confirms the spotify OAS has all the necessary informations to strongly type the json field :

Capture d’écran de 2023-09-07 11-58-55

Screenshots that shows the json field typed as never :

Capture d’écran de 2023-09-07 11-31-55
Capture d’écran de 2023-09-07 11-23-42

From my understanding of typing/client/types.d.ts, this json field should be strongly typed from the OAS so I don't get the expected behaviour :

Capture d’écran de 2023-09-07 11-53-35


Steps to reproduce the behavior :

Here's a reproduction repository (the branch that demonstrates the bug is bug/post-json) : https://github.com/romaindurand/fets-test/blob/bug/post-json/client.ts


Expected behavior

json field should be strongly typed according to the provided open api specification schema


Environment:

  • OS: ubuntu 20
  • NodeJS: 18.15.0

This library is awesome and I really hope this can be fixed (or explained). Thank you !

Router has wrong redirect to SwiggerUI '/docs' if basePath is used

Describe the bug

Redirect to SwiggerUI page is wrong if basePath is set to any non-empty path.
It redirects to:
<host>/docs
instead of:
<host>/<basePath>/docs

To Reproduce Steps to reproduce the behavior:

Set basePath = '/api'
Go to <my_host_and_port>/api

Expected behavior

I will be redirected to <my_host_and_port>/api/docs

Actual behavior:
I was redirected to <my_host_and_port>/docs and got 404

Feedback for β€œUtilizing Middlewares”

Great stuff, but I can't seem to use RouteHandler as a type on a separate handler function., it's expecting multiple types <1,2,3> to be passed.

RouteHandler requires 3 type arguments.

const authHandler: RouteHandler = (req, ctx) => { if (!req.headers.get("Authorization")) { return new Response(null, { status: 401 }); } };

Test

Describe the bug

To Reproduce Steps to reproduce the behavior:

Expected behavior

Environment:

  • OS:
  • package-name...:
  • NodeJS:

Additional context

`status` in `OASResponse` is `200 | NotOkStatusCode`, should be derived from the schema

Describe the bug

ok flag correctly narrows down the response body type, but when a certain endpoint can return different status codes, one has to use the status code to resolve the response type.

OASStatusMap<KratosNormalized, "/self-service/registration", "post"> returns an object with the following keys 200, 303, 400, 410, 422, default but OASResponse still resolves the status to 200 | NotOkStatusCode.

To Reproduce Steps to reproduce the behavior:

Created a repo showcasing the issue fets-response-status-repro

Expected behavior

OASResponse status type should be 200 | 303 | 400 | 410 | 422 in the above scenario.

Environment:

  • OS: macos ventura 13.5
  • fets: v0.4.11
  • NodeJS: v20.5.0

Additional context

EDIT: Forgot to mention this earlier, but it's possible to "fix" the above issue by manually casting to the OASOutput as mentioned in the docs.

if (response.status === 400) {
  type Type = OASOutput<
    KratosNormalized,
    "/self-service/registration",
    "post",
    "400"
  >;
  const json = (await response.json()) as Type;

  // ...
}

Params bug: Incorrect placeholder value

Describe the bug
When a URL contains a placeholder value along with .json the params key includes .json as the key

async function main() {
  const res = await apiClient['/pets/{petId}.json'].get({
    params: {
      petId: '82666346', <---- Error
      'petId}.json': '82666346', <---- intelisense value
    },
  });
export type ExtractPathParamsWithBrackets<TPath extends string> = Pipe<
  TPath,
  [
    Strings.Split<'/' | ';'>,
    Tuples.Filter<Strings.StartsWith<'{'> & Strings.EndsWith<'}'>>,
    Tuples.Map<Strings.Trim<'{' | '}'>>,
    Tuples.ToUnion, 
  ]
>;

[Gatsby.js integration error] Reading from "node:stream" is not handled by plugins

Describe the bug

It works perfect during the development, but fails at build time.

Error during gatsby build:

success Building production JavaScript and CSS bundles -
17.879s

 ERROR #98123  WEBPACK.BUILD-HTML

Generating SSR bundle failed

Reading from "node:stream" is not handled by plugins
(Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.

File: node:stream


 ERROR #98123  WEBPACK.BUILD-HTML

Generating SSR bundle failed

Reading from "node:util" is not handled by plugins (Unhandled
scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.

File: node:util

not finished Building HTML renderer - 6.812s

To Reproduce Steps to reproduce the behavior:

Add fets into gatsbyjs application, try to build it.

Expected behavior

Environment:

  • OS:
  • fets:
  • NodeJS: 16.17.1

Additional context

removing fets from imports fixing an isssue.

docs: FeTS server example with Next.js App router

FeTS looks very cool. I'm trying to use the server with Next.js App router but couldn't make it work. Having an example would be very helpful :)

I know I can use the pages directory, but I prefer using the App router.

Offering a CLI tool to have better DX in feTS Client

Instead of handling broken and invalid or huge (breaks TS Server and IDE)OpenAPI schemas in feTS Client typings
And many more things before getting feTS running;
We can offer a tool that

  • Download the schema from a URL as YAML or whatever format and save it to the disk as JSON
  • Validate the JSON Schemas
  • Autofix them if possible just like @omnigraph/openapi does under the hood before converting it to GraphQL

Param Type is coming through as `never` when it should be `number`

Describe the bug

The Schema below describes an endpoint which takes an id param. This client should presumably figure out the type for this param as defined in the schema but it is outputting the type never. This makes the client unusable. Not sure if there is an issue in the schema or if something is going wrong?

To Reproduce Steps to reproduce the behavior:

Using the following schema file:

export default {
  openapi: "3.0.0",
  info: {
    title: "test",
    version: "0.1.0",
  },
  paths: {
    "/{id}/meters": {
      get: {
        parameters: [
          {
            name: "id",
            in: "path",
            required: true,
            schema: {
              type: "integer",
              format: "int64",
            },
          },
        ],
        responses: {
          "200": {
            description: "",
            content: {
              "application/json": {
                schema: {
                  type: "array",
                  items: {
                    $ref: "#/components/schemas/Something",
                  },
                },
              },
            },
          },
          default: {
            description: "",
          },
        },
        security: [
          {
            Authorization: [],
          },
        ],
      },
    },
    securitySchemes: {
      Authorization: {
        description: "Requires JWT to access",
        type: "http",
        scheme: "bearer",
        bearerFormat: "bearer",
      },
    },
  },
} as const;

then using the generator as follows i get the TS error

import { createClient, type NormalizeOAS } from "fets";
import type openapi from "./openapi";

const client = createClient<NormalizeOAS<typeof openapi>>({});

const response = await client["/{id}/meters"].get({
  params: {
    id: 123,
  },
  headers: {
    Authorization: `Bearer ${123}`,
  },
});

DX/API change around `.json` mapping

It would be nice to make it possible to avoid having to do the json mapping for each client usage.

I.e. to avoid this part:

const res = await fetsClient['endpoint/'].get()

if (res.ok) {
  const json = await res.json()
}

Maybe we can have a similar abstraction like ky?

const json = await fetsClient['endpoint/'].get().json();

Module '"fets"' has no exported member 'useCookies'

Describe the bug
Module '"fets"' has no exported member 'useCookies'

Environment:
const router = createRouter({
plugins: [
useCORS({
origin: '*',
credentials: true,
// allowedHeaders: ['X-Custom-Header'],
// methods: ['POST']
}),
useCookies()
]
})

CLoudflare worker

Support circular schema definitions

First of all, great job.

I have tried to use this library but in a test case I have found a problem with the circular schema.

To Reproduce
Use any circular schema, here an example:

// file tree.oas.ts
// Open API Specification
export default {
  openapi: "3.0.3",
  info: {
    version: "1",
    title: "Tree - OpenAPI 3.0",
    description:
      "This is a sample of tree",
    termsOfService: "http://swagger.io/terms/",
  },
  paths: {
    "/tree": {
      get: {
        tags: ["tree"],
        summary: "Get tree",
        description: "",
        operationId: "getTree",
        responses: {
          "200": {
            description: "successful operation",
            content: {
              "application/json": {
                schema: {
                  $ref: "#/components/schemas/Node",
                },
              },
            },
          },
          "404": {
            description: "Tree not found",
          },
        },
      },
    },
  },
  components: {
    schemas: {
      Node: {
        type: "object",
        properties: {
          number: {
            type: "integer",
            format: "int64",
            example: 10,
          },
          child: {
            $ref: "#/components/schemas/Node",
          },
        },
      },
    },
  },
} as const;
// file client.ts
import { createClient, Mutable } from 'fets'
import treeOAS from './tree.oas'
 
const client = createClient<Mutable<typeof treeOAS>>()

const response = await client['/tree'].get() // <--- HERE THERE IS AN ERROR TS2615 (circular reference for field "child")

const body = await response.json()

console.log(body)

Expected behavior

Honestly, I don't know how to works deeply this library and I'm trying to understand, but I think that should be there a flag that avoids these scenarios with circular reference

Environment:

  • package-name...: fets
  • NodeJS: 18

Request for Improved Validation Speed with TypeBox in FETS Library

Is your feature request related to a problem? Please describe.
Issue Description:
As an enthusiastic user of the FETS library, I appreciate its potential and the fact that it leverages JSON Schema, making it compatible with OPEN API. However, during my usage, I've noticed that the current validation process, powered by ZOD, tends to be slower when dealing with large datasets. After some research, I came across TypeBox, a similar library known for its significantly faster execution speed.

Feature Request:
I kindly request the development team to consider integrating TypeBox as an alternative validation option within the FETS library. By doing so, users can benefit from improved validation performance, especially in scenarios where speed is crucial.

Benefits of TypeBox:
TypeBox has gained popularity due to its efficient validation capabilities, making it an ideal candidate to enhance the FETS library's overall user experience. By adopting TypeBox, we can take advantage of its speed and performance benefits while maintaining JSON Schema compatibility.

Community Impact:
Introducing TypeBox into the FETS library would not only benefit current users by accelerating validation but also attract new developers seeking a performant JSON Schema-based solution. This addition could potentially increase the library's adoption and foster a more vibrant and engaged user community.

Implementation Considerations:
While considering the incorporation of TypeBox, it would be prudent to conduct thorough compatibility testing to ensure seamless integration with the existing functionalities of the FETS library. Additionally, providing clear documentation and examples on how to leverage TypeBox for validation within the FETS ecosystem would be greatly appreciated by users.

Thank you for considering this feature request. Your continuous efforts in improving the FETS library are commendable, and I believe that adopting TypeBox will elevate its performance and broaden its appeal to developers worldwide.

Best regards,

https://moltar.github.io/typescript-runtime-type-benchmarks/

docs: incorrect configuration in Next.js example

The following Next.js code example https://the-guild.dev/openapi/fets/server/integrations/nextjs#usage works but TypeScript complains

import { createRouter, Response } from 'fets'
 
export default createRouter({
  swaggerUiEndpoint: '/api/docs',
  oasEndpoint: '/api/openapi.json'
}).route({
  method: 'GET',
  path: '/api/greetings',
  schemas: {
    responses: {
      200: {
        type: 'object',
        properties: {
          message: {
            type: 'string'
          }
        },
        required: ['message'],
        additionalProperties: false
      }
    }
  } as const,
  handler: () => Response.json({ message: 'Hello World!' })
})
Code-002895

Updating it to this fixes the type error

import { createRouter, Response } from 'fets'

export default createRouter({
+  swaggerUI: {
+    endpoint: '/api/docs'
+  },
+  openAPI: {
+   endpoint: '/api/openapi.json'
+  }
}).route({
  method: 'GET',
  path: '/api/greetings',
  schemas: {
    responses: {
      200: {
        type: 'object',
        properties: {
          message: {
            type: 'string'
          }
        },
        required: ['message'],
        additionalProperties: false
      }
    }
  } as const,
  handler: () => Response.json({ message: 'Hello World!' })
})

Abort signal is not handled

Describe the bug

The docs say that we can pass abort signal as second argument but looks like it's not being handled.

https://the-guild.dev/openapi/fets/client/request-params#request-cancellation

This means request cancellation doesn't actually work.

To Reproduce Steps to reproduce the behavior:

Something like:

const client = createClient<NormalizedOAS>({
  endpoint: 'https://postman-echo.com',
});

// This should throw because of timeout, but it didn't because the signal wasn't handled
client['/get'].get(undefined, { signal: AbortSignal.timeout(0) }))

Expected behavior

The signal should be handled

Environment:

  • OS:
  • package-name...:
  • NodeJS:

Additional context

I created a draft PR (#709) to illustrate the point with a test.

Enable "exactOptionalPropertyTypes": true, in tsconfig.json

Is your feature request related to a problem? Please describe.

@beerose I watched a youtube video, and it looks like fets is perfect for the project we are starting. Thank you for a great work!

Our project enabled "exactOptionalPropertyTypes": true, can you please enable this rule in fets?

essen

Describe the solution you'd like

Essentially it will require to add | undefined to every optional property across project types, except those which has default values.

Describe alternatives you've considered

Sometimes it requires to do extra data manipulations or type casting while using TS libraries without exactOptionalPropertyTypes enabled.
In my experience with code generation for graphql schema before, I had noticed that generated types could have undefined values, and passing it down to optional props could cause typescript false negatives, like you can't pass undefined to optional prop, if exactOptionalPropertyTypes disabled in consumer project.

Additional context

If you agree, I can create a PR.

Have a great day!

Project Roadmap

feTS roadmap

πŸ’‘ This page's content and the list of tasks is synced automatically from The Guild's Notion. We are open sourcing our roadmap and tasks because we wish to build tools in the public, and allow developers to take part in the process of shaping the future of this library.
πŸš€ Feel free to share your thoughts, feedback and ideas with us.
πŸ‘ If you wish to show interest and help us prioritize tasks, use the πŸ‘ on the issue.

Future

  • Add feTS client to GOT Table’s repo
  • create http clients benchmark
  • Fix CI in Hive PRS then get another review from Hive members
  • Reconsider shipping AJV & fast-json-stringify with FETS
  • Support default status code for errors instead of explicit 4xx or 5xx
  • HTTP Caching on server and support it with fetchache on client
  • adjust flow on feTS website page
  • Add links from whatwg-node repo to feTS, Yoga and other projects that rely on it
  • Document how to support older specs
  • Add a section in the docs about versioning
  • SupportΒ application/x-www-form-urlencoded
  • the-guild-org/website#1297
  • https://github.com/ardatan/feTS/pull/454/files
  • #333 πŸ‘€ 1
  • #307
  • #309
  • #316
  • #321
  • #320
  • #164

ajv and zod as optional dependencies

Currently, the feTS framework includes 'ajv' and 'zod' as dependencies for data validation in the API. However, there are a few issues with this approach:

  1. Typically, only one validation library is used at a time, making the other one unnecessary.
  2. Users of the framework might already be using a different validation mechanism.
  3. Users have no control over the versions of these libraries they want to use.

Solution

To address these problems, a possible solution is to convert these dependencies into 'optionalDependencies' in the package.json file, making them opt-in. If users want to utilize the built-in validation, they will need to install either ajv or zod.

Generated Swagger UI is unstyled

Describe the bug

Generated Swagger UI is unstyled

fets

To Reproduce Steps to reproduce the behavior:

https://codesandbox.io/p/sandbox/ecstatic-shirley-fnhm59?file=%2Fapp%2Fpage.tsx%3A6%2C1

Expected behavior

Swagger UI should be properly styled

Environment:

  • see CodeSandbox link
  • dark mode

Additional context

It seems that the dark-mode is not working properly. It's caused most likely by dark mode styles (https://raw.githubusercontent.com/Itz-fork/Fastapi-Swagger-UI-Dark/main/assets/swagger_ui_dark.min.css) to be returned with Content-Type: text/plain instead of Content-Type: text/css

Question about async handler

I'm still trying out feTS on the backend but am stuck at my first db query. I'm trying a mongoose find here, but uWebsockets hangs up as soon as I call 'await User.find()`. It gives me
'Error: Returning from a request handler without responding or attaching an abort handler is forbidden! libc++abi: terminating'.

I've tested the find method outside the router code, and it works as expected.

`.route({
description: "Get all users",
method: "GET",
path: "/users",
schemas: { ** **\ },
handler: async (request) => {
const users = await User.find();

  return Response.json(users);

 // wrapping in a try catch also did nothing 
  try {
    return Response.json(allUsers);
  } catch (err) {
    console.log(err);
  }

  return Response.json({ message: "ok" });
},

})`

server versioning story

Is your feature request related to a problem? Please describe.

A common practice in REST-style APIs is to use a header (e.g. x-api-version) to specify which API version you want to use.
For feTs server, we should think about how we can serve/satisfy multiple API versions with a single server/router.

Describe the solution you'd like

Happy path documented and if required the necessary API adjustments within feTS.

OpenAPI spec fails to generate from common Zod use cases

Describe the bug

When re-using a Zod object for multiple props inside another zod object, the openAPI generator breaks down with "Could not resolve reference" errors for each prop common between the props.

For example, if I have the body schema:
const item = z.object({name: z.string(), price: z.number()})
const bodySchema = z.object({foo: item, bar: item.extend({specialBarMetadata: z.string()})})

Then I am presented with reference errors on the /docs route for any endpoints using bodySchema. Specifically, I will see errors for name and price, but not for specialBarMetadata.

Auto-generated Swagger UI is unstyled

Describe the bug

The auto-generated Swagger UI is unstyled

Arc-002903

To Reproduce

Steps to reproduce the behavior:

  1. Project setup using a simple Cloudflare Worker
npm create cloudflare

β•­ Create an application with Cloudflare Step 1 of 3
β”‚
β”œ In which directory do you want to create your application?
β”‚ dir ./fets-cf
β”‚
β”œ What type of application do you want to create?
β”‚ type "Hello World" Worker
β”‚
β”œ Do you want to use TypeScript?
β”‚ yes typescript
β”‚
β”œ Copying files from "hello-world" template
β”‚
β”œ Do you want to use TypeScript?
β”‚ yes typescript
β”‚
β”œ Retrieving current workerd compatibility date
β”‚ compatibility date 2023-08-01
β”‚
β”œ Do you want to use git for version control?
β”‚ yes git
β”‚
β•° Application created

cd fets-cf

npm i fets
  1. update workers.ts to:
export interface Env {}

import { createRouter, Response } from 'fets';

const router = createRouter({
	openAPI: {
		endpoint: '/openapi.json',
	},
	swaggerUI: {
		endpoint: '/docs',
	},
}).route({
	method: 'GET',
	path: '/greetings',
	schemas: {
		responses: {
			200: {
				type: 'object',
				properties: {
					message: {
						type: 'string',
					},
				},
				required: ['message'],
				additionalProperties: false,
			},
		},
	} as const,
	handler: () => Response.json({ message: 'Hello World!' }),
});

export default {
	fetch: router.fetch,
};
  1. run npm start to start the development server and go to http://127.0.0.1:8787/docs

Expected behavior
It should have some styling

Test

Describe the bug

To Reproduce Steps to reproduce the behavior:

Expected behavior

Environment:

  • OS:
  • package-name...:
  • NodeJS:

Additional context

Test

Describe the bug

To Reproduce Steps to reproduce the behavior:

Expected behavior

Environment:

  • OS:
  • package-name...:
  • NodeJS:

Additional context

When using zod schemas the response isn't validate

Describe the bug

I use zod to define schemas of the request and responses, and it works to validate the request but not to validate the responses

To Reproduce Steps to reproduce the behavior:

  1. Install fets with zod
  2. Create a router with zod schemas
import { createRouter, Response } from 'fets';
import { z } from 'zod';

const CreateTask = z
  .object({
    title: z.string().min(1).max(255),
  })
  .strip();
const Task = z
  .object({
    id: z.coerce.number().positive(),
    title: z.string().min(1).max(255),
    completed: z.coerce.boolean(),
  })
  .strip();

export const router = createRouter()
  .route({
    method: 'POST',
    path: '/tasks',
    schemas: {
      request: {
        json: CreateTask,
      },
      responses: {
        201: Task,
      },
    },
    async handler(request) {
      const newTask = await request.json();
      const task = {
         ...newTask,
         // expected to be coerced to boolean
         completed: 0,
         id: Date.now(),
         // expected to be stripped
         created_at: new Date(),
         updated_at: new Date(),
      };

      return Response.json(task, { status: 201 });
    },
  })

https://codesandbox.io/p/sandbox/fets-kysely-example-pws6rd

Expected behavior

To validate the responses as well as the requests using the provided zod schemas

Environment:

  • OS: Linux
  • fets: 0.4.6
  • zod: 3.21.4
  • NodeJS: v18.13.0

Additional context

I expected a fully typed framework to validate the response too, so the contract between server and client is trustworhy.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.