caspian-utils 0.1.25 → 0.2.0
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/dist/docs/auth.md +7 -6
- package/dist/docs/commands.md +53 -27
- package/dist/docs/components.md +281 -213
- package/dist/docs/core-runtime-map.md +4 -4
- package/dist/docs/fetch-data.md +19 -1
- package/dist/docs/index.md +2 -0
- package/dist/docs/project-structure.md +62 -62
- package/dist/docs/pulsepoint-runtime-map.md +63 -17
- package/dist/docs/pulsepoint.md +183 -5
- package/dist/docs/routing.md +57 -55
- package/dist/docs/static-export.md +120 -0
- package/package.json +1 -1
package/dist/docs/auth.md
CHANGED
|
@@ -119,7 +119,7 @@ Important behavior from the current implementation:
|
|
|
119
119
|
- `token_auto_refresh` only changes behavior when the request lifecycle calls `auth.refresh_session()`. In the installed `auth.py`, the flag alone does not refresh expiry by itself.
|
|
120
120
|
- The framework `AuthSettings` dataclass defaults `is_all_routes_private=True`, but the project example above explicitly changes that to `False`.
|
|
121
121
|
- In generated app-owned starter config, `src/lib/auth/auth_config.py` starts with `is_all_routes_private=False`, so routes are public by default until the app chooses stricter route protection.
|
|
122
|
-
- `public_routes`, `auth_routes`, `private_routes`, and `role_based_routes` are exact
|
|
122
|
+
- `public_routes`, `auth_routes`, `private_routes`, and `role_based_routes` are matched as route **scopes**, not exact paths, in the installed `Auth` methods. An entry covers the path itself *and* everything nested under it, so `/admin` also matches `/admin/users`. Segment boundaries are respected (`/admin` does not match `/administration`), and dynamic segments work (`/orders/[id]` matches `/orders/42` and below). Root `/` is the one exception: it matches only `/`, so listing it in `public_routes` does not make the whole site public. Verify the exact rule in `_route_scope_matches_request` before relying on an entry to protect or expose a subtree.
|
|
123
123
|
- `private_routes` matters only when `is_all_routes_private=False`.
|
|
124
124
|
- `role_based_routes` currently expects `PATH -> [ROLES]`, not role names keyed to paths the other way around.
|
|
125
125
|
- `role_identifier` defaults to `role`, and the current `auth.sign_in(...)` flow also normalizes `userRole` into `role` when possible.
|
|
@@ -189,7 +189,7 @@ The installed auth code reads several values from `.env` when explicit values ar
|
|
|
189
189
|
- App-owned startup helpers may also validate `AUTH_SECRET` and refuse production startup when the value is missing or still on a default placeholder.
|
|
190
190
|
- `AUTH_COOKIE_NAME` backs `AuthSettings.cookie_name`.
|
|
191
191
|
- `SESSION_LIFETIME_HOURS` controls `SessionMiddleware.max_age` in the current `main.py` bootstrap.
|
|
192
|
-
- `APP_ENV
|
|
192
|
+
- `APP_ENV` selects the environment, resolved **fail-closed** by `casp.runtime_security.is_production_environment()`: only an explicit development value (`dev`, `development`, `local`, `staging`, `test`, `testing`) turns the development relaxations on, so an unset or misspelled value is treated as production. Production enables secure session cookies and the `Secure` flag on the CSRF cookie.
|
|
193
193
|
- `CASPIAN_BROWSER_SYNC_PORT` can override the development cookie scope suffix used by the current `main.py` bootstrap.
|
|
194
194
|
- `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`, and `GOOGLE_REDIRECT_URI` back `GoogleProvider`.
|
|
195
195
|
- `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET` back `GithubProvider`.
|
|
@@ -249,11 +249,11 @@ The current `main.py` also wires the session middleware directly, and some apps
|
|
|
249
249
|
|
|
250
250
|
```python
|
|
251
251
|
from starlette.middleware.sessions import SessionMiddleware
|
|
252
|
-
from casp.runtime_security import get_session_secret
|
|
252
|
+
from casp.runtime_security import get_session_secret, is_production_environment
|
|
253
253
|
|
|
254
254
|
|
|
255
255
|
SESSION_LIFETIME_HOURS = int(os.getenv("SESSION_LIFETIME_HOURS", 7))
|
|
256
|
-
IS_PRODUCTION =
|
|
256
|
+
IS_PRODUCTION = is_production_environment()
|
|
257
257
|
|
|
258
258
|
|
|
259
259
|
app.add_middleware(
|
|
@@ -344,7 +344,7 @@ The current installed methods are:
|
|
|
344
344
|
| `auth.is_authenticated()` | Check current auth state | Returns `False` when the payload is missing, malformed, or expired, and clears invalid session data. |
|
|
345
345
|
| `auth.get_payload()` | Read the signed-in payload | Returns the stored dict payload, or wraps non-dict payloads as `{"value": data}`. |
|
|
346
346
|
| `auth.refresh_session()` | Extend expiration | Only updates expiry when `token_auto_refresh=True`. |
|
|
347
|
-
| `auth.check_role(user, allowed_roles)` | Check RBAC access | Reads the configured role field
|
|
347
|
+
| `auth.check_role(user, allowed_roles)` | Check RBAC access | Reads the configured role field (a single role or a list of them) and grants access on any overlap. |
|
|
348
348
|
|
|
349
349
|
Sign-in example:
|
|
350
350
|
|
|
@@ -715,7 +715,8 @@ In the installed implementation:
|
|
|
715
715
|
|
|
716
716
|
- `auth.check_role(...)` reads `user[role_identifier]` when the payload is a dict.
|
|
717
717
|
- If you pass a plain string instead of a dict, that string is treated as the role directly.
|
|
718
|
-
- `
|
|
718
|
+
- That field may hold a single role or a list/tuple/set of them, so a user who is both `editor` and `auditor` passes a check for either. Access is granted when the user's roles and the allowed roles intersect.
|
|
719
|
+
- `role_based_routes` keys are matched as route *scopes*, not exact paths: `get_required_roles(path)` ranks every matching key by specificity and returns the most specific one. A key therefore also covers nested paths (`/admin` gates `/admin/users`), and dynamic segments such as `/orders/[id]` match. A static key wins over a dynamic one, which wins over a catch-all.
|
|
719
720
|
- The installed payload normalization helps when your Prisma include returns a `userRole` object and you want a plain `role` field in the session payload.
|
|
720
721
|
|
|
721
722
|
## OAuth Providers
|
package/dist/docs/commands.md
CHANGED
|
@@ -10,6 +10,7 @@ related:
|
|
|
10
10
|
- /docs/mcp
|
|
11
11
|
- /docs/file-uploads
|
|
12
12
|
- /docs/routing
|
|
13
|
+
- /docs/static-export
|
|
13
14
|
- /docs/project-structure
|
|
14
15
|
- /docs/index
|
|
15
16
|
---
|
|
@@ -98,29 +99,51 @@ Only use this when the current project's `package.json` actually defines `npm ru
|
|
|
98
99
|
|
|
99
100
|
Do not use `npm run build` as the default validation step for routine route, feature, or documentation edits.
|
|
100
101
|
|
|
102
|
+
### Export the app to static HTML and preview it
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Export to static/ (SSG, like Next.js `output: export`)
|
|
106
|
+
npm run static
|
|
107
|
+
|
|
108
|
+
# Serve the exported static/ folder over HTTP on an auto-selected free port
|
|
109
|
+
npm run static:serve
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Use `npm run static` when the user wants a folder of static HTML for a static host, and `npm run static:serve` to preview that folder locally.
|
|
113
|
+
|
|
114
|
+
This is an **app-owned build convention**, not a shipped Caspian feature and not gated by a `caspian.config.json` flag. Only use these when the current project's `package.json` actually defines them and `settings/build-static.py` (exporter) and `settings/serve-static.py` (preview server) exist.
|
|
115
|
+
|
|
116
|
+
Two things AI must keep correct:
|
|
117
|
+
|
|
118
|
+
- The `static` script must run `npm run build` (Tailwind **and** `projectName`) before `settings/build-static.py`, because the exporter walks the route index in `settings/files-list.json` that `projectName` regenerates. A build that only runs `tailwind:build` can export from a stale route index.
|
|
119
|
+
- `settings/serve-static.py` auto-selects a free port starting at a preferred default (8000) and binds loopback `127.0.0.1` by default; read the port it prints rather than assuming 8000 or reading `settings/bs-config.json` (that file is the dev BrowserSync source of truth, not the static preview).
|
|
120
|
+
|
|
121
|
+
See [static-export.md](./static-export.md) for the full export scope policy, `static_paths` dynamic-route pre-rendering, and the preview-server security and port behavior.
|
|
122
|
+
|
|
101
123
|
### Regenerate ORM after schema changes
|
|
102
124
|
|
|
103
125
|
```bash
|
|
104
126
|
npx prisma migrate dev
|
|
105
127
|
|
|
106
|
-
# If the change requires refreshed seed data:
|
|
107
|
-
npx prisma generate
|
|
108
|
-
# Destructive-data warning: ask the user for explicit approval before running this.
|
|
109
|
-
npx prisma db seed
|
|
110
|
-
|
|
111
|
-
npx ppy generate
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Use when `prisma/schema.prisma` changes and you need migrations, seed flow, and the generated Python ORM layer to stay aligned.
|
|
115
|
-
|
|
116
|
-
`npx prisma db seed` is a delicate operation because the configured seed script may clean tables or replace existing rows before inserting seed data. Before running it, an AI agent must say the exact command it plans to run, warn that it can delete or overwrite database data, confirm the active datasource when practical, and wait for explicit user approval.
|
|
128
|
+
# If the change requires refreshed seed data:
|
|
129
|
+
npx prisma generate
|
|
130
|
+
# Destructive-data warning: ask the user for explicit approval before running this.
|
|
131
|
+
npx prisma db seed
|
|
132
|
+
|
|
133
|
+
npx ppy generate
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Use when `prisma/schema.prisma` changes and you need migrations, seed flow, and the generated Python ORM layer to stay aligned.
|
|
137
|
+
|
|
138
|
+
`npx prisma db seed` is a delicate operation because the configured seed script may clean tables or replace existing rows before inserting seed data. Before running it, an AI agent must say the exact command it plans to run, warn that it can delete or overwrite database data, confirm the active datasource when practical, and wait for explicit user approval.
|
|
117
139
|
|
|
118
140
|
## 2. Script Guardrails
|
|
119
141
|
|
|
120
142
|
- Before using an optional feature, confirm its flag in `caspian.config.json`.
|
|
121
143
|
- If the flag is false and the user wants that feature, ask first, then update `caspian.config.json` and run `npx casp update project` before assuming feature-managed files or scripts exist.
|
|
122
144
|
- Do not run `package.json` scripts by default just because source files changed.
|
|
123
|
-
- Treat `npm run dev` and `npm run
|
|
145
|
+
- Treat `npm run dev`, `npm run build`, `npm run static`, and `npm run static:serve` as opt-in workflows.
|
|
146
|
+
- Use `npm run static` only when the user wants a static HTML export, and `npm run static:serve` only to preview it. Both are app-owned conventions; confirm the scripts and `settings/build-static.py` / `settings/serve-static.py` exist first.
|
|
124
147
|
- Use `npm run dev` only when the user explicitly asks to start the local stack or the task truly needs that running workflow.
|
|
125
148
|
- Use `npm run build` only for deployment prep or an explicit build request.
|
|
126
149
|
- Treat `public/css/styles.css`, `settings/component-map.json`, `settings/files-list.json`, `__pycache__/`, and `.pyc` files as generated outputs when a script intentionally runs.
|
|
@@ -182,12 +205,12 @@ In skip-prompt mode, the default feature values are:
|
|
|
182
205
|
|
|
183
206
|
- `backendOnly: false`
|
|
184
207
|
- `tailwindcss: false`
|
|
185
|
-
- `typescript: false`
|
|
186
|
-
- `mcp: false`
|
|
187
|
-
- `prisma: false`
|
|
188
|
-
- `websocket: false`
|
|
189
|
-
|
|
190
|
-
If a project needs WebSockets after creation, set `websocket: true` in `caspian.config.json`, then run the project update workflow so framework-managed files and any scaffolded socket surfaces stay aligned before assuming `@app.websocket(...)` routes or `src/lib/websocket/**` exist.
|
|
208
|
+
- `typescript: false`
|
|
209
|
+
- `mcp: false`
|
|
210
|
+
- `prisma: false`
|
|
211
|
+
- `websocket: false`
|
|
212
|
+
|
|
213
|
+
If a project needs WebSockets after creation, set `websocket: true` in `caspian.config.json`, then run the project update workflow so framework-managed files and any scaffolded socket surfaces stay aligned before assuming `@app.websocket(...)` routes or `src/lib/websocket/**` exist.
|
|
191
214
|
|
|
192
215
|
### 4.2 Backend-only combinations
|
|
193
216
|
|
|
@@ -598,18 +621,18 @@ The create and update commands above are not the whole maintenance story for a P
|
|
|
598
621
|
```bash
|
|
599
622
|
npx prisma migrate dev
|
|
600
623
|
|
|
601
|
-
# Only when seed flow or prisma/seed.ts depends on the new schema:
|
|
602
|
-
npx prisma generate
|
|
603
|
-
# Destructive-data warning: ask the user for explicit approval before running this.
|
|
604
|
-
npx prisma db seed
|
|
605
|
-
|
|
606
|
-
npx ppy generate
|
|
607
|
-
```
|
|
624
|
+
# Only when seed flow or prisma/seed.ts depends on the new schema:
|
|
625
|
+
npx prisma generate
|
|
626
|
+
# Destructive-data warning: ask the user for explicit approval before running this.
|
|
627
|
+
npx prisma db seed
|
|
628
|
+
|
|
629
|
+
npx ppy generate
|
|
630
|
+
```
|
|
608
631
|
|
|
609
632
|
Use this order:
|
|
610
633
|
|
|
611
634
|
1. Run `npx prisma migrate dev` first so migrations and the development database stay aligned.
|
|
612
|
-
2. If `prisma/seed.ts` or seed data depends on the new schema, run `npx prisma generate`, then request explicit user approval before running `npx prisma db seed` because the seed script may delete or overwrite database data.
|
|
635
|
+
2. If `prisma/seed.ts` or seed data depends on the new schema, run `npx prisma generate`, then request explicit user approval before running `npx prisma db seed` because the seed script may delete or overwrite database data.
|
|
613
636
|
3. Run `npx ppy generate` last so the generated Python ORM layer matches the updated Prisma schema.
|
|
614
637
|
|
|
615
638
|
Do not manually create or edit these generated files:
|
|
@@ -637,6 +660,8 @@ See [database.md](./database.md) for the full schema, migration, seed, and async
|
|
|
637
660
|
| Update current project to beta safely in PowerShell | `npx casp update project --tag beta` |
|
|
638
661
|
| Update current project to an exact version | `npx casp update project --version 1.2.3 -y` |
|
|
639
662
|
| Regenerate Python ORM after schema changes | `npx prisma migrate dev` then optional seed commands, then `npx ppy generate` |
|
|
663
|
+
| Export the app to static HTML (SSG) | `npm run static` (when the project defines it) |
|
|
664
|
+
| Preview the exported static build over HTTP | `npm run static:serve` (auto-selects a free port) |
|
|
640
665
|
|
|
641
666
|
## 10. Configuration Notes
|
|
642
667
|
|
|
@@ -682,8 +707,9 @@ If an AI agent is deciding which command flow to use, apply these rules first.
|
|
|
682
707
|
- Treat `--tailwindcss` and `--typescript` as frontend-oriented flags. They are not meaningful in normal backend-only scaffolds.
|
|
683
708
|
- Treat starter kit defaults as a base layer that can be overridden by explicit flags.
|
|
684
709
|
- Read `caspian.config.json` before running update commands.
|
|
685
|
-
- When `prisma/schema.prisma` changes, run `npx prisma migrate dev` first, then any required seed refresh, then `npx ppy generate`. Before running `npx prisma db seed`, warn the user that it can delete or overwrite data and wait for explicit approval.
|
|
710
|
+
- When `prisma/schema.prisma` changes, run `npx prisma migrate dev` first, then any required seed refresh, then `npx ppy generate`. Before running `npx prisma db seed`, warn the user that it can delete or overwrite data and wait for explicit approval.
|
|
686
711
|
- Never hand-edit generated Python ORM files under `src/lib/prisma/` or `settings/prisma-schema.json`.
|
|
687
712
|
- Read [database.md](./database.md) before generating Prisma schema, migration, seed, or ORM guidance.
|
|
713
|
+
- Read [static-export.md](./static-export.md) before generating or explaining static export (`npm run static`), dynamic-route pre-rendering with `static_paths`, or the `npm run static:serve` preview server. Confirm the scripts and `settings/build-static.py` / `settings/serve-static.py` exist first.
|
|
688
714
|
- Read [routing.md](./routing.md) before generating or modifying route folders under `src/app/`.
|
|
689
715
|
- Read [project-structure.md](./project-structure.md) before placing generated files into the project.
|