@every-app/sdk 0.3.0-rc.5 → 0.3.0-rc.6

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 (76) hide show
  1. package/dist/cloudflare/catalogSettings.generated.d.ts +1 -16
  2. package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -1
  3. package/dist/cloudflare/catalogSettings.generated.js +0 -49
  4. package/dist/cloudflare/worker.d.ts +14 -0
  5. package/dist/cloudflare/worker.d.ts.map +1 -1
  6. package/dist/cloudflare/worker.js +19 -6
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/internal/aiDefault.d.ts +70 -7
  10. package/dist/internal/aiDefault.d.ts.map +1 -1
  11. package/dist/internal/aiDefault.js +145 -15
  12. package/dist/internal/aiProviders.d.ts +3 -1
  13. package/dist/internal/aiProviders.d.ts.map +1 -1
  14. package/dist/internal/aiProviders.js +12 -3
  15. package/dist/internal/appSettings.d.ts +65 -5
  16. package/dist/internal/appSettings.d.ts.map +1 -1
  17. package/dist/internal/appSettings.js +141 -23
  18. package/dist/internal/capabilities.d.ts +52 -433
  19. package/dist/internal/capabilities.d.ts.map +1 -1
  20. package/dist/internal/capabilities.js +25 -558
  21. package/dist/internal/catalog/index.d.ts +6 -6
  22. package/dist/internal/catalog/inference.d.ts +6 -6
  23. package/dist/internal/catalog/inference.d.ts.map +1 -1
  24. package/dist/internal/catalog/inference.js +9 -6
  25. package/dist/internal/events.d.ts.map +1 -1
  26. package/dist/internal/events.js +1 -0
  27. package/dist/internal/gatewaySettings.d.ts +0 -6
  28. package/dist/internal/gatewaySettings.d.ts.map +1 -1
  29. package/dist/internal/gatewaySettings.js +1 -14
  30. package/dist/internal/identity.d.ts +12 -1
  31. package/dist/internal/identity.d.ts.map +1 -1
  32. package/dist/internal/identity.js +11 -1
  33. package/dist/internal/oauthClient.d.ts +10 -12
  34. package/dist/internal/oauthClient.d.ts.map +1 -1
  35. package/dist/internal/oauthClient.js +20 -81
  36. package/dist/internal/oauthPresets.d.ts +7 -3
  37. package/dist/internal/oauthPresets.d.ts.map +1 -1
  38. package/dist/internal/oauthPresets.js +533 -3
  39. package/dist/internal/oauthSpec.d.ts +44 -1
  40. package/dist/internal/oauthSpec.d.ts.map +1 -1
  41. package/dist/internal/oauthSpec.js +147 -34
  42. package/dist/internal/protocol.d.ts +14 -0
  43. package/dist/internal/protocol.d.ts.map +1 -1
  44. package/dist/internal/protocol.js +7 -0
  45. package/dist/internal/providerRegistry.d.ts +61 -1
  46. package/dist/internal/providerRegistry.d.ts.map +1 -1
  47. package/dist/internal/providerRegistry.js +127 -6
  48. package/dist/internal/providerSpec.d.ts +14 -7
  49. package/dist/internal/providerSpec.d.ts.map +1 -1
  50. package/dist/internal/providerSpec.js +306 -7
  51. package/dist/manifest.d.ts +25 -4
  52. package/dist/manifest.d.ts.map +1 -1
  53. package/dist/server/ai.d.ts +45 -0
  54. package/dist/server/ai.d.ts.map +1 -1
  55. package/dist/server/ai.js +77 -1
  56. package/dist/server/aiBinding.d.ts.map +1 -1
  57. package/dist/server/aiBinding.js +3 -3
  58. package/dist/server/authorizeUrl.d.ts +1 -1
  59. package/dist/server/authorizeUrl.d.ts.map +1 -1
  60. package/dist/server/authorizeUrl.js +2 -6
  61. package/dist/server/emailBinding.js +1 -1
  62. package/dist/server/emit.js +1 -1
  63. package/dist/server/gatewayFetch.d.ts.map +1 -1
  64. package/dist/server/gatewayFetch.js +20 -7
  65. package/dist/server/index.d.ts +3 -2
  66. package/dist/server/index.d.ts.map +1 -1
  67. package/dist/server/index.js +3 -2
  68. package/dist/server/integrationFetch.d.ts +4 -31
  69. package/dist/server/integrationFetch.d.ts.map +1 -1
  70. package/dist/server/integrationFetch.js +44 -42
  71. package/dist/server/listMembers.js +1 -1
  72. package/dist/server/refusal.d.ts +55 -0
  73. package/dist/server/refusal.d.ts.map +1 -0
  74. package/dist/server/refusal.js +193 -0
  75. package/dist/server/sendEmail.js +1 -1
  76. package/package.json +1 -1
@@ -5,13 +5,17 @@
5
5
  * preset becomes a `providers` row when added (`everyapp provider add
6
6
  * --oauth github`, the Admin dialog, `everyapp_provider_add` with
7
7
  * `preset`), so an operator may `provider show` and edit a copy; nothing
8
- * here is a hidden catalog entry. Google, Microsoft, Slack and Discord
9
- * are catalog clients with a `flow` and are offered in the same picker.
8
+ * here is a hidden catalog entry, and no gateway reserves a preset's
9
+ * setting names until it is added. Google, Microsoft and Slack are
10
+ * catalog clients with a `flow` and are offered in the same picker. The
11
+ * social networks' presets carry the tag `social`.
10
12
  *
11
13
  * Each preset parses with `parseProviderSpec` (oauthPresets.test.ts),
12
14
  * names a console where the client is made, the API hosts the token is
13
15
  * sent to, and scope sets an app declares under `scopes`. Scope strings
14
- * are the providers' own, verified against their docs on 2026-10-25.
16
+ * are the providers' own, verified against their docs on 2026-10-25;
17
+ * the social presets' come from the catalog entries Postiz used, and
18
+ * none of them has been tried against a live connect yet.
15
19
  */
16
20
  import { parseProviderSpec, } from "./providerSpec.js";
17
21
  export const OAUTH_PRESETS = {
@@ -512,6 +516,532 @@ export const OAUTH_PRESETS = {
512
516
  access: ["read", "write"],
513
517
  hint: "OAuth 2 with PKCE on X's v2 API; X's OAuth 1.0a (the v1.1 media upload) stays an app secret.",
514
518
  },
519
+ // Social networks, tagged `social`: the clients Postiz connected its
520
+ // channels with, once catalog entries every gateway reserved names for.
521
+ linkedin: {
522
+ id: "linkedin",
523
+ name: "LinkedIn",
524
+ description: "Posts on a member's profile and on the company pages they admin.",
525
+ docs: "https://www.linkedin.com/developers/apps",
526
+ api: "https://learn.microsoft.com/linkedin/",
527
+ hosts: ["api.linkedin.com"],
528
+ auth: {
529
+ kind: "oauth2-user",
530
+ authorizeUrl: "https://www.linkedin.com/oauth/v2/authorization",
531
+ tokenUrl: "https://www.linkedin.com/oauth/v2/accessToken",
532
+ clientId: "LINKEDIN_CLIENT_ID",
533
+ clientSecret: "LINKEDIN_CLIENT_SECRET",
534
+ inject: "form",
535
+ // PKCE is for LinkedIn's native apps; a web client sends the secret.
536
+ pkce: false,
537
+ scopeDialect: "space",
538
+ identity: {
539
+ url: "https://api.linkedin.com/v2/userinfo",
540
+ label: "name",
541
+ id: "sub",
542
+ },
543
+ },
544
+ scopeSets: {
545
+ identity: {
546
+ label: "LinkedIn account (who you are)",
547
+ access: "read",
548
+ scopes: ["openid", "profile"],
549
+ },
550
+ "posts.write": {
551
+ label: "Posts on your profile",
552
+ access: "write",
553
+ scopes: ["openid", "profile", "w_member_social"],
554
+ },
555
+ "pages.write": {
556
+ label: "Company pages you admin (read and post)",
557
+ access: "write",
558
+ scopes: [
559
+ "rw_organization_admin",
560
+ "w_organization_social",
561
+ "r_organization_social",
562
+ ],
563
+ },
564
+ },
565
+ access: ["read", "write"],
566
+ tags: ["social"],
567
+ hint: "Add the Sign In with LinkedIn and Share on LinkedIn products to the app; company pages need the Community Management API. Refresh tokens come to approved partners only. Not yet tried against a live connect.",
568
+ },
569
+ facebook: {
570
+ id: "facebook",
571
+ name: "Facebook Pages",
572
+ description: "Facebook pages, and the Instagram business accounts linked to them.",
573
+ docs: "https://developers.facebook.com/apps",
574
+ api: "https://developers.facebook.com/docs/graph-api",
575
+ hosts: ["graph.facebook.com"],
576
+ auth: {
577
+ kind: "oauth2-user",
578
+ authorizeUrl: "https://www.facebook.com/v25.0/dialog/oauth",
579
+ tokenUrl: "https://graph.facebook.com/v25.0/oauth/access_token",
580
+ clientId: "FACEBOOK_APP_ID",
581
+ clientSecret: "FACEBOOK_APP_SECRET",
582
+ inject: "form",
583
+ pkce: false,
584
+ scopeDialect: "comma",
585
+ identity: {
586
+ url: "https://graph.facebook.com/v25.0/me",
587
+ label: "name",
588
+ id: "id",
589
+ },
590
+ },
591
+ scopeSets: {
592
+ identity: {
593
+ label: "Facebook account (who you are)",
594
+ access: "read",
595
+ scopes: ["public_profile"],
596
+ },
597
+ "pages.read": {
598
+ label: "Pages you manage and their insights (read)",
599
+ access: "read",
600
+ scopes: ["pages_show_list", "pages_read_engagement", "read_insights"],
601
+ },
602
+ "pages.write": {
603
+ label: "Pages you manage (read, post and reply)",
604
+ access: "write",
605
+ scopes: [
606
+ "pages_show_list",
607
+ "business_management",
608
+ "pages_manage_posts",
609
+ "pages_manage_engagement",
610
+ "pages_read_engagement",
611
+ ],
612
+ },
613
+ "instagram.write": {
614
+ label: "Instagram business accounts linked to your pages",
615
+ access: "write",
616
+ scopes: [
617
+ "pages_show_list",
618
+ "instagram_basic",
619
+ "instagram_content_publish",
620
+ "instagram_manage_comments",
621
+ "instagram_manage_insights",
622
+ ],
623
+ },
624
+ },
625
+ access: ["read", "write"],
626
+ tags: ["social"],
627
+ hint: "A Business app with Facebook Login. Meta issues no refresh token: a person reconnects when the token expires. Not yet tried against a live connect.",
628
+ },
629
+ instagram: {
630
+ id: "instagram",
631
+ name: "Instagram",
632
+ description: "An Instagram professional account on its own, without a Facebook page.",
633
+ docs: "https://developers.facebook.com/apps",
634
+ api: "https://developers.facebook.com/docs/instagram-platform",
635
+ hosts: ["graph.instagram.com"],
636
+ auth: {
637
+ kind: "oauth2-user",
638
+ authorizeUrl: "https://www.instagram.com/oauth/authorize",
639
+ tokenUrl: "https://api.instagram.com/oauth/access_token",
640
+ clientId: "INSTAGRAM_APP_ID",
641
+ clientSecret: "INSTAGRAM_APP_SECRET",
642
+ inject: "form",
643
+ pkce: false,
644
+ scopeDialect: "comma",
645
+ identity: {
646
+ url: "https://graph.instagram.com/me?fields=username",
647
+ label: "username",
648
+ id: "id",
649
+ },
650
+ },
651
+ scopeSets: {
652
+ identity: {
653
+ label: "Instagram account (who you are)",
654
+ access: "read",
655
+ scopes: ["instagram_business_basic"],
656
+ },
657
+ "insights.read": {
658
+ label: "Insights (read)",
659
+ access: "read",
660
+ scopes: [
661
+ "instagram_business_basic",
662
+ "instagram_business_manage_insights",
663
+ ],
664
+ },
665
+ "posts.write": {
666
+ label: "Posts and comments",
667
+ access: "write",
668
+ scopes: [
669
+ "instagram_business_basic",
670
+ "instagram_business_content_publish",
671
+ "instagram_business_manage_comments",
672
+ ],
673
+ },
674
+ },
675
+ access: ["read", "write"],
676
+ tags: ["social"],
677
+ hint: "The Instagram API with Instagram Login, on a Meta app. The token lasts an hour; the long-lived exchange isn't done by the Gateway. Not yet tried against a live connect.",
678
+ },
679
+ threads: {
680
+ id: "threads",
681
+ name: "Threads",
682
+ description: "Posts, replies and insights on a Threads profile.",
683
+ docs: "https://developers.facebook.com/apps",
684
+ api: "https://developers.facebook.com/docs/threads",
685
+ hosts: ["graph.threads.net"],
686
+ auth: {
687
+ kind: "oauth2-user",
688
+ authorizeUrl: "https://threads.net/oauth/authorize",
689
+ tokenUrl: "https://graph.threads.net/oauth/access_token",
690
+ clientId: "THREADS_APP_ID",
691
+ clientSecret: "THREADS_APP_SECRET",
692
+ inject: "form",
693
+ pkce: false,
694
+ scopeDialect: "comma",
695
+ identity: {
696
+ url: "https://graph.threads.net/v1.0/me?fields=id,username",
697
+ label: "username",
698
+ id: "id",
699
+ },
700
+ },
701
+ scopeSets: {
702
+ identity: {
703
+ label: "Threads profile (who you are)",
704
+ access: "read",
705
+ scopes: ["threads_basic"],
706
+ },
707
+ "insights.read": {
708
+ label: "Insights (read)",
709
+ access: "read",
710
+ scopes: ["threads_basic", "threads_manage_insights"],
711
+ },
712
+ "posts.write": {
713
+ label: "Posts and replies",
714
+ access: "write",
715
+ scopes: [
716
+ "threads_basic",
717
+ "threads_content_publish",
718
+ "threads_manage_replies",
719
+ ],
720
+ },
721
+ },
722
+ access: ["read", "write"],
723
+ tags: ["social"],
724
+ hint: "The Threads use case on a Meta app. The token lasts an hour; the long-lived exchange isn't done by the Gateway. Not yet tried against a live connect.",
725
+ },
726
+ youtube: {
727
+ id: "youtube",
728
+ name: "YouTube",
729
+ description: "YouTube channels and their analytics, and Google Business Profiles.",
730
+ docs: "https://console.cloud.google.com/apis/credentials",
731
+ api: "https://developers.google.com/youtube/v3",
732
+ hosts: [
733
+ "www.googleapis.com",
734
+ "youtubeanalytics.googleapis.com",
735
+ "mybusinessaccountmanagement.googleapis.com",
736
+ "mybusinessbusinessinformation.googleapis.com",
737
+ "mybusiness.googleapis.com",
738
+ "businessprofileperformance.googleapis.com",
739
+ "openidconnect.googleapis.com",
740
+ ],
741
+ auth: {
742
+ kind: "oauth2-user",
743
+ authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
744
+ tokenUrl: "https://oauth2.googleapis.com/token",
745
+ revokeUrl: "https://oauth2.googleapis.com/revoke",
746
+ clientId: "YOUTUBE_CLIENT_ID",
747
+ clientSecret: "YOUTUBE_CLIENT_SECRET",
748
+ inject: "form",
749
+ pkce: true,
750
+ scopeDialect: "google",
751
+ authorizeParams: { access_type: "offline", prompt: "consent" },
752
+ identity: {
753
+ url: "https://openidconnect.googleapis.com/v1/userinfo",
754
+ label: "email",
755
+ id: "sub",
756
+ },
757
+ },
758
+ scopeSets: {
759
+ identity: {
760
+ label: "Google account (who you are)",
761
+ access: "read",
762
+ scopes: [
763
+ "https://www.googleapis.com/auth/userinfo.profile",
764
+ "https://www.googleapis.com/auth/userinfo.email",
765
+ ],
766
+ },
767
+ "youtube.read": {
768
+ label: "YouTube channels and analytics (read)",
769
+ access: "read",
770
+ scopes: [
771
+ "https://www.googleapis.com/auth/youtube.readonly",
772
+ "https://www.googleapis.com/auth/yt-analytics.readonly",
773
+ ],
774
+ },
775
+ "youtube.write": {
776
+ label: "YouTube channels (upload and manage)",
777
+ access: "write",
778
+ scopes: [
779
+ "https://www.googleapis.com/auth/youtube",
780
+ "https://www.googleapis.com/auth/youtube.upload",
781
+ "https://www.googleapis.com/auth/youtube.force-ssl",
782
+ ],
783
+ },
784
+ "business.write": {
785
+ label: "Google Business Profiles (read and post)",
786
+ access: "write",
787
+ scopes: ["https://www.googleapis.com/auth/business.manage"],
788
+ },
789
+ },
790
+ access: ["read", "write"],
791
+ tags: ["social"],
792
+ hint: "Its own Google Cloud project, apart from google-workspace's: YouTube's scopes need their own verification. Not yet tried against a live connect.",
793
+ },
794
+ reddit: {
795
+ id: "reddit",
796
+ name: "Reddit",
797
+ description: "Reading subreddits and posting as the person.",
798
+ docs: "https://www.reddit.com/prefs/apps",
799
+ api: "https://www.reddit.com/dev/api",
800
+ hosts: ["oauth.reddit.com"],
801
+ auth: {
802
+ kind: "oauth2-user",
803
+ authorizeUrl: "https://www.reddit.com/api/v1/authorize",
804
+ tokenUrl: "https://www.reddit.com/api/v1/access_token",
805
+ clientId: "REDDIT_CLIENT_ID",
806
+ clientSecret: "REDDIT_CLIENT_SECRET",
807
+ inject: "basic",
808
+ pkce: false,
809
+ scopeDialect: "space",
810
+ // A refresh token only with a permanent grant.
811
+ authorizeParams: { duration: "permanent" },
812
+ identity: {
813
+ url: "https://oauth.reddit.com/api/v1/me",
814
+ label: "name",
815
+ id: "id",
816
+ },
817
+ },
818
+ scopeSets: {
819
+ identity: {
820
+ label: "Reddit account (who you are)",
821
+ access: "read",
822
+ scopes: ["identity"],
823
+ },
824
+ "posts.read": {
825
+ label: "Subreddits and posts (read)",
826
+ access: "read",
827
+ scopes: ["identity", "read"],
828
+ },
829
+ "posts.write": {
830
+ label: "Posts (read, submit and flair)",
831
+ access: "write",
832
+ scopes: ["identity", "read", "submit", "flair"],
833
+ },
834
+ },
835
+ access: ["read", "write"],
836
+ tags: ["social"],
837
+ hint: "A web app on Reddit's apps page. Not yet tried against a live connect.",
838
+ },
839
+ pinterest: {
840
+ id: "pinterest",
841
+ name: "Pinterest",
842
+ description: "Boards and pins on a Pinterest account.",
843
+ docs: "https://developers.pinterest.com/apps/",
844
+ api: "https://developers.pinterest.com/docs/api/v5/",
845
+ hosts: ["api.pinterest.com"],
846
+ auth: {
847
+ kind: "oauth2-user",
848
+ authorizeUrl: "https://www.pinterest.com/oauth/",
849
+ tokenUrl: "https://api.pinterest.com/v5/oauth/token",
850
+ clientId: "PINTEREST_CLIENT_ID",
851
+ clientSecret: "PINTEREST_CLIENT_SECRET",
852
+ inject: "basic",
853
+ pkce: false,
854
+ scopeDialect: "comma",
855
+ identity: {
856
+ url: "https://api.pinterest.com/v5/user_account",
857
+ label: "username",
858
+ id: "id",
859
+ },
860
+ },
861
+ scopeSets: {
862
+ identity: {
863
+ label: "Pinterest account (who you are)",
864
+ access: "read",
865
+ scopes: ["user_accounts:read"],
866
+ },
867
+ "pins.read": {
868
+ label: "Boards and pins (read)",
869
+ access: "read",
870
+ scopes: ["user_accounts:read", "boards:read", "pins:read"],
871
+ },
872
+ "pins.write": {
873
+ label: "Boards and pins (read and write)",
874
+ access: "write",
875
+ scopes: [
876
+ "user_accounts:read",
877
+ "boards:read",
878
+ "boards:write",
879
+ "pins:read",
880
+ "pins:write",
881
+ ],
882
+ },
883
+ },
884
+ access: ["read", "write"],
885
+ tags: ["social"],
886
+ hint: "Not yet tried against a live connect.",
887
+ },
888
+ discord: {
889
+ id: "discord",
890
+ name: "Discord",
891
+ description: "The person's Discord account and servers, and installing a bot in a server.",
892
+ docs: "https://discord.com/developers/applications",
893
+ api: "https://discord.com/developers/docs/reference",
894
+ hosts: ["discord.com"],
895
+ auth: {
896
+ kind: "oauth2-user",
897
+ authorizeUrl: "https://discord.com/oauth2/authorize",
898
+ tokenUrl: "https://discord.com/api/oauth2/token",
899
+ revokeUrl: "https://discord.com/api/oauth2/token/revoke",
900
+ clientId: "DISCORD_CLIENT_ID",
901
+ clientSecret: "DISCORD_CLIENT_SECRET",
902
+ inject: "basic",
903
+ pkce: true,
904
+ scopeDialect: "space",
905
+ identity: {
906
+ url: "https://discord.com/api/users/@me",
907
+ label: "username",
908
+ id: "id",
909
+ },
910
+ },
911
+ scopeSets: {
912
+ identity: {
913
+ label: "Discord account (who you are)",
914
+ access: "read",
915
+ scopes: ["identify"],
916
+ },
917
+ "servers.read": {
918
+ label: "Servers you are in (read)",
919
+ access: "read",
920
+ scopes: ["identify", "guilds"],
921
+ },
922
+ "bot.write": {
923
+ label: "Add the bot to a server",
924
+ access: "write",
925
+ scopes: ["identify", "guilds", "bot"],
926
+ },
927
+ },
928
+ access: ["read", "write"],
929
+ tags: ["social"],
930
+ hint: "Posting as the bot uses the bot's own token, an app secret the Gateway doesn't hold. Not yet tried against a live connect.",
931
+ },
932
+ kick: {
933
+ id: "kick",
934
+ name: "Kick",
935
+ description: "A Kick channel and its chat.",
936
+ docs: "https://kick.com/settings/developer",
937
+ api: "https://docs.kick.com/",
938
+ hosts: ["api.kick.com"],
939
+ auth: {
940
+ kind: "oauth2-user",
941
+ authorizeUrl: "https://id.kick.com/oauth/authorize",
942
+ tokenUrl: "https://id.kick.com/oauth/token",
943
+ clientId: "KICK_CLIENT_ID",
944
+ clientSecret: "KICK_CLIENT_SECRET",
945
+ inject: "form",
946
+ pkce: true,
947
+ scopeDialect: "space",
948
+ },
949
+ scopeSets: {
950
+ identity: {
951
+ label: "Kick account (who you are)",
952
+ access: "read",
953
+ scopes: ["user:read"],
954
+ },
955
+ "channel.read": {
956
+ label: "Your channel (read)",
957
+ access: "read",
958
+ scopes: ["user:read", "channel:read"],
959
+ },
960
+ "chat.write": {
961
+ label: "Chat messages",
962
+ access: "write",
963
+ scopes: ["user:read", "chat:write"],
964
+ },
965
+ },
966
+ access: ["read", "write"],
967
+ tags: ["social"],
968
+ hint: "Not yet tried against a live connect.",
969
+ },
970
+ twitch: {
971
+ id: "twitch",
972
+ name: "Twitch",
973
+ description: "A Twitch channel's chat and announcements.",
974
+ docs: "https://dev.twitch.tv/console/apps",
975
+ api: "https://dev.twitch.tv/docs/api/",
976
+ hosts: ["api.twitch.tv"],
977
+ auth: {
978
+ kind: "oauth2-user",
979
+ authorizeUrl: "https://id.twitch.tv/oauth2/authorize",
980
+ tokenUrl: "https://id.twitch.tv/oauth2/token",
981
+ clientId: "TWITCH_CLIENT_ID",
982
+ clientSecret: "TWITCH_CLIENT_SECRET",
983
+ inject: "form",
984
+ pkce: false,
985
+ scopeDialect: "space",
986
+ },
987
+ scopeSets: {
988
+ "chat.read": {
989
+ label: "Chat (read)",
990
+ access: "read",
991
+ scopes: ["user:read:chat"],
992
+ },
993
+ "chat.write": {
994
+ label: "Chat messages and announcements",
995
+ access: "write",
996
+ scopes: [
997
+ "user:read:chat",
998
+ "user:write:chat",
999
+ "moderator:manage:announcements",
1000
+ ],
1001
+ },
1002
+ },
1003
+ access: ["read", "write"],
1004
+ tags: ["social"],
1005
+ hint: "Helix also wants the public client id as a Client-Id header on every call. Not yet tried against a live connect.",
1006
+ },
1007
+ tumblr: {
1008
+ id: "tumblr",
1009
+ name: "Tumblr",
1010
+ description: "Posting to the person's Tumblr blogs.",
1011
+ docs: "https://www.tumblr.com/oauth/apps",
1012
+ api: "https://www.tumblr.com/docs/en/api/v2",
1013
+ hosts: ["api.tumblr.com"],
1014
+ auth: {
1015
+ kind: "oauth2-user",
1016
+ authorizeUrl: "https://www.tumblr.com/oauth2/authorize",
1017
+ tokenUrl: "https://api.tumblr.com/v2/oauth2/token",
1018
+ clientId: "TUMBLR_CLIENT_ID",
1019
+ clientSecret: "TUMBLR_CLIENT_SECRET",
1020
+ inject: "form",
1021
+ pkce: false,
1022
+ scopeDialect: "space",
1023
+ identity: {
1024
+ url: "https://api.tumblr.com/v2/user/info",
1025
+ label: "response.user.name",
1026
+ },
1027
+ },
1028
+ scopeSets: {
1029
+ identity: {
1030
+ label: "Tumblr account (who you are)",
1031
+ access: "read",
1032
+ scopes: ["basic"],
1033
+ },
1034
+ "posts.write": {
1035
+ label: "Posts on your blogs",
1036
+ access: "write",
1037
+ scopes: ["basic", "write"],
1038
+ },
1039
+ },
1040
+ alwaysRequested: ["offline_access"],
1041
+ access: ["read", "write"],
1042
+ tags: ["social"],
1043
+ hint: "Not yet tried against a live connect.",
1044
+ },
515
1045
  };
516
1046
  /** The preset ids, in the order the picker shows them. */
517
1047
  export function oauthPresetIds() {
@@ -7,7 +7,7 @@
7
7
  * the common fields here once it sees `auth.kind: "oauth2-user"`; nothing
8
8
  * here reads a value: a spec names Gateway settings, never holds one.
9
9
  */
10
- import { type CapabilityAccess, type OAuthClientCapability } from "./capabilities.js";
10
+ import { type CapabilityAccess, type OAuthClientCapability, type OAuthScopeSet } from "./capabilities.js";
11
11
  export interface SpecProblem {
12
12
  path: string;
13
13
  message: string;
@@ -33,6 +33,49 @@ export interface OAuthSpecCommon {
33
33
  example?: string;
34
34
  tags?: readonly string[];
35
35
  }
36
+ /**
37
+ * One scope set (`{ label, access, scopes, userScopes?, routes? }`) at
38
+ * `at`, its routes on `hosts` alone; undefined when a field is wrong,
39
+ * every problem reported. `overlay`: a set added to a built-in client
40
+ * must name a scope and say what it unlocks (a set with no routes unlocks
41
+ * nothing on the held-token path); a spec's own set may leave both empty
42
+ * (Notion's sets carry no scope string).
43
+ */
44
+ export declare function parseScopeSet(raw: unknown, at: string, hosts: readonly string[], problems: SpecProblem[], { overlay }?: {
45
+ overlay?: boolean;
46
+ }): OAuthScopeSet | undefined;
47
+ /** What `parseScopeSetOverlay` returns. */
48
+ export type ParsedScopeSetOverlay = {
49
+ ok: true;
50
+ name: string;
51
+ set: OAuthScopeSet;
52
+ } | {
53
+ ok: false;
54
+ problems: SpecProblem[];
55
+ };
56
+ /**
57
+ * A scope set an operator adds to a built-in OAuth client
58
+ * (`everyapp provider scope-set add google-workspace gmail-send.json`):
59
+ * `{ "name": "gmail.send", "label", "access", "scopes", "routes" }`, held
60
+ * to the rules a built-in set is (the set's shape, routes on the client's
61
+ * `api` hosts alone, anchored `posts`) plus two of its own: `access` is
62
+ * said outright (a write set is never implied by its scopes) and `routes`
63
+ * is required. A `provider` field, when present, must be `id`. The name
64
+ * may not be one of the client's own sets: an overlay adds, never
65
+ * replaces. Nothing here reads a value.
66
+ */
67
+ export declare function parseScopeSetOverlay(input: unknown, client: {
68
+ id: string;
69
+ capability: OAuthClientCapability;
70
+ }): ParsedScopeSetOverlay;
71
+ /**
72
+ * `capability` with `sets` added to its scope policy: the sets after the
73
+ * client's own, in the order given, and each set's scopes added to the
74
+ * authorize URL's list (what the operator's client must be allowed), as
75
+ * `parseOAuthUserSpec` builds it. A name the client already has is left
76
+ * as the client's (the registry refuses such an overlay before this).
77
+ */
78
+ export declare function withScopeSets(capability: OAuthClientCapability, sets: Readonly<Record<string, OAuthScopeSet>>): OAuthClientCapability;
36
79
  /** What `parseOAuthUserSpec` returns on success, before the registry's rules. */
37
80
  export interface ParsedOAuthSpec {
38
81
  capability: OAuthClientCapability;
@@ -1 +1 @@
1
- {"version":3,"file":"oauthSpec.d.ts","sourceRoot":"","sources":["../../src/internal/oauthSpec.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAQ3B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qFAAqF;AACrF,eAAO,MAAM,cAAc,QAC0B,CAAC;AA4BtD,sFAAsF;AACtF,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAAwB,CAAC;AAE9E,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,yLAcpB,CAAC;AAEX,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACrC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAmXD,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,qBAAqB,CAAC;IAClC,8EAA8E;IAC9E,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,WAAW,EAAE,GACtB,eAAe,GAAG,SAAS,CAqN7B;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,qBAAqB,GAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAyFhC;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,qBAAqB,GAChC,SAAS,MAAM,EAAE,CAEnB;AAED,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,qBAAqB,GAChC,SAAS,MAAM,EAAE,CAEnB"}
1
+ {"version":3,"file":"oauthSpec.d.ts","sourceRoot":"","sources":["../../src/internal/oauthSpec.ts"],"names":[],"mappings":"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"}