@happyvertical/smrt-profiles 0.35.1 → 0.35.3

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/types.d.ts CHANGED
@@ -1,6 +1,646 @@
1
- /**
2
- * TypeScript type definitions for @have/profiles package
3
- */
1
+ import { Asset } from '@happyvertical/smrt-assets';
2
+ import { SmrtObject } from '@happyvertical/smrt-core';
3
+ import { SmrtObjectOptions } from '@happyvertical/smrt-core';
4
+
5
+ declare class ApiKey extends SmrtObject {
6
+ /**
7
+ * Link to the Profile (Person, Organization, Bot)
8
+ */
9
+ profileId?: string;
10
+ /**
11
+ * SHA-256 hash of the API key
12
+ */
13
+ keyHash: string;
14
+ /**
15
+ * First 8 characters of the key for identification (e.g., "sk_live_a1b2...")
16
+ */
17
+ keyPrefix: string;
18
+ /**
19
+ * Human-readable name for the key (e.g., "CI Bot", "Local CLI")
20
+ */
21
+ name: string;
22
+ /**
23
+ * Scopes/permissions for this key
24
+ */
25
+ scopes: string[];
26
+ /**
27
+ * Last time this key was used
28
+ */
29
+ lastUsedAt: Date | null;
30
+ /**
31
+ * When this key expires (null = never)
32
+ */
33
+ expiresAt: Date | null;
34
+ /**
35
+ * When this key was revoked (null = active)
36
+ */
37
+ revokedAt: Date | null;
38
+ constructor(options?: ApiKeyOptions);
39
+ /**
40
+ * Get the linked Profile
41
+ */
42
+ getProfile(): Promise<Profile | null>;
43
+ /**
44
+ * Check if this key is valid (not expired, not revoked)
45
+ */
46
+ isValid(): boolean;
47
+ /**
48
+ * Check if this key has a specific scope
49
+ */
50
+ hasScope(scope: string): boolean;
51
+ /**
52
+ * Revoke this key
53
+ */
54
+ revoke(): Promise<void>;
55
+ /**
56
+ * Record usage of this key
57
+ */
58
+ recordUsage(): Promise<void>;
59
+ /**
60
+ * Hash an API key
61
+ */
62
+ static hashKey(key: string): string;
63
+ /**
64
+ * Generate a new API key for a profile
65
+ */
66
+ static generate(profile: Profile, options: {
67
+ name: string;
68
+ scopes?: string[];
69
+ expiresAt?: Date | null;
70
+ db?: SmrtObjectOptions['db'];
71
+ }): Promise<GenerateKeyResult>;
72
+ /**
73
+ * Verify an API key and return the ApiKey record if valid
74
+ */
75
+ static verify(key: string, options?: SmrtObjectOptions): Promise<ApiKey | null>;
76
+ }
77
+
78
+ declare interface ApiKeyOptions extends SmrtObjectOptions {
79
+ profileId?: string;
80
+ name?: string;
81
+ scopes?: string[];
82
+ expiresAt?: Date | null;
83
+ }
84
+
85
+ declare class AuditLog extends SmrtObject {
86
+ tenantId: string | null;
87
+ /**
88
+ * The profile who performed the action
89
+ */
90
+ profileId?: string;
91
+ /**
92
+ * Action performed (e.g., 'issue.update', 'feedback.incorporate')
93
+ */
94
+ action: string;
95
+ /**
96
+ * Type of resource affected (e.g., 'Issue', 'Repository')
97
+ */
98
+ resourceType: string;
99
+ /**
100
+ * ID of the affected resource
101
+ */
102
+ resourceId: string;
103
+ /**
104
+ * Source of the action
105
+ */
106
+ source: AuditSource;
107
+ /**
108
+ * Additional context (CI run ID, request ID, etc.)
109
+ */
110
+ metadata: Record<string, unknown>;
111
+ /**
112
+ * For pass-through identity in CI - the actual person who triggered
113
+ */
114
+ onBehalfOfId?: string | null;
115
+ constructor(options?: AuditLogOptions);
116
+ /**
117
+ * Get the profile who performed the action
118
+ */
119
+ getProfile(): Promise<Profile | null>;
120
+ /**
121
+ * Get the profile on whose behalf the action was performed (if any)
122
+ */
123
+ getOnBehalfOf(): Promise<Profile | null>;
124
+ /**
125
+ * Get the effective actor (onBehalfOf if set, otherwise profile)
126
+ */
127
+ getEffectiveActor(): Promise<Profile | null>;
128
+ /**
129
+ * Create an audit log entry
130
+ */
131
+ static record(options: AuditLogOptions & {
132
+ profile: Profile;
133
+ onBehalfOf?: Profile | null;
134
+ }): Promise<AuditLog>;
135
+ }
136
+
137
+ declare interface AuditLogOptions extends SmrtObjectOptions {
138
+ profileId?: string;
139
+ action?: string;
140
+ resourceType?: string;
141
+ resourceId?: string;
142
+ source?: AuditSource;
143
+ metadata?: Record<string, unknown>;
144
+ onBehalfOfId?: string | null;
145
+ tenantId?: string | null;
146
+ }
147
+
148
+ declare type AuditSource = 'web' | 'cli' | 'ci' | 'webhook' | 'mcp';
149
+
150
+ declare interface GenerateKeyResult {
151
+ key: string;
152
+ apiKey: ApiKey;
153
+ }
154
+
155
+ declare class NostrIdentity extends SmrtObject {
156
+ /**
157
+ * Link to the Profile (Person, Organization, Bot)
158
+ */
159
+ profileId?: string;
160
+ /**
161
+ * Hex-encoded secp256k1 public key (64 characters)
162
+ */
163
+ pubkey: string;
164
+ /**
165
+ * AES-256-GCM encrypted private key (base64-encoded ciphertext)
166
+ */
167
+ encryptedPrivkey: string;
168
+ /**
169
+ * Initialization vector for AES-GCM decryption (base64)
170
+ */
171
+ encryptionIv: string;
172
+ /**
173
+ * Authentication tag from AES-GCM (base64)
174
+ */
175
+ encryptionTag: string;
176
+ /**
177
+ * Email address associated with this identity
178
+ */
179
+ email: string;
180
+ /**
181
+ * Username for NIP-05 verification (e.g., "alice" for alice@domain.com)
182
+ */
183
+ nip05Username: string;
184
+ /**
185
+ * Last time this identity was used for authentication
186
+ */
187
+ lastUsedAt: Date | null;
188
+ /**
189
+ * When this identity was verified via magic link
190
+ */
191
+ verifiedAt: Date | null;
192
+ constructor(options?: NostrIdentityOptions);
193
+ /**
194
+ * Get the linked Profile
195
+ */
196
+ getProfile(): Promise<Profile | null>;
197
+ /**
198
+ * Find identity by public key
199
+ */
200
+ static findByPubkey(pubkey: string, options?: SmrtObjectOptions): Promise<NostrIdentity | null>;
201
+ /**
202
+ * Find identity by email
203
+ */
204
+ static findByEmail(email: string, options?: SmrtObjectOptions): Promise<NostrIdentity | null>;
205
+ /**
206
+ * Find identity by NIP-05 username
207
+ */
208
+ static findByNip05(username: string, options?: SmrtObjectOptions): Promise<NostrIdentity | null>;
209
+ /**
210
+ * Decrypt the private key using the server master secret
211
+ * @param masterSecret - SERVER_MASTER_SECRET from environment
212
+ * @returns Hex-encoded private key
213
+ */
214
+ decryptPrivkey(masterSecret: string): string;
215
+ /**
216
+ * Get the full keypair (requires master secret)
217
+ * @param masterSecret - SERVER_MASTER_SECRET from environment
218
+ */
219
+ getKeypair(masterSecret: string): {
220
+ pubkey: string;
221
+ privkey: string;
222
+ npub: string;
223
+ nsec: string;
224
+ };
225
+ /**
226
+ * Record usage of this identity
227
+ */
228
+ recordUsage(): Promise<void>;
229
+ /**
230
+ * Mark this identity as verified
231
+ */
232
+ markVerified(): Promise<void>;
233
+ /**
234
+ * Check if this identity is verified
235
+ */
236
+ isVerified(): boolean;
237
+ /**
238
+ * Get the NIP-05 identifier (username@domain)
239
+ * Note: Domain must be provided by the application
240
+ */
241
+ getNip05Identifier(domain: string): string;
242
+ }
243
+
244
+ declare interface NostrIdentityOptions extends SmrtObjectOptions {
245
+ profileId?: string;
246
+ pubkey?: string;
247
+ encryptedPrivkey?: string;
248
+ encryptionIv?: string;
249
+ encryptionTag?: string;
250
+ email?: string;
251
+ nip05Username?: string;
252
+ lastUsedAt?: Date | null;
253
+ verifiedAt?: Date | null;
254
+ }
255
+
256
+ declare class OidcIdentity extends SmrtObject {
257
+ /**
258
+ * Link to the Profile (Person, Organization, Bot)
259
+ */
260
+ profileId?: string;
261
+ /**
262
+ * Provider name (e.g., 'keycloak', 'google', 'github')
263
+ */
264
+ provider: string;
265
+ /**
266
+ * OIDC issuer URL (e.g., https://keycloak.example.com/realms/bmp)
267
+ */
268
+ issuer: string;
269
+ /**
270
+ * OIDC subject claim - unique identifier from the provider
271
+ */
272
+ subject: string;
273
+ /**
274
+ * Cached email from the IdP (for display/lookup)
275
+ */
276
+ email: string;
277
+ /**
278
+ * Last time this identity was used for authentication
279
+ */
280
+ lastUsedAt: Date | null;
281
+ constructor(options?: OidcIdentityOptions);
282
+ /**
283
+ * Get the linked Profile
284
+ */
285
+ getProfile(): Promise<Profile | null>;
286
+ /**
287
+ * Find identity by issuer and subject
288
+ */
289
+ static findBySubject(issuer: string, subject: string, options?: SmrtObjectOptions): Promise<OidcIdentity | null>;
290
+ /**
291
+ * Find or create identity for a profile
292
+ */
293
+ static findOrCreate(profile: Profile, oidcData: {
294
+ provider: string;
295
+ issuer: string;
296
+ subject: string;
297
+ email?: string;
298
+ }, options?: SmrtObjectOptions): Promise<OidcIdentity>;
299
+ /**
300
+ * Record usage of this identity
301
+ */
302
+ recordUsage(): Promise<void>;
303
+ }
304
+
305
+ declare interface OidcIdentityOptions extends SmrtObjectOptions {
306
+ profileId?: string;
307
+ provider?: string;
308
+ issuer?: string;
309
+ subject?: string;
310
+ email?: string;
311
+ lastUsedAt?: Date | null;
312
+ }
313
+
314
+ declare class Profile extends SmrtObject {
315
+ tenantId: string | null;
316
+ typeId?: string;
317
+ email?: string;
318
+ name: string;
319
+ description?: string;
320
+ metadata: ProfileMetadata[];
321
+ relationshipsFrom: ProfileRelationship[];
322
+ relationshipsTo: ProfileRelationship[];
323
+ constructor(options?: ProfileOptions);
324
+ /**
325
+ * Get the profile type slug for this profile
326
+ *
327
+ * @returns The slug of the profile type
328
+ */
329
+ getTypeSlug(): Promise<string>;
330
+ /**
331
+ * Set the profile type by slug
332
+ *
333
+ * @param slug - The slug of the profile type
334
+ * @throws Error if profile type not found
335
+ */
336
+ setTypeBySlug(slug: string): Promise<void>;
337
+ /**
338
+ * Add metadata to this profile
339
+ *
340
+ * @param metafieldSlug - The slug of the metafield
341
+ * @param value - The value to set
342
+ */
343
+ addMetadata(metafieldSlug: string, value: unknown): Promise<void>;
344
+ /**
345
+ * Get all metadata for this profile as key-value object
346
+ *
347
+ * @returns Object with metafield slugs as keys
348
+ */
349
+ getMetadata(): Promise<Record<string, string>>;
350
+ /**
351
+ * Update multiple metadata values
352
+ *
353
+ * @param metadata - Object with metafield slugs as keys and values
354
+ */
355
+ updateMetadata(metadata: Record<string, unknown>): Promise<void>;
356
+ /**
357
+ * Remove metadata by metafield slug
358
+ *
359
+ * @param metafieldSlug - The slug of the metafield to remove
360
+ */
361
+ removeMetadata(metafieldSlug: string): Promise<void>;
362
+ private getProfileAssetCollection;
363
+ getAssets(relationship?: string): Promise<Asset[]>;
364
+ addAsset(asset: Asset, relationship?: string, sortOrder?: number): Promise<void>;
365
+ removeAsset(assetId: string, relationship?: string): Promise<void>;
366
+ /**
367
+ * Add a relationship to another profile
368
+ *
369
+ * @param toProfile - The target profile
370
+ * @param relationshipSlug - The type of relationship
371
+ * @param contextProfile - Optional context profile for tertiary relationships
372
+ */
373
+ addRelationship(toProfile: Profile, relationshipSlug: string, contextProfile?: Profile): Promise<void>;
374
+ /**
375
+ * Get all relationships for this profile
376
+ *
377
+ * @param options - Filter options (typeSlug, direction)
378
+ * @returns Array of ProfileRelationship instances
379
+ */
380
+ getRelationships(options?: {
381
+ typeSlug?: string;
382
+ direction?: 'from' | 'to' | 'all';
383
+ }): Promise<ProfileRelationship[]>;
384
+ /**
385
+ * Get related profiles
386
+ *
387
+ * @param relationshipSlug - Optional filter by relationship type slug
388
+ * @returns Array of related Profile instances
389
+ */
390
+ getRelatedProfiles(relationshipSlug?: string): Promise<Profile[]>;
391
+ /**
392
+ * Remove a relationship to another profile
393
+ *
394
+ * @param toProfile - The target profile
395
+ * @param relationshipSlug - The type of relationship to remove
396
+ */
397
+ removeRelationship(toProfile: Profile, relationshipSlug: string): Promise<void>;
398
+ /**
399
+ * AI-powered: Generate a professional bio for this profile
400
+ *
401
+ * Uses the `smrtProfiles.profile.generateBio` prompt registered via
402
+ * `@happyvertical/smrt-prompts`, allowing tenant- or instance-level
403
+ * overrides of the template, model, and parameters at runtime.
404
+ *
405
+ * @returns Generated bio text
406
+ */
407
+ generateBio(): Promise<string>;
408
+ /**
409
+ * AI-powered: Check if profile matches criteria
410
+ *
411
+ * @param criteria - Criteria to match against
412
+ * @returns True if matches criteria
413
+ */
414
+ matches(criteria: string): Promise<boolean>;
415
+ /**
416
+ * Find profiles by metadata key-value pair
417
+ *
418
+ * @param metafieldSlug - The metafield slug to search
419
+ * @param value - The value to match
420
+ * @returns Array of matching profiles
421
+ */
422
+ static findByMetadata(_metafieldSlug: string, _value: unknown): Promise<Profile[]>;
423
+ /**
424
+ * Find profiles by type slug
425
+ *
426
+ * @param typeSlug - The profile type slug
427
+ * @returns Array of matching profiles
428
+ */
429
+ static findByType(_typeSlug: string): Promise<Profile[]>;
430
+ /**
431
+ * Find related profiles for a given profile
432
+ *
433
+ * @param profileId - The profile UUID
434
+ * @param relationshipSlug - Optional filter by relationship type
435
+ * @returns Array of related profiles
436
+ */
437
+ static findRelated(_profileId: string, _relationshipSlug?: string): Promise<Profile[]>;
438
+ /**
439
+ * Search profiles by email
440
+ *
441
+ * @param email - The email to search for
442
+ * @returns Profile or null if not found
443
+ */
444
+ static searchByEmail(_email: string): Promise<Profile | null>;
445
+ /**
446
+ * Get all API keys for this profile
447
+ *
448
+ * @returns Array of API keys
449
+ */
450
+ getApiKeys(): Promise<ApiKey[]>;
451
+ /**
452
+ * Get active (non-revoked, non-expired) API keys for this profile
453
+ *
454
+ * @returns Array of active API keys
455
+ */
456
+ getActiveApiKeys(): Promise<ApiKey[]>;
457
+ /**
458
+ * Generate a new API key for this profile
459
+ *
460
+ * @param options - Key options (name, scopes, expiration)
461
+ * @returns The generated key (plaintext) and ApiKey record
462
+ */
463
+ generateApiKey(options: {
464
+ name: string;
465
+ scopes?: string[];
466
+ expiresAt?: Date | null;
467
+ }): Promise<GenerateKeyResult>;
468
+ /**
469
+ * Get all OIDC identities linked to this profile
470
+ *
471
+ * @returns Array of OIDC identity records
472
+ */
473
+ getOidcIdentities(): Promise<OidcIdentity[]>;
474
+ /**
475
+ * Link a new OIDC identity to this profile
476
+ *
477
+ * @param oidcData - OIDC provider data
478
+ * @returns The linked OIDC identity record
479
+ */
480
+ linkOidcIdentity(oidcData: {
481
+ provider: string;
482
+ issuer: string;
483
+ subject: string;
484
+ email?: string;
485
+ }): Promise<OidcIdentity>;
486
+ /**
487
+ * Get all Nostr identities linked to this profile
488
+ *
489
+ * @returns Array of Nostr identity records
490
+ */
491
+ getNostrIdentities(): Promise<NostrIdentity[]>;
492
+ /**
493
+ * Link a new Nostr identity to this profile
494
+ *
495
+ * @param nostrData - Nostr identity data (encrypted keypair)
496
+ * @returns The linked Nostr identity record
497
+ */
498
+ linkNostrIdentity(nostrData: {
499
+ pubkey: string;
500
+ encryptedPrivkey: string;
501
+ encryptionIv: string;
502
+ encryptionTag: string;
503
+ email: string;
504
+ nip05Username?: string;
505
+ }): Promise<NostrIdentity>;
506
+ /**
507
+ * Get audit logs for actions performed by this profile
508
+ *
509
+ * @param limit - Maximum number of logs to return
510
+ * @returns Array of audit log entries
511
+ */
512
+ getAuditLogs(limit?: number): Promise<AuditLog[]>;
513
+ /**
514
+ * Record an audit log entry for an action by this profile
515
+ *
516
+ * @param options - Audit log options
517
+ * @returns The created audit log entry
518
+ */
519
+ recordAction(options: {
520
+ action: string;
521
+ resourceType: string;
522
+ resourceId: string;
523
+ source?: 'web' | 'cli' | 'ci' | 'webhook' | 'mcp';
524
+ metadata?: Record<string, unknown>;
525
+ onBehalfOf?: Profile | null;
526
+ }): Promise<AuditLog>;
527
+ }
528
+
529
+ declare class ProfileMetadata extends SmrtObject {
530
+ tenantId: string | null;
531
+ profileId?: string;
532
+ metafieldId?: string;
533
+ value: string;
534
+ constructor(options?: ProfileMetadataOptions);
535
+ /**
536
+ * Validate this metadata value against the metafield's validation schema
537
+ *
538
+ * @returns True if valid, throws error if invalid
539
+ */
540
+ validate(): Promise<boolean>;
541
+ /**
542
+ * Get the metafield slug for this metadata
543
+ *
544
+ * @returns The slug of the metafield
545
+ */
546
+ getMetafieldSlug(): Promise<string>;
547
+ }
548
+
549
+ declare interface ProfileMetadataOptions extends SmrtObjectOptions {
550
+ profileId?: string;
551
+ metafieldId?: string;
552
+ value?: string;
553
+ tenantId?: string | null;
554
+ }
555
+
556
+ declare interface ProfileOptions extends SmrtObjectOptions {
557
+ typeId?: string;
558
+ email?: string;
559
+ name?: string;
560
+ description?: string;
561
+ tenantId?: string | null;
562
+ }
563
+
564
+ declare class ProfileRelationship extends SmrtObject {
565
+ tenantId: string | null;
566
+ fromProfileId?: string;
567
+ toProfileId?: string;
568
+ typeId?: string;
569
+ contextProfileId?: string;
570
+ terms: ProfileRelationshipTerm[];
571
+ constructor(options?: ProfileRelationshipOptions);
572
+ /**
573
+ * Get the relationship type slug
574
+ *
575
+ * @returns The slug of the relationship type
576
+ */
577
+ getTypeSlug(): Promise<string>;
578
+ /**
579
+ * Add a term (time period) to this relationship
580
+ *
581
+ * @param startedAt - Start date of the term
582
+ * @param endedAt - Optional end date of the term
583
+ */
584
+ addTerm(startedAt: Date, endedAt?: Date): Promise<void>;
585
+ /**
586
+ * End the current active term
587
+ *
588
+ * @param endedAt - End date for the term
589
+ */
590
+ endCurrentTerm(endedAt: Date): Promise<void>;
591
+ /**
592
+ * Get all terms for this relationship
593
+ *
594
+ * @returns Array of ProfileRelationshipTerm instances
595
+ */
596
+ getTerms(): Promise<ProfileRelationshipTerm[]>;
597
+ /**
598
+ * Get the active term (no end date)
599
+ *
600
+ * @returns Current term or null if none active
601
+ */
602
+ getActiveTerm(): Promise<ProfileRelationshipTerm | null>;
603
+ }
604
+
605
+ declare interface ProfileRelationshipOptions extends SmrtObjectOptions {
606
+ fromProfileId?: string;
607
+ toProfileId?: string;
608
+ typeId?: string;
609
+ contextProfileId?: string;
610
+ tenantId?: string | null;
611
+ }
612
+
613
+ declare class ProfileRelationshipTerm extends SmrtObject {
614
+ relationshipId?: string;
615
+ startedAt: Date;
616
+ endedAt?: Date;
617
+ constructor(options?: ProfileRelationshipTermOptions);
618
+ /**
619
+ * Check if this term is currently active
620
+ *
621
+ * @returns True if active (no end date or end date in future)
622
+ */
623
+ isActive(): boolean;
624
+ /**
625
+ * End this term
626
+ *
627
+ * @param endedAt - End date for the term (defaults to now)
628
+ */
629
+ end(endedAt?: Date): Promise<void>;
630
+ /**
631
+ * Get the duration of this term in days
632
+ *
633
+ * @returns Duration in days
634
+ */
635
+ getDurationDays(): number;
636
+ }
637
+
638
+ declare interface ProfileRelationshipTermOptions extends SmrtObjectOptions {
639
+ relationshipId?: string;
640
+ startedAt?: Date;
641
+ endedAt?: Date;
642
+ }
643
+
4
644
  /**
5
645
  * Handler function interface for reciprocal relationships
6
646
  *
@@ -9,7 +649,7 @@
9
649
  * @param context - Optional context profile for tertiary relationships
10
650
  * @param options - Additional options for the handler
11
651
  */
12
- export declare type ReciprocalHandler = (from: any, to: any, context?: any, options?: any) => Promise<void>;
652
+ export declare type ReciprocalHandler = (from: Profile, to: Profile, context?: Profile, options?: Record<string, unknown>) => Promise<void>;
13
653
 
14
654
  /**
15
655
  * Validation schema structure for profile metadata fields
@@ -36,6 +676,6 @@ export declare interface ValidationSchema {
36
676
  /**
37
677
  * Custom validator function type
38
678
  */
39
- export declare type ValidatorFunction = (value: any) => boolean | Promise<boolean>;
679
+ export declare type ValidatorFunction = (value: unknown) => boolean | Promise<boolean>;
40
680
 
41
681
  export { }