spfn 0.2.0-beta.64 → 0.2.0-beta.66
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 +109 -5
- package/dist/index.js +513 -393
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -20,7 +20,8 @@ Or add it as a project dependency (`spfn init`/`spfn create` do this for you), t
|
|
|
20
20
|
call it via `pnpm spfn <command>` / `npm run spfn:<script>`.
|
|
21
21
|
|
|
22
22
|
Requirements: Node.js 18.18+ for bare mode, Node.js 20+ for full mode's MCP server,
|
|
23
|
-
Next.js
|
|
23
|
+
Next.js 16.2.11+ (App Router, `src/` dir), PostgreSQL 14+ (Redis optional). Next.js 15
|
|
24
|
+
is not supported — see [the root README](../../README.md#what-do-i-need-installed).
|
|
24
25
|
|
|
25
26
|
## Usage
|
|
26
27
|
|
|
@@ -48,7 +49,7 @@ with `--pm`. In a pnpm workspace, `create` installs from the workspace root.
|
|
|
48
49
|
## Commands
|
|
49
50
|
|
|
50
51
|
Registered top-level commands: `create`, `init`, `add`, `dev`, `build`, `start`,
|
|
51
|
-
`
|
|
52
|
+
`provision`, `codegen`, `contract`, `key`, `setup`, `db`, `env`, `secret`.
|
|
52
53
|
|
|
53
54
|
### `spfn create <name>`
|
|
54
55
|
|
|
@@ -101,6 +102,23 @@ How it works: if not already present it installs the package, then reads the pac
|
|
|
101
102
|
function migrations to `DATABASE_URL`. If `DATABASE_URL` is unset, migration is skipped
|
|
102
103
|
with a hint to run `spfn db push` later. Works with published and workspace packages.
|
|
103
104
|
|
|
105
|
+
### `spfn add vercel`
|
|
106
|
+
|
|
107
|
+
`vercel` is not a package — it is a built-in target, and the one argument to `add` that is
|
|
108
|
+
not a scoped package name. It scaffolds the three files a Next.js + SPFN app needs to run
|
|
109
|
+
its backend as Vercel Functions:
|
|
110
|
+
|
|
111
|
+
| File | What it is |
|
|
112
|
+
|------|------------|
|
|
113
|
+
| `src/app/api/backend/[[...route]]/route.ts` | `hono/vercel` adapter, mounts the SPFN app under `/api/backend` |
|
|
114
|
+
| `vercel.json` | build config (`pnpm spfn:build`) |
|
|
115
|
+
| `.npmrc` | `@spfn` registry auth, reading `GITEA_NPM_TOKEN` from the environment — never committed |
|
|
116
|
+
|
|
117
|
+
Existing files are never overwritten; they are reported and skipped. The runtime behind
|
|
118
|
+
the adapter is `createServerlessApp()` from `@spfn/core/server`. Afterwards, point
|
|
119
|
+
`SPFN_API_URL` at `https://<your-domain>/api/backend`, and make sure `hono` is a direct
|
|
120
|
+
dependency of the app so `hono/vercel` resolves.
|
|
121
|
+
|
|
104
122
|
### `spfn dev`
|
|
105
123
|
|
|
106
124
|
Starts the SPFN server + Next.js (and a codegen watcher). The server must report ready
|
|
@@ -176,6 +194,43 @@ export default defineConfig({
|
|
|
176
194
|
});
|
|
177
195
|
```
|
|
178
196
|
|
|
197
|
+
### `spfn contract`
|
|
198
|
+
|
|
199
|
+
Manages the route contract — what a **separately deployed** client (a mobile app, an external
|
|
200
|
+
API consumer) is promised. A web client needs none of this: it derives its types from
|
|
201
|
+
`AppRouter` in the same build, so a broken response already fails the compile.
|
|
202
|
+
|
|
203
|
+
Requires the `@spfn/core:contract` generator in `.spfnrc.ts`. Every command regenerates the
|
|
204
|
+
contract from the router first, so a stale `contracts/current.json` is never what gets checked
|
|
205
|
+
or released.
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# Regenerate and compare against the newest released snapshot
|
|
209
|
+
spfn contract check
|
|
210
|
+
|
|
211
|
+
# Cut a release — writes contracts/released/1.3.0.json. Commit it.
|
|
212
|
+
spfn contract release 1.3.0
|
|
213
|
+
|
|
214
|
+
# List released snapshots
|
|
215
|
+
spfn contract list
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
| Subcommand | Description | Exit code |
|
|
219
|
+
|------------|-------------|-----------|
|
|
220
|
+
| `contract check` | Compares the current contract against the newest released snapshot | 1 when a promise is broken |
|
|
221
|
+
| `contract release <version>` | Writes the snapshot every later build is compared against | 1 when the contract is broken, the version already exists, or it is not newer than the newest one |
|
|
222
|
+
| `contract list` (`ls`) | Lists released snapshots | 0 |
|
|
223
|
+
|
|
224
|
+
`--dir <path>` overrides the contracts directory; by default it comes from the generator's
|
|
225
|
+
`outputDir` in `.spfnrc.ts`.
|
|
226
|
+
|
|
227
|
+
**`spfn build` runs the same gate.** A broken contract fails the build with a non-zero exit
|
|
228
|
+
code — that is the point of hanging the check off codegen rather than leaving it to a
|
|
229
|
+
separate step.
|
|
230
|
+
|
|
231
|
+
See [`@spfn/core` contract docs](../core/src/contract/README.md) for the case table and the
|
|
232
|
+
removal rules.
|
|
233
|
+
|
|
179
234
|
### `spfn db`
|
|
180
235
|
|
|
181
236
|
Wraps Drizzle Kit with auto-generated config. Most commands read `DATABASE_URL` from the
|
|
@@ -186,6 +241,7 @@ loaded `.env` chain.
|
|
|
186
241
|
| `db generate` (`g`) | Generate migrations from schema changes (timestamp-prefixed) |
|
|
187
242
|
| `db push` | Diff with Drizzle Kit's current PostgreSQL engine and apply the selected DDL atomically. Destructive changes need confirmation; `--force` applies them, `--dry-run` previews |
|
|
188
243
|
| `db migrate` (`m`) | Run pending migrations. `--with-backup` snapshots first |
|
|
244
|
+
| `db status` | Show which migrations are applied and which are pending, for the project and for each installed function package |
|
|
189
245
|
| `db studio` | Open Drizzle Studio. `-p, --port` (auto-finds a free port) |
|
|
190
246
|
| `db check` | Verify the database connection |
|
|
191
247
|
| `db drop` | Drop all tables — **destructive**, double-prompts (see [Pitfalls](#pitfalls)) |
|
|
@@ -396,7 +452,16 @@ the SPFN API with cookie forwarding and interceptors, resolving routes via the g
|
|
|
396
452
|
|
|
397
453
|
## Deployment
|
|
398
454
|
|
|
399
|
-
|
|
455
|
+
Two targets, both shipping from the same repository.
|
|
456
|
+
|
|
457
|
+
**Vercel — serverless, one origin, no container.** Run `spfn add vercel` (above) and
|
|
458
|
+
deploy. Frontend and backend share a single Vercel origin. One caveat: the in-process job
|
|
459
|
+
worker does not run there, so enqueuing works but nothing drains the queue — schedule a
|
|
460
|
+
route that processes a batch (Vercel Cron), or run jobs on an always-on target.
|
|
461
|
+
|
|
462
|
+
**Always-on — a long-lived process.** `spfn build` then `spfn start`, or the generated
|
|
463
|
+
Docker files. Background jobs, WebSocket events and the periodic database health check all
|
|
464
|
+
need this path.
|
|
400
465
|
|
|
401
466
|
```bash
|
|
402
467
|
# Build + run locally
|
|
@@ -423,6 +488,42 @@ type ships from `spfn` (`@type {import('spfn').SpfnConfig}`).
|
|
|
423
488
|
|
|
424
489
|
---
|
|
425
490
|
|
|
491
|
+
## FAQ
|
|
492
|
+
|
|
493
|
+
**`create` or `init` — which one?**
|
|
494
|
+
`create` starts a new project: it runs `create-next-app` with SPFN's flags and then runs
|
|
495
|
+
`init` inside it. `init` adds SPFN to a Next.js app that already exists. If you built
|
|
496
|
+
something with an AI coding agent and now want a real backend under it, `init` is the one.
|
|
497
|
+
|
|
498
|
+
**`bare` or `full`?**
|
|
499
|
+
`full` is the recommended baseline: core, auth, i18n and MCP wired together, so you get a
|
|
500
|
+
working authenticated app on day one. `bare` is core only — the architecture with nothing
|
|
501
|
+
else decided. Automation should always pass `--mode` explicitly, because a `--yes` run
|
|
502
|
+
without one still produces `bare` for backward compatibility.
|
|
503
|
+
|
|
504
|
+
**Why doesn't my server restart when I edit a file?**
|
|
505
|
+
Because hot reload is off by default. `spfn dev --watch` restarts the server on `src/server`
|
|
506
|
+
changes. Next.js reloads on its own either way.
|
|
507
|
+
|
|
508
|
+
**Do I have to use Docker?**
|
|
509
|
+
No. Vercel is a first-class target and needs no container. Docker is the always-on path,
|
|
510
|
+
and `docker compose up -d` is also the convenient way to get PostgreSQL and Redis locally —
|
|
511
|
+
pointing at your own PostgreSQL works too. PostgreSQL itself is not optional.
|
|
512
|
+
|
|
513
|
+
**Which Node version do I need?**
|
|
514
|
+
18.18 or later for bare mode, 20 or later for full mode, because full mode includes the
|
|
515
|
+
MCP server.
|
|
516
|
+
|
|
517
|
+
**When do I have to run codegen by hand?**
|
|
518
|
+
Whenever routes change outside `spfn dev`, which runs a codegen watcher for you. A stale or
|
|
519
|
+
missing `src/generated/route-map.ts` makes the RPC proxy answer 404 — run `spfn codegen run`
|
|
520
|
+
and commit the result.
|
|
521
|
+
|
|
522
|
+
**Where do secrets go?**
|
|
523
|
+
`.env.server` (gitignored, server-only) for backend values, `.env.local` for the session
|
|
524
|
+
cookie secret that the Next.js runtime itself needs. Never `spfn.config.js` — that file is
|
|
525
|
+
committed.
|
|
526
|
+
|
|
426
527
|
## Pitfalls
|
|
427
528
|
|
|
428
529
|
- **`.env.server` is gitignored and server-only.** Put backend-only DB/secret values there,
|
|
@@ -441,7 +542,8 @@ type ships from `spfn` (`@type {import('spfn').SpfnConfig}`).
|
|
|
441
542
|
destructive ones unless `--force`/confirmed. Prefer `db generate` + `db migrate` for
|
|
442
543
|
production; `db push` is dev-only.
|
|
443
544
|
- **`spfn add` requires a scoped package name** (must contain `/`) and only applies
|
|
444
|
-
migrations when `DATABASE_URL` is set — otherwise it skips with a hint.
|
|
545
|
+
migrations when `DATABASE_URL` is set — otherwise it skips with a hint. The single
|
|
546
|
+
exception is `spfn add vercel`, a built-in target rather than a package.
|
|
445
547
|
- **Package manager is auto-detected from lockfiles.** If detection is wrong (e.g. mixed
|
|
446
548
|
lockfiles), pass `--pm` to `create`. In a pnpm workspace, `create` installs from the
|
|
447
549
|
workspace root, not the new project dir.
|
|
@@ -456,5 +558,7 @@ type ships from `spfn` (`@type {import('spfn').SpfnConfig}`).
|
|
|
456
558
|
|
|
457
559
|
## Related
|
|
458
560
|
|
|
459
|
-
- `@spfn/core` — server, route DSL, codegen, db, client runtime.
|
|
561
|
+
- [`@spfn/core`](../core/README.md) — server, route DSL, codegen, db, client runtime.
|
|
562
|
+
- [`@spfn/auth`](../auth/README.md) — what `--mode full` wires in for accounts and roles.
|
|
563
|
+
- [`@spfn/mcp`](../mcp/README.md) — what `--mode full` wires in for operating the app.
|
|
460
564
|
- Project root README — framework overview and getting started.
|