shutro-erp 0.3.3 → 0.3.4

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 (85) hide show
  1. package/dist/account_portal/.kosh/bindings.js +1 -1
  2. package/dist/account_portal/.kosh/schema.d.ts +128 -1
  3. package/dist/accounting/.kosh/bindings.js +1 -1
  4. package/dist/accounting/.kosh/schema.d.ts +128 -1
  5. package/dist/contacts/.kosh/bindings.js +1 -1
  6. package/dist/contacts/.kosh/schema.d.ts +128 -1
  7. package/dist/integrations/index.js +12 -0
  8. package/dist/integrations/web/OAuthAppsPage.d.ts +9 -0
  9. package/dist/integrations/web/OAuthAppsPage.js +79 -0
  10. package/dist/integrations/web/index.d.ts +1 -0
  11. package/dist/integrations/web/index.js +3 -0
  12. package/dist/integrations/web/messages.js +58 -0
  13. package/dist/l10n_bd/.kosh/bindings.js +1 -1
  14. package/dist/l10n_bd/.kosh/schema.d.ts +128 -1
  15. package/dist/l10n_in/.kosh/bindings.js +1 -1
  16. package/dist/l10n_in/.kosh/schema.d.ts +128 -1
  17. package/dist/messaging/web/index.js +1 -1
  18. package/dist/notify/web/index.js +1 -1
  19. package/dist/payment/.kosh/bindings.js +1 -1
  20. package/dist/payment/.kosh/schema.d.ts +128 -1
  21. package/dist/portal/.kosh/bindings.js +1 -1
  22. package/dist/portal/.kosh/schema.d.ts +128 -1
  23. package/dist/product/.kosh/bindings.js +1 -1
  24. package/dist/product/.kosh/schema.d.ts +128 -1
  25. package/dist/project/.kosh/bindings.js +1 -1
  26. package/dist/project/.kosh/schema.d.ts +128 -1
  27. package/dist/project_portal/.kosh/bindings.js +1 -1
  28. package/dist/project_portal/.kosh/schema.d.ts +128 -1
  29. package/dist/purchase/.kosh/bindings.js +1 -1
  30. package/dist/purchase/.kosh/schema.d.ts +128 -1
  31. package/dist/purchase_account/.kosh/bindings.js +1 -1
  32. package/dist/purchase_account/.kosh/schema.d.ts +128 -1
  33. package/dist/purchase_portal/.kosh/bindings.js +1 -1
  34. package/dist/purchase_portal/.kosh/schema.d.ts +128 -1
  35. package/dist/sale_account/.kosh/bindings.js +1 -1
  36. package/dist/sale_account/.kosh/schema.d.ts +128 -1
  37. package/dist/sale_portal/.kosh/bindings.js +1 -1
  38. package/dist/sale_portal/.kosh/schema.d.ts +128 -1
  39. package/dist/sale_project/.kosh/bindings.js +1 -1
  40. package/dist/sale_project/.kosh/schema.d.ts +128 -1
  41. package/dist/sales/.kosh/bindings.js +1 -1
  42. package/dist/sales/.kosh/schema.d.ts +128 -1
  43. package/dist/server/auth/base.js +76 -0
  44. package/dist/server/auth/oauth.d.ts +21 -0
  45. package/dist/server/auth/oauth.js +579 -0
  46. package/dist/server/auth/service.d.ts +4 -0
  47. package/dist/server/auth/service.js +17 -0
  48. package/dist/server/identity.d.ts +2 -0
  49. package/dist/server/images.d.ts +12 -0
  50. package/dist/server/images.js +139 -0
  51. package/dist/server/index.d.ts +1 -0
  52. package/dist/server/index.js +1 -0
  53. package/dist/server/server.d.ts +4 -0
  54. package/dist/server/server.js +9 -1
  55. package/dist/settings/company.js +3 -1
  56. package/dist/settings/people.js +3 -1
  57. package/dist/settings/web/CompaniesPage.js +2 -2
  58. package/dist/settings/web/CompanyPage.js +13 -2
  59. package/dist/settings/web/ConnectedAppsPage.d.ts +7 -0
  60. package/dist/settings/web/ConnectedAppsPage.js +33 -0
  61. package/dist/settings/web/OverviewPage.js +12 -1
  62. package/dist/settings/web/PeoplePage.js +3 -12
  63. package/dist/settings/web/ProfilePage.js +9 -7
  64. package/dist/settings/web/index.d.ts +1 -0
  65. package/dist/settings/web/index.js +5 -0
  66. package/dist/settings/web/messages.js +28 -0
  67. package/dist/ui/api.d.ts +4 -0
  68. package/dist/ui/app.js +49 -16
  69. package/dist/ui/components/AppIcon.js +11 -1
  70. package/dist/ui/components/Avatar.d.ts +21 -0
  71. package/dist/ui/components/Avatar.js +71 -0
  72. package/dist/ui/i18n/messages.d.ts +30 -0
  73. package/dist/ui/i18n/messages.js +60 -0
  74. package/dist/ui/index.d.ts +1 -0
  75. package/dist/ui/index.js +1 -0
  76. package/dist/ui/registry.d.ts +7 -1
  77. package/dist/ui/registry.js +10 -1
  78. package/dist/ui/search/ViewTabs.d.ts +14 -0
  79. package/dist/ui/search/ViewTabs.js +42 -0
  80. package/dist/ui/shell/Consent.d.ts +5 -0
  81. package/dist/ui/shell/Consent.js +35 -0
  82. package/dist/ui/shell/Home.js +85 -16
  83. package/dist/ui/shell/Sidebar.js +15 -22
  84. package/dist/ui/views/ListView.js +49 -22
  85. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: 668898d9db81475e
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: b86e876d4a603b3c
2
2
  // Bindings of module `account_portal`: import the definition API from here to get types scoped to what it can see.
3
3
  export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
4
4
  import { definitions } from '../../server/orm.js';
@@ -1,4 +1,4 @@
1
- // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: 668898d9db81475e
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: b86e876d4a603b3c
2
2
  // Schema view of module `account_portal` (RFC 0002 §7.7): the models it owns or depends on, with the extensions it can see.
3
3
  import type { F } from '../../server/orm.js';
4
4
 
@@ -28,6 +28,7 @@ export interface SchemaView {
28
28
  readonly 'auth.session': AuthSession;
29
29
  readonly 'auth.user_grant': AuthUserGrant;
30
30
  readonly 'auth.user_group': AuthUserGroup;
31
+ readonly 'kosh.image': KoshImage;
31
32
  readonly 'kosh.saved_view': KoshSavedView;
32
33
  readonly 'mail.activity': MailActivity;
33
34
  readonly 'mail.activity.type': MailActivityType;
@@ -36,6 +37,10 @@ export interface SchemaView {
36
37
  readonly 'mail.follower': MailFollower;
37
38
  readonly 'mail.message': MailMessage;
38
39
  readonly 'mail.message.reaction': MailMessageReaction;
40
+ readonly 'oauth.app': OauthApp;
41
+ readonly 'oauth.code': OauthCode;
42
+ readonly 'oauth.grant': OauthGrant;
43
+ readonly 'oauth.token': OauthToken;
39
44
  readonly 'portal.announcement': PortalAnnouncement;
40
45
  readonly 'portal.invitation': PortalInvitation;
41
46
  readonly 'portal.signature': PortalSignature;
@@ -727,6 +732,29 @@ export interface AuthUserGroup {
727
732
  export interface AuthUserGroupMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'auth.user_group'> {
728
733
  }
729
734
 
735
+ /** `kosh.image` (owner: base). */
736
+ export interface KoshImage {
737
+ readonly name: 'kosh.image';
738
+ readonly fields: {
739
+ readonly id: F.Id<'kosh.image'>;
740
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
741
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
742
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
743
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
744
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
745
+ readonly ownerModel: F.Char<{ readonly required: true }>;
746
+ readonly ownerId: F.Integer<{ readonly required: true }>;
747
+ readonly mime: F.Char<{ readonly required: true }>;
748
+ readonly data: F.Text<{ readonly required: true }>;
749
+ readonly hash: F.Char<{ readonly required: true }>;
750
+ };
751
+ readonly methods: KoshImageMethods;
752
+ }
753
+
754
+ /** Methods of `kosh.image`: declared ones and transitions. */
755
+ export interface KoshImageMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'kosh.image'> {
756
+ }
757
+
730
758
  /** `kosh.saved_view` (owner: base). */
731
759
  export interface KoshSavedView {
732
760
  readonly name: 'kosh.saved_view';
@@ -929,6 +957,105 @@ export interface MailMessageReaction {
929
957
  export interface MailMessageReactionMethods extends F.Methods<typeof import('../../messaging/index.js').messagingShutro, 'mail.message.reaction'> {
930
958
  }
931
959
 
960
+ /** `oauth.app` (owner: base). */
961
+ export interface OauthApp {
962
+ readonly name: 'oauth.app';
963
+ readonly fields: {
964
+ readonly id: F.Id<'oauth.app'>;
965
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
966
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
967
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
968
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
969
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
970
+ readonly name: F.Char<{ readonly required: true }>;
971
+ readonly clientId: F.Char<{ readonly required: true }>;
972
+ readonly secretHash: F.Char;
973
+ readonly confidential: F.Bool<{ readonly required: true; readonly default: true }>;
974
+ readonly redirectUris: F.Text<{ readonly required: true }>;
975
+ readonly scopes: F.Char<{ readonly required: true }>;
976
+ readonly homepage: F.Char;
977
+ readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
978
+ readonly owner: F.Many2one<'res.users'>;
979
+ };
980
+ readonly methods: OauthAppMethods;
981
+ }
982
+
983
+ /** Methods of `oauth.app`: declared ones and transitions. */
984
+ export interface OauthAppMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'oauth.app'> {
985
+ }
986
+
987
+ /** `oauth.code` (owner: base). */
988
+ export interface OauthCode {
989
+ readonly name: 'oauth.code';
990
+ readonly fields: {
991
+ readonly id: F.Id<'oauth.code'>;
992
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
993
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
994
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
995
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
996
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
997
+ readonly codeHash: F.Char<{ readonly required: true }>;
998
+ readonly grant: F.Many2one<'oauth.grant', { readonly required: true }>;
999
+ readonly redirectUri: F.Char<{ readonly required: true }>;
1000
+ readonly challenge: F.Char;
1001
+ readonly expiresAt: F.Datetime<{ readonly required: true }>;
1002
+ readonly used: F.Bool<{ readonly required: true; readonly default: true }>;
1003
+ };
1004
+ readonly methods: OauthCodeMethods;
1005
+ }
1006
+
1007
+ /** Methods of `oauth.code`: declared ones and transitions. */
1008
+ export interface OauthCodeMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'oauth.code'> {
1009
+ }
1010
+
1011
+ /** `oauth.grant` (owner: base). */
1012
+ export interface OauthGrant {
1013
+ readonly name: 'oauth.grant';
1014
+ readonly fields: {
1015
+ readonly id: F.Id<'oauth.grant'>;
1016
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
1017
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
1018
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
1019
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
1020
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
1021
+ readonly user: F.Many2one<'res.users', { readonly required: true }>;
1022
+ readonly app: F.Many2one<'oauth.app', { readonly required: true }>;
1023
+ readonly scopes: F.Char<{ readonly required: true }>;
1024
+ readonly revoked: F.Bool<{ readonly required: true; readonly default: true }>;
1025
+ readonly lastUsedAt: F.Datetime;
1026
+ };
1027
+ readonly methods: OauthGrantMethods;
1028
+ }
1029
+
1030
+ /** Methods of `oauth.grant`: declared ones and transitions. */
1031
+ export interface OauthGrantMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'oauth.grant'> {
1032
+ }
1033
+
1034
+ /** `oauth.token` (owner: base). */
1035
+ export interface OauthToken {
1036
+ readonly name: 'oauth.token';
1037
+ readonly fields: {
1038
+ readonly id: F.Id<'oauth.token'>;
1039
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
1040
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
1041
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
1042
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
1043
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
1044
+ readonly grant: F.Many2one<'oauth.grant', { readonly required: true }>;
1045
+ readonly accessHash: F.Char<{ readonly required: true }>;
1046
+ readonly refreshHash: F.Char<{ readonly required: true }>;
1047
+ readonly accessExpiresAt: F.Datetime<{ readonly required: true }>;
1048
+ readonly refreshExpiresAt: F.Datetime<{ readonly required: true }>;
1049
+ readonly revoked: F.Bool<{ readonly required: true; readonly default: true }>;
1050
+ readonly rotated: F.Bool<{ readonly required: true; readonly default: true }>;
1051
+ };
1052
+ readonly methods: OauthTokenMethods;
1053
+ }
1054
+
1055
+ /** Methods of `oauth.token`: declared ones and transitions. */
1056
+ export interface OauthTokenMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'oauth.token'> {
1057
+ }
1058
+
932
1059
  /** `portal.announcement` (owner: portal). */
933
1060
  export interface PortalAnnouncement {
934
1061
  readonly name: 'portal.announcement';
@@ -1,4 +1,4 @@
1
- // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: e7d2cbddec9ade69
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: c9101ef07bbb3e64
2
2
  // Bindings of module `accounting`: import the definition API from here to get types scoped to what it can see.
3
3
  export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
4
4
  import { definitions } from '../../server/orm.js';
@@ -1,4 +1,4 @@
1
- // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: e7d2cbddec9ade69
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: c9101ef07bbb3e64
2
2
  // Schema view of module `accounting` (RFC 0002 §7.7): the models it owns or depends on, with the extensions it can see.
3
3
  import type { F } from '../../server/orm.js';
4
4
 
@@ -28,6 +28,7 @@ export interface SchemaView {
28
28
  readonly 'auth.session': AuthSession;
29
29
  readonly 'auth.user_grant': AuthUserGrant;
30
30
  readonly 'auth.user_group': AuthUserGroup;
31
+ readonly 'kosh.image': KoshImage;
31
32
  readonly 'kosh.saved_view': KoshSavedView;
32
33
  readonly 'mail.activity': MailActivity;
33
34
  readonly 'mail.activity.type': MailActivityType;
@@ -36,6 +37,10 @@ export interface SchemaView {
36
37
  readonly 'mail.follower': MailFollower;
37
38
  readonly 'mail.message': MailMessage;
38
39
  readonly 'mail.message.reaction': MailMessageReaction;
40
+ readonly 'oauth.app': OauthApp;
41
+ readonly 'oauth.code': OauthCode;
42
+ readonly 'oauth.grant': OauthGrant;
43
+ readonly 'oauth.token': OauthToken;
39
44
  readonly 'product.category': ProductCategory;
40
45
  readonly 'product.product': ProductProduct;
41
46
  readonly 'report.dashboard': ReportDashboard;
@@ -724,6 +729,29 @@ export interface AuthUserGroup {
724
729
  export interface AuthUserGroupMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'auth.user_group'> {
725
730
  }
726
731
 
732
+ /** `kosh.image` (owner: base). */
733
+ export interface KoshImage {
734
+ readonly name: 'kosh.image';
735
+ readonly fields: {
736
+ readonly id: F.Id<'kosh.image'>;
737
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
738
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
739
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
740
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
741
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
742
+ readonly ownerModel: F.Char<{ readonly required: true }>;
743
+ readonly ownerId: F.Integer<{ readonly required: true }>;
744
+ readonly mime: F.Char<{ readonly required: true }>;
745
+ readonly data: F.Text<{ readonly required: true }>;
746
+ readonly hash: F.Char<{ readonly required: true }>;
747
+ };
748
+ readonly methods: KoshImageMethods;
749
+ }
750
+
751
+ /** Methods of `kosh.image`: declared ones and transitions. */
752
+ export interface KoshImageMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'kosh.image'> {
753
+ }
754
+
727
755
  /** `kosh.saved_view` (owner: base). */
728
756
  export interface KoshSavedView {
729
757
  readonly name: 'kosh.saved_view';
@@ -926,6 +954,105 @@ export interface MailMessageReaction {
926
954
  export interface MailMessageReactionMethods extends F.Methods<typeof import('../../messaging/index.js').messagingShutro, 'mail.message.reaction'> {
927
955
  }
928
956
 
957
+ /** `oauth.app` (owner: base). */
958
+ export interface OauthApp {
959
+ readonly name: 'oauth.app';
960
+ readonly fields: {
961
+ readonly id: F.Id<'oauth.app'>;
962
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
963
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
964
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
965
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
966
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
967
+ readonly name: F.Char<{ readonly required: true }>;
968
+ readonly clientId: F.Char<{ readonly required: true }>;
969
+ readonly secretHash: F.Char;
970
+ readonly confidential: F.Bool<{ readonly required: true; readonly default: true }>;
971
+ readonly redirectUris: F.Text<{ readonly required: true }>;
972
+ readonly scopes: F.Char<{ readonly required: true }>;
973
+ readonly homepage: F.Char;
974
+ readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
975
+ readonly owner: F.Many2one<'res.users'>;
976
+ };
977
+ readonly methods: OauthAppMethods;
978
+ }
979
+
980
+ /** Methods of `oauth.app`: declared ones and transitions. */
981
+ export interface OauthAppMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'oauth.app'> {
982
+ }
983
+
984
+ /** `oauth.code` (owner: base). */
985
+ export interface OauthCode {
986
+ readonly name: 'oauth.code';
987
+ readonly fields: {
988
+ readonly id: F.Id<'oauth.code'>;
989
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
990
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
991
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
992
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
993
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
994
+ readonly codeHash: F.Char<{ readonly required: true }>;
995
+ readonly grant: F.Many2one<'oauth.grant', { readonly required: true }>;
996
+ readonly redirectUri: F.Char<{ readonly required: true }>;
997
+ readonly challenge: F.Char;
998
+ readonly expiresAt: F.Datetime<{ readonly required: true }>;
999
+ readonly used: F.Bool<{ readonly required: true; readonly default: true }>;
1000
+ };
1001
+ readonly methods: OauthCodeMethods;
1002
+ }
1003
+
1004
+ /** Methods of `oauth.code`: declared ones and transitions. */
1005
+ export interface OauthCodeMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'oauth.code'> {
1006
+ }
1007
+
1008
+ /** `oauth.grant` (owner: base). */
1009
+ export interface OauthGrant {
1010
+ readonly name: 'oauth.grant';
1011
+ readonly fields: {
1012
+ readonly id: F.Id<'oauth.grant'>;
1013
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
1014
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
1015
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
1016
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
1017
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
1018
+ readonly user: F.Many2one<'res.users', { readonly required: true }>;
1019
+ readonly app: F.Many2one<'oauth.app', { readonly required: true }>;
1020
+ readonly scopes: F.Char<{ readonly required: true }>;
1021
+ readonly revoked: F.Bool<{ readonly required: true; readonly default: true }>;
1022
+ readonly lastUsedAt: F.Datetime;
1023
+ };
1024
+ readonly methods: OauthGrantMethods;
1025
+ }
1026
+
1027
+ /** Methods of `oauth.grant`: declared ones and transitions. */
1028
+ export interface OauthGrantMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'oauth.grant'> {
1029
+ }
1030
+
1031
+ /** `oauth.token` (owner: base). */
1032
+ export interface OauthToken {
1033
+ readonly name: 'oauth.token';
1034
+ readonly fields: {
1035
+ readonly id: F.Id<'oauth.token'>;
1036
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
1037
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
1038
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
1039
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
1040
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
1041
+ readonly grant: F.Many2one<'oauth.grant', { readonly required: true }>;
1042
+ readonly accessHash: F.Char<{ readonly required: true }>;
1043
+ readonly refreshHash: F.Char<{ readonly required: true }>;
1044
+ readonly accessExpiresAt: F.Datetime<{ readonly required: true }>;
1045
+ readonly refreshExpiresAt: F.Datetime<{ readonly required: true }>;
1046
+ readonly revoked: F.Bool<{ readonly required: true; readonly default: true }>;
1047
+ readonly rotated: F.Bool<{ readonly required: true; readonly default: true }>;
1048
+ };
1049
+ readonly methods: OauthTokenMethods;
1050
+ }
1051
+
1052
+ /** Methods of `oauth.token`: declared ones and transitions. */
1053
+ export interface OauthTokenMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'oauth.token'> {
1054
+ }
1055
+
929
1056
  /** `product.category` (owner: product). */
930
1057
  export interface ProductCategory {
931
1058
  readonly name: 'product.category';
@@ -1,4 +1,4 @@
1
- // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: 31cf57953410c779
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: 87baf088f27622fd
2
2
  // Bindings of module `contacts`: import the definition API from here to get types scoped to what it can see.
3
3
  export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
4
4
  import { definitions } from '../../server/orm.js';
@@ -1,4 +1,4 @@
1
- // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: 31cf57953410c779
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: 87baf088f27622fd
2
2
  // Schema view of module `contacts` (RFC 0002 §7.7): the models it owns or depends on, with the extensions it can see.
3
3
  import type { F } from '../../server/orm.js';
4
4
 
@@ -11,7 +11,12 @@ export interface SchemaView {
11
11
  readonly 'auth.session': AuthSession;
12
12
  readonly 'auth.user_grant': AuthUserGrant;
13
13
  readonly 'auth.user_group': AuthUserGroup;
14
+ readonly 'kosh.image': KoshImage;
14
15
  readonly 'kosh.saved_view': KoshSavedView;
16
+ readonly 'oauth.app': OauthApp;
17
+ readonly 'oauth.code': OauthCode;
18
+ readonly 'oauth.grant': OauthGrant;
19
+ readonly 'oauth.token': OauthToken;
15
20
  readonly 'res.company': ResCompany;
16
21
  readonly 'res.currency': ResCurrency;
17
22
  readonly 'res.partner': ResPartner;
@@ -187,6 +192,29 @@ export interface AuthUserGroup {
187
192
  export interface AuthUserGroupMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'auth.user_group'> {
188
193
  }
189
194
 
195
+ /** `kosh.image` (owner: base). */
196
+ export interface KoshImage {
197
+ readonly name: 'kosh.image';
198
+ readonly fields: {
199
+ readonly id: F.Id<'kosh.image'>;
200
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
201
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
202
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
203
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
204
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
205
+ readonly ownerModel: F.Char<{ readonly required: true }>;
206
+ readonly ownerId: F.Integer<{ readonly required: true }>;
207
+ readonly mime: F.Char<{ readonly required: true }>;
208
+ readonly data: F.Text<{ readonly required: true }>;
209
+ readonly hash: F.Char<{ readonly required: true }>;
210
+ };
211
+ readonly methods: KoshImageMethods;
212
+ }
213
+
214
+ /** Methods of `kosh.image`: declared ones and transitions. */
215
+ export interface KoshImageMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'kosh.image'> {
216
+ }
217
+
190
218
  /** `kosh.saved_view` (owner: base). */
191
219
  export interface KoshSavedView {
192
220
  readonly name: 'kosh.saved_view';
@@ -211,6 +239,105 @@ export interface KoshSavedView {
211
239
  export interface KoshSavedViewMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'kosh.saved_view'> {
212
240
  }
213
241
 
242
+ /** `oauth.app` (owner: base). */
243
+ export interface OauthApp {
244
+ readonly name: 'oauth.app';
245
+ readonly fields: {
246
+ readonly id: F.Id<'oauth.app'>;
247
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
248
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
249
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
250
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
251
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
252
+ readonly name: F.Char<{ readonly required: true }>;
253
+ readonly clientId: F.Char<{ readonly required: true }>;
254
+ readonly secretHash: F.Char;
255
+ readonly confidential: F.Bool<{ readonly required: true; readonly default: true }>;
256
+ readonly redirectUris: F.Text<{ readonly required: true }>;
257
+ readonly scopes: F.Char<{ readonly required: true }>;
258
+ readonly homepage: F.Char;
259
+ readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
260
+ readonly owner: F.Many2one<'res.users'>;
261
+ };
262
+ readonly methods: OauthAppMethods;
263
+ }
264
+
265
+ /** Methods of `oauth.app`: declared ones and transitions. */
266
+ export interface OauthAppMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'oauth.app'> {
267
+ }
268
+
269
+ /** `oauth.code` (owner: base). */
270
+ export interface OauthCode {
271
+ readonly name: 'oauth.code';
272
+ readonly fields: {
273
+ readonly id: F.Id<'oauth.code'>;
274
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
275
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
276
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
277
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
278
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
279
+ readonly codeHash: F.Char<{ readonly required: true }>;
280
+ readonly grant: F.Many2one<'oauth.grant', { readonly required: true }>;
281
+ readonly redirectUri: F.Char<{ readonly required: true }>;
282
+ readonly challenge: F.Char;
283
+ readonly expiresAt: F.Datetime<{ readonly required: true }>;
284
+ readonly used: F.Bool<{ readonly required: true; readonly default: true }>;
285
+ };
286
+ readonly methods: OauthCodeMethods;
287
+ }
288
+
289
+ /** Methods of `oauth.code`: declared ones and transitions. */
290
+ export interface OauthCodeMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'oauth.code'> {
291
+ }
292
+
293
+ /** `oauth.grant` (owner: base). */
294
+ export interface OauthGrant {
295
+ readonly name: 'oauth.grant';
296
+ readonly fields: {
297
+ readonly id: F.Id<'oauth.grant'>;
298
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
299
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
300
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
301
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
302
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
303
+ readonly user: F.Many2one<'res.users', { readonly required: true }>;
304
+ readonly app: F.Many2one<'oauth.app', { readonly required: true }>;
305
+ readonly scopes: F.Char<{ readonly required: true }>;
306
+ readonly revoked: F.Bool<{ readonly required: true; readonly default: true }>;
307
+ readonly lastUsedAt: F.Datetime;
308
+ };
309
+ readonly methods: OauthGrantMethods;
310
+ }
311
+
312
+ /** Methods of `oauth.grant`: declared ones and transitions. */
313
+ export interface OauthGrantMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'oauth.grant'> {
314
+ }
315
+
316
+ /** `oauth.token` (owner: base). */
317
+ export interface OauthToken {
318
+ readonly name: 'oauth.token';
319
+ readonly fields: {
320
+ readonly id: F.Id<'oauth.token'>;
321
+ readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
322
+ readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
323
+ readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
324
+ readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
325
+ readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
326
+ readonly grant: F.Many2one<'oauth.grant', { readonly required: true }>;
327
+ readonly accessHash: F.Char<{ readonly required: true }>;
328
+ readonly refreshHash: F.Char<{ readonly required: true }>;
329
+ readonly accessExpiresAt: F.Datetime<{ readonly required: true }>;
330
+ readonly refreshExpiresAt: F.Datetime<{ readonly required: true }>;
331
+ readonly revoked: F.Bool<{ readonly required: true; readonly default: true }>;
332
+ readonly rotated: F.Bool<{ readonly required: true; readonly default: true }>;
333
+ };
334
+ readonly methods: OauthTokenMethods;
335
+ }
336
+
337
+ /** Methods of `oauth.token`: declared ones and transitions. */
338
+ export interface OauthTokenMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'oauth.token'> {
339
+ }
340
+
214
341
  /** `res.company` (owner: base). */
215
342
  export interface ResCompany {
216
343
  readonly name: 'res.company';
@@ -299,6 +299,11 @@ export function integrationsModule(options = {}) {
299
299
  label: 'Inbound calls',
300
300
  views: ['list', 'form'],
301
301
  }),
302
+ 'integrations.action_oauth_apps': {
303
+ type: 'client',
304
+ page: 'integrations.OAuthApps',
305
+ label: 'OAuth apps',
306
+ },
302
307
  },
303
308
  menus: [
304
309
  { id: 'integrations.root', label: 'Integrations', app: 'integrations' },
@@ -330,6 +335,13 @@ export function integrationsModule(options = {}) {
330
335
  action: 'integrations.action_inbound',
331
336
  sequence: 4,
332
337
  },
338
+ {
339
+ id: 'integrations.oauth_apps',
340
+ parent: 'integrations.root',
341
+ label: 'OAuth apps',
342
+ action: 'integrations.action_oauth_apps',
343
+ sequence: 5,
344
+ },
333
345
  ],
334
346
  views: {
335
347
  'webhook.subscription.list': list('webhook.subscription', {
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Integrations › OAuth apps (RFC 0017 §5.2): the third-party apps that may ask users for access — their client id,
3
+ * redirect addresses and the scopes they may ask for. A new app's client secret is shown once (public apps have none
4
+ * and use PKCE); a new secret replaces the old at once; an app switched off stops every token it holds. The server
5
+ * checks the addresses and scopes and audits every change.
6
+ */
7
+ import { type PageProps } from '../../ui/index.js';
8
+ import { type ReactElement } from 'react';
9
+ export declare function OAuthAppsPage({ api }: PageProps): ReactElement;
@@ -0,0 +1,79 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Integrations › OAuth apps (RFC 0017 §5.2): the third-party apps that may ask users for access — their client id,
4
+ * redirect addresses and the scopes they may ask for. A new app's client secret is shown once (public apps have none
5
+ * and use PKCE); a new secret replaces the old at once; an app switched off stops every token it holds. The server
6
+ * checks the addresses and scopes and audits every change.
7
+ */
8
+ import { Alert, ApiError, Badge, Button, Checkbox, Dialog, Input, Label, } from '../../ui/index.js';
9
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
10
+ import { Check, Copy, KeyRound, Plus } from 'lucide-react';
11
+ import { useEffect, useId, useState } from 'react';
12
+ import { useTranslation } from 'react-i18next';
13
+ const message = (error) => (error instanceof ApiError ? error.message : String(error));
14
+ /** A value to copy, with a button that says when it is copied. */
15
+ function Copyable({ value, label, }) {
16
+ const { t } = useTranslation('integrations');
17
+ const [copied, setCopied] = useState(false);
18
+ return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("code", { className: "min-w-0 flex-1 select-all break-all rounded bg-muted px-2 py-1 font-mono text-xs", children: value }), _jsx(Button, { size: "icon", variant: "ghost", "aria-label": t('oauth.copy', { what: label }), onClick: () => {
19
+ void navigator.clipboard?.writeText(value).then(() => setCopied(true));
20
+ }, children: copied ? _jsx(Check, { "aria-hidden": true }) : _jsx(Copy, { "aria-hidden": true }) })] }));
21
+ }
22
+ function NewAppDialog({ api, open, onOpenChange, }) {
23
+ const { t } = useTranslation('integrations');
24
+ const id = useId();
25
+ const queryClient = useQueryClient();
26
+ const [name, setName] = useState('');
27
+ const [uris, setUris] = useState('');
28
+ const [chosen, setChosen] = useState([]);
29
+ const [confidential, setConfidential] = useState(true);
30
+ const scopes = useQuery({
31
+ queryKey: ['auth', 'scopes'],
32
+ queryFn: () => api.call('GET', '/api/v1/auth/scopes'),
33
+ });
34
+ const create = useMutation({
35
+ mutationFn: () => api.call('POST', '/api/v1/oauth/apps', {
36
+ name,
37
+ confidential,
38
+ redirectUris: uris
39
+ .split(/\s+/)
40
+ .map((u) => u.trim())
41
+ .filter((u) => u !== ''),
42
+ scopes: chosen,
43
+ }),
44
+ onSuccess: () => void queryClient.invalidateQueries({ queryKey: ['oauth', 'apps'] }),
45
+ });
46
+ useEffect(() => {
47
+ if (!open) {
48
+ setName('');
49
+ setUris('');
50
+ setChosen([]);
51
+ setConfidential(true);
52
+ create.reset();
53
+ }
54
+ }, [open, create.reset]);
55
+ const made = create.data;
56
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, title: t('oauth.newTitle'), description: t('oauth.newHint'), wide: true, footer: made === undefined ? (_jsxs(_Fragment, { children: [_jsx(Button, { onClick: () => onOpenChange(false), children: t('oauth.cancel') }), _jsx(Button, { variant: "primary", busy: create.isPending, disabled: name.trim() === '' || uris.trim() === '' || chosen.length === 0, onClick: () => create.mutate(), children: t('oauth.create') })] })) : (_jsx(Button, { variant: "primary", onClick: () => onOpenChange(false), children: t('oauth.done') })), children: made !== undefined ? (_jsxs("div", { className: "grid gap-3", children: [_jsx(Alert, { tone: "warning", children: made.clientSecret === null ? t('oauth.publicMade') : t('oauth.secretOnce') }), _jsxs("div", { className: "grid gap-1", children: [_jsx("span", { className: "text-sm font-medium", children: t('oauth.clientId') }), _jsx(Copyable, { value: made.clientId, label: t('oauth.clientId') })] }), made.clientSecret === null ? null : (_jsxs("div", { className: "grid gap-1", "data-testid": "oauth-secret", children: [_jsx("span", { className: "text-sm font-medium", children: t('oauth.clientSecret') }), _jsx(Copyable, { value: made.clientSecret, label: t('oauth.clientSecret') })] }))] })) : (_jsxs("div", { className: "grid gap-4", children: [_jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { htmlFor: `${id}-name`, children: t('oauth.name') }), _jsx(Input, { id: `${id}-name`, value: name, onChange: (e) => setName(e.target.value) })] }), _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { htmlFor: `${id}-uris`, children: t('oauth.redirects') }), _jsx("textarea", { id: `${id}-uris`, rows: 2, className: "rounded-md border bg-surface px-3 py-2 font-mono text-sm", placeholder: "https://partner.example.com/oauth/callback", value: uris, onChange: (e) => setUris(e.target.value) }), _jsx("p", { className: "text-xs text-muted-foreground", children: t('oauth.redirectsHint') })] }), _jsxs("fieldset", { className: "grid gap-2", children: [_jsx("legend", { className: "mb-1 text-sm font-medium", children: t('oauth.scopes') }), _jsx("div", { className: "grid max-h-48 gap-1.5 overflow-auto rounded-md border p-2 sm:grid-cols-2", children: (scopes.data?.scopes ?? []).map((s) => (_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(Checkbox, { id: `${id}-scope-${s.scope}`, checked: chosen.includes(s.scope), onCheckedChange: (on) => setChosen((all) => on === true ? [...all, s.scope] : all.filter((x) => x !== s.scope)) }), _jsx(Label, { htmlFor: `${id}-scope-${s.scope}`, className: "font-normal", children: s.label }), _jsx("code", { className: "ms-auto font-mono text-xs text-muted-foreground", children: s.scope })] }, s.scope))) })] }), _jsxs("div", { className: "flex items-start gap-2 text-sm", children: [_jsx(Checkbox, { id: `${id}-public`, checked: !confidential, onCheckedChange: (on) => setConfidential(on !== true) }), _jsxs(Label, { htmlFor: `${id}-public`, className: "font-normal", children: [t('oauth.public'), _jsx("span", { className: "block text-xs text-muted-foreground", children: t('oauth.publicHint') })] })] }), create.error === null ? null : _jsx(Alert, { tone: "danger", children: message(create.error) })] })) }));
57
+ }
58
+ export function OAuthAppsPage({ api }) {
59
+ const { t } = useTranslation('integrations');
60
+ const queryClient = useQueryClient();
61
+ const [creating, setCreating] = useState(false);
62
+ const [secret, setSecret] = useState(null);
63
+ const apps = useQuery({
64
+ queryKey: ['oauth', 'apps'],
65
+ queryFn: () => api.call('GET', '/api/v1/oauth/apps'),
66
+ });
67
+ const refresh = () => void queryClient.invalidateQueries({ queryKey: ['oauth', 'apps'] });
68
+ const rotate = useMutation({
69
+ mutationFn: (app) => api
70
+ .call('POST', `/api/v1/oauth/apps/${app.id}/secret`)
71
+ .then((r) => setSecret({ app: app.name, value: r.clientSecret })),
72
+ });
73
+ const toggle = useMutation({
74
+ mutationFn: (app) => api.call('PATCH', `/api/v1/oauth/apps/${app.id}`, { active: !app.active }),
75
+ onSuccess: refresh,
76
+ });
77
+ const error = apps.error ?? rotate.error ?? toggle.error;
78
+ return (_jsxs("div", { className: "mx-auto grid max-w-4xl gap-6", children: [_jsxs("header", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-xl font-semibold", children: t('oauth.title') }), _jsx("p", { className: "text-sm text-muted-foreground", children: t('oauth.intro') })] }), _jsxs(Button, { variant: "primary", onClick: () => setCreating(true), children: [_jsx(Plus, { className: "size-4", "aria-hidden": true }), t('oauth.new')] })] }), error === null ? null : _jsx(Alert, { tone: "danger", children: message(error) }), secret === null ? null : (_jsxs(Alert, { tone: "warning", children: [_jsx("p", { className: "mb-2", children: t('oauth.newSecret', { app: secret.app }) }), _jsx(Copyable, { value: secret.value, label: t('oauth.clientSecret') })] })), apps.data === undefined ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "\u2026" })) : apps.data.apps.length === 0 ? (_jsx("p", { className: "rounded-lg border bg-surface p-6 text-center text-sm text-muted-foreground", children: t('oauth.none') })) : (_jsx("ul", { className: "grid gap-3", children: apps.data.apps.map((a) => (_jsxs("li", { className: "grid gap-3 rounded-lg border bg-surface p-4", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(KeyRound, { className: "size-4 text-muted-foreground", "aria-hidden": true }), _jsx("span", { className: "font-medium", children: a.name }), _jsx(Badge, { tone: a.confidential ? 'neutral' : 'info', children: a.confidential ? t('oauth.confidential') : t('oauth.publicBadge') }), a.active ? null : _jsx(Badge, { tone: "warning", children: t('oauth.inactive') }), _jsx("span", { className: "flex-1" }), a.confidential ? (_jsx(Button, { size: "sm", busy: rotate.isPending && rotate.variables?.id === a.id, onClick: () => rotate.mutate(a), children: t('oauth.rotate') })) : null, _jsx(Button, { size: "sm", variant: "ghost", busy: toggle.isPending && toggle.variables?.id === a.id, onClick: () => toggle.mutate(a), children: a.active ? t('oauth.deactivate') : t('oauth.activate') })] }), _jsxs("dl", { className: "grid gap-2 text-sm sm:grid-cols-[10rem_1fr]", children: [_jsx("dt", { className: "text-muted-foreground", children: t('oauth.clientId') }), _jsx("dd", { children: _jsx(Copyable, { value: a.clientId, label: t('oauth.clientId') }) }), _jsx("dt", { className: "text-muted-foreground", children: t('oauth.redirects') }), _jsx("dd", { className: "break-all font-mono text-xs", children: a.redirectUris.join('\n') }), _jsx("dt", { className: "text-muted-foreground", children: t('oauth.scopes') }), _jsx("dd", { className: "flex flex-wrap gap-1", children: a.scopes.map((s) => (_jsx(Badge, { children: _jsx("span", { className: "font-mono text-xs", children: s }) }, s))) })] })] }, a.id))) })), _jsx(NewAppDialog, { api: api, open: creating, onOpenChange: setCreating })] }));
79
+ }
@@ -10,6 +10,7 @@ import { messages } from './messages.js';
10
10
  export { DeliveryTools } from './DeliveryTools.js';
11
11
  export { EndpointTools } from './EndpointTools.js';
12
12
  export { InboundTools } from './InboundTools.js';
13
+ export { OAuthAppsPage } from './OAuthAppsPage.js';
13
14
  export { WebhookTools } from './WebhookTools.js';
14
15
  /** Registers the components (and the messages in `i18n`, when given). */
15
16
  export declare function registerIntegrationsWeb(registry: Registry, i18n?: i18n): Registry;