@jini-ai/admin 0.1.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.
Files changed (235) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +138 -0
  3. package/dist/browser/index.d.ts +8 -0
  4. package/dist/browser/index.d.ts.map +1 -0
  5. package/dist/browser/index.js +8 -0
  6. package/dist/browser/index.js.map +1 -0
  7. package/dist/browser/navigation.d.ts +39 -0
  8. package/dist/browser/navigation.d.ts.map +1 -0
  9. package/dist/browser/navigation.js +113 -0
  10. package/dist/browser/navigation.js.map +1 -0
  11. package/dist/core/gated/types.d.ts +87 -0
  12. package/dist/core/gated/types.d.ts.map +1 -0
  13. package/dist/core/gated/types.js +37 -0
  14. package/dist/core/gated/types.js.map +1 -0
  15. package/dist/core/index.d.ts +20 -0
  16. package/dist/core/index.d.ts.map +1 -0
  17. package/dist/core/index.js +15 -0
  18. package/dist/core/index.js.map +1 -0
  19. package/dist/core/manifest/rules.d.ts +84 -0
  20. package/dist/core/manifest/rules.d.ts.map +1 -0
  21. package/dist/core/manifest/rules.js +130 -0
  22. package/dist/core/manifest/rules.js.map +1 -0
  23. package/dist/core/manifest/types.d.ts +154 -0
  24. package/dist/core/manifest/types.d.ts.map +1 -0
  25. package/dist/core/manifest/types.js +31 -0
  26. package/dist/core/manifest/types.js.map +1 -0
  27. package/dist/core/permissions/rules.d.ts +32 -0
  28. package/dist/core/permissions/rules.d.ts.map +1 -0
  29. package/dist/core/permissions/rules.js +34 -0
  30. package/dist/core/permissions/rules.js.map +1 -0
  31. package/dist/core/ports/analytics.d.ts +35 -0
  32. package/dist/core/ports/analytics.d.ts.map +1 -0
  33. package/dist/core/ports/analytics.js +14 -0
  34. package/dist/core/ports/analytics.js.map +1 -0
  35. package/dist/core/ports/auth.d.ts +49 -0
  36. package/dist/core/ports/auth.d.ts.map +1 -0
  37. package/dist/core/ports/auth.js +19 -0
  38. package/dist/core/ports/auth.js.map +1 -0
  39. package/dist/core/ports/comments.d.ts +90 -0
  40. package/dist/core/ports/comments.d.ts.map +1 -0
  41. package/dist/core/ports/comments.js +24 -0
  42. package/dist/core/ports/comments.js.map +1 -0
  43. package/dist/core/ports/database.d.ts +101 -0
  44. package/dist/core/ports/database.d.ts.map +1 -0
  45. package/dist/core/ports/database.js +2 -0
  46. package/dist/core/ports/database.js.map +1 -0
  47. package/dist/core/ports/forms.d.ts +130 -0
  48. package/dist/core/ports/forms.d.ts.map +1 -0
  49. package/dist/core/ports/forms.js +62 -0
  50. package/dist/core/ports/forms.js.map +1 -0
  51. package/dist/core/ports/identity.d.ts +114 -0
  52. package/dist/core/ports/identity.d.ts.map +1 -0
  53. package/dist/core/ports/identity.js +28 -0
  54. package/dist/core/ports/identity.js.map +1 -0
  55. package/dist/core/ports/index.d.ts +21 -0
  56. package/dist/core/ports/index.d.ts.map +1 -0
  57. package/dist/core/ports/index.js +6 -0
  58. package/dist/core/ports/index.js.map +1 -0
  59. package/dist/core/ports/integrations.d.ts +81 -0
  60. package/dist/core/ports/integrations.d.ts.map +1 -0
  61. package/dist/core/ports/integrations.js +21 -0
  62. package/dist/core/ports/integrations.js.map +1 -0
  63. package/dist/core/ports/media.d.ts +74 -0
  64. package/dist/core/ports/media.d.ts.map +1 -0
  65. package/dist/core/ports/media.js +28 -0
  66. package/dist/core/ports/media.js.map +1 -0
  67. package/dist/core/ports/members.d.ts +50 -0
  68. package/dist/core/ports/members.d.ts.map +1 -0
  69. package/dist/core/ports/members.js +17 -0
  70. package/dist/core/ports/members.js.map +1 -0
  71. package/dist/core/ports/menus.d.ts +179 -0
  72. package/dist/core/ports/menus.d.ts.map +1 -0
  73. package/dist/core/ports/menus.js +70 -0
  74. package/dist/core/ports/menus.js.map +1 -0
  75. package/dist/core/ports/plugins.d.ts +68 -0
  76. package/dist/core/ports/plugins.d.ts.map +1 -0
  77. package/dist/core/ports/plugins.js +27 -0
  78. package/dist/core/ports/plugins.js.map +1 -0
  79. package/dist/core/ports/recovery.d.ts +171 -0
  80. package/dist/core/ports/recovery.d.ts.map +1 -0
  81. package/dist/core/ports/recovery.js +2 -0
  82. package/dist/core/ports/recovery.js.map +1 -0
  83. package/dist/core/ports/redirects.d.ts +139 -0
  84. package/dist/core/ports/redirects.d.ts.map +1 -0
  85. package/dist/core/ports/redirects.js +55 -0
  86. package/dist/core/ports/redirects.js.map +1 -0
  87. package/dist/core/ports/seo.d.ts +147 -0
  88. package/dist/core/ports/seo.d.ts.map +1 -0
  89. package/dist/core/ports/seo.js +39 -0
  90. package/dist/core/ports/seo.js.map +1 -0
  91. package/dist/core/ports/settings.d.ts +87 -0
  92. package/dist/core/ports/settings.d.ts.map +1 -0
  93. package/dist/core/ports/settings.js +23 -0
  94. package/dist/core/ports/settings.js.map +1 -0
  95. package/dist/core/ports/workspace.d.ts +44 -0
  96. package/dist/core/ports/workspace.d.ts.map +1 -0
  97. package/dist/core/ports/workspace.js +29 -0
  98. package/dist/core/ports/workspace.js.map +1 -0
  99. package/dist/core/routing/rules.d.ts +54 -0
  100. package/dist/core/routing/rules.d.ts.map +1 -0
  101. package/dist/core/routing/rules.js +113 -0
  102. package/dist/core/routing/rules.js.map +1 -0
  103. package/dist/core/routing/types.d.ts +36 -0
  104. package/dist/core/routing/types.d.ts.map +1 -0
  105. package/dist/core/routing/types.js +17 -0
  106. package/dist/core/routing/types.js.map +1 -0
  107. package/dist/core/transport/errors.d.ts +53 -0
  108. package/dist/core/transport/errors.d.ts.map +1 -0
  109. package/dist/core/transport/errors.js +63 -0
  110. package/dist/core/transport/errors.js.map +1 -0
  111. package/dist/core/transport/http.d.ts +63 -0
  112. package/dist/core/transport/http.d.ts.map +1 -0
  113. package/dist/core/transport/http.js +63 -0
  114. package/dist/core/transport/http.js.map +1 -0
  115. package/dist/core/transport/index.d.ts +5 -0
  116. package/dist/core/transport/index.d.ts.map +1 -0
  117. package/dist/core/transport/index.js +3 -0
  118. package/dist/core/transport/index.js.map +1 -0
  119. package/dist/core/transport/types.d.ts +81 -0
  120. package/dist/core/transport/types.d.ts.map +1 -0
  121. package/dist/core/transport/types.js +43 -0
  122. package/dist/core/transport/types.js.map +1 -0
  123. package/dist/react/components/ConfirmButton/ConfirmButton.d.ts +40 -0
  124. package/dist/react/components/ConfirmButton/ConfirmButton.d.ts.map +1 -0
  125. package/dist/react/components/ConfirmButton/ConfirmButton.hooks.d.ts +22 -0
  126. package/dist/react/components/ConfirmButton/ConfirmButton.hooks.d.ts.map +1 -0
  127. package/dist/react/components/ConfirmButton/ConfirmButton.hooks.js +59 -0
  128. package/dist/react/components/ConfirmButton/ConfirmButton.hooks.js.map +1 -0
  129. package/dist/react/components/ConfirmButton/ConfirmButton.js +40 -0
  130. package/dist/react/components/ConfirmButton/ConfirmButton.js.map +1 -0
  131. package/dist/react/components/ConfirmButton.d.ts +39 -0
  132. package/dist/react/components/ConfirmButton.d.ts.map +1 -0
  133. package/dist/react/components/ConfirmButton.js +79 -0
  134. package/dist/react/components/ConfirmButton.js.map +1 -0
  135. package/dist/react/components/ConfirmDialog/ConfirmDialog.d.ts +90 -0
  136. package/dist/react/components/ConfirmDialog/ConfirmDialog.d.ts.map +1 -0
  137. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts +49 -0
  138. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts.map +1 -0
  139. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js +81 -0
  140. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js.map +1 -0
  141. package/dist/react/components/ConfirmDialog/ConfirmDialog.js +92 -0
  142. package/dist/react/components/ConfirmDialog/ConfirmDialog.js.map +1 -0
  143. package/dist/react/components/ConfirmDialog.d.ts +57 -0
  144. package/dist/react/components/ConfirmDialog.d.ts.map +1 -0
  145. package/dist/react/components/ConfirmDialog.js +85 -0
  146. package/dist/react/components/ConfirmDialog.js.map +1 -0
  147. package/dist/react/components/DataTable.d.ts +97 -0
  148. package/dist/react/components/DataTable.d.ts.map +1 -0
  149. package/dist/react/components/DataTable.js +20 -0
  150. package/dist/react/components/DataTable.js.map +1 -0
  151. package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.d.ts +25 -0
  152. package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.d.ts.map +1 -0
  153. package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.js +148 -0
  154. package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.js.map +1 -0
  155. package/dist/react/components/RowMenu/RowMenu.d.ts +77 -0
  156. package/dist/react/components/RowMenu/RowMenu.d.ts.map +1 -0
  157. package/dist/react/components/RowMenu/RowMenu.hooks.d.ts +30 -0
  158. package/dist/react/components/RowMenu/RowMenu.hooks.d.ts.map +1 -0
  159. package/dist/react/components/RowMenu/RowMenu.hooks.js +154 -0
  160. package/dist/react/components/RowMenu/RowMenu.hooks.js.map +1 -0
  161. package/dist/react/components/RowMenu/RowMenu.js +46 -0
  162. package/dist/react/components/RowMenu/RowMenu.js.map +1 -0
  163. package/dist/react/components/RowMenu.d.ts +44 -0
  164. package/dist/react/components/RowMenu.d.ts.map +1 -0
  165. package/dist/react/components/RowMenu.js +149 -0
  166. package/dist/react/components/RowMenu.js.map +1 -0
  167. package/dist/react/components/Sidebar.d.ts +128 -0
  168. package/dist/react/components/Sidebar.d.ts.map +1 -0
  169. package/dist/react/components/Sidebar.js +168 -0
  170. package/dist/react/components/Sidebar.js.map +1 -0
  171. package/dist/react/hooks/use-nav-sections.d.ts +50 -0
  172. package/dist/react/hooks/use-nav-sections.d.ts.map +1 -0
  173. package/dist/react/hooks/use-nav-sections.js +112 -0
  174. package/dist/react/hooks/use-nav-sections.js.map +1 -0
  175. package/dist/react/hooks/use-sidebar-rail.d.ts +39 -0
  176. package/dist/react/hooks/use-sidebar-rail.d.ts.map +1 -0
  177. package/dist/react/hooks/use-sidebar-rail.js +93 -0
  178. package/dist/react/hooks/use-sidebar-rail.js.map +1 -0
  179. package/dist/react/index.d.ts +53 -0
  180. package/dist/react/index.d.ts.map +1 -0
  181. package/dist/react/index.js +53 -0
  182. package/dist/react/index.js.map +1 -0
  183. package/dist/react/types.d.ts +28 -0
  184. package/dist/react/types.d.ts.map +1 -0
  185. package/dist/react/types.js +23 -0
  186. package/dist/react/types.js.map +1 -0
  187. package/dist/server/composio/bounded-data.d.ts +36 -0
  188. package/dist/server/composio/bounded-data.d.ts.map +1 -0
  189. package/dist/server/composio/bounded-data.js +181 -0
  190. package/dist/server/composio/bounded-data.js.map +1 -0
  191. package/dist/server/composio/catalog.d.ts +147 -0
  192. package/dist/server/composio/catalog.d.ts.map +1 -0
  193. package/dist/server/composio/catalog.js +126 -0
  194. package/dist/server/composio/catalog.js.map +1 -0
  195. package/dist/server/composio/composio-config.d.ts +42 -0
  196. package/dist/server/composio/composio-config.d.ts.map +1 -0
  197. package/dist/server/composio/composio-config.js +145 -0
  198. package/dist/server/composio/composio-config.js.map +1 -0
  199. package/dist/server/composio/composio-descriptions.d.ts +16 -0
  200. package/dist/server/composio/composio-descriptions.d.ts.map +1 -0
  201. package/dist/server/composio/composio-descriptions.js +766 -0
  202. package/dist/server/composio/composio-descriptions.js.map +1 -0
  203. package/dist/server/composio/composio.d.ts +364 -0
  204. package/dist/server/composio/composio.d.ts.map +1 -0
  205. package/dist/server/composio/composio.js +1902 -0
  206. package/dist/server/composio/composio.js.map +1 -0
  207. package/dist/server/composio/errors.d.ts +15 -0
  208. package/dist/server/composio/errors.d.ts.map +1 -0
  209. package/dist/server/composio/errors.js +16 -0
  210. package/dist/server/composio/errors.js.map +1 -0
  211. package/dist/server/composio/file-lock.d.ts +13 -0
  212. package/dist/server/composio/file-lock.d.ts.map +1 -0
  213. package/dist/server/composio/file-lock.js +92 -0
  214. package/dist/server/composio/file-lock.js.map +1 -0
  215. package/dist/server/composio/index.d.ts +18 -0
  216. package/dist/server/composio/index.d.ts.map +1 -0
  217. package/dist/server/composio/index.js +7 -0
  218. package/dist/server/composio/index.js.map +1 -0
  219. package/dist/server/composio/json-schema.d.ts +93 -0
  220. package/dist/server/composio/json-schema.d.ts.map +1 -0
  221. package/dist/server/composio/json-schema.js +498 -0
  222. package/dist/server/composio/json-schema.js.map +1 -0
  223. package/dist/server/composio/output-protection.d.ts +32 -0
  224. package/dist/server/composio/output-protection.d.ts.map +1 -0
  225. package/dist/server/composio/output-protection.js +105 -0
  226. package/dist/server/composio/output-protection.js.map +1 -0
  227. package/dist/server/composio/service.d.ts +181 -0
  228. package/dist/server/composio/service.d.ts.map +1 -0
  229. package/dist/server/composio/service.js +758 -0
  230. package/dist/server/composio/service.js.map +1 -0
  231. package/dist/server/index.d.ts +15 -0
  232. package/dist/server/index.d.ts.map +1 -0
  233. package/dist/server/index.js +15 -0
  234. package/dist/server/index.js.map +1 -0
  235. package/package.json +92 -0
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for describing the origin of the Work and
141
+ reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Support. While redistributing the Work or
166
+ Derivative Works thereof, You may choose to offer, and charge a
167
+ fee for, acceptance of support, warranty, indemnity, or other
168
+ liability obligations and/or rights consistent with this License.
169
+ However, in accepting such obligations, You may act only on Your
170
+ own behalf and on Your sole responsibility, not on behalf of any
171
+ other Contributor, and only if You agree to indemnify, defend,
172
+ and hold each Contributor harmless for any liability incurred by,
173
+ or claims asserted against, such Contributor by reason of your
174
+ accepting any such warranty or support.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2026 Open Design contributors
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,138 @@
1
+ # `@jini-ai/admin`
2
+
3
+ A composable admin surface for Jini-hosted products. A host picks the panels it wants, wires the
4
+ ports those panels need, and gets a working admin — sidebar, routing, and agent-navigation
5
+ allowlist all derived from one declaration.
6
+
7
+ Extracted from the reference implementation's admin SPA, which had grown a 1,548-line API client
8
+ with 134 methods in a single object and defined every section across three files that had to be
9
+ kept in sync by hand.
10
+
11
+ ## Layers
12
+
13
+ Import only what you need. `sideEffects: false` plus per-layer subpaths means an unused layer is
14
+ not in your bundle.
15
+
16
+ | Subpath | Contains | Needs |
17
+ |---|---|---|
18
+ | `@jini-ai/admin/core` | contracts, panel registry, route matching, transport, ports | nothing |
19
+ | `@jini-ai/admin/browser` | `window`-bound navigation, link interception | a DOM |
20
+ | `@jini-ai/admin/server` | Composio integration: catalog, OAuth, tool execution | Node.js |
21
+ | `@jini-ai/admin/react` *(not built yet)* | `<AdminShell>`, primitives, panels | React (optional peer) |
22
+
23
+ `/core` is the layer a panel author codes against: no React, no DOM, no I/O. That boundary is
24
+ enforced at runtime — this package's vitest config runs `src/core/**` without a jsdom environment,
25
+ so a `window` reference in core fails loudly instead of passing quietly.
26
+
27
+ React and react-dom are **optional** peer dependencies (`peerDependenciesMeta`), so a consumer
28
+ importing only `/core` is not asked to install them.
29
+
30
+ ## A panel
31
+
32
+ ```ts
33
+ import type { AdminPanel } from '@jini-ai/admin/core';
34
+
35
+ export const usersPanel: AdminPanel<() => ReactNode> = {
36
+ id: 'users',
37
+ render: () => <Users />,
38
+ nav: { label: 'Users', group: 'People', order: 1 },
39
+ requires: ['identity'], // dropped entirely if no identity port is wired
40
+ permissions: ['users.read'], // affordance only — never the authz boundary
41
+ agentReachable: true, // explicit opt-in; defaults to false
42
+ routes: [{ pattern: '/:userId', view: 'user-detail' }],
43
+ };
44
+ ```
45
+
46
+ Three properties carry decisions worth not re-deriving:
47
+
48
+ - **`nav` is optional.** A panel can be routable without a sidebar row (the reference
49
+ implementation's `appearance` and `settings-raw` panels both rely on this).
50
+ - **`agentReachable` defaults to `false` and must stay an explicit opt-in.** It is the allowlist
51
+ behind `page.navigate`-style capabilities. Deriving it from panel registration would make every
52
+ new screen agent-reachable as a side effect of existing, which inverts the point of an
53
+ allowlist. An AI generating a panel manifest cannot make itself reachable by omission.
54
+ - **`requires` is how a host composes.** You do not ship or omit panel *code*; you supply or
55
+ withhold the *ports* a panel names, and unmet panels vanish — no dead nav row, no route that
56
+ renders an error.
57
+
58
+ ## Assembling a shell
59
+
60
+ ```ts
61
+ import { resolvePanels, buildNav, buildAgentPageMap, matchRoute } from '@jini-ai/admin/core';
62
+
63
+ const mounted = resolvePanels(ALL_PANELS, { capabilities: wiredPorts, permissions: me.permissions });
64
+ const nav = buildNav(mounted);
65
+ const agentPages = buildAgentPageMap(mounted); // pass the RESOLVED set, never the raw one
66
+ const route = matchRoute('/users/u1', mounted);
67
+ // -> { panelId: 'users', view: 'user-detail', params: { userId: 'u1' }, query }
68
+ ```
69
+
70
+ Route matching is registry-driven: a panel declares its own detail routes and the matcher is
71
+ generic. Unregistered paths return `panelId: null` so the shell can fall through to the dashboard,
72
+ matching the ported behaviour — a typo should look like a bad URL, not an empty screen.
73
+
74
+ ## Adding your own routes alongside the shipped ones
75
+
76
+ Every route group is `(transport) => port`. Jini's and yours are the same shape, so they compose
77
+ into one client with one auth policy, one error class, and one place to add retries or tracing:
78
+
79
+ ```ts
80
+ import { createAdminClient, createHttpTransport } from '@jini-ai/admin/core';
81
+
82
+ const transport = createHttpTransport({ baseUrl: '/api/admin/v1' });
83
+
84
+ const client = createAdminClient(transport, {
85
+ identity: createIdentityRoutes, // shipped by @jini-ai/admin
86
+ media: createMediaRoutes, // shipped by @jini-ai/admin
87
+ posts: createHostPostRoutes, // yours, same signature
88
+ widgets: createHostWidgetRoutes, // yours
89
+ });
90
+
91
+ await client.identity.listUsers();
92
+ await client.posts.list();
93
+ await client.transport.request('/one-off'); // escape hatch for un-wrapped routes
94
+ ```
95
+
96
+ `AdminTransport` is an interface rather than a bare function so a host can supply a non-HTTP
97
+ implementation — an in-process direct dispatch for a multi-instance runner, or a fixture-returning
98
+ fake in tests — without any route group knowing.
99
+
100
+ ## Errors
101
+
102
+ Route groups throw `AdminApiError` (`status`, `code`, raw `body`). There is deliberately **no**
103
+ shared code-to-message table: the same `code` means genuinely different things in different
104
+ domains, and a shared table could only pick one. `describeApiError` is the base case only; panels
105
+ layer their own per-code copy on top and fall through to it.
106
+
107
+ ## Not a security boundary
108
+
109
+ `hasPermission` and a panel's `permissions` decide whether a control renders. They never run on
110
+ the server. A bug here can only show or hide a control; it cannot grant or block the underlying
111
+ operation, because every mutation must be independently re-checked server-side. Do not import
112
+ these into server code.
113
+
114
+ ## Composio integration has moved
115
+
116
+ `@jini-ai/admin/server` no longer exists. Composio started as its own standalone package
117
+ (`@jini-ai/composio`), was folded into this package as `./server` on 2026-08-01, and has since
118
+ moved back out — now `@jini-ai/integrations/composio`, one of two subpaths (alongside
119
+ `@jini-ai/integrations/media-providers`) under the single `@jini-ai/integrations` package
120
+ (`packages/integrations/`). See that package's own `README.md` and `src/composio/source-map.md`
121
+ for full provenance. Import it directly rather than through `@jini-ai/admin`.
122
+
123
+ ## Before writing a panel: check `@jini-ai/ui-core` first
124
+
125
+ `@jini-ai/ui-core` already models several domains an admin panel would otherwise re-derive —
126
+ `execution`, `integrations`, `connectors`, `media-providers`, `notifications`, `appearance`. Reuse
127
+ its ports and rules rather than defining a second (or third) version. See that package's README
128
+ for the full map and for the `DetectedAgent` drift that motivated this rule.
129
+
130
+ Panels that reuse `ui-core` take the dependency in `/react/panels/*`. **`/core` stays
131
+ zero-dependency** — otherwise every consumer of the contracts layer pulls in 6,000+ lines of
132
+ unrelated domain features to get a type.
133
+
134
+ ## Status
135
+
136
+ Slice 1: `/core` and `/browser`, 76 tests. `/server` (Composio, folded in 2026-08-01, moved back out
137
+ to `@jini-ai/integrations/composio`) no longer exists in this package. `/react` is not built yet,
138
+ and of the twelve planned ports only `AdminIdentityPort` is specified.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @file `@jini-ai/admin/browser` — DOM-bound helpers. No React.
3
+ *
4
+ * Split from `/core` so the universal half stays testable and reusable without a DOM. See
5
+ * `navigation.ts`'s header.
6
+ */
7
+ export { NAVIGATION_EVENT, installInternalLinkInterceptor, navigate, readRoutePath, subscribeToRoute, } from './navigation.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,gBAAgB,EAChB,8BAA8B,EAC9B,QAAQ,EACR,aAAa,EACb,gBAAgB,GACjB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @file `@jini-ai/admin/browser` — DOM-bound helpers. No React.
3
+ *
4
+ * Split from `/core` so the universal half stays testable and reusable without a DOM. See
5
+ * `navigation.ts`'s header.
6
+ */
7
+ export { NAVIGATION_EVENT, installInternalLinkInterceptor, navigate, readRoutePath, subscribeToRoute, } from './navigation.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,gBAAgB,EAChB,8BAA8B,EAC9B,QAAQ,EACR,aAAa,EACb,gBAAgB,GACjB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @file `window`-bound navigation. DOM, but no React.
3
+ *
4
+ * Ported from the reference implementation's `lib/router.ts`. Separated from `core/routing` because that module must stay
5
+ * universal — a Vue consumer, an SSR pass, or a test asserting route rules should not need a DOM.
6
+ * Everything here genuinely touches `window`; everything that does not stayed in core.
7
+ *
8
+ * This is not a fourth architectural layer so much as an honest home for four functions. It
9
+ * follows the `src/browser/` split `@jini-ai/ui` already uses.
10
+ */
11
+ /** Fires on `navigate()`. `pushState` does not emit `popstate`, so subscribers need this too. */
12
+ export declare const NAVIGATION_EVENT = "jini:admin-navigate";
13
+ /** The current route path, read from the address bar. */
14
+ export declare function readRoutePath(base?: string): string;
15
+ /**
16
+ * Navigates without a page load.
17
+ *
18
+ * Takes a *route path*, not a URL — passing `/admin/settings` here would produce
19
+ * `/admin/admin/settings`, which is exactly the class of mistake `adminHref` prevents.
20
+ */
21
+ export declare function navigate(routePath: string, options?: {
22
+ readonly replace?: boolean;
23
+ readonly base?: string;
24
+ }): void;
25
+ /**
26
+ * Turns clicks on internal `<a href="/admin/...">` links into SPA navigations.
27
+ *
28
+ * A document-level listener rather than a `<Link>` component, and deliberately so: panel markup
29
+ * should stay plain anchors, because they are real URLs that middle-click, cmd-click and "copy
30
+ * link address" should all treat normally. Intercepting only the plain-left-click case preserves
31
+ * every one of those behaviours for free, where a `<Link>` component would have to re-implement
32
+ * them.
33
+ *
34
+ * @returns a teardown function.
35
+ */
36
+ export declare function installInternalLinkInterceptor(base?: string): () => void;
37
+ /** Subscribes to route changes from both `popstate` and programmatic `navigate()`. */
38
+ export declare function subscribeToRoute(onChange: () => void): () => void;
39
+ //# sourceMappingURL=navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/browser/navigation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,iGAAiG;AACjG,eAAO,MAAM,gBAAgB,wBAAwB,CAAC;AAEtD,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,IAAI,GAAE,MAA2B,GAAG,MAAM,CAEvE;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACnE,IAAI,CA8BN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,GAAE,MAA2B,GAAG,MAAM,IAAI,CAiC5F;AAED,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAOjE"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @file `window`-bound navigation. DOM, but no React.
3
+ *
4
+ * Ported from the reference implementation's `lib/router.ts`. Separated from `core/routing` because that module must stay
5
+ * universal — a Vue consumer, an SSR pass, or a test asserting route rules should not need a DOM.
6
+ * Everything here genuinely touches `window`; everything that does not stayed in core.
7
+ *
8
+ * This is not a fourth architectural layer so much as an honest home for four functions. It
9
+ * follows the `src/browser/` split `@jini-ai/ui` already uses.
10
+ */
11
+ import { DEFAULT_ADMIN_BASE, adminHref, currentRoutePath, stripTrailingSlash } from '../core/routing/rules.js';
12
+ /** Fires on `navigate()`. `pushState` does not emit `popstate`, so subscribers need this too. */
13
+ export const NAVIGATION_EVENT = 'jini:admin-navigate';
14
+ /** The current route path, read from the address bar. */
15
+ export function readRoutePath(base = DEFAULT_ADMIN_BASE) {
16
+ return currentRoutePath(window.location.pathname, base);
17
+ }
18
+ /**
19
+ * Navigates without a page load.
20
+ *
21
+ * Takes a *route path*, not a URL — passing `/admin/settings` here would produce
22
+ * `/admin/admin/settings`, which is exactly the class of mistake `adminHref` prevents.
23
+ */
24
+ export function navigate(routePath, options = {}) {
25
+ const base = options.base ?? DEFAULT_ADMIN_BASE;
26
+ const url = adminHref(routePath, base);
27
+ /*
28
+ * Navigating to where you already are is a no-op, not a history entry. Without this, clicking
29
+ * the already-active sidebar link five times pushes five identical entries and Back appears
30
+ * stuck on the same screen.
31
+ *
32
+ * Both sides go through `URL` before comparing rather than string-matching. `pushState` stores a
33
+ * *normalized* URL, so a path containing anything the browser percent-encodes (a space, any
34
+ * non-ASCII character) comes back out of `location.pathname` in a different spelling than
35
+ * `adminHref` produced — `/admin/collections/my recipe` vs `/admin/collections/my%20recipe`.
36
+ * Comparing raw strings there silently fails to match and pushes the duplicate anyway, which is
37
+ * the exact bug this guard exists to prevent.
38
+ *
39
+ * Trailing slash is normalized away because the matcher drops empty segments, so `/settings/`
40
+ * and `/settings` are the same screen. Query and hash are compared in full: a
41
+ * same-path/different-query navigation is a real one.
42
+ */
43
+ const target = new URL(url, window.location.href);
44
+ const isCurrent = stripTrailingSlash(target.pathname) === stripTrailingSlash(window.location.pathname) &&
45
+ target.search === window.location.search &&
46
+ target.hash === window.location.hash;
47
+ if (isCurrent)
48
+ return;
49
+ if (options.replace)
50
+ window.history.replaceState(null, '', url);
51
+ else
52
+ window.history.pushState(null, '', url);
53
+ window.dispatchEvent(new Event(NAVIGATION_EVENT));
54
+ }
55
+ /**
56
+ * Turns clicks on internal `<a href="/admin/...">` links into SPA navigations.
57
+ *
58
+ * A document-level listener rather than a `<Link>` component, and deliberately so: panel markup
59
+ * should stay plain anchors, because they are real URLs that middle-click, cmd-click and "copy
60
+ * link address" should all treat normally. Intercepting only the plain-left-click case preserves
61
+ * every one of those behaviours for free, where a `<Link>` component would have to re-implement
62
+ * them.
63
+ *
64
+ * @returns a teardown function.
65
+ */
66
+ export function installInternalLinkInterceptor(base = DEFAULT_ADMIN_BASE) {
67
+ const onClick = (event) => {
68
+ // Anything but an unmodified primary click is the browser's to handle: cmd/ctrl-click opens a
69
+ // tab, shift-click a window, alt-click downloads.
70
+ if (event.defaultPrevented)
71
+ return;
72
+ if (event.button !== 0)
73
+ return;
74
+ if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)
75
+ return;
76
+ const anchor = event.target?.closest?.('a');
77
+ if (!anchor)
78
+ return;
79
+ if (anchor.hasAttribute('download'))
80
+ return;
81
+ // An explicit target (`_blank`, a frame name) is an explicit request not to navigate in place.
82
+ const target = anchor.getAttribute('target');
83
+ if (target && target !== '_self')
84
+ return;
85
+ const href = anchor.getAttribute('href');
86
+ if (!href || href.startsWith('#'))
87
+ return;
88
+ // `anchor.href` is the resolved absolute form, which is what makes relative hrefs and
89
+ // cross-origin links both fall out correctly.
90
+ const url = new URL(anchor.href, window.location.href);
91
+ if (url.origin !== window.location.origin)
92
+ return;
93
+ if (url.pathname !== base && !url.pathname.startsWith(`${base}/`))
94
+ return;
95
+ event.preventDefault();
96
+ // `url.hash` is carried through: an in-page fragment (`/admin/settings#seo-defaults`) is not a
97
+ // routing concern, but dropping it silently loses the anchor. It never reaches the matcher —
98
+ // the route snapshot is path + query only — so preserving it cannot affect routing.
99
+ navigate(`${currentRoutePath(url.pathname, base)}${url.search}${url.hash}`, { base });
100
+ };
101
+ document.addEventListener('click', onClick);
102
+ return () => document.removeEventListener('click', onClick);
103
+ }
104
+ /** Subscribes to route changes from both `popstate` and programmatic `navigate()`. */
105
+ export function subscribeToRoute(onChange) {
106
+ window.addEventListener('popstate', onChange);
107
+ window.addEventListener(NAVIGATION_EVENT, onChange);
108
+ return () => {
109
+ window.removeEventListener('popstate', onChange);
110
+ window.removeEventListener(NAVIGATION_EVENT, onChange);
111
+ };
112
+ }
113
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/browser/navigation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * @file The plan -> confirm -> execute protocol for destructive operations.
3
+ *
4
+ * ## Why this is in core rather than in the panels that use it
5
+ *
6
+ * The reference implementation independently grew this same three-step shape in three unrelated places — database
7
+ * forward-migration (`planMigrateForward`/`confirmMigrateForward`/`executeMigrateForward`),
8
+ * point-in-time restore (`planRestore`/`confirmRestore`/`executeRestore`), and taxonomy term
9
+ * merge (`planMergeTerm`/`confirmMergeTerm`/`executeMergeTerm`) — sharing `GatedPlanResult<T>`
10
+ * and `GatedConfirmResult` types. Three independent arrivals at one shape is the signal that it
11
+ * is a protocol, not a coincidence, and any product doing irreversible operator actions will
12
+ * need it.
13
+ *
14
+ * ## What the three steps are for
15
+ *
16
+ * - **plan** is read-only and idempotent. It computes what *would* happen and returns a token.
17
+ * Safe to call on render; safe to call twice.
18
+ * - **confirm** records that the operator saw the plan. Separate from execute so the UI can show
19
+ * consequences the operator has to acknowledge, and so a stale plan (the world changed between
20
+ * plan and execute) can be rejected here rather than half-applied.
21
+ * - **execute** does the thing. Requires the token from confirm.
22
+ *
23
+ * The token is what makes this more than a confirmation dialog: it binds the execute call to a
24
+ * specific computed plan, so an operator cannot approve a small change and have a large one run.
25
+ *
26
+ * ## Warning: this protocol promises reversibility it cannot itself deliver
27
+ *
28
+ * A hard-won rule from the reference implementation's admin UX audit: **never promise an undo the
29
+ * product cannot deliver.** A `reversible: true` plan means the *backend* claims a revert path
30
+ * exists — it does not mean the admin has a reachable UI for it. The reference implementation's
31
+ * post/page delete is a genuine server-side
32
+ * soft delete with no restore path reachable from the admin. A panel rendering "you can undo
33
+ * this" off this flag alone would be lying to the operator. Check that the revert is reachable,
34
+ * not merely that it exists.
35
+ */
36
+ /** What `plan` returns: the computed consequences, plus the token that binds them to `execute`. */
37
+ export interface GatedPlanResult<TDetails = unknown> {
38
+ /** Opaque; pass back to `confirm`. Panels must not parse or construct these. */
39
+ readonly token: string;
40
+ /** Operation-specific description of what would happen — row counts, affected ids, warnings. */
41
+ readonly details: TDetails;
42
+ /** Whether the backend has a revert path. **Not** a claim that the admin exposes one — see the
43
+ * file header. */
44
+ readonly reversible?: boolean;
45
+ /** Operator-facing consequences to display before confirming. Rendered as-is; the backend owns
46
+ * the wording because it is the only side that knows the actual scope. */
47
+ readonly warnings?: readonly string[];
48
+ }
49
+ /** What `confirm` returns: the token `execute` requires. */
50
+ export interface GatedConfirmResult {
51
+ /** Distinct from the plan token. A backend may return the same value, but panels must pass
52
+ * through whatever they were given rather than reusing the plan's. */
53
+ readonly confirmToken: string;
54
+ }
55
+ /**
56
+ * A gated operation, as a panel sees it.
57
+ *
58
+ * Route groups implementing this get a consistent three-call shape, which is what lets a shared
59
+ * confirmation component drive any of them without knowing the operation.
60
+ *
61
+ * ## Why `confirm`/`execute` take a type parameter rather than a bare token
62
+ *
63
+ * The first draft of this interface declared `confirm(token: string)` and
64
+ * `execute(confirmToken: string)`, inferred from method names alone. Reading the actual reference
65
+ * signatures showed that only one of the three real triads fits that shape:
66
+ *
67
+ * - **migrate-forward** — confirm and execute each take only the token. Fits.
68
+ * - **restore** — `confirm` needs `{planId, planHash, disclosureAcknowledged}` and `execute` needs
69
+ * `{confirmationToken, restorePointId}`. Does not fit.
70
+ *
71
+ * The instructive one is restore's `disclosureAcknowledged`. It says this protocol is not merely a
72
+ * two-step token handshake, it is *recorded informed consent* — the operator was shown what would
73
+ * be lost and said yes. That is the most destructive operation in the product, so an interface that
74
+ * excludes it is describing the easy case and abandoning the one that matters. Widened rather than
75
+ * documented around.
76
+ *
77
+ * The extra parameters default to `string`, so the simple case still reads
78
+ * `GatedOperation<PlanInput, Details, Result>` with no change.
79
+ */
80
+ export interface GatedOperation<TPlanInput, TDetails, TResult, TConfirmInput = string, TExecuteInput = string> {
81
+ plan(input: TPlanInput): Promise<GatedPlanResult<TDetails>>;
82
+ /** Takes the plan's `token`, either bare or as one field of an operation-specific object. */
83
+ confirm(input: TConfirmInput): Promise<GatedConfirmResult>;
84
+ /** Takes the confirm step's `confirmToken`, bare or within an operation-specific object. */
85
+ execute(input: TExecuteInput): Promise<TResult>;
86
+ }
87
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/gated/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,mGAAmG;AACnG,MAAM,WAAW,eAAe,CAAC,QAAQ,GAAG,OAAO;IACjD,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gGAAgG;IAChG,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC3B;uBACmB;IACnB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;+EAC2E;IAC3E,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED,4DAA4D;AAC5D,MAAM,WAAW,kBAAkB;IACjC;2EACuE;IACvE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,cAAc,CAC7B,UAAU,EACV,QAAQ,EACR,OAAO,EACP,aAAa,GAAG,MAAM,EACtB,aAAa,GAAG,MAAM;IAEtB,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC5D,6FAA6F;IAC7F,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC3D,4FAA4F;IAC5F,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACjD"}