create-react-admin-template 0.0.0-stage → 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 (736) hide show
  1. package/README.md +46 -2
  2. package/bin/create.mjs +5 -0
  3. package/package.json +22 -4
  4. package/template/.dockerignore +12 -0
  5. package/template/.editorconfig +12 -0
  6. package/template/.env +14 -0
  7. package/template/.env.development +5 -0
  8. package/template/.env.production +2 -0
  9. package/template/.env.test +5 -0
  10. package/template/.github/workflows/ci.yml +40 -0
  11. package/template/.gitlab-ci.yml +208 -0
  12. package/template/.husky/commit-msg +1 -0
  13. package/template/.husky/pre-commit +1 -0
  14. package/template/.nvmrc +1 -0
  15. package/template/.prettierignore +11 -0
  16. package/template/.prettierrc +47 -0
  17. package/template/Dockerfile +16 -0
  18. package/template/README.md +372 -0
  19. package/template/build/advancedTable.ts +103 -0
  20. package/template/build/environment.ts +150 -0
  21. package/template/commitlint.config.js +32 -0
  22. package/template/components.json +21 -0
  23. package/template/deploy/README.md +132 -0
  24. package/template/deploy/host-nginx/react-admin-api.conf +14 -0
  25. package/template/deploy/host-nginx/react-admin-web.conf +8 -0
  26. package/template/deploy/nginx.conf +38 -0
  27. package/template/docs/activity-status.md +217 -0
  28. package/template/docs/audit-logs.md +158 -0
  29. package/template/docs/authentication-adapters.md +219 -0
  30. package/template/docs/browser-security.md +58 -0
  31. package/template/docs/bundle-budgets.md +65 -0
  32. package/template/docs/component-source-governance.md +99 -0
  33. package/template/docs/data-masking.md +169 -0
  34. package/template/docs/enterprise-scaffold.md +208 -0
  35. package/template/docs/feature-data-template.md +227 -0
  36. package/template/docs/feature-flags.md +169 -0
  37. package/template/docs/file-capabilities.md +196 -0
  38. package/template/docs/locale-and-i18n.md +132 -0
  39. package/template/docs/mutation-idempotency.md +24 -0
  40. package/template/docs/optional-editors.md +203 -0
  41. package/template/docs/page-feedback.md +83 -0
  42. package/template/docs/query-data-conventions.md +178 -0
  43. package/template/docs/realtime-collaboration.md +140 -0
  44. package/template/docs/reporting-printing-templates.md +156 -0
  45. package/template/docs/scaffold-capability-roadmap.md +226 -0
  46. package/template/docs/scaffold-guide.md +443 -0
  47. package/template/docs/template-changelog.md +30 -0
  48. package/template/docs/template-versioning.md +26 -0
  49. package/template/docs/tenant-workspace-context.md +147 -0
  50. package/template/docs/unsaved-changes.md +58 -0
  51. package/template/docs/white-label.md +102 -0
  52. package/template/eslint.config.js +697 -0
  53. package/template/gitignore +39 -0
  54. package/template/index.html +26 -0
  55. package/template/knip.config.ts +42 -0
  56. package/template/lint-staged.config.js +8 -0
  57. package/template/package.json +133 -0
  58. package/template/pnpm-lock.yaml +8694 -0
  59. package/template/public/favicon.ico +0 -0
  60. package/template/public/logo.svg +1 -0
  61. package/template/public/runtime-config.json +49 -0
  62. package/template/scaffold.template.json +5 -0
  63. package/template/src/Application.tsx +114 -0
  64. package/template/src/api/ApiError.ts +33 -0
  65. package/template/src/api/activity/ActivityProvider.tsx +167 -0
  66. package/template/src/api/activity/access.ts +13 -0
  67. package/template/src/api/activity/errors.ts +17 -0
  68. package/template/src/api/activity/index.ts +67 -0
  69. package/template/src/api/activity/model.ts +227 -0
  70. package/template/src/api/activity/query.ts +163 -0
  71. package/template/src/api/activity/source.ts +16 -0
  72. package/template/src/api/activity/subscription.ts +292 -0
  73. package/template/src/api/activity/transports.ts +271 -0
  74. package/template/src/api/activity/types.ts +402 -0
  75. package/template/src/api/authClient.ts +134 -0
  76. package/template/src/api/authSession.ts +307 -0
  77. package/template/src/api/clients/configureApiClient.ts +62 -0
  78. package/template/src/api/clients/httpStatus.ts +4 -0
  79. package/template/src/api/config/services.json +7 -0
  80. package/template/src/api/demoAuthClient.ts +46 -0
  81. package/template/src/api/enums/EnumCatalogProvider.tsx +169 -0
  82. package/template/src/api/enums/EnumDictionary.ts +55 -0
  83. package/template/src/api/enums/access.ts +130 -0
  84. package/template/src/api/enums/catalog.ts +216 -0
  85. package/template/src/api/enums/errors.ts +21 -0
  86. package/template/src/api/enums/index.ts +48 -0
  87. package/template/src/api/enums/query.ts +82 -0
  88. package/template/src/api/enums/scope.ts +58 -0
  89. package/template/src/api/enums/types.ts +251 -0
  90. package/template/src/api/hooks/error.ts +198 -0
  91. package/template/src/api/hooks/index.ts +4 -0
  92. package/template/src/api/hooks/request.ts +99 -0
  93. package/template/src/api/hooks/requestId.ts +65 -0
  94. package/template/src/api/hooks/response.ts +22 -0
  95. package/template/src/api/hooks/types.ts +20 -0
  96. package/template/src/api/idempotency/index.ts +1 -0
  97. package/template/src/api/idempotency/key.ts +23 -0
  98. package/template/src/api/index.ts +14 -0
  99. package/template/src/api/metadata/MetadataProvider.tsx +37 -0
  100. package/template/src/api/metadata/index.ts +2 -0
  101. package/template/src/api/metadata/types.ts +30 -0
  102. package/template/src/api/parameters/GlobalParameterProvider.tsx +210 -0
  103. package/template/src/api/parameters/access.ts +117 -0
  104. package/template/src/api/parameters/catalog.ts +170 -0
  105. package/template/src/api/parameters/errors.ts +21 -0
  106. package/template/src/api/parameters/index.ts +53 -0
  107. package/template/src/api/parameters/query.ts +84 -0
  108. package/template/src/api/parameters/scope.ts +58 -0
  109. package/template/src/api/parameters/types.ts +214 -0
  110. package/template/src/api/query/index.ts +13 -0
  111. package/template/src/api/query/keys.ts +155 -0
  112. package/template/src/api/query/mutation.ts +48 -0
  113. package/template/src/api/query/react.ts +36 -0
  114. package/template/src/api/query/scope.ts +38 -0
  115. package/template/src/api/query/types.ts +147 -0
  116. package/template/src/api/types.ts +144 -0
  117. package/template/src/application/types.ts +52 -0
  118. package/template/src/auditLogs/errors.ts +17 -0
  119. package/template/src/auditLogs/export.ts +85 -0
  120. package/template/src/auditLogs/index.ts +54 -0
  121. package/template/src/auditLogs/model.ts +526 -0
  122. package/template/src/auditLogs/query.ts +113 -0
  123. package/template/src/auditLogs/react.ts +36 -0
  124. package/template/src/auditLogs/source.ts +51 -0
  125. package/template/src/auditLogs/types.ts +357 -0
  126. package/template/src/authentication/controller.ts +351 -0
  127. package/template/src/authentication/index.ts +8 -0
  128. package/template/src/authentication/redirect.ts +72 -0
  129. package/template/src/authentication/types.ts +300 -0
  130. package/template/src/bootstrap.tsx +96 -0
  131. package/template/src/components/AppDataTable/AppDataTable.tsx +74 -0
  132. package/template/src/components/AppDataTable/index.ts +2 -0
  133. package/template/src/components/AppDataTable/types.ts +27 -0
  134. package/template/src/components/AppDialog/AppConfirmDialog.tsx +44 -0
  135. package/template/src/components/AppDialog/AppDialog.tsx +113 -0
  136. package/template/src/components/AppDialog/index.ts +3 -0
  137. package/template/src/components/AppDialog/messages.tsx +22 -0
  138. package/template/src/components/AppDialog/types.ts +53 -0
  139. package/template/src/components/AppPageForm/AppPageForm.tsx +21 -0
  140. package/template/src/components/AppPageForm/PageForm.tsx +765 -0
  141. package/template/src/components/AppPageForm/SOURCE.md +26 -0
  142. package/template/src/components/AppPageForm/config.ts +253 -0
  143. package/template/src/components/AppPageForm/controller.ts +580 -0
  144. package/template/src/components/AppPageForm/index.ts +2 -0
  145. package/template/src/components/AppPageForm/messages.ts +90 -0
  146. package/template/src/components/AppPageForm/optionUtils.ts +91 -0
  147. package/template/src/components/AppPageForm/options.ts +397 -0
  148. package/template/src/components/AppPageForm/query.ts +44 -0
  149. package/template/src/components/AppPageForm/style.css +119 -0
  150. package/template/src/components/AppPageForm/types.ts +632 -0
  151. package/template/src/components/AppPageForm/validation.ts +233 -0
  152. package/template/src/components/AppTable/AppTable.tsx +26 -0
  153. package/template/src/components/AppTable/SOURCE.md +72 -0
  154. package/template/src/components/AppTable/cell/customCell/TableCellLayer.tsx +73 -0
  155. package/template/src/components/AppTable/cell/customCell/actions/ActionDropdownCell.tsx +104 -0
  156. package/template/src/components/AppTable/cell/customCell/cellLayer.ts +358 -0
  157. package/template/src/components/AppTable/cell/customCell/componentProps.ts +30 -0
  158. package/template/src/components/AppTable/cell/customCell/date/TemporalPickerEditor.tsx +54 -0
  159. package/template/src/components/AppTable/cell/customCell/index.ts +2 -0
  160. package/template/src/components/AppTable/cell/customCell/select/SelectCellEditor.tsx +225 -0
  161. package/template/src/components/AppTable/cell/customCell/tableCellLayer.css +20 -0
  162. package/template/src/components/AppTable/cell/customCell/tooltip/TooltipCell.tsx +45 -0
  163. package/template/src/components/AppTable/cell/customCell/types.ts +63 -0
  164. package/template/src/components/AppTable/cell/customCell/useCellLayerLifecycle.ts +111 -0
  165. package/template/src/components/AppTable/cell/frameworkCell/TableCellComponentLayer.tsx +40 -0
  166. package/template/src/components/AppTable/cell/frameworkCell/cellComponentSession.ts +203 -0
  167. package/template/src/components/AppTable/cell/frameworkCell/index.ts +3 -0
  168. package/template/src/components/AppTable/cell/index.ts +2 -0
  169. package/template/src/components/AppTable/columns/TableColumnEditor.tsx +257 -0
  170. package/template/src/components/AppTable/columns/index.ts +1 -0
  171. package/template/src/components/AppTable/columns/useTableColumnPreferenceActions.ts +85 -0
  172. package/template/src/components/AppTable/config/defaults.ts +46 -0
  173. package/template/src/components/AppTable/config/index.ts +2 -0
  174. package/template/src/components/AppTable/config/license.ts +39 -0
  175. package/template/src/components/AppTable/config/resolver.ts +25 -0
  176. package/template/src/components/AppTable/config/types.ts +377 -0
  177. package/template/src/components/AppTable/engine/bottom/index.ts +1 -0
  178. package/template/src/components/AppTable/engine/bottom/types.ts +14 -0
  179. package/template/src/components/AppTable/engine/cell/constants.ts +32 -0
  180. package/template/src/components/AppTable/engine/cell/customCell/actions/index.ts +1 -0
  181. package/template/src/components/AppTable/engine/cell/customCell/actions/renderer.ts +162 -0
  182. package/template/src/components/AppTable/engine/cell/customCell/date/index.ts +1 -0
  183. package/template/src/components/AppTable/engine/cell/customCell/date/renderer.ts +116 -0
  184. package/template/src/components/AppTable/engine/cell/customCell/editors/editorBounds.ts +57 -0
  185. package/template/src/components/AppTable/engine/cell/customCell/editors/editorTrigger.ts +46 -0
  186. package/template/src/components/AppTable/engine/cell/customCell/editors/index.ts +3 -0
  187. package/template/src/components/AppTable/engine/cell/customCell/editors/layerEditor.ts +244 -0
  188. package/template/src/components/AppTable/engine/cell/customCell/index.ts +7 -0
  189. package/template/src/components/AppTable/engine/cell/customCell/renderers/columnRenderer.ts +245 -0
  190. package/template/src/components/AppTable/engine/cell/customCell/renderers/confirmInput.ts +57 -0
  191. package/template/src/components/AppTable/engine/cell/customCell/renderers/display.ts +78 -0
  192. package/template/src/components/AppTable/engine/cell/customCell/renderers/index.ts +3 -0
  193. package/template/src/components/AppTable/engine/cell/customCell/renderers/itemList.ts +60 -0
  194. package/template/src/components/AppTable/engine/cell/customCell/renderers/links.ts +131 -0
  195. package/template/src/components/AppTable/engine/cell/customCell/renderers/selection.ts +41 -0
  196. package/template/src/components/AppTable/engine/cell/customCell/renderers/shared.ts +71 -0
  197. package/template/src/components/AppTable/engine/cell/customCell/renderers/step.ts +37 -0
  198. package/template/src/components/AppTable/engine/cell/customCell/renderers/switch.ts +45 -0
  199. package/template/src/components/AppTable/engine/cell/customCell/select/index.ts +1 -0
  200. package/template/src/components/AppTable/engine/cell/customCell/select/renderer.ts +33 -0
  201. package/template/src/components/AppTable/engine/cell/customCell/tooltip/index.ts +1 -0
  202. package/template/src/components/AppTable/engine/cell/customCell/tooltip/tooltip.ts +94 -0
  203. package/template/src/components/AppTable/engine/cell/customCell/types.ts +82 -0
  204. package/template/src/components/AppTable/engine/cell/formatting.ts +355 -0
  205. package/template/src/components/AppTable/engine/cell/formula.ts +145 -0
  206. package/template/src/components/AppTable/engine/cell/index.ts +7 -0
  207. package/template/src/components/AppTable/engine/cell/multiSelect.ts +96 -0
  208. package/template/src/components/AppTable/engine/cell/options.ts +339 -0
  209. package/template/src/components/AppTable/engine/cell/types.ts +53 -0
  210. package/template/src/components/AppTable/engine/columns/column.ts +430 -0
  211. package/template/src/components/AppTable/engine/columns/config/columns.ts +33 -0
  212. package/template/src/components/AppTable/engine/columns/config/index.ts +4 -0
  213. package/template/src/components/AppTable/engine/columns/config/mutation.ts +138 -0
  214. package/template/src/components/AppTable/engine/columns/config/temporal.ts +11 -0
  215. package/template/src/components/AppTable/engine/columns/config/validation.ts +106 -0
  216. package/template/src/components/AppTable/engine/columns/constants.ts +6 -0
  217. package/template/src/components/AppTable/engine/columns/gridColumns.ts +332 -0
  218. package/template/src/components/AppTable/engine/columns/index.ts +4 -0
  219. package/template/src/components/AppTable/engine/columns/rendererPolicies.ts +129 -0
  220. package/template/src/components/AppTable/engine/component/resolver.ts +272 -0
  221. package/template/src/components/AppTable/engine/component/types.ts +384 -0
  222. package/template/src/components/AppTable/engine/config/constants.ts +33 -0
  223. package/template/src/components/AppTable/engine/config/grid/compiler.ts +65 -0
  224. package/template/src/components/AppTable/engine/config/grid/defaults.ts +82 -0
  225. package/template/src/components/AppTable/engine/config/grid/ownership.ts +35 -0
  226. package/template/src/components/AppTable/engine/config/grid/runtimeDelta.ts +34 -0
  227. package/template/src/components/AppTable/engine/config/grid/types.ts +30 -0
  228. package/template/src/components/AppTable/engine/pagination/config.ts +75 -0
  229. package/template/src/components/AppTable/engine/pagination/constants.ts +5 -0
  230. package/template/src/components/AppTable/engine/pagination/index.ts +3 -0
  231. package/template/src/components/AppTable/engine/pagination/types.ts +70 -0
  232. package/template/src/components/AppTable/engine/preference/index.ts +2 -0
  233. package/template/src/components/AppTable/engine/preference/preference.ts +535 -0
  234. package/template/src/components/AppTable/engine/preference/types.ts +28 -0
  235. package/template/src/components/AppTable/engine/right/index.ts +1 -0
  236. package/template/src/components/AppTable/engine/right/types.ts +18 -0
  237. package/template/src/components/AppTable/engine/search/config.ts +64 -0
  238. package/template/src/components/AppTable/engine/search/constants.ts +8 -0
  239. package/template/src/components/AppTable/engine/search/index.ts +7 -0
  240. package/template/src/components/AppTable/engine/search/localQuery.ts +145 -0
  241. package/template/src/components/AppTable/engine/search/query.ts +203 -0
  242. package/template/src/components/AppTable/engine/search/remoteQuery.ts +99 -0
  243. package/template/src/components/AppTable/engine/search/searchInteraction.ts +46 -0
  244. package/template/src/components/AppTable/engine/search/types.ts +155 -0
  245. package/template/src/components/AppTable/engine/selection/config.ts +13 -0
  246. package/template/src/components/AppTable/engine/selection/index.ts +4 -0
  247. package/template/src/components/AppTable/engine/selection/selection.ts +357 -0
  248. package/template/src/components/AppTable/engine/selection/selectionHeader.ts +88 -0
  249. package/template/src/components/AppTable/engine/selection/types.ts +66 -0
  250. package/template/src/components/AppTable/engine/shared/action.ts +11 -0
  251. package/template/src/components/AppTable/engine/shared/constants.ts +2 -0
  252. package/template/src/components/AppTable/engine/shared/decimal.ts +114 -0
  253. package/template/src/components/AppTable/engine/shared/feedback.ts +62 -0
  254. package/template/src/components/AppTable/engine/shared/index.ts +13 -0
  255. package/template/src/components/AppTable/engine/shared/interaction.ts +55 -0
  256. package/template/src/components/AppTable/engine/shared/messages.ts +161 -0
  257. package/template/src/components/AppTable/engine/shared/row.ts +32 -0
  258. package/template/src/components/AppTable/engine/shared/scheduler.ts +17 -0
  259. package/template/src/components/AppTable/engine/shared/tableKey.ts +31 -0
  260. package/template/src/components/AppTable/engine/shared/theme.ts +196 -0
  261. package/template/src/components/AppTable/engine/shared/treeRows.ts +155 -0
  262. package/template/src/components/AppTable/engine/shared/types.ts +58 -0
  263. package/template/src/components/AppTable/engine/shared/valueSnapshot.ts +46 -0
  264. package/template/src/components/AppTable/engine/summary/config/export.ts +117 -0
  265. package/template/src/components/AppTable/engine/summary/config/index.ts +3 -0
  266. package/template/src/components/AppTable/engine/summary/config/summary.ts +62 -0
  267. package/template/src/components/AppTable/engine/summary/config/types.ts +93 -0
  268. package/template/src/components/AppTable/engine/summary/constants.ts +13 -0
  269. package/template/src/components/AppTable/engine/summary/excelJs.ts +133 -0
  270. package/template/src/components/AppTable/engine/summary/export.ts +311 -0
  271. package/template/src/components/AppTable/engine/summary/index.ts +6 -0
  272. package/template/src/components/AppTable/engine/summary/selectionSum.ts +92 -0
  273. package/template/src/components/AppTable/engine/summary/summary.ts +457 -0
  274. package/template/src/components/AppTable/engine/table/clipboard/index.ts +1 -0
  275. package/template/src/components/AppTable/engine/table/clipboard/transfer.ts +9 -0
  276. package/template/src/components/AppTable/engine/table/controller/TableController.ts +802 -0
  277. package/template/src/components/AppTable/engine/table/controller/errors.ts +106 -0
  278. package/template/src/components/AppTable/engine/table/controller/index.ts +4 -0
  279. package/template/src/components/AppTable/engine/table/controller/latestAbortableTask.ts +33 -0
  280. package/template/src/components/AppTable/engine/table/controller/tableDataReplacement.ts +60 -0
  281. package/template/src/components/AppTable/engine/table/controller/tableDomainConfiguration.ts +94 -0
  282. package/template/src/components/AppTable/engine/table/controller/tableEditingCommands.ts +163 -0
  283. package/template/src/components/AppTable/engine/table/controller/tableGridHost.ts +324 -0
  284. package/template/src/components/AppTable/engine/table/controller/tableIdentity.ts +68 -0
  285. package/template/src/components/AppTable/engine/table/controller/tableMutationPipeline.ts +79 -0
  286. package/template/src/components/AppTable/engine/table/controller/tableQueryCoordinator.ts +187 -0
  287. package/template/src/components/AppTable/engine/table/controller/tableReportingCoordinator.ts +143 -0
  288. package/template/src/components/AppTable/engine/table/controller/tableSaveCoordinator.ts +227 -0
  289. package/template/src/components/AppTable/engine/table/controller/tableSaveValidation.ts +29 -0
  290. package/template/src/components/AppTable/engine/table/controller/tableSnapshot.ts +58 -0
  291. package/template/src/components/AppTable/engine/table/controller/types.ts +202 -0
  292. package/template/src/components/AppTable/engine/table/editing/baselineStore.ts +134 -0
  293. package/template/src/components/AppTable/engine/table/editing/changeSet.ts +492 -0
  294. package/template/src/components/AppTable/engine/table/editing/changeSetSettlement.ts +633 -0
  295. package/template/src/components/AppTable/engine/table/editing/commitResultIndex.ts +75 -0
  296. package/template/src/components/AppTable/engine/table/editing/constants.ts +15 -0
  297. package/template/src/components/AppTable/engine/table/editing/dirtyCellIndex.ts +96 -0
  298. package/template/src/components/AppTable/engine/table/editing/index.ts +6 -0
  299. package/template/src/components/AppTable/engine/table/editing/mutation.ts +173 -0
  300. package/template/src/components/AppTable/engine/table/editing/rowKey.ts +10 -0
  301. package/template/src/components/AppTable/engine/table/editing/types.ts +404 -0
  302. package/template/src/components/AppTable/engine/table/editing/validation.ts +452 -0
  303. package/template/src/components/AppTable/engine/table/grid/cellMeta.ts +90 -0
  304. package/template/src/components/AppTable/engine/table/grid/handsontable.ts +25 -0
  305. package/template/src/components/AppTable/engine/table/grid/handsontableExtensions.d.ts +26 -0
  306. package/template/src/components/AppTable/engine/table/grid/index.ts +5 -0
  307. package/template/src/components/AppTable/engine/table/grid/moduleRegistry.ts +39 -0
  308. package/template/src/components/AppTable/engine/table/grid/runtime.ts +31 -0
  309. package/template/src/components/AppTable/engine/table/grid/types.ts +25 -0
  310. package/template/src/components/AppTable/engine/table/hooks/fixedEndHooks.ts +44 -0
  311. package/template/src/components/AppTable/engine/table/hooks/gridHooks.ts +108 -0
  312. package/template/src/components/AppTable/engine/table/hooks/headerHooks.ts +103 -0
  313. package/template/src/components/AppTable/engine/table/hooks/index.ts +3 -0
  314. package/template/src/components/AppTable/engine/table/index.ts +6 -0
  315. package/template/src/components/AppTable/engine/table/layout/constants.ts +2 -0
  316. package/template/src/components/AppTable/engine/table/layout/dropdownMenu.ts +89 -0
  317. package/template/src/components/AppTable/engine/table/layout/fixedColumns.ts +44 -0
  318. package/template/src/components/AppTable/engine/table/layout/fixedEndOverlay.ts +90 -0
  319. package/template/src/components/AppTable/engine/table/layout/fixedEndOverlayAccessibility.ts +104 -0
  320. package/template/src/components/AppTable/engine/table/layout/fixedEndOverlayRenderer.ts +690 -0
  321. package/template/src/components/AppTable/engine/table/layout/fixedEndOverlaySignature.ts +58 -0
  322. package/template/src/components/AppTable/engine/table/layout/fixedEndRuntime.ts +137 -0
  323. package/template/src/components/AppTable/engine/table/layout/handsontableDomAdapter.ts +40 -0
  324. package/template/src/components/AppTable/engine/table/layout/height.ts +72 -0
  325. package/template/src/components/AppTable/engine/table/layout/index.ts +14 -0
  326. package/template/src/components/AppTable/engine/table/layout/layoutScheduler.ts +60 -0
  327. package/template/src/components/AppTable/engine/table/layout/mergeCells.ts +146 -0
  328. package/template/src/components/AppTable/engine/table/layout/nestedHeaders.ts +271 -0
  329. package/template/src/components/AppTable/engine/table/layout/types.ts +10 -0
  330. package/template/src/components/AppTable/engine/toolbar/index.ts +1 -0
  331. package/template/src/components/AppTable/engine/toolbar/types.ts +56 -0
  332. package/template/src/components/AppTable/index.ts +11 -0
  333. package/template/src/components/AppTable/messages.ts +256 -0
  334. package/template/src/components/AppTable/pagination/TablePaginationBar.tsx +193 -0
  335. package/template/src/components/AppTable/pagination/index.ts +1 -0
  336. package/template/src/components/AppTable/pagination/paginationItems.ts +56 -0
  337. package/template/src/components/AppTable/preference/index.ts +1 -0
  338. package/template/src/components/AppTable/preference/useTablePreference.ts +208 -0
  339. package/template/src/components/AppTable/reporting/index.ts +1 -0
  340. package/template/src/components/AppTable/reporting/useTableReporting.ts +342 -0
  341. package/template/src/components/AppTable/search/TableSearchBar.tsx +301 -0
  342. package/template/src/components/AppTable/search/TableSearchConditionEditor.tsx +254 -0
  343. package/template/src/components/AppTable/search/TableSearchField.tsx +338 -0
  344. package/template/src/components/AppTable/search/TableSearchFields.tsx +65 -0
  345. package/template/src/components/AppTable/search/constants.ts +9 -0
  346. package/template/src/components/AppTable/search/index.ts +3 -0
  347. package/template/src/components/AppTable/search/tableSearchBar.css +164 -0
  348. package/template/src/components/AppTable/search/types.ts +7 -0
  349. package/template/src/components/AppTable/search/useTableQuery.ts +373 -0
  350. package/template/src/components/AppTable/selection/index.ts +1 -0
  351. package/template/src/components/AppTable/selection/useTableSelection.ts +188 -0
  352. package/template/src/components/AppTable/sensitiveData.tsx +41 -0
  353. package/template/src/components/AppTable/shared/styles.ts +2 -0
  354. package/template/src/components/AppTable/styles/index.css +6 -0
  355. package/template/src/components/AppTable/styles/tableComponent.css +297 -0
  356. package/template/src/components/AppTable/styles/theme.css +133 -0
  357. package/template/src/components/AppTable/table/components/TableComponent.tsx +567 -0
  358. package/template/src/components/AppTable/table/components/TableErrorFeedback.tsx +36 -0
  359. package/template/src/components/AppTable/table/components/TableGridViewport.tsx +85 -0
  360. package/template/src/components/AppTable/table/components/index.ts +2 -0
  361. package/template/src/components/AppTable/table/components/types.ts +90 -0
  362. package/template/src/components/AppTable/table/controller/configuration.ts +89 -0
  363. package/template/src/components/AppTable/table/controller/index.ts +2 -0
  364. package/template/src/components/AppTable/table/controller/useTableController.ts +155 -0
  365. package/template/src/components/AppTable/table/controller/useTableLifecycle.ts +97 -0
  366. package/template/src/components/AppTable/table/grid/index.ts +1 -0
  367. package/template/src/components/AppTable/table/grid/useTableGrid.ts +857 -0
  368. package/template/src/components/AppTable/table/grid/useTableGridRuntimeSettings.ts +49 -0
  369. package/template/src/components/AppTable/table/index.ts +4 -0
  370. package/template/src/components/AppTable/table/layout/TablePanels.tsx +389 -0
  371. package/template/src/components/AppTable/table/layout/index.ts +7 -0
  372. package/template/src/components/AppTable/table/layout/types.ts +3 -0
  373. package/template/src/components/AppTable/table/layout/useResizablePanel.ts +213 -0
  374. package/template/src/components/AppTable/table/layout/useTableAdaptiveHeight.ts +238 -0
  375. package/template/src/components/AppTable/table/layout/useTablePanels.ts +329 -0
  376. package/template/src/components/AppTable/table/layout/useTableTheme.ts +123 -0
  377. package/template/src/components/AppTable/toolbar/TableToolbar.tsx +336 -0
  378. package/template/src/components/AppTable/toolbar/index.ts +1 -0
  379. package/template/src/components/BrandLogo/BrandLogo.tsx +41 -0
  380. package/template/src/components/BrandLogo/index.ts +1 -0
  381. package/template/src/components/Can/Can.tsx +19 -0
  382. package/template/src/components/Can/index.ts +7 -0
  383. package/template/src/components/Can/types.ts +41 -0
  384. package/template/src/components/EnumBadge/EnumBadge.tsx +44 -0
  385. package/template/src/components/EnumBadge/index.ts +2 -0
  386. package/template/src/components/EnumBadge/types.ts +16 -0
  387. package/template/src/components/EnumText/EnumText.tsx +33 -0
  388. package/template/src/components/EnumText/index.ts +2 -0
  389. package/template/src/components/EnumText/types.ts +13 -0
  390. package/template/src/components/FilePreview/FilePreview.tsx +120 -0
  391. package/template/src/components/FilePreview/index.ts +11 -0
  392. package/template/src/components/FilePreview/preview.ts +88 -0
  393. package/template/src/components/FilePreview/types.ts +91 -0
  394. package/template/src/components/FileUpload/FileUpload.tsx +172 -0
  395. package/template/src/components/FileUpload/index.ts +2 -0
  396. package/template/src/components/FileUpload/types.ts +32 -0
  397. package/template/src/components/JsonEditor/JsonEditor.tsx +103 -0
  398. package/template/src/components/JsonEditor/index.ts +1 -0
  399. package/template/src/components/JsonEditor/types.ts +14 -0
  400. package/template/src/components/PageFeedback/PageFeedback.tsx +194 -0
  401. package/template/src/components/PageFeedback/index.ts +10 -0
  402. package/template/src/components/PageFeedback/types.ts +31 -0
  403. package/template/src/components/PasswordInput/PasswordInput.tsx +50 -0
  404. package/template/src/components/PasswordInput/index.ts +1 -0
  405. package/template/src/components/RouteDialog/RouteDialog.tsx +20 -0
  406. package/template/src/components/RouteDialog/index.ts +2 -0
  407. package/template/src/components/RouteDialog/types.ts +8 -0
  408. package/template/src/components/RouteDialog/useRouteDialogNavigation.ts +30 -0
  409. package/template/src/components/SensitiveData/SensitiveData.tsx +337 -0
  410. package/template/src/components/SensitiveData/index.ts +2 -0
  411. package/template/src/components/SensitiveData/types.ts +31 -0
  412. package/template/src/components/StatusBadge/StatusBadge.tsx +28 -0
  413. package/template/src/components/StatusBadge/index.ts +2 -0
  414. package/template/src/components/StatusBadge/statusBadgeStyles.ts +30 -0
  415. package/template/src/components/StatusBadge/types.ts +7 -0
  416. package/template/src/components/layout/AppHeader/AppHeader.tsx +57 -0
  417. package/template/src/components/layout/AppHeader/HeaderSearch.tsx +160 -0
  418. package/template/src/components/layout/AppHeader/HeaderUserMenu.tsx +59 -0
  419. package/template/src/components/layout/AppHeader/ThemeControls.tsx +44 -0
  420. package/template/src/components/layout/AppHeader/index.ts +1 -0
  421. package/template/src/components/layout/AppHeader/themeOptions.ts +13 -0
  422. package/template/src/components/layout/AppSidebar.tsx +268 -0
  423. package/template/src/components/layout/PageContainer.tsx +16 -0
  424. package/template/src/components/ui/avatar.tsx +108 -0
  425. package/template/src/components/ui/badge.tsx +47 -0
  426. package/template/src/components/ui/button.tsx +63 -0
  427. package/template/src/components/ui/card.tsx +60 -0
  428. package/template/src/components/ui/checkbox.tsx +31 -0
  429. package/template/src/components/ui/collapsible.tsx +33 -0
  430. package/template/src/components/ui/command.tsx +181 -0
  431. package/template/src/components/ui/dialog.tsx +157 -0
  432. package/template/src/components/ui/dropdown-menu.tsx +254 -0
  433. package/template/src/components/ui/form.tsx +141 -0
  434. package/template/src/components/ui/input.tsx +20 -0
  435. package/template/src/components/ui/label.tsx +23 -0
  436. package/template/src/components/ui/pagination.tsx +127 -0
  437. package/template/src/components/ui/popover.tsx +41 -0
  438. package/template/src/components/ui/select.tsx +187 -0
  439. package/template/src/components/ui/separator.tsx +25 -0
  440. package/template/src/components/ui/sheet.tsx +142 -0
  441. package/template/src/components/ui/sidebar.tsx +878 -0
  442. package/template/src/components/ui/skeleton.tsx +13 -0
  443. package/template/src/components/ui/sonner.tsx +33 -0
  444. package/template/src/components/ui/tooltip.tsx +54 -0
  445. package/template/src/config/RuntimeConfigErrorPage.tsx +48 -0
  446. package/template/src/config/appConfig.ts +126 -0
  447. package/template/src/config/buildInfo.ts +8 -0
  448. package/template/src/config/observabilityAdapter.ts +8 -0
  449. package/template/src/config/runtimeConfig.ts +360 -0
  450. package/template/src/config/types.ts +195 -0
  451. package/template/src/context/ThemeProvider.tsx +84 -0
  452. package/template/src/context/UnsavedChangesProvider.tsx +123 -0
  453. package/template/src/context/applicationScope.ts +39 -0
  454. package/template/src/context/types.ts +41 -0
  455. package/template/src/dataMasking/index.ts +14 -0
  456. package/template/src/dataMasking/masking.ts +139 -0
  457. package/template/src/dataMasking/types.ts +144 -0
  458. package/template/src/featureFlags/FeatureFlagProvider.tsx +143 -0
  459. package/template/src/featureFlags/FeatureGate.tsx +12 -0
  460. package/template/src/featureFlags/catalog.ts +140 -0
  461. package/template/src/featureFlags/errors.ts +17 -0
  462. package/template/src/featureFlags/index.ts +43 -0
  463. package/template/src/featureFlags/query.ts +103 -0
  464. package/template/src/featureFlags/registry.ts +149 -0
  465. package/template/src/featureFlags/scope.ts +27 -0
  466. package/template/src/featureFlags/types.ts +241 -0
  467. package/template/src/features/auth/AuthLayout.tsx +17 -0
  468. package/template/src/features/auth/index.ts +2 -0
  469. package/template/src/features/auth/signIn/components/UserAuthForm.tsx +121 -0
  470. package/template/src/features/auth/signIn/index.tsx +71 -0
  471. package/template/src/features/auth/signIn/messages.ts +37 -0
  472. package/template/src/features/auth/signIn/types.ts +4 -0
  473. package/template/src/features/errors/ForbiddenError.tsx +34 -0
  474. package/template/src/features/errors/GeneralError.tsx +46 -0
  475. package/template/src/features/errors/MaintenanceError.tsx +31 -0
  476. package/template/src/features/errors/NotFoundError.tsx +34 -0
  477. package/template/src/features/errors/RouteError.tsx +72 -0
  478. package/template/src/features/errors/UnauthorizedError.tsx +34 -0
  479. package/template/src/features/errors/index.ts +6 -0
  480. package/template/src/features/errors/messages.ts +56 -0
  481. package/template/src/features/home/index.tsx +107 -0
  482. package/template/src/features/home/messages.ts +59 -0
  483. package/template/src/features/showcase/AccessShowcasePage.tsx +284 -0
  484. package/template/src/features/showcase/AdvancedTableDemo.tsx +120 -0
  485. package/template/src/features/showcase/FeedbackShowcasePage.tsx +142 -0
  486. package/template/src/features/showcase/FileShowcasePage.tsx +110 -0
  487. package/template/src/features/showcase/FormShowcasePage.tsx +156 -0
  488. package/template/src/features/showcase/MetadataShowcasePage.tsx +241 -0
  489. package/template/src/features/showcase/ShowcasePageHeader.tsx +24 -0
  490. package/template/src/features/showcase/TableShowcasePage.tsx +436 -0
  491. package/template/src/features/showcase/accessMessages.ts +67 -0
  492. package/template/src/features/showcase/index.ts +6 -0
  493. package/template/src/features/showcase/messages.ts +192 -0
  494. package/template/src/files/download.ts +82 -0
  495. package/template/src/files/errors.ts +15 -0
  496. package/template/src/files/filename.ts +61 -0
  497. package/template/src/files/index.ts +38 -0
  498. package/template/src/files/types.ts +299 -0
  499. package/template/src/files/useFileTask.ts +153 -0
  500. package/template/src/files/useFileUpload.ts +117 -0
  501. package/template/src/files/validation.ts +109 -0
  502. package/template/src/layouts/AppLayout.tsx +37 -0
  503. package/template/src/lib/accessControl.ts +42 -0
  504. package/template/src/lib/navigationRedirect.ts +26 -0
  505. package/template/src/lib/utils.ts +6 -0
  506. package/template/src/locale/LocaleProvider.tsx +37 -0
  507. package/template/src/locale/context.ts +15 -0
  508. package/template/src/locale/formatters.ts +123 -0
  509. package/template/src/locale/hooks.ts +35 -0
  510. package/template/src/locale/index.ts +17 -0
  511. package/template/src/locale/messages.ts +151 -0
  512. package/template/src/locale/types.ts +167 -0
  513. package/template/src/main.tsx +5 -0
  514. package/template/src/observability/browser.ts +37 -0
  515. package/template/src/observability/consoleAdapter.ts +18 -0
  516. package/template/src/observability/index.ts +26 -0
  517. package/template/src/observability/observer.ts +118 -0
  518. package/template/src/observability/redaction.ts +85 -0
  519. package/template/src/observability/types.ts +119 -0
  520. package/template/src/optionalEditors/controller.ts +327 -0
  521. package/template/src/optionalEditors/errors.ts +21 -0
  522. package/template/src/optionalEditors/index.ts +35 -0
  523. package/template/src/optionalEditors/model.ts +253 -0
  524. package/template/src/optionalEditors/react.ts +89 -0
  525. package/template/src/optionalEditors/types.ts +254 -0
  526. package/template/src/permissions/index.ts +3 -0
  527. package/template/src/permissions/types.ts +5 -0
  528. package/template/src/permissions/usePermission.ts +16 -0
  529. package/template/src/realtimeCollaboration/controller.ts +355 -0
  530. package/template/src/realtimeCollaboration/errors.ts +20 -0
  531. package/template/src/realtimeCollaboration/index.ts +39 -0
  532. package/template/src/realtimeCollaboration/model.ts +212 -0
  533. package/template/src/realtimeCollaboration/react.ts +72 -0
  534. package/template/src/realtimeCollaboration/types.ts +251 -0
  535. package/template/src/reporting/errors.ts +21 -0
  536. package/template/src/reporting/generation.ts +87 -0
  537. package/template/src/reporting/index.ts +42 -0
  538. package/template/src/reporting/model.ts +373 -0
  539. package/template/src/reporting/print.ts +16 -0
  540. package/template/src/reporting/query.ts +50 -0
  541. package/template/src/reporting/react.ts +17 -0
  542. package/template/src/reporting/source.ts +13 -0
  543. package/template/src/reporting/types.ts +219 -0
  544. package/template/src/router/RootRouteLayout.tsx +11 -0
  545. package/template/src/router/authLifecycle.ts +39 -0
  546. package/template/src/router/config.ts +293 -0
  547. package/template/src/router/interceptors.ts +48 -0
  548. package/template/src/router/lazyRouteComponents.ts +78 -0
  549. package/template/src/router/messages.ts +48 -0
  550. package/template/src/router/navigation.ts +167 -0
  551. package/template/src/router/router.ts +66 -0
  552. package/template/src/router/searchSchemas.ts +9 -0
  553. package/template/src/router/types.ts +76 -0
  554. package/template/src/stores/authSessionStorage.ts +27 -0
  555. package/template/src/stores/authStore.ts +165 -0
  556. package/template/src/stores/types.ts +36 -0
  557. package/template/src/stores/uiPreferenceStore.ts +34 -0
  558. package/template/src/styles/index.css +141 -0
  559. package/template/src/styles/theme.css +213 -0
  560. package/template/src/tenantWorkspace/TenantWorkspaceProvider.tsx +102 -0
  561. package/template/src/tenantWorkspace/index.ts +33 -0
  562. package/template/src/tenantWorkspace/store.ts +184 -0
  563. package/template/src/tenantWorkspace/switch.ts +206 -0
  564. package/template/src/tenantWorkspace/types.ts +155 -0
  565. package/template/src/vite-env.d.ts +20 -0
  566. package/template/stylelint.config.js +28 -0
  567. package/template/tests/integration/Application.test.tsx +269 -0
  568. package/template/tests/integration/layout/AppHeader.test.tsx +182 -0
  569. package/template/tests/integration/layout/AppSidebar.test.tsx +121 -0
  570. package/template/tests/integration/layout/__screenshots__/AppHeader.test.tsx/AppHeader-command-search-hides-the-duplicate-header-trigger-when-the-desktop-sidebar-collapses-1.png +0 -0
  571. package/template/tests/integration/router/__screenshots__/config.test.ts/route-tree-authentication-boundaries-exposes-only-scaffold-navigation-metadata-1.png +0 -0
  572. package/template/tests/integration/router/config.test.ts +123 -0
  573. package/template/tests/integration/router/interceptors.test.ts +100 -0
  574. package/template/tests/setup/accessibility.ts +25 -0
  575. package/template/tests/setup/runtimeConfig.ts +3 -0
  576. package/template/tests/unit/api/ApiError.test.ts +25 -0
  577. package/template/tests/unit/api/__screenshots__/authSession.test.ts/administrator-authentication-clears-the-session-if-a-refresh-identity-loses-administrator-access-1.png +0 -0
  578. package/template/tests/unit/api/__screenshots__/authSession.test.ts/administrator-authentication-creates-a-session-from-the-generated-login-response-for-an-admin-1.png +0 -0
  579. package/template/tests/unit/api/__screenshots__/authSession.test.ts/administrator-authentication-rejects-and-revokes-the-generated-login-result-for-an-ordinary-user-1.png +0 -0
  580. package/template/tests/unit/api/activity/ActivityProvider.test.tsx +131 -0
  581. package/template/tests/unit/api/activity/__screenshots__/transports.test.ts/activity-transport-adapters-polls-sequentially-and-advances-the-last-event-ID-1.png +0 -0
  582. package/template/tests/unit/api/activity/modelAndQuery.test.ts +144 -0
  583. package/template/tests/unit/api/activity/subscription.test.ts +103 -0
  584. package/template/tests/unit/api/activity/transports.test.ts +145 -0
  585. package/template/tests/unit/api/authClient.test.ts +110 -0
  586. package/template/tests/unit/api/authSession.test.ts +289 -0
  587. package/template/tests/unit/api/clients/configureApiClient.test.ts +198 -0
  588. package/template/tests/unit/api/demoAuthClient.test.ts +47 -0
  589. package/template/tests/unit/api/enums/access.test.ts +107 -0
  590. package/template/tests/unit/api/enums/catalog.test.ts +200 -0
  591. package/template/tests/unit/api/enums/query.test.ts +110 -0
  592. package/template/tests/unit/api/enums/useEnum.test.tsx +98 -0
  593. package/template/tests/unit/api/enums/useEnumCatalog.test.tsx +68 -0
  594. package/template/tests/unit/api/hooks/error.test.ts +168 -0
  595. package/template/tests/unit/api/hooks/request.test.ts +170 -0
  596. package/template/tests/unit/api/hooks/response.test.ts +46 -0
  597. package/template/tests/unit/api/metadata/MetadataProvider.test.tsx +102 -0
  598. package/template/tests/unit/api/parameters/catalog.test.ts +147 -0
  599. package/template/tests/unit/api/parameters/query.test.ts +78 -0
  600. package/template/tests/unit/api/parameters/useGlobalParameter.test.tsx +89 -0
  601. package/template/tests/unit/api/query/queryPolicy.test.ts +245 -0
  602. package/template/tests/unit/api/query/useAppQueryScope.test.tsx +74 -0
  603. package/template/tests/unit/auditLogs/auditLogHooks.test.tsx +194 -0
  604. package/template/tests/unit/auditLogs/auditLogs.test.ts +199 -0
  605. package/template/tests/unit/authentication/__screenshots__/authentication.test.ts/authentication-controller-completes-Step-up-callbacks-without-creating-a-second-login-result-1.png +0 -0
  606. package/template/tests/unit/authentication/__screenshots__/authentication.test.ts/authentication-controller-moves-from-challenge-to-completion-without-retaining-tokens-in-snapshot-1.png +0 -0
  607. package/template/tests/unit/authentication/authentication.test.ts +376 -0
  608. package/template/tests/unit/components/AppDialog.test.tsx +225 -0
  609. package/template/tests/unit/components/AppTable.test.tsx +129 -0
  610. package/template/tests/unit/components/AppTableLayoutTransition.test.ts +118 -0
  611. package/template/tests/unit/components/AppTableLocalization.test.ts +58 -0
  612. package/template/tests/unit/components/AppTableSensitiveData.test.ts +35 -0
  613. package/template/tests/unit/components/AppTableUpgrade.test.tsx +179 -0
  614. package/template/tests/unit/components/AppTableUpgradeCore.test.ts +258 -0
  615. package/template/tests/unit/components/BrandLogo.test.tsx +24 -0
  616. package/template/tests/unit/components/Can.test.tsx +80 -0
  617. package/template/tests/unit/components/Dialog.test.tsx +56 -0
  618. package/template/tests/unit/components/EnumPresentation.test.tsx +64 -0
  619. package/template/tests/unit/components/FilePreviewEngine.test.ts +51 -0
  620. package/template/tests/unit/components/JsonEditor.test.tsx +47 -0
  621. package/template/tests/unit/components/LocalizedSharedComponents.test.tsx +36 -0
  622. package/template/tests/unit/components/OverlayLayer.test.tsx +151 -0
  623. package/template/tests/unit/components/PageFeedback.test.tsx +143 -0
  624. package/template/tests/unit/components/PageForm.test.tsx +272 -0
  625. package/template/tests/unit/components/PageFormCore.test.ts +74 -0
  626. package/template/tests/unit/components/PasswordInput.test.tsx +105 -0
  627. package/template/tests/unit/components/ScaffoldComponents.test.tsx +64 -0
  628. package/template/tests/unit/components/SensitiveData.test.tsx +151 -0
  629. package/template/tests/unit/components/StatusBadge.test.tsx +36 -0
  630. package/template/tests/unit/components/TableComponent.test.tsx +644 -0
  631. package/template/tests/unit/components/TableCore.test.ts +145 -0
  632. package/template/tests/unit/components/ThemeAccessibility.test.tsx +27 -0
  633. package/template/tests/unit/components/__screenshots__/BatchOperationDialog.test.tsx/confirms-a-batch-action-and-presents-partial-failure-details-1.png +0 -0
  634. package/template/tests/unit/components/__screenshots__/PageForm.test.tsx/PageForm-writes-uploaded-values-through-the-public-file-field-and-resets-dirty-state-1.png +0 -0
  635. package/template/tests/unit/components/__screenshots__/PasswordInput.test.tsx/PasswordInput-toggles-the-password-visibility-when-the-show-password-button-is-clicked-1.png +0 -0
  636. package/template/tests/unit/components/__screenshots__/TableComponent.test.tsx/TableComponent-pins-trailing-action-columns-and-removes-their-header-menu-by-default-1.png +0 -0
  637. package/template/tests/unit/components/__screenshots__/TableComponent.test.tsx/TableComponent-renders-shadcn-components-through-cellComponent-1.png +0 -0
  638. package/template/tests/unit/components/__screenshots__/TableComponent.test.tsx/TableComponent-renders-the-toolbar-without-a-bottom-divider-1.png +0 -0
  639. package/template/tests/unit/components/__screenshots__/TableComponent.test.tsx/TableComponent-resyncs-adaptive-height-after-a-column-resize-changes-wrapped-row-height-1.png +0 -0
  640. package/template/tests/unit/config/RuntimeConfigErrorPage.test.tsx +23 -0
  641. package/template/tests/unit/config/appConfig.test.ts +98 -0
  642. package/template/tests/unit/config/appTableContracts.test.mjs +120 -0
  643. package/template/tests/unit/config/bundleBudget.test.mjs +190 -0
  644. package/template/tests/unit/config/componentGovernance.test.mjs +156 -0
  645. package/template/tests/unit/config/deployConfig.test.mjs +211 -0
  646. package/template/tests/unit/config/eslintConfig.test.mjs +101 -0
  647. package/template/tests/unit/config/featureBoundaries.test.mjs +126 -0
  648. package/template/tests/unit/config/npmPackage.test.mjs +37 -0
  649. package/template/tests/unit/config/releaseArtifact.test.mjs +105 -0
  650. package/template/tests/unit/config/runtimeConfig.test.ts +225 -0
  651. package/template/tests/unit/config/scaffoldCheck.test.mjs +53 -0
  652. package/template/tests/unit/config/scaffoldFeature.test.mjs +177 -0
  653. package/template/tests/unit/config/scaffoldInit.test.mjs +218 -0
  654. package/template/tests/unit/config/scaffoldProject.test.mjs +378 -0
  655. package/template/tests/unit/config/scaffoldTransaction.test.mjs +77 -0
  656. package/template/tests/unit/config/viteConfig.test.mjs +371 -0
  657. package/template/tests/unit/context/ThemeProvider.test.tsx +108 -0
  658. package/template/tests/unit/context/UnsavedChangesProvider.test.tsx +94 -0
  659. package/template/tests/unit/context/__screenshots__/ThemeProvider.test.tsx/ThemeProvider-uses-the-neutral-black-palette-for-the-app-and-scoped-table-theme-1.png +0 -0
  660. package/template/tests/unit/context/applicationScope.test.ts +62 -0
  661. package/template/tests/unit/dataMasking/dataMasking.test.ts +95 -0
  662. package/template/tests/unit/featureFlags/featureFlags.test.ts +169 -0
  663. package/template/tests/unit/featureFlags/useFeatureFlag.test.tsx +108 -0
  664. package/template/tests/unit/features/FeatureLocalization.test.tsx +54 -0
  665. package/template/tests/unit/features/RouteError.test.tsx +40 -0
  666. package/template/tests/unit/features/auth/signIn/UserAuthForm.test.tsx +79 -0
  667. package/template/tests/unit/features/auth/signIn/__screenshots__/UserAuthForm.test.tsx/UserAuthForm-passes-validated-values-to-onSubmit-1.png +0 -0
  668. package/template/tests/unit/features/auth/signIn/__screenshots__/UserAuthForm.test.tsx/UserAuthForm-shows-validation-messages-when-submitting-an-empty-form-1.png +0 -0
  669. package/template/tests/unit/files/fileHooks.test.tsx +130 -0
  670. package/template/tests/unit/files/files.test.ts +112 -0
  671. package/template/tests/unit/lib/accessControl.test.ts +69 -0
  672. package/template/tests/unit/locale/locale.test.tsx +90 -0
  673. package/template/tests/unit/observability/browser.test.ts +48 -0
  674. package/template/tests/unit/observability/observer.test.ts +115 -0
  675. package/template/tests/unit/optionalEditors/__screenshots__/useOptionalEditor.test.tsx/useOptionalEditor-fails-permission-precheck-before-loading-the-project-SDK-1.png +0 -0
  676. package/template/tests/unit/optionalEditors/__screenshots__/useOptionalEditor.test.tsx/useOptionalEditor-mounts-a-route-scoped-SDK-into-the-dedicated-host-with-permission-1.png +0 -0
  677. package/template/tests/unit/optionalEditors/optionalEditors.test.ts +313 -0
  678. package/template/tests/unit/optionalEditors/useOptionalEditor.test.tsx +141 -0
  679. package/template/tests/unit/realtimeCollaboration/collaboration.test.ts +240 -0
  680. package/template/tests/unit/realtimeCollaboration/useRealtimeCollaboration.test.tsx +115 -0
  681. package/template/tests/unit/reporting/reporting.test.ts +195 -0
  682. package/template/tests/unit/reporting/reportingHooks.test.tsx +203 -0
  683. package/template/tests/unit/router/authLifecycle.test.ts +55 -0
  684. package/template/tests/unit/router/navigation.test.ts +55 -0
  685. package/template/tests/unit/router/redirects.test.ts +22 -0
  686. package/template/tests/unit/scaffoldFeatureTemplate/featureTemplate.test.ts +42 -0
  687. package/template/tests/unit/scaffoldFeatureTemplate/publicContract.test.ts +28 -0
  688. package/template/tests/unit/scaffoldFeatureTemplate/queries.test.tsx +289 -0
  689. package/template/tests/unit/stores/authStore.test.ts +128 -0
  690. package/template/tests/unit/stores/uiPreferenceStore.test.ts +56 -0
  691. package/template/tests/unit/tenantWorkspace/tenantWorkspace.test.tsx +261 -0
  692. package/template/tools/bundle/budgets.json +48 -0
  693. package/template/tools/bundle/check.mjs +307 -0
  694. package/template/tools/component-governance/check.mjs +703 -0
  695. package/template/tools/component-governance/manifest.json +112 -0
  696. package/template/tools/deployment/browser-smoke.mjs +76 -0
  697. package/template/tools/deployment/browser-smoke.sh +141 -0
  698. package/template/tools/openapi/generate.mjs +268 -0
  699. package/template/tools/openapi/templates/README.md +14 -0
  700. package/template/tools/openapi/templates/base/README.md +7 -0
  701. package/template/tools/openapi/templates/base/data-contracts.eta +44 -0
  702. package/template/tools/openapi/templates/base/http-client.eta +3 -0
  703. package/template/tools/openapi/templates/base/http-clients/axios-http-client.eta +132 -0
  704. package/template/tools/openapi/templates/base/http-clients/fetch-http-client.eta +220 -0
  705. package/template/tools/openapi/templates/base/route-docs.eta +31 -0
  706. package/template/tools/openapi/templates/base/route-name.eta +43 -0
  707. package/template/tools/openapi/templates/base/route-type.eta +22 -0
  708. package/template/tools/openapi/templates/default/README.md +7 -0
  709. package/template/tools/openapi/templates/default/api.eta +67 -0
  710. package/template/tools/openapi/templates/default/http-client.eta +137 -0
  711. package/template/tools/openapi/templates/default/procedure-call.eta +99 -0
  712. package/template/tools/openapi/templates/default/route-docs.eta +40 -0
  713. package/template/tools/openapi/templates/default/route-types.eta +28 -0
  714. package/template/tools/openapi/templates/modular/README.md +7 -0
  715. package/template/tools/openapi/templates/modular/api.eta +28 -0
  716. package/template/tools/openapi/templates/modular/procedure-call.eta +99 -0
  717. package/template/tools/openapi/templates/modular/route-types.eta +18 -0
  718. package/template/tools/release/artifact.mjs +258 -0
  719. package/template/tools/scaffold/add-capability.mjs +409 -0
  720. package/template/tools/scaffold/capability-catalog.json +163 -0
  721. package/template/tools/scaffold/check.mjs +326 -0
  722. package/template/tools/scaffold/create-feature.mjs +444 -0
  723. package/template/tools/scaffold/create-project.mjs +482 -0
  724. package/template/tools/scaffold/init.example.json +64 -0
  725. package/template/tools/scaffold/init.mjs +419 -0
  726. package/template/tools/scaffold/lockfile.mjs +193 -0
  727. package/template/tools/scaffold/templates/feature/index.ts +19 -0
  728. package/template/tools/scaffold/templates/feature/model.ts +142 -0
  729. package/template/tools/scaffold/templates/feature/queries.ts +154 -0
  730. package/template/tools/scaffold/templates/feature/repository.ts +206 -0
  731. package/template/tools/scaffold/templates/feature/types.ts +168 -0
  732. package/template/tools/scaffold/workspace-transaction.mjs +111 -0
  733. package/template/tsconfig.app.json +31 -0
  734. package/template/tsconfig.json +12 -0
  735. package/template/tsconfig.node.json +24 -0
  736. package/template/vite.config.ts +121 -0
@@ -0,0 +1,82 @@
1
+ import { queryOptions, type QueryClient } from '@tanstack/react-query'
2
+ import { fnResolveEnumCatalogScope } from './scope'
3
+ import type {
4
+ IEnumCatalog,
5
+ IEnumCatalogScope,
6
+ IEnumCatalogSource,
7
+ TEnumCatalogScopeInput,
8
+ } from './types'
9
+
10
+ const arrEnumCatalogQueryRoot: readonly ['enumCatalog'] = ['enumCatalog']
11
+ const nEnumCatalogStaleTimeMs = 5 * 60_000
12
+ const nEnumCatalogGcTimeMs = 30 * 60_000
13
+
14
+ /** 返回一个语言对应的稳定枚举目录查询 Key。 */
15
+ export function fnEnumCatalogQueryKey(
16
+ objScopeInput: TEnumCatalogScopeInput
17
+ ): readonly ['enumCatalog', IEnumCatalogScope] {
18
+ return ['enumCatalog', fnResolveEnumCatalogScope(objScopeInput)]
19
+ }
20
+
21
+ /** 创建完整枚举目录的 QueryClient 查询配置。 */
22
+ export function fnEnumCatalogQueryOptions(
23
+ objSource: IEnumCatalogSource,
24
+ objScopeInput: TEnumCatalogScopeInput
25
+ ) {
26
+ const objScope = fnResolveEnumCatalogScope(objScopeInput)
27
+ return queryOptions({
28
+ queryKey: fnEnumCatalogQueryKey(objScope),
29
+ queryFn: ({ signal: objSignal }) =>
30
+ objSource.fnLoadCatalog({
31
+ objScope,
32
+ objSignal,
33
+ strLocale: objScope.strLocale,
34
+ }),
35
+ staleTime: nEnumCatalogStaleTimeMs,
36
+ gcTime: nEnumCatalogGcTimeMs,
37
+ })
38
+ }
39
+
40
+ /** 在路由 Loader 或应用启动阶段确保指定语言目录已加载。 */
41
+ export function fnEnsureEnumCatalog(
42
+ objQueryClient: QueryClient,
43
+ objSource: IEnumCatalogSource,
44
+ objScopeInput: TEnumCatalogScopeInput = 'zh-CN'
45
+ ) {
46
+ return objQueryClient.ensureQueryData(
47
+ fnEnumCatalogQueryOptions(objSource, objScopeInput)
48
+ )
49
+ }
50
+
51
+ /** 从 QueryClient 同步读取指定语言已缓存的完整枚举目录。 */
52
+ export function fnGetCachedEnumCatalog(
53
+ objQueryClient: QueryClient,
54
+ objScopeInput: TEnumCatalogScopeInput = 'zh-CN'
55
+ ): IEnumCatalog | undefined {
56
+ return objQueryClient.getQueryData<IEnumCatalog>(
57
+ fnEnumCatalogQueryKey(objScopeInput)
58
+ )
59
+ }
60
+
61
+ /** 枚举维护完成后统一失效一个语言或全部语言的目录缓存。 */
62
+ export function fnInvalidateEnumCatalog(
63
+ objQueryClient: QueryClient,
64
+ objScopeInput?: TEnumCatalogScopeInput
65
+ ) {
66
+ if (!objScopeInput) {
67
+ return objQueryClient.invalidateQueries({
68
+ queryKey: arrEnumCatalogQueryRoot,
69
+ })
70
+ }
71
+
72
+ if (typeof objScopeInput === 'string') {
73
+ return objQueryClient.invalidateQueries({
74
+ queryKey: [arrEnumCatalogQueryRoot[0], { strLocale: objScopeInput }],
75
+ })
76
+ }
77
+
78
+ return objQueryClient.invalidateQueries({
79
+ exact: true,
80
+ queryKey: fnEnumCatalogQueryKey(objScopeInput),
81
+ })
82
+ }
@@ -0,0 +1,58 @@
1
+ import { EnumCatalogError } from './errors'
2
+ import type {
3
+ IEnumCatalogScope,
4
+ IEnumCatalogScopeContext,
5
+ TEnumCatalogScopeInput,
6
+ TEnumLocale,
7
+ } from './types'
8
+
9
+ function fnNormalizeScopeValue(strValue: string | undefined) {
10
+ const strNormalizedValue = strValue?.trim()
11
+ return strNormalizedValue || undefined
12
+ }
13
+
14
+ /** 创建不含凭据、可安全用于 Query Key 的枚举目录作用域。 */
15
+ export function fnCreateEnumCatalogScope(
16
+ strLocale: TEnumLocale,
17
+ objContext: IEnumCatalogScopeContext = {}
18
+ ): IEnumCatalogScope {
19
+ if (!strLocale) {
20
+ throw new EnumCatalogError(
21
+ 'INVALID_SCOPE',
22
+ '枚举目录作用域必须包含显示语言。'
23
+ )
24
+ }
25
+ if (
26
+ objContext.nSessionGeneration !== undefined &&
27
+ (!Number.isInteger(objContext.nSessionGeneration) ||
28
+ objContext.nSessionGeneration < 0)
29
+ ) {
30
+ throw new EnumCatalogError(
31
+ 'INVALID_SCOPE',
32
+ '枚举目录作用域的会话版本必须是非负整数。'
33
+ )
34
+ }
35
+
36
+ const strNamespace = fnNormalizeScopeValue(objContext.strNamespace)
37
+ const strTenantId = fnNormalizeScopeValue(objContext.strTenantId)
38
+ const strWorkspaceId = fnNormalizeScopeValue(objContext.strWorkspaceId)
39
+
40
+ return Object.freeze({
41
+ ...(objContext.nSessionGeneration !== undefined
42
+ ? { nSessionGeneration: objContext.nSessionGeneration }
43
+ : {}),
44
+ ...(strNamespace ? { strNamespace } : {}),
45
+ ...(strTenantId ? { strTenantId } : {}),
46
+ ...(strWorkspaceId ? { strWorkspaceId } : {}),
47
+ strLocale,
48
+ })
49
+ }
50
+
51
+ /** 将兼容的语言或完整作用域输入标准化为稳定作用域。 */
52
+ export function fnResolveEnumCatalogScope(
53
+ objScope: TEnumCatalogScopeInput
54
+ ): IEnumCatalogScope {
55
+ return typeof objScope === 'string'
56
+ ? fnCreateEnumCatalogScope(objScope)
57
+ : fnCreateEnumCatalogScope(objScope.strLocale, objScope)
58
+ }
@@ -0,0 +1,251 @@
1
+ import type { ReactNode } from 'react'
2
+ import type { TAppLocale } from '@/locale/types'
3
+
4
+ /** 枚举目录支持的显示语言。 */
5
+ export type TEnumLocale = TAppLocale
6
+
7
+ /** 业务字段可用于查找枚举显示值的基础类型。 */
8
+ export type TEnumValue = boolean | number | string
9
+
10
+ /** 枚举目录错误的稳定分类。 */
11
+ export type TEnumCatalogErrorCode =
12
+ | 'DUPLICATE_LABEL'
13
+ | 'DUPLICATE_VALUE'
14
+ | 'INVALID_OPTION'
15
+ | 'INVALID_RESPONSE'
16
+ | 'INVALID_SCOPE'
17
+ | 'LOCALE_MISMATCH'
18
+
19
+ /** 除语言外用于隔离枚举缓存的业务作用域。 */
20
+ export interface IEnumCatalogScopeContext {
21
+ /** 登录、退出或授权上下文变化时递增的会话版本。 */
22
+ readonly nSessionGeneration?: number
23
+ /** 产品模块或后端枚举命名空间。 */
24
+ readonly strNamespace?: string
25
+ /** 当前租户标识。 */
26
+ readonly strTenantId?: string
27
+ /** 当前组织、项目或工作空间标识。 */
28
+ readonly strWorkspaceId?: string
29
+ }
30
+
31
+ /** 一个枚举目录请求与缓存的完整身份。 */
32
+ export interface IEnumCatalogScope extends IEnumCatalogScopeContext {
33
+ /** 当前目录使用的显示语言。 */
34
+ readonly strLocale: TEnumLocale
35
+ }
36
+
37
+ /** 查询 API 接受完整作用域,也兼容仅传语言的简单调用。 */
38
+ export type TEnumCatalogScopeInput = IEnumCatalogScope | TEnumLocale
39
+
40
+ /** 后端枚举扩展信息允许携带的 JSON 值。 */
41
+ export type TEnumMetadataValue =
42
+ | boolean
43
+ | number
44
+ | string
45
+ | null
46
+ | readonly TEnumMetadataValue[]
47
+ | { readonly [strKey: string]: TEnumMetadataValue }
48
+
49
+ /** 后端枚举目录中的原始选项;字段保持 Swagger 数据契约命名。 */
50
+ export interface IEnumOptionPayload {
51
+ /** 可选颜色标识,可由具体展示组件解释为设计系统色调。 */
52
+ color?: string
53
+ /** 可选补充说明,用于提示或无障碍描述。 */
54
+ description?: string
55
+ /** 是否保留展示但禁止产生新的选择。 */
56
+ disabled?: boolean
57
+ /** 面向当前语言的显示文本。 */
58
+ label?: string
59
+ /** 不参与全局基础逻辑的后端扩展信息。 */
60
+ metadata?: Readonly<Record<string, TEnumMetadataValue>>
61
+ /** 升序排列权重。 */
62
+ sortOrder?: number
63
+ /** 跨语言稳定、用于提交和比较的枚举值。 */
64
+ value?: TEnumValue
65
+ }
66
+
67
+ /** 后端统一枚举接口的原始目录;字段保持 Swagger 数据契约命名。 */
68
+ export interface IEnumCatalogPayload {
69
+ /** 以稳定枚举 Key 为索引的选项集合。 */
70
+ enums?: Readonly<Record<string, readonly IEnumOptionPayload[] | undefined>>
71
+ /** 本次目录响应的显示语言。 */
72
+ locale?: string
73
+ /** 后端目录版本,用于诊断与刷新确认。 */
74
+ version?: string
75
+ }
76
+
77
+ /** 经过运行时校验、可安全交给 Feature 使用的枚举选项。 */
78
+ export interface IEnumOption {
79
+ /** 可选颜色标识;组件应显式映射到自身视觉语义。 */
80
+ readonly color?: string
81
+ /** 可选补充说明。 */
82
+ readonly description?: string
83
+ /** 是否保留展示但禁止产生新的选择。 */
84
+ readonly disabled: boolean
85
+ /** 面向当前语言的显示文本。 */
86
+ readonly label: string
87
+ /** 只读的后端扩展信息。 */
88
+ readonly metadata?: Readonly<Record<string, TEnumMetadataValue>>
89
+ /** 升序排列权重。 */
90
+ readonly sortOrder: number
91
+ /** 跨语言稳定的枚举值。 */
92
+ readonly value: TEnumValue
93
+ }
94
+
95
+ /** 单个语言下已标准化的完整枚举目录。 */
96
+ export interface IEnumCatalog {
97
+ /** 以稳定枚举 Key 为索引的只读选项集合。 */
98
+ readonly enums: ReadonlyMap<string, readonly IEnumOption[]>
99
+ /** 已加载目录的显示语言。 */
100
+ readonly locale: TEnumLocale
101
+ /** 后端返回的目录版本。 */
102
+ readonly version: string
103
+ }
104
+
105
+ /** 完整枚举目录展开后的单个条目。 */
106
+ export interface IEnumCatalogEntry {
107
+ /** 当前枚举下已按 `sortOrder` 排序的只读选项。 */
108
+ readonly arrOptions: readonly IEnumOption[]
109
+ /** 后端定义的稳定枚举 Key。 */
110
+ readonly strKey: string
111
+ }
112
+
113
+ /** 后端枚举请求所需的运行时上下文。 */
114
+ export interface IEnumCatalogRequestContext {
115
+ /** 本次请求与缓存使用的完整业务作用域。 */
116
+ readonly objScope: IEnumCatalogScope
117
+ /** QueryClient 取消或替换请求时触发的取消信号。 */
118
+ readonly objSignal: AbortSignal
119
+ /** 请求使用的显示语言。 */
120
+ readonly strLocale: TEnumLocale
121
+ }
122
+
123
+ /** 由生成客户端实现的后端枚举请求函数。 */
124
+ export type TEnumCatalogRequest = (
125
+ objContext: IEnumCatalogRequestContext
126
+ ) => Promise<IEnumCatalogPayload | undefined>
127
+
128
+ /** 全局枚举系统依赖的后端数据源契约。 */
129
+ export interface IEnumCatalogSource {
130
+ /** 加载并返回一个语言下的完整、已校验目录。 */
131
+ fnLoadCatalog: (
132
+ objContext: IEnumCatalogRequestContext
133
+ ) => Promise<IEnumCatalog>
134
+ }
135
+
136
+ /** 全局枚举 Provider 的公共参数。 */
137
+ export interface IEnumCatalogProviderProps {
138
+ /** 是否允许发起目录请求,默认启用。 */
139
+ bIsEnabled?: boolean
140
+ /** 使用统一枚举能力的应用子树。 */
141
+ children: ReactNode
142
+ /** 租户、工作空间等非语言缓存作用域。 */
143
+ objScope?: IEnumCatalogScopeContext
144
+ /** 由 Swagger 生成客户端适配的后端数据源;未配置时不会发起请求。 */
145
+ objSource?: IEnumCatalogSource
146
+ /** 当前目录语言,默认 `zh-CN`。 */
147
+ strLocale?: TEnumLocale
148
+ }
149
+
150
+ /** 完整目录查询暴露给预加载与诊断界面的状态。 */
151
+ export interface IUseEnumCatalogResult {
152
+ /** 完整目录按 Key 排序后展开的只读条目。 */
153
+ arrEntries: readonly IEnumCatalogEntry[]
154
+ /** 完整目录中按字典序排列的枚举 Key。 */
155
+ arrKeys: readonly string[]
156
+ /** 是否已经配置后端枚举数据源。 */
157
+ bIsConfigured: boolean
158
+ /** 当前是否允许发起目录请求。 */
159
+ bIsEnabled: boolean
160
+ /** 请求是否失败。 */
161
+ bIsError: boolean
162
+ /** 包含首次请求和后台刷新的所有请求状态。 */
163
+ bIsFetching: boolean
164
+ /** 首次目录请求是否仍在进行。 */
165
+ bIsLoading: boolean
166
+ /** 已有数据时是否正在后台刷新。 */
167
+ bIsRefetching: boolean
168
+ /** 最近一次成功更新的时间戳,尚未成功时为 `0`。 */
169
+ nUpdatedAt: number
170
+ /** 请求失败时的标准 Error。 */
171
+ objError: Error | null
172
+ /** 已加载目录;尚未成功时为空。 */
173
+ objCatalog: IEnumCatalog | undefined
174
+ /** 当前请求与缓存使用的完整业务作用域。 */
175
+ objScope: IEnumCatalogScope
176
+ /** 当前请求语言。 */
177
+ strLocale: TEnumLocale
178
+ /** 后端目录版本;尚未加载时为空。 */
179
+ strVersion: string | null
180
+ /** 根据枚举 Key 和值读取显示文本,未知值回退为原始字符串。 */
181
+ fnGetLabel: (
182
+ strEnumKey: string,
183
+ objValue: TEnumValue | null | undefined
184
+ ) => string
185
+ /** 批量读取显示文本,保持输入顺序和重复项。 */
186
+ fnGetLabels: (
187
+ strEnumKey: string,
188
+ arrValues: readonly TEnumValue[]
189
+ ) => readonly string[]
190
+ /** 根据枚举 Key 读取已排序的完整选项。 */
191
+ fnGetOptions: (strEnumKey: string) => readonly IEnumOption[]
192
+ /** 批量读取已存在的选项,保持输入顺序并忽略未知值。 */
193
+ fnGetOptionsByValues: (
194
+ strEnumKey: string,
195
+ arrValues: readonly TEnumValue[]
196
+ ) => readonly IEnumOption[]
197
+ /** 根据枚举 Key 和显示文本反查稳定值。 */
198
+ fnGetValue: (strEnumKey: string, strLabel: string) => TEnumValue | undefined
199
+ /** 根据枚举 Key 读取所有稳定值。 */
200
+ fnGetValues: (strEnumKey: string) => readonly TEnumValue[]
201
+ /** 判断完整目录中是否存在指定枚举 Key。 */
202
+ fnHasKey: (strEnumKey: string) => boolean
203
+ /** 重新请求当前语言目录。 */
204
+ fnRefetch: () => Promise<void>
205
+ }
206
+
207
+ /** Feature 按枚举 Key 消费时获得的标准结果。 */
208
+ export interface IUseEnumResult {
209
+ /** 已按 `sortOrder` 排序的只读选项。 */
210
+ arrOptions: readonly IEnumOption[]
211
+ /** 是否已经配置后端枚举数据源。 */
212
+ bIsConfigured: boolean
213
+ /** 当前是否允许发起目录请求。 */
214
+ bIsEnabled: boolean
215
+ /** 目录请求是否失败。 */
216
+ bIsError: boolean
217
+ /** 包含首次请求和后台刷新的所有请求状态。 */
218
+ bIsFetching: boolean
219
+ /** 目录已加载但没有找到当前枚举 Key。 */
220
+ bIsMissing: boolean
221
+ /** 首次目录请求是否仍在进行。 */
222
+ bIsLoading: boolean
223
+ /** 已有数据时是否正在后台刷新。 */
224
+ bIsRefetching: boolean
225
+ /** 最近一次成功更新的时间戳,尚未成功时为 `0`。 */
226
+ nUpdatedAt: number
227
+ /** 请求失败时的标准 Error。 */
228
+ objError: Error | null
229
+ /** 当前请求与缓存使用的完整业务作用域。 */
230
+ objScope: IEnumCatalogScope
231
+ /** 返回值对应的目录语言。 */
232
+ strLocale: TEnumLocale
233
+ /** 后端目录版本;尚未加载时为空。 */
234
+ strVersion: string | null
235
+ /** 判断值是否存在于当前枚举。 */
236
+ fnHasValue: (objValue: TEnumValue | null | undefined) => boolean
237
+ /** 根据值读取完整选项,不存在时返回 `null`。 */
238
+ fnGetOption: (objValue: TEnumValue | null | undefined) => IEnumOption | null
239
+ /** 根据值读取显示文本,未知值回退为原始字符串。 */
240
+ fnGetLabel: (objValue: TEnumValue | null | undefined) => string
241
+ /** 批量读取显示文本,保持输入顺序和重复项。 */
242
+ fnGetLabels: (arrValues: readonly TEnumValue[]) => readonly string[]
243
+ /** 批量读取已存在的选项,保持输入顺序并忽略未知值。 */
244
+ fnGetOptionsByValues: (
245
+ arrValues: readonly TEnumValue[]
246
+ ) => readonly IEnumOption[]
247
+ /** 根据显示文本反查稳定值。 */
248
+ fnGetValue: (strLabel: string) => TEnumValue | undefined
249
+ /** 重新请求当前语言的完整枚举目录。 */
250
+ fnRefetch: () => Promise<void>
251
+ }
@@ -0,0 +1,198 @@
1
+ import { fnCaptureError } from '@/observability'
2
+ import axios, { AxiosError, type AxiosResponse } from 'axios'
3
+ import { ApiError } from '@/api/ApiError'
4
+ import type { TApiErrorKind } from '@/api/types'
5
+ import { fnResolveResponseRequestId } from './requestId'
6
+ import type { IApiHookOptions } from './types'
7
+
8
+ type TErrorPayload = Record<string, unknown>
9
+ const nMaxDisplayMessageLength = 500
10
+
11
+ async function fnResolveBlobPayload(objPayload: unknown) {
12
+ if (!(objPayload instanceof Blob)) return objPayload
13
+
14
+ try {
15
+ return JSON.parse(await objPayload.text()) as unknown
16
+ } catch {
17
+ return objPayload
18
+ }
19
+ }
20
+
21
+ function fnReadPayloadString(objPayload: TErrorPayload, strKey: string) {
22
+ const objValue = objPayload[strKey]
23
+ return typeof objValue === 'string' || typeof objValue === 'number'
24
+ ? String(objValue)
25
+ : null
26
+ }
27
+
28
+ function fnIsErrorPayload(objPayload: unknown): objPayload is TErrorPayload {
29
+ return (
30
+ typeof objPayload === 'object' &&
31
+ objPayload !== null &&
32
+ !Array.isArray(objPayload) &&
33
+ !(objPayload instanceof Blob)
34
+ )
35
+ }
36
+
37
+ function fnNormalizeDisplayMessage(strMessage: string, strFallback: string) {
38
+ const strNormalized = Array.from(strMessage)
39
+ .map((strCharacter) => {
40
+ const nCodePoint = strCharacter.codePointAt(0) ?? 0
41
+ return nCodePoint <= 31 || nCodePoint === 127 ? ' ' : strCharacter
42
+ })
43
+ .join('')
44
+ .trim()
45
+ if (!strNormalized || /^\s*<(?:!doctype|html)/i.test(strNormalized)) {
46
+ return strFallback
47
+ }
48
+ return strNormalized.slice(0, nMaxDisplayMessageLength)
49
+ }
50
+
51
+ function fnNormalizeErrorCode(strCode: string | null, strFallback: string) {
52
+ const strNormalized = strCode?.trim() ?? ''
53
+ return /^[a-z0-9._:-]{1,128}$/i.test(strNormalized)
54
+ ? strNormalized
55
+ : strFallback
56
+ }
57
+
58
+ function fnGetErrorKind(objError: AxiosError): TApiErrorKind {
59
+ if (objError.response) return 'http'
60
+ if (['ECONNABORTED', 'ETIMEDOUT'].includes(objError.code ?? '')) {
61
+ return 'timeout'
62
+ }
63
+ if (objError.code === 'ERR_NETWORK') return 'network'
64
+ if (objError.config) return 'client'
65
+ return 'unknown'
66
+ }
67
+
68
+ function fnIsRetriableApiError(strKind: TApiErrorKind, nStatus?: number) {
69
+ if (strKind === 'network' || strKind === 'timeout') return true
70
+ return nStatus === 408 || nStatus === 429 || (nStatus ?? 0) >= 500
71
+ }
72
+
73
+ function fnGetFallbackMessage(objError: AxiosError, strKind: TApiErrorKind) {
74
+ if (strKind === 'network') return '网络连接异常,请稍后重试'
75
+ if (strKind === 'timeout') return '请求超时,请稍后重试'
76
+ if (objError.code === 'ERR_UNAUTHORIZED') return '登录状态已失效,请重新登录'
77
+ return fnNormalizeDisplayMessage(objError.message, '请求失败,请稍后重试')
78
+ }
79
+
80
+ function fnGetErrorMessage(
81
+ objResponse: AxiosResponse | undefined,
82
+ objPayload: unknown,
83
+ strFallback: string
84
+ ) {
85
+ if (!objResponse) return strFallback
86
+ if (typeof objPayload === 'string') {
87
+ return fnNormalizeDisplayMessage(
88
+ objPayload,
89
+ objResponse.statusText || `HTTP ${objResponse.status}`
90
+ )
91
+ }
92
+ if (!fnIsErrorPayload(objPayload)) {
93
+ return objResponse.statusText || `HTTP ${objResponse.status}`
94
+ }
95
+
96
+ const strCode =
97
+ fnReadPayloadString(objPayload, 'rspCode') ??
98
+ fnReadPayloadString(objPayload, 'code') ??
99
+ String(objResponse.status)
100
+ const strMessage =
101
+ fnReadPayloadString(objPayload, 'msg') ??
102
+ fnReadPayloadString(objPayload, 'message') ??
103
+ fnReadPayloadString(objPayload, 'detail') ??
104
+ fnReadPayloadString(objPayload, 'title')
105
+ const strError = fnReadPayloadString(objPayload, 'error')
106
+
107
+ return fnNormalizeDisplayMessage(
108
+ strMessage ?? `${strCode}${strError ? ` ${strError}` : ''}`,
109
+ objResponse.statusText || `HTTP ${objResponse.status}`
110
+ )
111
+ }
112
+
113
+ function fnGetPayloadDetails(objPayload: unknown) {
114
+ if (!fnIsErrorPayload(objPayload)) return undefined
115
+ return objPayload.details ?? objPayload.errors
116
+ }
117
+
118
+ function fnGetPayloadRequestId(objPayload: unknown) {
119
+ if (!fnIsErrorPayload(objPayload)) return undefined
120
+ return (
121
+ fnReadPayloadString(objPayload, 'requestId') ??
122
+ fnReadPayloadString(objPayload, 'traceId')
123
+ )
124
+ }
125
+
126
+ function fnGetErrorCode(
127
+ objError: AxiosError,
128
+ objPayload: unknown,
129
+ nStatus?: number
130
+ ) {
131
+ const strPayloadCode = fnIsErrorPayload(objPayload)
132
+ ? (fnReadPayloadString(objPayload, 'rspCode') ??
133
+ fnReadPayloadString(objPayload, 'code') ??
134
+ fnReadPayloadString(objPayload, 'type'))
135
+ : null
136
+ return fnNormalizeErrorCode(
137
+ strPayloadCode,
138
+ nStatus ? `HTTP_${nStatus}` : (objError.code ?? 'UNKNOWN_ERROR')
139
+ )
140
+ }
141
+
142
+ export function fnCreateErrorHook(objOptions: IApiHookOptions = {}) {
143
+ return async (objReason: unknown) => {
144
+ if (axios.isCancel(objReason)) return Promise.reject(objReason)
145
+
146
+ const objError = axios.isAxiosError(objReason)
147
+ ? objReason
148
+ : new AxiosError(
149
+ objReason instanceof Error ? objReason.message : String(objReason)
150
+ )
151
+ const objResponse = objError.response
152
+ const objPayload = await fnResolveBlobPayload(objResponse?.data)
153
+ const nStatus = objResponse?.status
154
+ const strKind = fnGetErrorKind(objError)
155
+ const strFallbackMessage = fnGetFallbackMessage(objError, strKind)
156
+ const objApiError = new ApiError({
157
+ bRetriable: fnIsRetriableApiError(strKind, nStatus),
158
+ nStatus,
159
+ objDetails: fnGetPayloadDetails(objPayload),
160
+ strCode: fnGetErrorCode(objError, objPayload, nStatus),
161
+ strKind,
162
+ strMessage: fnGetErrorMessage(
163
+ objResponse,
164
+ objPayload,
165
+ strFallbackMessage
166
+ ),
167
+ strRequestId: fnResolveResponseRequestId(
168
+ objResponse,
169
+ fnGetPayloadRequestId(objPayload),
170
+ objError.config?.strRequestId
171
+ ),
172
+ })
173
+
174
+ objError.config?.fnProgress?.(false)
175
+
176
+ fnCaptureError(objApiError, {
177
+ strName: 'api.request_failed',
178
+ strSource: 'api',
179
+ objAttributes: {
180
+ bRetriable: objApiError.bRetriable,
181
+ nStatus: objApiError.nStatus ?? null,
182
+ strCode: objApiError.strCode,
183
+ strKind: objApiError.strKind,
184
+ strRequestId: objApiError.strRequestId ?? null,
185
+ },
186
+ })
187
+
188
+ if (nStatus === 401 || objError.code === 'ERR_UNAUTHORIZED') {
189
+ await objOptions.fnOnUnauthorized?.()
190
+ }
191
+
192
+ if (objError.config?.bShowError !== false) {
193
+ await objOptions.fnOnError?.(objApiError)
194
+ }
195
+
196
+ return Promise.reject(objApiError)
197
+ }
198
+ }
@@ -0,0 +1,4 @@
1
+ export { fnCreateErrorHook } from './error'
2
+ export { fnCreateRequestHook } from './request'
3
+ export { fnCreateResponseHook } from './response'
4
+ export type { IApiHookOptions, TMaybePromise } from './types'
@@ -0,0 +1,99 @@
1
+ import { AxiosError, isCancel, type InternalAxiosRequestConfig } from 'axios'
2
+ import { fnIsSuccessfulHttpStatus } from '@/api/clients/httpStatus'
3
+ import { fnNormalizeIdempotencyKey } from '@/api/idempotency/key'
4
+ import { fnEnsureRequestId } from './requestId'
5
+ import type { IApiHookOptions } from './types'
6
+
7
+ const arrDefaultAnonymousPaths = ['/login', '/refresh-token']
8
+
9
+ function fnIsAnonymousRequest(
10
+ strUrl: string,
11
+ arrAnonymousPaths: readonly string[]
12
+ ) {
13
+ let strPathname: string
14
+
15
+ try {
16
+ strPathname = new URL(strUrl, 'http://localhost').pathname
17
+ } catch {
18
+ return false
19
+ }
20
+
21
+ return arrAnonymousPaths.some((strPath) => {
22
+ const strNormalizedPath = strPath.startsWith('/') ? strPath : `/${strPath}`
23
+ return (
24
+ strPathname === strNormalizedPath ||
25
+ strPathname.endsWith(strNormalizedPath)
26
+ )
27
+ })
28
+ }
29
+
30
+ function fnCreateUnauthorizedRequestError(
31
+ objConfig: InternalAxiosRequestConfig
32
+ ) {
33
+ return new AxiosError(
34
+ 'Authentication is required before sending this request.',
35
+ 'ERR_UNAUTHORIZED',
36
+ objConfig
37
+ )
38
+ }
39
+
40
+ export function fnCreateRequestHook(objOptions: IApiHookOptions = {}) {
41
+ let objRefreshPromise: Promise<string | null> | null = null
42
+
43
+ return async (objConfig: InternalAxiosRequestConfig) => {
44
+ objConfig.validateStatus = fnIsSuccessfulHttpStatus
45
+ fnEnsureRequestId(objConfig, objOptions.fnCreateRequestId)
46
+ if (objConfig.strIdempotencyKey) {
47
+ objConfig.headers.set(
48
+ 'Idempotency-Key',
49
+ fnNormalizeIdempotencyKey(objConfig.strIdempotencyKey)
50
+ )
51
+ }
52
+ objConfig.fnProgress?.(true)
53
+
54
+ if (objConfig.fnBeforeRequest) {
55
+ objConfig.fnBeforeRequest(objConfig)
56
+ return objConfig
57
+ }
58
+
59
+ const strUrl = objConfig.url ?? ''
60
+ const arrAnonymousPaths =
61
+ objOptions.arrAnonymousPaths ?? arrDefaultAnonymousPaths
62
+
63
+ if (fnIsAnonymousRequest(strUrl, arrAnonymousPaths)) {
64
+ return objConfig
65
+ }
66
+
67
+ let strAccessToken = (await objOptions.fnGetAccessToken?.()) ?? null
68
+ const bIsExpired = (await objOptions.fnIsAccessTokenExpired?.()) ?? false
69
+
70
+ if (bIsExpired) {
71
+ if (!objOptions.fnRefreshAccessToken) {
72
+ await objOptions.fnOnUnauthorized?.()
73
+ throw fnCreateUnauthorizedRequestError(objConfig)
74
+ }
75
+
76
+ objRefreshPromise ??= objOptions.fnRefreshAccessToken().finally(() => {
77
+ objRefreshPromise = null
78
+ })
79
+
80
+ try {
81
+ strAccessToken = await objRefreshPromise
82
+ } catch (objError) {
83
+ if (!isCancel(objError)) await objOptions.fnOnUnauthorized?.()
84
+ throw objError
85
+ }
86
+
87
+ if (!strAccessToken) {
88
+ await objOptions.fnOnUnauthorized?.()
89
+ throw fnCreateUnauthorizedRequestError(objConfig)
90
+ }
91
+ }
92
+
93
+ if (strAccessToken) {
94
+ objConfig.headers.set('Authorization', `Bearer ${strAccessToken}`)
95
+ }
96
+
97
+ return objConfig
98
+ }
99
+ }