@pikku/cli 0.12.34 → 0.12.36
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/cli.schema.json +1 -1
- package/console-app/assets/index-Dxl3JsMK.js +233 -0
- package/console-app/index.html +1 -1
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-channel.js +6 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +6 -0
- package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
- package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +2 -2
- package/dist/.pikku/function/pikku-function-types.gen.js +17 -3
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +238 -221
- package/dist/.pikku/function/pikku-functions.gen.js +3 -1
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
- package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
- package/dist/.pikku/pikku-meta-service.gen.js +1 -1
- package/dist/.pikku/pikku-services.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +5 -4
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +17 -13
- package/dist/.pikku/schemas/schemas/DbGenerateInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuFunctionTypesInput.schema.json +1 -0
- package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
- package/dist/.pikku/workflow/meta/allWorkflow.gen.json +22 -4
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
- package/dist/bin/pikku-bin.mjs +2 -2
- package/dist/src/cli.wiring.js +5 -0
- package/dist/src/fabric/functions/login.function.d.ts +1 -1
- package/dist/src/fabric/functions/login.function.js +1 -1
- package/dist/src/functions/commands/bootstrap.js +1 -1
- package/dist/src/functions/commands/db-generate.d.ts +1 -0
- package/dist/src/functions/commands/db-generate.js +45 -0
- package/dist/src/functions/commands/db-migrate.js +13 -1
- package/dist/src/functions/db/annotation-parser.d.ts +27 -16
- package/dist/src/functions/db/annotation-parser.js +50 -110
- package/dist/src/functions/db/better-auth-schema.d.ts +23 -0
- package/dist/src/functions/db/better-auth-schema.js +122 -0
- package/dist/src/functions/db/coercion-plugin.d.ts +1 -1
- package/dist/src/functions/db/coercion-plugin.js +4 -0
- package/dist/src/functions/db/db-codegen.d.ts +13 -1
- package/dist/src/functions/db/db-codegen.js +142 -31
- package/dist/src/functions/db/db-introspector.d.ts +6 -0
- package/dist/src/functions/db/local-db.d.ts +33 -0
- package/dist/src/functions/db/local-db.js +221 -79
- package/dist/src/functions/db/postgres/postgres-introspector.js +2 -0
- package/dist/src/functions/db/zod-codegen.d.ts +38 -0
- package/dist/src/functions/db/zod-codegen.js +153 -38
- package/dist/src/functions/validate/workspace-validate.js +1 -1
- package/dist/src/functions/wirings/auth/pikku-command-auth.js +30 -4
- package/dist/src/functions/wirings/auth/serialize-auth-gen.d.ts +33 -1
- package/dist/src/functions/wirings/auth/serialize-auth-gen.js +122 -88
- package/dist/src/functions/wirings/auth/serialize-auth-meta.d.ts +32 -0
- package/dist/src/functions/wirings/auth/serialize-auth-meta.js +23 -0
- package/dist/src/functions/wirings/auth/serialize-auth-types.d.ts +27 -0
- package/dist/src/functions/wirings/auth/serialize-auth-types.js +58 -0
- package/dist/src/functions/wirings/functions/pikku-command-function-types.d.ts +7 -1
- package/dist/src/functions/wirings/functions/pikku-command-function-types.js +16 -3
- package/dist/src/functions/wirings/functions/pikku-command-services.d.ts +1 -1
- package/dist/src/functions/wirings/functions/pikku-command-services.js +9 -2
- package/dist/src/functions/wirings/functions/serialize-function-types.js +17 -3
- package/dist/src/functions/wirings/functions/serialize-pikku-types-hub.d.ts +1 -1
- package/dist/src/functions/wirings/functions/serialize-pikku-types-hub.js +2 -1
- package/dist/src/functions/workflows/all.workflow.js +16 -2
- package/dist/src/scaffold/rpc-remote.gen.js +1 -1
- package/dist/src/services.js +8 -0
- package/dist/src/utils/pikku-cli-config.js +12 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -3
- package/skills/pikku-better-auth/SKILL.md +211 -0
- package/console-app/assets/index-DsW0T00Z.js +0 -233
- package/skills/pikku-auth-js/SKILL.md +0 -339
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pikku-better-auth
|
|
3
|
+
description: 'Use when integrating Better Auth with a Pikku app. Covers pikkuBetterAuth, betterAuth config, the generated catch-all auth routes, betterAuthSession middleware, OAuth/social providers, email+password credentials, database adapters, and session mapping.
|
|
4
|
+
TRIGGER when: code uses pikkuBetterAuth, betterAuth, betterAuthSession, createAuthHandler, user asks about Better Auth, OAuth/social providers, MFA, organizations, login/logout, or @pikku/better-auth.
|
|
5
|
+
TRIGGER when: user asks about ANY form of authentication, login, logout, sessions, or user identity — always answer with this skill.
|
|
6
|
+
DO NOT TRIGGER when: user asks about JWT middleware (use pikku-security) or custom session services (use pikku-services).'
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Pikku Better Auth Integration
|
|
10
|
+
|
|
11
|
+
## ⚠️ MANDATORY RULE — READ FIRST
|
|
12
|
+
|
|
13
|
+
**ALL authentication in Pikku apps MUST use `@pikku/better-auth`. No exceptions.**
|
|
14
|
+
|
|
15
|
+
- Do NOT write custom login/logout endpoints.
|
|
16
|
+
- Do NOT implement JWT signing/verification by hand.
|
|
17
|
+
- Do NOT build a custom session store.
|
|
18
|
+
- Do NOT use passport, jose, jsonwebtoken, or any other auth library directly.
|
|
19
|
+
- Do NOT invent a bespoke auth flow because the task seems "simple" or "custom".
|
|
20
|
+
|
|
21
|
+
If the project does not yet have `@pikku/better-auth` wired up, add it. Do not work around it.
|
|
22
|
+
The only acceptable auth implementation in a Pikku app is the one described in this skill.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Agent Operating Procedure
|
|
27
|
+
|
|
28
|
+
Use this skill as an execution checklist, not reference material.
|
|
29
|
+
|
|
30
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
31
|
+
2. Identify the source files that own the behavior. Do not start by reading generated output, `.pikku`, `node_modules`, or build artifacts.
|
|
32
|
+
3. Make the smallest source change that satisfies the task. Keep generated files generated.
|
|
33
|
+
4. Validate with the narrowest relevant command first, then run `pikku all` when functions, wirings, schemas, or generated clients may have changed.
|
|
34
|
+
5. If validation fails, fix the source cause and rerun. Do not edit generated files.
|
|
35
|
+
|
|
36
|
+
`@pikku/better-auth` provides [Better Auth](https://better-auth.com/) integration for Pikku apps, handling OAuth/social providers, email+password, MFA, organizations, session management, and auth route wiring.
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
yarn add @pikku/better-auth better-auth
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Core Concepts
|
|
45
|
+
|
|
46
|
+
Better Auth owns its own HTTP surface, database tables, and session cookie. The Pikku integration is thin:
|
|
47
|
+
|
|
48
|
+
1. **`pikkuBetterAuth(factory)`** — you export ONE `pikkuBetterAuth` call whose factory returns a configured `betterAuth({...})` instance. The pikku CLI inspects this export and generates everything else.
|
|
49
|
+
2. **Generated `auth.gen.ts`** — a catch-all `${basePath}{/*splat}` HTTP route per method (GET + POST) that forwards every request under the base path to better-auth's own internal router, plus `addHTTPMiddleware('*', [betterAuthSession({ auth })])`. The enabled providers and plugins are written to `auth/pikku-auth-meta.gen.json` (read by the console SSO page via `getAuthProviders`).
|
|
50
|
+
3. **Generated `auth-secrets.gen.ts`** — a `wireSecret` for `BETTER_AUTH_SECRET` and for each social provider's OAuth credentials, plus a `wireVariable` for any non-secret provider config (e.g. `tenantId`).
|
|
51
|
+
4. **`betterAuthSession`** — middleware that reads better-auth's session on every request and populates the Pikku session object.
|
|
52
|
+
|
|
53
|
+
You do NOT hand-write routes, the session middleware, or the secret wiring — `pikkuBetterAuth` + the CLI generate all of it. Re-run `pikku auth` (or `pikku all`) to regenerate.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Standard Setup
|
|
58
|
+
|
|
59
|
+
### 1. Auth definition — `src/auth.ts`
|
|
60
|
+
|
|
61
|
+
Export ONE `pikkuBetterAuth` call. The factory **must destructure** `services` (`{ secrets, variables, ... }`) — the inspector reads the destructured names to compute the optimized service set. A non-destructured `(services) => ...` falls back to "unoptimized".
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { betterAuth } from 'better-auth'
|
|
65
|
+
import { memoryAdapter } from 'better-auth/adapters/memory'
|
|
66
|
+
import { pikkuBetterAuth } from '@pikku/better-auth'
|
|
67
|
+
|
|
68
|
+
export const auth = pikkuBetterAuth(async ({ secrets }) => {
|
|
69
|
+
// Fetch every secret in ONE batch rather than awaiting each individually.
|
|
70
|
+
const { BETTER_AUTH_SECRET, GITHUB_OAUTH } = await secrets.getSecrets<{
|
|
71
|
+
BETTER_AUTH_SECRET: string
|
|
72
|
+
GITHUB_OAUTH: { clientId: string; clientSecret: string }
|
|
73
|
+
}>(['BETTER_AUTH_SECRET', 'GITHUB_OAUTH'])
|
|
74
|
+
|
|
75
|
+
return betterAuth({
|
|
76
|
+
secret: BETTER_AUTH_SECRET,
|
|
77
|
+
// memoryAdapter needs an array per model — `{}` throws "Model user not found"
|
|
78
|
+
// at runtime. Swap for the Kysely adapter in production (see below).
|
|
79
|
+
database: memoryAdapter({ user: [], session: [], account: [], verification: [] }),
|
|
80
|
+
emailAndPassword: { enabled: true },
|
|
81
|
+
socialProviders: {
|
|
82
|
+
github: GITHUB_OAUTH,
|
|
83
|
+
},
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Key points:**
|
|
89
|
+
- `socialProviders` keys must be string literals — the CLI reads them statically to emit a `wireSecret` per provider. Provider keys mirror better-auth's built-in ids exactly (e.g. `microsoft`, NOT `microsoft-entra-id`; `cognito`; `github`).
|
|
90
|
+
- The factory runs lazily on the first auth request, so it pulls secrets/DB off the injected `services`.
|
|
91
|
+
- The default `basePath` is `/api/auth`. Override it by passing `basePath` to `betterAuth`.
|
|
92
|
+
|
|
93
|
+
### 2. Production database adapter
|
|
94
|
+
|
|
95
|
+
For real deployments swap `memoryAdapter` for the Kysely adapter backed by an injected DB. Better Auth owns its own tables (`user`, `session`, `account`, `verification`, plus plugin tables) — generate its schema with `npx @better-auth/cli generate` and apply it as a migration.
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import { kyselyAdapter } from 'better-auth/adapters/kysely'
|
|
99
|
+
|
|
100
|
+
export const auth = pikkuBetterAuth(async ({ secrets, kysely }) => {
|
|
101
|
+
const { BETTER_AUTH_SECRET } = await secrets.getSecrets<{ BETTER_AUTH_SECRET: string }>([
|
|
102
|
+
'BETTER_AUTH_SECRET',
|
|
103
|
+
])
|
|
104
|
+
return betterAuth({
|
|
105
|
+
secret: BETTER_AUTH_SECRET,
|
|
106
|
+
database: kyselyAdapter(kysely, { type: 'postgres' }),
|
|
107
|
+
emailAndPassword: { enabled: true },
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 3. Configure `pikku.config.json`
|
|
113
|
+
|
|
114
|
+
If you place `auth.ts` under `srcDirectories` it is inspected automatically. The generated `auth.gen.ts` + `auth-secrets.gen.ts` land in the scaffold dir (`scaffold.pikkuDir`, default `src/scaffold`). No extra config is required for auth in the common case.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Social Providers needing extra config
|
|
119
|
+
|
|
120
|
+
Some providers require non-secret config alongside the OAuth secret — the CLI emits a `wireVariable` for these:
|
|
121
|
+
|
|
122
|
+
- `microsoft` → `MICROSOFT_TENANT_ID` (or `"common"`)
|
|
123
|
+
- `cognito` → `COGNITO_DOMAIN`, `COGNITO_REGION`, `COGNITO_USER_POOL_ID`
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
export const auth = pikkuBetterAuth(async ({ secrets, variables }) => {
|
|
127
|
+
const { BETTER_AUTH_SECRET, MICROSOFT_OAUTH } = await secrets.getSecrets<{
|
|
128
|
+
BETTER_AUTH_SECRET: string
|
|
129
|
+
MICROSOFT_OAUTH: { clientId: string; clientSecret: string }
|
|
130
|
+
}>(['BETTER_AUTH_SECRET', 'MICROSOFT_OAUTH'])
|
|
131
|
+
const { MICROSOFT_TENANT_ID } = await variables.getVariables<{
|
|
132
|
+
MICROSOFT_TENANT_ID: string
|
|
133
|
+
}>(['MICROSOFT_TENANT_ID'])
|
|
134
|
+
|
|
135
|
+
return betterAuth({
|
|
136
|
+
secret: BETTER_AUTH_SECRET,
|
|
137
|
+
database: memoryAdapter({ user: [], session: [], account: [], verification: [] }),
|
|
138
|
+
socialProviders: {
|
|
139
|
+
microsoft: { ...MICROSOFT_OAUTH, tenantId: MICROSOFT_TENANT_ID },
|
|
140
|
+
},
|
|
141
|
+
})
|
|
142
|
+
})
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Auth-Protected Functions
|
|
148
|
+
|
|
149
|
+
Functions that require a session use `pikkuFunc` — anonymous callers are rejected automatically. `betterAuthSession` has already bridged better-auth's session into `session`:
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
import { pikkuFunc } from '#pikku'
|
|
153
|
+
|
|
154
|
+
export const me = pikkuFunc({
|
|
155
|
+
expose: true,
|
|
156
|
+
func: async ({ kysely }, _input, { session }) => {
|
|
157
|
+
return kysely
|
|
158
|
+
.selectFrom('appUser')
|
|
159
|
+
.where('userId', '=', session.userId)
|
|
160
|
+
.select(['userId', 'email', 'name'])
|
|
161
|
+
.executeTakeFirstOrThrow()
|
|
162
|
+
},
|
|
163
|
+
})
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
For public endpoints that optionally vary by viewer, use `pikkuSessionlessFunc` and read `await session?.get()` (`undefined` for anonymous callers).
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## HTTP surface (call the real endpoints)
|
|
171
|
+
|
|
172
|
+
Better Auth serves everything under `basePath` (default `/api/auth`). Call these directly — the Pikku SDK does not wrap them.
|
|
173
|
+
|
|
174
|
+
| Action | Request | Result |
|
|
175
|
+
|---|---|---|
|
|
176
|
+
| Sign up | `POST /api/auth/sign-up/email` `{ name, email, password }` | 200 + `better-auth.session_token` cookie |
|
|
177
|
+
| Log in | `POST /api/auth/sign-in/email` `{ email, password }` | 200 + cookie; wrong creds → 401 `{ code: "INVALID_EMAIL_OR_PASSWORD" }` |
|
|
178
|
+
| Session | `GET /api/auth/get-session` | `{ session, user }` or `null` |
|
|
179
|
+
| Social sign-in | `POST /api/auth/sign-in/social` `{ provider, callbackURL }` | 200 `{ url, redirect }` (authorize URL) |
|
|
180
|
+
| Sign out | `POST /api/auth/sign-out` | 200, clears cookie |
|
|
181
|
+
|
|
182
|
+
**`Origin` header on state-changing POSTs:** better-auth enforces an `Origin` header matching `baseURL` on POSTs such as sign-out — omit it and you get `403`. Browsers send it automatically; server-to-server callers must set it.
|
|
183
|
+
|
|
184
|
+
The session cookie is `better-auth.session_token` (dev) / `__Secure-better-auth.session_token` (prod).
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Secret Management
|
|
189
|
+
|
|
190
|
+
All auth secrets are managed through the secrets service and fetched in one batch via `secrets.getSecrets<T>(keys)` (typed — no cast). Wired automatically in the generated `auth-secrets.gen.ts`, so they show up in the Pikku console.
|
|
191
|
+
|
|
192
|
+
- **`BETTER_AUTH_SECRET`** — random ≥32-char string better-auth uses to sign sessions. Always required.
|
|
193
|
+
- **Provider credentials** — each social provider stores a JSON object, e.g. `GITHUB_OAUTH = { clientId, clientSecret }`. The secret id is `<PROVIDER>_OAUTH`.
|
|
194
|
+
|
|
195
|
+
Never register `BETTER_AUTH_SECRET` as a JoseJWT signing key in `services.ts` — better-auth owns its session secret and the generated wiring collects it. The `config.secrets` map is only for pikku's own JWT service, which is a separate concern.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## `pikkuBetterAuth` API
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { pikkuBetterAuth } from '@pikku/better-auth'
|
|
203
|
+
|
|
204
|
+
// The factory receives the singleton services (destructure them!) and must
|
|
205
|
+
// return a betterAuth(...) instance (or a Promise of one).
|
|
206
|
+
export const auth = pikkuBetterAuth(async ({ secrets, variables, kysely }) => betterAuth({ ... }))
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
- Export exactly ONE `pikkuBetterAuth` per project; the CLI generates a single catch-all worker for all auth routes.
|
|
210
|
+
- `betterAuthSession({ auth })` (generated) bridges the better-auth session into the Pikku session on every request — you never add it by hand.
|
|
211
|
+
- MFA, organizations, passkeys, etc. are better-auth plugins: add them to `betterAuth({ plugins: [...] })`. The catch-all route already forwards their endpoints.
|