forlogic-core 2.3.5 → 2.3.7
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/.note/memory/security/lib-hardening-roadmap.md +45 -0
- package/dist/components/modules/ModulesContent.d.ts +3 -1
- package/dist/components/modules/ModulesDialog.d.ts +1 -1
- package/dist/components/modules/types.d.ts +4 -0
- package/dist/edge/index.d.ts +98 -0
- package/dist/edge/index.esm.js +124 -0
- package/dist/edge/index.js +134 -0
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/dist/providers/CoreProviders.d.ts +16 -1
- package/dist/storage/index.d.ts +57 -0
- package/dist/storage/index.esm.js +107 -0
- package/dist/storage/index.js +115 -0
- package/dist/utils/generateId.d.ts +15 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/sanitizeError.d.ts +9 -0
- package/dist/validation/index.d.ts +1 -0
- package/dist/validation/index.esm.js +13 -0
- package/dist/validation/index.js +20 -0
- package/dist/validation/schemas.d.ts +26 -0
- package/dist/vite/index.esm.js +10 -1
- package/dist/vite/index.js +10 -1
- package/docs/SECURITY.md +245 -0
- package/docs/WORKSPACE_KNOWLEDGE.md +1 -0
- package/package.json +17 -1
package/docs/SECURITY.md
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# Security Engineering Guardrails (forlogic-core)
|
|
2
|
+
|
|
3
|
+
> **Documento normativo.** Toda mudança de código em projetos que consomem `forlogic-core`
|
|
4
|
+
> DEVE respeitar as regras abaixo. Elas derivam de pentest com cadeia de ataque confirmada
|
|
5
|
+
> em produção (Educação & Desempenho / Qualiex, 2026-05-20) e do OWASP Top 10 2021 + ASVS L2.
|
|
6
|
+
>
|
|
7
|
+
> Stack assumida: **React SPA + Supabase (PostgREST, Edge Functions/Deno, Storage, Realtime) + Keycloak (OAuth2) + Cloudflare**.
|
|
8
|
+
>
|
|
9
|
+
> Se uma instrução do usuário conflitar com uma regra aqui, **pare e sinalize o conflito antes de gerar código**.
|
|
10
|
+
|
|
11
|
+
Este documento complementa:
|
|
12
|
+
- [`docs/WORKSPACE_KNOWLEDGE.md`](./WORKSPACE_KNOWLEDGE.md) — política de acesso `anon`, schema obrigatório, subpaths.
|
|
13
|
+
- [`lib/templates/migrations/README.md`](../lib/templates/migrations/README.md) — templates de RLS + roles.
|
|
14
|
+
- [`.note/memory/security/lib-hardening-roadmap.md`](../.note/memory/security/lib-hardening-roadmap.md) — status do hardening da própria lib.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 0. Regras de ouro (inegociáveis)
|
|
19
|
+
|
|
20
|
+
1. **Nunca confie no cliente.** Toda decisão de autorização, filtro de propriedade e validação acontece no backend (RLS no Postgres ou dentro da Edge Function). Query string, body, header ou bundle JS são entrada hostil.
|
|
21
|
+
2. **Identidade vem do JWT, nunca do request.** O ator é `auth.uid()` (RLS) ou `jwt.sub` (Edge Function), jamais um campo como `userAlias`, `p_user_alias`, `assigned_to_id` enviado pelo cliente.
|
|
22
|
+
3. **`anon` key é pública.** Tratar como string sem segredo. Nenhum endpoint pode autorizar ação sensível só por possuir a `anon` key.
|
|
23
|
+
4. **Default deny.** Toda tabela tem RLS habilitado. Todo bucket é privado. Todo header de segurança presente. Ausência = bug bloqueante.
|
|
24
|
+
5. **Sem segredo no frontend.** Nenhuma `service_role` key, secret de API ou credencial em bundle JS, `VITE_*`/`NEXT_PUBLIC_*` ou URL.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 1. Autenticação e autorização
|
|
29
|
+
|
|
30
|
+
### 1.1 Row Level Security (PostgREST / tabelas)
|
|
31
|
+
|
|
32
|
+
- `ALTER TABLE ... ENABLE ROW LEVEL SECURITY` é **obrigatório** em toda tabela exposta via PostgREST. Tabela nova sem policy = não mergeia.
|
|
33
|
+
- Policies devem comparar a identidade real do JWT, **não** um filtro enviado pelo cliente:
|
|
34
|
+
|
|
35
|
+
```sql
|
|
36
|
+
CREATE POLICY tasks_select ON one_on_one_tasks FOR SELECT
|
|
37
|
+
USING (assigned_to_id = auth.uid()
|
|
38
|
+
OR created_by_id = auth.uid()
|
|
39
|
+
OR is_manager_of(assigned_to_id));
|
|
40
|
+
|
|
41
|
+
CREATE POLICY tasks_update ON one_on_one_tasks FOR UPDATE
|
|
42
|
+
USING (assigned_to_id = auth.uid() OR is_manager_of(assigned_to_id))
|
|
43
|
+
WITH CHECK (assigned_to_id = auth.uid() OR is_manager_of(assigned_to_id));
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- PostgREST ignora `WHERE` do cliente para fins de segurança. Remover `assigned_to_id=eq.X` da URL **nunca** pode ampliar o escopo. A policy é a fronteira, não o filtro.
|
|
47
|
+
- Permissões administrativas: `SELECT` só do próprio registro; `INSERT/UPDATE/DELETE` bloqueados para `anon` e `authenticated`. Conceder permissão é operação privilegiada executada via função `SECURITY DEFINER` chamada por admin já validado — nunca `POST` direto na tabela.
|
|
48
|
+
|
|
49
|
+
> 📦 Use `lib/templates/migrations/01-user-owned-table.sql` e `02-user-roles.sql` como ponto de partida.
|
|
50
|
+
> 🧪 Rode `npm run check:rls` no CI para detectar `CREATE TABLE` sem GRANT/RLS.
|
|
51
|
+
|
|
52
|
+
### 1.2 Campos imutáveis
|
|
53
|
+
|
|
54
|
+
- `created_at`, `created_by`, `completed_at`, `id` são **read-only** após criação.
|
|
55
|
+
- Impor no banco, não na aplicação: `GENERATED ALWAYS`, default + trigger `BEFORE UPDATE` rejeitando alteração, ou coluna fora do `WITH CHECK` editável. PATCH **nunca** pode reescrever histórico temporal.
|
|
56
|
+
|
|
57
|
+
### 1.3 Visibilidade de conteúdo
|
|
58
|
+
|
|
59
|
+
- Listagens filtram status e visibilidade na **policy**, não no front:
|
|
60
|
+
|
|
61
|
+
```sql
|
|
62
|
+
CREATE POLICY contents_read ON education.contents FOR SELECT
|
|
63
|
+
USING ((status = 'active' AND visibility = 'public')
|
|
64
|
+
OR has_enrollment(auth.uid(), id)
|
|
65
|
+
OR is_admin(auth.uid()));
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- `draft`, `archived`, `private` **nunca** retornam para quem não tem matrícula ou papel admin.
|
|
69
|
+
|
|
70
|
+
### 1.4 RPC e contadores
|
|
71
|
+
|
|
72
|
+
- Toda RPC `SECURITY DEFINER` valida: (a) JWT presente, (b) `jwt.sub === p_user_alias`, (c) existência do alvo antes de qualquer `INSERT`.
|
|
73
|
+
- Contadores/enrollments protegidos por `UNIQUE(user_alias, content_id)` para impedir inflação/duplicata. Rejeitar alias inexistente.
|
|
74
|
+
|
|
75
|
+
### 1.5 Soft-delete
|
|
76
|
+
|
|
77
|
+
- **Soft-delete não é controle de acesso.** Registros "deletados" não podem retornar invertendo um filtro. Use tabela de archive com RLS própria, hard-delete, **ou** inclua `deleted_at IS NULL` na própria policy (nunca como filtro do cliente).
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 2. Edge Functions (Deno / Supabase)
|
|
82
|
+
|
|
83
|
+
> 📦 Use os helpers de `forlogic-core/edge`:
|
|
84
|
+
> ```ts
|
|
85
|
+
> import { requireUserJWT, requireOwnership, jsonError, rateLimit, stripTechHeaders } from 'npm:forlogic-core/edge';
|
|
86
|
+
> ```
|
|
87
|
+
|
|
88
|
+
- Toda função que muta estado ou lê PII exige `Authorization: Bearer <jwt>`. Presença apenas de `apikey` (anon) **não autentica**. Padrão obrigatório no topo de cada handler:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
const jwt = await requireUserJWT(req); // 401 se ausente/inválido
|
|
92
|
+
requireOwnership(jwt.sub, body.userAlias); // 403 se não bate
|
|
93
|
+
// ...só então a lógica de negócio
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- `studentName`, `userAlias`, `email` e afins derivam do **JWT/banco**, nunca do body controlado pelo atacante.
|
|
97
|
+
- Erro de parse de JSON → `HTTP 400` com mensagem genérica (`safeJsonParse`). Nunca vazar `stack`, `sb-project-ref`, `x-deno-execution-id`, `x-sb-edge-region`, `x-served-by` (use `stripTechHeaders`).
|
|
98
|
+
- **Rate limit** em funções sensíveis (certificado, conclusão de aula): teto por IP + por usuário (ex. 5 req/min). Registrar auditoria (IP, UA, `sub`, ação).
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 3. Storage e upload de arquivos
|
|
103
|
+
|
|
104
|
+
> 📦 Use `forlogic-core/storage`:
|
|
105
|
+
> ```ts
|
|
106
|
+
> import { validateMagicBytes, sanitizeAndRandomizeFilename, getSignedUrl, SAFE_IMAGE_MIME, SAFE_DOCUMENT_MIME } from 'forlogic-core/storage';
|
|
107
|
+
> ```
|
|
108
|
+
|
|
109
|
+
- Buckets **privados por padrão**. Servir arquivos via **signed URL** com TTL curto (≤ 15 min). Sem bucket `public` com URL previsível.
|
|
110
|
+
- Upload com **allowlist de MIME explícita** + validação de **magic bytes server-side**. Nunca confiar em extensão ou `Content-Type` do cliente.
|
|
111
|
+
- Bloquear `.php`, `.html`, `.svg`, `.js`, binários. Renomear arquivo no servidor com nome aleatório (`sanitizeAndRandomizeFilename`); jamais preservar nome do cliente como path.
|
|
112
|
+
- O par "upload + registro RPC" valida ownership e tipo **em ambas** as requisições.
|
|
113
|
+
|
|
114
|
+
Veja [`docs/STORAGE_BUCKETS.md`](./STORAGE_BUCKETS.md) para inventário e [`lib/storage/index.ts`](../lib/storage/index.ts) para `RECOMMENDED_PRIVATE_BUCKETS`.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 4. Headers HTTP e configuração de borda
|
|
119
|
+
|
|
120
|
+
> 📦 A lib já entrega defaults seguros via `lib/vite/security-headers.ts` (dev) e `lib/vite/csp-policy.ts`. Em produção, replicar na borda (Cloudflare / Nginx).
|
|
121
|
+
|
|
122
|
+
- **CORS:** `Access-Control-Allow-Origin` com allowlist explícita (`https://educacao.sabergestao.com.br`, `https://desempenho.sabergestao.com.br`, etc). **Nunca `*`** em API autenticada. Métodos `TRACE` e `CONNECT` bloqueados.
|
|
123
|
+
- **CSP** obrigatória em todas as páginas:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
Content-Security-Policy: default-src 'self';
|
|
127
|
+
script-src 'self' 'nonce-{random}';
|
|
128
|
+
style-src 'self' 'unsafe-inline' fonts.googleapis.com;
|
|
129
|
+
img-src 'self' data: https:;
|
|
130
|
+
connect-src 'self' *.supabase.co wss://*.supabase.co;
|
|
131
|
+
frame-ancestors 'none'; object-src 'none'; base-uri 'self';
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
- **Clickjacking:** `X-Frame-Options: DENY` + `frame-ancestors 'none'` em todos os domínios.
|
|
135
|
+
- **Cookies:** `SameSite=Strict`/`Lax` salvo necessidade cross-site comprovada. `HttpOnly; Secure` sempre. Evitar `SameSite=None`.
|
|
136
|
+
- Manter: HSTS, `X-Content-Type-Options: nosniff`, `Referrer-Policy`, COOP, CORP.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 5. Sessão, tokens e segredos
|
|
141
|
+
|
|
142
|
+
- **JWT fora do `localStorage`.** Storage baseado em cookie `HttpOnly; Secure; SameSite=Strict`. Token de sessão não pode ser legível por `localStorage.getItem()`. Alternativa mínima: `sessionStorage` com expiração curta + refresh em background.
|
|
143
|
+
- *Status na lib:* breaking change planejado para `v2.0.0` (Bloco 3). Hoje o `TokenManager` ainda usa `localStorage`; opte por `securityMode="strict"` para receber warnings.
|
|
144
|
+
- **API key fora da URL.** Em WebSocket/Realtime, passar via `Sec-WebSocket-Protocol`, nunca em query string (vaza em logs, proxy, CDN, referrer). A lib já remove `apikey=` de qualquer URL no `SupabaseSingleton`.
|
|
145
|
+
- **Segredos só em env do servidor / Supabase secrets.** Nunca em código, nunca em `VITE_*`.
|
|
146
|
+
- Exceção documentada: `VITE_SUPABASE_PK_OVERRIDE` (publishable key, pública por definição).
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 6. Exposição de informação
|
|
151
|
+
|
|
152
|
+
> 📦 Use `import { generateId } from 'forlogic-core'` (UUID v4 via `crypto.randomUUID()`).
|
|
153
|
+
|
|
154
|
+
- **IDs:** UUID v4 ou nanoid. **Proibido** `Date.now()` / timestamp Unix como identificador.
|
|
155
|
+
- **PostgREST:** desabilitar hints de schema em produção (`--no-hint`/env), restringir `db-extra-search-path`. Respostas de erro não revelam nomes de tabela/schema.
|
|
156
|
+
- **Erros genéricos para o cliente**; detalhe técnico só em log interno. A lib já sanitiza via `sanitizeErrorMessage` em `ErrorService`.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 7. Baseline OWASP Top 10 2021 (checklist de aceite)
|
|
161
|
+
|
|
162
|
+
Ordem por incidência neste ecossistema:
|
|
163
|
+
|
|
164
|
+
| # | Item | Foco |
|
|
165
|
+
|---|------|------|
|
|
166
|
+
| **A01** | Broken Access Control | Falha dominante. Autorização no servidor, ownership via JWT, default deny, RLS habilitado. Sem IDOR. |
|
|
167
|
+
| **A02** | Cryptographic Failures | Sem segredo no front; token em cookie seguro; key fora da URL; TLS/HSTS; nada sensível em log. |
|
|
168
|
+
| **A03** | Injection | Queries parametrizadas; nunca concatenar input em SQL ou `filter` PostgREST dinâmico; validar entrada por schema (zod) no servidor; escapar saída. |
|
|
169
|
+
| **A04** | Insecure Design | Modelar abuso, não só caminho feliz. Validar existência, rate limit, idempotência, `UNIQUE`. |
|
|
170
|
+
| **A05** | Security Misconfiguration | CORS restrito, CSP, anti-clickjacking, sem hints de schema, sem headers técnicos, buckets privados, cookies sãos. |
|
|
171
|
+
| **A06** | Vulnerable Components | Fixar versões; `npm audit`/dependabot; remover libs ociosas. |
|
|
172
|
+
| **A07** | Authentication Failures | Exigir JWT válido em endpoint sensível; nunca autenticar por `anon`; validar expiração/assinatura; rate limit em auth. |
|
|
173
|
+
| **A08** | Software & Data Integrity | Campos imutáveis no banco; audit trail protegido; magic bytes em upload. |
|
|
174
|
+
| **A09** | Logging & Monitoring | Logar ações sensíveis (quem, quando, IP, UA) sem vazar PII; sem log silencioso de falha de autorização. |
|
|
175
|
+
| **A10** | SSRF | Fetch server-side com URL derivada de input passa por allowlist; sem requisição a IP interno/metadata. |
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 8. Definition of Done de segurança (checklist de PR)
|
|
180
|
+
|
|
181
|
+
Antes de marcar qualquer tarefa como concluída, confirme cada item **ou justifique a exceção**:
|
|
182
|
+
|
|
183
|
+
- [ ] Toda tabela tocada tem RLS habilitado e policy testada (positivo **e** negativo).
|
|
184
|
+
- [ ] Toda decisão de autorização usa `auth.uid()` / `jwt.sub`, não input do cliente.
|
|
185
|
+
- [ ] Edge Function valida JWT e ownership **antes** da lógica de negócio.
|
|
186
|
+
- [ ] Bucket envolvido é privado; arquivos servidos via signed URL; upload com allowlist de MIME + magic bytes.
|
|
187
|
+
- [ ] Headers de resposta: CORS allowlist, CSP, `X-Frame-Options`/`frame-ancestors`, sem headers técnicos vazados.
|
|
188
|
+
- [ ] Nenhum segredo em código/bundle/URL; token de sessão fora de `localStorage` (ou tracking issue aberta).
|
|
189
|
+
- [ ] IDs são UUID/nanoid; sem timestamp como identificador.
|
|
190
|
+
- [ ] Entradas validadas por schema no servidor; saídas escapadas (XSS).
|
|
191
|
+
- [ ] Campos imutáveis impostos no banco; ação sensível gera log de auditoria.
|
|
192
|
+
- [ ] Caso de abuso (mass exploit, IDOR, escalation) considerado e mitigado.
|
|
193
|
+
- [ ] `npm run check:rls` passa.
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## 9. Rastreabilidade pentest → regra
|
|
198
|
+
|
|
199
|
+
| ID | Achado | Regra que previne |
|
|
200
|
+
|----|--------|-------------------|
|
|
201
|
+
| C1 | `generate-certificate` sem auth | §2 JWT+ownership, §1.1 |
|
|
202
|
+
| C2 | `complete-lesson` sem auth | §2 JWT+ownership |
|
|
203
|
+
| C3 | Bypass painel de Gestão | §1.1 RLS em permissions, default deny |
|
|
204
|
+
| C4 | Upload + bucket público | §3 inteiro |
|
|
205
|
+
| H1 | IDOR `one_on_one_tasks` | §1.1 policies, §0.1 |
|
|
206
|
+
| H2 | Cursos privados/inativos vazados | §1.3 |
|
|
207
|
+
| H3 | Inflação de matrículas | §1.4 |
|
|
208
|
+
| M1 | CORS wildcard | §4 CORS |
|
|
209
|
+
| M2 | CSP ausente | §4 CSP |
|
|
210
|
+
| M3 | JWT em `localStorage` | §5 |
|
|
211
|
+
| M4 | Clickjacking | §4 anti-clickjacking |
|
|
212
|
+
| B1 | Error disclosure | §2 erro genérico, §6 |
|
|
213
|
+
| B2 | `SameSite=None` | §4 cookies |
|
|
214
|
+
| B3 | Timestamp como ID | §6 IDs |
|
|
215
|
+
| B4 | API key na URL | §5 |
|
|
216
|
+
| B5 | Deletadas + campos imutáveis | §1.2, §1.5 |
|
|
217
|
+
| I1 | Schema via error hints | §6 PostgREST |
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## 10. O que a lib (`forlogic-core`) já entrega
|
|
222
|
+
|
|
223
|
+
| Helper / Default | Onde | Cobre |
|
|
224
|
+
|------------------|------|-------|
|
|
225
|
+
| `generateId()` (UUID v4) | `forlogic-core` (barrel) | §6 B3 |
|
|
226
|
+
| `sanitizeErrorMessage` + `ErrorService` | interno | §2 B1, §6 |
|
|
227
|
+
| `SupabaseSingleton` (remove `apikey` da URL, bloqueia `/auth/v1/user`) | interno | §5 B4 |
|
|
228
|
+
| `securityMode="strict"` em `CoreProviders` | opt-in | §0, §2, §5 |
|
|
229
|
+
| Subpath `forlogic-core/edge` (`requireUserJWT`, `requireOwnership`, `rateLimit`, `stripTechHeaders`, `safeJsonParse`, `jsonError`) | `npm:forlogic-core/edge` | §2 |
|
|
230
|
+
| Subpath `forlogic-core/storage` (`validateMagicBytes`, `sanitizeAndRandomizeFilename`, `getSignedUrl`, `SAFE_*_MIME`, `RECOMMENDED_PRIVATE_BUCKETS`) | `forlogic-core/storage` | §3 |
|
|
231
|
+
| Subpath `forlogic-core/validation` (schemas zod compartilhados) | `forlogic-core/validation` | §1.1, A03 |
|
|
232
|
+
| Templates SQL (`01-user-owned-table.sql`, `02-user-roles.sql`) | `lib/templates/migrations/` | §1.1, §1.4 |
|
|
233
|
+
| `scripts/check-rls.ts` + `npm run check:rls` | CI | §1.1 |
|
|
234
|
+
| `lib/vite/security-headers.ts` (COOP/CORP, bloqueio TRACE/CONNECT, `Vary: Origin`, X-Frame DENY) | dev server | §4 |
|
|
235
|
+
|
|
236
|
+
Itens **fora de escopo** da lib (responsabilidade do projeto):
|
|
237
|
+
- RLS de tabelas específicas do produto.
|
|
238
|
+
- Configuração Cloudflare / WAF / rate-limit de borda.
|
|
239
|
+
- Endpoint próprio para emitir cookie `HttpOnly` (necessário para mover JWT do `localStorage`).
|
|
240
|
+
- Hardening do Keycloak.
|
|
241
|
+
- `--no-hint` no PostgREST.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
*Origem: Pentest Educação & Desempenho / Qualiex (ForLogic) · 2026-05-20 · 17 achados confirmados. PTES + OWASP Top 10 2021 + ASVS L2.*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forlogic-core",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -47,6 +47,21 @@
|
|
|
47
47
|
"types": "./dist/places/index.d.ts",
|
|
48
48
|
"import": "./dist/places/index.esm.js",
|
|
49
49
|
"require": "./dist/places/index.js"
|
|
50
|
+
},
|
|
51
|
+
"./edge": {
|
|
52
|
+
"types": "./dist/edge/index.d.ts",
|
|
53
|
+
"import": "./dist/edge/index.esm.js",
|
|
54
|
+
"require": "./dist/edge/index.js"
|
|
55
|
+
},
|
|
56
|
+
"./storage": {
|
|
57
|
+
"types": "./dist/storage/index.d.ts",
|
|
58
|
+
"import": "./dist/storage/index.esm.js",
|
|
59
|
+
"require": "./dist/storage/index.js"
|
|
60
|
+
},
|
|
61
|
+
"./validation": {
|
|
62
|
+
"types": "./dist/validation/index.d.ts",
|
|
63
|
+
"import": "./dist/validation/index.esm.js",
|
|
64
|
+
"require": "./dist/validation/index.js"
|
|
50
65
|
}
|
|
51
66
|
},
|
|
52
67
|
"files": [
|
|
@@ -67,6 +82,7 @@
|
|
|
67
82
|
"docs:check-all": "tsx scripts/check-docs.ts --all",
|
|
68
83
|
"docs:fix": "tsx scripts/auto-doc.ts",
|
|
69
84
|
"docs:fix-all": "tsx scripts/auto-doc.ts --all",
|
|
85
|
+
"check:rls": "tsx scripts/check-rls.ts",
|
|
70
86
|
"preview": "vite preview"
|
|
71
87
|
},
|
|
72
88
|
"dependencies": {
|