@nocobase/portal-template-default 1.0.9 → 1.0.10

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 (304) hide show
  1. package/.env.example +5 -0
  2. package/.github/workflows/publish.yml +106 -0
  3. package/.gitignore +33 -0
  4. package/AGENTS.md +19 -0
  5. package/README.MD +61 -180
  6. package/package.json +3 -5
  7. package/scripts/build-html.mjs +12 -0
  8. package/src/App.css +2 -0
  9. package/src/App.tsx +35 -186
  10. package/src/app/development.tsx +154 -0
  11. package/src/app/extension.ts +5 -0
  12. package/src/app/extensions.tsx +18 -4
  13. package/src/app/routes.tsx +65 -0
  14. package/src/components/access-control/acl-bootstrap.tsx +11 -3
  15. package/src/components/access-control/acl-gate.tsx +7 -6
  16. package/src/components/access-control/can-access.tsx +17 -0
  17. package/src/components/access-control/navigate-to-accessible-resource.tsx +8 -3
  18. package/src/components/app-shell/sidebar.tsx +21 -5
  19. package/src/components/auth/auto-redirect-provider.tsx +2 -1
  20. package/src/extensions/nocobase-acl/README.md +74 -0
  21. package/{registry → src/extensions}/nocobase-acl/components/acl-boundary.tsx +22 -25
  22. package/{registry → src/extensions}/nocobase-acl/components/role-switcher.tsx +26 -23
  23. package/src/extensions/nocobase-acl/demo/acl-preview-provider.tsx +81 -0
  24. package/{registry → src/extensions}/nocobase-acl/demo/boundary-api.tsx +58 -0
  25. package/{registry → src/extensions}/nocobase-acl/demo/index.tsx +243 -105
  26. package/{registry → src/extensions}/nocobase-acl/demo/prompt-generator.tsx +3 -1
  27. package/src/extensions/nocobase-acl/extension.tsx +73 -0
  28. package/{registry → src/extensions}/nocobase-ai/README.md +21 -5
  29. package/{registry → src/extensions}/nocobase-ai/components/chat/chat-composer.tsx +3 -1
  30. package/{registry → src/extensions}/nocobase-ai/components/chat/chat-messages.tsx +38 -3
  31. package/{registry → src/extensions}/nocobase-ai/components/chat/tool-call-card.tsx +1 -9
  32. package/{registry → src/extensions}/nocobase-ai/components/index.ts +5 -0
  33. package/src/extensions/nocobase-ai/components/surfaces/chat-dialog.tsx +17 -0
  34. package/src/extensions/nocobase-ai/components/surfaces/chat-side-panel.tsx +35 -0
  35. package/src/extensions/nocobase-ai/components/surfaces/chat-surface.tsx +108 -0
  36. package/{registry → src/extensions}/nocobase-ai/components/triggers/ai-chat-floating-trigger.tsx +2 -2
  37. package/{registry → src/extensions}/nocobase-ai/demo/configuration-gate.tsx +4 -1
  38. package/{registry → src/extensions}/nocobase-ai/demo/container-showcase.tsx +2 -2
  39. package/{registry → src/extensions}/nocobase-ai/demo/floating.tsx +45 -15
  40. package/{registry → src/extensions}/nocobase-ai/demo/index.tsx +116 -74
  41. package/{registry → src/extensions}/nocobase-ai/demo/prompt-generator.tsx +3 -3
  42. package/{registry → src/extensions}/nocobase-ai/demo/tool-cards.tsx +2 -3
  43. package/src/extensions/nocobase-ai/extension.tsx +160 -0
  44. package/{registry → src/extensions}/nocobase-ai/global-ai-chat.tsx +12 -28
  45. package/{registry → src/extensions}/nocobase-ai/providers/ai-provider.tsx +14 -1
  46. package/{registry → src/extensions}/nocobase-ai/providers/chat-context.tsx +1 -0
  47. package/{registry → src/extensions}/nocobase-ai/providers/chat-provider.tsx +29 -8
  48. package/{registry → src/extensions}/nocobase-ai/providers/use-chat-attachments.ts +6 -1
  49. package/{registry → src/extensions}/nocobase-ai/providers/use-chat-work-context.ts +4 -1
  50. package/{registry → src/extensions}/nocobase-route-surfaces/README.md +2 -1
  51. package/{registry → src/extensions}/nocobase-route-surfaces/demo/index.tsx +33 -7
  52. package/{registry → src/extensions}/nocobase-route-surfaces/demo/scenarios.ts +20 -14
  53. package/{registry → src/extensions}/nocobase-route-surfaces/extension.tsx +55 -52
  54. package/src/{pages/users → extensions/nocobase-users-example}/create.tsx +4 -4
  55. package/src/{pages/users → extensions/nocobase-users-example}/edit.tsx +5 -9
  56. package/src/extensions/nocobase-users-example/extension.tsx +109 -0
  57. package/src/{pages/users → extensions/nocobase-users-example}/form-context.ts +11 -9
  58. package/src/extensions/nocobase-users-example/layout.tsx +16 -0
  59. package/src/{pages/users → extensions/nocobase-users-example}/list.tsx +1 -1
  60. package/src/extensions/nocobase-users-example/locales/en-US.ts +77 -0
  61. package/src/extensions/nocobase-users-example/locales/index.ts +8 -0
  62. package/src/extensions/nocobase-users-example/locales/zh-CN.ts +73 -0
  63. package/src/extensions/nocobase-users-example/optional-ai.ts +67 -0
  64. package/src/{pages/users → extensions/nocobase-users-example}/role-detail.tsx +4 -15
  65. package/src/{pages/users → extensions/nocobase-users-example}/routes.ts +1 -4
  66. package/src/extensions/nocobase-users-example/show.tsx +266 -0
  67. package/src/lib/nocobase/acl/context.ts +32 -0
  68. package/src/lib/nocobase/acl/evaluator.ts +186 -0
  69. package/src/lib/nocobase/acl/hooks.ts +40 -0
  70. package/src/lib/nocobase/acl/index.ts +4 -1
  71. package/src/lib/nocobase/acl/menu.ts +6 -6
  72. package/src/lib/nocobase/acl/record-permissions.ts +37 -7
  73. package/src/lib/nocobase/acl/store-provider.tsx +14 -0
  74. package/src/lib/nocobase/acl/store.ts +92 -86
  75. package/src/lib/nocobase/acl/types.ts +52 -32
  76. package/src/lib/nocobase/auth-session.ts +128 -0
  77. package/src/lib/nocobase/client.ts +48 -50
  78. package/src/locales/en-US.ts +0 -78
  79. package/src/locales/index.ts +2 -7
  80. package/src/locales/zh-CN.ts +0 -74
  81. package/src/providers/access-control.ts +43 -8
  82. package/src/providers/auth-callback.ts +1 -0
  83. package/src/providers/auth.ts +24 -26
  84. package/src/providers/constants.ts +0 -4
  85. package/src/providers/data.ts +14 -26
  86. package/src/providers/runtime-config.ts +40 -0
  87. package/src/vite-env.d.ts +9 -0
  88. package/tests/auth-session-regression.mjs +101 -0
  89. package/tsconfig.json +2 -1
  90. package/vite.config.ts +9 -1
  91. package/dist/assets/CoordinateSystem-C8P-Cleg.js +0 -1
  92. package/dist/assets/LegendVisualProvider-Bdgkckq-.js +0 -1
  93. package/dist/assets/LineDraw-C0m1GONT.js +0 -1
  94. package/dist/assets/SymbolDraw-CCospe5G.js +0 -1
  95. package/dist/assets/VisualMapping-Cbv1v7Cd.js +0 -1
  96. package/dist/assets/ai-employee-shortcut-B253WWow.js +0 -1
  97. package/dist/assets/calendar-B3dXXyIv.js +0 -1
  98. package/dist/assets/chat-inline-xpQ9iq4p.js +0 -1
  99. package/dist/assets/chat-side-panel-layout-BVWsp5rr.js +0 -1
  100. package/dist/assets/components-ChhJaNRc.js +0 -20
  101. package/dist/assets/configuration-gate-Dwdq_lxf.js +0 -1
  102. package/dist/assets/createClipPathFromCoordSys-uEftn1Mq.js +0 -1
  103. package/dist/assets/createSeriesDataSimply-CI7l7Ufv.js +0 -1
  104. package/dist/assets/customGraphicKeyframeAnimation-DE3jSfMd.js +0 -3
  105. package/dist/assets/echarts-preview-C-cNUtJF.js +0 -1
  106. package/dist/assets/echarts-runtime-CEgJbv68.js +0 -58
  107. package/dist/assets/echarts-runtime-advanced-Buhm2BHz.js +0 -1
  108. package/dist/assets/echarts-runtime-common-DLAdBAIa.js +0 -1
  109. package/dist/assets/echarts-runtime-components-ypnyLkYx.js +0 -1
  110. package/dist/assets/echarts-runtime-hierarchy-ClStquCF.js +0 -1
  111. package/dist/assets/floating-BarTmn-b.js +0 -13
  112. package/dist/assets/index-BJIcYTdc.js +0 -53
  113. package/dist/assets/index-C6xNKxpg.js +0 -656
  114. package/dist/assets/index-D4JQi1TM.js +0 -54
  115. package/dist/assets/index-YA7-AUO8.css +0 -1
  116. package/dist/assets/index-g8zWVpP9.js +0 -23
  117. package/dist/assets/labelHelper-C137W5gU.js +0 -1
  118. package/dist/assets/nocobase-ai-chat-VTMaZFQB.svg +0 -50
  119. package/dist/assets/page-context-Cxx11gzg.js +0 -73
  120. package/dist/assets/prompt-card-BsYMW_rq.js +0 -1
  121. package/dist/assets/sectorHelper-Fqgz3uEk.js +0 -1
  122. package/dist/assets/shortcut-xtghDP63.js +0 -47
  123. package/dist/assets/static.browser-CfQQzERe.js +0 -30
  124. package/dist/assets/switch-DrxImI8F.js +0 -1
  125. package/dist/assets/tool-cards-BGfsY8JF.js +0 -41
  126. package/dist/favicon.ico +0 -0
  127. package/dist/index.html +0 -40
  128. package/dist/index.raw.html +0 -46
  129. package/dist/logo-dark.png +0 -0
  130. package/dist/logo-mark-dark.png +0 -0
  131. package/dist/logo-mark.png +0 -0
  132. package/dist/logo.png +0 -0
  133. package/registry/nocobase-acl/README.md +0 -19
  134. package/registry/nocobase-acl/extension.tsx +0 -71
  135. package/registry/nocobase-acl/tests/acl-regression.mjs +0 -314
  136. package/registry/nocobase-ai/components/surfaces/chat-dialog.tsx +0 -31
  137. package/registry/nocobase-ai/components/surfaces/chat-side-panel.tsx +0 -74
  138. package/registry/nocobase-ai/extension.tsx +0 -158
  139. package/registry/nocobase-ai/tests/business-report-regression.mjs +0 -70
  140. package/registry/nocobase-ai/tests/form-filler-regression.mjs +0 -129
  141. package/registry/nocobase-ai/tests/frontend-tool-regression.mjs +0 -128
  142. package/registry/nocobase-ai/tests/page-context-regression.mjs +0 -48
  143. package/registry/nocobase-ai/tests/stream-regression.mjs +0 -207
  144. package/registry/nocobase-auth-cas/README.md +0 -6
  145. package/registry/nocobase-auth-cas/cas-sign-in-button.tsx +0 -41
  146. package/registry/nocobase-auth-cas/demo.tsx +0 -20
  147. package/registry/nocobase-auth-cas/extension.tsx +0 -46
  148. package/registry/nocobase-auth-cas/index.ts +0 -1
  149. package/registry/nocobase-auth-cas/use-cas-sign-in.ts +0 -29
  150. package/registry/nocobase-auth-dingtalk/README.md +0 -7
  151. package/registry/nocobase-auth-dingtalk/auto-login-provider.tsx +0 -154
  152. package/registry/nocobase-auth-dingtalk/demo.tsx +0 -23
  153. package/registry/nocobase-auth-dingtalk/dingtalk-sign-in-button.tsx +0 -45
  154. package/registry/nocobase-auth-dingtalk/extension.tsx +0 -55
  155. package/registry/nocobase-auth-dingtalk/index.ts +0 -4
  156. package/registry/nocobase-auth-dingtalk/use-dingtalk-sign-in.ts +0 -64
  157. package/registry/nocobase-auth-ldap/README.md +0 -6
  158. package/registry/nocobase-auth-ldap/demo.tsx +0 -21
  159. package/registry/nocobase-auth-ldap/extension.tsx +0 -46
  160. package/registry/nocobase-auth-ldap/index.ts +0 -1
  161. package/registry/nocobase-auth-ldap/ldap-sign-in-form.tsx +0 -69
  162. package/registry/nocobase-auth-ldap/use-ldap-sign-in.ts +0 -5
  163. package/registry/nocobase-auth-oidc/README.md +0 -11
  164. package/registry/nocobase-auth-oidc/auto-redirect-provider.tsx +0 -13
  165. package/registry/nocobase-auth-oidc/demo.tsx +0 -20
  166. package/registry/nocobase-auth-oidc/extension.tsx +0 -51
  167. package/registry/nocobase-auth-oidc/index.ts +0 -1
  168. package/registry/nocobase-auth-oidc/oidc-sign-in-button.tsx +0 -44
  169. package/registry/nocobase-auth-oidc/use-oidc-sign-in.ts +0 -58
  170. package/registry/nocobase-auth-saml/README.md +0 -6
  171. package/registry/nocobase-auth-saml/auto-redirect-provider.tsx +0 -13
  172. package/registry/nocobase-auth-saml/demo.tsx +0 -20
  173. package/registry/nocobase-auth-saml/extension.tsx +0 -51
  174. package/registry/nocobase-auth-saml/index.ts +0 -1
  175. package/registry/nocobase-auth-saml/saml-sign-in-button.tsx +0 -43
  176. package/registry/nocobase-auth-saml/use-saml-sign-in.ts +0 -51
  177. package/registry/nocobase-auth-sms/README.md +0 -7
  178. package/registry/nocobase-auth-sms/demo.tsx +0 -25
  179. package/registry/nocobase-auth-sms/extension.tsx +0 -46
  180. package/registry/nocobase-auth-sms/index.ts +0 -1
  181. package/registry/nocobase-auth-sms/sms-sign-in-form.tsx +0 -107
  182. package/registry/nocobase-auth-sms/use-sms-sign-in.ts +0 -88
  183. package/registry/nocobase-auth-wecom/README.md +0 -6
  184. package/registry/nocobase-auth-wecom/auto-login-provider.tsx +0 -21
  185. package/registry/nocobase-auth-wecom/demo.tsx +0 -23
  186. package/registry/nocobase-auth-wecom/extension.tsx +0 -49
  187. package/registry/nocobase-auth-wecom/index.ts +0 -1
  188. package/registry/nocobase-auth-wecom/use-wecom-sign-in.ts +0 -62
  189. package/registry/nocobase-auth-wecom/wecom-sign-in-button.tsx +0 -70
  190. package/registry/nocobase-i18n/README.md +0 -44
  191. package/registry/nocobase-i18n/components/index.ts +0 -1
  192. package/registry/nocobase-i18n/components/language-switcher.tsx +0 -138
  193. package/registry/nocobase-i18n/demo/index.tsx +0 -209
  194. package/registry/nocobase-i18n/demo/prompt-generator.tsx +0 -132
  195. package/registry/nocobase-i18n/extension.tsx +0 -45
  196. package/registry/nocobase-i18n/index.ts +0 -7
  197. package/registry/nocobase-i18n/locales/en-US.ts +0 -39
  198. package/registry/nocobase-i18n/locales/index.ts +0 -8
  199. package/registry/nocobase-i18n/locales/zh-CN.ts +0 -35
  200. package/registry/nocobase-i18n/provider.tsx +0 -44
  201. package/registry/nocobase-i18n/server-resources.ts +0 -166
  202. package/registry/nocobase-i18n/tests/i18n-regression.mjs +0 -51
  203. package/registry.config.json +0 -302
  204. package/scripts/registry.mjs +0 -164
  205. package/src/components/access-control/resource-access-guard.tsx +0 -21
  206. package/src/components/access-control/use-acl-runtime.ts +0 -28
  207. package/src/lib/nocobase/acl/action.ts +0 -147
  208. package/src/pages/users/layout.tsx +0 -15
  209. package/src/pages/users/show.tsx +0 -278
  210. /package/{registry → src/extensions}/nocobase-acl/components/index.ts +0 -0
  211. /package/{registry → src/extensions}/nocobase-acl/components/role-options.ts +0 -0
  212. /package/{registry → src/extensions}/nocobase-acl/demo/components.tsx +0 -0
  213. /package/{registry → src/extensions}/nocobase-acl/demo/lazy-route.tsx +0 -0
  214. /package/{registry → src/extensions}/nocobase-acl/demo/role-switcher-prompt-generator.tsx +0 -0
  215. /package/{registry → src/extensions}/nocobase-acl/demo/scenario-section.tsx +0 -0
  216. /package/{registry → src/extensions}/nocobase-acl/index.ts +0 -0
  217. /package/{registry → src/extensions}/nocobase-ai/adapters/react-hook-form.ts +0 -0
  218. /package/{registry → src/extensions}/nocobase-ai/assets/nocobase-ai-chat.svg +0 -0
  219. /package/{registry → src/extensions}/nocobase-ai/components/ai-root-provider.tsx +0 -0
  220. /package/{registry → src/extensions}/nocobase-ai/components/chat/ai-employee-avatar.tsx +0 -0
  221. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-attachment.tsx +0 -0
  222. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-compact.tsx +0 -0
  223. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-empty-state.tsx +0 -0
  224. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-header.tsx +0 -0
  225. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-history-dialog.tsx +0 -0
  226. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-message.tsx +0 -0
  227. /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-window.tsx +0 -0
  228. /package/{registry → src/extensions}/nocobase-ai/components/chat/conversation-list.tsx +0 -0
  229. /package/{registry → src/extensions}/nocobase-ai/components/chat/markdown-message.tsx +0 -0
  230. /package/{registry → src/extensions}/nocobase-ai/components/chat/model-select-options.tsx +0 -0
  231. /package/{registry → src/extensions}/nocobase-ai/components/chat/reasoning-panel.tsx +0 -0
  232. /package/{registry → src/extensions}/nocobase-ai/components/chat/sub-agent-conversation.tsx +0 -0
  233. /package/{registry → src/extensions}/nocobase-ai/components/chat/user-prompt-editor.tsx +0 -0
  234. /package/{registry → src/extensions}/nocobase-ai/components/chat/work-context-chip.tsx +0 -0
  235. /package/{registry → src/extensions}/nocobase-ai/components/page-elements/ai-form.tsx +0 -0
  236. /package/{registry → src/extensions}/nocobase-ai/components/page-elements/page-element-provider.tsx +0 -0
  237. /package/{registry → src/extensions}/nocobase-ai/components/surfaces/chat-inline.tsx +0 -0
  238. /package/{registry → src/extensions}/nocobase-ai/components/surfaces/chat-page.tsx +0 -0
  239. /package/{registry → src/extensions}/nocobase-ai/components/surfaces/chat-side-panel-layout.tsx +0 -0
  240. /package/{registry → src/extensions}/nocobase-ai/components/surfaces/chat-surface-actions.tsx +0 -0
  241. /package/{registry → src/extensions}/nocobase-ai/components/tools/builtin-tool-renderers.tsx +0 -0
  242. /package/{registry → src/extensions}/nocobase-ai/components/tools/business-report-dialog.tsx +0 -0
  243. /package/{registry → src/extensions}/nocobase-ai/components/tools/business-report-renderer.tsx +0 -0
  244. /package/{registry → src/extensions}/nocobase-ai/components/tools/business-report-utils.tsx +0 -0
  245. /package/{registry → src/extensions}/nocobase-ai/components/tools/chart-renderer.tsx +0 -0
  246. /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-preview.tsx +0 -0
  247. /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime-advanced.ts +0 -0
  248. /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime-common.ts +0 -0
  249. /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime-components.ts +0 -0
  250. /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime-hierarchy.ts +0 -0
  251. /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime.ts +0 -0
  252. /package/{registry → src/extensions}/nocobase-ai/components/tools/sub-agent-renderer.tsx +0 -0
  253. /package/{registry → src/extensions}/nocobase-ai/components/tools/suggestions-renderer.tsx +0 -0
  254. /package/{registry → src/extensions}/nocobase-ai/components/tools/tool-renderer-provider.tsx +0 -0
  255. /package/{registry → src/extensions}/nocobase-ai/components/tools/tool-renderer-utils.ts +0 -0
  256. /package/{registry → src/extensions}/nocobase-ai/components/tools/workflow-renderer.tsx +0 -0
  257. /package/{registry → src/extensions}/nocobase-ai/components/triggers/ai-employee-shortcut.tsx +0 -0
  258. /package/{registry → src/extensions}/nocobase-ai/demo/interaction-showcase.tsx +0 -0
  259. /package/{registry → src/extensions}/nocobase-ai/demo/page-context-prompt-generator.tsx +0 -0
  260. /package/{registry → src/extensions}/nocobase-ai/demo/page-context.tsx +0 -0
  261. /package/{registry → src/extensions}/nocobase-ai/demo/page-element-showcase.tsx +0 -0
  262. /package/{registry → src/extensions}/nocobase-ai/demo/prompt-card.tsx +0 -0
  263. /package/{registry → src/extensions}/nocobase-ai/demo/shortcut.tsx +0 -0
  264. /package/{registry → src/extensions}/nocobase-ai/index.ts +0 -0
  265. /package/{registry → src/extensions}/nocobase-ai/providers/avatars.ts +0 -0
  266. /package/{registry → src/extensions}/nocobase-ai/providers/chat-controller.ts +0 -0
  267. /package/{registry → src/extensions}/nocobase-ai/providers/chat-message-utils.ts +0 -0
  268. /package/{registry → src/extensions}/nocobase-ai/providers/chat-reducer.ts +0 -0
  269. /package/{registry → src/extensions}/nocobase-ai/providers/chat-task-utils.ts +0 -0
  270. /package/{registry → src/extensions}/nocobase-ai/providers/chat-transport.ts +0 -0
  271. /package/{registry → src/extensions}/nocobase-ai/providers/form-registry.tsx +0 -0
  272. /package/{registry → src/extensions}/nocobase-ai/providers/frontend-tool-registry.tsx +0 -0
  273. /package/{registry → src/extensions}/nocobase-ai/providers/index.ts +0 -0
  274. /package/{registry → src/extensions}/nocobase-ai/providers/model.ts +0 -0
  275. /package/{registry → src/extensions}/nocobase-ai/providers/page-context.tsx +0 -0
  276. /package/{registry → src/extensions}/nocobase-ai/providers/stream-coalescer.ts +0 -0
  277. /package/{registry → src/extensions}/nocobase-ai/providers/stream-event-utils.ts +0 -0
  278. /package/{registry → src/extensions}/nocobase-ai/providers/stream-parser.ts +0 -0
  279. /package/{registry → src/extensions}/nocobase-ai/providers/sub-agent-stream.ts +0 -0
  280. /package/{registry → src/extensions}/nocobase-ai/providers/types.ts +0 -0
  281. /package/{registry → src/extensions}/nocobase-ai/providers/ui-message-stream.ts +0 -0
  282. /package/{registry → src/extensions}/nocobase-ai/providers/use-automatic-tool-approval.ts +0 -0
  283. /package/{registry → src/extensions}/nocobase-ai/providers/use-chat-message-actions.ts +0 -0
  284. /package/{registry → src/extensions}/nocobase-ai/providers/use-chat-runtime.ts +0 -0
  285. /package/{registry → src/extensions}/nocobase-ai/providers/use-conversation-catalog.ts +0 -0
  286. /package/{registry → src/extensions}/nocobase-ai/providers/use-conversation-history.ts +0 -0
  287. /package/{registry → src/extensions}/nocobase-ai/services/index.ts +0 -0
  288. /package/{registry → src/extensions}/nocobase-ai/services/nocobase-ai-service.ts +0 -0
  289. /package/{registry → src/extensions}/nocobase-ai/services/types.ts +0 -0
  290. /package/{registry → src/extensions}/nocobase-route-surfaces/demo/lazy-route.tsx +0 -0
  291. /package/{registry → src/extensions}/nocobase-route-surfaces/demo/prompt-generator.tsx +0 -0
  292. /package/{registry → src/extensions}/nocobase-route-surfaces/index.ts +0 -0
  293. /package/{registry → src/extensions}/nocobase-route-surfaces/route-dialog.tsx +0 -0
  294. /package/{registry → src/extensions}/nocobase-route-surfaces/route-drawer.tsx +0 -0
  295. /package/{registry → src/extensions}/nocobase-route-surfaces/route-page.tsx +0 -0
  296. /package/{registry → src/extensions}/nocobase-route-surfaces/route-surface-context.ts +0 -0
  297. /package/{registry → src/extensions}/nocobase-route-surfaces/use-refine-unsaved-changes.tsx +0 -0
  298. /package/{registry → src/extensions}/nocobase-route-surfaces/use-route-surface-close.ts +0 -0
  299. /package/{registry → src/extensions}/nocobase-route-surfaces/use-route-surface-state.ts +0 -0
  300. /package/src/{pages/users → extensions/nocobase-users-example}/form-fields.tsx +0 -0
  301. /package/src/{pages/users → extensions/nocobase-users-example}/index.ts +0 -0
  302. /package/src/{pages/users → extensions/nocobase-users-example}/role-badges.tsx +0 -0
  303. /package/src/{pages/users → extensions/nocobase-users-example}/role-utils.ts +0 -0
  304. /package/src/{pages/users → extensions/nocobase-users-example}/types.ts +0 -0
@@ -1,129 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { createServer } from "vite";
3
-
4
- const server = await createServer({
5
- appType: "custom",
6
- logLevel: "silent",
7
- server: { middlewareMode: true },
8
- });
9
-
10
- try {
11
- const { AIFormRegistry, createFormFillerInvoker } =
12
- await server.ssrLoadModule(
13
- "/registry/nocobase-ai/providers/form-registry.tsx"
14
- );
15
-
16
- const registry = new AIFormRegistry();
17
- const applied = [];
18
- const unregister = registry.register({
19
- id: "lead-form",
20
- title: "Lead form",
21
- fields: [
22
- { name: "company", type: "string" },
23
- {
24
- name: "priority",
25
- type: "string",
26
- enum: ["normal", "high"],
27
- },
28
- { name: "owner", type: "string", readonly: true },
29
- ],
30
- getValues: () => ({}),
31
- setValues: (values) => applied.push(values),
32
- });
33
- const invoke = createFormFillerInvoker(registry);
34
-
35
- const allowedContext = { allowedFormIds: ["lead-form"] };
36
- assert.deepEqual(
37
- await invoke(
38
- {
39
- form: "lead-form",
40
- data: { company: "Acme", priority: "high" },
41
- },
42
- allowedContext
43
- ),
44
- {
45
- status: "success",
46
- content:
47
- 'Filled "Lead form". Please review the values and submit the form manually.',
48
- appliedFields: ["company", "priority"],
49
- skippedFields: [],
50
- }
51
- );
52
- assert.deepEqual(applied, [{ company: "Acme", priority: "high" }]);
53
-
54
- assert.deepEqual(
55
- await invoke(
56
- {
57
- form: "lead-form",
58
- data: { company: 42, owner: "Ada", unknown: true },
59
- },
60
- allowedContext
61
- ),
62
- {
63
- status: "error",
64
- content: 'No valid editable fields were provided for "Lead form".',
65
- appliedFields: [],
66
- skippedFields: [
67
- {
68
- name: "company",
69
- reason: "invalid",
70
- message: "Expected a string.",
71
- },
72
- {
73
- name: "owner",
74
- reason: "readonly",
75
- message: "This field is read-only.",
76
- },
77
- {
78
- name: "unknown",
79
- reason: "undeclared",
80
- message: "This field is not declared by the target form.",
81
- },
82
- ],
83
- }
84
- );
85
-
86
- assert.throws(
87
- () =>
88
- registry.register({
89
- id: "lead-form",
90
- title: "Duplicate lead form",
91
- fields: [],
92
- getValues: () => ({}),
93
- setValues: () => undefined,
94
- }),
95
- /already registered/
96
- );
97
-
98
- unregister();
99
- assert.deepEqual(
100
- await invoke(
101
- { form: "lead-form", data: { company: "Acme" } },
102
- allowedContext
103
- ),
104
- {
105
- status: "error",
106
- content: 'The target form "lead-form" is not available on this page.',
107
- appliedFields: [],
108
- skippedFields: [],
109
- }
110
- );
111
-
112
- assert.deepEqual(
113
- await invoke(
114
- { form: "lead-form", data: { company: "Acme" } },
115
- { allowedFormIds: [] }
116
- ),
117
- {
118
- status: "error",
119
- content:
120
- 'The target form "lead-form" is not available in this conversation context.',
121
- appliedFields: [],
122
- skippedFields: [],
123
- }
124
- );
125
-
126
- console.log("AI Form filler regression tests passed");
127
- } finally {
128
- await server.close();
129
- }
@@ -1,128 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { createServer } from "vite";
3
-
4
- const server = await createServer({
5
- appType: "custom",
6
- logLevel: "silent",
7
- server: { middlewareMode: true },
8
- });
9
-
10
- try {
11
- const { AIFrontendToolRegistry, createFrontendToolInvokers } =
12
- await server.ssrLoadModule(
13
- "/registry/nocobase-ai/providers/frontend-tool-registry.tsx"
14
- );
15
-
16
- const registry = new AIFrontendToolRegistry();
17
- const calls = [];
18
- const unregister = registry.register("quote-card", {
19
- name: "update_quote_discount",
20
- description: "Update the quote discount preview.",
21
- permission: "ASK",
22
- inputSchema: {
23
- type: "object",
24
- properties: { discountPercent: { type: "number" } },
25
- },
26
- execute: (args) => {
27
- calls.push(args);
28
- return { updated: true };
29
- },
30
- });
31
- const [manifest] = registry.list("quote-card");
32
- assert.deepEqual(manifest, {
33
- id: "quote-card:update_quote_discount",
34
- blockUid: "quote-card",
35
- name: "update_quote_discount",
36
- title: undefined,
37
- description: "Update the quote discount preview.",
38
- permission: "ASK",
39
- inputSchema: {
40
- type: "object",
41
- properties: { discountPercent: { type: "number" } },
42
- },
43
- });
44
-
45
- const invokers = createFrontendToolInvokers(registry);
46
- const allowedContext = { allowedFrontendToolIds: [manifest.id] };
47
- assert.deepEqual(
48
- await invokers.loadFrontendTool({ toolId: manifest.id }, allowedContext),
49
- manifest
50
- );
51
- assert.deepEqual(
52
- await invokers.executeFrontendTool(
53
- { toolId: manifest.id, args: { discountPercent: 12 } },
54
- allowedContext
55
- ),
56
- { updated: true }
57
- );
58
- assert.deepEqual(calls, [{ discountPercent: 12 }]);
59
-
60
- assert.throws(
61
- () =>
62
- registry.register("quote-card", {
63
- name: "update_quote_discount",
64
- description: "Duplicate Tool",
65
- execute: () => undefined,
66
- }),
67
- /already registered/
68
- );
69
- assert.throws(
70
- () =>
71
- registry.register("quote-card", {
72
- name: "invalid_schema",
73
- description: "Invalid schema",
74
- inputSchema: [],
75
- execute: () => undefined,
76
- }),
77
- /inputSchema must be an object/
78
- );
79
-
80
- const unregisterInvalidResult = registry.register("quote-card", {
81
- name: "invalid_result",
82
- description: "Return an invalid result.",
83
- execute: () => ({ value: 1n }),
84
- });
85
- assert.deepEqual(
86
- await invokers.executeFrontendTool(
87
- { toolId: "quote-card:invalid_result", args: {} },
88
- {
89
- allowedFrontendToolIds: ["quote-card:invalid_result"],
90
- }
91
- ),
92
- {
93
- status: "error",
94
- content:
95
- 'Frontend Tool "quote-card:invalid_result" returned a non-serializable result',
96
- }
97
- );
98
- unregisterInvalidResult();
99
-
100
- unregister();
101
- assert.deepEqual(
102
- await invokers.executeFrontendTool(
103
- { toolId: manifest.id, args: {} },
104
- allowedContext
105
- ),
106
- {
107
- status: "error",
108
- content:
109
- 'Frontend Tool "quote-card:update_quote_discount" is unavailable',
110
- }
111
- );
112
-
113
- assert.deepEqual(
114
- await invokers.executeFrontendTool(
115
- { toolId: manifest.id, args: {} },
116
- { allowedFrontendToolIds: [] }
117
- ),
118
- {
119
- status: "error",
120
- content:
121
- 'Frontend Tool "quote-card:update_quote_discount" is not available in this conversation context',
122
- }
123
- );
124
-
125
- console.log("AI frontend Tool regression tests passed");
126
- } finally {
127
- await server.close();
128
- }
@@ -1,48 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { createServer } from "vite";
3
-
4
- const server = await createServer({
5
- appType: "custom",
6
- logLevel: "silent",
7
- server: { middlewareMode: true },
8
- });
9
-
10
- try {
11
- const {
12
- createAIPageContextReference,
13
- getAIWorkContextRequiredTools,
14
- mergeAIRequiredTools,
15
- } = await server.ssrLoadModule(
16
- "/registry/nocobase-ai/providers/page-context.tsx"
17
- );
18
-
19
- const formContext = createAIPageContextReference({
20
- id: "lead-form",
21
- title: "Lead form",
22
- kind: "form",
23
- });
24
- assert.deepEqual(formContext, {
25
- type: "page-element",
26
- id: "lead-form",
27
- title: "Lead form",
28
- kind: "form",
29
- });
30
- assert.deepEqual(getAIWorkContextRequiredTools([formContext]), [
31
- "formFiller",
32
- ]);
33
- assert.deepEqual(
34
- mergeAIRequiredTools(
35
- { skills: ["lead-review"], tools: ["inspect-record"] },
36
- ["formFiller", "inspect-record"]
37
- ),
38
- {
39
- skills: ["lead-review"],
40
- tools: ["inspect-record", "formFiller"],
41
- }
42
- );
43
- assert.equal(mergeAIRequiredTools(undefined, []), undefined);
44
-
45
- console.log("AI page context regression tests passed");
46
- } finally {
47
- await server.close();
48
- }
@@ -1,207 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { createServer } from "vite";
3
-
4
- const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5
-
6
- const encodeSSE = (events) => {
7
- const encoder = new TextEncoder();
8
- return new ReadableStream({
9
- start(controller) {
10
- controller.enqueue(
11
- encoder.encode(
12
- events.map((event) => `data: ${JSON.stringify(event)}\n\n`).join("")
13
- )
14
- );
15
- controller.close();
16
- },
17
- });
18
- };
19
-
20
- const collectStream = async (stream) => {
21
- const result = [];
22
- for await (const chunk of stream) result.push(chunk);
23
- return result;
24
- };
25
-
26
- const server = await createServer({
27
- appType: "custom",
28
- logLevel: "silent",
29
- server: { middlewareMode: true },
30
- });
31
-
32
- try {
33
- const { StreamCoalescer } = await server.ssrLoadModule(
34
- "/registry/nocobase-ai/providers/stream-coalescer.ts"
35
- );
36
- const { NocoBaseChatTransport } = await server.ssrLoadModule(
37
- "/registry/nocobase-ai/providers/chat-transport.ts"
38
- );
39
- const { SubAgentStreamAccumulator } = await server.ssrLoadModule(
40
- "/registry/nocobase-ai/providers/sub-agent-stream.ts"
41
- );
42
- const { NocoBaseClient } = await server.ssrLoadModule(
43
- "/src/lib/nocobase/client.ts"
44
- );
45
-
46
- {
47
- const client = new NocoBaseClient("http://localhost:13001/api");
48
- assert.equal(
49
- client.resolveUrl("/files/main/main/aiFiles/5.png?preview=1"),
50
- "http://localhost:13001/files/main/main/aiFiles/5.png?preview=1"
51
- );
52
- assert.equal(
53
- client.resolveUrl("https://cdn.example.com/file.png"),
54
- "https://cdn.example.com/file.png"
55
- );
56
- }
57
-
58
- {
59
- const flushed = [];
60
- const coalescer = new StreamCoalescer({
61
- interval: 20,
62
- maxSize: 100,
63
- getSize: (value) => value.length,
64
- merge: (current, incoming) => current + incoming,
65
- onFlush: (key, value) => flushed.push([key, value]),
66
- });
67
- coalescer.push("message", "hello ");
68
- coalescer.push("message", "world");
69
- await wait(35);
70
- assert.deepEqual(flushed, [["message", "hello world"]]);
71
- }
72
-
73
- {
74
- const seedMessage = {
75
- id: "assistant-existing",
76
- role: "assistant",
77
- parts: [
78
- {
79
- type: "data-subAgent",
80
- id: "sub-1",
81
- data: {
82
- sessionId: "sub-1",
83
- username: "viz",
84
- status: "pending",
85
- messages: [
86
- {
87
- id: "sub-message",
88
- role: "assistant",
89
- parts: [{ type: "text", text: "saved ", state: "done" }],
90
- },
91
- ],
92
- },
93
- },
94
- ],
95
- };
96
- const accumulator = new SubAgentStreamAccumulator(seedMessage);
97
- const [chunk] = accumulator.process({
98
- type: "content",
99
- body: "tail",
100
- from: "sub-agent",
101
- sessionId: "sub-1",
102
- username: "viz",
103
- });
104
- assert.equal(chunk.data.messages.length, 1);
105
- assert.equal(chunk.data.messages[0].parts[0].text, "saved tail");
106
- }
107
-
108
- {
109
- const toolCallId = "report-tool";
110
- const events = [
111
- ...Array.from({ length: 100 }, (_, index) => ({
112
- type: "tool_call_chunks",
113
- from: "main-agent",
114
- sessionId: "conversation-1",
115
- body: [
116
- index === 0
117
- ? {
118
- id: toolCallId,
119
- name: "businessReportGenerator",
120
- args: "{",
121
- }
122
- : { id: toolCallId, args: "x" },
123
- ],
124
- })),
125
- { type: "stream_end", from: "main-agent", sessionId: "conversation-1" },
126
- ];
127
- const service = {
128
- resumeConversationStream: async () => encodeSSE(events),
129
- };
130
- const transport = new NocoBaseChatTransport({
131
- service,
132
- getContext: () => ({
133
- sessionId: "conversation-1",
134
- employee: { username: "atlas", nickname: "Atlas" },
135
- model: { value: "test", label: "Test" },
136
- }),
137
- });
138
- transport.prepareConversationResume([
139
- { id: "assistant-existing", role: "assistant", parts: [] },
140
- ]);
141
- const chunks = await collectStream(await transport.reconnectToStream());
142
- const start = chunks.find((chunk) => chunk.type === "start");
143
- const toolDeltas = chunks.filter(
144
- (chunk) => chunk.type === "tool-input-delta"
145
- );
146
- assert.equal(start.messageId, undefined);
147
- assert.ok(toolDeltas.length < 10, `received ${toolDeltas.length} deltas`);
148
- assert.equal(
149
- toolDeltas.reduce((size, chunk) => size + chunk.inputTextDelta.length, 0),
150
- 100
151
- );
152
- }
153
-
154
- {
155
- let request;
156
- const service = {
157
- sendMessagesStream: async (input) => {
158
- request = input;
159
- return encodeSSE([
160
- { type: "content", body: "ok", from: "main-agent" },
161
- { type: "stream_end", from: "main-agent" },
162
- ]);
163
- },
164
- };
165
- const transport = new NocoBaseChatTransport({
166
- service,
167
- getContext: () => ({
168
- sessionId: "conversation-context",
169
- employee: { username: "mira", nickname: "Mira" },
170
- model: { value: "test", label: "Test" },
171
- }),
172
- });
173
- await collectStream(
174
- await transport.sendMessages({
175
- messages: [
176
- {
177
- id: "user-context",
178
- role: "user",
179
- metadata: {
180
- workContext: [
181
- {
182
- type: "page-element",
183
- id: "customer-form",
184
- title: "Customer form",
185
- content: { values: { name: "Northwind" } },
186
- },
187
- ],
188
- },
189
- parts: [{ type: "text", text: "Review this form" }],
190
- },
191
- ],
192
- })
193
- );
194
- assert.deepEqual(request.messages[0].workContext, [
195
- {
196
- type: "page-element",
197
- id: "customer-form",
198
- title: "Customer form",
199
- content: { values: { name: "Northwind" } },
200
- },
201
- ]);
202
- }
203
-
204
- console.log("AI stream regression tests passed");
205
- } finally {
206
- await server.close();
207
- }
@@ -1,6 +0,0 @@
1
- # NocoBase CAS authentication
2
-
3
- Adds the CAS sign-in button, callback error handling, and `useCasSignIn` for
4
- application-owned login UI.
5
-
6
- Installing the Registry also adds a CAS component Demo under Authentication.
@@ -1,41 +0,0 @@
1
- import { LogIn } from "lucide-react";
2
-
3
- import type { AuthenticatorComponentProps } from "@/components/auth/types";
4
- import {
5
- Alert,
6
- AlertDescription,
7
- AlertTitle,
8
- } from "@/components/ui/alert";
9
- import { Button } from "@/components/ui/button";
10
- import { resolveTranslatableText } from "@/lib/i18n";
11
-
12
- import { useCasSignIn } from "./use-cas-sign-in";
13
-
14
- export default function CasSignInButton({
15
- authenticator,
16
- onSignIn,
17
- }: AuthenticatorComponentProps & { onSignIn?: () => void }) {
18
- const { signIn, error } = useCasSignIn(authenticator);
19
-
20
- return (
21
- <div className="space-y-3">
22
- {error && (
23
- <Alert variant="destructive">
24
- <AlertTitle>CAS sign-in failed</AlertTitle>
25
- <AlertDescription>{error.message}</AlertDescription>
26
- </Alert>
27
- )}
28
- <Button
29
- type="button"
30
- variant="outline"
31
- className="w-full"
32
- onClick={onSignIn ?? signIn}
33
- >
34
- <LogIn />
35
- {resolveTranslatableText(
36
- authenticator.title || authenticator.authTypeTitle || "CAS"
37
- )}
38
- </Button>
39
- </div>
40
- );
41
- }
@@ -1,20 +0,0 @@
1
- import { AuthMethodDemo } from "@/components/auth/demo";
2
- import CasSignInButton from "./cas-sign-in-button";
3
-
4
- const authenticator = {
5
- name: "company-cas",
6
- authType: "CAS",
7
- title: "Company CAS",
8
- };
9
-
10
- export function CasAuthDemoPage() {
11
- return (
12
- <AuthMethodDemo
13
- authType="CAS"
14
- methodName="Central Authentication Service"
15
- description="Redirect users to a CAS server and capture the returned NocoBase token without coupling the page UI to CAS."
16
- >
17
- <CasSignInButton authenticator={authenticator} onSignIn={() => {}} />
18
- </AuthMethodDemo>
19
- );
20
- }
@@ -1,46 +0,0 @@
1
- import { lazy } from "react";
2
- import { KeyRound } from "lucide-react";
3
- import { Route } from "react-router";
4
-
5
- import type { AppExtension } from "@/app/extension";
6
- import { AuthDemoRoute } from "@/components/auth/demo";
7
-
8
- const CasSignInButton = lazy(() => import("./cas-sign-in-button"));
9
- const CasAuthDemoPage = lazy(() =>
10
- import("./demo").then((module) => ({ default: module.CasAuthDemoPage }))
11
- );
12
-
13
- const casAuthExtension: AppExtension = {
14
- id: "nocobase-auth-cas",
15
- resources: [
16
- {
17
- name: "auth-cas-demo",
18
- list: "/auth/cas",
19
- meta: {
20
- parent: "auth-components",
21
- label: "CAS",
22
- icon: <KeyRound />,
23
- acl: { type: "authenticated" },
24
- },
25
- },
26
- ],
27
- routes: (
28
- <Route
29
- path="/auth/cas"
30
- element={
31
- <AuthDemoRoute>
32
- <CasAuthDemoPage />
33
- </AuthDemoRoute>
34
- }
35
- />
36
- ),
37
- authAdapters: [
38
- {
39
- authType: "CAS",
40
- placement: "button",
41
- Component: CasSignInButton,
42
- },
43
- ],
44
- };
45
-
46
- export default casAuthExtension;
@@ -1 +0,0 @@
1
- export { useCasSignIn } from "./use-cas-sign-in";
@@ -1,29 +0,0 @@
1
- import { useCallback, useMemo } from "react";
2
- import { useSearchParams } from "react-router";
3
-
4
- import type { Authenticator } from "@/components/auth/types";
5
- import { nocobaseClient } from "@/lib/nocobase/client";
6
-
7
- export function useCasSignIn(authenticator: Authenticator) {
8
- const [searchParams] = useSearchParams();
9
- const callbackError = useMemo(() => {
10
- if (searchParams.get("authenticator") !== authenticator.name) {
11
- return undefined;
12
- }
13
- const message = searchParams.get("error");
14
- return message ? new Error(message) : undefined;
15
- }, [authenticator.name, searchParams]);
16
-
17
- const signIn = useCallback(() => {
18
- const redirect =
19
- searchParams.get("to") || searchParams.get("redirect") || "/";
20
- const url = nocobaseClient.buildUrl("cas:login", {
21
- authenticator: authenticator.name,
22
- __appName: "main",
23
- redirect,
24
- });
25
- window.location.replace(url.toString());
26
- }, [authenticator.name, searchParams]);
27
-
28
- return { signIn, error: callbackError };
29
- }
@@ -1,7 +0,0 @@
1
- # NocoBase DingTalk authentication
2
-
3
- Adds DingTalk OAuth sign-in, callback errors, OAuth or micro-app automatic
4
- login, and `useDingtalkSignIn` for custom UI. The DingTalk JSAPI is loaded only
5
- inside a DingTalk browser during internal automatic login.
6
-
7
- Installing the Registry also adds a DingTalk component Demo under Authentication.