@shaferllc/keel 0.83.0 → 0.83.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/billing/billable.d.ts +2 -3
- package/dist/billing/billable.js +2 -3
- package/dist/billing/billing.config.stub +1 -1
- package/dist/billing/builder.d.ts +2 -2
- package/dist/billing/builder.js +2 -2
- package/dist/billing/provider.d.ts +1 -1
- package/dist/billing/provider.js +2 -2
- package/dist/billing/subscription-item.d.ts +0 -1
- package/dist/billing/subscription-item.js +0 -1
- package/dist/core/decorators.d.ts +5 -7
- package/dist/core/decorators.js +5 -7
- package/dist/core/exceptions.d.ts +2 -3
- package/dist/core/exceptions.js +2 -3
- package/dist/core/model-query.d.ts +1 -1
- package/dist/core/model-query.js +1 -1
- package/dist/core/request-logger.d.ts +2 -2
- package/dist/core/request-logger.js +2 -2
- package/dist/core/request.js +1 -1
- package/dist/core/testing.d.ts +3 -3
- package/dist/core/testing.js +3 -3
- package/docs/ai-manifest.json +14 -14
- package/docs/billing.md +45 -6
- package/docs/changelog.md +124 -21
- package/docs/cors.md +28 -0
- package/docs/decorators.md +2 -6
- package/docs/errors.md +1 -1
- package/docs/examples/billing.ts +128 -0
- package/docs/examples/cors.ts +29 -0
- package/docs/examples/hono.ts +29 -0
- package/docs/examples/openapi.ts +35 -0
- package/docs/examples/orm.ts +30 -0
- package/docs/examples/packages.ts +26 -0
- package/docs/examples/query-builder.ts +118 -0
- package/docs/examples/security.ts +31 -0
- package/docs/examples/social-auth.ts +76 -0
- package/docs/examples/starter-kits.ts +14 -0
- package/docs/examples/watch.ts +10 -0
- package/docs/hooks.md +1 -3
- package/docs/logger.md +2 -2
- package/docs/orm.md +39 -0
- package/docs/packages.md +3 -3
- package/docs/providers.md +6 -6
- package/docs/request-response.md +2 -2
- package/docs/starter-kits.md +14 -0
- package/docs/testing.md +1 -2
- package/docs/validation.md +1 -2
- package/docs/watch.md +1 -1
- package/llms-full.txt +145 -34
- package/llms.txt +13 -2
- package/package.json +1 -1
package/llms-full.txt
CHANGED
|
@@ -1233,12 +1233,12 @@ app.register(RateLimitProvider, { max: 100 }); // parameterized, like a plugin
|
|
|
1233
1233
|
The same provider class can be registered more than once with different options.
|
|
1234
1234
|
Without options, `this.options` is an empty object.
|
|
1235
1235
|
|
|
1236
|
-
>
|
|
1237
|
-
>
|
|
1238
|
-
>
|
|
1239
|
-
>
|
|
1240
|
-
>
|
|
1241
|
-
>
|
|
1236
|
+
> Keel providers are **not encapsulated** — bindings, decorators, and routes are
|
|
1237
|
+
> registered into the one global container. That's a deliberate simplification:
|
|
1238
|
+
> there's a single, predictable scope, and no plugin-boundary rules to reason
|
|
1239
|
+
> about. For per-request behavior in the HTTP pipeline (auth, logging, etc.),
|
|
1240
|
+
> reach for [middleware](./middleware.md), which *is* scoped to the routes you
|
|
1241
|
+
> attach it to.
|
|
1242
1242
|
|
|
1243
1243
|
## Generating a provider
|
|
1244
1244
|
|
|
@@ -3102,8 +3102,8 @@ and host (handy for building absolute links or forcing HTTPS).
|
|
|
3102
3102
|
|
|
3103
3103
|
`all()` understands JSON and form bodies. For anything else — XML, CSV, a binary
|
|
3104
3104
|
payload, a custom format — read the raw body and parse it yourself. There's no
|
|
3105
|
-
content-type parser registry to configure
|
|
3106
|
-
|
|
3105
|
+
content-type parser registry to configure: parsing is explicit, so you call the
|
|
3106
|
+
accessor you want.
|
|
3107
3107
|
|
|
3108
3108
|
```ts
|
|
3109
3109
|
await request.text(); // the body as a string (XML, CSV, …)
|
|
@@ -5559,10 +5559,9 @@ all gates/policies/hooks (a test helper).
|
|
|
5559
5559
|
|
|
5560
5560
|
# Billing
|
|
5561
5561
|
|
|
5562
|
-
Keel Billing is a subscription-billing layer
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
as a Keel [package](./packages.md) and supports two gateways behind one API:
|
|
5562
|
+
Keel Billing is a subscription-billing layer for charging customers, managing
|
|
5563
|
+
subscriptions, and reconciling gateway state through webhooks. It ships as a
|
|
5564
|
+
Keel [package](./packages.md) and supports two gateways behind one API:
|
|
5566
5565
|
**Stripe** and **Paddle**.
|
|
5567
5566
|
|
|
5568
5567
|
It attaches to a model with a mixin. Your `User` becomes billable, gains a
|
|
@@ -5765,6 +5764,46 @@ resolveBillableUsing(async (customerId) => {
|
|
|
5765
5764
|
});
|
|
5766
5765
|
```
|
|
5767
5766
|
|
|
5767
|
+
## A complete flow
|
|
5768
|
+
|
|
5769
|
+
From "user signs up" to "they're subscribed", with the fake gateway for tests:
|
|
5770
|
+
|
|
5771
|
+
```ts
|
|
5772
|
+
import { Model } from "@shaferllc/keel/core";
|
|
5773
|
+
import {
|
|
5774
|
+
Billable,
|
|
5775
|
+
BillingManager,
|
|
5776
|
+
FakeGateway,
|
|
5777
|
+
setBilling,
|
|
5778
|
+
} from "@shaferllc/keel/billing";
|
|
5779
|
+
|
|
5780
|
+
class User extends Billable(Model) {
|
|
5781
|
+
static table = "users";
|
|
5782
|
+
declare email: string;
|
|
5783
|
+
}
|
|
5784
|
+
|
|
5785
|
+
// In a test bootstrap:
|
|
5786
|
+
const fake = new FakeGateway();
|
|
5787
|
+
const manager = new BillingManager({
|
|
5788
|
+
default: "fake",
|
|
5789
|
+
currency: "usd",
|
|
5790
|
+
billableModel: "User",
|
|
5791
|
+
webhook: { path: "billing/webhook" },
|
|
5792
|
+
gateways: { stripe: { key: "", webhookSecret: "" }, paddle: { key: "", webhookSecret: "" }, fake: {} },
|
|
5793
|
+
});
|
|
5794
|
+
manager.register("fake", () => fake);
|
|
5795
|
+
setBilling(manager);
|
|
5796
|
+
|
|
5797
|
+
const user = await User.create({ email: "ada@example.com" });
|
|
5798
|
+
await user.newSubscription("default", "price_pro").trialDays(14).create();
|
|
5799
|
+
|
|
5800
|
+
await user.subscribed(); // true
|
|
5801
|
+
fake.calls.some((c) => c.method === "createSubscription"); // true
|
|
5802
|
+
```
|
|
5803
|
+
|
|
5804
|
+
In production you skip the fake manager — `BillingServiceProvider` wires the
|
|
5805
|
+
real gateway from `config/billing.ts` and `.env`.
|
|
5806
|
+
|
|
5768
5807
|
## Gateway differences
|
|
5769
5808
|
|
|
5770
5809
|
| Concern | Stripe | Paddle |
|
|
@@ -5780,8 +5819,8 @@ resolveBillableUsing(async (customerId) => {
|
|
|
5780
5819
|
The migration is gateway-neutral: `subscriptions` (with `gateway`,
|
|
5781
5820
|
`provider_id`, `provider_status`, `provider_price`, trial/grace timestamps),
|
|
5782
5821
|
`subscription_items`, and columns on `users` (`billing_gateway`,
|
|
5783
|
-
`billing_customer_id`, `pm_type`, `pm_last_four`, `trial_ends_at`).
|
|
5784
|
-
targets the standard `users` billable table.
|
|
5822
|
+
`billing_customer_id`, `pm_type`, `pm_last_four`, `trial_ends_at`). The default
|
|
5823
|
+
migration targets the standard `users` billable table.
|
|
5785
5824
|
|
|
5786
5825
|
## Testing
|
|
5787
5826
|
|
|
@@ -7612,6 +7651,34 @@ router.group(() => { /* … */ }).use(cors({ origin: ["https://app.example.com"]
|
|
|
7612
7651
|
With no options, `cors()` reflects the caller's origin — convenient in
|
|
7613
7652
|
development. **Lock it down in production** with an explicit allowlist.
|
|
7614
7653
|
|
|
7654
|
+
## A production API group
|
|
7655
|
+
|
|
7656
|
+
Typical setup for a JSON API served from `api.example.com` and called from a
|
|
7657
|
+
SPA on `app.example.com`:
|
|
7658
|
+
|
|
7659
|
+
```ts
|
|
7660
|
+
// app/Http/Kernel.ts
|
|
7661
|
+
import { cors } from "@shaferllc/keel/core";
|
|
7662
|
+
|
|
7663
|
+
this.use(
|
|
7664
|
+
cors({
|
|
7665
|
+
origin: ["https://app.example.com"],
|
|
7666
|
+
credentials: true, // cookies / Authorization
|
|
7667
|
+
exposeHeaders: ["X-Request-Id"],
|
|
7668
|
+
}),
|
|
7669
|
+
);
|
|
7670
|
+
```
|
|
7671
|
+
|
|
7672
|
+
During local development, allow any localhost port with a predicate:
|
|
7673
|
+
|
|
7674
|
+
```ts
|
|
7675
|
+
cors({
|
|
7676
|
+
origin: (origin) =>
|
|
7677
|
+
origin.startsWith("http://localhost:") || origin === "https://app.example.com",
|
|
7678
|
+
credentials: true,
|
|
7679
|
+
});
|
|
7680
|
+
```
|
|
7681
|
+
|
|
7615
7682
|
## Options
|
|
7616
7683
|
|
|
7617
7684
|
```ts
|
|
@@ -8162,10 +8229,9 @@ arguments still halts the request and renders an empty page.
|
|
|
8162
8229
|
|
|
8163
8230
|
Attach named, computed values to the current request — `request.user`,
|
|
8164
8231
|
`request.tenant`, `request.locale` — resolved **lazily** and **memoized for the
|
|
8165
|
-
life of the request**.
|
|
8166
|
-
but without the footguns: you register a resolver once, and Keel computes it on
|
|
8232
|
+
life of the request**. You register a resolver once, and Keel computes it on
|
|
8167
8233
|
first access and caches it per request. No null-placeholder declaration, no
|
|
8168
|
-
|
|
8234
|
+
shared-state leak between requests.
|
|
8169
8235
|
|
|
8170
8236
|
> Decorating the **application** is already the [service container's](./container.md)
|
|
8171
8237
|
> job — `bind` / `singleton` / `instance` / `make`, with `bound()` as
|
|
@@ -8213,9 +8279,6 @@ setRequestValue("user", theAuthenticatedUser);
|
|
|
8213
8279
|
const user = await decorated("user"); // returns the value set above, no re-lookup
|
|
8214
8280
|
```
|
|
8215
8281
|
|
|
8216
|
-
This is the clean version of Fastify's "declare a placeholder, set it in an
|
|
8217
|
-
`onRequest` hook" pattern.
|
|
8218
|
-
|
|
8219
8282
|
## Why lazy + memoized
|
|
8220
8283
|
|
|
8221
8284
|
Resolving the current user (or tenant, or locale, or a feature-flag set) is the
|
|
@@ -8479,7 +8542,7 @@ subclasses don't define either — they render through the default path.
|
|
|
8479
8542
|
|
|
8480
8543
|
When all you want is a coded error class — a stable `code`, a message, a status —
|
|
8481
8544
|
skip the boilerplate and mint one with `createError`. It's the ergonomic shortcut
|
|
8482
|
-
for the common case
|
|
8545
|
+
for the common case:
|
|
8483
8546
|
|
|
8484
8547
|
```ts
|
|
8485
8548
|
import { createError } from "@shaferllc/keel/core";
|
|
@@ -10418,9 +10481,7 @@ implementing anything — the same `fetch` handler just gets served over it.
|
|
|
10418
10481
|
# Lifecycle Hooks
|
|
10419
10482
|
|
|
10420
10483
|
Tap into the **application lifecycle** — run code once the app is ready, clean up
|
|
10421
|
-
on shutdown, and observe route registration.
|
|
10422
|
-
[Fastify's hooks](https://fastify.dev/docs/latest/Reference/Hooks/), scoped to the
|
|
10423
|
-
parts Keel doesn't already cover.
|
|
10484
|
+
on shutdown, and observe route registration.
|
|
10424
10485
|
|
|
10425
10486
|
> **Request-lifecycle hooks** (before/after a request, on error) are
|
|
10426
10487
|
> [middleware](./middleware.md) in Keel — `HttpKernel.use()`, route/group
|
|
@@ -11585,8 +11646,8 @@ With no options it defaults to `level: "info"`, `pretty: false`, and no bindings
|
|
|
11585
11646
|
|
|
11586
11647
|
`requestLogger()` is a built-in middleware that binds a **child logger with a
|
|
11587
11648
|
generated `reqId` to each request**, so every log line within a request
|
|
11588
|
-
correlates
|
|
11589
|
-
|
|
11649
|
+
correlates. Install it in your HTTP kernel, then reach the request's logger
|
|
11650
|
+
anywhere with `requestLog()`:
|
|
11590
11651
|
|
|
11591
11652
|
```ts
|
|
11592
11653
|
import { requestLogger, requestLog } from "@shaferllc/keel/core";
|
|
@@ -14941,6 +15002,44 @@ query shapes without an ORM dependency. For a gnarly one-off report, reach for
|
|
|
14941
15002
|
the [query builder](./query-builder.md) or a raw `connection().select(sql)`; the
|
|
14942
15003
|
model layer never gets in the way.
|
|
14943
15004
|
|
|
15005
|
+
## A worked example
|
|
15006
|
+
|
|
15007
|
+
A blog with authors and posts — enough to see CRUD, a relation, and eager loading
|
|
15008
|
+
together:
|
|
15009
|
+
|
|
15010
|
+
```ts
|
|
15011
|
+
import { Model } from "@shaferllc/keel/core";
|
|
15012
|
+
|
|
15013
|
+
class Post extends Model {
|
|
15014
|
+
static table = "posts";
|
|
15015
|
+
static fillable = ["title", "body"];
|
|
15016
|
+
declare id: number;
|
|
15017
|
+
declare title: string;
|
|
15018
|
+
declare user_id: number;
|
|
15019
|
+
|
|
15020
|
+
author() { return this.belongsTo(User); }
|
|
15021
|
+
}
|
|
15022
|
+
|
|
15023
|
+
class User extends Model {
|
|
15024
|
+
static table = "users";
|
|
15025
|
+
declare id: number;
|
|
15026
|
+
declare email: string;
|
|
15027
|
+
|
|
15028
|
+
posts() { return this.hasMany(Post); }
|
|
15029
|
+
}
|
|
15030
|
+
|
|
15031
|
+
const ada = await User.create({ email: "ada@example.com" });
|
|
15032
|
+
await ada.posts().create({ title: "Notes on engines", body: "…" });
|
|
15033
|
+
|
|
15034
|
+
const withPosts = await User.with("posts").where("id", ada.id).first();
|
|
15035
|
+
for (const post of (withPosts as User & { posts: Post[] }).posts) {
|
|
15036
|
+
console.log(post.title);
|
|
15037
|
+
}
|
|
15038
|
+
```
|
|
15039
|
+
|
|
15040
|
+
For the full surface — casts, soft deletes, scopes, polymorphic relations —
|
|
15041
|
+
see [Models](./models.md).
|
|
15042
|
+
|
|
14944
15043
|
|
|
14945
15044
|
|
|
14946
15045
|
---
|
|
@@ -14956,9 +15055,9 @@ adds the conventions a *shippable* package needs so it can carry its own schema
|
|
|
14956
15055
|
and assets instead of asking the app to wire them by hand.
|
|
14957
15056
|
|
|
14958
15057
|
[Keel Watch](./watch.md) — the debug dashboard — is a first-party package and the
|
|
14959
|
-
reference implementation of everything below. [Billing](./billing.md) (
|
|
14960
|
-
|
|
14961
|
-
|
|
15058
|
+
reference implementation of everything below. [Billing](./billing.md) (Stripe and
|
|
15059
|
+
Paddle subscriptions) is another, and shows a package contributing models, a
|
|
15060
|
+
schema migration, gateway drivers, and verified webhook routes.
|
|
14962
15061
|
|
|
14963
15062
|
## The shape of a package
|
|
14964
15063
|
|
|
@@ -17637,6 +17736,20 @@ to finish.
|
|
|
17637
17736
|
| `app` *(default)* | Full-stack: views, sessions, register/login, password reset, two-factor. |
|
|
17638
17737
|
| `saas` | `app` plus teams, roles, invitations, billing, and multi-tenancy. |
|
|
17639
17738
|
|
|
17739
|
+
## Pick a kit
|
|
17740
|
+
|
|
17741
|
+
```bash
|
|
17742
|
+
npm create keeljs@latest my-app # app (default)
|
|
17743
|
+
npm create keeljs@latest my-api -- --preset api
|
|
17744
|
+
npm create keeljs@latest my-saas -- --preset saas
|
|
17745
|
+
npm create keeljs@latest bare -- --preset minimal
|
|
17746
|
+
cd my-app && npm install && npm run dev
|
|
17747
|
+
```
|
|
17748
|
+
|
|
17749
|
+
Then open `http://localhost:3000`. The SaaS kit already has a team switcher,
|
|
17750
|
+
invites, and a billing stub wired through [teams](./teams.md) and
|
|
17751
|
+
[billing](./billing.md) — start by editing `app/Models` and `routes/web.ts`.
|
|
17752
|
+
|
|
17640
17753
|
## Every database, Cloudflare first
|
|
17641
17754
|
|
|
17642
17755
|
Each kit ships with all four drivers wired. Switching is `DB_CONNECTION` and nothing
|
|
@@ -19171,8 +19284,7 @@ construct it directly.
|
|
|
19171
19284
|
|
|
19172
19285
|
Test your app by **injecting requests** — no server, no port, no network — and
|
|
19173
19286
|
asserting on the response. `testClient()` wraps your app's Hono instance (which
|
|
19174
|
-
already does fetch-style injection) with verb helpers and fluent assertions
|
|
19175
|
-
way Fastify's `inject()` works.
|
|
19287
|
+
already does fetch-style injection) with verb helpers and fluent assertions.
|
|
19176
19288
|
|
|
19177
19289
|
## The client
|
|
19178
19290
|
|
|
@@ -20355,8 +20467,7 @@ router.get("/posts/:id", [Posts, "show"]).middleware([
|
|
|
20355
20467
|
|
|
20356
20468
|
`validated(part)` returns the parsed, typed value for that part (defaults to
|
|
20357
20469
|
`"body"`). Coercion (`z.coerce.number()`) is the schema's job — it applies before
|
|
20358
|
-
your handler sees the value.
|
|
20359
|
-
route schemas, on top of the same `validate()` engine.
|
|
20470
|
+
your handler sees the value. Built on the same `validate()` engine.
|
|
20360
20471
|
|
|
20361
20472
|
## Body parsing is JSON-only
|
|
20362
20473
|
|
|
@@ -21253,7 +21364,7 @@ Vite's `manifest.json`, as produced by the build. You rarely touch it directly
|
|
|
21253
21364
|
|
|
21254
21365
|
# Watch
|
|
21255
21366
|
|
|
21256
|
-
Keel Watch is a debug dashboard
|
|
21367
|
+
Keel Watch is a debug dashboard for Keel apps. It records the requests,
|
|
21257
21368
|
queries, exceptions, logs, jobs, mail, notifications, cache lookups, events, and
|
|
21258
21369
|
scheduled tasks flowing through your app, and shows them in a single-page UI at
|
|
21259
21370
|
`/watch`, with every request linked to the queries and logs it produced.
|
package/llms.txt
CHANGED
|
@@ -15,7 +15,7 @@ Userland imports everything from `@shaferllc/keel/core`.
|
|
|
15
15
|
- [Architecture](https://github.com/shaferllc/keel/blob/main/docs/architecture.md): Keel is small on purpose. This page maps the pieces and traces a request from socket to response. Nothing here is magic — every layer is a short, readable file in src/core/, and this guide is mostly a reading order for it.
|
|
16
16
|
- [Authentication](https://github.com/shaferllc/keel/blob/main/docs/authentication.md): Session-based auth built on the pieces you already have: sessions hold the login, hashing checks passwords.
|
|
17
17
|
- [Authorization](https://github.com/shaferllc/keel/blob/main/docs/authorization.md): Where authentication answers who you are, authorization answers what you're allowed to do.
|
|
18
|
-
- [Billing](https://github.com/shaferllc/keel/blob/main/docs/billing.md): Keel Billing is a subscription-billing layer
|
|
18
|
+
- [Billing](https://github.com/shaferllc/keel/blob/main/docs/billing.md): Keel Billing is a subscription-billing layer for charging customers, managing subscriptions, and reconciling gateway state through webhooks.
|
|
19
19
|
- [Broadcasting](https://github.com/shaferllc/keel/blob/main/docs/broadcasting.md): Push events to clients in real time over named channels.
|
|
20
20
|
- [Service Broker](https://github.com/shaferllc/keel/blob/main/docs/broker.md): Structure an application as services that talk to each other by name instead of by import.
|
|
21
21
|
- [Cache](https://github.com/shaferllc/keel/blob/main/docs/cache.md): A small cache with TTLs and the remember pattern.
|
|
@@ -72,7 +72,7 @@ Userland imports everything from `@shaferllc/keel/core`.
|
|
|
72
72
|
- [Validation](https://github.com/shaferllc/keel/blob/main/docs/validation.md): validate() parses request input against a schema and returns typed data.
|
|
73
73
|
- [Views](https://github.com/shaferllc/keel/blob/main/docs/views.md): Keel renders HTML with Hono JSX — type-safe components that run identically on Node and on Cloudflare Workers (no filesystem templating, so it ports anywhere).
|
|
74
74
|
- [Vite](https://github.com/shaferllc/keel/blob/main/docs/vite.md): Wire a modern frontend build — bundling, hashed filenames, hot module reload — to Keel's server-rendered HTML, the way modern full-stack frameworks do.
|
|
75
|
-
- [Watch](https://github.com/shaferllc/keel/blob/main/docs/watch.md): Keel Watch is a debug dashboard
|
|
75
|
+
- [Watch](https://github.com/shaferllc/keel/blob/main/docs/watch.md): Keel Watch is a debug dashboard for Keel apps.
|
|
76
76
|
|
|
77
77
|
## Examples
|
|
78
78
|
|
|
@@ -82,6 +82,7 @@ Every topic has a runnable, type-checked example:
|
|
|
82
82
|
- [API Resources example](https://github.com/shaferllc/keel/blob/main/docs/examples/api-resources.ts)
|
|
83
83
|
- [Authentication example](https://github.com/shaferllc/keel/blob/main/docs/examples/authentication.ts)
|
|
84
84
|
- [Authorization example](https://github.com/shaferllc/keel/blob/main/docs/examples/authorization.ts)
|
|
85
|
+
- [Billing example](https://github.com/shaferllc/keel/blob/main/docs/examples/billing.ts)
|
|
85
86
|
- [Broadcasting example](https://github.com/shaferllc/keel/blob/main/docs/examples/broadcasting.ts)
|
|
86
87
|
- [Service Broker example](https://github.com/shaferllc/keel/blob/main/docs/examples/broker.ts)
|
|
87
88
|
- [Cache example](https://github.com/shaferllc/keel/blob/main/docs/examples/cache.ts)
|
|
@@ -89,6 +90,7 @@ Every topic has a runnable, type-checked example:
|
|
|
89
90
|
- [The Console example](https://github.com/shaferllc/keel/blob/main/docs/examples/console.ts)
|
|
90
91
|
- [The Service Container example](https://github.com/shaferllc/keel/blob/main/docs/examples/container.ts)
|
|
91
92
|
- [Controllers example](https://github.com/shaferllc/keel/blob/main/docs/examples/controllers.ts)
|
|
93
|
+
- [CORS example](https://github.com/shaferllc/keel/blob/main/docs/examples/cors.ts)
|
|
92
94
|
- [Database example](https://github.com/shaferllc/keel/blob/main/docs/examples/database.ts)
|
|
93
95
|
- [Debugging example](https://github.com/shaferllc/keel/blob/main/docs/examples/debugging.ts)
|
|
94
96
|
- [Request Decorators example](https://github.com/shaferllc/keel/blob/main/docs/examples/decorators.ts)
|
|
@@ -98,6 +100,7 @@ Every topic has a runnable, type-checked example:
|
|
|
98
100
|
- [Hashing & Encryption example](https://github.com/shaferllc/keel/blob/main/docs/examples/hashing.ts)
|
|
99
101
|
- [Health Checks example](https://github.com/shaferllc/keel/blob/main/docs/examples/health.ts)
|
|
100
102
|
- [Helpers example](https://github.com/shaferllc/keel/blob/main/docs/examples/helpers.ts)
|
|
103
|
+
- [Built on Hono example](https://github.com/shaferllc/keel/blob/main/docs/examples/hono.ts)
|
|
101
104
|
- [Lifecycle Hooks example](https://github.com/shaferllc/keel/blob/main/docs/examples/hooks.ts)
|
|
102
105
|
- [Internationalization example](https://github.com/shaferllc/keel/blob/main/docs/examples/i18n.ts)
|
|
103
106
|
- [Inertia example](https://github.com/shaferllc/keel/blob/main/docs/examples/inertia.ts)
|
|
@@ -108,15 +111,22 @@ Every topic has a runnable, type-checked example:
|
|
|
108
111
|
- [Migrations example](https://github.com/shaferllc/keel/blob/main/docs/examples/migrations.ts)
|
|
109
112
|
- [Models example](https://github.com/shaferllc/keel/blob/main/docs/examples/models.ts)
|
|
110
113
|
- [Notifications example](https://github.com/shaferllc/keel/blob/main/docs/examples/notification.ts)
|
|
114
|
+
- [OpenAPI example](https://github.com/shaferllc/keel/blob/main/docs/examples/openapi.ts)
|
|
115
|
+
- [ORM example](https://github.com/shaferllc/keel/blob/main/docs/examples/orm.ts)
|
|
116
|
+
- [Packages example](https://github.com/shaferllc/keel/blob/main/docs/examples/packages.ts)
|
|
111
117
|
- [Pages example](https://github.com/shaferllc/keel/blob/main/docs/examples/pages.ts)
|
|
112
118
|
- [Service Providers example](https://github.com/shaferllc/keel/blob/main/docs/examples/providers.ts)
|
|
119
|
+
- [Query Builder example](https://github.com/shaferllc/keel/blob/main/docs/examples/query-builder.ts)
|
|
113
120
|
- [Queues & Jobs example](https://github.com/shaferllc/keel/blob/main/docs/examples/queues.ts)
|
|
114
121
|
- [Rate Limiting example](https://github.com/shaferllc/keel/blob/main/docs/examples/rate-limiting.ts)
|
|
115
122
|
- [Redis example](https://github.com/shaferllc/keel/blob/main/docs/examples/redis.ts)
|
|
116
123
|
- [Request & Response example](https://github.com/shaferllc/keel/blob/main/docs/examples/request-response.ts)
|
|
117
124
|
- [Routing example](https://github.com/shaferllc/keel/blob/main/docs/examples/routing.ts)
|
|
118
125
|
- [Task Scheduling example](https://github.com/shaferllc/keel/blob/main/docs/examples/scheduling.ts)
|
|
126
|
+
- [Securing SSR apps example](https://github.com/shaferllc/keel/blob/main/docs/examples/security.ts)
|
|
119
127
|
- [Sessions example](https://github.com/shaferllc/keel/blob/main/docs/examples/sessions.ts)
|
|
128
|
+
- [Social authentication example](https://github.com/shaferllc/keel/blob/main/docs/examples/social-auth.ts)
|
|
129
|
+
- [Starter kits example](https://github.com/shaferllc/keel/blob/main/docs/examples/starter-kits.ts)
|
|
120
130
|
- [Static Files example](https://github.com/shaferllc/keel/blob/main/docs/examples/static-files.ts)
|
|
121
131
|
- [Storage example](https://github.com/shaferllc/keel/blob/main/docs/examples/storage.ts)
|
|
122
132
|
- [Teams example](https://github.com/shaferllc/keel/blob/main/docs/examples/teams.ts)
|
|
@@ -128,6 +138,7 @@ Every topic has a runnable, type-checked example:
|
|
|
128
138
|
- [Validation example](https://github.com/shaferllc/keel/blob/main/docs/examples/validation.ts)
|
|
129
139
|
- [Views example](https://github.com/shaferllc/keel/blob/main/docs/examples/views.tsx)
|
|
130
140
|
- [Vite example](https://github.com/shaferllc/keel/blob/main/docs/examples/vite.ts)
|
|
141
|
+
- [Watch example](https://github.com/shaferllc/keel/blob/main/docs/examples/watch.ts)
|
|
131
142
|
|
|
132
143
|
## Optional
|
|
133
144
|
|
package/package.json
CHANGED