Comparing version 0.1.6 to 0.1.7
{ | ||
"name": "funclify", | ||
"version": "0.1.6", | ||
"version": "0.1.7", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "src/index.ts", |
107
src/api.ts
@@ -8,6 +8,5 @@ import { | ||
import { Request, ResponseContext } from './context'; | ||
import { Request, ResponseContext } from './context.js'; | ||
import { | ||
ContextExtractor, | ||
IntegrationWrapper, | ||
RouteContext, | ||
RouteHandler, | ||
@@ -18,5 +17,5 @@ RouteMiddleware, | ||
RouteResponse, | ||
} from './types'; | ||
import { LogLevel, Logger } from './logger'; | ||
import { RouteTreeEngine } from './route-tree'; | ||
} from './types.js'; | ||
import { LogLevel, Logger } from './logger.js'; | ||
import { RouteTreeEngine } from './route-tree.js'; | ||
@@ -42,5 +41,3 @@ export interface ApiOptions { | ||
export class Api< | ||
TIntegrations extends IntegrationWrapper | undefined = undefined | ||
> { | ||
export class Api<RequestContext extends HandlerContext = HandlerContext> { | ||
private routeTree: RouteTreeEngine; | ||
@@ -59,13 +56,17 @@ private options: ApiOptions; | ||
public post< | ||
TPath extends string = '', | ||
TQuerySchema extends ZodSchema | undefined = undefined, | ||
TBodySchema extends ZodSchema | undefined = undefined | ||
>( | ||
public withMiddleware<TContext>( | ||
middleware: RouteMiddleware<'/', TContext & RequestContext, RequestContext> | ||
): Api<TContext & RequestContext> { | ||
this.use('/', middleware); | ||
return this as unknown as Api<TContext & RequestContext>; | ||
} | ||
public post<TPath extends string = ''>( | ||
url: TPath, | ||
...handlers: RouteHandler< | ||
TPath, | ||
TQuerySchema, | ||
TBodySchema, | ||
ContextExtractor<TIntegrations> | ||
undefined, | ||
undefined, | ||
RouteContext<RequestContext> | ||
>[] | ||
@@ -91,3 +92,3 @@ ) { | ||
TBodySchema, | ||
ContextExtractor<TIntegrations> | ||
RouteContext<RequestContext> | ||
>[] | ||
@@ -103,13 +104,9 @@ ) { | ||
public put< | ||
TPath extends string = '', | ||
TQuerySchema extends ZodSchema | undefined = undefined, | ||
TBodySchema extends ZodSchema | undefined = undefined | ||
>( | ||
public put<TPath extends string = ''>( | ||
url: TPath, | ||
...handlers: RouteHandler< | ||
TPath, | ||
TQuerySchema, | ||
TBodySchema, | ||
ContextExtractor<TIntegrations> | ||
undefined, | ||
undefined, | ||
RouteContext<RequestContext> | ||
>[] | ||
@@ -135,3 +132,3 @@ ) { | ||
TBodySchema, | ||
ContextExtractor<TIntegrations> | ||
RouteContext<RequestContext> | ||
>[] | ||
@@ -147,13 +144,9 @@ ) { | ||
public patch< | ||
TPath extends string = '', | ||
TQuerySchema extends ZodSchema | undefined = undefined, | ||
TBodySchema extends ZodSchema | undefined = undefined | ||
>( | ||
public patch<TPath extends string = ''>( | ||
url: TPath, | ||
...handlers: RouteHandler< | ||
TPath, | ||
TQuerySchema, | ||
TBodySchema, | ||
ContextExtractor<TIntegrations> | ||
undefined, | ||
undefined, | ||
RouteContext<RequestContext> | ||
>[] | ||
@@ -179,3 +172,3 @@ ) { | ||
TBodySchema, | ||
ContextExtractor<TIntegrations> | ||
RouteContext<RequestContext> | ||
>[] | ||
@@ -191,13 +184,9 @@ ) { | ||
public delete< | ||
TPath extends string = '', | ||
TQuerySchema extends ZodSchema | undefined = undefined, | ||
TBodySchema extends ZodSchema | undefined = undefined | ||
>( | ||
public delete<TPath extends string = ''>( | ||
url: TPath, | ||
...handlers: RouteHandler< | ||
TPath, | ||
TQuerySchema, | ||
TBodySchema, | ||
ContextExtractor<TIntegrations> | ||
undefined, | ||
undefined, | ||
RouteContext<RequestContext> | ||
>[] | ||
@@ -223,3 +212,3 @@ ) { | ||
TBodySchema, | ||
ContextExtractor<TIntegrations> | ||
RouteContext<RequestContext> | ||
>[] | ||
@@ -235,13 +224,9 @@ ) { | ||
public get< | ||
TPath extends string = '', | ||
TQuerySchema extends ZodSchema | undefined = undefined, | ||
TBodySchema extends ZodSchema | undefined = undefined | ||
>( | ||
public get<TPath extends string = ''>( | ||
url: TPath, | ||
...handlers: RouteHandler< | ||
TPath, | ||
TQuerySchema, | ||
TBodySchema, | ||
ContextExtractor<TIntegrations> | ||
undefined, | ||
undefined, | ||
RouteContext<RequestContext> | ||
>[] | ||
@@ -267,3 +252,3 @@ ) { | ||
TBodySchema, | ||
ContextExtractor<TIntegrations> | ||
RouteContext<RequestContext> | ||
>[] | ||
@@ -279,3 +264,6 @@ ) { | ||
public use(url: string, ...handlers: RouteMiddleware[]) { | ||
public use<TPath extends string>( | ||
url: TPath, | ||
...handlers: RouteMiddleware<TPath, any>[] | ||
) { | ||
this.routeTree.addMiddleware(url, handlers); | ||
@@ -359,5 +347,8 @@ } | ||
let i = 0; | ||
const next = async () => { | ||
const next = async ( | ||
request: Request<any, any>, | ||
response: ResponseContext | ||
) => { | ||
i++; | ||
return handlers[i - 1](req, responseContext, next); | ||
return handlers[i - 1](request, response, next); | ||
}; | ||
@@ -368,3 +359,3 @@ | ||
try { | ||
const result = await next(); | ||
const result = await next(req, responseContext); | ||
const end = Date.now(); | ||
@@ -371,0 +362,0 @@ const time = `${end - start}ms`; |
import { ZodSchema, z } from 'zod'; | ||
import { ExtractRouteParams, RouteRequest, RouteResponse } from './types'; | ||
import { ExtractRouteParams, RouteRequest, RouteResponse } from './types.js'; | ||
import { HandlerContext } from '@netlify/functions'; | ||
@@ -35,2 +35,14 @@ | ||
with<TMutatedContext>( | ||
ctx: TMutatedContext | ||
): Request<TPath, TQuery, TBodySchema, TContext & TMutatedContext> { | ||
return new Request({ | ||
...this, | ||
context: { | ||
...this.context, | ||
...ctx, | ||
}, | ||
}); | ||
} | ||
queryFrom<T extends ZodSchema>(schema: T): z.infer<T> { | ||
@@ -37,0 +49,0 @@ const res = schema.safeParse(this.query); |
@@ -1,3 +0,5 @@ | ||
export { withBodyValidator, withQueryValidator } from './middleware'; | ||
export { Api } from './api'; | ||
export { ApiTestHarness } from './testing'; | ||
export { withBodyValidator, withQueryValidator } from './middleware.js'; | ||
export { Api, ApiOptions } from './api.js'; | ||
export { LogLevel } from './logger.js'; | ||
export { IntegrationContextExtractor } from './types.js'; | ||
export { ApiTestHarness } from './testing.js'; |
@@ -1,7 +0,6 @@ | ||
import { RouteMiddleware } from './types'; | ||
import { RouteMiddlewareInitialiser } from './types.js'; | ||
import { ZodSchema } from 'zod'; | ||
export const withBodyValidator = | ||
(schema: ZodSchema): RouteMiddleware => | ||
async (req, context, next) => { | ||
export const withBodyValidator: RouteMiddlewareInitialiser<ZodSchema> = | ||
(schema: ZodSchema) => async (req, res, next) => { | ||
if (!next) { | ||
@@ -13,14 +12,13 @@ throw new Error('next is not defined'); | ||
if (!result.success) { | ||
return context.withStatus(400).withJSON({ | ||
return res.withStatus(400).withJSON({ | ||
message: 'Invalid request body', | ||
errors: result.error.errors, | ||
errors: (result as any).error.errors, | ||
}); | ||
} | ||
return next(); | ||
return next(req, res); | ||
}; | ||
export const withQueryValidator = | ||
(schema: ZodSchema): RouteMiddleware => | ||
async (req, context, next) => { | ||
export const withQueryValidator: RouteMiddlewareInitialiser<ZodSchema> = | ||
(schema: ZodSchema) => async (req, res, next) => { | ||
if (!next) { | ||
@@ -32,14 +30,18 @@ throw new Error('next is not defined'); | ||
if (!result.success) { | ||
return context.withStatus(400).withJSON({ | ||
return res.withStatus(400).withJSON({ | ||
message: 'Invalid query params', | ||
errors: result.error.errors, | ||
errors: (result as any).error.errors, | ||
}); | ||
} | ||
return next(); | ||
return next(req, res); | ||
}; | ||
export const withCors = | ||
(origin: string): RouteMiddleware => | ||
async (req, context, next) => { | ||
type CorsOptions = { | ||
origin: string; | ||
}; | ||
export const withCors: RouteMiddlewareInitialiser<CorsOptions> = | ||
({ origin }) => | ||
async (req, res, next) => { | ||
if (!next) { | ||
@@ -49,3 +51,3 @@ throw new Error('next is not defined'); | ||
const response = await next(); | ||
const response = await next(req, res); | ||
@@ -68,4 +70,10 @@ return { | ||
export const withAuth = (provider: AuthProvider): RouteMiddleware => { | ||
return async (req, context, next) => { | ||
type AuthOptions = { | ||
provider: AuthProvider; | ||
}; | ||
export const withAuth: RouteMiddlewareInitialiser<AuthOptions> = ({ | ||
provider, | ||
}) => { | ||
return async (req, res, next) => { | ||
if (!next) { | ||
@@ -83,4 +91,4 @@ throw new Error('next is not defined'); | ||
return next(); | ||
return next(req, res); | ||
}; | ||
}; |
import { HandlerContext } from '@netlify/functions'; | ||
import { withBodyValidator, withQueryValidator } from './middleware'; | ||
import { withBodyValidator, withQueryValidator } from './middleware.js'; | ||
import { | ||
@@ -9,6 +9,6 @@ InternalRouteHandler, | ||
TreeSearchResult, | ||
} from './types'; | ||
import { UrlPattern } from './url-pattern'; | ||
} from './types.js'; | ||
import { UrlPattern } from './url-pattern.js'; | ||
import { ZodSchema } from 'zod'; | ||
import { Logger } from './logger'; | ||
import { Logger } from './logger.js'; | ||
@@ -24,3 +24,3 @@ export class RouteTreeEngine { | ||
public addMiddleware(url: string, handlers: RouteHandler[]) { | ||
public addMiddleware(url: string, handlers: RouteHandler<any>[]) { | ||
const components = url.split('/'); | ||
@@ -27,0 +27,0 @@ let current = this.routeTree; |
@@ -1,2 +0,2 @@ | ||
import { Api } from './index'; | ||
import { Api } from './index.js'; | ||
import { | ||
@@ -3,0 +3,0 @@ HandlerContext, |
import { ZodSchema, z } from 'zod'; | ||
import { Request, ResponseContext } from './context'; | ||
import { UrlPattern } from './url-pattern'; | ||
import { Request, ResponseContext } from './context.js'; | ||
import { UrlPattern } from './url-pattern.js'; | ||
import { HandlerContext } from '@netlify/functions'; | ||
@@ -8,9 +8,12 @@ | ||
export type ContextExtractor<T extends IntegrationWrapper | undefined> = | ||
T extends (a: infer Handler, b?: infer _Config) => infer _Res | ||
? Handler extends (a: infer _Req, b: infer Ctx) => Promise<infer _Res> | ||
? Ctx | ||
: never | ||
: HandlerContext; | ||
export type RouteContext<T> = HandlerContext & T; | ||
export type IntegrationContextExtractor< | ||
T extends IntegrationWrapper | undefined | ||
> = T extends (a: infer Handler, b?: infer _Config) => infer _Res | ||
? Handler extends (a: infer _Req, b: infer Ctx) => Promise<infer _Res> | ||
? Ctx | ||
: never | ||
: HandlerContext; | ||
export type ExtractRouteParams<T extends string> = | ||
@@ -53,2 +56,12 @@ T extends `${infer _Start}:${infer Param}/${infer Rest}` | ||
export type NextHandler< | ||
TPath extends string, | ||
TQuerySchema extends ZodSchema | undefined, | ||
TBodySchema extends ZodSchema | undefined, | ||
TContext extends HandlerContext | ||
> = ( | ||
req: Request<TPath, TQuerySchema, TBodySchema, TContext>, | ||
context: ResponseContext | ||
) => Promise<RouteResponse>; | ||
export type RouteHandler< | ||
@@ -58,14 +71,20 @@ TPath extends string = '', | ||
TBodySchema extends ZodSchema | undefined = undefined, | ||
TContext extends HandlerContext = HandlerContext | ||
TContextIn extends HandlerContext = HandlerContext, | ||
TContextOut extends HandlerContext = TContextIn | ||
> = ( | ||
request: Request<TPath, TQuerySchema, TBodySchema, TContext>, | ||
request: Request<TPath, TQuerySchema, TBodySchema, TContextIn>, | ||
context: ResponseContext, | ||
next?: () => Promise<RouteResponse> | ||
next?: NextHandler<TPath, TQuerySchema, TBodySchema, TContextOut> | ||
) => Promise<RouteResponse>; | ||
export type RouteMiddleware<TPath extends string = any> = RouteHandler< | ||
TPath, | ||
any | ||
>; | ||
export type RouteMiddlewareInitialiser<TOptions> = <TPath extends string>( | ||
options: TOptions | ||
) => RouteMiddleware<TPath>; | ||
export type RouteMiddleware< | ||
TPath extends string, | ||
TContextOut extends HandlerContext = any, | ||
TContext extends HandlerContext = any | ||
> = RouteHandler<TPath, any, any, TContext, TContextOut>; | ||
export interface InternalRouteHandler { | ||
@@ -72,0 +91,0 @@ method: string; |
@@ -14,3 +14,3 @@ { | ||
/* Language and Environment */ | ||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ | ||
"target": "ES2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, | ||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ | ||
@@ -29,6 +29,6 @@ // "jsx": "preserve", /* Specify what JSX code is generated. */ | ||
/* Modules */ | ||
"module": "commonjs", /* Specify what module code is generated. */ | ||
"module": "ES2022" /* Specify what module code is generated. */, | ||
// "rootDir": "./", /* Specify the root folder within your source files. */ | ||
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ | ||
"baseUrl": "./src", /* Specify the base directory to resolve non-relative module names. */ | ||
"moduleResolution": "nodenext" /* Specify how TypeScript looks up a file from a given module specifier. */, | ||
"baseUrl": "./src" /* Specify the base directory to resolve non-relative module names. */, | ||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ | ||
@@ -54,3 +54,3 @@ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ | ||
/* Emit */ | ||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ | ||
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */, | ||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */ | ||
@@ -61,3 +61,3 @@ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ | ||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ | ||
// "outDir": "./", /* Specify an output folder for all emitted files. */ | ||
"outDir": "./dist" /* Specify an output folder for all emitted files. */, | ||
// "removeComments": true, /* Disable emitting comments. */ | ||
@@ -84,8 +84,8 @@ // "noEmit": true, /* Disable emitting files from a compilation. */ | ||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ | ||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ | ||
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, | ||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ | ||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ | ||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, | ||
/* Type Checking */ | ||
"strict": true, /* Enable all strict type-checking options. */ | ||
"strict": true /* Enable all strict type-checking options. */, | ||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ | ||
@@ -112,4 +112,4 @@ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ | ||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ | ||
"skipLibCheck": true /* Skip type checking all .d.ts files. */ | ||
"skipLibCheck": true /* Skip type checking all .d.ts files. */ | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
46423
1158