@maravilla-labs/types 0.5.0 → 0.6.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/global.d.ts +23 -0
- package/index.d.ts +564 -97
- package/index.ts +656 -91
- package/package.json +3 -2
- package/tsconfig.test.json +10 -0
- package/types.test-d.ts +46 -0
package/index.d.ts
CHANGED
|
@@ -149,12 +149,32 @@ export interface DbFindOptions {
|
|
|
149
149
|
/** Hybrid metadata + vector search clause. */
|
|
150
150
|
vector?: VectorQuery;
|
|
151
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* A document as it is returned by the runtime. Every row the platform
|
|
154
|
+
* stores carries a string `id` (mirrored as `_id`) injected at insert
|
|
155
|
+
* time, plus optional server-managed timestamps. `find`/`findOne` return
|
|
156
|
+
* this shape; the generic `T` is your own document fields.
|
|
157
|
+
*
|
|
158
|
+
* This is a **type-level** contract — the runtime already injects/returns
|
|
159
|
+
* `id`+`_id` on both the dev (SQLite) and production (Mongo) paths, so no
|
|
160
|
+
* normalization happens here.
|
|
161
|
+
*/
|
|
162
|
+
export type DbDocument<T = Record<string, unknown>> = T & {
|
|
163
|
+
/** Stable string row id, injected by the runtime on insert. */
|
|
164
|
+
id: string;
|
|
165
|
+
/** Mirror of `id` for MongoDB-style call sites. Always equals `id`. */
|
|
166
|
+
_id: string;
|
|
167
|
+
/** Server-managed creation timestamp, when present. */
|
|
168
|
+
_created_at?: string;
|
|
169
|
+
/** Server-managed update timestamp, when present. */
|
|
170
|
+
_updated_at?: string;
|
|
171
|
+
};
|
|
152
172
|
/**
|
|
153
173
|
* Database collection interface
|
|
154
174
|
*/
|
|
155
175
|
export interface DbCollection {
|
|
156
|
-
find(filter?: Record<string, any>, options?: DbFindOptions): Promise<
|
|
157
|
-
findOne(filter?: Record<string, any>): Promise<
|
|
176
|
+
find<T = Record<string, unknown>>(filter?: Record<string, any>, options?: DbFindOptions): Promise<DbDocument<T>[]>;
|
|
177
|
+
findOne<T = Record<string, unknown>>(filter?: Record<string, any>): Promise<DbDocument<T> | null>;
|
|
158
178
|
insertOne(document: Record<string, any>): Promise<string>;
|
|
159
179
|
updateOne(filter: Record<string, any>, update: Record<string, any>): Promise<void>;
|
|
160
180
|
deleteOne(filter: Record<string, any>): Promise<void>;
|
|
@@ -274,6 +294,316 @@ export interface Storage {
|
|
|
274
294
|
*/
|
|
275
295
|
getMetadata(key: string): Promise<StorageMetadata>;
|
|
276
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Authenticated user record from the platform auth service.
|
|
299
|
+
*/
|
|
300
|
+
export interface AuthUser {
|
|
301
|
+
/** Unique user ID (prefixed with "usr_") */
|
|
302
|
+
id: string;
|
|
303
|
+
/** User's email address */
|
|
304
|
+
email: string;
|
|
305
|
+
/** Whether the email has been verified */
|
|
306
|
+
email_verified: boolean;
|
|
307
|
+
/** Account status */
|
|
308
|
+
status: 'active' | 'suspended' | 'deactivated';
|
|
309
|
+
/** Authentication provider ("email", "google", "github", "managed", etc.) */
|
|
310
|
+
provider: string;
|
|
311
|
+
/** Group IDs the user belongs to */
|
|
312
|
+
groups: string[];
|
|
313
|
+
/**
|
|
314
|
+
* Caller-supplied external identifier used for idempotent
|
|
315
|
+
* managed-user creation (FR-3). `null`/absent for normal accounts.
|
|
316
|
+
*/
|
|
317
|
+
external_id?: string | null;
|
|
318
|
+
/** Unix timestamp when the user was created */
|
|
319
|
+
created_at: number;
|
|
320
|
+
/** Unix timestamp when the user was last updated */
|
|
321
|
+
updated_at: number;
|
|
322
|
+
/** Unix timestamp of last login (if any) */
|
|
323
|
+
last_login_at?: number;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Snapshot of whoever is currently bound to the request as the caller.
|
|
327
|
+
* This is exactly what per-resource policies see as `auth.*`.
|
|
328
|
+
*/
|
|
329
|
+
export interface AuthCaller {
|
|
330
|
+
/** Caller's user id, or `""` if anonymous */
|
|
331
|
+
user_id: string;
|
|
332
|
+
/** Caller's email, or `""` if anonymous */
|
|
333
|
+
email: string;
|
|
334
|
+
/** Admin flag from the session */
|
|
335
|
+
is_admin: boolean;
|
|
336
|
+
/** Role names (project-scoped) */
|
|
337
|
+
roles: string[];
|
|
338
|
+
/** `true` when no identity is bound to this request */
|
|
339
|
+
is_anonymous: boolean;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Session returned after successful login or token refresh.
|
|
343
|
+
*/
|
|
344
|
+
export interface AuthSession {
|
|
345
|
+
/** Short-lived JWT access token (default 15 min) */
|
|
346
|
+
access_token: string;
|
|
347
|
+
/** Single-use opaque refresh token (default 30 days) */
|
|
348
|
+
refresh_token: string;
|
|
349
|
+
/** Access token lifetime in seconds */
|
|
350
|
+
expires_in: number;
|
|
351
|
+
/** The authenticated user */
|
|
352
|
+
user: AuthUser;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Custom registration field defined in project auth settings.
|
|
356
|
+
*/
|
|
357
|
+
export interface AuthField {
|
|
358
|
+
/** Field key (used as form field name) */
|
|
359
|
+
key: string;
|
|
360
|
+
/** Display label */
|
|
361
|
+
label: string;
|
|
362
|
+
/** Field type: text, email, phone, date, number, select, boolean, url, textarea */
|
|
363
|
+
field_type: string;
|
|
364
|
+
/** Whether the field is required */
|
|
365
|
+
required: boolean;
|
|
366
|
+
/** Whether the field appears on the registration form */
|
|
367
|
+
show_on_register: boolean;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Options for registering a new user.
|
|
371
|
+
*/
|
|
372
|
+
export interface RegisterOptions {
|
|
373
|
+
/** User's email address */
|
|
374
|
+
email: string;
|
|
375
|
+
/** Password (minimum 8 characters) */
|
|
376
|
+
password: string;
|
|
377
|
+
/** Optional profile data (custom fields) */
|
|
378
|
+
profile?: Record<string, any>;
|
|
379
|
+
/**
|
|
380
|
+
* Caller-supplied external id. When set, registration is idempotent on
|
|
381
|
+
* `(tenant, external_id)` — re-registering with the same key returns the
|
|
382
|
+
* existing user instead of erroring (FR-3).
|
|
383
|
+
*/
|
|
384
|
+
external_id?: string;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Options for logging in.
|
|
388
|
+
*/
|
|
389
|
+
export interface LoginOptions {
|
|
390
|
+
/** User's email address */
|
|
391
|
+
email: string;
|
|
392
|
+
/** User's password */
|
|
393
|
+
password: string;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Options for creating a managed (no-login) user — e.g. an imported
|
|
397
|
+
* contact or service-owned record that authenticates out-of-band (FR-2).
|
|
398
|
+
* Created with no password; sessions are only minted when the account is
|
|
399
|
+
* later activated.
|
|
400
|
+
*/
|
|
401
|
+
export interface CreateManagedUserOptions {
|
|
402
|
+
/** Optional email. A synthetic no-login address is generated when omitted. */
|
|
403
|
+
email?: string;
|
|
404
|
+
/** Optional profile data. */
|
|
405
|
+
profile?: Record<string, any>;
|
|
406
|
+
/** Optional external id for idempotent create-by-key (FR-3). */
|
|
407
|
+
external_id?: string;
|
|
408
|
+
/** Optional group ids/slugs to add the user to on creation. */
|
|
409
|
+
groups?: string[];
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Filter options for listing users.
|
|
413
|
+
*/
|
|
414
|
+
export interface UserListFilter {
|
|
415
|
+
/** Max results per page (default 50) */
|
|
416
|
+
limit?: number;
|
|
417
|
+
/** Number of results to skip */
|
|
418
|
+
offset?: number;
|
|
419
|
+
/** Filter by account status */
|
|
420
|
+
status?: 'active' | 'suspended' | 'deactivated';
|
|
421
|
+
/** Filter by email (partial match) */
|
|
422
|
+
email_contains?: string;
|
|
423
|
+
/** Filter by group ID */
|
|
424
|
+
group_id?: string;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Paginated user list response.
|
|
428
|
+
*/
|
|
429
|
+
export interface UserListResponse {
|
|
430
|
+
/** Users in this page */
|
|
431
|
+
users: AuthUser[];
|
|
432
|
+
/** Total number of matching users */
|
|
433
|
+
total: number;
|
|
434
|
+
/** Page size */
|
|
435
|
+
limit: number;
|
|
436
|
+
/** Offset */
|
|
437
|
+
offset: number;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Options for updating a user.
|
|
441
|
+
*/
|
|
442
|
+
export interface UpdateUserOptions {
|
|
443
|
+
/** New email address */
|
|
444
|
+
email?: string;
|
|
445
|
+
/** New status */
|
|
446
|
+
status?: 'active' | 'suspended' | 'deactivated';
|
|
447
|
+
/** Profile data to merge */
|
|
448
|
+
profile?: Record<string, any>;
|
|
449
|
+
}
|
|
450
|
+
export interface AuthGroup {
|
|
451
|
+
id: string;
|
|
452
|
+
name: string;
|
|
453
|
+
description: string | null;
|
|
454
|
+
permissions: string[];
|
|
455
|
+
member_count: number;
|
|
456
|
+
created_at: number;
|
|
457
|
+
updated_at: number;
|
|
458
|
+
}
|
|
459
|
+
export interface CreateGroupOptions {
|
|
460
|
+
name: string;
|
|
461
|
+
description?: string;
|
|
462
|
+
permissions?: string[];
|
|
463
|
+
}
|
|
464
|
+
export interface UpdateGroupOptions {
|
|
465
|
+
name?: string;
|
|
466
|
+
description?: string;
|
|
467
|
+
permissions?: string[];
|
|
468
|
+
}
|
|
469
|
+
export interface GroupPermission {
|
|
470
|
+
resource_name: string;
|
|
471
|
+
actions: string[];
|
|
472
|
+
}
|
|
473
|
+
export interface AuthCircle {
|
|
474
|
+
id: string;
|
|
475
|
+
name: string;
|
|
476
|
+
metadata: Record<string, any> | null;
|
|
477
|
+
member_count: number;
|
|
478
|
+
created_at: number;
|
|
479
|
+
updated_at: number;
|
|
480
|
+
}
|
|
481
|
+
export interface CreateCircleOptions {
|
|
482
|
+
name: string;
|
|
483
|
+
metadata?: Record<string, any>;
|
|
484
|
+
}
|
|
485
|
+
export interface UpdateCircleOptions {
|
|
486
|
+
name?: string;
|
|
487
|
+
metadata?: Record<string, any>;
|
|
488
|
+
}
|
|
489
|
+
export interface AddCircleMemberOptions {
|
|
490
|
+
user_id: string;
|
|
491
|
+
relationship: string;
|
|
492
|
+
is_primary_contact?: boolean;
|
|
493
|
+
}
|
|
494
|
+
/** Circle membership entry */
|
|
495
|
+
export interface CircleMembership {
|
|
496
|
+
user_id: string;
|
|
497
|
+
email: string;
|
|
498
|
+
relationship: string;
|
|
499
|
+
is_primary_contact: boolean;
|
|
500
|
+
joined_at: number;
|
|
501
|
+
}
|
|
502
|
+
export type ResourceServiceType = 'kv' | 'database' | 'realtime' | 'media' | 'vector' | 'storage' | 'queue' | 'push' | 'workflow' | 'transforms';
|
|
503
|
+
/** A platform resource definition. */
|
|
504
|
+
export interface Resource {
|
|
505
|
+
id: string;
|
|
506
|
+
resource_name: string;
|
|
507
|
+
title: string;
|
|
508
|
+
description: string | null;
|
|
509
|
+
actions: string[];
|
|
510
|
+
policy: string | null;
|
|
511
|
+
service_type: ResourceServiceType | null;
|
|
512
|
+
read_filter: string | null;
|
|
513
|
+
created_at: number;
|
|
514
|
+
updated_at: number;
|
|
515
|
+
}
|
|
516
|
+
export interface CreateResourceOptions {
|
|
517
|
+
resource_name: string;
|
|
518
|
+
title: string;
|
|
519
|
+
description?: string;
|
|
520
|
+
actions?: string[];
|
|
521
|
+
policy?: string;
|
|
522
|
+
service_type?: ResourceServiceType;
|
|
523
|
+
read_filter?: string;
|
|
524
|
+
}
|
|
525
|
+
export interface UpdateResourceOptions {
|
|
526
|
+
title?: string;
|
|
527
|
+
description?: string;
|
|
528
|
+
actions?: string[];
|
|
529
|
+
policy?: string;
|
|
530
|
+
service_type?: ResourceServiceType;
|
|
531
|
+
read_filter?: string;
|
|
532
|
+
}
|
|
533
|
+
export interface RelationType {
|
|
534
|
+
id: string;
|
|
535
|
+
relation_name: string;
|
|
536
|
+
title: string;
|
|
537
|
+
description: string | null;
|
|
538
|
+
category: string;
|
|
539
|
+
icon: string | null;
|
|
540
|
+
color: string | null;
|
|
541
|
+
inverse_relation_id: string | null;
|
|
542
|
+
implies_stewardship: boolean;
|
|
543
|
+
requires_minor: boolean;
|
|
544
|
+
bidirectional: boolean;
|
|
545
|
+
is_system: boolean;
|
|
546
|
+
created_at: number;
|
|
547
|
+
updated_at: number;
|
|
548
|
+
}
|
|
549
|
+
export interface CreateRelationTypeOptions {
|
|
550
|
+
relation_name: string;
|
|
551
|
+
title: string;
|
|
552
|
+
description?: string;
|
|
553
|
+
category?: string;
|
|
554
|
+
icon?: string;
|
|
555
|
+
color?: string;
|
|
556
|
+
inverse_relation_id?: string;
|
|
557
|
+
implies_stewardship?: boolean;
|
|
558
|
+
requires_minor?: boolean;
|
|
559
|
+
bidirectional?: boolean;
|
|
560
|
+
is_system?: boolean;
|
|
561
|
+
}
|
|
562
|
+
export interface UpdateRelationTypeOptions {
|
|
563
|
+
title?: string;
|
|
564
|
+
description?: string;
|
|
565
|
+
category?: string;
|
|
566
|
+
icon?: string;
|
|
567
|
+
color?: string;
|
|
568
|
+
inverse_relation_id?: string;
|
|
569
|
+
implies_stewardship?: boolean;
|
|
570
|
+
requires_minor?: boolean;
|
|
571
|
+
bidirectional?: boolean;
|
|
572
|
+
}
|
|
573
|
+
/** A single typed relation edge between two users (FR-1). */
|
|
574
|
+
export interface Relation {
|
|
575
|
+
id: string;
|
|
576
|
+
from_user_id: string;
|
|
577
|
+
to_user_id: string;
|
|
578
|
+
/** The relation type's name (e.g. `STEWARDS`). */
|
|
579
|
+
relation_type: string;
|
|
580
|
+
/** The relation type's id (`rlt_…`). */
|
|
581
|
+
relation_type_id: string;
|
|
582
|
+
metadata?: Record<string, any> | null;
|
|
583
|
+
created_at: number;
|
|
584
|
+
}
|
|
585
|
+
/** Options for adding a relation edge. */
|
|
586
|
+
export interface AddRelationOptions {
|
|
587
|
+
from_user_id: string;
|
|
588
|
+
to_user_id: string;
|
|
589
|
+
/** Either a relation-type id (`rlt_…`) or a relation name. */
|
|
590
|
+
relation_type: string;
|
|
591
|
+
metadata?: Record<string, any>;
|
|
592
|
+
}
|
|
593
|
+
/** Direction filter when listing a user's relations. */
|
|
594
|
+
export type RelationListDirection = 'outgoing' | 'incoming' | 'both';
|
|
595
|
+
/** Options for listing relation edges touching a user. */
|
|
596
|
+
export interface ListRelationsOptions {
|
|
597
|
+
user_id: string;
|
|
598
|
+
direction?: RelationListDirection;
|
|
599
|
+
}
|
|
600
|
+
export interface AuthConfig {
|
|
601
|
+
fields: AuthField[];
|
|
602
|
+
oauth_providers: any[];
|
|
603
|
+
branding: Record<string, any>;
|
|
604
|
+
password_policy: Record<string, any>;
|
|
605
|
+
session_config: Record<string, any>;
|
|
606
|
+
}
|
|
277
607
|
/** Delegation mode for stewardship overrides */
|
|
278
608
|
export type DelegationMode = 'full' | 'scoped';
|
|
279
609
|
/** Status of a stewardship override */
|
|
@@ -292,18 +622,18 @@ export interface StewardshipOverride {
|
|
|
292
622
|
ward_id: string;
|
|
293
623
|
delegation_mode: DelegationMode;
|
|
294
624
|
scoped_permissions: ScopedPermission[];
|
|
295
|
-
valid_from
|
|
296
|
-
valid_until
|
|
625
|
+
valid_from: number | null;
|
|
626
|
+
valid_until: number | null;
|
|
297
627
|
status: StewardshipStatus;
|
|
298
|
-
reason
|
|
628
|
+
reason: string | null;
|
|
299
629
|
source: string;
|
|
300
|
-
source_circle_id
|
|
301
|
-
source_relation_type_id
|
|
630
|
+
source_circle_id: string | null;
|
|
631
|
+
source_relation_type_id: string | null;
|
|
302
632
|
created_at: number;
|
|
303
633
|
updated_at: number;
|
|
304
634
|
}
|
|
305
635
|
/** Options for creating a stewardship override */
|
|
306
|
-
export interface
|
|
636
|
+
export interface CreateStewardshipOverrideOptions {
|
|
307
637
|
steward_id: string;
|
|
308
638
|
ward_id: string;
|
|
309
639
|
delegation_mode?: DelegationMode;
|
|
@@ -334,57 +664,224 @@ export interface StewardshipAuditEntry {
|
|
|
334
664
|
performed_by: string;
|
|
335
665
|
on_behalf_of: string;
|
|
336
666
|
action: string;
|
|
337
|
-
resource
|
|
338
|
-
details
|
|
667
|
+
resource: string | null;
|
|
668
|
+
details: Record<string, any> | null;
|
|
339
669
|
created_at: number;
|
|
340
670
|
}
|
|
341
|
-
/**
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
/** Stewardship service interface */
|
|
347
|
-
export interface Stewardship {
|
|
671
|
+
/**
|
|
672
|
+
* Sub-namespace exposed at `platform.auth.stewardship` mirroring the
|
|
673
|
+
* runtime's `globalThis.platform.auth.stewardship.*` surface.
|
|
674
|
+
*/
|
|
675
|
+
export interface AuthStewardshipApi {
|
|
348
676
|
resolve(userId: string): Promise<StewardshipResolution>;
|
|
349
|
-
createOverride(
|
|
677
|
+
createOverride(opts: CreateStewardshipOverrideOptions): Promise<StewardshipOverride>;
|
|
350
678
|
revoke(id: string): Promise<void>;
|
|
351
679
|
checkPermission(stewardId: string, wardId: string, resource: string, action: string): Promise<boolean>;
|
|
352
680
|
createActAs(stewardId: string, wardId: string): Promise<ActAsContext>;
|
|
353
|
-
listAudit(userId: string, options?:
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
}
|
|
365
|
-
/** Options for creating a resource */
|
|
366
|
-
export interface CreateResourceRequest {
|
|
367
|
-
resource_name: string;
|
|
368
|
-
title: string;
|
|
369
|
-
description?: string;
|
|
370
|
-
actions?: string[];
|
|
681
|
+
listAudit(userId: string, options?: {
|
|
682
|
+
limit?: number;
|
|
683
|
+
offset?: number;
|
|
684
|
+
}): Promise<StewardshipAuditEntry[]>;
|
|
685
|
+
}
|
|
686
|
+
/** Result of an `explain()` policy check. */
|
|
687
|
+
export interface PolicyExplain {
|
|
688
|
+
allowed: boolean;
|
|
689
|
+
reason?: string;
|
|
690
|
+
/** The specific clause that caused a denial, when the engine can isolate it. */
|
|
691
|
+
failedClause?: string;
|
|
371
692
|
}
|
|
372
|
-
/**
|
|
373
|
-
export interface
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
is_primary_contact: boolean;
|
|
378
|
-
joined_at: number;
|
|
693
|
+
/** A single authorization check for batched `canMany()`. */
|
|
694
|
+
export interface CanCheck {
|
|
695
|
+
action: string;
|
|
696
|
+
resourceId: string;
|
|
697
|
+
node?: Record<string, unknown> | null;
|
|
379
698
|
}
|
|
380
|
-
/**
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
699
|
+
/**
|
|
700
|
+
* Auth service for end-user authentication and user management.
|
|
701
|
+
* Implemented by the in-runtime native bridge and by the dev-server
|
|
702
|
+
* remote client (`RemoteAuthService`).
|
|
703
|
+
*/
|
|
704
|
+
export interface AuthService {
|
|
705
|
+
/**
|
|
706
|
+
* Register a new user with email and password.
|
|
707
|
+
* @returns The created user (not yet email-verified)
|
|
708
|
+
*/
|
|
709
|
+
register(options: RegisterOptions): Promise<AuthUser>;
|
|
710
|
+
/**
|
|
711
|
+
* Authenticate a user and create a session.
|
|
712
|
+
* @returns Session with access token, refresh token, and user info
|
|
713
|
+
*/
|
|
714
|
+
login(options: LoginOptions): Promise<AuthSession>;
|
|
715
|
+
/**
|
|
716
|
+
* Validate an access token and return the authenticated user.
|
|
717
|
+
* @throws If the token is invalid or expired
|
|
718
|
+
*/
|
|
719
|
+
validate(accessToken: string): Promise<AuthUser>;
|
|
720
|
+
/**
|
|
721
|
+
* Refresh a session using a refresh token (single-use).
|
|
722
|
+
* @returns New session with fresh access and refresh tokens
|
|
723
|
+
*/
|
|
724
|
+
refresh(refreshToken: string): Promise<AuthSession>;
|
|
725
|
+
/** Revoke a specific session. */
|
|
726
|
+
logout(sessionId: string): Promise<void>;
|
|
727
|
+
/**
|
|
728
|
+
* Get a user by ID.
|
|
729
|
+
* @returns The user, or null if not found
|
|
730
|
+
*/
|
|
731
|
+
getUser(userId: string): Promise<AuthUser | null>;
|
|
732
|
+
/** List users with optional filtering and pagination. */
|
|
733
|
+
listUsers(filter?: UserListFilter): Promise<UserListResponse>;
|
|
734
|
+
/** Update a user's email, status, or profile data. */
|
|
735
|
+
updateUser(userId: string, update: UpdateUserOptions): Promise<AuthUser>;
|
|
736
|
+
/** Delete a user and all their sessions. */
|
|
737
|
+
deleteUser(userId: string): Promise<void>;
|
|
738
|
+
/**
|
|
739
|
+
* Create a managed (no-login) user (FR-2). Idempotent on `external_id`
|
|
740
|
+
* when supplied (FR-3).
|
|
741
|
+
*/
|
|
742
|
+
createManagedUser(options: CreateManagedUserOptions): Promise<AuthUser>;
|
|
743
|
+
/**
|
|
744
|
+
* Create an email verification token.
|
|
745
|
+
* @returns The verification token (caller decides how to deliver it)
|
|
746
|
+
*/
|
|
747
|
+
sendVerification(userId: string): Promise<{
|
|
748
|
+
token: string;
|
|
749
|
+
}>;
|
|
750
|
+
/** Verify an email address using a verification token. */
|
|
751
|
+
verifyEmail(token: string): Promise<void>;
|
|
752
|
+
/**
|
|
753
|
+
* Create a password reset token for an email address.
|
|
754
|
+
* @returns The reset token (caller decides how to deliver it)
|
|
755
|
+
*/
|
|
756
|
+
sendPasswordReset(email: string): Promise<{
|
|
757
|
+
token: string;
|
|
758
|
+
}>;
|
|
759
|
+
/** Reset a password using a reset token. */
|
|
760
|
+
resetPassword(token: string, newPassword: string): Promise<void>;
|
|
761
|
+
/** Change a user's password (requires old password). */
|
|
762
|
+
changePassword(userId: string, oldPassword: string, newPassword: string): Promise<void>;
|
|
763
|
+
/** Get the configured registration fields for this project. */
|
|
764
|
+
getFieldConfig(): Promise<{
|
|
765
|
+
fields: AuthField[];
|
|
766
|
+
}>;
|
|
767
|
+
/**
|
|
768
|
+
* Start an OAuth flow by generating an authorization URL.
|
|
769
|
+
* @param provider - "google", "github", "okta", or "custom_oidc"
|
|
770
|
+
*/
|
|
771
|
+
getOAuthUrl(provider: string, options?: {
|
|
772
|
+
redirectUri?: string;
|
|
773
|
+
}): Promise<{
|
|
774
|
+
auth_url: string;
|
|
775
|
+
state: string;
|
|
776
|
+
}>;
|
|
777
|
+
/** Complete an OAuth flow by exchanging the authorization code. */
|
|
778
|
+
handleOAuthCallback(provider: string, params: {
|
|
779
|
+
code: string;
|
|
780
|
+
state: string;
|
|
781
|
+
}): Promise<AuthSession | {
|
|
782
|
+
type: 'LinkRequired';
|
|
783
|
+
email: string;
|
|
784
|
+
provider: string;
|
|
785
|
+
provider_id: string;
|
|
786
|
+
existing_user_id: string;
|
|
787
|
+
}>;
|
|
788
|
+
/**
|
|
789
|
+
* Middleware helper that validates auth and injects `request.user`.
|
|
790
|
+
* Returns 401 JSON response if no valid token is found.
|
|
791
|
+
*/
|
|
792
|
+
withAuth<T extends (request: Request & {
|
|
793
|
+
user: AuthUser;
|
|
794
|
+
}) => Promise<Response>>(handler: T): (request: Request) => Promise<Response>;
|
|
795
|
+
createGroup(options: CreateGroupOptions): Promise<AuthGroup>;
|
|
796
|
+
listGroups(): Promise<AuthGroup[]>;
|
|
797
|
+
/** @param groupId - the group id **or slug** (resolved server-side). */
|
|
798
|
+
getGroup(groupId: string): Promise<AuthGroup | null>;
|
|
799
|
+
/**
|
|
800
|
+
* Look up a group by its declarative name (the same name used in
|
|
801
|
+
* `maravilla.config.ts`'s `groups: [...]` block). Returns null if the
|
|
802
|
+
* auth-settings reconciler hasn't created it yet.
|
|
803
|
+
*/
|
|
804
|
+
getGroupByName(name: string): Promise<AuthGroup | null>;
|
|
805
|
+
/** @param groupId - the group id **or slug** (resolved server-side). */
|
|
806
|
+
updateGroup(groupId: string, options: UpdateGroupOptions): Promise<AuthGroup>;
|
|
807
|
+
/** @param groupId - the group id **or slug** (resolved server-side). */
|
|
808
|
+
deleteGroup(groupId: string): Promise<void>;
|
|
809
|
+
/** @param groupId - the group id **or slug** (resolved server-side). */
|
|
810
|
+
addUserToGroup(userId: string, groupId: string): Promise<void>;
|
|
811
|
+
/** @param groupId - the group id **or slug** (resolved server-side). */
|
|
812
|
+
removeUserFromGroup(userId: string, groupId: string): Promise<void>;
|
|
813
|
+
getUserGroups(userId: string): Promise<AuthGroup[]>;
|
|
814
|
+
/** @param groupId - the group id **or slug** (resolved server-side). */
|
|
815
|
+
getGroupMembers(groupId: string): Promise<AuthUser[]>;
|
|
816
|
+
/** @param groupId - the group id **or slug** (resolved server-side). */
|
|
817
|
+
getGroupPermissions(groupId: string): Promise<GroupPermission[]>;
|
|
818
|
+
/** @param groupId - the group id **or slug** (resolved server-side). */
|
|
819
|
+
setGroupPermissions(groupId: string, permissions: GroupPermission[]): Promise<void>;
|
|
820
|
+
createCircle(options: CreateCircleOptions): Promise<AuthCircle>;
|
|
821
|
+
listCircles(): Promise<AuthCircle[]>;
|
|
822
|
+
/** @param circleId - the circle id **or slug** (resolved server-side). */
|
|
823
|
+
getCircle(circleId: string): Promise<AuthCircle | null>;
|
|
824
|
+
/** @param circleId - the circle id **or slug** (resolved server-side). */
|
|
825
|
+
updateCircle(circleId: string, options: UpdateCircleOptions): Promise<AuthCircle>;
|
|
826
|
+
/** @param circleId - the circle id **or slug** (resolved server-side). */
|
|
827
|
+
deleteCircle(circleId: string): Promise<void>;
|
|
828
|
+
/** @param circleId - the circle id **or slug** (resolved server-side). */
|
|
829
|
+
addCircleMember(circleId: string, options: AddCircleMemberOptions): Promise<void>;
|
|
830
|
+
/** @param circleId - the circle id **or slug** (resolved server-side). */
|
|
831
|
+
removeCircleMember(circleId: string, userId: string): Promise<void>;
|
|
832
|
+
/** @param circleId - the circle id **or slug** (resolved server-side). */
|
|
833
|
+
getCircleMembers(circleId: string): Promise<CircleMembership[]>;
|
|
834
|
+
getUserCircles(userId: string): Promise<AuthCircle[]>;
|
|
835
|
+
createResource(options: CreateResourceOptions): Promise<Resource>;
|
|
836
|
+
listResources(): Promise<Resource[]>;
|
|
837
|
+
updateResource(resourceId: string, options: UpdateResourceOptions): Promise<Resource>;
|
|
838
|
+
deleteResource(resourceId: string): Promise<void>;
|
|
839
|
+
createRelationType(options: CreateRelationTypeOptions): Promise<RelationType>;
|
|
840
|
+
listRelationTypes(): Promise<RelationType[]>;
|
|
841
|
+
/** @param id - the relation-type id **or slug** (resolved server-side). */
|
|
842
|
+
updateRelationType(id: string, options: UpdateRelationTypeOptions): Promise<RelationType>;
|
|
843
|
+
/** @param id - the relation-type id **or slug** (resolved server-side). */
|
|
844
|
+
deleteRelationType(id: string): Promise<void>;
|
|
845
|
+
/** Add a directed relation edge between two users. */
|
|
846
|
+
addRelation(options: AddRelationOptions): Promise<Relation>;
|
|
847
|
+
/** Remove a relation edge by its endpoints and relation-type id. */
|
|
848
|
+
removeRelation(fromUserId: string, toUserId: string, relationTypeId: string): Promise<void>;
|
|
849
|
+
/** List relation edges touching a user, optionally filtered by direction. */
|
|
850
|
+
listRelations(options: ListRelationsOptions): Promise<Relation[]>;
|
|
851
|
+
getProfile(userId: string): Promise<Record<string, any>>;
|
|
852
|
+
setProfile(userId: string, data: Record<string, any>): Promise<void>;
|
|
853
|
+
getAuthConfig(): Promise<AuthConfig>;
|
|
854
|
+
setAuthConfig(config: AuthConfig): Promise<void>;
|
|
855
|
+
readonly stewardship: AuthStewardshipApi;
|
|
856
|
+
/**
|
|
857
|
+
* Explicitly bind the caller for the remainder of this request.
|
|
858
|
+
* Pass a JWT to validate + bind, or `null` / `""` to clear.
|
|
859
|
+
*/
|
|
860
|
+
setCurrentUser(token: string | null): Promise<void>;
|
|
861
|
+
/**
|
|
862
|
+
* Snapshot of the currently bound caller. Returns an anonymous caller
|
|
863
|
+
* (`is_anonymous: true`) when no identity has been bound.
|
|
864
|
+
*/
|
|
865
|
+
getCurrentUser(): AuthCaller;
|
|
866
|
+
/**
|
|
867
|
+
* Ask the policy engine whether the bound caller would be allowed to
|
|
868
|
+
* perform `action` on `resourceId`. Returns a boolean — never throws on
|
|
869
|
+
* denial. Fails closed when no caller is bound.
|
|
870
|
+
*/
|
|
871
|
+
can(action: string, resourceId: string, node?: Record<string, unknown> | null): Promise<boolean>;
|
|
872
|
+
/**
|
|
873
|
+
* Like {@link can}, but returns *why* (FR-7). Fails closed with
|
|
874
|
+
* `{ allowed: false, reason: 'no bound user' }` when no caller is bound.
|
|
875
|
+
*/
|
|
876
|
+
explain(action: string, resourceId: string, node?: Record<string, unknown> | null): Promise<PolicyExplain>;
|
|
877
|
+
/**
|
|
878
|
+
* Batch authorization check (FR-7). Results are returned in the same
|
|
879
|
+
* order as `checks`. Fails closed (all `{ allowed: false }`) when no
|
|
880
|
+
* caller is bound.
|
|
881
|
+
*/
|
|
882
|
+
canMany(checks: CanCheck[]): Promise<{
|
|
883
|
+
allowed: boolean;
|
|
884
|
+
}[]>;
|
|
388
885
|
}
|
|
389
886
|
/** State of a workflow run. */
|
|
390
887
|
export type WorkflowRunStatus = 'queued' | 'running' | 'sleeping' | 'waiting_event' | 'completed' | 'failed' | 'cancelled';
|
|
@@ -460,48 +957,13 @@ export interface Platform {
|
|
|
460
957
|
storage: Storage;
|
|
461
958
|
/** Durable multi-step workflows */
|
|
462
959
|
workflows: Workflows;
|
|
463
|
-
/**
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
login(options: {
|
|
471
|
-
email: string;
|
|
472
|
-
password: string;
|
|
473
|
-
}): Promise<any>;
|
|
474
|
-
validate(accessToken: string): Promise<any>;
|
|
475
|
-
refresh(refreshToken: string): Promise<any>;
|
|
476
|
-
logout(sessionId: string): Promise<void>;
|
|
477
|
-
getUser(userId: string): Promise<any>;
|
|
478
|
-
listUsers(filter?: Record<string, any>): Promise<any>;
|
|
479
|
-
updateUser(userId: string, update: Record<string, any>): Promise<any>;
|
|
480
|
-
deleteUser(userId: string): Promise<void>;
|
|
481
|
-
sendVerification(userId: string): Promise<any>;
|
|
482
|
-
verifyEmail(token: string): Promise<void>;
|
|
483
|
-
sendPasswordReset(email: string): Promise<any>;
|
|
484
|
-
resetPassword(token: string, newPassword: string): Promise<void>;
|
|
485
|
-
changePassword(userId: string, oldPassword: string, newPassword: string): Promise<void>;
|
|
486
|
-
getFieldConfig(): Promise<any>;
|
|
487
|
-
getOAuthUrl(provider: string, options?: {
|
|
488
|
-
redirectUri?: string;
|
|
489
|
-
}): Promise<any>;
|
|
490
|
-
handleOAuthCallback(provider: string, params: {
|
|
491
|
-
code: string;
|
|
492
|
-
state: string;
|
|
493
|
-
}): Promise<any>;
|
|
494
|
-
/** Stewardship (guardian/ward delegation) */
|
|
495
|
-
stewardship: Stewardship;
|
|
496
|
-
/** List available resources */
|
|
497
|
-
listResources(): Promise<Resource[]>;
|
|
498
|
-
/** Create a resource definition */
|
|
499
|
-
createResource(options: CreateResourceRequest): Promise<Resource>;
|
|
500
|
-
/** Get circle members */
|
|
501
|
-
getCircleMembers(circleId: string): Promise<CircleMembership[]>;
|
|
502
|
-
/** Get circles a user belongs to */
|
|
503
|
-
getUserCircles(userId: string): Promise<Circle[]>;
|
|
504
|
-
};
|
|
960
|
+
/**
|
|
961
|
+
* Auth service — the full canonical {@link AuthService} surface:
|
|
962
|
+
* authentication, user management, groups, circles, resources, relation
|
|
963
|
+
* types, typed relation edges, stewardship, profile/config, and the
|
|
964
|
+
* request-scoped `can`/`explain`/`canMany` authorization checks.
|
|
965
|
+
*/
|
|
966
|
+
auth: AuthService;
|
|
505
967
|
/** Legacy aliases for compatibility */
|
|
506
968
|
env: {
|
|
507
969
|
KV: KvStore;
|
|
@@ -510,9 +972,14 @@ export interface Platform {
|
|
|
510
972
|
};
|
|
511
973
|
}
|
|
512
974
|
/**
|
|
513
|
-
*
|
|
975
|
+
* The ambient `platform` global is declared in `./global.d.ts` (kept
|
|
976
|
+
* separate so that *type-only* imports of these interfaces — e.g. from
|
|
977
|
+
* `@maravilla-labs/platform`, which has its own `getPlatform()` global —
|
|
978
|
+
* do not pull a conflicting ambient `const platform` into scope). Tooling
|
|
979
|
+
* and app code that want the global reference it explicitly:
|
|
980
|
+
*
|
|
981
|
+
* ```ts
|
|
982
|
+
* /// <reference types="@maravilla-labs/types/global" />
|
|
983
|
+
* ```
|
|
514
984
|
*/
|
|
515
|
-
declare global {
|
|
516
|
-
const platform: Platform;
|
|
517
|
-
}
|
|
518
985
|
export { Platform as default };
|