@rebasepro/types 0.22.0 → 0.23.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/controllers/client.d.ts +13 -0
- package/dist/controllers/data_driver.d.ts +10 -0
- package/dist/index.es.js.map +1 -1
- package/dist/types/auth_adapter.d.ts +34 -0
- package/dist/types/backend.d.ts +49 -1
- package/dist/types/cron.d.ts +5 -2
- package/dist/types/database_adapter.d.ts +6 -2
- package/dist/types/postgres_introspection.d.ts +10 -0
- package/dist/types/schema_editing.d.ts +2 -2
- package/dist/types/security_rules.d.ts +28 -1
- package/package.json +2 -2
|
@@ -490,6 +490,40 @@ export interface AuthAdapter {
|
|
|
490
490
|
id: string;
|
|
491
491
|
values: Record<string, unknown>;
|
|
492
492
|
}, clearPassword?: string): Promise<UserCreationFinalizeResult>;
|
|
493
|
+
/**
|
|
494
|
+
* Check, and put in stored form, updates to rows of the auth collection
|
|
495
|
+
* that arrive through the data API — `PATCH /<users>/:id`, `PATCH /bulk`,
|
|
496
|
+
* `_batch`, the realtime socket.
|
|
497
|
+
*
|
|
498
|
+
* Those rows are the users, so an update to one is user administration,
|
|
499
|
+
* and has to hold to what the admin user routes hold to: no update that
|
|
500
|
+
* leaves the project without an administrator, and an email stored the
|
|
501
|
+
* way sign-in looks it up. Throws to refuse; the updates are judged
|
|
502
|
+
* together, so a bulk demotion of every admin is refused even though each
|
|
503
|
+
* row alone would pass.
|
|
504
|
+
*
|
|
505
|
+
* If not implemented, the values are written as they arrived.
|
|
506
|
+
*
|
|
507
|
+
* @returns Each update's values, as they should be written, in order.
|
|
508
|
+
*/
|
|
509
|
+
prepareUserUpdates?(updates: ReadonlyArray<{
|
|
510
|
+
uid: string;
|
|
511
|
+
values: Record<string, unknown>;
|
|
512
|
+
}>): Promise<Record<string, unknown>[]>;
|
|
513
|
+
/**
|
|
514
|
+
* Check a deletion of these users through the data API before any row goes,
|
|
515
|
+
* and run the hooks that may veto it (`beforeUserDelete`). Throws to
|
|
516
|
+
* refuse — for one that would leave the project without an administrator,
|
|
517
|
+
* among others.
|
|
518
|
+
*
|
|
519
|
+
* If not implemented, the rows are deleted as any other.
|
|
520
|
+
*/
|
|
521
|
+
prepareUserDeletions?(uids: readonly string[]): Promise<void>;
|
|
522
|
+
/**
|
|
523
|
+
* After those users' rows are deleted through the data API: end their
|
|
524
|
+
* sessions and run the after-delete hooks (`afterUserDelete`).
|
|
525
|
+
*/
|
|
526
|
+
finalizeUserDeletions?(uids: readonly string[]): Promise<void>;
|
|
493
527
|
/**
|
|
494
528
|
* A static secret key for server-to-server / script authentication.
|
|
495
529
|
*
|
package/dist/types/backend.d.ts
CHANGED
|
@@ -350,11 +350,18 @@ export interface DataTransformer {
|
|
|
350
350
|
export interface SQLAdmin {
|
|
351
351
|
/**
|
|
352
352
|
* Execute raw SQL against the database.
|
|
353
|
+
*
|
|
354
|
+
* `isolateSession` runs it on a connection of its own and resets that
|
|
355
|
+
* connection's session state — role, session authorization, settings —
|
|
356
|
+
* before it is reused. For SQL a person wrote (the Studio editor), which
|
|
357
|
+
* may `SET ROLE` and must not leave that on a pooled connection the
|
|
358
|
+
* server's own queries use next.
|
|
353
359
|
*/
|
|
354
360
|
executeSql(sql: string, options?: {
|
|
355
361
|
database?: string;
|
|
356
362
|
role?: string;
|
|
357
363
|
params?: unknown[];
|
|
364
|
+
isolateSession?: boolean;
|
|
358
365
|
}): Promise<Record<string, unknown>[]>;
|
|
359
366
|
/**
|
|
360
367
|
* Fetch the available databases on the server.
|
|
@@ -579,6 +586,47 @@ export interface BackendInstance extends BackendLifecycle {
|
|
|
579
586
|
* Factory function type for creating backend instances
|
|
580
587
|
*/
|
|
581
588
|
export type BackendFactory<TConfig extends BackendConfig = BackendConfig> = (config: TConfig) => BackendInstance;
|
|
589
|
+
/**
|
|
590
|
+
* A caller of the data API as its rate limiter buckets one outside an HTTP
|
|
591
|
+
* request: a realtime socket's frame, counted in the same bucket the same
|
|
592
|
+
* person's HTTP requests are.
|
|
593
|
+
* @group Backend
|
|
594
|
+
*/
|
|
595
|
+
export interface DataRateLimitCaller {
|
|
596
|
+
/**
|
|
597
|
+
* The signed-in user's uid. Absent, or the anonymous principal, buckets
|
|
598
|
+
* the caller by address at the anonymous allowance.
|
|
599
|
+
*/
|
|
600
|
+
uid?: string;
|
|
601
|
+
/**
|
|
602
|
+
* A header of the request that opened the connection, by lower-case name:
|
|
603
|
+
* the proxy headers an address is read from when proxies are declared.
|
|
604
|
+
*/
|
|
605
|
+
header(name: string): string | undefined;
|
|
606
|
+
/** The address the connection comes from. */
|
|
607
|
+
socketAddress?: string;
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* The data API's request limits, handed to the realtime socket so its frames
|
|
611
|
+
* carry the ones an HTTP request to the same rows does.
|
|
612
|
+
* @group Backend
|
|
613
|
+
*/
|
|
614
|
+
export interface RealtimeSocketLimits {
|
|
615
|
+
/**
|
|
616
|
+
* The largest frame accepted, in bytes — the data API's body limit. `0` or
|
|
617
|
+
* less for none. Defaults to the server's default body limit.
|
|
618
|
+
*/
|
|
619
|
+
maxPayload?: number;
|
|
620
|
+
/**
|
|
621
|
+
* Count one data request from `caller` in the data API's per-caller
|
|
622
|
+
* buckets and say whether it is allowed; `null` for a caller who is not
|
|
623
|
+
* limited. Absent when the deployment has rate limiting off.
|
|
624
|
+
*/
|
|
625
|
+
dataRateLimit?: (caller: DataRateLimitCaller) => Promise<{
|
|
626
|
+
allowed: boolean;
|
|
627
|
+
retryAfterMs: number;
|
|
628
|
+
} | null>;
|
|
629
|
+
}
|
|
582
630
|
/**
|
|
583
631
|
* A `BackendBootstrapper` encapsulates all driver-specific initialization logic.
|
|
584
632
|
*
|
|
@@ -784,7 +832,7 @@ export interface BackendBootstrapper {
|
|
|
784
832
|
/**
|
|
785
833
|
* Initialize WebSocket server for realtime operations.
|
|
786
834
|
*/
|
|
787
|
-
initializeWebsockets?(server: unknown, realtimeService: RealtimeProvider, driver: import("../controllers/data_driver.js").DataDriver, config?: unknown, authAdapter?: AuthAdapter): Promise<void> | void;
|
|
835
|
+
initializeWebsockets?(server: unknown, realtimeService: RealtimeProvider, driver: import("../controllers/data_driver.js").DataDriver, config?: unknown, authAdapter?: AuthAdapter, limits?: RealtimeSocketLimits): Promise<void> | void;
|
|
788
836
|
}
|
|
789
837
|
/**
|
|
790
838
|
* Result of `BackendBootstrapper.initializeDriver()`.
|
package/dist/types/cron.d.ts
CHANGED
|
@@ -43,7 +43,9 @@ export interface CronJobDefinition {
|
|
|
43
43
|
enabled?: boolean;
|
|
44
44
|
/**
|
|
45
45
|
* Maximum number of seconds the handler may run before being
|
|
46
|
-
* considered timed-out. Default: 300 (5 min).
|
|
46
|
+
* considered timed-out. Default: 300 (5 min). `Infinity` means no
|
|
47
|
+
* timeout. Zero, a negative number or `NaN` is refused when the job
|
|
48
|
+
* loads, and the job is listed as rejected.
|
|
47
49
|
*/
|
|
48
50
|
timeoutSeconds?: number;
|
|
49
51
|
/**
|
|
@@ -95,7 +97,8 @@ export interface CronJobContext {
|
|
|
95
97
|
/** A simple logger scoped to this job run. */
|
|
96
98
|
log: (...args: unknown[]) => void;
|
|
97
99
|
/**
|
|
98
|
-
* Aborted when the run exceeds `timeoutSeconds
|
|
100
|
+
* Aborted when the run exceeds `timeoutSeconds`, or when the server
|
|
101
|
+
* shuts down and the run has not finished within the shutdown's wait.
|
|
99
102
|
*
|
|
100
103
|
* The timeout has always stopped the scheduler *waiting* — it loses the
|
|
101
104
|
* race and the run is recorded as failed. It has never stopped the handler:
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import type { DataDriver } from "../controllers/data_driver.js";
|
|
23
23
|
import type { CollectionConfig } from "./collections.js";
|
|
24
|
-
import type { CollectionRegistryInterface, DatabaseAdmin, InitializedDriver, RealtimeProvider, BootstrappedAuth } from "./backend.js";
|
|
24
|
+
import type { CollectionRegistryInterface, DatabaseAdmin, InitializedDriver, RealtimeProvider, RealtimeSocketLimits, BootstrappedAuth } from "./backend.js";
|
|
25
25
|
import type { HistoryConfig } from "../controllers/client.js";
|
|
26
26
|
/**
|
|
27
27
|
* A `DatabaseAdapter` provides data persistence for Rebase.
|
|
@@ -73,8 +73,12 @@ export interface DatabaseAdapter {
|
|
|
73
73
|
* already passed it, so it was dropped at every adapter that routed through
|
|
74
74
|
* here — turning an adapter-authenticated server's socket into one that
|
|
75
75
|
* accepted every client as already authenticated.
|
|
76
|
+
*
|
|
77
|
+
* `limits` are the data API's body and per-caller rate limits, for the
|
|
78
|
+
* socket's frames: it serves the same rows, and without them a frame had
|
|
79
|
+
* neither. Forwarded for the same reason `adapter` is.
|
|
76
80
|
*/
|
|
77
|
-
initializeWebsockets?(server: unknown, realtimeService: RealtimeProvider, driver: DataDriver, config?: unknown, adapter?: import("./auth_adapter.js").AuthAdapter): Promise<void> | void;
|
|
81
|
+
initializeWebsockets?(server: unknown, realtimeService: RealtimeProvider, driver: DataDriver, config?: unknown, adapter?: import("./auth_adapter.js").AuthAdapter, limits?: RealtimeSocketLimits): Promise<void> | void;
|
|
78
82
|
/**
|
|
79
83
|
* Ask the database whether it is there, before boot's first real query. See
|
|
80
84
|
* `BackendBootstrapper.verifyConnection` for the contract.
|
|
@@ -56,8 +56,18 @@ export interface TableJunctionInfo {
|
|
|
56
56
|
*/
|
|
57
57
|
export interface TablePolicyInfo {
|
|
58
58
|
policy_name: string;
|
|
59
|
+
/**
|
|
60
|
+
* The policy's `TO` list — *database* roles, `public` for every
|
|
61
|
+
* connection — as `pg_policies.roles` reports it.
|
|
62
|
+
*/
|
|
59
63
|
roles: string[];
|
|
64
|
+
/** `SELECT`, `INSERT`, `UPDATE`, `DELETE` or `ALL`, as `pg_policies.cmd` reports it. */
|
|
60
65
|
cmd: string;
|
|
66
|
+
/**
|
|
67
|
+
* `pg_policies.permissive`. Absent means `PERMISSIVE`, Postgres's own
|
|
68
|
+
* default.
|
|
69
|
+
*/
|
|
70
|
+
permissive?: "PERMISSIVE" | "RESTRICTIVE";
|
|
61
71
|
qual?: string;
|
|
62
72
|
with_check?: string;
|
|
63
73
|
}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* changing a type, moving a primary key.
|
|
25
25
|
*/
|
|
26
26
|
export type SchemaChangeVerdict = "safe" | "diverges" | "needs-migration";
|
|
27
|
-
export type SchemaChangeKind = "add-collection" | "remove-collection" | "add-property" | "remove-property" | "change-property-type" | "rename-column" | "add-enum-value" | "remove-enum-value" | "change-required" | "change-primary-key";
|
|
27
|
+
export type SchemaChangeKind = "add-collection" | "remove-collection" | "add-property" | "remove-property" | "change-property-type" | "rename-column" | "add-enum-value" | "remove-enum-value" | "change-required" | "change-primary-key" | "rename-table";
|
|
28
28
|
export interface SchemaChange {
|
|
29
29
|
kind: SchemaChangeKind;
|
|
30
30
|
verdict: SchemaChangeVerdict;
|
|
@@ -106,7 +106,7 @@ export interface SchemaChangePlan {
|
|
|
106
106
|
export interface WithheldSchemaConstraint {
|
|
107
107
|
/** `schema.table.column`. */
|
|
108
108
|
target: string;
|
|
109
|
-
kind: "not-null";
|
|
109
|
+
kind: "not-null" | "unique";
|
|
110
110
|
/** What is in the way, naming the obstacle rather than the rule. */
|
|
111
111
|
reason: string;
|
|
112
112
|
/** What would make it applicable. */
|
|
@@ -53,7 +53,7 @@ export type SecurityOperation = "select" | "insert" | "update" | "delete" | "all
|
|
|
53
53
|
*
|
|
54
54
|
* @group Models
|
|
55
55
|
*/
|
|
56
|
-
export type SecurityRule = OwnerSecurityRule | PublicSecurityRule | StructuredSecurityRule | RawSQLSecurityRule | RolesOnlySecurityRule;
|
|
56
|
+
export type SecurityRule = OwnerSecurityRule | PublicSecurityRule | StructuredSecurityRule | RawSQLSecurityRule | RawSQLCheckOnlySecurityRule | RolesOnlySecurityRule;
|
|
57
57
|
/**
|
|
58
58
|
* Shared fields for all SecurityRule variants.
|
|
59
59
|
* @group Models
|
|
@@ -297,6 +297,33 @@ export interface RawSQLSecurityRule extends SecurityRuleBase {
|
|
|
297
297
|
condition?: never;
|
|
298
298
|
check?: never;
|
|
299
299
|
}
|
|
300
|
+
/**
|
|
301
|
+
* Security rule with a raw SQL `WITH CHECK` clause and no `USING` clause — the
|
|
302
|
+
* shape of every INSERT policy, which checks the row being written and has no
|
|
303
|
+
* existing row to filter.
|
|
304
|
+
*
|
|
305
|
+
* On an operation that takes a `USING` clause, the missing one grants no rows,
|
|
306
|
+
* as a Postgres policy without one does.
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* // Anyone may insert a row they own
|
|
310
|
+
* { operation: "insert", withCheck: "{owner_id} = rebase.uid()" }
|
|
311
|
+
*
|
|
312
|
+
* @group Models
|
|
313
|
+
*/
|
|
314
|
+
export interface RawSQLCheckOnlySecurityRule extends SecurityRuleBase {
|
|
315
|
+
/**
|
|
316
|
+
* Raw SQL expression for the `WITH CHECK` clause.
|
|
317
|
+
* This controls which *new/updated* row values are allowed.
|
|
318
|
+
* Applied to INSERT and UPDATE.
|
|
319
|
+
*/
|
|
320
|
+
withCheck: string;
|
|
321
|
+
using?: never;
|
|
322
|
+
ownerField?: never;
|
|
323
|
+
access?: never;
|
|
324
|
+
condition?: never;
|
|
325
|
+
check?: never;
|
|
326
|
+
}
|
|
300
327
|
/**
|
|
301
328
|
* Security rule that only filters by application roles, without any
|
|
302
329
|
* row-level condition (USING/WITH CHECK).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebasepro/types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Rebase type definitions — shared interfaces and controller types",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rebase",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@types/node": "^26.1.2",
|
|
47
47
|
"@types/object-hash": "^3.0.6",
|
|
48
48
|
"@types/react-measure": "^2.0.12",
|
|
49
|
-
"hono": "^4.13.
|
|
49
|
+
"hono": "^4.13.5",
|
|
50
50
|
"jest": "^30.4.2",
|
|
51
51
|
"ts-jest": "^29.4.12",
|
|
52
52
|
"typescript": "^6.0.3",
|