@selvajs/platform 0.19.0 → 0.19.1
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @selvajs/platform
|
|
2
2
|
|
|
3
|
-
Pure TypeScript interfaces defining Selva's contract with its backends — no runtime dependency on a specific database, storage, or auth service. Concrete adapters
|
|
3
|
+
Pure TypeScript interfaces defining Selva's contract with its backends — no runtime dependency on a specific database, storage, or auth service. Concrete adapters live in their own packages: `@selvajs/local-provider`, `@selvajs/supabase-provider`, `@selvajs/header-auth-provider`.
|
|
4
4
|
|
|
5
5
|
This README is the contract. Read it before writing an adapter.
|
|
6
6
|
|
|
@@ -22,7 +22,7 @@ This README is the contract. Read it before writing an adapter.
|
|
|
22
22
|
| `IComputeServerStore` | Global + per-org compute-server config. | No — not tenant-scoped. |
|
|
23
23
|
| `IStorageProvider` | Path-based blob storage. Authorization is the caller's responsibility. | No — callers pass already-authorized paths. |
|
|
24
24
|
|
|
25
|
-
`IDataProvider` composes every store, plus optional `auditQuery` / `events` hooks and
|
|
25
|
+
`IDataProvider` composes every store, plus optional `auditQuery` / `events` hooks, an optional `verifySchemaVersion` handshake (for adapters whose schema migrates out-of-band), and the `ensureUser` / `onUserDeleted` lifecycle methods. An adapter typically implements one class per store and aggregates them.
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
@@ -31,7 +31,7 @@ This README is the contract. Read it before writing an adapter.
|
|
|
31
31
|
`RequestContext` carries the caller's identity and active scope. Built once per HTTP request in `hooks.server.ts` from the authenticated session.
|
|
32
32
|
|
|
33
33
|
1. **The query is the security boundary.** Adapters MUST filter reads and writes by `ctx`. An unauthorized caller gets an empty page, `null`, or a `ProviderError` — never someone else's data.
|
|
34
|
-
2. **Never trust a caller's pre-flight check.**
|
|
34
|
+
2. **Never trust a caller's pre-flight check.** The predicates in [`access/rules.ts`](src/access/rules.ts) gate the UI and the route layer. A mutating store method must remain safe even if the caller skipped them.
|
|
35
35
|
3. **Extend `RequestContext`, not method signatures.** Add a field to the interface for new dimensions (e.g. `tenantId`); don't thread it through every call.
|
|
36
36
|
4. **`SYSTEM_CONTEXT` is for trusted server code only.** Bootstrap, scheduled janitors, migrations, test setup. Never derive it from a user session.
|
|
37
37
|
|
|
@@ -39,7 +39,7 @@ This README is the contract. Read it before writing an adapter.
|
|
|
39
39
|
|
|
40
40
|
## Transaction ordering rules
|
|
41
41
|
|
|
42
|
-
Providers are two-phase: a metadata store (`IDataProvider`) and a blob store (`IStorageProvider`) with no shared transaction.
|
|
42
|
+
Providers are two-phase: a metadata store (`IDataProvider`) and a blob store (`IStorageProvider`) with no shared transaction. The definition service in [`@selvajs/server/definitions`](../server/src/definitions/definition-service.ts) composes them with fixed ordering so partial failure is recoverable.
|
|
43
43
|
|
|
44
44
|
**Create — metadata-first, `pending` → `draft`:**
|
|
45
45
|
|
|
@@ -78,7 +78,7 @@ export class MyDefinitionStore implements IDefinitionStore {
|
|
|
78
78
|
}
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
The Selva app normally picks bundled providers from `SELVA_AUTH_PROVIDER` / `SELVA_DATA_PROVIDER` / `SELVA_STORAGE_PROVIDER`. For an adapter that isn't bundled, export a `defineConfig({ auth, data, storage, … })` result from a `.js` file and point `SELVA_CONFIG_PATH` at it — see [config.ts](src/config.ts) for the full `SelvaConfig` shape (tenancy, flags, branding, event/metric sinks, binding resolver).
|
|
82
82
|
|
|
83
83
|
---
|
|
84
84
|
|
|
@@ -96,7 +96,7 @@ runDefinitionStoreConformance({
|
|
|
96
96
|
});
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
A suite exists per store, plus auth, email-link auth, storage, event sink, and solve-metric sink. They cover `ctx` scoping, `pending` filtering, `includePending` opt-in, and `ProviderError` shapes; they do not cover performance or concurrency.
|
|
100
100
|
|
|
101
101
|
---
|
|
102
102
|
|
|
@@ -108,13 +108,13 @@ Throw `ProviderError` for user-facing failures (`new ProviderError('...', 404)`)
|
|
|
108
108
|
|
|
109
109
|
## Data privacy
|
|
110
110
|
|
|
111
|
-
Identity and credentials belong to whichever `IAuthProvider` is configured — for Supabase that's a separate service; for the local provider, Selva itself is the auth provider and holds
|
|
111
|
+
Identity and credentials belong to whichever `IAuthProvider` is configured — for Supabase that's a separate service; for the local provider, Selva itself is the auth provider and holds email addresses and password hashes on disk. This package's own stores hold user IDs, authorization metadata, display names, invite email addresses, and audit payloads. **The operator is the data controller.** See [data privacy](../../docs/self-hosting/concepts/data-privacy.md) for the full inventory and what erasure reaches, plus [providers](../../docs/self-hosting/providers/overview.md) and [security & limits](../../docs/self-hosting/concepts/security-and-limits.md).
|
|
112
112
|
|
|
113
113
|
---
|
|
114
114
|
|
|
115
115
|
## What not to put in this package
|
|
116
116
|
|
|
117
117
|
- No runtime dependencies on databases, ORMs, auth SDKs, or HTTP frameworks.
|
|
118
|
-
- No concrete adapters
|
|
119
|
-
- No service orchestration. Multi-step workflows
|
|
120
|
-
- No HTTP-boundary concerns. Zod request schemas and
|
|
118
|
+
- No concrete adapters — they live in their own packages.
|
|
119
|
+
- No service orchestration. Multi-step workflows composing data + storage live in `@selvajs/server`.
|
|
120
|
+
- No HTTP-boundary concerns. Zod request schemas and route gating belong in the app's handlers.
|
|
@@ -25,7 +25,7 @@ export interface PlatformPermissionStoreConformanceOptions {
|
|
|
25
25
|
/**
|
|
26
26
|
* Optional: disable a user in the adapter's auth backend, in a way the
|
|
27
27
|
* store's enabled-admin invariant queries observe. When present, the
|
|
28
|
-
* disabled-admin exclusion tests run (
|
|
28
|
+
* disabled-admin exclusion tests run (docs/contributing/permissions.md §10 counts only
|
|
29
29
|
* *enabled* instance_admins). Adapters whose permission store can't see
|
|
30
30
|
* disabled state (local — documented boundary) omit it; the tests then
|
|
31
31
|
* show as skipped rather than silently green.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { describe, it, expect } from 'vitest';
|
|
9
9
|
import { SYSTEM_CONTEXT } from '../../context.js';
|
|
10
10
|
import { makeUuid } from './helpers.js';
|
|
11
|
-
// Profile mutations need a ctx scoped to the target user (
|
|
11
|
+
// Profile mutations need a ctx scoped to the target user (docs/contributing/permissions.md §9 +
|
|
12
12
|
// the `IUserProfileStore` JSDoc auth-boundary note). The conformance suite
|
|
13
13
|
// uses SYSTEM_CONTEXT throughout so it doesn't need to mint per-user ctxs;
|
|
14
14
|
// the per-user authorization is exercised in adapter-specific tests.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userProfileStoreSuite.js","sourceRoot":"","sources":["../../../src/testing/suites/userProfileStoreSuite.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAI9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,
|
|
1
|
+
{"version":3,"file":"userProfileStoreSuite.js","sourceRoot":"","sources":["../../../src/testing/suites/userProfileStoreSuite.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@selvajs/platform",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"description": "Pure TypeScript interfaces for Selva platform providers (auth, definitions, compute)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "VektorNode",
|
|
7
|
-
"homepage": "https://
|
|
7
|
+
"homepage": "https://selva.dev",
|
|
8
8
|
"bugs": "https://github.com/VektorNode/selva/issues",
|
|
9
9
|
"keywords": [
|
|
10
10
|
"selva",
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
],
|
|
123
123
|
"dependencies": {
|
|
124
124
|
"zod": "^4.3.6",
|
|
125
|
-
"@selvajs/schemas": "^5.0.
|
|
125
|
+
"@selvajs/schemas": "^5.0.1"
|
|
126
126
|
},
|
|
127
127
|
"peerDependencies": {
|
|
128
128
|
"sharp": "^0.34.0 || ^0.35.0",
|
|
@@ -147,6 +147,8 @@
|
|
|
147
147
|
"dev": "tsc --watch",
|
|
148
148
|
"type-check": "tsc --noEmit",
|
|
149
149
|
"test": "vitest run",
|
|
150
|
-
"test:watch": "vitest"
|
|
150
|
+
"test:watch": "vitest",
|
|
151
|
+
"lint": "eslint .",
|
|
152
|
+
"lint:types": "eslint . --config eslint.typed.config.js"
|
|
151
153
|
}
|
|
152
154
|
}
|