backd-js 0.1.15 → 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/LICENSE +21 -201
- package/README.md +32 -26
- package/package.json +47 -40
- package/src/admin.js +597 -0
- package/src/auth.js +374 -0
- package/src/client.js +214 -0
- package/src/data.js +278 -0
- package/src/errors.js +135 -0
- package/src/functions.js +143 -0
- package/src/index.js +51 -0
- package/src/storage.js +43 -0
- package/types/admin.d.ts +709 -0
- package/types/auth.d.ts +281 -0
- package/types/client.d.ts +132 -0
- package/types/data.d.ts +260 -0
- package/types/errors.d.ts +106 -0
- package/types/functions.d.ts +135 -0
- package/types/index.d.ts +59 -0
- package/types/storage.d.ts +26 -0
- package/.babelrc +0 -4
- package/.editorconfig +0 -12
- package/.eslintrc.js +0 -28
- package/.npmignore +0 -9
- package/.nvmrc +0 -1
- package/.travis.yml +0 -33
- package/lib/backd.js +0 -13625
- package/lib/backd.js.map +0 -1
- package/lib/backd.min.js +0 -7
package/types/auth.d.ts
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
export type Client = import('./client.js').Client;
|
|
2
|
+
export type RequestOptions = import('./client.js').RequestOptions;
|
|
3
|
+
export type User = {
|
|
4
|
+
id: string;
|
|
5
|
+
email: string;
|
|
6
|
+
email_verified: boolean;
|
|
7
|
+
roles: string[];
|
|
8
|
+
/**
|
|
9
|
+
* The user's language, one the realm lists (used for their emails).
|
|
10
|
+
*/
|
|
11
|
+
locale: string;
|
|
12
|
+
/**
|
|
13
|
+
* RFC3339 timestamp.
|
|
14
|
+
*/
|
|
15
|
+
created_at: string;
|
|
16
|
+
};
|
|
17
|
+
export type Session = {
|
|
18
|
+
/**
|
|
19
|
+
* Session token (`bds_…`); already stored by the client.
|
|
20
|
+
*/
|
|
21
|
+
token: string;
|
|
22
|
+
token_type: 'Bearer';
|
|
23
|
+
session_id: string;
|
|
24
|
+
/**
|
|
25
|
+
* RFC3339; pushed forward as the session is used.
|
|
26
|
+
*/
|
|
27
|
+
expires_at: string;
|
|
28
|
+
user: User;
|
|
29
|
+
};
|
|
30
|
+
export type SessionInfo = {
|
|
31
|
+
id: string;
|
|
32
|
+
created_at: string;
|
|
33
|
+
last_used_at: string;
|
|
34
|
+
expires_at: string;
|
|
35
|
+
/**
|
|
36
|
+
* The session making this request.
|
|
37
|
+
*/
|
|
38
|
+
current: boolean;
|
|
39
|
+
};
|
|
40
|
+
export type AuthEvent = 'SIGNED_IN' | 'SIGNED_OUT' | 'SESSION_EXPIRED';
|
|
41
|
+
export type AuthListener = (event: AuthEvent, session: Session | null) => void;
|
|
42
|
+
/** Sign-up, login and session management: `client.auth`. */
|
|
43
|
+
export declare class Auth {
|
|
44
|
+
/** @internal */
|
|
45
|
+
client: import("./client.js").Client;
|
|
46
|
+
/** @internal */
|
|
47
|
+
listeners: Set<any>;
|
|
48
|
+
/** @param {Client} client */
|
|
49
|
+
constructor(client: Client);
|
|
50
|
+
/**
|
|
51
|
+
* Creates an account and signs in. Realms with `signup: invite` need an
|
|
52
|
+
* invitation token. `locale` (such as `es` or `es-MX`) is the language to
|
|
53
|
+
* use for the user; the server maps it silently to one the realm lists. A
|
|
54
|
+
* browser also sends its `Accept-Language`, which is used when no `locale`
|
|
55
|
+
* is given. `redirectTo` is where the page after the verification link may
|
|
56
|
+
* send the user (it must be within the realm's `email.allowed_redirects`).
|
|
57
|
+
*
|
|
58
|
+
* A realm that requires verified addresses (`account.require_verified_email`)
|
|
59
|
+
* creates the account but starts no session: this rejects with a
|
|
60
|
+
* {@link VerificationRequiredError}, nothing is stored, and the user signs
|
|
61
|
+
* in after following the link in the email they were sent.
|
|
62
|
+
* @param {{ email: string, password: string, invitation?: string, locale?: string, redirectTo?: string }} input
|
|
63
|
+
* @param {RequestOptions} [opts]
|
|
64
|
+
* @returns {Promise<Session>}
|
|
65
|
+
*/
|
|
66
|
+
signup({ email, password, invitation, locale, redirectTo }: {
|
|
67
|
+
email: string;
|
|
68
|
+
password: string;
|
|
69
|
+
invitation?: string;
|
|
70
|
+
locale?: string;
|
|
71
|
+
redirectTo?: string;
|
|
72
|
+
}, opts?: RequestOptions): Promise<Session>;
|
|
73
|
+
/**
|
|
74
|
+
* Signs in with email and password.
|
|
75
|
+
* @param {{ email: string, password: string }} input
|
|
76
|
+
* @param {RequestOptions} [opts]
|
|
77
|
+
* @returns {Promise<Session>}
|
|
78
|
+
*/
|
|
79
|
+
login({ email, password }: {
|
|
80
|
+
email: string;
|
|
81
|
+
password: string;
|
|
82
|
+
}, opts?: RequestOptions): Promise<Session>;
|
|
83
|
+
/**
|
|
84
|
+
* Asks for the verification email again. Always resolves, whatever the
|
|
85
|
+
* address is (unknown, disabled, already verified), so it can't be used to
|
|
86
|
+
* find out who is registered. `redirectTo` is where the page after the link
|
|
87
|
+
* may send the user (within the realm's `email.allowed_redirects`).
|
|
88
|
+
* @param {{ email: string, redirectTo?: string }} input
|
|
89
|
+
* @param {RequestOptions} [opts]
|
|
90
|
+
* @returns {Promise<void>}
|
|
91
|
+
*/
|
|
92
|
+
resendVerification({ email, redirectTo }: {
|
|
93
|
+
email: string;
|
|
94
|
+
redirectTo?: string;
|
|
95
|
+
}, opts?: RequestOptions): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Verifies an address with the token of the link in the email: for apps
|
|
98
|
+
* that host their own page (`email.links` in `realm.yaml`). Starts no
|
|
99
|
+
* session. An expired, used or unknown token rejects with a
|
|
100
|
+
* `ValidationError` whose `code` is `invalid_token`.
|
|
101
|
+
* @param {string} token
|
|
102
|
+
* @param {RequestOptions} [opts]
|
|
103
|
+
* @returns {Promise<void>}
|
|
104
|
+
*/
|
|
105
|
+
verifyEmail(token: string, opts?: RequestOptions): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Asks for a password reset email. Always resolves, whatever the address is.
|
|
108
|
+
* Rejects with a `RetryableError` once the realm's limits for reset
|
|
109
|
+
* requests (per address and per client) are reached.
|
|
110
|
+
* @param {{ email: string, redirectTo?: string }} input
|
|
111
|
+
* @param {RequestOptions} [opts]
|
|
112
|
+
* @returns {Promise<void>}
|
|
113
|
+
*/
|
|
114
|
+
requestPasswordReset({ email, redirectTo }: {
|
|
115
|
+
email: string;
|
|
116
|
+
redirectTo?: string;
|
|
117
|
+
}, opts?: RequestOptions): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Sets a new password with the token of a reset link. Ends every session of
|
|
120
|
+
* the user, verifies their address and starts no session: log in afterwards.
|
|
121
|
+
* A password the policy refuses rejects with a `ValidationError` and leaves
|
|
122
|
+
* the token usable; a bad token has the `invalid_token` code.
|
|
123
|
+
* @param {{ token: string, password: string }} input
|
|
124
|
+
* @param {RequestOptions} [opts]
|
|
125
|
+
* @returns {Promise<void>}
|
|
126
|
+
*/
|
|
127
|
+
resetPassword({ token, password }: {
|
|
128
|
+
token: string;
|
|
129
|
+
password: string;
|
|
130
|
+
}, opts?: RequestOptions): Promise<void>;
|
|
131
|
+
/**
|
|
132
|
+
* Asks to change the signed-in user's email address (realms with
|
|
133
|
+
* `account.allow_email_change`). Needs the current password. Resolves
|
|
134
|
+
* whether or not the new address is free; nothing changes until the link
|
|
135
|
+
* sent to the new address is used (see {@link Auth#confirmEmailChange}).
|
|
136
|
+
* @param {{ newEmail: string, password: string, redirectTo?: string }} input
|
|
137
|
+
* @param {RequestOptions} [opts]
|
|
138
|
+
* @returns {Promise<void>}
|
|
139
|
+
*/
|
|
140
|
+
requestEmailChange({ newEmail, password, redirectTo }: {
|
|
141
|
+
newEmail: string;
|
|
142
|
+
password: string;
|
|
143
|
+
redirectTo?: string;
|
|
144
|
+
}, opts?: RequestOptions): Promise<void>;
|
|
145
|
+
/**
|
|
146
|
+
* Confirms an email change with the token sent to the new address: the
|
|
147
|
+
* address changes and every session of the user ends.
|
|
148
|
+
* @param {string} token
|
|
149
|
+
* @param {RequestOptions} [opts]
|
|
150
|
+
* @returns {Promise<void>}
|
|
151
|
+
*/
|
|
152
|
+
confirmEmailChange(token: string, opts?: RequestOptions): Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Undoes an email change with the token sent to the old address: restores
|
|
155
|
+
* it, ends every session and makes the password unusable until it is reset
|
|
156
|
+
* (a reset email is sent to the restored address).
|
|
157
|
+
* @param {string} token
|
|
158
|
+
* @param {RequestOptions} [opts]
|
|
159
|
+
* @returns {Promise<void>}
|
|
160
|
+
*/
|
|
161
|
+
revertEmailChange(token: string, opts?: RequestOptions): Promise<void>;
|
|
162
|
+
/**
|
|
163
|
+
* Accepts an invitation that was emailed (admin `invitations.send`), with
|
|
164
|
+
* the token of its link: creates the account for the invited address,
|
|
165
|
+
* already verified, and starts no session. `locale` is the user's language.
|
|
166
|
+
* @param {{ token: string, password: string, locale?: string }} input
|
|
167
|
+
* @param {RequestOptions} [opts]
|
|
168
|
+
* @returns {Promise<void>}
|
|
169
|
+
*/
|
|
170
|
+
acceptInvitation({ token, password, locale }: {
|
|
171
|
+
token: string;
|
|
172
|
+
password: string;
|
|
173
|
+
locale?: string;
|
|
174
|
+
}, opts?: RequestOptions): Promise<void>;
|
|
175
|
+
/**
|
|
176
|
+
* A call that needs no session and answers with no body.
|
|
177
|
+
* @internal
|
|
178
|
+
* @param {string[]} path
|
|
179
|
+
* @param {Record<string, unknown>} body
|
|
180
|
+
* @param {RequestOptions} [opts]
|
|
181
|
+
*/
|
|
182
|
+
accepted(path: string[], body: Record<string, unknown>, opts?: RequestOptions): Promise<void>;
|
|
183
|
+
/**
|
|
184
|
+
* Ends the current session. The stored token is removed even if the
|
|
185
|
+
* server can't be reached.
|
|
186
|
+
* @param {RequestOptions} [opts]
|
|
187
|
+
* @returns {Promise<void>}
|
|
188
|
+
*/
|
|
189
|
+
logout(opts?: RequestOptions): Promise<void>;
|
|
190
|
+
/**
|
|
191
|
+
* Ends every session of the user, on every device.
|
|
192
|
+
* @param {RequestOptions} [opts]
|
|
193
|
+
* @returns {Promise<void>}
|
|
194
|
+
*/
|
|
195
|
+
logoutAll(opts?: RequestOptions): Promise<void>;
|
|
196
|
+
/**
|
|
197
|
+
* The signed-in user.
|
|
198
|
+
* @param {RequestOptions} [opts]
|
|
199
|
+
* @returns {Promise<User>}
|
|
200
|
+
*/
|
|
201
|
+
me(opts?: RequestOptions): Promise<User>;
|
|
202
|
+
/**
|
|
203
|
+
* Changes the signed-in user's own settings: today their language, which
|
|
204
|
+
* must be one the realm lists (case is ignored). Anything else is a
|
|
205
|
+
* `ValidationError` with code `invalid_locale` and the allowed languages in
|
|
206
|
+
* `details`.
|
|
207
|
+
* @param {{ locale?: string }} changes
|
|
208
|
+
* @param {RequestOptions} [opts]
|
|
209
|
+
* @returns {Promise<User>}
|
|
210
|
+
*/
|
|
211
|
+
updateMe(changes: {
|
|
212
|
+
locale?: string;
|
|
213
|
+
}, opts?: RequestOptions): Promise<User>;
|
|
214
|
+
/**
|
|
215
|
+
* Deletes the signed-in user's account: it is **deactivated** (disabled, its
|
|
216
|
+
* sessions end) and all data is kept. Erasing a user's data is an
|
|
217
|
+
* administrator's action (`admin.users.delete`).
|
|
218
|
+
* @param {{ password: string }} input
|
|
219
|
+
* @param {RequestOptions} [opts]
|
|
220
|
+
* @returns {Promise<void>}
|
|
221
|
+
*/
|
|
222
|
+
deleteAccount({ password }: {
|
|
223
|
+
password: string;
|
|
224
|
+
}, opts?: RequestOptions): Promise<void>;
|
|
225
|
+
/**
|
|
226
|
+
* Changes the password. This session stays valid; all others end.
|
|
227
|
+
* @param {{ currentPassword: string, newPassword: string }} input
|
|
228
|
+
* @param {RequestOptions} [opts]
|
|
229
|
+
* @returns {Promise<void>}
|
|
230
|
+
*/
|
|
231
|
+
changePassword({ currentPassword, newPassword }: {
|
|
232
|
+
currentPassword: string;
|
|
233
|
+
newPassword: string;
|
|
234
|
+
}, opts?: RequestOptions): Promise<void>;
|
|
235
|
+
/**
|
|
236
|
+
* The user's active sessions, newest first.
|
|
237
|
+
* @param {RequestOptions} [opts]
|
|
238
|
+
* @returns {Promise<SessionInfo[]>}
|
|
239
|
+
*/
|
|
240
|
+
sessions(opts?: RequestOptions): Promise<SessionInfo[]>;
|
|
241
|
+
/**
|
|
242
|
+
* Ends one of the user's sessions, for example a lost device.
|
|
243
|
+
* @param {string} id
|
|
244
|
+
* @param {RequestOptions} [opts]
|
|
245
|
+
* @returns {Promise<void>}
|
|
246
|
+
*/
|
|
247
|
+
revokeSession(id: string, opts?: RequestOptions): Promise<void>;
|
|
248
|
+
/**
|
|
249
|
+
* The stored session token, if any.
|
|
250
|
+
* @returns {Promise<string | null>}
|
|
251
|
+
*/
|
|
252
|
+
token(): Promise<string | null>;
|
|
253
|
+
/**
|
|
254
|
+
* Calls listener on sign-in, sign-out and session expiry.
|
|
255
|
+
* @param {AuthListener} listener
|
|
256
|
+
* @returns {() => void} Stops listening.
|
|
257
|
+
*/
|
|
258
|
+
onAuthChange(listener: AuthListener): () => void;
|
|
259
|
+
/**
|
|
260
|
+
* @internal
|
|
261
|
+
* @param {Session} session
|
|
262
|
+
* @returns {Promise<Session>}
|
|
263
|
+
*/
|
|
264
|
+
signedIn(session: Session): Promise<Session>;
|
|
265
|
+
/**
|
|
266
|
+
* @internal
|
|
267
|
+
* @param {AuthEvent} event
|
|
268
|
+
*/
|
|
269
|
+
signedOut(event: AuthEvent): Promise<void>;
|
|
270
|
+
/**
|
|
271
|
+
* Called by the client when the server refuses the stored token.
|
|
272
|
+
* @internal
|
|
273
|
+
*/
|
|
274
|
+
_expired(): Promise<void>;
|
|
275
|
+
/**
|
|
276
|
+
* @internal
|
|
277
|
+
* @param {AuthEvent} event
|
|
278
|
+
* @param {Session | null} session
|
|
279
|
+
*/
|
|
280
|
+
emit(event: AuthEvent, session: Session | null): void;
|
|
281
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Admin } from './admin.js';
|
|
2
|
+
import { Auth } from './auth.js';
|
|
3
|
+
import { Database } from './data.js';
|
|
4
|
+
export type TokenStorage = import('./storage.js').TokenStorage;
|
|
5
|
+
export type RetryOptions = {
|
|
6
|
+
/**
|
|
7
|
+
* Extra attempts after the first (0 disables).
|
|
8
|
+
*/
|
|
9
|
+
attempts: number;
|
|
10
|
+
/**
|
|
11
|
+
* Longest wait between attempts; default 30000.
|
|
12
|
+
*/
|
|
13
|
+
maxDelayMs?: number;
|
|
14
|
+
};
|
|
15
|
+
export type ClientOptions = {
|
|
16
|
+
/**
|
|
17
|
+
* Base URL of backd, e.g. "https://api.example.com".
|
|
18
|
+
*/
|
|
19
|
+
url: string;
|
|
20
|
+
/**
|
|
21
|
+
* The realm to talk to.
|
|
22
|
+
*/
|
|
23
|
+
realm: string;
|
|
24
|
+
/**
|
|
25
|
+
* Server-side only: an API key (`bdk_…`). Full access to the realm.
|
|
26
|
+
*/
|
|
27
|
+
apiKey?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Allow `apiKey` in a browser. Anyone who loads the page gets the key.
|
|
30
|
+
*/
|
|
31
|
+
dangerouslyAllowBrowser?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Where the session token lives; memory by default.
|
|
34
|
+
*/
|
|
35
|
+
storage?: TokenStorage;
|
|
36
|
+
/**
|
|
37
|
+
* Retries for 429/503; off by default.
|
|
38
|
+
*/
|
|
39
|
+
retry?: RetryOptions;
|
|
40
|
+
/**
|
|
41
|
+
* A fetch implementation; the global one by default.
|
|
42
|
+
*/
|
|
43
|
+
fetch?: typeof fetch;
|
|
44
|
+
/**
|
|
45
|
+
* Extra headers for every request.
|
|
46
|
+
*/
|
|
47
|
+
headers?: Record<string, string>;
|
|
48
|
+
};
|
|
49
|
+
export type RequestOptions = {
|
|
50
|
+
signal?: AbortSignal;
|
|
51
|
+
retry?: RetryOptions;
|
|
52
|
+
headers?: Record<string, string>;
|
|
53
|
+
};
|
|
54
|
+
export type RequestInit = {
|
|
55
|
+
method: string;
|
|
56
|
+
/**
|
|
57
|
+
* Path segments after /v1/{realm}, encoded here.
|
|
58
|
+
*/
|
|
59
|
+
path: string[];
|
|
60
|
+
query?: Record<string, string | number | boolean | undefined>;
|
|
61
|
+
/**
|
|
62
|
+
* Sent as JSON.
|
|
63
|
+
*/
|
|
64
|
+
body?: unknown;
|
|
65
|
+
/**
|
|
66
|
+
* Defaults to application/json when there's a body.
|
|
67
|
+
*/
|
|
68
|
+
contentType?: string;
|
|
69
|
+
headers?: Record<string, string>;
|
|
70
|
+
/**
|
|
71
|
+
* Send credentials; default true.
|
|
72
|
+
*/
|
|
73
|
+
auth?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Treat a refused session token as expired; default true.
|
|
76
|
+
*/
|
|
77
|
+
expire?: boolean;
|
|
78
|
+
signal?: AbortSignal;
|
|
79
|
+
retry?: RetryOptions;
|
|
80
|
+
};
|
|
81
|
+
export type RawResponse = {
|
|
82
|
+
status: number;
|
|
83
|
+
headers: Headers;
|
|
84
|
+
/**
|
|
85
|
+
* Parsed JSON, or undefined for empty bodies.
|
|
86
|
+
*/
|
|
87
|
+
data: any;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Creates a client for one realm.
|
|
91
|
+
* @param {ClientOptions} options
|
|
92
|
+
* @returns {Client}
|
|
93
|
+
*/
|
|
94
|
+
export declare function createClient(options: ClientOptions): Client;
|
|
95
|
+
export declare class Client {
|
|
96
|
+
/** @readonly */
|
|
97
|
+
url: string;
|
|
98
|
+
/** @readonly */
|
|
99
|
+
realm: string;
|
|
100
|
+
/** @internal */
|
|
101
|
+
apiKey: string | undefined;
|
|
102
|
+
/** @internal */
|
|
103
|
+
fetchImpl: typeof fetch;
|
|
104
|
+
/** @internal */
|
|
105
|
+
retry: RetryOptions;
|
|
106
|
+
/** @internal */
|
|
107
|
+
headers: Record<string, string>;
|
|
108
|
+
/** @readonly */
|
|
109
|
+
storage: import("./storage.js").TokenStorage;
|
|
110
|
+
/** Sign-up, login and sessions. */
|
|
111
|
+
auth: Auth;
|
|
112
|
+
/** Users, roles, invitations and API keys; needs an admin `apiKey` or an admin user's session. */
|
|
113
|
+
admin: Admin;
|
|
114
|
+
/** @param {ClientOptions} options */
|
|
115
|
+
constructor(options: ClientOptions);
|
|
116
|
+
/** Whether the client was created with an API key. */
|
|
117
|
+
get hasApiKey(): boolean;
|
|
118
|
+
/**
|
|
119
|
+
* A database of the realm, to reach its collections:
|
|
120
|
+
* `client.db('main').collection('posts')`.
|
|
121
|
+
* @param {string} name
|
|
122
|
+
* @returns {Database}
|
|
123
|
+
*/
|
|
124
|
+
db(name: string): Database;
|
|
125
|
+
/**
|
|
126
|
+
* Sends a request to /v1/{realm}/…, adding credentials, and returns the
|
|
127
|
+
* parsed answer. Non-2xx answers throw a BackdError.
|
|
128
|
+
* @param {RequestInit} req
|
|
129
|
+
* @returns {Promise<RawResponse>}
|
|
130
|
+
*/
|
|
131
|
+
request(req: RequestInit): Promise<RawResponse>;
|
|
132
|
+
}
|
package/types/data.d.ts
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { Job } from './functions.js';
|
|
2
|
+
export type Client = import('./client.js').Client;
|
|
3
|
+
export type RequestOptions = import('./client.js').RequestOptions;
|
|
4
|
+
export type JobData = import('./functions.js').JobData;
|
|
5
|
+
export type Meta = {
|
|
6
|
+
/**
|
|
7
|
+
* RFC3339 timestamp.
|
|
8
|
+
*/
|
|
9
|
+
created_at: string;
|
|
10
|
+
/**
|
|
11
|
+
* RFC3339 timestamp.
|
|
12
|
+
*/
|
|
13
|
+
updated_at: string;
|
|
14
|
+
/**
|
|
15
|
+
* Increases on every write; missing only on very old documents.
|
|
16
|
+
*/
|
|
17
|
+
version?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Id of the user who created it (realms with auth enabled).
|
|
20
|
+
*/
|
|
21
|
+
owner?: string | null;
|
|
22
|
+
/**
|
|
23
|
+
* `user:<id>`, `key:<name>` or `anonymous`.
|
|
24
|
+
*/
|
|
25
|
+
created_by?: string;
|
|
26
|
+
/**
|
|
27
|
+
* `user:<id>`, `key:<name>` or `anonymous`.
|
|
28
|
+
*/
|
|
29
|
+
updated_by?: string;
|
|
30
|
+
};
|
|
31
|
+
export type Doc<T extends object = Record<string, any>> = T & {
|
|
32
|
+
id: string;
|
|
33
|
+
_meta: Meta;
|
|
34
|
+
};
|
|
35
|
+
export type ListParams = {
|
|
36
|
+
/**
|
|
37
|
+
* Filter in backd's query language, e.g. `{ price: { $lt: 20 } }`
|
|
38
|
+
* or `{ $or: [{ title: { $icontains: 'go' } }, { body: { $icontains: 'go' } }] }`.
|
|
39
|
+
*/
|
|
40
|
+
where?: object | string;
|
|
41
|
+
/**
|
|
42
|
+
* Fields, `-` prefix for descending, e.g. `'-_meta.created_at'`.
|
|
43
|
+
*/
|
|
44
|
+
orderBy?: string | string[];
|
|
45
|
+
/**
|
|
46
|
+
* 1–100; default 20.
|
|
47
|
+
*/
|
|
48
|
+
limit?: number;
|
|
49
|
+
skip?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Also return `total`.
|
|
52
|
+
*/
|
|
53
|
+
count?: boolean;
|
|
54
|
+
};
|
|
55
|
+
export type Page<T extends object = Record<string, any>> = {
|
|
56
|
+
items: Doc<T>[];
|
|
57
|
+
limit: number;
|
|
58
|
+
skip: number;
|
|
59
|
+
has_more: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* With `count: true`.
|
|
62
|
+
*/
|
|
63
|
+
total?: number;
|
|
64
|
+
};
|
|
65
|
+
export type WriteOptions = RequestOptions & {
|
|
66
|
+
ifMatch?: number | string;
|
|
67
|
+
};
|
|
68
|
+
export type BatchOperation = {
|
|
69
|
+
op: 'create' | 'replace' | 'patch' | 'delete';
|
|
70
|
+
collection: string;
|
|
71
|
+
id?: string;
|
|
72
|
+
document?: Record<string, any>;
|
|
73
|
+
patch?: Record<string, any>;
|
|
74
|
+
ifMatch?: number | string;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* @typedef {import('./client.js').Client} Client
|
|
78
|
+
* @typedef {import('./client.js').RequestOptions} RequestOptions
|
|
79
|
+
* @typedef {import('./functions.js').JobData} JobData
|
|
80
|
+
*/
|
|
81
|
+
/**
|
|
82
|
+
* Server-owned fields of a document.
|
|
83
|
+
* @typedef {object} Meta
|
|
84
|
+
* @property {string} created_at RFC3339 timestamp.
|
|
85
|
+
* @property {string} updated_at RFC3339 timestamp.
|
|
86
|
+
* @property {number} [version] Increases on every write; missing only on very old documents.
|
|
87
|
+
* @property {string | null} [owner] Id of the user who created it (realms with auth enabled).
|
|
88
|
+
* @property {string} [created_by] `user:<id>`, `key:<name>` or `anonymous`.
|
|
89
|
+
* @property {string} [updated_by] `user:<id>`, `key:<name>` or `anonymous`.
|
|
90
|
+
*/
|
|
91
|
+
/**
|
|
92
|
+
* A stored document: the collection's fields plus `id` and `_meta`.
|
|
93
|
+
* @template {object} [T=Record<string, any>]
|
|
94
|
+
* @typedef {T & { id: string, _meta: Meta }} Doc
|
|
95
|
+
*/
|
|
96
|
+
/**
|
|
97
|
+
* @typedef {object} ListParams
|
|
98
|
+
* @property {object | string} [where] Filter in backd's query language, e.g. `{ price: { $lt: 20 } }`
|
|
99
|
+
* or `{ $or: [{ title: { $icontains: 'go' } }, { body: { $icontains: 'go' } }] }`.
|
|
100
|
+
* @property {string | string[]} [orderBy] Fields, `-` prefix for descending, e.g. `'-_meta.created_at'`.
|
|
101
|
+
* @property {number} [limit] 1–100; default 20.
|
|
102
|
+
* @property {number} [skip]
|
|
103
|
+
* @property {boolean} [count] Also return `total`.
|
|
104
|
+
*/
|
|
105
|
+
/**
|
|
106
|
+
* A page of documents, as the API returns it.
|
|
107
|
+
* @template {object} [T=Record<string, any>]
|
|
108
|
+
* @typedef {object} Page
|
|
109
|
+
* @property {Doc<T>[]} items
|
|
110
|
+
* @property {number} limit
|
|
111
|
+
* @property {number} skip
|
|
112
|
+
* @property {boolean} has_more
|
|
113
|
+
* @property {number} [total] With `count: true`.
|
|
114
|
+
*/
|
|
115
|
+
/**
|
|
116
|
+
* Options for writes. `ifMatch` makes the write fail with a
|
|
117
|
+
* VersionMismatchError unless the document is still at that version.
|
|
118
|
+
* @typedef {RequestOptions & { ifMatch?: number | string }} WriteOptions
|
|
119
|
+
*/
|
|
120
|
+
/**
|
|
121
|
+
* One write for `db.batch(...)`, applied atomically with the others.
|
|
122
|
+
* `create` and `replace` need `document`; `patch` needs `patch` (a JSON
|
|
123
|
+
* Merge Patch). `replace`, `patch` and `delete` need `id`, and accept
|
|
124
|
+
* `ifMatch` (like `WriteOptions`).
|
|
125
|
+
* @typedef {object} BatchOperation
|
|
126
|
+
* @property {'create' | 'replace' | 'patch' | 'delete'} op
|
|
127
|
+
* @property {string} collection
|
|
128
|
+
* @property {string} [id]
|
|
129
|
+
* @property {Record<string, any>} [document]
|
|
130
|
+
* @property {Record<string, any>} [patch]
|
|
131
|
+
* @property {number | string} [ifMatch]
|
|
132
|
+
*/
|
|
133
|
+
/** A database of the realm: `client.db(name)`. */
|
|
134
|
+
export declare class Database {
|
|
135
|
+
/** @internal */
|
|
136
|
+
client: import("./client.js").Client;
|
|
137
|
+
/** @readonly */
|
|
138
|
+
name: string;
|
|
139
|
+
/**
|
|
140
|
+
* @param {Client} client
|
|
141
|
+
* @param {string} name
|
|
142
|
+
*/
|
|
143
|
+
constructor(client: Client, name: string);
|
|
144
|
+
/**
|
|
145
|
+
* A collection of this database.
|
|
146
|
+
* @template {object} [T=Record<string, any>]
|
|
147
|
+
* @param {string} name
|
|
148
|
+
* @returns {Collection<T>}
|
|
149
|
+
*/
|
|
150
|
+
collection<T extends object = Record<string, any>>(name: string): Collection<T>;
|
|
151
|
+
/**
|
|
152
|
+
* Creates, replaces, patches and deletes documents across this
|
|
153
|
+
* database's collections in one MongoDB transaction: either every
|
|
154
|
+
* operation applies, or none does (up to 100 operations). Rejects with
|
|
155
|
+
* a `BackdError` naming the first operation that failed; a version
|
|
156
|
+
* mismatch (`ifMatch`) is a `VersionMismatchError`, same as a single
|
|
157
|
+
* write.
|
|
158
|
+
* @param {BatchOperation[]} operations
|
|
159
|
+
* @param {RequestOptions} [opts]
|
|
160
|
+
* @returns {Promise<(Doc | { id: string })[]>} one entry per operation, in order
|
|
161
|
+
*/
|
|
162
|
+
batch(operations: BatchOperation[], opts?: RequestOptions): Promise<(Doc | {
|
|
163
|
+
id: string;
|
|
164
|
+
})[]>;
|
|
165
|
+
/**
|
|
166
|
+
* Calls a function. Returns its output directly for a `sync`
|
|
167
|
+
* function; for `async`, a `Job` handle to poll instead of the
|
|
168
|
+
* output (`job.status()`, or `job.wait()` for the output). A
|
|
169
|
+
* function's own error (`ctx.error(status, code, message)`) arrives
|
|
170
|
+
* as a `BackdError` with that status and code — for `async`, only
|
|
171
|
+
* once `job.wait()` resolves, not from this call itself.
|
|
172
|
+
*
|
|
173
|
+
* `webhook` functions can't be called through this method: their
|
|
174
|
+
* caller is whatever service sends the webhook, never this client.
|
|
175
|
+
* @param {string} name
|
|
176
|
+
* @param {unknown} [input] Any JSON value; omitted is sent as `null`.
|
|
177
|
+
* @param {RequestOptions & { idempotencyKey?: string }} [opts]
|
|
178
|
+
* @returns {Promise<unknown | Job>}
|
|
179
|
+
*/
|
|
180
|
+
fn(name: string, input?: unknown, opts?: RequestOptions & {
|
|
181
|
+
idempotencyKey?: string;
|
|
182
|
+
}): Promise<unknown | Job>;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* A collection: `client.db(db).collection(name)`. `T` describes the
|
|
186
|
+
* documents' own fields.
|
|
187
|
+
* @template {object} [T=Record<string, any>]
|
|
188
|
+
*/
|
|
189
|
+
export declare class Collection<T extends object = Record<string, any>> {
|
|
190
|
+
/** @internal */
|
|
191
|
+
client: import("./client.js").Client;
|
|
192
|
+
/** @internal */
|
|
193
|
+
path: string[];
|
|
194
|
+
/**
|
|
195
|
+
* @param {Client} client
|
|
196
|
+
* @param {string} database
|
|
197
|
+
* @param {string} name
|
|
198
|
+
*/
|
|
199
|
+
constructor(client: Client, database: string, name: string);
|
|
200
|
+
/**
|
|
201
|
+
* One page of documents the caller may read.
|
|
202
|
+
* @param {ListParams} [params]
|
|
203
|
+
* @param {RequestOptions} [opts]
|
|
204
|
+
* @returns {Promise<Page<T>>}
|
|
205
|
+
*/
|
|
206
|
+
list(params?: ListParams, opts?: RequestOptions): Promise<Page<T>>;
|
|
207
|
+
/**
|
|
208
|
+
* Every matching document, fetching pages as needed:
|
|
209
|
+
* `for await (const doc of posts.iterate({ where }))`. Pages are
|
|
210
|
+
* fetched by offset, so documents created or deleted meanwhile can be
|
|
211
|
+
* skipped or repeated.
|
|
212
|
+
* @param {Omit<ListParams, 'skip' | 'count'>} [params] `limit` is the page size (default 100).
|
|
213
|
+
* @param {RequestOptions} [opts]
|
|
214
|
+
* @returns {AsyncGenerator<Doc<T>, void, undefined>}
|
|
215
|
+
*/
|
|
216
|
+
iterate(params?: Omit<ListParams, 'skip' | 'count'>, opts?: RequestOptions): AsyncGenerator<Doc<T>, void, undefined>;
|
|
217
|
+
/**
|
|
218
|
+
* One document; NotFoundError if it doesn't exist or the caller may not read it.
|
|
219
|
+
* @param {string} id
|
|
220
|
+
* @param {RequestOptions} [opts]
|
|
221
|
+
* @returns {Promise<Doc<T>>}
|
|
222
|
+
*/
|
|
223
|
+
get(id: string, opts?: RequestOptions): Promise<Doc<T>>;
|
|
224
|
+
/**
|
|
225
|
+
* Creates a document. `id` and `_meta` are set by the server.
|
|
226
|
+
* @param {T} doc
|
|
227
|
+
* @param {RequestOptions} [opts]
|
|
228
|
+
* @returns {Promise<Doc<T>>}
|
|
229
|
+
*/
|
|
230
|
+
create(doc: T, opts?: RequestOptions): Promise<Doc<T>>;
|
|
231
|
+
/**
|
|
232
|
+
* Replaces the whole document: fields not in `doc` are removed.
|
|
233
|
+
* @param {string} id
|
|
234
|
+
* @param {T} doc
|
|
235
|
+
* @param {WriteOptions} [opts]
|
|
236
|
+
* @returns {Promise<Doc<T>>}
|
|
237
|
+
*/
|
|
238
|
+
replace(id: string, doc: T, opts?: WriteOptions): Promise<Doc<T>>;
|
|
239
|
+
/**
|
|
240
|
+
* Updates some fields (JSON Merge Patch): fields in `patch` are set,
|
|
241
|
+
* nested objects are merged, and `null` removes a field.
|
|
242
|
+
* @param {string} id
|
|
243
|
+
* @param {Partial<T> | Record<string, unknown>} patch
|
|
244
|
+
* @param {WriteOptions} [opts]
|
|
245
|
+
* @returns {Promise<Doc<T>>}
|
|
246
|
+
*/
|
|
247
|
+
patch(id: string, patch: Partial<T> | Record<string, unknown>, opts?: WriteOptions): Promise<Doc<T>>;
|
|
248
|
+
/**
|
|
249
|
+
* Deletes a document.
|
|
250
|
+
* @param {string} id
|
|
251
|
+
* @param {WriteOptions} [opts]
|
|
252
|
+
* @returns {Promise<void>}
|
|
253
|
+
*/
|
|
254
|
+
delete(id: string, opts?: WriteOptions): Promise<void>;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* `3` → `"3"`; strings (`*`, `"3"`, `"2", "3"`) are sent as given.
|
|
258
|
+
* @param {number | string} v
|
|
259
|
+
*/
|
|
260
|
+
export declare function ifMatchValue(v: number | string): string;
|