Skip to content

Commit

Permalink
switch to OpenApi annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-smart committed Oct 22, 2024
1 parent 4cd4c61 commit b3cf878
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .changeset/nervous-foxes-flash.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"@effect/platform": patch
---

Add missing bearer format field
Add support for bearer format OpenApi annotation
13 changes: 4 additions & 9 deletions packages/platform/src/HttpApiSecurity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ export declare namespace HttpApiSecurity {
*/
export interface Bearer extends HttpApiSecurity.Proto<Redacted> {
readonly _tag: "Bearer"
readonly format?: string
}

/**
Expand Down Expand Up @@ -100,14 +99,10 @@ const Proto = {
* @since 1.0.0
* @category constructors
*/
export const bearer = (options?: {
format?: string
}): Bearer =>
Object.assign(Object.create(Proto), {
_tag: "Bearer",
format: options?.format,
annotations: Context.empty()
})
export const bearer: Bearer = Object.assign(Object.create(Proto), {
_tag: "Bearer",
annotations: Context.empty()
})

/**
* Create an API key security scheme.
Expand Down
85 changes: 45 additions & 40 deletions packages/platform/src/OpenApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,64 +58,65 @@ export class ExternalDocs
* @category annotations
*/
export class Servers
extends Context.Tag("@effect/platform/OpenApi/Servers")<ExternalDocs, ReadonlyArray<OpenAPISpecServer>>()
extends Context.Tag("@effect/platform/OpenApi/Servers")<Servers, ReadonlyArray<OpenAPISpecServer>>()
{}

/**
* @since 1.0.0
* @category annotations
*/
export class Override extends Context.Tag("@effect/platform/OpenApi/Override")<Override, Record<string, unknown>>() {}
export class Format extends Context.Tag("@effect/platform/OpenApi/Format")<Format, string>() {}

/**
* @since 1.0.0
* @category annotations
*/
export const annotations = (annotations: {
readonly identifier?: string | undefined
readonly title?: string | undefined
readonly description?: string | undefined
readonly version?: string | undefined
readonly license?: OpenAPISpecLicense | undefined
readonly externalDocs?: OpenAPISpecExternalDocs | undefined
readonly servers?: ReadonlyArray<OpenAPISpecServer> | undefined
readonly override?: Record<string, unknown> | undefined
}): Context.Context<never> => {
let context = Context.empty()
if (annotations.identifier !== undefined) {
context = Context.add(context, Identifier, annotations.identifier)
}
if (annotations.title !== undefined) {
context = Context.add(context, Title, annotations.title)
}
if (annotations.description !== undefined) {
context = Context.add(context, Description, annotations.description)
}
if (annotations.version !== undefined) {
context = Context.add(context, Version, annotations.version)
}
if (annotations.license !== undefined) {
context = Context.add(context, License, annotations.license)
}
if (annotations.externalDocs !== undefined) {
context = Context.add(context, ExternalDocs, annotations.externalDocs)
}
if (annotations.servers !== undefined) {
context = Context.add(context, Servers, annotations.servers)
export class Override extends Context.Tag("@effect/platform/OpenApi/Override")<Override, Record<string, unknown>>() {}

const contextPartial = <Tags extends Record<string, Context.Tag<any, any>>>(tags: Tags): (
options: {
readonly [K in keyof Tags]?: Context.Tag.Service<Tags[K]> | undefined
}
if (annotations.override !== undefined) {
context = Context.add(context, Override, annotations.override)
) => Context.Context<never> => {
const entries = Object.entries(tags)
return (options) => {
let context = Context.empty()
for (const [key, tag] of entries) {
if (options[key] !== undefined) {
context = Context.add(context, tag, options[key]!)
}
}
return context
}
return context
}

/**
* @since 1.0.0
* @category annotations
*/
export interface Annotatable {
readonly annotations: Context.Context<never>
}
export const annotations: (
options: {
readonly identifier?: string | undefined
readonly title?: string | undefined
readonly version?: string | undefined
readonly description?: string | undefined
readonly license?: OpenAPISpecLicense | undefined
readonly externalDocs?: OpenAPISpecExternalDocs | undefined
readonly servers?: ReadonlyArray<OpenAPISpecServer> | undefined
readonly format?: string | undefined
readonly override?: Record<string, unknown> | undefined
}
) => Context.Context<never> = contextPartial({
identifier: Identifier,
title: Title,
version: Version,
description: Description,
license: License,
externalDocs: ExternalDocs,
servers: Servers,
format: Format,
override: Override
})

/**
* @category constructors
Expand Down Expand Up @@ -351,11 +352,15 @@ const makeSecurityScheme = (security: HttpApiSecurity): OpenAPISecurityScheme =>
}
}
case "Bearer": {
const format = Context.getOption(security.annotations, Format).pipe(
Option.map((format) => ({ bearerFormat: format })),
Option.getOrUndefined
)
return {
...meta,
type: "http",
scheme: "bearer",
bearerFormat: security.format
...format
}
}
case "ApiKey": {
Expand Down

0 comments on commit b3cf878

Please sign in to comment.