lsh-framework 3.1.5 → 3.1.7

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.
@@ -331,7 +331,22 @@ export class OrganizationService {
331
331
  }
332
332
  }
333
333
  /**
334
- * Map database org to Organization type
334
+ * Transform Supabase organization record to domain model.
335
+ *
336
+ * Maps database snake_case columns to TypeScript camelCase properties:
337
+ * - `created_at` (ISO string) → `createdAt` (Date)
338
+ * - `subscription_tier` (string) → `subscriptionTier` (SubscriptionTier type)
339
+ * - `subscription_status` (string) → `subscriptionStatus` (SubscriptionStatus type)
340
+ * - `stripe_customer_id` → `stripeCustomerId`
341
+ * - `subscription_expires_at` → `subscriptionExpiresAt` (nullable Date)
342
+ * - `deleted_at` → `deletedAt` (nullable Date, for soft delete filtering)
343
+ *
344
+ * Settings are passed through as-is (JSONB column).
345
+ *
346
+ * @param dbOrg - Supabase record from 'organizations' table
347
+ * @returns Domain Organization object with validated types
348
+ * @see DbOrganizationRecord in database-types.ts for input shape
349
+ * @see Organization in saas-types.ts for output shape
335
350
  */
336
351
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- DB row type varies by schema
337
352
  mapDbOrgToOrg(dbOrg) {
@@ -352,7 +367,20 @@ export class OrganizationService {
352
367
  };
353
368
  }
354
369
  /**
355
- * Map database member to OrganizationMember type
370
+ * Transform Supabase organization member record to domain model.
371
+ *
372
+ * Maps database snake_case columns to TypeScript camelCase properties:
373
+ * - `organization_id` → `organizationId`
374
+ * - `user_id` → `userId`
375
+ * - `role` (string) → `role` (OrganizationRole type)
376
+ * - `invited_by` → `invitedBy` (nullable, FK to users.id)
377
+ * - `invited_at` (ISO string) → `invitedAt` (Date)
378
+ * - `accepted_at` (ISO string) → `acceptedAt` (nullable Date)
379
+ *
380
+ * @param dbMember - Supabase record from 'organization_members' table
381
+ * @returns Domain OrganizationMember object
382
+ * @see DbOrganizationMemberRecord in database-types.ts for input shape
383
+ * @see OrganizationMember in saas-types.ts for output shape
356
384
  */
357
385
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- DB row type varies by schema
358
386
  mapDbMemberToMember(dbMember) {
@@ -369,7 +397,24 @@ export class OrganizationService {
369
397
  };
370
398
  }
371
399
  /**
372
- * Map database member detailed to OrganizationMemberDetailed type
400
+ * Transform Supabase organization member detailed view record to domain model.
401
+ *
402
+ * This mapper handles records from the 'organization_members_detailed' view,
403
+ * which joins organization_members with users and organizations tables.
404
+ *
405
+ * Maps all OrganizationMember fields plus:
406
+ * - `email` (from users table)
407
+ * - `first_name` → `firstName` (from users table)
408
+ * - `last_name` → `lastName` (from users table)
409
+ * - `avatar_url` → `avatarUrl` (from users table)
410
+ * - `last_login_at` → `lastLoginAt` (from users table, nullable Date)
411
+ * - `organization_name` → `organizationName` (from organizations table)
412
+ * - `organization_slug` → `organizationSlug` (from organizations table)
413
+ *
414
+ * @param dbMember - Supabase record from 'organization_members_detailed' view
415
+ * @returns Domain OrganizationMemberDetailed object
416
+ * @see DbOrganizationMemberDetailedRecord in database-types.ts for input shape
417
+ * @see OrganizationMemberDetailed in saas-types.ts for output shape
373
418
  */
374
419
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- DB row with joined user data
375
420
  mapDbMemberDetailedToMemberDetailed(dbMember) {
@@ -560,7 +605,19 @@ export class TeamService {
560
605
  return data || [];
561
606
  }
562
607
  /**
563
- * Map database team to Team type
608
+ * Transform Supabase team record to domain model.
609
+ *
610
+ * Maps database snake_case columns to TypeScript camelCase properties:
611
+ * - `organization_id` → `organizationId`
612
+ * - `encryption_key_id` → `encryptionKeyId` (FK to active team encryption key)
613
+ * - `created_at` (ISO string) → `createdAt` (Date)
614
+ * - `updated_at` (ISO string) → `updatedAt` (Date)
615
+ * - `deleted_at` (ISO string) → `deletedAt` (nullable Date, for soft delete)
616
+ *
617
+ * @param dbTeam - Supabase record from 'teams' table
618
+ * @returns Domain Team object
619
+ * @see DbTeamRecord in database-types.ts for input shape
620
+ * @see Team in saas-types.ts for output shape
564
621
  */
565
622
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- DB row type varies by schema
566
623
  mapDbTeamToTeam(dbTeam) {
@@ -577,7 +634,19 @@ export class TeamService {
577
634
  };
578
635
  }
579
636
  /**
580
- * Map database team member to TeamMember type
637
+ * Transform Supabase team member record to domain model.
638
+ *
639
+ * Maps database snake_case columns to TypeScript camelCase properties:
640
+ * - `team_id` → `teamId`
641
+ * - `user_id` → `userId`
642
+ * - `role` (string) → `role` (TeamRole type: 'admin' | 'member' | 'viewer')
643
+ * - `created_at` (ISO string) → `createdAt` (Date)
644
+ * - `updated_at` (ISO string) → `updatedAt` (Date)
645
+ *
646
+ * @param dbMember - Supabase record from 'team_members' table
647
+ * @returns Domain TeamMember object
648
+ * @see DbTeamMemberRecord in database-types.ts for input shape
649
+ * @see TeamMember in saas-types.ts for output shape
581
650
  */
582
651
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- DB row type varies by schema
583
652
  mapDbTeamMemberToTeamMember(dbMember) {
@@ -341,7 +341,14 @@ export class SecretsService {
341
341
  }
342
342
  }
343
343
  /**
344
- * Helper to get team
344
+ * Helper to get team record from database.
345
+ *
346
+ * Fetches raw team record from 'teams' table. Used internally to get
347
+ * organization_id for audit logging and tier limit checks.
348
+ *
349
+ * @param teamId - UUID of team to fetch
350
+ * @returns Raw Supabase team record or null if not found
351
+ * @see DbTeamRecord in database-types.ts for return shape
345
352
  */
346
353
  async getTeamById(teamId) {
347
354
  const { data } = await this.supabase
@@ -352,7 +359,28 @@ export class SecretsService {
352
359
  return data;
353
360
  }
354
361
  /**
355
- * Map database secret to Secret type
362
+ * Transform Supabase secret record to domain model.
363
+ *
364
+ * Maps database snake_case columns to TypeScript camelCase properties:
365
+ * - `team_id` → `teamId`
366
+ * - `encrypted_value` → `encryptedValue` (AES-256 encrypted)
367
+ * - `encryption_key_id` → `encryptionKeyId` (FK to team's encryption key)
368
+ * - `last_rotated_at` → `lastRotatedAt` (nullable Date)
369
+ * - `rotation_interval_days` → `rotationIntervalDays` (nullable number)
370
+ * - `created_by` → `createdBy` (FK to users.id)
371
+ * - `updated_by` → `updatedBy` (FK to users.id)
372
+ * - `deleted_by` → `deletedBy` (FK to users.id, for soft delete audit)
373
+ *
374
+ * Special handling:
375
+ * - `tags`: Parses JSON string to string[] if stored as string, passes through if already array
376
+ *
377
+ * Note: The `encryptedValue` field contains the encrypted secret. Use
378
+ * `encryptionService.decryptForTeam()` to decrypt it when needed.
379
+ *
380
+ * @param dbSecret - Supabase record from 'secrets' table
381
+ * @returns Domain Secret object with parsed tags
382
+ * @see DbSecretRecord in database-types.ts for input shape
383
+ * @see Secret in saas-types.ts for output shape
356
384
  */
357
385
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- DB row type varies by schema
358
386
  mapDbSecretToSecret(dbSecret) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lsh-framework",
3
- "version": "3.1.5",
3
+ "version": "3.1.7",
4
4
  "description": "Simple, cross-platform encrypted secrets manager with automatic sync, IPFS audit logs, and multi-environment support. Just run lsh sync and start managing your secrets.",
5
5
  "main": "dist/app.js",
6
6
  "bin": {
@@ -71,7 +71,7 @@
71
71
  "commander": "^14.0.2",
72
72
  "cors": "^2.8.5",
73
73
  "dotenv": "^17.2.3",
74
- "express": "^4.18.2",
74
+ "express": "^4.22.1",
75
75
  "express-rate-limit": "^8.2.1",
76
76
  "glob": "^13.0.0",
77
77
  "inquirer": "^9.2.12",
@@ -90,7 +90,7 @@
90
90
  "@types/jest": "^30.0.0",
91
91
  "@types/js-yaml": "^4.0.9",
92
92
  "@types/jsonwebtoken": "^9.0.5",
93
- "@types/node": "^20.12.7",
93
+ "@types/node": "^20.19.27",
94
94
  "@typescript-eslint/eslint-plugin": "^8.44.1",
95
95
  "@typescript-eslint/parser": "^8.44.1",
96
96
  "eslint": "^9.36.0",