andale
v0.7.1
Published
Andale (spanish for "come along") is a new take on routing frameworks. It is built on [effect](https://effect.website/) and focuses on functional concepts, type safety and easy code re-use.
Readme
Andale
Andale (spanish for "come along") is a new take on routing frameworks. It is built on effect and focuses on functional concepts, type safety and easy code re-use.
Documentation
Highlights, Reasons to use
Typesafe paths
Given a route like
{@includeCode ./tests/how-tos/EnforceQueryParams.test.ts#route}
You can build a typesafe path like
{@includeCode ./tests/how-tos/EnforceQueryParams.test.ts#path}
Simple dependency usage
{@includeCode ./tests/how-tos/Auth.test.ts#route}
Easy content negotiation
{@includeCode ./tests/how-tos/ContentNegotiation.test.ts#html route}
Straigtforward body parsing
Define a schema {@includeCode ./tests/how-tos/Structure/User/Entity.ts#schema} and use it {@includeCode ./tests/how-tos/Structure/User/Resource.ts#putUser}
For more information please check out the how-tos.
Inflating nested structures
Where you'd normally use JSON to send nested structures andale simply inflates your form values by key. E.g.
{@includeCode ./src/Body/Body.test.ts#inflate urlencoded}
Sends the key "friends[0].name" with value "Mary" which results in John having a Friend!
Ok, in all seriousness, it shouldn't be hard to imagine simply using a <form> with the
appropriate name attributes, e.g. like this:
const userForm = A.path("/user/create");
const getUser = userForm.pipe(
A.verb("GET"),
A.respond(function* () {
return yield* A.Response.html(`
<form>
<input name="name" />
<input name="age" type="number" />
<input name="friends[0].name" />
<button formmethod="POST" formaction="${A.pathTo(userForm)}" />
</form>
`);
}),
);
const postUser = userForm.pipe(
A.verb("POST"),
A.body(User.omit("id")),
A.respond(function* ({ body }) {
yield* UserService.save(body).pipe(
Effect.mapError(() => new A.Error.GenericServerError()),
);
return new Response(null, { status: 201 });
}),
);You could even combine this with htmx-tsx and some
light type magic to build typesafe forms ;)
Quick Start
{@include ./tests/how-tos/Quickstart.md}
Contributing
The structure follows a few simple rules:
- Modules are uppercased
- Every
modulehas its own directory which has the same name as themodule, e.g.Foo/Foo.ts - The
moduleexports EVERYTHING - There must be a
index.tsfile which lists the public exports, e.g.Foo/index.ts. - there must be a
<module name>.test.tsfile next to themodule, e.g.Foo/Foo.test.ts. This test module is meant for whitebox tests - Blackbox tests go into the
tests/folder in the root and must never use anything else but theAmodule.
