lsh-framework 3.1.6 → 3.1.8
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/ipfs-secrets-storage.js +54 -14
- 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/dist/services/secrets/secrets.js +8 -5
- package/package.json +6 -4
package/dist/lib/saas-billing.js
CHANGED
|
@@ -154,7 +154,22 @@ export class BillingService {
|
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
/**
|
|
157
|
-
* Verify webhook signature
|
|
157
|
+
* Verify Stripe webhook signature and parse event payload.
|
|
158
|
+
*
|
|
159
|
+
* In production, this should use Stripe's signature verification:
|
|
160
|
+
* ```typescript
|
|
161
|
+
* const event = stripe.webhooks.constructEvent(
|
|
162
|
+
* payload, signature, this.stripeWebhookSecret
|
|
163
|
+
* );
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* Current implementation parses JSON without verification (TODO: implement proper verification).
|
|
167
|
+
*
|
|
168
|
+
* @param payload - Raw webhook body as string
|
|
169
|
+
* @param _signature - Stripe-Signature header value (not yet used)
|
|
170
|
+
* @returns Parsed Stripe event object
|
|
171
|
+
* @throws Error if payload is not valid JSON
|
|
172
|
+
* @see https://stripe.com/docs/webhooks/signatures
|
|
158
173
|
*/
|
|
159
174
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Stripe event structure
|
|
160
175
|
verifyWebhookSignature(payload, _signature) {
|
|
@@ -168,7 +183,16 @@ export class BillingService {
|
|
|
168
183
|
}
|
|
169
184
|
}
|
|
170
185
|
/**
|
|
171
|
-
* Handle checkout
|
|
186
|
+
* Handle Stripe checkout.session.completed webhook event.
|
|
187
|
+
*
|
|
188
|
+
* Called when a customer completes checkout. The actual subscription
|
|
189
|
+
* creation is handled by the customer.subscription.created event.
|
|
190
|
+
*
|
|
191
|
+
* Extracts organization_id from session.metadata to link the checkout
|
|
192
|
+
* to the correct organization.
|
|
193
|
+
*
|
|
194
|
+
* @param session - Stripe checkout session object
|
|
195
|
+
* @see StripeCheckoutSession in database-types.ts for partial type
|
|
172
196
|
*/
|
|
173
197
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Stripe checkout session object
|
|
174
198
|
async handleCheckoutCompleted(session) {
|
|
@@ -181,7 +205,20 @@ export class BillingService {
|
|
|
181
205
|
console.log(`Checkout completed for organization ${organizationId}`);
|
|
182
206
|
}
|
|
183
207
|
/**
|
|
184
|
-
* Handle subscription
|
|
208
|
+
* Handle Stripe customer.subscription.created/updated webhook events.
|
|
209
|
+
*
|
|
210
|
+
* Creates or updates subscription record in database and syncs tier
|
|
211
|
+
* to the organization. Key operations:
|
|
212
|
+
* 1. Extracts organization_id from subscription.metadata
|
|
213
|
+
* 2. Determines tier from price ID (maps Stripe price → 'free' | 'pro' | 'enterprise')
|
|
214
|
+
* 3. Upserts subscription record with all billing details
|
|
215
|
+
* 4. Updates organization's subscription_tier and subscription_status
|
|
216
|
+
* 5. Logs audit event
|
|
217
|
+
*
|
|
218
|
+
* Timestamps from Stripe are Unix timestamps (seconds), converted to ISO strings.
|
|
219
|
+
*
|
|
220
|
+
* @param subscription - Stripe subscription object
|
|
221
|
+
* @see StripeSubscriptionEvent in database-types.ts for partial type
|
|
185
222
|
*/
|
|
186
223
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Stripe subscription object
|
|
187
224
|
async handleSubscriptionUpdated(subscription) {
|
|
@@ -235,7 +272,17 @@ export class BillingService {
|
|
|
235
272
|
});
|
|
236
273
|
}
|
|
237
274
|
/**
|
|
238
|
-
* Handle subscription
|
|
275
|
+
* Handle Stripe customer.subscription.deleted webhook event.
|
|
276
|
+
*
|
|
277
|
+
* Called when a subscription is canceled (immediate or at period end).
|
|
278
|
+
* Operations:
|
|
279
|
+
* 1. Marks subscription as 'canceled' with canceled_at timestamp
|
|
280
|
+
* 2. Downgrades organization to 'free' tier
|
|
281
|
+
* 3. Updates organization subscription_status to 'canceled'
|
|
282
|
+
* 4. Logs audit event
|
|
283
|
+
*
|
|
284
|
+
* @param subscription - Stripe subscription object
|
|
285
|
+
* @see StripeSubscriptionEvent in database-types.ts for partial type
|
|
239
286
|
*/
|
|
240
287
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Stripe subscription object
|
|
241
288
|
async handleSubscriptionDeleted(subscription) {
|
|
@@ -268,7 +315,15 @@ export class BillingService {
|
|
|
268
315
|
});
|
|
269
316
|
}
|
|
270
317
|
/**
|
|
271
|
-
* Handle invoice
|
|
318
|
+
* Handle Stripe invoice.paid webhook event.
|
|
319
|
+
*
|
|
320
|
+
* Records successful payment in the invoices table. Extracts organization_id
|
|
321
|
+
* from invoice.subscription_metadata (set during checkout).
|
|
322
|
+
*
|
|
323
|
+
* Amounts are in cents (e.g., 1000 = $10.00). Currency is uppercased.
|
|
324
|
+
*
|
|
325
|
+
* @param invoice - Stripe invoice object
|
|
326
|
+
* @see StripeInvoiceEvent in database-types.ts for partial type
|
|
272
327
|
*/
|
|
273
328
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Stripe invoice object
|
|
274
329
|
async handleInvoicePaid(invoice) {
|
|
@@ -291,7 +346,16 @@ export class BillingService {
|
|
|
291
346
|
}, { onConflict: 'stripe_invoice_id' });
|
|
292
347
|
}
|
|
293
348
|
/**
|
|
294
|
-
* Handle invoice
|
|
349
|
+
* Handle Stripe invoice.payment_failed webhook event.
|
|
350
|
+
*
|
|
351
|
+
* Called when payment fails (declined card, insufficient funds, etc.).
|
|
352
|
+
* Updates organization subscription_status to 'past_due' and logs audit event.
|
|
353
|
+
*
|
|
354
|
+
* Note: Does not immediately downgrade tier. Stripe will retry payment
|
|
355
|
+
* according to your dunning settings. Downgrade happens on subscription.deleted.
|
|
356
|
+
*
|
|
357
|
+
* @param invoice - Stripe invoice object
|
|
358
|
+
* @see StripeInvoiceEvent in database-types.ts for partial type
|
|
295
359
|
*/
|
|
296
360
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Stripe invoice object
|
|
297
361
|
async handleInvoicePaymentFailed(invoice) {
|
|
@@ -358,7 +422,26 @@ export class BillingService {
|
|
|
358
422
|
return (data || []).map(this.mapDbInvoiceToInvoice);
|
|
359
423
|
}
|
|
360
424
|
/**
|
|
361
|
-
*
|
|
425
|
+
* Transform Supabase subscription record to domain model.
|
|
426
|
+
*
|
|
427
|
+
* Maps database snake_case columns to TypeScript camelCase properties:
|
|
428
|
+
* - `organization_id` → `organizationId`
|
|
429
|
+
* - `stripe_subscription_id` → `stripeSubscriptionId` (Stripe sub_xxx ID)
|
|
430
|
+
* - `stripe_price_id` → `stripePriceId` (Stripe price_xxx ID)
|
|
431
|
+
* - `stripe_product_id` → `stripeProductId` (Stripe prod_xxx ID)
|
|
432
|
+
* - `tier` → `tier` (SubscriptionTier: 'free' | 'pro' | 'enterprise')
|
|
433
|
+
* - `status` → `status` (SubscriptionStatus)
|
|
434
|
+
* - `current_period_start` → `currentPeriodStart` (nullable Date)
|
|
435
|
+
* - `current_period_end` → `currentPeriodEnd` (nullable Date)
|
|
436
|
+
* - `cancel_at_period_end` → `cancelAtPeriodEnd` (boolean)
|
|
437
|
+
* - `trial_start` → `trialStart` (nullable Date)
|
|
438
|
+
* - `trial_end` → `trialEnd` (nullable Date)
|
|
439
|
+
* - `canceled_at` → `canceledAt` (nullable Date)
|
|
440
|
+
*
|
|
441
|
+
* @param dbSub - Supabase record from 'subscriptions' table
|
|
442
|
+
* @returns Domain Subscription object
|
|
443
|
+
* @see DbSubscriptionRecord in database-types.ts for input shape
|
|
444
|
+
* @see Subscription in saas-types.ts for output shape
|
|
362
445
|
*/
|
|
363
446
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- DB row type varies by schema
|
|
364
447
|
mapDbSubscriptionToSubscription(dbSub) {
|
|
@@ -383,7 +466,22 @@ export class BillingService {
|
|
|
383
466
|
};
|
|
384
467
|
}
|
|
385
468
|
/**
|
|
386
|
-
*
|
|
469
|
+
* Transform Supabase invoice record to domain model.
|
|
470
|
+
*
|
|
471
|
+
* Maps database snake_case columns to TypeScript camelCase properties:
|
|
472
|
+
* - `organization_id` → `organizationId`
|
|
473
|
+
* - `stripe_invoice_id` → `stripeInvoiceId` (Stripe in_xxx ID)
|
|
474
|
+
* - `amount_due` → `amountDue` (in cents, e.g., 1000 = $10.00)
|
|
475
|
+
* - `amount_paid` → `amountPaid` (in cents)
|
|
476
|
+
* - `invoice_date` → `invoiceDate` (Date)
|
|
477
|
+
* - `due_date` → `dueDate` (nullable Date)
|
|
478
|
+
* - `paid_at` → `paidAt` (nullable Date)
|
|
479
|
+
* - `invoice_pdf_url` → `invoicePdfUrl` (Stripe-hosted PDF URL)
|
|
480
|
+
*
|
|
481
|
+
* @param dbInvoice - Supabase record from 'invoices' table
|
|
482
|
+
* @returns Domain Invoice object
|
|
483
|
+
* @see DbInvoiceRecord in database-types.ts for input shape
|
|
484
|
+
* @see Invoice in saas-types.ts for output shape
|
|
387
485
|
*/
|
|
388
486
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- DB row type varies by schema
|
|
389
487
|
mapDbInvoiceToInvoice(dbInvoice) {
|
|
@@ -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) {
|
|
@@ -458,6 +458,7 @@ API_KEY=
|
|
|
458
458
|
.option('--export', 'Output in export format for shell evaluation (alias for --format export)')
|
|
459
459
|
.option('--format <type>', 'Output format: env, json, yaml, toml, export', 'env')
|
|
460
460
|
.option('--exact', 'Require exact key match (disable fuzzy matching)')
|
|
461
|
+
.option('--no-mask', 'Show full values in fuzzy match results')
|
|
461
462
|
.action(async (key, options) => {
|
|
462
463
|
try {
|
|
463
464
|
const manager = new SecretsManager({ globalMode: options.global });
|
|
@@ -546,11 +547,13 @@ API_KEY=
|
|
|
546
547
|
// Multiple matches - show all matches for user to choose
|
|
547
548
|
console.error(`🔍 Found ${matches.length} matches for '${key}':\n`);
|
|
548
549
|
for (const match of matches) {
|
|
549
|
-
// Mask value for display
|
|
550
|
-
const
|
|
551
|
-
? match.value
|
|
552
|
-
:
|
|
553
|
-
|
|
550
|
+
// Mask value for display unless --no-mask is set
|
|
551
|
+
const displayValue = options.mask === false
|
|
552
|
+
? match.value
|
|
553
|
+
: (match.value.length > 4
|
|
554
|
+
? match.value.substring(0, 4) + '*'.repeat(Math.min(match.value.length - 4, 10))
|
|
555
|
+
: '****');
|
|
556
|
+
console.error(` ${match.key}=${displayValue}`);
|
|
554
557
|
}
|
|
555
558
|
console.error('');
|
|
556
559
|
console.error('💡 Please specify the exact key name or use one of:');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lsh-framework",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.8",
|
|
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": {
|
|
@@ -65,13 +65,14 @@
|
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"@storacha/client": "^1.8.18",
|
|
67
67
|
"@supabase/supabase-js": "^2.57.4",
|
|
68
|
-
"
|
|
68
|
+
"@types/proper-lockfile": "^4.1.4",
|
|
69
|
+
"bcrypt": "^6.0.0",
|
|
69
70
|
"chalk": "^5.3.0",
|
|
70
71
|
"chokidar": "^5.0.0",
|
|
71
72
|
"commander": "^14.0.2",
|
|
72
73
|
"cors": "^2.8.5",
|
|
73
74
|
"dotenv": "^17.2.3",
|
|
74
|
-
"express": "^4.
|
|
75
|
+
"express": "^4.22.1",
|
|
75
76
|
"express-rate-limit": "^8.2.1",
|
|
76
77
|
"glob": "^13.0.0",
|
|
77
78
|
"inquirer": "^9.2.12",
|
|
@@ -80,6 +81,7 @@
|
|
|
80
81
|
"node-cron": "^4.2.1",
|
|
81
82
|
"ora": "^9.0.0",
|
|
82
83
|
"pg": "^8.16.3",
|
|
84
|
+
"proper-lockfile": "^4.1.2",
|
|
83
85
|
"smol-toml": "^1.3.1",
|
|
84
86
|
"uuid": "^13.0.0"
|
|
85
87
|
},
|
|
@@ -90,7 +92,7 @@
|
|
|
90
92
|
"@types/jest": "^30.0.0",
|
|
91
93
|
"@types/js-yaml": "^4.0.9",
|
|
92
94
|
"@types/jsonwebtoken": "^9.0.5",
|
|
93
|
-
"@types/node": "^20.
|
|
95
|
+
"@types/node": "^20.19.27",
|
|
94
96
|
"@typescript-eslint/eslint-plugin": "^8.44.1",
|
|
95
97
|
"@typescript-eslint/parser": "^8.44.1",
|
|
96
98
|
"eslint": "^9.36.0",
|