lsh-framework 3.1.6 → 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.
- package/dist/__tests__/fixtures/job-fixtures.js +204 -0
- package/dist/__tests__/fixtures/supabase-mocks.js +252 -0
- package/dist/cli.js +12 -2
- package/dist/lib/database-types.js +90 -0
- package/dist/lib/lsh-error.js +406 -0
- package/dist/lib/saas-auth.js +39 -2
- package/dist/lib/saas-billing.js +106 -8
- package/dist/lib/saas-organizations.js +74 -5
- package/dist/lib/saas-secrets.js +30 -2
- package/package.json +3 -3
|
@@ -331,7 +331,22 @@ export class OrganizationService {
|
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
333
|
/**
|
|
334
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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) {
|
package/dist/lib/saas-secrets.js
CHANGED
|
@@ -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
|
-
*
|
|
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.
|
|
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.
|
|
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.
|
|
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",
|