@anymux/connect 0.1.0 → 0.2.0
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/GitBrowser-BFyS9qJb.js +3 -0
- package/dist/{GitBrowser-BLgTNQyd.js → GitBrowser-C0L48q3x.js} +5 -5
- package/dist/GitBrowser-C0L48q3x.js.map +1 -0
- package/dist/index.d.ts +52 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +161 -44
- package/dist/index.js.map +1 -1
- package/dist/registry.js +1 -1
- package/dist/{scope-labels-B4VAwoL6.js → scope-labels-C7KX6ju6.js} +266 -2
- package/dist/scope-labels-C7KX6ju6.js.map +1 -0
- package/dist/scope-labels-DvdJLcSL.d.ts.map +1 -1
- package/package.json +10 -8
- package/src/adapters/adapter-registry.ts +45 -9
- package/src/components/CapabilityPanel.tsx +6 -5
- package/src/components/ConnectButton.tsx +2 -2
- package/src/components/CredentialForm.tsx +60 -4
- package/src/components/GitBrowser.tsx +5 -5
- package/src/index.ts +7 -0
- package/src/models/ConnectionManagerModel.ts +6 -3
- package/src/models/CredentialFormModel.ts +28 -11
- package/src/registry/service-registry.ts +12 -0
- package/src/registry/services/backblaze-b2.ts +21 -0
- package/src/registry/services/cloudflare-r2.ts +21 -0
- package/src/registry/services/imgur.ts +21 -0
- package/src/registry/services/pexels.ts +21 -0
- package/src/registry/services/unsplash.ts +21 -0
- package/src/registry/services/wasabi.ts +21 -0
- package/src/types/optional-deps.d.ts +9 -9
- package/dist/GitBrowser-BLgTNQyd.js.map +0 -1
- package/dist/GitBrowser-CIyWiuX-.js +0 -3
- package/dist/scope-labels-B4VAwoL6.js.map +0 -1
package/dist/registry.js
CHANGED
|
@@ -483,6 +483,264 @@ const boxService = {
|
|
|
483
483
|
scopes: { "file-system": ["root_readwrite"] }
|
|
484
484
|
};
|
|
485
485
|
|
|
486
|
+
//#endregion
|
|
487
|
+
//#region src/registry/services/backblaze-b2.ts
|
|
488
|
+
const backblazeB2Service = {
|
|
489
|
+
id: "backblaze-b2",
|
|
490
|
+
name: "Backblaze B2",
|
|
491
|
+
icon: "HardDrive",
|
|
492
|
+
color: "#E21E29",
|
|
493
|
+
authProvider: "backblaze-b2",
|
|
494
|
+
capabilities: [
|
|
495
|
+
{
|
|
496
|
+
id: "file-system",
|
|
497
|
+
supported: false
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
id: "object-storage",
|
|
501
|
+
supported: true
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
id: "git-repo",
|
|
505
|
+
supported: false
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
id: "git-host",
|
|
509
|
+
supported: false
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
id: "media",
|
|
513
|
+
supported: false
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
id: "contacts",
|
|
517
|
+
supported: false
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
id: "calendar",
|
|
521
|
+
supported: false
|
|
522
|
+
}
|
|
523
|
+
],
|
|
524
|
+
scopes: { "object-storage": [
|
|
525
|
+
"s3:GetObject",
|
|
526
|
+
"s3:PutObject",
|
|
527
|
+
"s3:ListBucket"
|
|
528
|
+
] }
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
//#endregion
|
|
532
|
+
//#region src/registry/services/cloudflare-r2.ts
|
|
533
|
+
const cloudflareR2Service = {
|
|
534
|
+
id: "cloudflare-r2",
|
|
535
|
+
name: "Cloudflare R2",
|
|
536
|
+
icon: "Cloud",
|
|
537
|
+
color: "#F38020",
|
|
538
|
+
authProvider: "cloudflare-r2",
|
|
539
|
+
capabilities: [
|
|
540
|
+
{
|
|
541
|
+
id: "file-system",
|
|
542
|
+
supported: false
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
id: "object-storage",
|
|
546
|
+
supported: true
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
id: "git-repo",
|
|
550
|
+
supported: false
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
id: "git-host",
|
|
554
|
+
supported: false
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
id: "media",
|
|
558
|
+
supported: false
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
id: "contacts",
|
|
562
|
+
supported: false
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
id: "calendar",
|
|
566
|
+
supported: false
|
|
567
|
+
}
|
|
568
|
+
],
|
|
569
|
+
scopes: { "object-storage": [
|
|
570
|
+
"s3:GetObject",
|
|
571
|
+
"s3:PutObject",
|
|
572
|
+
"s3:ListBucket"
|
|
573
|
+
] }
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
//#endregion
|
|
577
|
+
//#region src/registry/services/wasabi.ts
|
|
578
|
+
const wasabiService = {
|
|
579
|
+
id: "wasabi",
|
|
580
|
+
name: "Wasabi",
|
|
581
|
+
icon: "Database",
|
|
582
|
+
color: "#56B847",
|
|
583
|
+
authProvider: "wasabi",
|
|
584
|
+
capabilities: [
|
|
585
|
+
{
|
|
586
|
+
id: "file-system",
|
|
587
|
+
supported: false
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
id: "object-storage",
|
|
591
|
+
supported: true
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
id: "git-repo",
|
|
595
|
+
supported: false
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
id: "git-host",
|
|
599
|
+
supported: false
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
id: "media",
|
|
603
|
+
supported: false
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
id: "contacts",
|
|
607
|
+
supported: false
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
id: "calendar",
|
|
611
|
+
supported: false
|
|
612
|
+
}
|
|
613
|
+
],
|
|
614
|
+
scopes: { "object-storage": [
|
|
615
|
+
"s3:GetObject",
|
|
616
|
+
"s3:PutObject",
|
|
617
|
+
"s3:ListBucket"
|
|
618
|
+
] }
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
//#endregion
|
|
622
|
+
//#region src/registry/services/unsplash.ts
|
|
623
|
+
const unsplashService = {
|
|
624
|
+
id: "unsplash",
|
|
625
|
+
name: "Unsplash",
|
|
626
|
+
icon: "Image",
|
|
627
|
+
color: "#111111",
|
|
628
|
+
authProvider: "unsplash",
|
|
629
|
+
capabilities: [
|
|
630
|
+
{
|
|
631
|
+
id: "file-system",
|
|
632
|
+
supported: false
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
id: "object-storage",
|
|
636
|
+
supported: false
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
id: "git-repo",
|
|
640
|
+
supported: false
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
id: "git-host",
|
|
644
|
+
supported: false
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
id: "media",
|
|
648
|
+
supported: true
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
id: "contacts",
|
|
652
|
+
supported: false
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
id: "calendar",
|
|
656
|
+
supported: false
|
|
657
|
+
}
|
|
658
|
+
],
|
|
659
|
+
scopes: { "media": ["public"] }
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
//#endregion
|
|
663
|
+
//#region src/registry/services/pexels.ts
|
|
664
|
+
const pexelsService = {
|
|
665
|
+
id: "pexels",
|
|
666
|
+
name: "Pexels",
|
|
667
|
+
icon: "Camera",
|
|
668
|
+
color: "#05A081",
|
|
669
|
+
authProvider: "pexels",
|
|
670
|
+
capabilities: [
|
|
671
|
+
{
|
|
672
|
+
id: "file-system",
|
|
673
|
+
supported: false
|
|
674
|
+
},
|
|
675
|
+
{
|
|
676
|
+
id: "object-storage",
|
|
677
|
+
supported: false
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
id: "git-repo",
|
|
681
|
+
supported: false
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
id: "git-host",
|
|
685
|
+
supported: false
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
id: "media",
|
|
689
|
+
supported: true
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
id: "contacts",
|
|
693
|
+
supported: false
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
id: "calendar",
|
|
697
|
+
supported: false
|
|
698
|
+
}
|
|
699
|
+
],
|
|
700
|
+
scopes: { "media": ["read"] }
|
|
701
|
+
};
|
|
702
|
+
|
|
703
|
+
//#endregion
|
|
704
|
+
//#region src/registry/services/imgur.ts
|
|
705
|
+
const imgurService = {
|
|
706
|
+
id: "imgur",
|
|
707
|
+
name: "Imgur",
|
|
708
|
+
icon: "ImagePlus",
|
|
709
|
+
color: "#1BB76E",
|
|
710
|
+
authProvider: "imgur",
|
|
711
|
+
capabilities: [
|
|
712
|
+
{
|
|
713
|
+
id: "file-system",
|
|
714
|
+
supported: false
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
id: "object-storage",
|
|
718
|
+
supported: false
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
id: "git-repo",
|
|
722
|
+
supported: false
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
id: "git-host",
|
|
726
|
+
supported: false
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
id: "media",
|
|
730
|
+
supported: true
|
|
731
|
+
},
|
|
732
|
+
{
|
|
733
|
+
id: "contacts",
|
|
734
|
+
supported: false
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
id: "calendar",
|
|
738
|
+
supported: false
|
|
739
|
+
}
|
|
740
|
+
],
|
|
741
|
+
scopes: { "media": ["read"] }
|
|
742
|
+
};
|
|
743
|
+
|
|
486
744
|
//#endregion
|
|
487
745
|
//#region src/registry/service-registry.ts
|
|
488
746
|
const services = new Map();
|
|
@@ -500,6 +758,12 @@ register(giteaService);
|
|
|
500
758
|
register(browserFsService);
|
|
501
759
|
register(indexeddbService);
|
|
502
760
|
register(boxService);
|
|
761
|
+
register(backblazeB2Service);
|
|
762
|
+
register(cloudflareR2Service);
|
|
763
|
+
register(wasabiService);
|
|
764
|
+
register(unsplashService);
|
|
765
|
+
register(pexelsService);
|
|
766
|
+
register(imgurService);
|
|
503
767
|
const serviceRegistry = {
|
|
504
768
|
get(id) {
|
|
505
769
|
return services.get(id);
|
|
@@ -578,5 +842,5 @@ function getScopeLabels(scopes) {
|
|
|
578
842
|
}
|
|
579
843
|
|
|
580
844
|
//#endregion
|
|
581
|
-
export { bitbucketService, browserFsService, dropboxService, getScopeLabel, getScopeLabels, giteaService, githubService, gitlabService, googleService, indexeddbService, s3Service, serviceRegistry, webdavService };
|
|
582
|
-
//# sourceMappingURL=scope-labels-
|
|
845
|
+
export { backblazeB2Service, bitbucketService, browserFsService, cloudflareR2Service, dropboxService, getScopeLabel, getScopeLabels, giteaService, githubService, gitlabService, googleService, imgurService, indexeddbService, pexelsService, s3Service, serviceRegistry, unsplashService, wasabiService, webdavService };
|
|
846
|
+
//# sourceMappingURL=scope-labels-C7KX6ju6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-labels-C7KX6ju6.js","names":["googleService: ServiceDefinition","dropboxService: ServiceDefinition","githubService: ServiceDefinition","s3Service: ServiceDefinition","webdavService: ServiceDefinition","gitlabService: ServiceDefinition","bitbucketService: ServiceDefinition","giteaService: ServiceDefinition","browserFsService: ServiceDefinition","indexeddbService: ServiceDefinition","boxService: ServiceDefinition","backblazeB2Service: ServiceDefinition","cloudflareR2Service: ServiceDefinition","wasabiService: ServiceDefinition","unsplashService: ServiceDefinition","pexelsService: ServiceDefinition","imgurService: ServiceDefinition","service: ServiceDefinition","id: string","capability: CapabilityId","SCOPE_LABELS: Record<string, string>","scope: string","segment: string","scopes: string[]"],"sources":["../src/registry/services/google.ts","../src/registry/services/dropbox.ts","../src/registry/services/github.ts","../src/registry/services/s3.ts","../src/registry/services/webdav.ts","../src/registry/services/gitlab.ts","../src/registry/services/bitbucket.ts","../src/registry/services/gitea.ts","../src/registry/services/browser-fs.ts","../src/registry/services/indexeddb.ts","../src/registry/services/box.ts","../src/registry/services/backblaze-b2.ts","../src/registry/services/cloudflare-r2.ts","../src/registry/services/wasabi.ts","../src/registry/services/unsplash.ts","../src/registry/services/pexels.ts","../src/registry/services/imgur.ts","../src/registry/service-registry.ts","../src/utils/scope-labels.ts"],"sourcesContent":["import type { ServiceDefinition } from '../../types/service';\n\nexport const googleService: ServiceDefinition = {\n id: 'google',\n name: 'Google',\n icon: 'Cloud',\n color: '#4285F4',\n authProvider: 'google',\n grantsUrl: 'https://myaccount.google.com/permissions',\n capabilities: [\n { id: 'file-system', supported: true },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: false },\n { id: 'contacts', supported: true },\n { id: 'calendar', supported: true },\n ],\n scopes: {\n 'file-system': ['https://www.googleapis.com/auth/drive'],\n 'calendar': ['https://www.googleapis.com/auth/calendar.readonly'],\n 'contacts': ['https://www.googleapis.com/auth/contacts.readonly'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const dropboxService: ServiceDefinition = {\n id: 'dropbox',\n name: 'Dropbox',\n icon: 'Box',\n color: '#0061FF',\n authProvider: 'dropbox',\n grantsUrl: 'https://www.dropbox.com/account/connected_apps',\n capabilities: [\n { id: 'file-system', supported: true },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'file-system': ['files.metadata.read', 'files.content.read', 'files.content.write'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const githubService: ServiceDefinition = {\n id: 'github',\n name: 'GitHub',\n icon: 'Github',\n color: '#24292F',\n authProvider: 'github',\n grantsUrl: 'https://github.com/settings/applications',\n capabilities: [\n { id: 'file-system', supported: true },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: true },\n { id: 'git-host', supported: true },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'file-system': ['repo'],\n 'git-repo': ['repo'],\n 'git-host': ['repo'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const s3Service: ServiceDefinition = {\n id: 's3',\n name: 'Amazon S3',\n icon: 'Database',\n color: '#FF9900',\n authProvider: 's3',\n capabilities: [\n { id: 'file-system', supported: false },\n { id: 'object-storage', supported: true },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'object-storage': ['s3:GetObject', 's3:PutObject', 's3:ListBucket'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const webdavService: ServiceDefinition = {\n id: 'webdav',\n name: 'WebDAV',\n icon: 'Server',\n color: '#6B7280',\n authProvider: 'webdav',\n capabilities: [\n { id: 'file-system', supported: true },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'file-system': [],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const gitlabService: ServiceDefinition = {\n id: 'gitlab',\n name: 'GitLab',\n icon: 'GitBranch',\n color: '#FC6D26',\n authProvider: 'gitlab',\n grantsUrl: 'https://gitlab.com/-/user_settings/applications',\n capabilities: [\n { id: 'file-system', supported: true },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: true },\n { id: 'git-host', supported: true },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'file-system': ['read_api'],\n 'git-repo': ['read_api'],\n 'git-host': ['read_api'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const bitbucketService: ServiceDefinition = {\n id: 'bitbucket',\n name: 'Bitbucket',\n icon: 'GitBranch',\n color: '#0052CC',\n authProvider: 'bitbucket',\n grantsUrl: 'https://bitbucket.org/account/settings/app-authorizations/',\n capabilities: [\n { id: 'file-system', supported: true },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: true },\n { id: 'git-host', supported: true },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'file-system': ['repository'],\n 'git-repo': ['repository'],\n 'git-host': ['repository', 'pullrequest'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const giteaService: ServiceDefinition = {\n id: 'gitea',\n name: 'Gitea',\n icon: 'GitBranch',\n color: '#609926',\n authProvider: 'gitea',\n grantsUrl: 'https://gitea.io/en-us/user_settings/applications',\n capabilities: [\n { id: 'file-system', supported: true },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: true },\n { id: 'git-host', supported: true },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'file-system': ['read:repository'],\n 'git-repo': ['read:repository'],\n 'git-host': ['read:repository', 'read:user'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const browserFsService: ServiceDefinition = {\n id: 'browser-fs',\n name: 'Local Files',\n icon: 'FolderOpen',\n color: '#4CAF50',\n authProvider: 'browser-fs',\n capabilities: [\n { id: 'file-system', supported: true },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {},\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const indexeddbService: ServiceDefinition = {\n id: 'indexeddb',\n name: 'IndexedDB',\n icon: 'Database',\n color: '#FF9800',\n authProvider: 'indexeddb',\n capabilities: [\n { id: 'file-system', supported: true },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {},\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const boxService: ServiceDefinition = {\n id: 'box',\n name: 'Box',\n icon: 'Box',\n color: '#0061D5',\n authProvider: 'box',\n grantsUrl: 'https://app.box.com/account/security',\n capabilities: [\n { id: 'file-system', supported: true },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'file-system': ['root_readwrite'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const backblazeB2Service: ServiceDefinition = {\n id: 'backblaze-b2',\n name: 'Backblaze B2',\n icon: 'HardDrive',\n color: '#E21E29',\n authProvider: 'backblaze-b2',\n capabilities: [\n { id: 'file-system', supported: false },\n { id: 'object-storage', supported: true },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'object-storage': ['s3:GetObject', 's3:PutObject', 's3:ListBucket'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const cloudflareR2Service: ServiceDefinition = {\n id: 'cloudflare-r2',\n name: 'Cloudflare R2',\n icon: 'Cloud',\n color: '#F38020',\n authProvider: 'cloudflare-r2',\n capabilities: [\n { id: 'file-system', supported: false },\n { id: 'object-storage', supported: true },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'object-storage': ['s3:GetObject', 's3:PutObject', 's3:ListBucket'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const wasabiService: ServiceDefinition = {\n id: 'wasabi',\n name: 'Wasabi',\n icon: 'Database',\n color: '#56B847',\n authProvider: 'wasabi',\n capabilities: [\n { id: 'file-system', supported: false },\n { id: 'object-storage', supported: true },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: false },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'object-storage': ['s3:GetObject', 's3:PutObject', 's3:ListBucket'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const unsplashService: ServiceDefinition = {\n id: 'unsplash',\n name: 'Unsplash',\n icon: 'Image',\n color: '#111111',\n authProvider: 'unsplash',\n capabilities: [\n { id: 'file-system', supported: false },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: true },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'media': ['public'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const pexelsService: ServiceDefinition = {\n id: 'pexels',\n name: 'Pexels',\n icon: 'Camera',\n color: '#05A081',\n authProvider: 'pexels',\n capabilities: [\n { id: 'file-system', supported: false },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: true },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'media': ['read'],\n },\n};\n","import type { ServiceDefinition } from '../../types/service';\n\nexport const imgurService: ServiceDefinition = {\n id: 'imgur',\n name: 'Imgur',\n icon: 'ImagePlus',\n color: '#1BB76E',\n authProvider: 'imgur',\n capabilities: [\n { id: 'file-system', supported: false },\n { id: 'object-storage', supported: false },\n { id: 'git-repo', supported: false },\n { id: 'git-host', supported: false },\n { id: 'media', supported: true },\n { id: 'contacts', supported: false },\n { id: 'calendar', supported: false },\n ],\n scopes: {\n 'media': ['read'],\n },\n};\n","import type { CapabilityId, ServiceDefinition } from '../types/service';\nimport { googleService } from './services/google';\nimport { dropboxService } from './services/dropbox';\nimport { githubService } from './services/github';\nimport { s3Service } from './services/s3';\nimport { webdavService } from './services/webdav';\nimport { gitlabService } from './services/gitlab';\nimport { bitbucketService } from './services/bitbucket';\nimport { giteaService } from './services/gitea';\nimport { browserFsService } from './services/browser-fs';\nimport { indexeddbService } from './services/indexeddb';\nimport { boxService } from './services/box';\nimport { backblazeB2Service } from './services/backblaze-b2';\nimport { cloudflareR2Service } from './services/cloudflare-r2';\nimport { wasabiService } from './services/wasabi';\nimport { unsplashService } from './services/unsplash';\nimport { pexelsService } from './services/pexels';\nimport { imgurService } from './services/imgur';\n\nconst services = new Map<string, ServiceDefinition>();\n\nfunction register(service: ServiceDefinition) {\n services.set(service.id, service);\n}\n\nregister(googleService);\nregister(dropboxService);\nregister(githubService);\nregister(s3Service);\nregister(webdavService);\nregister(gitlabService);\nregister(bitbucketService);\nregister(giteaService);\nregister(browserFsService);\nregister(indexeddbService);\nregister(boxService);\nregister(backblazeB2Service);\nregister(cloudflareR2Service);\nregister(wasabiService);\nregister(unsplashService);\nregister(pexelsService);\nregister(imgurService);\n\nexport const serviceRegistry = {\n get(id: string): ServiceDefinition | undefined {\n return services.get(id);\n },\n\n getAll(): ServiceDefinition[] {\n return Array.from(services.values());\n },\n\n getByCapability(capability: CapabilityId): ServiceDefinition[] {\n return Array.from(services.values()).filter((s) =>\n s.capabilities.some((c) => c.id === capability && c.supported)\n );\n },\n};\n","/**\n * Maps raw OAuth scope strings to human-readable descriptions.\n * Falls back to a cleaned-up version of the scope string for unknown scopes.\n */\n\nconst SCOPE_LABELS: Record<string, string> = {\n // GitHub\n 'repo': 'Repository access',\n 'read:user': 'Read user profile',\n 'user:email': 'Read email address',\n 'gist': 'Gist access',\n 'read:org': 'Read organizations',\n\n // Google\n 'https://www.googleapis.com/auth/drive': 'Google Drive',\n 'https://www.googleapis.com/auth/drive.readonly': 'Google Drive (read-only)',\n 'https://www.googleapis.com/auth/calendar.readonly': 'Calendar (read-only)',\n 'https://www.googleapis.com/auth/calendar': 'Calendar',\n 'https://www.googleapis.com/auth/contacts.readonly': 'Contacts (read-only)',\n 'https://www.googleapis.com/auth/contacts': 'Contacts',\n\n // Microsoft\n 'Files.ReadWrite.All': 'File read/write',\n 'Files.Read.All': 'File read',\n 'Contacts.Read': 'Contacts (read-only)',\n 'Calendars.Read': 'Calendar (read-only)',\n 'User.Read': 'User profile',\n\n // GitLab\n 'read_api': 'API read access',\n 'read_repository': 'Repository read access',\n 'api': 'Full API access',\n 'read_user': 'Read user profile',\n\n // Bitbucket\n 'repository': 'Repository access',\n 'pullrequest': 'Pull request access',\n 'account': 'Account access',\n\n // Dropbox\n 'files.metadata.read': 'Read file metadata',\n 'files.content.read': 'Read file content',\n 'files.content.write': 'Write file content',\n\n // S3\n 's3:GetObject': 'Read objects',\n 's3:PutObject': 'Write objects',\n 's3:ListBucket': 'List buckets',\n\n // Box\n 'root_readwrite': 'Read & write all files',\n\n // Gitea\n 'read:repository': 'Repository read access',\n 'write:repository': 'Repository write access',\n};\n\n/**\n * Returns a human-readable label for a scope string.\n * Unknown scopes get cleaned up: URL paths are extracted, dots/underscores become spaces.\n */\nexport function getScopeLabel(scope: string): string {\n if (SCOPE_LABELS[scope]) {\n return SCOPE_LABELS[scope];\n }\n\n // Google-style URL scopes: extract the last path segment\n if (scope.startsWith('https://')) {\n const last = scope.split('/').pop() ?? scope;\n return formatScopeSegment(last);\n }\n\n return formatScopeSegment(scope);\n}\n\n/** Turn a scope segment like \"files.content.read\" into \"Files content read\" */\nfunction formatScopeSegment(segment: string): string {\n return segment\n .replace(/[._:]/g, ' ')\n .replace(/\\b\\w/g, c => c.toUpperCase())\n .trim();\n}\n\n/**\n * Deduplicate and label a list of scope strings.\n * Returns unique human-readable labels sorted alphabetically.\n */\nexport function getScopeLabels(scopes: string[]): string[] {\n const unique = [...new Set(scopes)];\n return unique.map(getScopeLabel).sort();\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope-labels-DvdJLcSL.d.ts","names":[],"sources":["../src/types/service.ts","../src/registry/service-registry.ts","../src/utils/scope-labels.ts"],"sourcesContent":null,"mappings":";KAAY,YAAA;AAAA,UAEK,iBAAA,CAFO;EAEP,EAAA,EACX,YADW;EAKA,SAAA,EAAA,OAAA;;AAMD,UANC,iBAAA,CAMD;EAAiB,EAAA,EACR,MAAA;EAAY,IAAnB,EAAA,MAAA;EAAM,IAAd,EAAA,MAAA;EAAO,KAAA,EAAA,MAAA;;gBADD;UACN,QAAQ,OAAO;
|
|
1
|
+
{"version":3,"file":"scope-labels-DvdJLcSL.d.ts","names":[],"sources":["../src/types/service.ts","../src/registry/service-registry.ts","../src/utils/scope-labels.ts"],"sourcesContent":null,"mappings":";KAAY,YAAA;AAAA,UAEK,iBAAA,CAFO;EAEP,EAAA,EACX,YADW;EAKA,SAAA,EAAA,OAAA;;AAMD,UANC,iBAAA,CAMD;EAAiB,EAAA,EACR,MAAA;EAAY,IAAnB,EAAA,MAAA;EAAM,IAAd,EAAA,MAAA;EAAO,KAAA,EAAA,MAAA;;gBADD;UACN,QAAQ,OAAO;EC6BZ;EAcZ,SAAA,CAAA,EAAA,MAAA;CAAA;;;;ADzDW,cC2CC,eD3CW,EAAA;EAEP,GAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EC0CE,iBDzCb,GAAA,SAAY;EAID,MAAA,EAAA,ECyCL,iBDzCsB,EAAA;EAAA,eAAA,CAAA,UAAA,EC6CJ,YD7CI,CAAA,EC6CW,iBD7CX,EAAA;CAAA;;;;;;;AAPlC;AAEA;AAKA;;;;;AAOU,iBE+CM,aAAA,CF/CN,KAAA,EAAA,MAAA,CAAA,EAAA,MAAA;AAAO;;;;AC6BJ,iBC4CG,cAAA,CD9Bf,MAAA,EAAA,MAAA,EAAA,CAAA,EAAA,MAAA,EAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anymux/connect",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "HelloJS-style service connection dashboard for AnyMux",
|
|
@@ -45,22 +45,25 @@
|
|
|
45
45
|
"sonner": "^2.0.3",
|
|
46
46
|
"ts-pattern": "^5.6.0",
|
|
47
47
|
"zod": "^3.24.0",
|
|
48
|
-
"@anymux/box": "0.1.0",
|
|
49
48
|
"@anymux/bitbucket": "0.1.0",
|
|
49
|
+
"@anymux/box": "0.1.0",
|
|
50
|
+
"@anymux/browser-fs": "0.1.0",
|
|
50
51
|
"@anymux/dropbox": "0.1.0",
|
|
51
52
|
"@anymux/file-system": "0.1.0",
|
|
52
|
-
"@anymux/browser-fs": "0.1.0",
|
|
53
53
|
"@anymux/flickr": "0.1.0",
|
|
54
54
|
"@anymux/instagram": "0.1.0",
|
|
55
55
|
"@anymux/gitea": "0.1.0",
|
|
56
56
|
"@anymux/github": "0.1.0",
|
|
57
57
|
"@anymux/icloud": "0.1.0",
|
|
58
58
|
"@anymux/gitlab": "0.1.0",
|
|
59
|
-
"@anymux/microsoft": "0.1.0",
|
|
60
|
-
"@anymux/indexeddb": "0.1.0",
|
|
61
59
|
"@anymux/google-drive": "0.1.0",
|
|
62
|
-
"@anymux/
|
|
60
|
+
"@anymux/indexeddb": "0.1.0",
|
|
61
|
+
"@anymux/microsoft": "0.1.0",
|
|
62
|
+
"@anymux/imgur": "0.1.0",
|
|
63
|
+
"@anymux/pexels": "0.1.0",
|
|
63
64
|
"@anymux/s3": "0.1.0",
|
|
65
|
+
"@anymux/ui": "0.1.0",
|
|
66
|
+
"@anymux/unsplash": "0.1.0",
|
|
64
67
|
"@anymux/webdav": "0.1.0"
|
|
65
68
|
},
|
|
66
69
|
"peerDependencies": {
|
|
@@ -76,8 +79,7 @@
|
|
|
76
79
|
"lucide-react": "^0.475.0",
|
|
77
80
|
"tsdown": "^0.10.2",
|
|
78
81
|
"typescript": "^5.7.3",
|
|
79
|
-
"@anymux/
|
|
80
|
-
"@anymux/object-ui": "0.1.0",
|
|
82
|
+
"@anymux/ui-kit": "0.2.0",
|
|
81
83
|
"@anymux/typescript-config": "0.0.0"
|
|
82
84
|
},
|
|
83
85
|
"scripts": {
|
|
@@ -41,6 +41,18 @@ export const adapterRegistry = {
|
|
|
41
41
|
// --- Register all adapter factories ---
|
|
42
42
|
// Capability validation is handled by the service registry; factories only create adapters.
|
|
43
43
|
|
|
44
|
+
/** Safely invoke a capability factory, throwing a descriptive error for unsupported capabilities */
|
|
45
|
+
function invokeCapability(adapters: Partial<Record<CapabilityId, () => unknown>>, capabilityId: CapabilityId, serviceId: string): unknown {
|
|
46
|
+
const factory = adapters[capabilityId];
|
|
47
|
+
if (!factory) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`Unsupported capability "${capabilityId}" for service "${serviceId}". ` +
|
|
50
|
+
`Supported: ${Object.keys(adapters).join(', ')}`,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
return factory();
|
|
54
|
+
}
|
|
55
|
+
|
|
44
56
|
// Google Drive / Contacts / Calendar
|
|
45
57
|
adapterRegistry.register('google', async (token, capabilityId) => {
|
|
46
58
|
const m = await import('@anymux/google-drive');
|
|
@@ -49,7 +61,7 @@ adapterRegistry.register('google', async (token, capabilityId) => {
|
|
|
49
61
|
'contacts': () => new m.GoogleContactsProvider(token),
|
|
50
62
|
'calendar': () => new m.GoogleCalendarProvider(token),
|
|
51
63
|
};
|
|
52
|
-
return adapters
|
|
64
|
+
return invokeCapability(adapters, capabilityId, 'google');
|
|
53
65
|
});
|
|
54
66
|
|
|
55
67
|
// Dropbox
|
|
@@ -75,7 +87,7 @@ adapterRegistry.register('github', async (token, capabilityId, ctx) => {
|
|
|
75
87
|
'git-repo': () => new m.GitHubGitRepo(config),
|
|
76
88
|
'git-host': () => new m.GitHubGitHost(config),
|
|
77
89
|
};
|
|
78
|
-
return adapters
|
|
90
|
+
return invokeCapability(adapters, capabilityId, 'github');
|
|
79
91
|
});
|
|
80
92
|
|
|
81
93
|
// GitLab
|
|
@@ -89,7 +101,7 @@ adapterRegistry.register('gitlab', async (token, capabilityId, ctx) => {
|
|
|
89
101
|
'git-repo': () => new m.GitLabGitRepo(config),
|
|
90
102
|
'git-host': () => new m.GitLabGitHost(config),
|
|
91
103
|
};
|
|
92
|
-
return adapters
|
|
104
|
+
return invokeCapability(adapters, capabilityId, 'gitlab');
|
|
93
105
|
});
|
|
94
106
|
|
|
95
107
|
// Bitbucket
|
|
@@ -103,7 +115,7 @@ adapterRegistry.register('bitbucket', async (token, capabilityId, ctx) => {
|
|
|
103
115
|
'git-repo': () => new m.BitbucketGitRepo(config),
|
|
104
116
|
'git-host': () => new m.BitbucketGitHost(config),
|
|
105
117
|
};
|
|
106
|
-
return adapters
|
|
118
|
+
return invokeCapability(adapters, capabilityId, 'bitbucket');
|
|
107
119
|
});
|
|
108
120
|
|
|
109
121
|
// Gitea
|
|
@@ -117,7 +129,7 @@ adapterRegistry.register('gitea', async (token, capabilityId, ctx) => {
|
|
|
117
129
|
'git-repo': () => new m.GiteaGitRepo(config),
|
|
118
130
|
'git-host': () => new m.GiteaGitHost(config),
|
|
119
131
|
};
|
|
120
|
-
return adapters
|
|
132
|
+
return invokeCapability(adapters, capabilityId, 'gitea');
|
|
121
133
|
});
|
|
122
134
|
|
|
123
135
|
// WebDAV
|
|
@@ -128,12 +140,11 @@ adapterRegistry.register('webdav', async (token) => {
|
|
|
128
140
|
return new WebDAVFileSystem({ url: creds.url, username: creds.username, password: creds.password, proxyUrl });
|
|
129
141
|
});
|
|
130
142
|
|
|
131
|
-
// S3
|
|
132
|
-
|
|
143
|
+
// S3-compatible adapter factory (shared by S3, Backblaze B2, Cloudflare R2, Wasabi)
|
|
144
|
+
async function createS3Adapter(token: string) {
|
|
133
145
|
const creds = JSON.parse(token);
|
|
134
146
|
const proxyUrl = typeof window !== 'undefined' ? window.location.origin : undefined;
|
|
135
147
|
if (proxyUrl) {
|
|
136
|
-
// Browser: use proxy to avoid CORS
|
|
137
148
|
const { S3ProxyStorage } = await import('@anymux/s3');
|
|
138
149
|
const storage = new S3ProxyStorage({
|
|
139
150
|
proxyUrl,
|
|
@@ -145,7 +156,6 @@ adapterRegistry.register('s3', async (token) => {
|
|
|
145
156
|
});
|
|
146
157
|
return { storage, bucket: creds.bucket || 'anymux-test' };
|
|
147
158
|
}
|
|
148
|
-
// Server: use direct SDK
|
|
149
159
|
const { S3ObjectStorage } = await import('@anymux/s3');
|
|
150
160
|
const storage = new S3ObjectStorage({
|
|
151
161
|
region: creds.region?.trim(),
|
|
@@ -154,6 +164,32 @@ adapterRegistry.register('s3', async (token) => {
|
|
|
154
164
|
forcePathStyle: true,
|
|
155
165
|
});
|
|
156
166
|
return { storage, bucket: creds.bucket || 'anymux-test' };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
adapterRegistry.register('s3', createS3Adapter);
|
|
170
|
+
adapterRegistry.register('backblaze-b2', createS3Adapter);
|
|
171
|
+
adapterRegistry.register('cloudflare-r2', createS3Adapter);
|
|
172
|
+
adapterRegistry.register('wasabi', createS3Adapter);
|
|
173
|
+
|
|
174
|
+
// Unsplash
|
|
175
|
+
adapterRegistry.register('unsplash', async (token) => {
|
|
176
|
+
const creds = JSON.parse(token);
|
|
177
|
+
const { UnsplashMediaProvider } = await import('@anymux/unsplash');
|
|
178
|
+
return new UnsplashMediaProvider({ accessKey: creds.accessKey });
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Pexels
|
|
182
|
+
adapterRegistry.register('pexels', async (token) => {
|
|
183
|
+
const creds = JSON.parse(token);
|
|
184
|
+
const { PexelsMediaProvider } = await import('@anymux/pexels');
|
|
185
|
+
return new PexelsMediaProvider({ apiKey: creds.apiKey });
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Imgur
|
|
189
|
+
adapterRegistry.register('imgur', async (token) => {
|
|
190
|
+
const creds = JSON.parse(token);
|
|
191
|
+
const { ImgurMediaProvider } = await import('@anymux/imgur');
|
|
192
|
+
return new ImgurMediaProvider({ clientId: creds.clientId });
|
|
157
193
|
});
|
|
158
194
|
|
|
159
195
|
// BrowserFS (File System Access API)
|
|
@@ -15,11 +15,11 @@ import { CapabilityError, isAuthError } from './CapabilityError';
|
|
|
15
15
|
|
|
16
16
|
// Lazy-load browser components
|
|
17
17
|
const FileBrowser = React.lazy(() =>
|
|
18
|
-
import('@anymux/
|
|
18
|
+
import('@anymux/ui-kit/file-browser').then((m) => ({ default: m.FileBrowser }))
|
|
19
19
|
);
|
|
20
20
|
|
|
21
21
|
const LazyMediaBrowser = React.lazy(() =>
|
|
22
|
-
import('@anymux/
|
|
22
|
+
import('@anymux/ui-kit/media').then((m) => ({
|
|
23
23
|
default: ({ provider }: { provider: unknown }) => {
|
|
24
24
|
const model = new m.MediaBrowserModel(provider as never);
|
|
25
25
|
return React.createElement(m.MediaBrowser, { model, provider: provider as never, className: 'h-full' });
|
|
@@ -28,7 +28,7 @@ const LazyMediaBrowser = React.lazy(() =>
|
|
|
28
28
|
);
|
|
29
29
|
|
|
30
30
|
const LazyContactBrowser = React.lazy(() =>
|
|
31
|
-
import('@anymux/
|
|
31
|
+
import('@anymux/ui-kit/contacts').then((m) => ({
|
|
32
32
|
default: ({ provider }: { provider: unknown }) => {
|
|
33
33
|
const model = new m.ContactListModel(provider as never);
|
|
34
34
|
return React.createElement(m.ContactBrowser, { model, className: 'h-full' });
|
|
@@ -37,7 +37,7 @@ const LazyContactBrowser = React.lazy(() =>
|
|
|
37
37
|
);
|
|
38
38
|
|
|
39
39
|
const LazyCalendarBrowser = React.lazy(() =>
|
|
40
|
-
import('@anymux/
|
|
40
|
+
import('@anymux/ui-kit/calendar').then((m) => ({
|
|
41
41
|
default: ({ provider }: { provider: unknown }) => {
|
|
42
42
|
const model = new m.CalendarModel(provider as never);
|
|
43
43
|
return React.createElement(m.CalendarBrowser, { model, className: 'h-full' });
|
|
@@ -275,7 +275,8 @@ const GenericCapabilityContent = observer(function GenericCapabilityContent({
|
|
|
275
275
|
await connectionManager.disconnect(serviceId);
|
|
276
276
|
dashboardModel.closePanel();
|
|
277
277
|
// For OAuth services, immediately redirect to provider consent screen
|
|
278
|
-
const
|
|
278
|
+
const CRED_PROVIDERS = new Set(['s3', 'backblaze-b2', 'cloudflare-r2', 'wasabi', 'webdav', 'gitea', 'icloud', 'unsplash', 'pexels', 'imgur', 'browser-fs', 'indexeddb']);
|
|
279
|
+
const isOAuth = service && !CRED_PROVIDERS.has(service.authProvider);
|
|
279
280
|
if (isOAuth) {
|
|
280
281
|
await connectionManager.connect(serviceId);
|
|
281
282
|
} else {
|
|
@@ -5,7 +5,7 @@ import { ConnectionBadge } from '@anymux/ui/components/connection-badge';
|
|
|
5
5
|
import type { ConnectionManagerModel } from '../models/ConnectionManagerModel';
|
|
6
6
|
import type { ServiceDefinition } from '../types/service';
|
|
7
7
|
import { getServiceConnectionState } from '../types/connection-state';
|
|
8
|
-
import { CredentialFormModel, type CredentialServiceType } from '../models/CredentialFormModel';
|
|
8
|
+
import { CredentialFormModel, type CredentialServiceType, isS3Compatible } from '../models/CredentialFormModel';
|
|
9
9
|
import { CredentialForm } from './CredentialForm';
|
|
10
10
|
import { ConnectedMenu } from './ConnectedMenu';
|
|
11
11
|
|
|
@@ -18,7 +18,7 @@ export const ConnectButton: React.FC<ConnectButtonProps> = observer(({ service,
|
|
|
18
18
|
const [formModel] = useState(() => new CredentialFormModel());
|
|
19
19
|
const state = getServiceConnectionState(connectionManager, service.id);
|
|
20
20
|
|
|
21
|
-
const needsCredentialForm = service.authProvider
|
|
21
|
+
const needsCredentialForm = isS3Compatible(service.authProvider as CredentialServiceType) || service.authProvider === 'webdav' || service.authProvider === 'gitea' || service.authProvider === 'icloud' || service.authProvider === 'unsplash' || service.authProvider === 'pexels' || service.authProvider === 'imgur';
|
|
22
22
|
const isBrowserFs = service.authProvider === 'browser-fs';
|
|
23
23
|
const isIndexedDb = service.authProvider === 'indexeddb';
|
|
24
24
|
|