@vunexa/lixa 0.1.6-alpha.4 → 0.1.6-alpha.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.
Files changed (3) hide show
  1. package/README.md +167 -18
  2. package/README.template.md +167 -18
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -363,14 +363,6 @@ export const lixa = new Lixa({
363
363
  "accessToken": "gho_8f7b2a9e1c3...",
364
364
  "linkedAt": 1771657250000
365
365
  }
366
- },
367
- "resources": {
368
- "github": {
369
- "provider": "github",
370
- "accessToken": "gho_resource_repo_9a8b7c...",
371
- "scopes": ["repo", "read:org"],
372
- "connectedAt": 1771657300000
373
- }
374
366
  }
375
367
  }
376
368
  ```
@@ -498,16 +490,12 @@ export const lixa = new Lixa({
498
490
  "accessToken": "gho_8f7b2a9e1c3...",
499
491
  "linkedAt": 1771657250000
500
492
  }
501
- },
502
- "resources": {
503
- "github": {
504
- "provider": "github",
505
- "accessToken": "gho_resource_repo_9a8b7c...",
506
- "scopes": ["repo", "read:org"],
507
- "connectedAt": 1771657300000
508
- }
509
493
  }
510
- ---
494
+ }
495
+ }
496
+ ```
497
+
498
+ ---
511
499
 
512
500
  ## Custom Resource Storage Implementation (`ResourceStorage`)
513
501
 
@@ -601,7 +589,168 @@ export const lixa = new Lixa({
601
589
  });
602
590
  ```
603
591
 
604
- ### 2. Querying Connected Resources Directly by User ID
592
+ #### Saved JSON Records Example in SQLite (`user_resources` Table)
593
+
594
+ **Row 1 (GitHub Repositories)**:
595
+ ```json
596
+ {
597
+ "user_id": "1049281048",
598
+ "provider": "github",
599
+ "data": {
600
+ "accessToken": "gho_resource_repo_9a8b7c...",
601
+ "refreshToken": "ghr_refresh_token_123...",
602
+ "scopes": ["repo", "read:org"],
603
+ "expiresAt": 1771743600000,
604
+ "connectedAt": 1771657300000
605
+ }
606
+ }
607
+ ```
608
+
609
+ **Row 2 (Google Drive)**:
610
+ ```json
611
+ {
612
+ "user_id": "1049281048",
613
+ "provider": "google",
614
+ "data": {
615
+ "accessToken": "ya29.drive_resource_token_456...",
616
+ "refreshToken": "1//09abc_google_refresh_token...",
617
+ "scopes": ["https://www.googleapis.com/auth/drive.readonly"],
618
+ "expiresAt": 1771660800000,
619
+ "connectedAt": 1771657400000
620
+ }
621
+ }
622
+ ```
623
+
624
+ ---
625
+
626
+ ### 2. AWS DynamoDB Resource Storage (`@aws-sdk/lib-dynamodb`)
627
+
628
+ For serverless AWS deployments storing user API credentials in DynamoDB:
629
+
630
+ #### Table Configuration
631
+
632
+ - **Table Name**: `LixaUserResources`
633
+ - **Partition Key (PK)**: `userId` (String)
634
+ - **Sort Key (SK)**: `provider` (String)
635
+
636
+ #### TypeScript Implementation
637
+
638
+ ```typescript
639
+ import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
640
+ import { DynamoDBDocumentClient, PutCommand, GetCommand, DeleteCommand, QueryCommand } from "@aws-sdk/lib-dynamodb";
641
+ import { Lixa, type ResourceStorage, type ConnectedResource } from "@vunexa/lixa";
642
+
643
+ export class DynamoDbResourceStorage implements ResourceStorage {
644
+ private docClient: DynamoDBDocumentClient;
645
+ private tableName = "LixaUserResources";
646
+
647
+ constructor() {
648
+ const client = new DynamoDBClient({ region: process.env.AWS_REGION || "us-east-1" });
649
+ this.docClient = DynamoDBDocumentClient.from(client);
650
+ }
651
+
652
+ async saveResource(userId: string, provider: string, resource: ConnectedResource): Promise<void> {
653
+ await this.docClient.send(
654
+ new PutCommand({
655
+ TableName: this.tableName,
656
+ Item: {
657
+ userId,
658
+ provider: provider.toLowerCase(),
659
+ resourceData: resource,
660
+ updatedAt: Date.now(),
661
+ },
662
+ })
663
+ );
664
+ }
665
+
666
+ async getResource(userId: string, provider: string): Promise<ConnectedResource | null> {
667
+ const res = await this.docClient.send(
668
+ new GetCommand({
669
+ TableName: this.tableName,
670
+ Key: {
671
+ userId,
672
+ provider: provider.toLowerCase(),
673
+ },
674
+ })
675
+ );
676
+
677
+ return res.Item ? (res.Item.resourceData as ConnectedResource) : null;
678
+ }
679
+
680
+ async getUserResources(userId: string): Promise<Record<string, ConnectedResource>> {
681
+ const res = await this.docClient.send(
682
+ new QueryCommand({
683
+ TableName: this.tableName,
684
+ KeyConditionExpression: "userId = :userId",
685
+ ExpressionAttributeValues: { ":userId": userId },
686
+ })
687
+ );
688
+
689
+ const result: Record<string, ConnectedResource> = {};
690
+ if (res.Items) {
691
+ for (const item of res.Items) {
692
+ result[item.provider] = item.resourceData as ConnectedResource;
693
+ }
694
+ }
695
+ return result;
696
+ }
697
+
698
+ async deleteResource(userId: string, provider: string): Promise<void> {
699
+ await this.docClient.send(
700
+ new DeleteCommand({
701
+ TableName: this.tableName,
702
+ Key: {
703
+ userId,
704
+ provider: provider.toLowerCase(),
705
+ },
706
+ })
707
+ );
708
+ }
709
+ }
710
+
711
+ // Pass to Lixa instance via resourceHandler
712
+ export const lixa = new Lixa({
713
+ resourceHandler: {
714
+ resourceStorage: new DynamoDbResourceStorage(),
715
+ },
716
+ providers: { /* ... */ },
717
+ });
718
+ ```
719
+
720
+ #### Saved DynamoDB Resource Items Example (`LixaUserResources` Table)
721
+
722
+ ```json
723
+ [
724
+ {
725
+ "userId": "1049281048",
726
+ "provider": "github",
727
+ "updatedAt": 1771657300000,
728
+ "resourceData": {
729
+ "accessToken": "gho_resource_repo_9a8b7c...",
730
+ "refreshToken": "ghr_refresh_token_123...",
731
+ "scopes": ["repo", "read:org"],
732
+ "expiresAt": 1771743600000,
733
+ "connectedAt": 1771657300000
734
+ }
735
+ },
736
+ {
737
+ "userId": "1049281048",
738
+ "provider": "google",
739
+ "updatedAt": 1771657400000,
740
+ "resourceData": {
741
+ "accessToken": "ya29.drive_resource_token_456...",
742
+ "refreshToken": "1//09abc_google_refresh_token...",
743
+ "scopes": ["https://www.googleapis.com/auth/drive.readonly"],
744
+ "expiresAt": 1771660800000,
745
+ "connectedAt": 1771657400000
746
+ }
747
+ }
748
+ ]
749
+ ```
750
+
751
+ ---
752
+
753
+ ### 3. Querying Connected Resources Directly by User ID
605
754
 
606
755
  `ResourceStorage` enables background workers, cron jobs, and webhooks to access third-party API credentials by `userId` without an active HTTP session:
607
756
 
@@ -453,14 +453,6 @@ export const lixa = new Lixa({
453
453
  "accessToken": "gho_8f7b2a9e1c3...",
454
454
  "linkedAt": 1771657250000
455
455
  }
456
- },
457
- "resources": {
458
- "github": {
459
- "provider": "github",
460
- "accessToken": "gho_resource_repo_9a8b7c...",
461
- "scopes": ["repo", "read:org"],
462
- "connectedAt": 1771657300000
463
- }
464
456
  }
465
457
  }
466
458
  ```
@@ -588,16 +580,12 @@ export const lixa = new Lixa({
588
580
  "accessToken": "gho_8f7b2a9e1c3...",
589
581
  "linkedAt": 1771657250000
590
582
  }
591
- },
592
- "resources": {
593
- "github": {
594
- "provider": "github",
595
- "accessToken": "gho_resource_repo_9a8b7c...",
596
- "scopes": ["repo", "read:org"],
597
- "connectedAt": 1771657300000
598
- }
599
583
  }
600
- ---
584
+ }
585
+ }
586
+ ```
587
+
588
+ ---
601
589
 
602
590
  ## Custom Resource Storage Implementation (`ResourceStorage`)
603
591
 
@@ -691,7 +679,168 @@ export const lixa = new Lixa({
691
679
  });
692
680
  ```
693
681
 
694
- ### 2. Querying Connected Resources Directly by User ID
682
+ #### Saved JSON Records Example in SQLite (`user_resources` Table)
683
+
684
+ **Row 1 (GitHub Repositories)**:
685
+ ```json
686
+ {
687
+ "user_id": "1049281048",
688
+ "provider": "github",
689
+ "data": {
690
+ "accessToken": "gho_resource_repo_9a8b7c...",
691
+ "refreshToken": "ghr_refresh_token_123...",
692
+ "scopes": ["repo", "read:org"],
693
+ "expiresAt": 1771743600000,
694
+ "connectedAt": 1771657300000
695
+ }
696
+ }
697
+ ```
698
+
699
+ **Row 2 (Google Drive)**:
700
+ ```json
701
+ {
702
+ "user_id": "1049281048",
703
+ "provider": "google",
704
+ "data": {
705
+ "accessToken": "ya29.drive_resource_token_456...",
706
+ "refreshToken": "1//09abc_google_refresh_token...",
707
+ "scopes": ["https://www.googleapis.com/auth/drive.readonly"],
708
+ "expiresAt": 1771660800000,
709
+ "connectedAt": 1771657400000
710
+ }
711
+ }
712
+ ```
713
+
714
+ ---
715
+
716
+ ### 2. AWS DynamoDB Resource Storage (`@aws-sdk/lib-dynamodb`)
717
+
718
+ For serverless AWS deployments storing user API credentials in DynamoDB:
719
+
720
+ #### Table Configuration
721
+
722
+ - **Table Name**: `LixaUserResources`
723
+ - **Partition Key (PK)**: `userId` (String)
724
+ - **Sort Key (SK)**: `provider` (String)
725
+
726
+ #### TypeScript Implementation
727
+
728
+ ```typescript
729
+ import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
730
+ import { DynamoDBDocumentClient, PutCommand, GetCommand, DeleteCommand, QueryCommand } from "@aws-sdk/lib-dynamodb";
731
+ import { Lixa, type ResourceStorage, type ConnectedResource } from "@vunexa/lixa";
732
+
733
+ export class DynamoDbResourceStorage implements ResourceStorage {
734
+ private docClient: DynamoDBDocumentClient;
735
+ private tableName = "LixaUserResources";
736
+
737
+ constructor() {
738
+ const client = new DynamoDBClient({ region: process.env.AWS_REGION || "us-east-1" });
739
+ this.docClient = DynamoDBDocumentClient.from(client);
740
+ }
741
+
742
+ async saveResource(userId: string, provider: string, resource: ConnectedResource): Promise<void> {
743
+ await this.docClient.send(
744
+ new PutCommand({
745
+ TableName: this.tableName,
746
+ Item: {
747
+ userId,
748
+ provider: provider.toLowerCase(),
749
+ resourceData: resource,
750
+ updatedAt: Date.now(),
751
+ },
752
+ })
753
+ );
754
+ }
755
+
756
+ async getResource(userId: string, provider: string): Promise<ConnectedResource | null> {
757
+ const res = await this.docClient.send(
758
+ new GetCommand({
759
+ TableName: this.tableName,
760
+ Key: {
761
+ userId,
762
+ provider: provider.toLowerCase(),
763
+ },
764
+ })
765
+ );
766
+
767
+ return res.Item ? (res.Item.resourceData as ConnectedResource) : null;
768
+ }
769
+
770
+ async getUserResources(userId: string): Promise<Record<string, ConnectedResource>> {
771
+ const res = await this.docClient.send(
772
+ new QueryCommand({
773
+ TableName: this.tableName,
774
+ KeyConditionExpression: "userId = :userId",
775
+ ExpressionAttributeValues: { ":userId": userId },
776
+ })
777
+ );
778
+
779
+ const result: Record<string, ConnectedResource> = {};
780
+ if (res.Items) {
781
+ for (const item of res.Items) {
782
+ result[item.provider] = item.resourceData as ConnectedResource;
783
+ }
784
+ }
785
+ return result;
786
+ }
787
+
788
+ async deleteResource(userId: string, provider: string): Promise<void> {
789
+ await this.docClient.send(
790
+ new DeleteCommand({
791
+ TableName: this.tableName,
792
+ Key: {
793
+ userId,
794
+ provider: provider.toLowerCase(),
795
+ },
796
+ })
797
+ );
798
+ }
799
+ }
800
+
801
+ // Pass to Lixa instance via resourceHandler
802
+ export const lixa = new Lixa({
803
+ resourceHandler: {
804
+ resourceStorage: new DynamoDbResourceStorage(),
805
+ },
806
+ providers: { /* ... */ },
807
+ });
808
+ ```
809
+
810
+ #### Saved DynamoDB Resource Items Example (`LixaUserResources` Table)
811
+
812
+ ```json
813
+ [
814
+ {
815
+ "userId": "1049281048",
816
+ "provider": "github",
817
+ "updatedAt": 1771657300000,
818
+ "resourceData": {
819
+ "accessToken": "gho_resource_repo_9a8b7c...",
820
+ "refreshToken": "ghr_refresh_token_123...",
821
+ "scopes": ["repo", "read:org"],
822
+ "expiresAt": 1771743600000,
823
+ "connectedAt": 1771657300000
824
+ }
825
+ },
826
+ {
827
+ "userId": "1049281048",
828
+ "provider": "google",
829
+ "updatedAt": 1771657400000,
830
+ "resourceData": {
831
+ "accessToken": "ya29.drive_resource_token_456...",
832
+ "refreshToken": "1//09abc_google_refresh_token...",
833
+ "scopes": ["https://www.googleapis.com/auth/drive.readonly"],
834
+ "expiresAt": 1771660800000,
835
+ "connectedAt": 1771657400000
836
+ }
837
+ }
838
+ ]
839
+ ```
840
+
841
+ ---
842
+
843
+ ### 3. Querying Connected Resources Directly by User ID
695
844
 
696
845
  `ResourceStorage` enables background workers, cron jobs, and webhooks to access third-party API credentials by `userId` without an active HTTP session:
697
846
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vunexa/lixa",
3
- "version": "0.1.6-alpha.4",
3
+ "version": "0.1.6-alpha.7",
4
4
  "description": "Lixa is a flexible, provider-agnostic OAuth and OpenID Connect (OIDC) client library that simplifies multi-provider authentication flows. It supports seamless integration with providers like Google and GitHub, offers extensible session management, and enables dynamic provider resolution based on callback URLs.",
5
5
  "keywords": [
6
6
  "oauth",