Skip to content

Commit

Permalink
extend and use InputBag for State, QueryParams, PathParams
Browse files Browse the repository at this point in the history
  • Loading branch information
marcuspoehls committed Oct 29, 2023
1 parent 8a4687f commit 95a0e5d
Show file tree
Hide file tree
Showing 17 changed files with 313 additions and 427 deletions.
57 changes: 4 additions & 53 deletions packages/contracts/src/http/concerns/state-bag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,63 +8,14 @@
* the index signature would resolve all keys to the `any` type. Using the
* empty interface allows everyone to merge their interface definitions.
*/

import { InputBag } from '../input-bag.js'

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface HttpStateData {
//
}

export interface StateBag<State = HttpStateData> {
/**
* Returns the state object.
*/
all (): State
all<K extends keyof State> (...keys: K[]): Pick<State, K>
all<R = Record<string, any>> (...keys: string[]): R

/**
* Returns the saved state for the given `name`.
*/
get<K extends keyof State> (name: K): State[K] extends undefined ? undefined : State[K]
get<R = any> (name: string, defaultValue?: R): R

/**
* Add a key-value-pair to the shared state or an object of key-value-pairs.
*/
add<K extends keyof State> (key: K, value: State[K]): this
add (key: string, value: any): this
add (values: State): this

/**
* Merge the given `data` object with the existing shared state.
*/
merge (data: Record<string, any>): this

/**
* Determine whether the state bag contains an item for the given `key`.
*/
exists<K extends keyof State> (key: K): K extends undefined ? false : true
exists (key: string): boolean

/**
* Determine whether a shared state item exists for the given `name`.
*/
has<K extends keyof State> (name: K): State[K] extends undefined ? false : true
has (name: string): boolean

/**
* Determine whether the shared state is missing an item for the given `name`.
*/
isMissing<K extends keyof State> (name: K): State[K] extends undefined ? true : false
isMissing (name: string): boolean

/**
* Remove the shared state item for the given `name`.
*/
remove<K extends keyof State> (name: K): this
remove (name: string): this
export interface StateBag<State = HttpStateData> extends InputBag<State> {

/**
* Removes all shared state items.
*/
clear(): this
}
50 changes: 40 additions & 10 deletions packages/contracts/src/http/input-bag.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,62 @@

import { Dict } from '../index.js'
export interface InputBag<Properties = Record<string, any>> {
/**
* Returns the properties object of this input bag.
*/
toJSON (): Properties

export interface InputBag<T> {
/**
* Returns an object with all `keys` existing in the input bag.
*/
all(...keys: Array<keyof Dict<T>> | Array<Array<keyof Dict<T>>>): Dict<T>
all (): Properties
all <R extends Record<string, any>>(): R
all<Key extends keyof Properties> (...keys: Key[] | Key[][]): Partial<Record<keyof Properties, Properties[keyof Properties]>>

/**
* Returns the input value for the given `name`. This method returns
* `undefined` if the input bag doesn’t contain the given `name`.
*/
get<Value = any, Key extends keyof Dict<T> = string> (name: Key): Value | Dict<T>[Key] | undefined
get<Value = any, Key extends keyof Dict<T> = string> (name: Key, defaultValue: Value): Value | Dict<T>[Key]
get<Key extends keyof Properties> (name: Key): Properties[Key]
get<Value = any, Key extends keyof Properties = any> (name: Key, defaultValue: Value): Properties[Key] | Value

/**
* Set an input for the given `name` and assign the `value`. This
* overrides a possibly existing input with the same `name`.
*/
set (name: string, value: any): this
set<Key extends keyof Properties> (name: Key, value: Properties[Key]): this
set (values: Partial<Properties>): this

/**
* Merge the given `data` object with the existing input bag.
*/
merge (data: Partial<Properties>): this

/**
* Determine whether the input bag contains an item for the given `key`,
* independently from the key’s assigned value. If you need to ensure
* that a value is not `undefined`, use the related `has` method.
*/
exists<Key extends keyof Properties> (key: Key): boolean

/**
* Determine whether an item with the given `key` exists in the input bag
* and the assigned value is not `undefined`. The assigned value could
* also be `null`. Empty states should explcitely use `undefinied`.
*/
has<Key extends keyof Properties> (key: Key): boolean

/**
* Determine whether the input bag is missing a value for the given `key`.
*/
isMissing<Key extends keyof Properties> (key: Key): boolean

/**
* Removes the input with the given `name`.
* Remove the input bag item for the given `key`.
*/
remove(name: keyof Dict<T>): this
remove<Key extends keyof Properties> (key: Key): this

/**
* Determine whether the input for the given `name` exists.
* Removes all data from the input bag.
*/
has(name: keyof Dict<T>): boolean
clear(): this
}
11 changes: 0 additions & 11 deletions packages/contracts/src/http/parameter-bag.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/contracts/src/http/query-parameter-bag.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

import { ParameterBag } from '../index.js'
import { InputBag } from './input-bag.js'

export interface QueryParameterBag<T> extends ParameterBag<T> {
export interface QueryParameterBag<Properties> extends InputBag<Properties> {
/**
* Returns the querystring created from all items in this query parameter bag,
* without the leading question mark `?`.
Expand Down
8 changes: 4 additions & 4 deletions packages/contracts/src/http/request.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@

import { FileBag } from './file-bag.js'
import { InputBag } from './input-bag.js'
import { HttpMethods } from './methods.js'
import { HttpContext } from './context.js'
import { CookieBag } from './cookie-bag.js'
import { ParameterBag } from './parameter-bag.js'
import { CookieOptions } from './cookie-options.js'
import { MacroableCtor } from '@supercharge/macroable'
import { RequestHeaderBag } from './request-header-bag.js'
import { QueryParameterBag } from './query-parameter-bag.js'
import { IncomingHttpHeaders, IncomingMessage } from 'node:http'
import { InteractsWithState } from './concerns/interacts-with-state.js'
import { RequestCookieBuilderCallback } from './cookie-options-builder.js'
import { InteractsWithContentTypes } from './concerns/interacts-with-content-types.js'
import { QueryParameterBag } from './query-parameter-bag.js'

export interface HttpRequestCtor extends MacroableCtor {
/**
Expand Down Expand Up @@ -67,7 +67,7 @@ export interface HttpRequest extends InteractsWithState, InteractsWithContentTyp
/**
* Returns the query parameter bag.
*/
query(): QueryParameterBag<string | string[]>
query<QueryParams extends Record<string, string | string[]> = {}>(): QueryParameterBag<QueryParams>

/**
* Returns the plain query string, without the leading ?.
Expand All @@ -77,7 +77,7 @@ export interface HttpRequest extends InteractsWithState, InteractsWithContentTyp
/**
* Returns the path parameter bag.
*/
params(): ParameterBag<string>
params<PathParams extends Record<string, string> = {}> (): InputBag<PathParams>

/**
* Returns the path parameter for the given `name`. Returns the
Expand Down
1 change: 0 additions & 1 deletion packages/contracts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export { InteractsWithState } from './http/concerns/interacts-with-state.js'
export { StateBag, HttpStateData } from './http/concerns/state-bag.js'
export { FileBag } from './http/file-bag.js'
export { InputBag } from './http/input-bag.js'
export { ParameterBag } from './http/parameter-bag.js'
export { QueryParameterBag } from './http/query-parameter-bag.js'
export { HttpKernel } from './http/kernel.js'
export { HttpMethods } from './http/methods.js'
Expand Down
2 changes: 1 addition & 1 deletion packages/http/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export {
FileBag,
HttpContext,
HttpRedirect,
ParameterBag,
InputBag,
Request,
RequestHeaderBag,
Response,
Expand Down
2 changes: 1 addition & 1 deletion packages/http/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export * from './controller.js'
export * from './file-bag.js'
export * from './http-context.js'
export * from './http-redirect.js'
export * from './parameter-bag.js'
export * from './input-bag.js'
export * from './request.js'
export * from './request-header-bag.js'
export * from './response.js'
Expand Down
Loading

0 comments on commit 95a0e5d

Please sign in to comment.