@happyvertical/smrt-profiles 0.54.1 → 0.54.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.
Files changed (65) hide show
  1. package/AGENTS.md +1 -1
  2. package/dist/audit-trail.d.ts +24 -0
  3. package/dist/audit-trail.d.ts.map +1 -0
  4. package/dist/chunks/{ApiKey-BZmbOTnL.js → ApiKey-CVmlf3V6.js} +11 -3
  5. package/dist/chunks/ApiKey-CVmlf3V6.js.map +1 -0
  6. package/dist/chunks/{ApiKeyCollection-Bfb_nw81.js → ApiKeyCollection-CiiDNFdD.js} +3 -3
  7. package/dist/chunks/{ApiKeyCollection-Bfb_nw81.js.map → ApiKeyCollection-CiiDNFdD.js.map} +1 -1
  8. package/dist/chunks/{AuditLogCollection-B1YonCAP.js → AuditLogCollection-WDHL-_AF.js} +30 -12
  9. package/dist/chunks/AuditLogCollection-WDHL-_AF.js.map +1 -0
  10. package/dist/chunks/{NostrIdentity-n70E0vck.js → NostrIdentity-AC8fAdxe.js} +12 -4
  11. package/dist/chunks/{NostrIdentity-n70E0vck.js.map → NostrIdentity-AC8fAdxe.js.map} +1 -1
  12. package/dist/chunks/{NostrIdentityCollection-Ca74dkaL.js → NostrIdentityCollection-CctlECpX.js} +2 -2
  13. package/dist/chunks/{NostrIdentityCollection-Ca74dkaL.js.map → NostrIdentityCollection-CctlECpX.js.map} +1 -1
  14. package/dist/chunks/{OidcIdentity-Cb1bxreM.js → OidcIdentity-BjRu3n1g.js} +11 -3
  15. package/dist/chunks/OidcIdentity-BjRu3n1g.js.map +1 -0
  16. package/dist/chunks/{OidcIdentityCollection-TV8VdK69.js → OidcIdentityCollection-B4jYh36_.js} +3 -3
  17. package/dist/chunks/{OidcIdentityCollection-TV8VdK69.js.map → OidcIdentityCollection-B4jYh36_.js.map} +1 -1
  18. package/dist/chunks/{ProfileAssetCollection-B9hacUJa.js → ProfileAssetCollection-HeMtjBc0.js} +12 -3
  19. package/dist/chunks/ProfileAssetCollection-HeMtjBc0.js.map +1 -0
  20. package/dist/chunks/{ProfileCollection-DuJT7Mum.js → ProfileCollection-Bt6IJK49.js} +49 -25
  21. package/dist/chunks/ProfileCollection-Bt6IJK49.js.map +1 -0
  22. package/dist/chunks/{ProfileLinkCollection-4uNURz32.js → ProfileLinkCollection-u1hhzKTm.js} +11 -3
  23. package/dist/chunks/ProfileLinkCollection-u1hhzKTm.js.map +1 -0
  24. package/dist/chunks/{ProfileMetadataCollection-DQhbfEfa.js → ProfileMetadataCollection-BIYKy4Y3.js} +10 -2
  25. package/dist/chunks/ProfileMetadataCollection-BIYKy4Y3.js.map +1 -0
  26. package/dist/chunks/{ProfileMetafieldCollection-CoBuM_5G.js → ProfileMetafieldCollection-Buz7gzag.js} +10 -2
  27. package/dist/chunks/ProfileMetafieldCollection-Buz7gzag.js.map +1 -0
  28. package/dist/chunks/{ProfileRelationshipCollection-DUVgaIqf.js → ProfileRelationshipCollection-C4g_QLI4.js} +13 -5
  29. package/dist/chunks/ProfileRelationshipCollection-C4g_QLI4.js.map +1 -0
  30. package/dist/chunks/{ProfileRelationshipTermCollection-DtA9OM23.js → ProfileRelationshipTermCollection-C9J7mC7P.js} +10 -2
  31. package/dist/chunks/ProfileRelationshipTermCollection-C9J7mC7P.js.map +1 -0
  32. package/dist/chunks/{ProfileRelationshipType-BRiRka6t.js → ProfileRelationshipType-U7IwF6Wf.js} +10 -2
  33. package/dist/chunks/ProfileRelationshipType-U7IwF6Wf.js.map +1 -0
  34. package/dist/chunks/{ProfileRelationshipTypeCollection-BdXwd7Kf.js → ProfileRelationshipTypeCollection-_n22WqTb.js} +3 -3
  35. package/dist/chunks/{ProfileRelationshipTypeCollection-BdXwd7Kf.js.map → ProfileRelationshipTypeCollection-_n22WqTb.js.map} +1 -1
  36. package/dist/chunks/{oidcProvisioningPrimitives-D9OYu5-F.js → oidcProvisioningPrimitives-CYood-2M.js} +14 -4
  37. package/dist/chunks/{oidcProvisioningPrimitives-D9OYu5-F.js.map → oidcProvisioningPrimitives-CYood-2M.js.map} +1 -1
  38. package/dist/chunks/{resolveIdentity-B-PK6RwU.js → resolveIdentity-CvGDegU6.js} +16 -16
  39. package/dist/chunks/{resolveIdentity-B-PK6RwU.js.map → resolveIdentity-CvGDegU6.js.map} +1 -1
  40. package/dist/collections/AuditLogCollection.d.ts +3 -1
  41. package/dist/collections/AuditLogCollection.d.ts.map +1 -1
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +91 -24
  45. package/dist/index.js.map +1 -1
  46. package/dist/internal/oidc-provisioning.js +2 -2
  47. package/dist/manifest.json +126 -33
  48. package/dist/models/AuditLog.d.ts +9 -1
  49. package/dist/models/AuditLog.d.ts.map +1 -1
  50. package/dist/models/Profile.d.ts +2 -0
  51. package/dist/models/Profile.d.ts.map +1 -1
  52. package/dist/smrt-knowledge.json +62 -366
  53. package/dist/utils.js +4 -4
  54. package/package.json +12 -12
  55. package/dist/chunks/ApiKey-BZmbOTnL.js.map +0 -1
  56. package/dist/chunks/AuditLogCollection-B1YonCAP.js.map +0 -1
  57. package/dist/chunks/OidcIdentity-Cb1bxreM.js.map +0 -1
  58. package/dist/chunks/ProfileAssetCollection-B9hacUJa.js.map +0 -1
  59. package/dist/chunks/ProfileCollection-DuJT7Mum.js.map +0 -1
  60. package/dist/chunks/ProfileLinkCollection-4uNURz32.js.map +0 -1
  61. package/dist/chunks/ProfileMetadataCollection-DQhbfEfa.js.map +0 -1
  62. package/dist/chunks/ProfileMetafieldCollection-CoBuM_5G.js.map +0 -1
  63. package/dist/chunks/ProfileRelationshipCollection-DUVgaIqf.js.map +0 -1
  64. package/dist/chunks/ProfileRelationshipTermCollection-DtA9OM23.js.map +0 -1
  65. package/dist/chunks/ProfileRelationshipType-BRiRka6t.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { c as generateNostrKeypair, s as encryptPrivkey, t as NostrIdentity, y as __exportAll } from "./NostrIdentity-n70E0vck.js";
1
+ import { c as generateNostrKeypair, s as encryptPrivkey, t as NostrIdentity, y as __exportAll } from "./NostrIdentity-AC8fAdxe.js";
2
2
  import { SmrtCollection } from "@happyvertical/smrt-core";
3
3
  //#region src/collections/NostrIdentityCollection.ts
4
4
  var NostrIdentityCollection_exports = /* @__PURE__ */ __exportAll({ NostrIdentityCollection: () => NostrIdentityCollection });
@@ -121,4 +121,4 @@ var NostrIdentityCollection = class extends SmrtCollection {
121
121
  //#endregion
122
122
  export { NostrIdentityCollection_exports as n, NostrIdentityCollection as t };
123
123
 
124
- //# sourceMappingURL=NostrIdentityCollection-Ca74dkaL.js.map
124
+ //# sourceMappingURL=NostrIdentityCollection-CctlECpX.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NostrIdentityCollection-Ca74dkaL.js","names":[],"sources":["../../src/collections/NostrIdentityCollection.ts"],"sourcesContent":["/**\n * NostrIdentityCollection - Collection for managing Nostr identity records\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { encryptPrivkey, generateNostrKeypair } from '../auth/nostrCrypto';\nimport { NostrIdentity } from '../models/NostrIdentity';\nimport type { Profile } from '../models/Profile';\n\nexport interface Nip05Response {\n names: Record<string, string>;\n relays?: Record<string, string[]>;\n}\n\nexport class NostrIdentityCollection extends SmrtCollection<NostrIdentity> {\n static readonly _itemClass = NostrIdentity;\n\n /**\n * Find identities for a profile\n */\n async findByProfile(profileId: string): Promise<NostrIdentity[]> {\n return await this.list({\n where: { profileId },\n });\n }\n\n /**\n * Find identity by public key\n */\n async findByPubkey(pubkey: string): Promise<NostrIdentity | null> {\n return await this.findOne({\n where: { pubkey },\n });\n }\n\n /**\n * Find identity by email\n */\n async findByEmail(email: string): Promise<NostrIdentity | null> {\n return await this.findOne({\n where: { email: email.toLowerCase() },\n });\n }\n\n /**\n * Find identity by NIP-05 username\n */\n async findByNip05(username: string): Promise<NostrIdentity | null> {\n return await this.findOne({\n where: { nip05Username: username.toLowerCase() },\n });\n }\n\n /**\n * Link a new Nostr identity to a profile with a new keypair\n * @param profile - The profile to link to\n * @param email - Email address for this identity\n * @param masterSecret - Server master secret for encryption\n * @param nip05Username - Optional NIP-05 username (defaults to email local part)\n */\n async createForProfile(\n profile: Profile,\n email: string,\n masterSecret: string,\n nip05Username?: string,\n ): Promise<NostrIdentity> {\n const normalizedEmail = email.toLowerCase();\n\n // Check if already exists for this email\n const existing = await this.findByEmail(normalizedEmail);\n if (existing) {\n throw new Error(`Nostr identity already exists for email: ${email}`);\n }\n\n // Generate new keypair\n const keypair = generateNostrKeypair();\n\n // Encrypt private key\n const encrypted = encryptPrivkey(keypair.privkey, masterSecret);\n\n // Derive NIP-05 username from email if not provided\n const username =\n nip05Username?.toLowerCase() || normalizedEmail.split('@')[0];\n\n // Create identity\n const identity = new NostrIdentity({\n ...this.options,\n profileId: profile.id as string,\n pubkey: keypair.pubkey,\n encryptedPrivkey: encrypted.ciphertext,\n encryptionIv: encrypted.iv,\n encryptionTag: encrypted.tag,\n email: normalizedEmail,\n nip05Username: username,\n });\n\n await identity.initialize();\n await identity.save();\n\n return identity;\n }\n\n /**\n * Link an existing Nostr identity (with encrypted keypair) to a profile\n */\n async linkToProfile(\n profile: Profile,\n nostrData: {\n pubkey: string;\n encryptedPrivkey: string;\n encryptionIv: string;\n encryptionTag: string;\n email: string;\n nip05Username?: string;\n },\n ): Promise<NostrIdentity> {\n // Check if pubkey already exists\n const existingPubkey = await this.findByPubkey(nostrData.pubkey);\n if (existingPubkey) {\n throw new Error('Nostr identity with this public key already exists');\n }\n\n // Check if email already exists\n const existingEmail = await this.findByEmail(nostrData.email);\n if (existingEmail) {\n throw new Error('Nostr identity with this email already exists');\n }\n\n const identity = new NostrIdentity({\n ...this.options,\n profileId: profile.id as string,\n pubkey: nostrData.pubkey,\n encryptedPrivkey: nostrData.encryptedPrivkey,\n encryptionIv: nostrData.encryptionIv,\n encryptionTag: nostrData.encryptionTag,\n email: nostrData.email.toLowerCase(),\n nip05Username:\n nostrData.nip05Username?.toLowerCase() ||\n nostrData.email.toLowerCase().split('@')[0],\n });\n\n await identity.initialize();\n await identity.save();\n\n return identity;\n }\n\n /**\n * Unlink a Nostr identity from a profile\n */\n async unlinkFromProfile(profileId: string, pubkey: string): Promise<boolean> {\n const identity = await this.findOne({\n where: { profileId, pubkey },\n });\n\n if (identity) {\n await identity.delete();\n return true;\n }\n return false;\n }\n\n /**\n * Get NIP-05 response data for the /.well-known/nostr.json endpoint\n * @param username - Optional username filter, returns all if not provided\n */\n async getNip05Response(username?: string): Promise<Nip05Response> {\n const where = username ? { nip05Username: username.toLowerCase() } : {};\n\n const identities = await this.list({\n where,\n // Only return verified identities for NIP-05\n // Uncomment if you want to require verification:\n // where: { ...where, 'verifiedAt IS NOT': null },\n });\n\n const names: Record<string, string> = {};\n for (const identity of identities) {\n if (identity.nip05Username && identity.pubkey) {\n names[identity.nip05Username] = identity.pubkey;\n }\n }\n\n return { names };\n }\n\n /**\n * Check if a NIP-05 username is available\n */\n async isNip05Available(username: string): Promise<boolean> {\n const existing = await this.findByNip05(username);\n return existing === null;\n }\n\n /**\n * Update NIP-05 username for an identity\n */\n async updateNip05Username(\n identity: NostrIdentity,\n newUsername: string,\n ): Promise<NostrIdentity> {\n const normalizedUsername = newUsername.toLowerCase();\n\n // Check if username is available\n const existing = await this.findByNip05(normalizedUsername);\n if (existing && existing.id !== identity.id) {\n throw new Error(`NIP-05 username \"${newUsername}\" is already taken`);\n }\n\n identity.nip05Username = normalizedUsername;\n await identity.save();\n\n return identity;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"NostrIdentityCollection-CctlECpX.js","names":[],"sources":["../../src/collections/NostrIdentityCollection.ts"],"sourcesContent":["/**\n * NostrIdentityCollection - Collection for managing Nostr identity records\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { encryptPrivkey, generateNostrKeypair } from '../auth/nostrCrypto';\nimport { NostrIdentity } from '../models/NostrIdentity';\nimport type { Profile } from '../models/Profile';\n\nexport interface Nip05Response {\n names: Record<string, string>;\n relays?: Record<string, string[]>;\n}\n\nexport class NostrIdentityCollection extends SmrtCollection<NostrIdentity> {\n static readonly _itemClass = NostrIdentity;\n\n /**\n * Find identities for a profile\n */\n async findByProfile(profileId: string): Promise<NostrIdentity[]> {\n return await this.list({\n where: { profileId },\n });\n }\n\n /**\n * Find identity by public key\n */\n async findByPubkey(pubkey: string): Promise<NostrIdentity | null> {\n return await this.findOne({\n where: { pubkey },\n });\n }\n\n /**\n * Find identity by email\n */\n async findByEmail(email: string): Promise<NostrIdentity | null> {\n return await this.findOne({\n where: { email: email.toLowerCase() },\n });\n }\n\n /**\n * Find identity by NIP-05 username\n */\n async findByNip05(username: string): Promise<NostrIdentity | null> {\n return await this.findOne({\n where: { nip05Username: username.toLowerCase() },\n });\n }\n\n /**\n * Link a new Nostr identity to a profile with a new keypair\n * @param profile - The profile to link to\n * @param email - Email address for this identity\n * @param masterSecret - Server master secret for encryption\n * @param nip05Username - Optional NIP-05 username (defaults to email local part)\n */\n async createForProfile(\n profile: Profile,\n email: string,\n masterSecret: string,\n nip05Username?: string,\n ): Promise<NostrIdentity> {\n const normalizedEmail = email.toLowerCase();\n\n // Check if already exists for this email\n const existing = await this.findByEmail(normalizedEmail);\n if (existing) {\n throw new Error(`Nostr identity already exists for email: ${email}`);\n }\n\n // Generate new keypair\n const keypair = generateNostrKeypair();\n\n // Encrypt private key\n const encrypted = encryptPrivkey(keypair.privkey, masterSecret);\n\n // Derive NIP-05 username from email if not provided\n const username =\n nip05Username?.toLowerCase() || normalizedEmail.split('@')[0];\n\n // Create identity\n const identity = new NostrIdentity({\n ...this.options,\n profileId: profile.id as string,\n pubkey: keypair.pubkey,\n encryptedPrivkey: encrypted.ciphertext,\n encryptionIv: encrypted.iv,\n encryptionTag: encrypted.tag,\n email: normalizedEmail,\n nip05Username: username,\n });\n\n await identity.initialize();\n await identity.save();\n\n return identity;\n }\n\n /**\n * Link an existing Nostr identity (with encrypted keypair) to a profile\n */\n async linkToProfile(\n profile: Profile,\n nostrData: {\n pubkey: string;\n encryptedPrivkey: string;\n encryptionIv: string;\n encryptionTag: string;\n email: string;\n nip05Username?: string;\n },\n ): Promise<NostrIdentity> {\n // Check if pubkey already exists\n const existingPubkey = await this.findByPubkey(nostrData.pubkey);\n if (existingPubkey) {\n throw new Error('Nostr identity with this public key already exists');\n }\n\n // Check if email already exists\n const existingEmail = await this.findByEmail(nostrData.email);\n if (existingEmail) {\n throw new Error('Nostr identity with this email already exists');\n }\n\n const identity = new NostrIdentity({\n ...this.options,\n profileId: profile.id as string,\n pubkey: nostrData.pubkey,\n encryptedPrivkey: nostrData.encryptedPrivkey,\n encryptionIv: nostrData.encryptionIv,\n encryptionTag: nostrData.encryptionTag,\n email: nostrData.email.toLowerCase(),\n nip05Username:\n nostrData.nip05Username?.toLowerCase() ||\n nostrData.email.toLowerCase().split('@')[0],\n });\n\n await identity.initialize();\n await identity.save();\n\n return identity;\n }\n\n /**\n * Unlink a Nostr identity from a profile\n */\n async unlinkFromProfile(profileId: string, pubkey: string): Promise<boolean> {\n const identity = await this.findOne({\n where: { profileId, pubkey },\n });\n\n if (identity) {\n await identity.delete();\n return true;\n }\n return false;\n }\n\n /**\n * Get NIP-05 response data for the /.well-known/nostr.json endpoint\n * @param username - Optional username filter, returns all if not provided\n */\n async getNip05Response(username?: string): Promise<Nip05Response> {\n const where = username ? { nip05Username: username.toLowerCase() } : {};\n\n const identities = await this.list({\n where,\n // Only return verified identities for NIP-05\n // Uncomment if you want to require verification:\n // where: { ...where, 'verifiedAt IS NOT': null },\n });\n\n const names: Record<string, string> = {};\n for (const identity of identities) {\n if (identity.nip05Username && identity.pubkey) {\n names[identity.nip05Username] = identity.pubkey;\n }\n }\n\n return { names };\n }\n\n /**\n * Check if a NIP-05 username is available\n */\n async isNip05Available(username: string): Promise<boolean> {\n const existing = await this.findByNip05(username);\n return existing === null;\n }\n\n /**\n * Update NIP-05 username for an identity\n */\n async updateNip05Username(\n identity: NostrIdentity,\n newUsername: string,\n ): Promise<NostrIdentity> {\n const normalizedUsername = newUsername.toLowerCase();\n\n // Check if username is available\n const existing = await this.findByNip05(normalizedUsername);\n if (existing && existing.id !== identity.id) {\n throw new Error(`NIP-05 username \"${newUsername}\" is already taken`);\n }\n\n identity.nip05Username = normalizedUsername;\n await identity.save();\n\n return identity;\n }\n}\n"],"mappings":"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"}
@@ -2,12 +2,19 @@ import { SmrtObject, field, foreignKey, smrt } from "@happyvertical/smrt-core";
2
2
  //#region src/models/OidcIdentity.ts
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true,
9
+ value
10
+ }) : obj[key] = value;
5
11
  var __decorateClass = (decorators, target, key, kind) => {
6
12
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
7
13
  for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
14
  if (kind && result) __defProp(target, key, result);
9
15
  return result;
10
16
  };
17
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
11
18
  var OidcIdentity = class extends SmrtObject {
12
19
  profileId;
13
20
  provider = "";
@@ -35,7 +42,7 @@ var OidcIdentity = class extends SmrtObject {
35
42
  * Find identity by issuer and subject
36
43
  */
37
44
  static async findBySubject(issuer, subject, options = {}) {
38
- const { OidcIdentityCollection } = await import("./OidcIdentityCollection-TV8VdK69.js").then((n) => n.r);
45
+ const { OidcIdentityCollection } = await import("./OidcIdentityCollection-B4jYh36_.js").then((n) => n.r);
39
46
  return await (await OidcIdentityCollection.create(options)).findBySubject(issuer, subject);
40
47
  }
41
48
  /** Build the collision-free natural key for one OIDC issuer subject. */
@@ -58,7 +65,7 @@ var OidcIdentity = class extends SmrtObject {
58
65
  static async findOrCreate(profile, oidcData, options = {}) {
59
66
  const profileId = profile.id;
60
67
  if (typeof profileId !== "string" || !profileId) throw new Error("OidcIdentity.findOrCreate() requires a saved Profile.");
61
- const { reuseExistingOidcIdentityForProfile } = await import("./resolveIdentity-B-PK6RwU.js").then((n) => n.i);
68
+ const { reuseExistingOidcIdentityForProfile } = await import("./resolveIdentity-CvGDegU6.js").then((n) => n.i);
62
69
  const profileOptions = profile.options ?? {};
63
70
  return (await reuseExistingOidcIdentityForProfile(profileId, {
64
71
  email: oidcData.email,
@@ -86,6 +93,7 @@ var OidcIdentity = class extends SmrtObject {
86
93
  }
87
94
  }
88
95
  };
96
+ __publicField(OidcIdentity, "__smrtPackage__", "@happyvertical/smrt-profiles");
89
97
  __decorateClass([foreignKey("Profile", { required: true })], OidcIdentity.prototype, "profileId", 2);
90
98
  __decorateClass([field({ type: "text" })], OidcIdentity.prototype, "provider", 2);
91
99
  __decorateClass([field({
@@ -116,4 +124,4 @@ OidcIdentity = __decorateClass([smrt({
116
124
  //#endregion
117
125
  export { OidcIdentity as t };
118
126
 
119
- //# sourceMappingURL=OidcIdentity-Cb1bxreM.js.map
127
+ //# sourceMappingURL=OidcIdentity-BjRu3n1g.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OidcIdentity-BjRu3n1g.js","names":[],"sources":["../../src/models/OidcIdentity.ts"],"sourcesContent":["/**\n * OidcIdentity - Links OIDC provider identities to Profile\n *\n * Stores the mapping between external OIDC providers (Keycloak, Google, GitHub)\n * and internal Profile records. Multiple identities can link to a single profile.\n */\n\nimport {\n field,\n foreignKey,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport type { Profile } from './Profile';\n\nexport interface OidcIdentityOptions extends SmrtObjectOptions {\n profileId?: string;\n provider?: string;\n issuer?: string;\n subject?: string;\n email?: string;\n lastUsedAt?: Date | null;\n}\n\n@smrt({\n tableName: 'oidc_identities',\n // Identity linking is an authentication authority change. Generated routes\n // authenticate callers but do not authorize Profile ownership, so mutations\n // must stay behind the trusted provisioning APIs below.\n api: { include: ['list', 'get'] },\n mcp: { include: ['list', 'get'] },\n cli: { include: ['list', 'get'] },\n})\nexport class OidcIdentity extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-profiles\";\n /**\n * Link to the Profile (Person, Organization, Bot)\n */\n @foreignKey('Profile', { required: true })\n profileId?: string;\n\n /**\n * Provider name (e.g., 'keycloak', 'google', 'github')\n */\n @field({ type: 'text' })\n provider: string = '';\n\n /**\n * OIDC issuer URL (e.g., https://keycloak.example.com/realms/bmp)\n */\n @field({ type: 'text', indexed: true })\n issuer: string = '';\n\n /**\n * OIDC subject claim - unique identifier from the provider\n */\n @field({ type: 'text', indexed: true })\n subject: string = '';\n\n /**\n * Stable issuer+subject key used as the database race arbiter.\n *\n * Nullable for legacy rows; every newly linked or reused identity backfills\n * it. A separate unique constraint makes concurrent first login fail with a\n * retryable conflict instead of creating two identities.\n */\n @field({ type: 'text', nullable: true, unique: true, readonly: true })\n identityKey: string | null = null;\n\n /**\n * Cached email from the IdP (for display/lookup)\n */\n @field({ type: 'text' })\n email: string = '';\n\n /**\n * Last time this identity was used for authentication\n */\n @field({ type: 'datetime', nullable: true })\n lastUsedAt: Date | null = null;\n\n constructor(options: OidcIdentityOptions = {}) {\n super(options);\n if (options.profileId) this.profileId = options.profileId;\n if (options.provider) this.provider = options.provider;\n if (options.issuer) this.issuer = options.issuer;\n if (options.subject) this.subject = options.subject;\n if (options.email) this.email = options.email;\n if (options.lastUsedAt !== undefined) this.lastUsedAt = options.lastUsedAt;\n }\n\n /**\n * Get the linked Profile\n */\n async getProfile(): Promise<Profile | null> {\n return (await this.getRelated('profileId')) as Profile | null;\n }\n\n /**\n * Find identity by issuer and subject\n */\n static async findBySubject(\n issuer: string,\n subject: string,\n options: SmrtObjectOptions = {},\n ): Promise<OidcIdentity | null> {\n const { OidcIdentityCollection } = await import(\n '../collections/OidcIdentityCollection'\n );\n const collection = await OidcIdentityCollection.create(options);\n return await collection.findBySubject(issuer, subject);\n }\n\n /** Build the collision-free natural key for one OIDC issuer subject. */\n static buildIdentityKey(issuer: string, subject: string): string {\n return JSON.stringify([issuer, subject]);\n }\n\n /** Keep the durable key derived from its natural-key source fields. */\n override async save(): Promise<this> {\n this.identityKey =\n this.issuer.trim() && this.subject.trim()\n ? OidcIdentity.buildIdentityKey(this.issuer, this.subject)\n : null;\n return super.save();\n }\n\n /**\n * Reuse an existing exact identity for its unchanged Profile.\n *\n * @deprecated Authentication links must be created through transactional\n * provisioning. This compatibility method only refreshes a unique mapping\n * that already belongs to the supplied Profile, including legacy Profile\n * types, and deliberately refuses to create or rebind authority.\n */\n static async findOrCreate(\n profile: Profile,\n oidcData: {\n provider: string;\n issuer: string;\n subject: string;\n email?: string;\n },\n options: SmrtObjectOptions = {},\n ): Promise<OidcIdentity> {\n const profileId = profile.id;\n if (typeof profileId !== 'string' || !profileId) {\n throw new Error('OidcIdentity.findOrCreate() requires a saved Profile.');\n }\n const { reuseExistingOidcIdentityForProfile } = await import(\n '../auth/resolveIdentity'\n );\n const profileOptions = profile.options ?? {};\n const result = await reuseExistingOidcIdentityForProfile(\n profileId,\n {\n email: oidcData.email,\n iss: oidcData.issuer,\n sub: oidcData.subject,\n },\n oidcData.provider,\n {\n ...profileOptions,\n ...options,\n db: options.db ?? profileOptions.db,\n },\n );\n return result.oidcIdentity;\n }\n\n /**\n * Record usage of this identity\n */\n async recordUsage(): Promise<void> {\n // Trusted provisioning or another authentication may refresh this exact\n // identity through a second instance. Rehydrate before each bounded attempt\n // so this usage-only write preserves those changes while retaining CAS.\n for (let attempt = 0; attempt < 4; attempt += 1) {\n await this.loadFromId();\n this.lastUsedAt = new Date();\n try {\n await this.save();\n return;\n } catch (error) {\n if (\n attempt === 3 ||\n !(\n error instanceof Error &&\n 'code' in error &&\n error.code === 'RUNTIME_REVISION_CONFLICT'\n )\n ) {\n throw error;\n }\n }\n }\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { y as __exportAll } from "./NostrIdentity-n70E0vck.js";
2
- import { t as OidcIdentity } from "./OidcIdentity-Cb1bxreM.js";
1
+ import { y as __exportAll } from "./NostrIdentity-AC8fAdxe.js";
2
+ import { t as OidcIdentity } from "./OidcIdentity-BjRu3n1g.js";
3
3
  import { SmrtCollection } from "@happyvertical/smrt-core";
4
4
  //#region src/collections/OidcIdentityCollection.ts
5
5
  var OidcIdentityCollection_exports = /* @__PURE__ */ __exportAll({
@@ -79,4 +79,4 @@ var OidcIdentityCollection = class extends SmrtCollection {
79
79
  //#endregion
80
80
  export { OidcIdentityCollection as n, OidcIdentityCollection_exports as r, AmbiguousOidcIdentityError as t };
81
81
 
82
- //# sourceMappingURL=OidcIdentityCollection-TV8VdK69.js.map
82
+ //# sourceMappingURL=OidcIdentityCollection-B4jYh36_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OidcIdentityCollection-TV8VdK69.js","names":[],"sources":["../../src/collections/OidcIdentityCollection.ts"],"sourcesContent":["/**\n * OidcIdentityCollection - Collection for managing OIDC identity records\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { OidcIdentity } from '../models/OidcIdentity';\nimport type { Profile } from '../models/Profile';\n\n/** More than one legacy row maps the same opaque OIDC issuer and subject. */\nexport class AmbiguousOidcIdentityError extends Error {\n constructor(\n readonly issuer: string,\n readonly subject: string,\n ) {\n super('Multiple OIDC identities match the same issuer and subject.');\n this.name = 'AmbiguousOidcIdentityError';\n }\n}\n\nexport class OidcIdentityCollection extends SmrtCollection<OidcIdentity> {\n static readonly _itemClass = OidcIdentity;\n\n /**\n * Find identities for a profile\n */\n async findByProfile(profileId: string): Promise<OidcIdentity[]> {\n return await this.list({\n where: { profileId },\n });\n }\n\n /**\n * Find identity by issuer and subject\n */\n async findBySubject(\n issuer: string,\n subject: string,\n ): Promise<OidcIdentity | null> {\n const result = await this.db.query(\n `SELECT CAST(id AS VARCHAR) AS id,\n CAST(profile_id AS VARCHAR) AS profile_id\n FROM oidc_identities\n WHERE issuer = ? AND subject = ?\n LIMIT 2`,\n issuer,\n subject,\n );\n if (result.rows.length > 1) {\n throw new AmbiguousOidcIdentityError(issuer, subject);\n }\n const row = result.rows[0];\n const id = row?.id;\n const profileId = row?.profile_id;\n if (typeof id !== 'string' || typeof profileId !== 'string') return null;\n const identity = await this.get({ id });\n if (!identity) return null;\n // Preserve portable identities at this authentication boundary when\n // native DuckDB exposes UUID results through internal objects.\n identity.id = id;\n identity.profileId = profileId;\n return identity;\n }\n\n /**\n * Find identities by provider\n */\n async findByProvider(provider: string): Promise<OidcIdentity[]> {\n return await this.list({\n where: { provider },\n });\n }\n\n /**\n * Reuse an existing exact OIDC identity for its unchanged Profile.\n *\n * @deprecated New authentication links require the owner-aware,\n * transactional provisioning APIs. This compatibility helper may refresh a\n * legacy Profile type, but refuses to create or rebind authority.\n */\n async linkToProfile(\n profile: Profile,\n oidcData: {\n provider: string;\n issuer: string;\n subject: string;\n email?: string;\n },\n ): Promise<OidcIdentity> {\n return OidcIdentity.findOrCreate(profile, oidcData, this.options);\n }\n\n /**\n * Unlink an OIDC identity from a profile\n */\n async unlinkFromProfile(\n profileId: string,\n issuer: string,\n subject: string,\n ): Promise<boolean> {\n const identity = await this.findOne({\n where: { profileId, issuer, subject },\n });\n\n if (identity) {\n await identity.delete();\n return true;\n }\n return false;\n }\n}\n"],"mappings":";;;;;;;;AASO,IAAM,6BAAN,cAAyC,MAAM;CACpD,YACW,QACA,SACT;EACA,MAAM,6DAA6D;EAH1D,KAAA,SAAA;EACA,KAAA,UAAA;EAGT,KAAK,OAAO;CACd;CALW;CACA;AAKb;AAEO,IAAM,yBAAN,cAAqC,eAA6B;CACvE,OAAgB,aAAa;;;;CAK7B,MAAM,cAAc,WAA4C;EAC9D,OAAO,MAAM,KAAK,KAAK,EACrB,OAAO,EAAE,UAAU,EACrB,CAAC;CACH;;;;CAKA,MAAM,cACJ,QACA,SAC8B;EAC9B,MAAM,SAAS,MAAM,KAAK,GAAG,MAC3B;;;;kBAKA,QACA,OACF;EACA,IAAI,OAAO,KAAK,SAAS,GACvB,MAAM,IAAI,2BAA2B,QAAQ,OAAO;EAEtD,MAAM,MAAM,OAAO,KAAK;EACxB,MAAM,KAAK,KAAK;EAChB,MAAM,YAAY,KAAK;EACvB,IAAI,OAAO,OAAO,YAAY,OAAO,cAAc,UAAU,OAAO;EACpE,MAAM,WAAW,MAAM,KAAK,IAAI,EAAE,GAAG,CAAC;EACtC,IAAI,CAAC,UAAU,OAAO;EAGtB,SAAS,KAAK;EACd,SAAS,YAAY;EACrB,OAAO;CACT;;;;CAKA,MAAM,eAAe,UAA2C;EAC9D,OAAO,MAAM,KAAK,KAAK,EACrB,OAAO,EAAE,SAAS,EACpB,CAAC;CACH;;;;;;;;CASA,MAAM,cACJ,SACA,UAMuB;EACvB,OAAO,aAAa,aAAa,SAAS,UAAU,KAAK,OAAO;CAClE;;;;CAKA,MAAM,kBACJ,WACA,QACA,SACkB;EAClB,MAAM,WAAW,MAAM,KAAK,QAAQ,EAClC,OAAO;GAAE;GAAW;GAAQ;EAAQ,EACtC,CAAC;EAED,IAAI,UAAU;GACZ,MAAM,SAAS,OAAO;GACtB,OAAO;EACT;EACA,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"OidcIdentityCollection-B4jYh36_.js","names":[],"sources":["../../src/collections/OidcIdentityCollection.ts"],"sourcesContent":["/**\n * OidcIdentityCollection - Collection for managing OIDC identity records\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { OidcIdentity } from '../models/OidcIdentity';\nimport type { Profile } from '../models/Profile';\n\n/** More than one legacy row maps the same opaque OIDC issuer and subject. */\nexport class AmbiguousOidcIdentityError extends Error {\n constructor(\n readonly issuer: string,\n readonly subject: string,\n ) {\n super('Multiple OIDC identities match the same issuer and subject.');\n this.name = 'AmbiguousOidcIdentityError';\n }\n}\n\nexport class OidcIdentityCollection extends SmrtCollection<OidcIdentity> {\n static readonly _itemClass = OidcIdentity;\n\n /**\n * Find identities for a profile\n */\n async findByProfile(profileId: string): Promise<OidcIdentity[]> {\n return await this.list({\n where: { profileId },\n });\n }\n\n /**\n * Find identity by issuer and subject\n */\n async findBySubject(\n issuer: string,\n subject: string,\n ): Promise<OidcIdentity | null> {\n const result = await this.db.query(\n `SELECT CAST(id AS VARCHAR) AS id,\n CAST(profile_id AS VARCHAR) AS profile_id\n FROM oidc_identities\n WHERE issuer = ? AND subject = ?\n LIMIT 2`,\n issuer,\n subject,\n );\n if (result.rows.length > 1) {\n throw new AmbiguousOidcIdentityError(issuer, subject);\n }\n const row = result.rows[0];\n const id = row?.id;\n const profileId = row?.profile_id;\n if (typeof id !== 'string' || typeof profileId !== 'string') return null;\n const identity = await this.get({ id });\n if (!identity) return null;\n // Preserve portable identities at this authentication boundary when\n // native DuckDB exposes UUID results through internal objects.\n identity.id = id;\n identity.profileId = profileId;\n return identity;\n }\n\n /**\n * Find identities by provider\n */\n async findByProvider(provider: string): Promise<OidcIdentity[]> {\n return await this.list({\n where: { provider },\n });\n }\n\n /**\n * Reuse an existing exact OIDC identity for its unchanged Profile.\n *\n * @deprecated New authentication links require the owner-aware,\n * transactional provisioning APIs. This compatibility helper may refresh a\n * legacy Profile type, but refuses to create or rebind authority.\n */\n async linkToProfile(\n profile: Profile,\n oidcData: {\n provider: string;\n issuer: string;\n subject: string;\n email?: string;\n },\n ): Promise<OidcIdentity> {\n return OidcIdentity.findOrCreate(profile, oidcData, this.options);\n }\n\n /**\n * Unlink an OIDC identity from a profile\n */\n async unlinkFromProfile(\n profileId: string,\n issuer: string,\n subject: string,\n ): Promise<boolean> {\n const identity = await this.findOne({\n where: { profileId, issuer, subject },\n });\n\n if (identity) {\n await identity.delete();\n return true;\n }\n return false;\n }\n}\n"],"mappings":";;;;;;;;AASO,IAAM,6BAAN,cAAyC,MAAM;CACpD,YACW,QACA,SACT;EACA,MAAM,6DAA6D;EAH1D,KAAA,SAAA;EACA,KAAA,UAAA;EAGT,KAAK,OAAO;CACd;CALW;CACA;AAKb;AAEO,IAAM,yBAAN,cAAqC,eAA6B;CACvE,OAAgB,aAAa;;;;CAK7B,MAAM,cAAc,WAA4C;EAC9D,OAAO,MAAM,KAAK,KAAK,EACrB,OAAO,EAAE,UAAU,EACrB,CAAC;CACH;;;;CAKA,MAAM,cACJ,QACA,SAC8B;EAC9B,MAAM,SAAS,MAAM,KAAK,GAAG,MAC3B;;;;kBAKA,QACA,OACF;EACA,IAAI,OAAO,KAAK,SAAS,GACvB,MAAM,IAAI,2BAA2B,QAAQ,OAAO;EAEtD,MAAM,MAAM,OAAO,KAAK;EACxB,MAAM,KAAK,KAAK;EAChB,MAAM,YAAY,KAAK;EACvB,IAAI,OAAO,OAAO,YAAY,OAAO,cAAc,UAAU,OAAO;EACpE,MAAM,WAAW,MAAM,KAAK,IAAI,EAAE,GAAG,CAAC;EACtC,IAAI,CAAC,UAAU,OAAO;EAGtB,SAAS,KAAK;EACd,SAAS,YAAY;EACrB,OAAO;CACT;;;;CAKA,MAAM,eAAe,UAA2C;EAC9D,OAAO,MAAM,KAAK,KAAK,EACrB,OAAO,EAAE,SAAS,EACpB,CAAC;CACH;;;;;;;;CASA,MAAM,cACJ,SACA,UAMuB;EACvB,OAAO,aAAa,aAAa,SAAS,UAAU,KAAK,OAAO;CAClE;;;;CAKA,MAAM,kBACJ,WACA,QACA,SACkB;EAClB,MAAM,WAAW,MAAM,KAAK,QAAQ,EAClC,OAAO;GAAE;GAAW;GAAQ;EAAQ,EACtC,CAAC;EAED,IAAI,UAAU;GACZ,MAAM,SAAS,OAAO;GACtB,OAAO;EACT;EACA,OAAO;CACT;AACF"}
@@ -1,16 +1,23 @@
1
- import { y as __exportAll } from "./NostrIdentity-n70E0vck.js";
1
+ import { y as __exportAll } from "./NostrIdentity-AC8fAdxe.js";
2
2
  import { SmrtJunction, SmrtObject, crossPackageRef, field, foreignKey, smrt } from "@happyvertical/smrt-core";
3
3
  import { TenantScoped, tenantId } from "@happyvertical/smrt-tenancy";
4
4
  import { addOwnedAssetFromCollection, getOwnedAssetsFromCollection, removeOwnedAssetFromCollection } from "@happyvertical/smrt-assets";
5
5
  //#region src/models/ProfileAsset.ts
6
6
  var __defProp$1 = Object.defineProperty;
7
7
  var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
8
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true,
12
+ value
13
+ }) : obj[key] = value;
8
14
  var __decorateClass$1 = (decorators, target, key, kind) => {
9
15
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
10
16
  for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
11
17
  if (kind && result) __defProp$1(target, key, result);
12
18
  return result;
13
19
  };
20
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
14
21
  var ProfileAsset = class extends SmrtObject {
15
22
  tenantId = null;
16
23
  profileId = "";
@@ -26,6 +33,7 @@ var ProfileAsset = class extends SmrtObject {
26
33
  if (options.tenantId !== void 0) this.tenantId = options.tenantId;
27
34
  }
28
35
  };
36
+ __publicField$1(ProfileAsset, "__smrtPackage__", "@happyvertical/smrt-profiles");
29
37
  __decorateClass$1([tenantId({ nullable: true })], ProfileAsset.prototype, "tenantId", 2);
30
38
  __decorateClass$1([foreignKey("Profile", {
31
39
  required: true,
@@ -72,7 +80,7 @@ var ProfileAssetCollection = class extends SmrtJunction {
72
80
  profileCollectionPromise = null;
73
81
  async getProfileCollection() {
74
82
  if (!this.profileCollectionPromise) {
75
- const { ProfileCollection } = await import("./ProfileCollection-DuJT7Mum.js").then((n) => n.r);
83
+ const { ProfileCollection } = await import("./ProfileCollection-Bt6IJK49.js").then((n) => n.r);
76
84
  this.profileCollectionPromise = ProfileCollection.create({ db: this.db });
77
85
  }
78
86
  return this.profileCollectionPromise;
@@ -87,6 +95,7 @@ var ProfileAssetCollection = class extends SmrtJunction {
87
95
  await removeOwnedAssetFromCollection(await this.getProfileCollection(), "Profile", profileId, assetId, relationship);
88
96
  }
89
97
  };
98
+ __publicField(ProfileAssetCollection, "__smrtPackage__", "@happyvertical/smrt-profiles");
90
99
  __publicField(ProfileAssetCollection, "_itemClass", ProfileAsset);
91
100
  ProfileAssetCollection = __decorateClass([smrt({
92
101
  api: false,
@@ -96,4 +105,4 @@ ProfileAssetCollection = __decorateClass([smrt({
96
105
  //#endregion
97
106
  export { ProfileAssetCollection_exports as n, ProfileAsset as r, ProfileAssetCollection as t };
98
107
 
99
- //# sourceMappingURL=ProfileAssetCollection-B9hacUJa.js.map
108
+ //# sourceMappingURL=ProfileAssetCollection-HeMtjBc0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProfileAssetCollection-HeMtjBc0.js","names":[],"sources":["../../src/models/ProfileAsset.ts","../../src/collections/ProfileAssetCollection.ts"],"sourcesContent":["import type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\n\nexport interface ProfileAssetOptions extends SmrtObjectOptions {\n profileId?: string;\n assetId?: string;\n relationship?: string;\n sortOrder?: number;\n tenantId?: string | null;\n}\n\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableName: 'profile_assets',\n conflictColumns: ['profile_id', 'asset_id', 'relationship'],\n api: false,\n mcp: false,\n cli: false,\n})\nexport class ProfileAsset extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-profiles\";\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n @foreignKey('Profile', { required: true, onDelete: 'CASCADE' })\n profileId = '';\n\n @crossPackageRef('@happyvertical/smrt-assets:Asset', {\n required: true,\n onDelete: 'CASCADE',\n })\n assetId = '';\n\n @field({ required: true })\n relationship = 'attachment';\n\n @field()\n sortOrder = 0;\n\n constructor(options: ProfileAssetOptions = {}) {\n super(options);\n if (options.profileId) this.profileId = options.profileId;\n if (options.assetId) this.assetId = options.assetId;\n if (options.relationship) this.relationship = options.relationship;\n if (options.sortOrder !== undefined) this.sortOrder = options.sortOrder;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n}\n","import type { Asset } from '@happyvertical/smrt-assets';\nimport {\n addOwnedAssetFromCollection,\n getOwnedAssetsFromCollection,\n removeOwnedAssetFromCollection,\n} from '@happyvertical/smrt-assets';\nimport type { SmrtCollectionOptions } from '@happyvertical/smrt-core';\nimport { SmrtJunction, smrt } from '@happyvertical/smrt-core';\nimport { ProfileAsset } from '../models/ProfileAsset';\nimport type { ProfileCollection } from './ProfileCollection';\n\nexport interface ProfileAssetCollectionOptions extends SmrtCollectionOptions {}\n\n@smrt({\n api: false,\n mcp: false,\n cli: false,\n})\nexport class ProfileAssetCollection extends SmrtJunction<ProfileAsset> { static __smrtPackage__ = \"@happyvertical/smrt-profiles\";\n static readonly _itemClass = ProfileAsset;\n protected leftField = 'profileId';\n protected rightField = 'assetId';\n\n private profileCollectionPromise: Promise<ProfileCollection> | null = null;\n\n private async getProfileCollection(): Promise<ProfileCollection> {\n if (!this.profileCollectionPromise) {\n const { ProfileCollection } = await import('./ProfileCollection');\n this.profileCollectionPromise = ProfileCollection.create({ db: this.db });\n }\n\n return this.profileCollectionPromise;\n }\n\n async getAssets(profileId: string, relationship?: string): Promise<Asset[]> {\n return getOwnedAssetsFromCollection(\n await this.getProfileCollection(),\n profileId,\n relationship,\n );\n }\n\n async addAsset(\n profileId: string,\n asset: Asset,\n relationship = 'attachment',\n sortOrder = 0,\n ): Promise<void> {\n await addOwnedAssetFromCollection(\n await this.getProfileCollection(),\n 'Profile',\n profileId,\n asset,\n relationship,\n sortOrder,\n );\n }\n\n async removeAsset(\n profileId: string,\n assetId: string,\n relationship?: string,\n ): Promise<void> {\n await removeOwnedAssetFromCollection(\n await this.getProfileCollection(),\n 'Profile',\n profileId,\n assetId,\n relationship,\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA0BO,IAAM,eAAN,cAA2B,WAAW;CAE3C,WAA0B;CAG1B,YAAY;CAMZ,UAAU;CAGV,eAAe;CAGf,YAAY;CAEZ,YAAY,UAA+B,CAAC,GAAG;EAC7C,MAAM,OAAO;EACb,IAAI,QAAQ,WAAW,KAAK,YAAY,QAAQ;EAChD,IAAI,QAAQ,SAAS,KAAK,UAAU,QAAQ;EAC5C,IAAI,QAAQ,cAAc,KAAK,eAAe,QAAQ;EACtD,IAAI,QAAQ,cAAc,KAAA,GAAW,KAAK,YAAY,QAAQ;EAC9D,IAAI,QAAQ,aAAa,KAAA,GAAW,KAAK,WAAW,QAAQ;CAC9D;AACF;AA3B+C,gBAAlC,cAAyC,mBAAkB,8BAAA;AAEtE,kBAAA,CADC,SAAS,EAAE,UAAU,KAAK,CAAC,CAAA,GADjB,aAEX,WAAA,YAAA,CAAA;AAGA,kBAAA,CADC,WAAW,WAAW;CAAE,UAAU;CAAM,UAAU;AAAU,CAAC,CAAA,GAJnD,aAKX,WAAA,aAAA,CAAA;AAMA,kBAAA,CAJC,gBAAgB,oCAAoC;CACnD,UAAU;CACV,UAAU;AACZ,CAAC,CAAA,GAVU,aAWX,WAAA,WAAA,CAAA;AAGA,kBAAA,CADC,MAAM,EAAE,UAAU,KAAK,CAAC,CAAA,GAbd,aAcX,WAAA,gBAAA,CAAA;AAGA,kBAAA,CADC,MAAM,CAAA,GAhBI,aAiBX,WAAA,aAAA,CAAA;AAjBW,eAAN,kBAAA,CARN,aAAa,EAAE,MAAM,WAAW,CAAC,GACjC,KAAK;CACJ,WAAW;CACX,iBAAiB;EAAC;EAAc;EAAY;CAAc;CAC1D,KAAK;CACL,KAAK;CACL,KAAK;AACP,CAAC,CAAA,GACY,YAAA;;;;;;;;;;;;;;;;;;;ACRN,IAAM,yBAAN,cAAqC,aAA2B;CAE3D,YAAY;CACZ,aAAa;CAEf,2BAA8D;CAEtE,MAAc,uBAAmD;EAC/D,IAAI,CAAC,KAAK,0BAA0B;GAClC,MAAM,EAAE,sBAAsB,MAAM,OAAO,kCAAA,CAAA,MAAA,MAAA,EAAA,CAAA;GAC3C,KAAK,2BAA2B,kBAAkB,OAAO,EAAE,IAAI,KAAK,GAAG,CAAC;EAC1E;EAEA,OAAO,KAAK;CACd;CAEA,MAAM,UAAU,WAAmB,cAAyC;EAC1E,OAAO,6BACL,MAAM,KAAK,qBAAqB,GAChC,WACA,YACF;CACF;CAEA,MAAM,SACJ,WACA,OACA,eAAe,cACf,YAAY,GACG;EACf,MAAM,4BACJ,MAAM,KAAK,qBAAqB,GAChC,WACA,WACA,OACA,cACA,SACF;CACF;CAEA,MAAM,YACJ,WACA,SACA,cACe;EACf,MAAM,+BACJ,MAAM,KAAK,qBAAqB,GAChC,WACA,WACA,SACA,YACF;CACF;AACF;AArDyE,cAA5D,wBAAmE,mBAAkB,8BAAA;AAChG,cADW,wBACK,cAAa,YAAA;AADlB,yBAAN,gBAAA,CALN,KAAK;CACJ,KAAK;CACL,KAAK;CACL,KAAK;AACP,CAAC,CAAA,GACY,sBAAA"}
@@ -1,4 +1,4 @@
1
- import { y as __exportAll } from "./NostrIdentity-n70E0vck.js";
1
+ import { y as __exportAll } from "./NostrIdentity-AC8fAdxe.js";
2
2
  import { RuntimeError, SmrtCollection, SmrtObject, ValidationError, field, foreignKey, isAbortedTransactionError, oneToMany, smrt } from "@happyvertical/smrt-core";
3
3
  import { definePrompt, resolvePrompt } from "@happyvertical/smrt-prompts";
4
4
  import { TenantScoped, getTenantId, queryGlobal, queryWithGlobals, tenantId, withSystemContext } from "@happyvertical/smrt-tenancy";
@@ -33,12 +33,19 @@ function promptMessageOptions(ai) {
33
33
  var ProfileType_exports = /* @__PURE__ */ __exportAll({ ProfileType: () => ProfileType });
34
34
  var __defProp$2 = Object.defineProperty;
35
35
  var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
36
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, {
37
+ enumerable: true,
38
+ configurable: true,
39
+ writable: true,
40
+ value
41
+ }) : obj[key] = value;
36
42
  var __decorateClass$2 = (decorators, target, key, kind) => {
37
43
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
38
44
  for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
39
45
  if (kind && result) __defProp$2(target, key, result);
40
46
  return result;
41
47
  };
48
+ var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
42
49
  var ProfileType = class extends SmrtObject {
43
50
  tenantId = null;
44
51
  name = "";
@@ -58,6 +65,7 @@ var ProfileType = class extends SmrtObject {
58
65
  return null;
59
66
  }
60
67
  };
68
+ __publicField$2(ProfileType, "__smrtPackage__", "@happyvertical/smrt-profiles");
61
69
  __decorateClass$2([tenantId({ nullable: true })], ProfileType.prototype, "tenantId", 2);
62
70
  __decorateClass$2([field({ required: true })], ProfileType.prototype, "name", 2);
63
71
  ProfileType = __decorateClass$2([TenantScoped({ mode: "optional" }), smrt({
@@ -359,12 +367,19 @@ async function backfillProfileEmailKeys(db) {
359
367
  //#region src/models/OidcProfileEmailReservation.ts
360
368
  var __defProp$1 = Object.defineProperty;
361
369
  var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
370
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
371
+ enumerable: true,
372
+ configurable: true,
373
+ writable: true,
374
+ value
375
+ }) : obj[key] = value;
362
376
  var __decorateClass$1 = (decorators, target, key, kind) => {
363
377
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
364
378
  for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
365
379
  if (kind && result) __defProp$1(target, key, result);
366
380
  return result;
367
381
  };
382
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
368
383
  var OidcProfileEmailReservation = class extends SmrtObject {
369
384
  profileId;
370
385
  emailKey = "";
@@ -374,6 +389,7 @@ var OidcProfileEmailReservation = class extends SmrtObject {
374
389
  if (options.emailKey !== void 0) this.emailKey = options.emailKey;
375
390
  }
376
391
  };
392
+ __publicField$1(OidcProfileEmailReservation, "__smrtPackage__", "@happyvertical/smrt-profiles");
377
393
  __decorateClass$1([foreignKey("Profile", {
378
394
  required: true,
379
395
  unique: true
@@ -394,12 +410,19 @@ OidcProfileEmailReservation = __decorateClass$1([smrt({
394
410
  //#region src/models/Profile.ts
395
411
  var __defProp = Object.defineProperty;
396
412
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
413
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
414
+ enumerable: true,
415
+ configurable: true,
416
+ writable: true,
417
+ value
418
+ }) : obj[key] = value;
397
419
  var __decorateClass = (decorators, target, key, kind) => {
398
420
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
399
421
  for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
400
422
  if (kind && result) __defProp(target, key, result);
401
423
  return result;
402
424
  };
425
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
403
426
  var Profile = class extends SmrtObject {
404
427
  tenantId = null;
405
428
  typeId;
@@ -450,8 +473,8 @@ var Profile = class extends SmrtObject {
450
473
  * @param value - The value to set
451
474
  */
452
475
  async addMetadata(metafieldSlug, value) {
453
- const { ProfileMetafieldCollection } = await import("./ProfileMetafieldCollection-CoBuM_5G.js").then((n) => n.n);
454
- const { ProfileMetadataCollection } = await import("./ProfileMetadataCollection-DQhbfEfa.js").then((n) => n.n);
476
+ const { ProfileMetafieldCollection } = await import("./ProfileMetafieldCollection-Buz7gzag.js").then((n) => n.n);
477
+ const { ProfileMetadataCollection } = await import("./ProfileMetadataCollection-BIYKy4Y3.js").then((n) => n.n);
455
478
  const metafield = await this.resolveMetafield(await ProfileMetafieldCollection.create(this.options), metafieldSlug);
456
479
  if (!metafield) throw new Error(`Metafield '${metafieldSlug}' not found`);
457
480
  await metafield.validateValue(value);
@@ -484,7 +507,7 @@ var Profile = class extends SmrtObject {
484
507
  * @returns Object with metafield slugs as keys
485
508
  */
486
509
  async getMetadata() {
487
- const { ProfileMetadataCollection } = await import("./ProfileMetadataCollection-DQhbfEfa.js").then((n) => n.n);
510
+ const { ProfileMetadataCollection } = await import("./ProfileMetadataCollection-BIYKy4Y3.js").then((n) => n.n);
488
511
  return await (await ProfileMetadataCollection.create(this.options)).getMetadataObject(this.id);
489
512
  }
490
513
  /**
@@ -501,8 +524,8 @@ var Profile = class extends SmrtObject {
501
524
  * @param metafieldSlug - The slug of the metafield to remove
502
525
  */
503
526
  async removeMetadata(metafieldSlug) {
504
- const { ProfileMetafieldCollection } = await import("./ProfileMetafieldCollection-CoBuM_5G.js").then((n) => n.n);
505
- const { ProfileMetadataCollection } = await import("./ProfileMetadataCollection-DQhbfEfa.js").then((n) => n.n);
527
+ const { ProfileMetafieldCollection } = await import("./ProfileMetafieldCollection-Buz7gzag.js").then((n) => n.n);
528
+ const { ProfileMetadataCollection } = await import("./ProfileMetadataCollection-BIYKy4Y3.js").then((n) => n.n);
506
529
  const metafield = await this.resolveMetafield(await ProfileMetafieldCollection.create(this.options), metafieldSlug);
507
530
  if (!metafield) throw new Error(`Metafield '${metafieldSlug}' not found`);
508
531
  const existing = await (await ProfileMetadataCollection.create(this.options)).list({
@@ -527,7 +550,7 @@ var Profile = class extends SmrtObject {
527
550
  return candidates.find((candidate) => ownerTenantId && candidate.tenantId === ownerTenantId) ?? candidates.find((candidate) => !candidate.tenantId) ?? null;
528
551
  }
529
552
  async getProfileLinkCollection() {
530
- const { ProfileLinkCollection } = await import("./ProfileLinkCollection-4uNURz32.js").then((n) => n.r);
553
+ const { ProfileLinkCollection } = await import("./ProfileLinkCollection-u1hhzKTm.js").then((n) => n.r);
531
554
  return ProfileLinkCollection.create({ db: this.db });
532
555
  }
533
556
  /** This profile's web links in display order. */
@@ -544,7 +567,7 @@ var Profile = class extends SmrtObject {
544
567
  return (await this.getProfileLinkCollection()).replaceForProfile(this.id, links);
545
568
  }
546
569
  async getProfileAssetCollection() {
547
- const { ProfileAssetCollection } = await import("./ProfileAssetCollection-B9hacUJa.js").then((n) => n.n);
570
+ const { ProfileAssetCollection } = await import("./ProfileAssetCollection-HeMtjBc0.js").then((n) => n.n);
548
571
  return ProfileAssetCollection.create({ db: this.db });
549
572
  }
550
573
  async getAssets(relationship) {
@@ -575,9 +598,9 @@ var Profile = class extends SmrtObject {
575
598
  * @param contextProfile - Optional context profile for tertiary relationships
576
599
  */
577
600
  async addRelationship(toProfile, relationshipSlug, contextProfile) {
578
- const { ProfileRelationshipTypeCollection } = await import("./ProfileRelationshipTypeCollection-BdXwd7Kf.js").then((n) => n.n);
579
- const { ProfileRelationshipCollection } = await import("./ProfileRelationshipCollection-DUVgaIqf.js").then((n) => n.n);
580
- const { ProfileRelationshipType } = await import("./ProfileRelationshipType-BRiRka6t.js").then((n) => n.n);
601
+ const { ProfileRelationshipTypeCollection } = await import("./ProfileRelationshipTypeCollection-_n22WqTb.js").then((n) => n.n);
602
+ const { ProfileRelationshipCollection } = await import("./ProfileRelationshipCollection-C4g_QLI4.js").then((n) => n.n);
603
+ const { ProfileRelationshipType } = await import("./ProfileRelationshipType-U7IwF6Wf.js").then((n) => n.n);
581
604
  const relationshipType = await (await ProfileRelationshipTypeCollection.create(this.options)).getBySlug(relationshipSlug);
582
605
  if (!relationshipType) throw new Error(`Relationship type '${relationshipSlug}' not found`);
583
606
  const relationshipCollection = await ProfileRelationshipCollection.create(this.options);
@@ -601,8 +624,8 @@ var Profile = class extends SmrtObject {
601
624
  * @returns Array of ProfileRelationship instances
602
625
  */
603
626
  async getRelationships(options) {
604
- const { ProfileRelationshipCollection } = await import("./ProfileRelationshipCollection-DUVgaIqf.js").then((n) => n.n);
605
- const { ProfileRelationshipTypeCollection } = await import("./ProfileRelationshipTypeCollection-BdXwd7Kf.js").then((n) => n.n);
627
+ const { ProfileRelationshipCollection } = await import("./ProfileRelationshipCollection-C4g_QLI4.js").then((n) => n.n);
628
+ const { ProfileRelationshipTypeCollection } = await import("./ProfileRelationshipTypeCollection-_n22WqTb.js").then((n) => n.n);
606
629
  const relationshipCollection = await ProfileRelationshipCollection.create(this.options);
607
630
  const direction = options?.direction || "all";
608
631
  let typeId;
@@ -645,8 +668,8 @@ var Profile = class extends SmrtObject {
645
668
  * @param relationshipSlug - The type of relationship to remove
646
669
  */
647
670
  async removeRelationship(toProfile, relationshipSlug) {
648
- const { ProfileRelationshipTypeCollection } = await import("./ProfileRelationshipTypeCollection-BdXwd7Kf.js").then((n) => n.n);
649
- const { ProfileRelationshipCollection } = await import("./ProfileRelationshipCollection-DUVgaIqf.js").then((n) => n.n);
671
+ const { ProfileRelationshipTypeCollection } = await import("./ProfileRelationshipTypeCollection-_n22WqTb.js").then((n) => n.n);
672
+ const { ProfileRelationshipCollection } = await import("./ProfileRelationshipCollection-C4g_QLI4.js").then((n) => n.n);
650
673
  const relationshipType = await (await ProfileRelationshipTypeCollection.create(this.options)).getBySlug(relationshipSlug);
651
674
  if (!relationshipType) throw new Error(`Relationship type '${relationshipSlug}' not found`);
652
675
  const relationshipCollection = await ProfileRelationshipCollection.create(this.options);
@@ -739,7 +762,7 @@ var Profile = class extends SmrtObject {
739
762
  * @returns Array of API keys
740
763
  */
741
764
  async getApiKeys() {
742
- const { ApiKeyCollection } = await import("./ApiKeyCollection-Bfb_nw81.js").then((n) => n.n);
765
+ const { ApiKeyCollection } = await import("./ApiKeyCollection-CiiDNFdD.js").then((n) => n.n);
743
766
  return await (await ApiKeyCollection.create(this.options)).findByProfile(this.id);
744
767
  }
745
768
  /**
@@ -748,7 +771,7 @@ var Profile = class extends SmrtObject {
748
771
  * @returns Array of active API keys
749
772
  */
750
773
  async getActiveApiKeys() {
751
- const { ApiKeyCollection } = await import("./ApiKeyCollection-Bfb_nw81.js").then((n) => n.n);
774
+ const { ApiKeyCollection } = await import("./ApiKeyCollection-CiiDNFdD.js").then((n) => n.n);
752
775
  return await (await ApiKeyCollection.create(this.options)).findActiveByProfile(this.id);
753
776
  }
754
777
  /**
@@ -758,7 +781,7 @@ var Profile = class extends SmrtObject {
758
781
  * @returns The generated key (plaintext) and ApiKey record
759
782
  */
760
783
  async generateApiKey(options) {
761
- const { ApiKey } = await import("./ApiKey-BZmbOTnL.js").then((n) => n.n);
784
+ const { ApiKey } = await import("./ApiKey-CVmlf3V6.js").then((n) => n.n);
762
785
  return await ApiKey.generate(this, {
763
786
  ...options,
764
787
  db: this.options?.db
@@ -770,7 +793,7 @@ var Profile = class extends SmrtObject {
770
793
  * @returns Array of OIDC identity records
771
794
  */
772
795
  async getOidcIdentities() {
773
- const { OidcIdentityCollection } = await import("./OidcIdentityCollection-TV8VdK69.js").then((n) => n.r);
796
+ const { OidcIdentityCollection } = await import("./OidcIdentityCollection-B4jYh36_.js").then((n) => n.r);
774
797
  return await (await OidcIdentityCollection.create(this.options)).findByProfile(this.id);
775
798
  }
776
799
  /**
@@ -783,7 +806,7 @@ var Profile = class extends SmrtObject {
783
806
  * type, but refuses to create or rebind authority.
784
807
  */
785
808
  async linkOidcIdentity(oidcData) {
786
- const { OidcIdentityCollection } = await import("./OidcIdentityCollection-TV8VdK69.js").then((n) => n.r);
809
+ const { OidcIdentityCollection } = await import("./OidcIdentityCollection-B4jYh36_.js").then((n) => n.r);
787
810
  return await (await OidcIdentityCollection.create(this.options)).linkToProfile(this, oidcData);
788
811
  }
789
812
  /**
@@ -792,7 +815,7 @@ var Profile = class extends SmrtObject {
792
815
  * @returns Array of Nostr identity records
793
816
  */
794
817
  async getNostrIdentities() {
795
- const { NostrIdentityCollection } = await import("./NostrIdentityCollection-Ca74dkaL.js").then((n) => n.n);
818
+ const { NostrIdentityCollection } = await import("./NostrIdentityCollection-CctlECpX.js").then((n) => n.n);
796
819
  return await (await NostrIdentityCollection.create(this.options)).findByProfile(this.id);
797
820
  }
798
821
  /**
@@ -802,7 +825,7 @@ var Profile = class extends SmrtObject {
802
825
  * @returns The linked Nostr identity record
803
826
  */
804
827
  async linkNostrIdentity(nostrData) {
805
- const { NostrIdentityCollection } = await import("./NostrIdentityCollection-Ca74dkaL.js").then((n) => n.n);
828
+ const { NostrIdentityCollection } = await import("./NostrIdentityCollection-CctlECpX.js").then((n) => n.n);
806
829
  return await (await NostrIdentityCollection.create(this.options)).linkToProfile(this, nostrData);
807
830
  }
808
831
  /**
@@ -812,7 +835,7 @@ var Profile = class extends SmrtObject {
812
835
  * @returns Array of audit log entries
813
836
  */
814
837
  async getAuditLogs(limit = 50) {
815
- const { AuditLogCollection } = await import("./AuditLogCollection-B1YonCAP.js").then((n) => n.n);
838
+ const { AuditLogCollection } = await import("./AuditLogCollection-WDHL-_AF.js").then((n) => n.n);
816
839
  return await (await AuditLogCollection.create(this.options)).getRecentActivity(this.id, limit);
817
840
  }
818
841
  /**
@@ -822,13 +845,14 @@ var Profile = class extends SmrtObject {
822
845
  * @returns The created audit log entry
823
846
  */
824
847
  async recordAction(options) {
825
- const { AuditLogCollection } = await import("./AuditLogCollection-B1YonCAP.js").then((n) => n.n);
848
+ const { AuditLogCollection } = await import("./AuditLogCollection-WDHL-_AF.js").then((n) => n.n);
826
849
  return await (await AuditLogCollection.create(this.options)).record({
827
850
  profile: this,
828
851
  ...options
829
852
  });
830
853
  }
831
854
  };
855
+ __publicField(Profile, "__smrtPackage__", "@happyvertical/smrt-profiles");
832
856
  __decorateClass([tenantId({ nullable: true })], Profile.prototype, "tenantId", 2);
833
857
  __decorateClass([foreignKey("ProfileType", { required: true })], Profile.prototype, "typeId", 2);
834
858
  __decorateClass([field({
@@ -1191,4 +1215,4 @@ function readRequiredString(row, key) {
1191
1215
  //#endregion
1192
1216
  export { smrtProfilesGenerateBioPrompt as _, Profile as a, backfillProfileEmailKeys as c, isOidcProvisioningRaceConflict as d, saveOidcRaceArbiter as f, promptMessageOptions as g, ProfileType_exports as h, OidcProfileEmailReservationCollection as i, coordinateOidcProvisioning as l, ProfileType as m, ProfileCollection as n, OidcProfileEmailReservation as o, normalizeIdentityEmail as p, ProfileCollection_exports as r, PROFILE_EMAIL_KEY_BACKFILL_NAME as s, CanonicalPersonProfileError as t, isOidcAbortedTransactionError as u };
1193
1217
 
1194
- //# sourceMappingURL=ProfileCollection-DuJT7Mum.js.map
1218
+ //# sourceMappingURL=ProfileCollection-Bt6IJK49.js.map