Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TestClient generated using NodeTesting requires body, path, query, params as any #645

Open
arijoon opened this issue Aug 1, 2024 · 3 comments

Comments

@arijoon
Copy link

arijoon commented Aug 1, 2024

Example:

import { HttpServerRequest } from '@effect/platform'
import { Schema } from '@effect/schema'
import { Effect, flow, pipe } from 'effect'
import { Api, RouterBuilder, Security } from 'effect-http'
import { NodeTesting } from 'effect-http-node'

const AuthorizationSchema = Schema.Struct({ authorization: Schema.String })
export const authHeader = Security.make(
  pipe(
    HttpServerRequest.schemaHeaders(
      AuthorizationSchema,
    ),
  ),
  {
    myApiKey: {
      name: 'Authorization',
      type: 'apiKey',
      in: 'header',
      description: 'signed authorization token',
    },
  },
)

export const addAuthHeader = Api.setRequestHeaders(
  AuthorizationSchema,
)

export const addAuth = flow(
  Api.setSecurity(authHeader),
  addAuthHeader,
)

const testApi = Api.make().pipe(
  Api.addEndpoint(
    pipe(
      Api.get('test', '/test'),
      Api.setResponseBody(Schema.String),
      addAuth,
    ),
  ),
)

const app = RouterBuilder.make(testApi).pipe(
  RouterBuilder.handle(
    'test',
    _ => Effect.succeed('ok'),
  ),
  RouterBuilder.build,
)

const testClient = NodeTesting.make(app, testApi)

// Using the client:
Effect
  .gen(function*() {
    const client = yield* testClient
    const result = yield* client.test({
      headers: { authorization: 'somevalue' },
      body: undefined,
      query: undefined,
      path: undefined,
    })
  })

Seems like extra props in type show as any. Since they are not defined on the spec, they shouldn't be allowed
image

Updated the code, it seems to come from the flow based addition of security

@sukovanej
Copy link
Owner

sukovanej commented Aug 1, 2024

Hey, I'm not able to reproduce. Please make sure there are no mismatching dependency versions in your package or other type errors. Otherwise, I'll need a repro to take a look.

import { Schema } from "@effect/schema"
import { Effect, pipe } from "effect"
import { Api, RouterBuilder } from "effect-http"
import { NodeTesting } from "effect-http-node"

const testApi = Api.make().pipe(
  Api.addEndpoint(
    pipe(
      Api.get("test", "/test"),
      Api.setResponseBody(Schema.String)
    )
  )
)

const app = RouterBuilder.make(testApi).pipe(
  RouterBuilder.handle(
    "test",
    () => Effect.succeed("ok")
  ),
  RouterBuilder.build
)

const testClient = NodeTesting.make(app, testApi)

// Using the client:
Effect.gen(function*() {
  const client = yield* testClient
  // test: (input: {}, map?: ((request: HttpClientRequest) => HttpClientRequest) | undefined) => Effect.Effect<string, ClientError<number>, never>
  const result = yield* client.test({})
  console.log(result)
})

@arijoon
Copy link
Author

arijoon commented Aug 2, 2024

my appologies @sukovanej , It was coming from the Seucurity addition which I didn't have in the original example. Updated the example to include it. Using flow to compose it causes the type issue. Directly adding them without using flow works fine.

I'm unsure if this is a typescript limitation or the types can be improved to handle the case of using flow to perform partial composition as well

@sukovanej
Copy link
Owner

I'll try to dig deeper, but it is very probably an issue with the flow. On the type level, once generics get involved (which is the case in here) you need to be careful with the flow because things can go downhill pretty easily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants