New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

funclify

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

funclify - npm Package Compare versions

Comparing version 0.1.3 to 0.1.4

2

package.json
{
"name": "funclify",
"version": "0.1.3",
"version": "0.1.4",
"description": "",

@@ -5,0 +5,0 @@ "main": "src/index.ts",

@@ -5,2 +5,4 @@ # Funclify 🤖

Currently, this is a **TypeScript-only** framework. This reflects the current focus of the project, being a type-safe and DX focused package, and in the future it may be updated to compile to support ESM. It's early days, so please forgive the narrow-focus.
## ⚠️ Just one thing!

@@ -10,2 +12,12 @@

## Install
```shell
# pnpm
pnpm add funclify
# npm
npm install funclify
```
## Basic Use

@@ -27,1 +39,61 @@

```
### Typed Route Parameters
Funclify is focused on being a strongly-typed framework. This extends to route parameters. Making heavy use of `infer`, we can create a strongly-typed `params` property that lives on the `req` argument passed to your route handler.
```ts
api.get("/users/:user_id/orders/:order_id", async({ params }, res) => {
// params: { user_id: string, order_id: string }
const { user_id, order_id } = params;
const order = await fetchOrder(user_id, order_id);
return res.withJSON(order);
})
```
## Testing
Funclify comes bundled with a test harness to make it simple to run integration tests against your API.
Although you could adopt a more "unit" approach, the framework is built to encourage testing to the boundary of your application for each and every API route.
An example below utilising Vitest
```ts
import { describe, it, beforeEach, expect } from "vitest";
import { ApiTestHarness } from "funclify";
import { api } from "../functions/api";
describe("API", () => {
let test: ApiTestHarness<typeof api>;
beforeEach(() => {
// This could be set once rather than in before-each, as
// in theory an API should be idempotent. However, for flexibility
// atomicity can be guaranteed by initialising in the beforeEach
test = new ApiTestHarness(api);
});
it("should return a user object", async () => {
// Perform the request. Under the hood, this
// emulates the `event` and `context` fed in
// from a Netlify Function
const response = await test.get("/user/123");
expect(response.statusCode).toBe(200);
// Regardless of your application output, the response
// from a Netlify Function will be a string, so we need
// to parse into JSON to assert on the returned objects
expect(response.body).toBeTypeOf("string");
const body = JSON.parse(response.body!);
expect(body).toContain({
id: "123",
name: "Ed",
});
});
});
```

@@ -84,5 +84,9 @@ import { HandlerContext } from '@netlify/functions';

}): InternalRouteHandler {
let routeUrl = url;
if (url.endsWith('/')) {
routeUrl = url.slice(0, -1) as TPath;
}
const route: InternalRouteHandler = {
method,
urlPattern: new UrlPattern(url),
urlPattern: new UrlPattern(routeUrl),
handlers,

@@ -98,3 +102,8 @@ };

const components = url.split('/');
if (routeUrl === '/') {
this.routeTree.routeHandler = route;
return route;
}
const components = routeUrl.split('/');
let current = this.routeTree;

@@ -140,4 +149,22 @@

const components = url.split('/').slice(1);
console.log({ components });
const [current, ...rest] = components;
console.log({ tree });
if (url === '/') {
if (tree.routeHandler) {
if (
tree.routeHandler.method === method &&
tree.routeHandler.urlPattern.match(fullUrl)
) {
return {
matchedRoute: tree.routeHandler,
params: tree.routeHandler.urlPattern.parse(fullUrl),
handlers: tree.routeHandler.handlers,
};
}
}
}
// Try a direct match

@@ -255,2 +282,22 @@ const node = tree.children?.[current];

}
public GetAllRoutes(): InternalRouteHandler[] {
const routes: InternalRouteHandler[] = [];
const recurse = (tree: RouteTree) => {
if (tree.routeHandler) {
routes.push(tree.routeHandler);
}
if (tree.children) {
for (const child of Object.values(tree.children)) {
recurse(child);
}
}
};
recurse(this.routeTree);
return routes;
}
}

@@ -63,3 +63,6 @@ import { ZodSchema, z } from 'zod';

export type RouteMiddleware = RouteHandler<any, any>;
export type RouteMiddleware<TPath extends string = any> = RouteHandler<
TPath,
any
>;

@@ -66,0 +69,0 @@ export interface InternalRouteHandler {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc