@rebasepro/types 0.8.0 → 0.9.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/README.md +10 -10
- package/dist/controllers/auth.d.ts +1 -1
- package/dist/controllers/client.d.ts +184 -6
- package/dist/controllers/collection_registry.d.ts +3 -3
- package/dist/controllers/customization_controller.d.ts +1 -1
- package/dist/controllers/data.d.ts +267 -35
- package/dist/controllers/data_driver.d.ts +50 -37
- package/dist/controllers/index.d.ts +1 -1
- package/dist/controllers/local_config_persistence.d.ts +4 -4
- package/dist/controllers/navigation.d.ts +2 -2
- package/dist/controllers/registry.d.ts +17 -4
- package/dist/controllers/{side_entity_controller.d.ts → side_panel_controller.d.ts} +7 -7
- package/dist/controllers/storage.d.ts +39 -0
- package/dist/errors.d.ts +64 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +142 -15
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +150 -17
- package/dist/index.umd.js.map +1 -1
- package/dist/rebase_context.d.ts +8 -4
- package/dist/types/auth_adapter.d.ts +4 -1
- package/dist/types/backend.d.ts +26 -26
- package/dist/types/builders.d.ts +2 -2
- package/dist/types/collections.d.ts +62 -63
- package/dist/types/component_overrides.d.ts +61 -3
- package/dist/types/cron.d.ts +10 -1
- package/dist/types/data_source.d.ts +15 -2
- package/dist/types/database_adapter.d.ts +4 -3
- package/dist/types/entities.d.ts +7 -7
- package/dist/types/entity_actions.d.ts +7 -7
- package/dist/types/entity_callbacks.d.ts +39 -39
- package/dist/types/entity_views.d.ts +3 -3
- package/dist/types/filter-operators.d.ts +62 -17
- package/dist/types/modify_collections.d.ts +2 -2
- package/dist/types/plugins.d.ts +9 -9
- package/dist/types/policy.d.ts +64 -10
- package/dist/types/properties.d.ts +41 -9
- package/dist/types/relations.d.ts +3 -3
- package/dist/types/slots.d.ts +14 -14
- package/dist/types/websockets.d.ts +12 -13
- package/dist/users/user.d.ts +21 -9
- package/package.json +1 -1
- package/src/controllers/auth.tsx +1 -1
- package/src/controllers/client.ts +214 -6
- package/src/controllers/collection_registry.ts +3 -3
- package/src/controllers/customization_controller.tsx +1 -1
- package/src/controllers/data.ts +290 -39
- package/src/controllers/data_driver.ts +49 -40
- package/src/controllers/index.ts +1 -1
- package/src/controllers/local_config_persistence.tsx +4 -4
- package/src/controllers/navigation.ts +2 -2
- package/src/controllers/registry.ts +18 -4
- package/src/controllers/{side_entity_controller.tsx → side_panel_controller.tsx} +7 -7
- package/src/controllers/storage.ts +60 -1
- package/src/errors.ts +80 -0
- package/src/index.ts +1 -0
- package/src/rebase_context.tsx +8 -4
- package/src/types/auth_adapter.ts +4 -1
- package/src/types/backend.ts +36 -36
- package/src/types/builders.ts +2 -2
- package/src/types/collections.ts +78 -79
- package/src/types/component_overrides.ts +72 -5
- package/src/types/cron.ts +10 -1
- package/src/types/data_source.ts +24 -2
- package/src/types/database_adapter.ts +4 -3
- package/src/types/entities.ts +7 -7
- package/src/types/entity_actions.tsx +7 -7
- package/src/types/entity_callbacks.ts +42 -42
- package/src/types/entity_views.tsx +3 -3
- package/src/types/filter-operators.ts +96 -23
- package/src/types/modify_collections.tsx +2 -2
- package/src/types/plugins.tsx +9 -9
- package/src/types/policy.ts +64 -8
- package/src/types/properties.ts +44 -9
- package/src/types/relations.ts +3 -3
- package/src/types/slots.tsx +14 -14
- package/src/types/websockets.ts +12 -14
- package/src/users/user.ts +22 -9
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { EntityReference } from "../types/entities";
|
|
3
|
-
import type {
|
|
3
|
+
import type { CollectionConfig } from "../types/collections";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -248,7 +248,7 @@ export interface NavigationEntry {
|
|
|
248
248
|
name: string;
|
|
249
249
|
slug: string;
|
|
250
250
|
type: "collection" | "view" | "admin";
|
|
251
|
-
collection?:
|
|
251
|
+
collection?: CollectionConfig;
|
|
252
252
|
view?: AppView;
|
|
253
253
|
description?: string;
|
|
254
254
|
group: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { CollectionConfig } from "../types/collections";
|
|
3
|
+
import type { CollectionConfigsBuilder, AppViewsBuilder } from "../types/builders";
|
|
4
4
|
import type { EntityCustomView } from "../types/entity_views";
|
|
5
5
|
import type { EntityAction } from "../types/entity_actions";
|
|
6
6
|
import type { AppView, NavigationGroupMapping } from "./navigation";
|
|
@@ -21,8 +21,8 @@ export interface CollectionEditorOptions {
|
|
|
21
21
|
pathSuggestions?: string[];
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export interface RebaseCMSConfig<EC extends
|
|
25
|
-
collections?: EC[] |
|
|
24
|
+
export interface RebaseCMSConfig<EC extends CollectionConfig = CollectionConfig> {
|
|
25
|
+
collections?: EC[] | CollectionConfigsBuilder<EC>;
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Custom top-level views added to the main navigation.
|
|
@@ -51,6 +51,20 @@ export interface RebaseCMSConfig<EC extends EntityCollection = EntityCollection>
|
|
|
51
51
|
* are all auto-wired — no plugin or manual view injection needed.
|
|
52
52
|
*/
|
|
53
53
|
collectionEditor?: boolean | CollectionEditorOptions;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* URL path prefix the admin is mounted under, when it does not live at the
|
|
57
|
+
* site root. Set this when the admin is rendered inside a path-prefixed
|
|
58
|
+
* route (e.g. `<Route path="/admin/*">`) so URL⇄collection resolution
|
|
59
|
+
* accounts for the prefix — otherwise the current path won't be recognized
|
|
60
|
+
* as a collection path and views hang on a spinner with no data fetch.
|
|
61
|
+
*
|
|
62
|
+
* Do NOT set this when mounting via a react-router `basename` — react-router
|
|
63
|
+
* already strips the prefix from the location, so the default (`/`) is correct.
|
|
64
|
+
*
|
|
65
|
+
* @default "/"
|
|
66
|
+
*/
|
|
67
|
+
basePath?: string;
|
|
54
68
|
}
|
|
55
69
|
|
|
56
70
|
export interface RebaseStudioConfig {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Entity } from "../types/entities";
|
|
2
|
-
import type {
|
|
2
|
+
import type { CollectionConfig } from "../types/collections";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Props used to open a side dialog
|
|
6
6
|
* @group Hooks and utilities
|
|
7
7
|
*/
|
|
8
|
-
export interface
|
|
8
|
+
export interface SidePanelBindingProps<M extends Record<string, unknown> = Record<string, unknown>> {
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Absolute path of the entity
|
|
@@ -38,7 +38,7 @@ export interface EntitySidePanelProps<M extends Record<string, unknown> = Record
|
|
|
38
38
|
* Collection representing the entities of this view.
|
|
39
39
|
* If you leave it blank it will be induced by your navigation
|
|
40
40
|
*/
|
|
41
|
-
collection?:
|
|
41
|
+
collection?: CollectionConfig<M>;
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Should update the URL when opening the dialog.
|
|
@@ -87,7 +87,7 @@ export interface EntitySidePanelProps<M extends Record<string, unknown> = Record
|
|
|
87
87
|
* Controller to open the side dialog displaying entity forms
|
|
88
88
|
* @group Hooks and utilities
|
|
89
89
|
*/
|
|
90
|
-
export interface
|
|
90
|
+
export interface SidePanelController {
|
|
91
91
|
/**
|
|
92
92
|
* Close the last panel
|
|
93
93
|
*/
|
|
@@ -98,15 +98,15 @@ export interface SideEntityController {
|
|
|
98
98
|
* of the view is fetched from the collections you have specified in the
|
|
99
99
|
* navigation.
|
|
100
100
|
* At least you need to pass the path of the entity you would like
|
|
101
|
-
* to edit. You can set
|
|
101
|
+
* to edit. You can set a entityId if you would like to edit and existing one
|
|
102
102
|
* (or a new one with that id).
|
|
103
103
|
* @param props
|
|
104
104
|
*/
|
|
105
|
-
open: <M extends Record<string, unknown> = Record<string, unknown>>(props:
|
|
105
|
+
open: <M extends Record<string, unknown> = Record<string, unknown>>(props: SidePanelBindingProps<M>) => void;
|
|
106
106
|
|
|
107
107
|
/**
|
|
108
108
|
* Replace the last open entity panel with the given one.
|
|
109
109
|
* @param props
|
|
110
110
|
*/
|
|
111
|
-
replace: <M extends Record<string, unknown> = Record<string, unknown>>(props:
|
|
111
|
+
replace: <M extends Record<string, unknown> = Record<string, unknown>>(props: SidePanelBindingProps<M>) => void;
|
|
112
112
|
}
|
|
@@ -1,3 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path prefix that marks an object as **public**. Files stored under this
|
|
3
|
+
* prefix are served without any auth token via a stable, permanent,
|
|
4
|
+
* CDN-cacheable URL (see {@link StorageSource.getSignedUrl}). Shared by the
|
|
5
|
+
* client SDK and the backend so both agree on which objects are public.
|
|
6
|
+
*
|
|
7
|
+
* @group Models
|
|
8
|
+
*/
|
|
9
|
+
export const PUBLIC_STORAGE_PREFIX = "public/";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* True when a storage key/path points at a public object (lives under
|
|
13
|
+
* {@link PUBLIC_STORAGE_PREFIX}). The check is applied to the key *within the
|
|
14
|
+
* bucket* — strip any `bucket/` and `scheme://` prefixes first.
|
|
15
|
+
*
|
|
16
|
+
* @group Models
|
|
17
|
+
*/
|
|
18
|
+
export function isPublicStoragePath(path: string | null | undefined): boolean {
|
|
19
|
+
if (!path) return false;
|
|
20
|
+
let p = path;
|
|
21
|
+
const scheme = p.indexOf("://");
|
|
22
|
+
if (scheme !== -1) p = p.substring(scheme + 3);
|
|
23
|
+
p = p.replace(/^\/+/, "");
|
|
24
|
+
|
|
25
|
+
// Defense-in-depth: a path containing traversal segments is never public,
|
|
26
|
+
// so an attacker can't reach a private object via `public/../secret`.
|
|
27
|
+
if (p.split("/").some((seg) => seg === "..")) return false;
|
|
28
|
+
|
|
29
|
+
// Public iff the object **key** starts with the public prefix. A single
|
|
30
|
+
// leading `default/` bucket segment is tolerated (the default bucket).
|
|
31
|
+
// A substring match is deliberately NOT used — a private object under a
|
|
32
|
+
// folder literally named `public` (e.g. `reports/public/q3.pdf`) must stay
|
|
33
|
+
// private. Named buckets: pass the key (not `bucket/key`) so the prefix is
|
|
34
|
+
// anchored; otherwise it falls back to a private, token-scoped URL (safe).
|
|
35
|
+
return p.startsWith(PUBLIC_STORAGE_PREFIX) || p.startsWith(`default/${PUBLIC_STORAGE_PREFIX}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
1
38
|
/**
|
|
2
39
|
* @group Models
|
|
3
40
|
*/
|
|
@@ -5,7 +42,14 @@ export interface UploadFileProps {
|
|
|
5
42
|
file: File,
|
|
6
43
|
key: string,
|
|
7
44
|
metadata?: Record<string, unknown>,
|
|
8
|
-
bucket?: string
|
|
45
|
+
bucket?: string,
|
|
46
|
+
/**
|
|
47
|
+
* Store this object as **public**: it is placed under
|
|
48
|
+
* {@link PUBLIC_STORAGE_PREFIX} and served via a stable, token-less,
|
|
49
|
+
* permanent URL (safe to persist in a database and cache on a CDN).
|
|
50
|
+
* Defaults to `false` (private, short-lived signed URLs).
|
|
51
|
+
*/
|
|
52
|
+
public?: boolean
|
|
9
53
|
}
|
|
10
54
|
|
|
11
55
|
/**
|
|
@@ -74,6 +118,21 @@ export declare interface DownloadMetadata {
|
|
|
74
118
|
contentType: string;
|
|
75
119
|
|
|
76
120
|
customMetadata: Record<string, unknown>;
|
|
121
|
+
/**
|
|
122
|
+
* Optional short-lived download token (for local/server-mediated storage).
|
|
123
|
+
* Absent for public objects, which need no token.
|
|
124
|
+
*/
|
|
125
|
+
token?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Optional remaining lifetime of the token, in seconds.
|
|
128
|
+
*/
|
|
129
|
+
tokenExpiresIn?: number;
|
|
130
|
+
/**
|
|
131
|
+
* True when this object is public: it is served without a token via a
|
|
132
|
+
* stable, permanent, CDN-cacheable URL. When set, the client builds a
|
|
133
|
+
* token-less URL and caches it indefinitely.
|
|
134
|
+
*/
|
|
135
|
+
public?: boolean;
|
|
77
136
|
}
|
|
78
137
|
|
|
79
138
|
/**
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured initializer for {@link RebaseApiError}.
|
|
3
|
+
*
|
|
4
|
+
* @group Errors
|
|
5
|
+
*/
|
|
6
|
+
export interface RebaseErrorInit {
|
|
7
|
+
/**
|
|
8
|
+
* HTTP status code, when the error originated from an HTTP response.
|
|
9
|
+
* Left `undefined` for realtime/WebSocket, network, and client-side
|
|
10
|
+
* logic errors that have no HTTP status.
|
|
11
|
+
*/
|
|
12
|
+
status?: number;
|
|
13
|
+
/** Stable, machine-readable error code (e.g. `"NOT_FOUND"`, `"BAD_REQUEST"`). */
|
|
14
|
+
code?: string;
|
|
15
|
+
/** Structured error payload returned by the server, when present. */
|
|
16
|
+
details?: unknown;
|
|
17
|
+
/** The underlying error this one wraps, if any. */
|
|
18
|
+
cause?: unknown;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The single error type thrown across the entire Rebase client surface —
|
|
23
|
+
* HTTP data/control-plane calls, realtime/WebSocket operations, and
|
|
24
|
+
* client-side logic errors (e.g. an unknown collection accessor). A `catch`
|
|
25
|
+
* block only ever needs to check for this one class:
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { RebaseApiError } from "@rebasepro/client"; // re-exported
|
|
29
|
+
*
|
|
30
|
+
* try {
|
|
31
|
+
* await client.data.products.update(id, { price: 9 });
|
|
32
|
+
* } catch (e) {
|
|
33
|
+
* if (e instanceof RebaseApiError) {
|
|
34
|
+
* if (e.status === 404) { ... } // HTTP failures carry a status
|
|
35
|
+
* console.error(e.code, e.details);
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* `status` is present for HTTP failures and `undefined` otherwise, so its
|
|
41
|
+
* presence distinguishes transport-level errors from realtime/logic errors.
|
|
42
|
+
*
|
|
43
|
+
* @group Errors
|
|
44
|
+
*/
|
|
45
|
+
export class RebaseApiError extends Error {
|
|
46
|
+
/** HTTP status code, or `undefined` for non-HTTP errors. */
|
|
47
|
+
readonly status?: number;
|
|
48
|
+
/** Stable machine-readable error code, when the server supplied one. */
|
|
49
|
+
readonly code?: string;
|
|
50
|
+
/** Structured error payload from the server, when present. */
|
|
51
|
+
readonly details?: unknown;
|
|
52
|
+
|
|
53
|
+
constructor(message: string, init: RebaseErrorInit = {}) {
|
|
54
|
+
super(message);
|
|
55
|
+
this.name = "RebaseApiError";
|
|
56
|
+
this.status = init.status;
|
|
57
|
+
this.code = init.code;
|
|
58
|
+
this.details = init.details;
|
|
59
|
+
if (init.cause !== undefined) {
|
|
60
|
+
// `cause` is standard on Error but not always in the lib target's type.
|
|
61
|
+
(this as { cause?: unknown }).cause = init.cause;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Client-side logic error — raised before any request is made (e.g. accessing
|
|
68
|
+
* an unknown collection accessor when a typed dictionary is configured).
|
|
69
|
+
*
|
|
70
|
+
* A subclass of {@link RebaseApiError} (with no `status`), so a single
|
|
71
|
+
* `catch (e) { if (e instanceof RebaseApiError) ... }` handles it too.
|
|
72
|
+
*
|
|
73
|
+
* @group Errors
|
|
74
|
+
*/
|
|
75
|
+
export class RebaseClientError extends RebaseApiError {
|
|
76
|
+
constructor(message: string) {
|
|
77
|
+
super(message);
|
|
78
|
+
this.name = "RebaseClientError";
|
|
79
|
+
}
|
|
80
|
+
}
|
package/src/index.ts
CHANGED
package/src/rebase_context.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import type { UserConfigurationPersistence } from "./controllers/local_config_pe
|
|
|
5
5
|
import type { DatabaseAdmin } from "./types/backend";
|
|
6
6
|
import type { RebaseClient } from "./controllers/client";
|
|
7
7
|
|
|
8
|
-
import type {
|
|
8
|
+
import type { RebaseSdkData } from "./controllers/data";
|
|
9
9
|
import type { User } from "./users";
|
|
10
10
|
|
|
11
11
|
|
|
@@ -36,8 +36,12 @@ export type RebaseCallContext<USER extends User = User> = {
|
|
|
36
36
|
/**
|
|
37
37
|
* Unified data access — `context.data.products.create(...)`.
|
|
38
38
|
* Access any collection as a dynamic property.
|
|
39
|
+
*
|
|
40
|
+
* Returns flat rows (`{ id, ...columns }`), identical to the frontend SDK
|
|
41
|
+
* client — so `context.data` in a backend callback and `client.data` in the
|
|
42
|
+
* frontend behave the same way (`row.title`, never `row.values.title`).
|
|
39
43
|
*/
|
|
40
|
-
data:
|
|
44
|
+
data: RebaseSdkData;
|
|
41
45
|
|
|
42
46
|
/**
|
|
43
47
|
* Used storage implementation
|
|
@@ -77,9 +81,9 @@ export type RebaseContext<USER extends User = User, AuthControllerType extends A
|
|
|
77
81
|
sideDialogsController?: import("./controllers/side_dialogs_controller").SideDialogsController;
|
|
78
82
|
|
|
79
83
|
/**
|
|
80
|
-
* Controller to open the side
|
|
84
|
+
* Controller to open the side panel displaying entity forms
|
|
81
85
|
*/
|
|
82
|
-
|
|
86
|
+
sidePanelController?: import("./controllers/side_panel_controller").SidePanelController;
|
|
83
87
|
|
|
84
88
|
/**
|
|
85
89
|
* Controller resolving URLs in the CMS
|
|
@@ -237,6 +237,9 @@ export interface AuthResponsePayload {
|
|
|
237
237
|
email: string;
|
|
238
238
|
displayName: string | null;
|
|
239
239
|
photoURL: string | null;
|
|
240
|
+
providerId?: string;
|
|
241
|
+
isAnonymous?: boolean;
|
|
242
|
+
emailVerified?: boolean;
|
|
240
243
|
roles: string[];
|
|
241
244
|
metadata: Record<string, unknown>;
|
|
242
245
|
};
|
|
@@ -393,7 +396,7 @@ export interface AuthAdapter {
|
|
|
393
396
|
*
|
|
394
397
|
* @param values - Raw request body from the client.
|
|
395
398
|
* @param collectionAuth - The parsed `AuthCollectionConfig` from the collection (if `auth` is an object).
|
|
396
|
-
* @returns Processed values ready for `driver.
|
|
399
|
+
* @returns Processed values ready for `driver.save()`, plus metadata for the post-save step.
|
|
397
400
|
*/
|
|
398
401
|
prepareUserCreation?(
|
|
399
402
|
values: Record<string, unknown>,
|
package/src/types/backend.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { EntityCollection, FilterValues, WhereFilterOp } from "./collections";
|
|
1
|
+
import type { CollectionConfig, FilterValues, WhereFilterOp } from "./collections";
|
|
3
2
|
import type { AuthAdapter } from "./auth_adapter";
|
|
3
|
+
import type { HistoryConfig } from "../controllers/client";
|
|
4
4
|
|
|
5
5
|
// =============================================================================
|
|
6
6
|
// DATABASE CONNECTION INTERFACES
|
|
@@ -52,7 +52,7 @@ export interface FetchCollectionOptions<M extends Record<string, unknown> = Reco
|
|
|
52
52
|
startAfter?: unknown;
|
|
53
53
|
searchString?: string;
|
|
54
54
|
databaseId?: string;
|
|
55
|
-
collection?:
|
|
55
|
+
collection?: CollectionConfig;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
/**
|
|
@@ -64,7 +64,7 @@ export interface SearchOptions<M extends Record<string, unknown> = Record<string
|
|
|
64
64
|
order?: "desc" | "asc";
|
|
65
65
|
limit?: number;
|
|
66
66
|
databaseId?: string;
|
|
67
|
-
collection?:
|
|
67
|
+
collection?: CollectionConfig;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/**
|
|
@@ -150,15 +150,15 @@ export type ConditionBuilderStatic<T = unknown> = {
|
|
|
150
150
|
* - Relation resolution
|
|
151
151
|
* - ID generation and conversion
|
|
152
152
|
*/
|
|
153
|
-
export interface
|
|
153
|
+
export interface DataRepository {
|
|
154
154
|
/**
|
|
155
155
|
* Fetch a single entity by ID
|
|
156
156
|
*/
|
|
157
|
-
|
|
157
|
+
fetchOne<M extends Record<string, unknown>>(
|
|
158
158
|
collectionPath: string,
|
|
159
|
-
|
|
159
|
+
id: string | number,
|
|
160
160
|
databaseId?: string
|
|
161
|
-
): Promise<
|
|
161
|
+
): Promise<Record<string, unknown> | undefined>;
|
|
162
162
|
|
|
163
163
|
/**
|
|
164
164
|
* Fetch a collection of entities with optional filtering, ordering, and pagination
|
|
@@ -166,41 +166,41 @@ export interface EntityRepository {
|
|
|
166
166
|
fetchCollection<M extends Record<string, unknown>>(
|
|
167
167
|
collectionPath: string,
|
|
168
168
|
options?: FetchCollectionOptions<M>
|
|
169
|
-
): Promise<
|
|
169
|
+
): Promise<Record<string, unknown>[]>;
|
|
170
170
|
|
|
171
171
|
/**
|
|
172
172
|
* Search entities by text
|
|
173
173
|
*/
|
|
174
|
-
|
|
174
|
+
searchRows<M extends Record<string, unknown>>(
|
|
175
175
|
collectionPath: string,
|
|
176
176
|
searchString: string,
|
|
177
177
|
options?: SearchOptions<M>
|
|
178
|
-
): Promise<
|
|
178
|
+
): Promise<Record<string, unknown>[]>;
|
|
179
179
|
|
|
180
180
|
/**
|
|
181
181
|
* Count entities in a collection
|
|
182
182
|
*/
|
|
183
|
-
|
|
183
|
+
count<M extends Record<string, unknown>>(
|
|
184
184
|
collectionPath: string,
|
|
185
185
|
options?: CountOptions<M>
|
|
186
186
|
): Promise<number>;
|
|
187
187
|
|
|
188
188
|
/**
|
|
189
|
-
* Save
|
|
189
|
+
* Save a entity (create or update)
|
|
190
190
|
*/
|
|
191
|
-
|
|
191
|
+
save<M extends Record<string, unknown>>(
|
|
192
192
|
collectionPath: string,
|
|
193
193
|
values: Partial<M>,
|
|
194
|
-
|
|
194
|
+
id?: string | number,
|
|
195
195
|
databaseId?: string
|
|
196
|
-
): Promise<
|
|
196
|
+
): Promise<Record<string, unknown>>;
|
|
197
197
|
|
|
198
198
|
/**
|
|
199
|
-
* Delete
|
|
199
|
+
* Delete a entity by ID
|
|
200
200
|
*/
|
|
201
|
-
|
|
201
|
+
delete(
|
|
202
202
|
collectionPath: string,
|
|
203
|
-
|
|
203
|
+
id: string | number,
|
|
204
204
|
databaseId?: string
|
|
205
205
|
): Promise<void>;
|
|
206
206
|
|
|
@@ -239,10 +239,10 @@ export interface CollectionSubscriptionConfig {
|
|
|
239
239
|
/**
|
|
240
240
|
* Configuration for subscribing to a single entity
|
|
241
241
|
*/
|
|
242
|
-
export interface
|
|
242
|
+
export interface SingleSubscriptionConfig {
|
|
243
243
|
clientId: string;
|
|
244
244
|
path: string;
|
|
245
|
-
|
|
245
|
+
id: string | number;
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
/**
|
|
@@ -256,16 +256,16 @@ export interface RealtimeProvider {
|
|
|
256
256
|
subscribeToCollection(
|
|
257
257
|
subscriptionId: string,
|
|
258
258
|
config: CollectionSubscriptionConfig,
|
|
259
|
-
callback?: (
|
|
259
|
+
callback?: (rows: Record<string, unknown>[]) => void
|
|
260
260
|
): void;
|
|
261
261
|
|
|
262
262
|
/**
|
|
263
263
|
* Subscribe to single entity changes
|
|
264
264
|
*/
|
|
265
|
-
|
|
265
|
+
subscribeToOne(
|
|
266
266
|
subscriptionId: string,
|
|
267
|
-
config:
|
|
268
|
-
callback?: (
|
|
267
|
+
config: SingleSubscriptionConfig,
|
|
268
|
+
callback?: (row: Record<string, unknown> | null) => void
|
|
269
269
|
): void;
|
|
270
270
|
|
|
271
271
|
/**
|
|
@@ -274,12 +274,12 @@ export interface RealtimeProvider {
|
|
|
274
274
|
unsubscribe(subscriptionId: string): void;
|
|
275
275
|
|
|
276
276
|
/**
|
|
277
|
-
* Notify all relevant subscribers of
|
|
277
|
+
* Notify all relevant subscribers of a entity update
|
|
278
278
|
*/
|
|
279
|
-
|
|
279
|
+
notifyUpdate(
|
|
280
280
|
path: string,
|
|
281
|
-
|
|
282
|
-
|
|
281
|
+
id: string,
|
|
282
|
+
row: Record<string, unknown> | null,
|
|
283
283
|
databaseId?: string
|
|
284
284
|
): Promise<void>;
|
|
285
285
|
|
|
@@ -314,17 +314,17 @@ export interface CollectionRegistryInterface {
|
|
|
314
314
|
/**
|
|
315
315
|
* Register a collection
|
|
316
316
|
*/
|
|
317
|
-
register(collection:
|
|
317
|
+
register(collection: CollectionConfig): void;
|
|
318
318
|
|
|
319
319
|
/**
|
|
320
320
|
* Get a collection by its path
|
|
321
321
|
*/
|
|
322
|
-
getCollectionByPath(path: string):
|
|
322
|
+
getCollectionByPath(path: string): CollectionConfig | undefined;
|
|
323
323
|
|
|
324
324
|
/**
|
|
325
325
|
* Get all registered collections
|
|
326
326
|
*/
|
|
327
|
-
getCollections():
|
|
327
|
+
getCollections(): CollectionConfig[];
|
|
328
328
|
|
|
329
329
|
/**
|
|
330
330
|
* Get the currently registered global callbacks, if any.
|
|
@@ -346,7 +346,7 @@ export interface DataTransformer {
|
|
|
346
346
|
*/
|
|
347
347
|
serializeToDatabase<M extends Record<string, unknown>>(
|
|
348
348
|
entity: M,
|
|
349
|
-
collection:
|
|
349
|
+
collection: CollectionConfig
|
|
350
350
|
): Record<string, unknown>;
|
|
351
351
|
|
|
352
352
|
/**
|
|
@@ -354,7 +354,7 @@ export interface DataTransformer {
|
|
|
354
354
|
*/
|
|
355
355
|
deserializeFromDatabase<M extends Record<string, unknown>>(
|
|
356
356
|
data: Record<string, unknown>,
|
|
357
|
-
collection:
|
|
357
|
+
collection: CollectionConfig
|
|
358
358
|
): Promise<M>;
|
|
359
359
|
}
|
|
360
360
|
|
|
@@ -589,7 +589,7 @@ export interface BackendInstance extends BackendLifecycle {
|
|
|
589
589
|
/**
|
|
590
590
|
* Entity repository for CRUD operations
|
|
591
591
|
*/
|
|
592
|
-
entityRepository:
|
|
592
|
+
entityRepository: DataRepository;
|
|
593
593
|
|
|
594
594
|
/**
|
|
595
595
|
* Realtime provider for subscriptions
|
|
@@ -697,7 +697,7 @@ export interface BackendBootstrapper {
|
|
|
697
697
|
* Initialize history tables / services if this driver supports them.
|
|
698
698
|
* Return undefined if history is not supported by this backend.
|
|
699
699
|
*/
|
|
700
|
-
initializeHistory?(config:
|
|
700
|
+
initializeHistory?(config: HistoryConfig, driverResult: InitializedDriver): Promise<{ historyService: unknown } | undefined>;
|
|
701
701
|
|
|
702
702
|
/**
|
|
703
703
|
* Create a realtime provider for this driver.
|
package/src/types/builders.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { AuthController } from "../controllers/auth";
|
|
2
2
|
import type { RebaseData } from "../controllers/data";
|
|
3
3
|
import type { User } from "../users";
|
|
4
|
-
import type {
|
|
4
|
+
import type { CollectionConfig } from "./collections";
|
|
5
5
|
import type { AppView } from "../controllers/navigation";
|
|
6
6
|
|
|
7
|
-
export type
|
|
7
|
+
export type CollectionConfigsBuilder<EC extends CollectionConfig = CollectionConfig> = (params: {
|
|
8
8
|
user: User | null,
|
|
9
9
|
authController: AuthController,
|
|
10
10
|
data: RebaseData
|