@oj-module/cli 0.2.64 → 0.2.67

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 (369) hide show
  1. package/bin/.oj-version +1 -0
  2. package/bin/oj +4 -0
  3. package/devkit/README.md +18 -4
  4. package/devkit/SKILL.md +35 -3
  5. package/devkit/framework-dev.md +22 -11
  6. package/devkit/manual.md +161 -68
  7. package/devkit/menu-rules.md +4 -1
  8. package/devkit/publish-walkthrough.md +110 -37
  9. package/devkit/wecom-internal-app.md +7 -2
  10. package/devkit/wecom-multi-corp-links.md +163 -0
  11. package/package.json +3 -2
  12. package/shell-dist/assets/ahooks.2l850ymmh0.js +18 -0
  13. package/shell-dist/assets/antd-es-locale-zh_CN.1gjjsvxbf0.js +1 -0
  14. package/shell-dist/assets/antd-img-crop.196rkty480.js +99 -0
  15. package/shell-dist/assets/antd-locale-en_US.561tozx860.js +1 -0
  16. package/shell-dist/assets/antd-locale-zh_CN.1cmpmgzh70.js +1 -0
  17. package/shell-dist/assets/antd.uw1coq15l0.js +348 -0
  18. package/shell-dist/assets/clsx.jotilrt2e0.js +1 -0
  19. package/shell-dist/assets/contract-errors.2o17vz9u50.js +1 -0
  20. package/shell-dist/assets/contract.3h327o3mj0.js +57 -0
  21. package/shell-dist/assets/cssinjs.atgmhan7m0.js +3 -0
  22. package/shell-dist/assets/dayjs-plugin-advancedFormat.3vsyd2eis0.js +1 -0
  23. package/shell-dist/assets/dayjs-plugin-customParseFormat.13xhghv1d0.js +1 -0
  24. package/shell-dist/assets/dayjs-plugin-isoWeek.1fn1tw82p0.js +1 -0
  25. package/shell-dist/assets/dayjs-plugin-localeData.2rwbjp9nk0.js +1 -0
  26. package/shell-dist/assets/dayjs-plugin-quarterOfYear.2oqo1lcx80.js +1 -0
  27. package/shell-dist/assets/dayjs-plugin-relativeTime.2pqs3et4y0.js +1 -0
  28. package/shell-dist/assets/dayjs-plugin-weekOfYear.gvn9iph080.js +1 -0
  29. package/shell-dist/assets/dayjs-plugin-weekYear.2u78l3ex10.js +1 -0
  30. package/shell-dist/assets/dayjs-plugin-weekday.2d56a4tml0.js +1 -0
  31. package/shell-dist/assets/dayjs.pa60l6wjo0.js +1 -0
  32. package/shell-dist/assets/dnd-kit-core.1xyreig6r0.js +5 -0
  33. package/shell-dist/assets/dnd-kit-sortable.s94qciuft0.js +1 -0
  34. package/shell-dist/assets/dnd-kit-utilities.1umw4xphb0.js +1 -0
  35. package/shell-dist/assets/i18next.33zqofapj0.js +1 -0
  36. package/shell-dist/assets/icons-es-components-Context.365qmflwg0.js +1 -0
  37. package/shell-dist/assets/icons.159wjwals0.js +57 -0
  38. package/shell-dist/assets/{index-xZhmujjM.js → index.6alqyx6ae0.js} +21 -1
  39. package/shell-dist/assets/jsx-dev-runtime.3uibuc82f0.js +14 -0
  40. package/shell-dist/assets/jsx-runtime.h40xu4o5b0.js +14 -0
  41. package/shell-dist/assets/keepalive-for-react.xenu5vam70.js +1 -0
  42. package/shell-dist/assets/kit.37kr8ui390.js +1 -0
  43. package/shell-dist/assets/ky.1cgch7gu60.js +6 -0
  44. package/shell-dist/assets/motion-react.pjsxytvjs0.js +12 -0
  45. package/shell-dist/assets/motion.21tciqutg0.js +4 -0
  46. package/shell-dist/assets/nprogress.2nz76n9ny0.js +7 -0
  47. package/shell-dist/assets/ojm-dayjs-locale-zh-cn.3vr3beiyp0.js +9 -0
  48. package/shell-dist/assets/pinyin-pro.3v0mnxczn0.js +1 -0
  49. package/shell-dist/assets/pro-components.2kyot1vcl0.js +83 -0
  50. package/shell-dist/assets/react-countup.2x8idnr8y0.js +10 -0
  51. package/shell-dist/assets/react-dom-client.ick0v05ob0.js +43 -0
  52. package/shell-dist/assets/react-dom.2so9uxg3f0.js +22 -0
  53. package/shell-dist/assets/react-error-boundary.2dncdfj3b0.js +1 -0
  54. package/shell-dist/assets/react-i18next.auhvjhqv00.js +1 -0
  55. package/shell-dist/assets/react-jss.1ei6dr9e00.js +29 -0
  56. package/shell-dist/assets/react-query.3rln45ow00.js +1 -0
  57. package/shell-dist/assets/react-router-dom.3c6zld8h40.js +44 -0
  58. package/shell-dist/assets/react-router.2h9rebcv50.js +56 -0
  59. package/shell-dist/assets/react.1ew63mwts0.js +14 -0
  60. package/shell-dist/assets/runtime.2dgstpjsu0.js +21702 -0
  61. package/shell-dist/assets/simplebar-react.2g739uvai0.js +1 -0
  62. package/shell-dist/assets/spin-delay.yjeyj6iwp0.js +9 -0
  63. package/shell-dist/assets/tailwind-merge.125ehiqjw0.js +1 -0
  64. package/shell-dist/assets/use-sync-external-store-shim.1nz1pi9bb0.js +22 -0
  65. package/shell-dist/assets/zustand-middleware.1xaxjueme0.js +6 -0
  66. package/shell-dist/assets/zustand-react-shallow.pybayv1hx0.js +1 -0
  67. package/shell-dist/assets/zustand-react.9fsl9brxy0.js +1 -0
  68. package/shell-dist/assets/zustand-shallow.6cz0yyv9x0.js +1 -0
  69. package/shell-dist/assets/zustand-vanilla-shallow.3424monv50.js +1 -0
  70. package/shell-dist/assets/zustand-vanilla.1mo3ka3g30.js +1 -0
  71. package/shell-dist/assets/zustand.3gjgzlnqo0.js +1 -0
  72. package/shell-dist/index.html +67 -118
  73. package/shell-dist/versions.json +3 -3
  74. package/src/__tests__/publish-keygen.test.ts +157 -0
  75. package/src/__tests__/templates-migration-schema-parity.test.ts +540 -0
  76. package/src/__tests__/templates-schema-columns.test.ts +15 -2
  77. package/src/__tests__/templates-tenant-scope.test.ts +6 -2
  78. package/src/bundle.ts +8 -3
  79. package/src/cli.ts +17 -5
  80. package/src/dev.ts +15 -10
  81. package/src/esm-exports.ts +152 -70
  82. package/src/install.ts +11 -4
  83. package/src/keygen.ts +54 -0
  84. package/src/lifecycle/__tests__/bundle.test.ts +21 -3
  85. package/src/lifecycle/__tests__/fixtures/fixture-valid/api/src/demo-solution/manifest.yaml +1 -1
  86. package/src/lifecycle/__tests__/fixtures/fixture-valid/api/src/demo-solution/migrations/0001__init.sql +2 -2
  87. package/src/lifecycle/__tests__/fixtures/fixture-valid/api/src/demo-solution/schema.yaml +5 -2
  88. package/src/lifecycle/__tests__/fixtures/fixture-valid/manifest.yaml +1 -1
  89. package/src/lifecycle/__tests__/manifest-contract.test.ts +75 -3
  90. package/src/lifecycle/__tests__/smoke.test.ts +2 -2
  91. package/src/manifest-contract.ts +91 -8
  92. package/src/market/bootstrap.ts +26 -2
  93. package/src/market/command.ts +1 -0
  94. package/src/market/publish.ts +5 -1
  95. package/src/market/walkthrough.ts +24 -8
  96. package/src/shared-deps.ts +69 -19
  97. package/src/site-base.ts +4 -0
  98. package/src/site.ts +2 -0
  99. package/src/usage.ts +8 -4
  100. package/src/vendor.ts +5 -1
  101. package/templates/config.yaml +4 -2
  102. package/templates/init.include.yaml +8 -3
  103. package/templates/openapi.json +460 -1
  104. package/templates/src/app/api/_platform/_lifecycle/compensate.ts +136 -0
  105. package/templates/src/app/api/_platform/_lifecycle/installer.ts +71 -22
  106. package/templates/src/app/api/_platform/_lifecycle/lock.ts +23 -0
  107. package/templates/src/app/api/_platform/_lifecycle/steps/deploy-web.ts +28 -0
  108. package/templates/src/app/api/_platform/_lifecycle/steps/preflight.ts +46 -0
  109. package/templates/src/app/api/_platform/_lifecycle/steps/reload.ts +100 -36
  110. package/templates/src/app/api/_platform/_lifecycle/steps/smoke.ts +7 -15
  111. package/templates/src/app/api/_platform/_lifecycle/text-edit.ts +71 -19
  112. package/templates/src/app/api/_platform/_lifecycle/types.ts +26 -2
  113. package/templates/src/app/api/_platform/_lifecycle/uninstall.ts +93 -14
  114. package/templates/src/app/api/_platform/_shared/service/domain/settings.ts +8 -4
  115. package/templates/src/app/api/_platform/manifest.yaml +1 -0
  116. package/templates/src/app/api/_platform/market/api.ts +235 -10
  117. package/templates/src/app/api/_platform/migrations/0001__baseline.mysql.sql +178 -0
  118. package/templates/src/app/api/_platform/migrations/0001__baseline.pg.sql +173 -0
  119. package/templates/src/app/api/_platform/migrations/0001__baseline.sql +188 -0
  120. package/templates/src/app/api/_platform/migrations/0002__market_release.mysql.sql +17 -0
  121. package/templates/src/app/api/_platform/migrations/0002__market_release.pg.sql +16 -0
  122. package/templates/src/app/api/_platform/migrations/0002__market_release.sql +33 -0
  123. package/templates/src/app/api/_platform/schema.yaml +18 -0
  124. package/templates/src/app/api/_platform/seed.mysql.sql +10 -0
  125. package/templates/src/app/api/_platform/seed.pg.sql +10 -0
  126. package/templates/src/app/api/auth/_shared/wecom/client.ts +24 -4
  127. package/templates/src/app/api/home/migrations/0001__create_home_tables.mysql.sql +14 -0
  128. package/templates/src/app/api/home/migrations/0001__create_home_tables.pg.sql +14 -0
  129. package/templates/src/app/api/home/migrations/0002__tenant.pg.sql +4 -0
  130. package/templates/src/app/api/home/seed.mysql.sql +71 -0
  131. package/templates/src/app/api/home/seed.pg.sql +71 -0
  132. package/templates/src/app/api/notification/_shared/notify.ts +6 -6
  133. package/templates/src/app/api/notification/migrations/0001__create_notifications.mysql.sql +11 -0
  134. package/templates/src/app/api/notification/migrations/0001__create_notifications.pg.sql +11 -0
  135. package/templates/src/app/api/notification/migrations/0002__notifications_user.mysql.sql +8 -0
  136. package/templates/src/app/api/notification/migrations/0003__notifications_broadcast.mysql.sql +21 -0
  137. package/templates/src/app/api/notification/migrations/0003__notifications_broadcast.pg.sql +22 -0
  138. package/templates/src/app/api/notification/migrations/0004__notifications_broadcast_hidden.mysql.sql +10 -0
  139. package/templates/src/app/api/notification/migrations/0004__notifications_broadcast_hidden.pg.sql +11 -0
  140. package/templates/src/app/api/notification/migrations/0005__tenant.pg.sql +6 -0
  141. package/templates/src/app/api/notification/seed.mysql.sql +8 -0
  142. package/templates/src/app/api/notification/seed.pg.sql +11 -0
  143. package/templates/src/app/api/publish/_shared/identity.ts +69 -0
  144. package/templates/src/app/api/publish/api.ts +349 -0
  145. package/templates/src/app/api/publish/manifest.yaml +8 -0
  146. package/templates/src/app/api/publish/migrations/0001__publish_credential.mysql.sql +23 -0
  147. package/templates/src/app/api/publish/migrations/0001__publish_credential.pg.sql +23 -0
  148. package/templates/src/app/api/publish/migrations/0001__publish_credential.sql +39 -0
  149. package/templates/src/app/api/publish/schema.yaml +33 -0
  150. package/templates/src/app/api/system/login-methods/api.ts +2 -1
  151. package/templates/src/app/web/_platform/__client/api.schemas.ts +15 -0
  152. package/templates/src/app/web/_platform/__client/index.ts +25 -1
  153. package/templates/src/app/web/entry.ts +9 -5
  154. package/templates/src/app/web/home/pages/components/bar-chart.tsx +5 -3
  155. package/templates/src/app/web/home/pages/components/echarts-setup.ts +30 -0
  156. package/templates/src/app/web/home/pages/components/line-chart.tsx +5 -3
  157. package/templates/src/app/web/home/pages/components/pie-chart.tsx +6 -3
  158. package/templates/src/app/web/home/pages/index.tsx +3 -2
  159. package/templates/src/app/web/home/routes.ts +8 -2
  160. package/templates/src/app/web/login/locales/en-US.json +7 -1
  161. package/templates/src/app/web/login/locales/zh-CN.json +7 -1
  162. package/templates/src/app/web/login/pages/login.tsx +79 -86
  163. package/templates/src/app/web/login/routes.ts +54 -1
  164. package/templates/src/app/web/personal-center/locales/en-US.json +1 -0
  165. package/templates/src/app/web/personal-center/locales/zh-CN.json +1 -0
  166. package/templates/src/app/web/personal-center/pages/my-profile/index.tsx +5 -0
  167. package/templates/src/app/web/system/__client/api.schemas.ts +2 -1
  168. package/templates/src/app/web/system/locales/en-US.json +1 -8
  169. package/templates/src/app/web/system/locales/zh-CN.json +1 -8
  170. package/templates/src/app/web/system/pages/settings/index.tsx +17 -4
  171. package/templates/src/app/web/system/routes.ts +0 -6
  172. package/templates/src/oj-market/web/__tests__/CardGrid.test.tsx +33 -0
  173. package/templates/src/oj-market/web/__tests__/DetailDrawer.test.tsx +69 -0
  174. package/templates/src/oj-market/web/__tests__/marketClient.fake.ts +7 -1
  175. package/templates/src/oj-market/web/api/client.ts +3 -0
  176. package/templates/src/oj-market/web/api/defaultClient.ts +5 -0
  177. package/templates/src/oj-market/web/components/CardItem.tsx +44 -1
  178. package/templates/src/oj-market/web/components/DetailDrawer.tsx +17 -1
  179. package/templates/src/oj-market/web/entry.ts +31 -2
  180. package/templates/src/oj-market/web/locales/en-US.json +5 -1
  181. package/templates/src/oj-market/web/locales/zh-CN.json +5 -1
  182. package/templates/src/oj-market/web/publish/__client/api.schemas.ts +61 -0
  183. package/templates/src/oj-market/web/publish/__client/index.ts +164 -0
  184. package/templates/src/oj-market/web/publish/locales/en-US.json +80 -0
  185. package/templates/src/oj-market/web/publish/locales/zh-CN.json +80 -0
  186. package/templates/src/oj-market/web/publish/pages/history.tsx +112 -0
  187. package/templates/src/oj-market/web/publish/pages/index.tsx +196 -0
  188. package/templates/src/oj-market/web/publish/pages/model.ts +52 -0
  189. package/templates/src/oj-market/web/publish/pages/token-modal.tsx +82 -0
  190. package/templates/src/oj-market/web/publish/routes.ts +41 -0
  191. package/templates/src/oj-market/web/types.ts +30 -0
  192. package/templates/tests/lifecycle/compensate.spec.ts +207 -0
  193. package/templates/tests/lifecycle/deploy-smoke.spec.ts +38 -14
  194. package/templates/tests/lifecycle/installer.spec.ts +28 -9
  195. package/templates/tests/lifecycle/market-api.spec.ts +164 -12
  196. package/templates/tests/lifecycle/preflight.spec.ts +68 -0
  197. package/templates/tests/lifecycle/role-title-translate.spec.ts +2 -32
  198. package/templates/tests/lifecycle/text-edit.spec.ts +45 -27
  199. package/templates/tests/lifecycle/uninstall.spec.ts +36 -0
  200. package/templates/tests/publish-credential.spec.ts +354 -0
  201. package/templates/tests/publish-identity.spec.ts +44 -0
  202. package/templates/tests/wecom-client-timeout.spec.ts +33 -3
  203. package/templates/tests/wecom-landing.spec.ts +63 -1
  204. package/templates/tsconfig.paths.json +1 -0
  205. package/templates/web.config.ts +6 -4
  206. package/vendor/host-versions.json +3 -3
  207. package/shell-dist/assets/ahooks.js +0 -6909
  208. package/shell-dist/assets/antd-es-locale-zh_CN.js +0 -257
  209. package/shell-dist/assets/antd-img-crop.js +0 -1495
  210. package/shell-dist/assets/antd-locale-en_US.js +0 -374
  211. package/shell-dist/assets/antd-locale-zh_CN.js +0 -379
  212. package/shell-dist/assets/antd.js +0 -106874
  213. package/shell-dist/assets/clsx.js +0 -33
  214. package/shell-dist/assets/contract-errors.js +0 -30
  215. package/shell-dist/assets/contract.js +0 -18900
  216. package/shell-dist/assets/cssinjs.js +0 -2595
  217. package/shell-dist/assets/dayjs-plugin-advancedFormat.js +0 -98
  218. package/shell-dist/assets/dayjs-plugin-customParseFormat.js +0 -173
  219. package/shell-dist/assets/dayjs-plugin-isoWeek.js +0 -77
  220. package/shell-dist/assets/dayjs-plugin-localeData.js +0 -126
  221. package/shell-dist/assets/dayjs-plugin-quarterOfYear.js +0 -77
  222. package/shell-dist/assets/dayjs-plugin-relativeTime.js +0 -92
  223. package/shell-dist/assets/dayjs-plugin-weekOfYear.js +0 -73
  224. package/shell-dist/assets/dayjs-plugin-weekYear.js +0 -63
  225. package/shell-dist/assets/dayjs-plugin-weekday.js +0 -63
  226. package/shell-dist/assets/dayjs.js +0 -326
  227. package/shell-dist/assets/dnd-kit-core.js +0 -3601
  228. package/shell-dist/assets/dnd-kit-sortable.js +0 -717
  229. package/shell-dist/assets/dnd-kit-utilities.js +0 -340
  230. package/shell-dist/assets/i18next.js +0 -2321
  231. package/shell-dist/assets/icons-es-components-Context.js +0 -20
  232. package/shell-dist/assets/icons.js +0 -34961
  233. package/shell-dist/assets/jsx-dev-runtime.js +0 -75
  234. package/shell-dist/assets/jsx-runtime.js +0 -97
  235. package/shell-dist/assets/keepalive-for-react.js +0 -283
  236. package/shell-dist/assets/kit.js +0 -151
  237. package/shell-dist/assets/ky.js +0 -1427
  238. package/shell-dist/assets/motion-react.js +0 -13589
  239. package/shell-dist/assets/motion.js +0 -9959
  240. package/shell-dist/assets/nprogress.js +0 -314
  241. package/shell-dist/assets/ojm--ant-design-icons-es-icons-BarsOutlined.js +0 -7
  242. package/shell-dist/assets/ojm--ant-design-icons-es-icons-CalendarOutlined.js +0 -7
  243. package/shell-dist/assets/ojm--ant-design-icons-es-icons-CaretDownFilled.js +0 -7
  244. package/shell-dist/assets/ojm--ant-design-icons-es-icons-CaretDownOutlined.js +0 -7
  245. package/shell-dist/assets/ojm--ant-design-icons-es-icons-CaretUpOutlined.js +0 -7
  246. package/shell-dist/assets/ojm--ant-design-icons-es-icons-CheckCircleFilled.js +0 -7
  247. package/shell-dist/assets/ojm--ant-design-icons-es-icons-CheckOutlined.js +0 -7
  248. package/shell-dist/assets/ojm--ant-design-icons-es-icons-ClockCircleOutlined.js +0 -7
  249. package/shell-dist/assets/ojm--ant-design-icons-es-icons-CloseCircleFilled.js +0 -7
  250. package/shell-dist/assets/ojm--ant-design-icons-es-icons-CloseOutlined.js +0 -7
  251. package/shell-dist/assets/ojm--ant-design-icons-es-icons-CopyOutlined.js +0 -7
  252. package/shell-dist/assets/ojm--ant-design-icons-es-icons-DeleteOutlined.js +0 -7
  253. package/shell-dist/assets/ojm--ant-design-icons-es-icons-DoubleLeftOutlined.js +0 -7
  254. package/shell-dist/assets/ojm--ant-design-icons-es-icons-DoubleRightOutlined.js +0 -7
  255. package/shell-dist/assets/ojm--ant-design-icons-es-icons-DownOutlined.js +0 -7
  256. package/shell-dist/assets/ojm--ant-design-icons-es-icons-DownloadOutlined.js +0 -7
  257. package/shell-dist/assets/ojm--ant-design-icons-es-icons-EditOutlined.js +0 -7
  258. package/shell-dist/assets/ojm--ant-design-icons-es-icons-EllipsisOutlined.js +0 -7
  259. package/shell-dist/assets/ojm--ant-design-icons-es-icons-EnterOutlined.js +0 -7
  260. package/shell-dist/assets/ojm--ant-design-icons-es-icons-ExclamationCircleFilled.js +0 -7
  261. package/shell-dist/assets/ojm--ant-design-icons-es-icons-EyeInvisibleOutlined.js +0 -7
  262. package/shell-dist/assets/ojm--ant-design-icons-es-icons-EyeOutlined.js +0 -7
  263. package/shell-dist/assets/ojm--ant-design-icons-es-icons-FileOutlined.js +0 -7
  264. package/shell-dist/assets/ojm--ant-design-icons-es-icons-FileTextOutlined.js +0 -7
  265. package/shell-dist/assets/ojm--ant-design-icons-es-icons-FilterFilled.js +0 -7
  266. package/shell-dist/assets/ojm--ant-design-icons-es-icons-FolderOpenOutlined.js +0 -7
  267. package/shell-dist/assets/ojm--ant-design-icons-es-icons-FolderOutlined.js +0 -7
  268. package/shell-dist/assets/ojm--ant-design-icons-es-icons-HolderOutlined.js +0 -7
  269. package/shell-dist/assets/ojm--ant-design-icons-es-icons-InfoCircleFilled.js +0 -7
  270. package/shell-dist/assets/ojm--ant-design-icons-es-icons-LeftOutlined.js +0 -7
  271. package/shell-dist/assets/ojm--ant-design-icons-es-icons-LoadingOutlined.js +0 -7
  272. package/shell-dist/assets/ojm--ant-design-icons-es-icons-MinusOutlined.js +0 -7
  273. package/shell-dist/assets/ojm--ant-design-icons-es-icons-MinusSquareOutlined.js +0 -7
  274. package/shell-dist/assets/ojm--ant-design-icons-es-icons-PaperClipOutlined.js +0 -7
  275. package/shell-dist/assets/ojm--ant-design-icons-es-icons-PictureOutlined.js +0 -7
  276. package/shell-dist/assets/ojm--ant-design-icons-es-icons-PlusOutlined.js +0 -7
  277. package/shell-dist/assets/ojm--ant-design-icons-es-icons-PlusSquareOutlined.js +0 -7
  278. package/shell-dist/assets/ojm--ant-design-icons-es-icons-QuestionCircleOutlined.js +0 -7
  279. package/shell-dist/assets/ojm--ant-design-icons-es-icons-ReloadOutlined.js +0 -7
  280. package/shell-dist/assets/ojm--ant-design-icons-es-icons-RightOutlined.js +0 -7
  281. package/shell-dist/assets/ojm--ant-design-icons-es-icons-RotateLeftOutlined.js +0 -7
  282. package/shell-dist/assets/ojm--ant-design-icons-es-icons-RotateRightOutlined.js +0 -7
  283. package/shell-dist/assets/ojm--ant-design-icons-es-icons-SearchOutlined.js +0 -7
  284. package/shell-dist/assets/ojm--ant-design-icons-es-icons-StarFilled.js +0 -7
  285. package/shell-dist/assets/ojm--ant-design-icons-es-icons-SwapOutlined.js +0 -7
  286. package/shell-dist/assets/ojm--ant-design-icons-es-icons-SwapRightOutlined.js +0 -7
  287. package/shell-dist/assets/ojm--ant-design-icons-es-icons-UpOutlined.js +0 -7
  288. package/shell-dist/assets/ojm--ant-design-icons-es-icons-VerticalAlignTopOutlined.js +0 -7
  289. package/shell-dist/assets/ojm--ant-design-icons-es-icons-WarningFilled.js +0 -7
  290. package/shell-dist/assets/ojm--ant-design-icons-es-icons-ZoomInOutlined.js +0 -7
  291. package/shell-dist/assets/ojm--ant-design-icons-es-icons-ZoomOutOutlined.js +0 -7
  292. package/shell-dist/assets/ojm-dayjs-locale-zh-cn.js +0 -81
  293. package/shell-dist/assets/pinyin-pro.js +0 -25175
  294. package/shell-dist/assets/pro-components.js +0 -44627
  295. package/shell-dist/assets/react-countup.js +0 -525
  296. package/shell-dist/assets/react-dom-client.js +0 -12134
  297. package/shell-dist/assets/react-dom.js +0 -266
  298. package/shell-dist/assets/react-error-boundary.js +0 -141
  299. package/shell-dist/assets/react-i18next.js +0 -1773
  300. package/shell-dist/assets/react-jss.js +0 -4089
  301. package/shell-dist/assets/react-query.js +0 -3072
  302. package/shell-dist/assets/react-router-dom.js +0 -9927
  303. package/shell-dist/assets/react-router.js +0 -14584
  304. package/shell-dist/assets/react.js +0 -590
  305. package/shell-dist/assets/runtime.js +0 -28311
  306. package/shell-dist/assets/simplebar-react.js +0 -1119
  307. package/shell-dist/assets/spin-delay.js +0 -111
  308. package/shell-dist/assets/tailwind-merge.js +0 -3364
  309. package/shell-dist/assets/use-sync-external-store-shim.js +0 -130
  310. package/shell-dist/assets/zustand-middleware.js +0 -513
  311. package/shell-dist/assets/zustand-react-shallow.js +0 -27
  312. package/shell-dist/assets/zustand-react.js +0 -39
  313. package/shell-dist/assets/zustand-shallow.js +0 -22
  314. package/shell-dist/assets/zustand-vanilla-shallow.js +0 -71
  315. package/shell-dist/assets/zustand-vanilla.js +0 -40
  316. package/shell-dist/assets/zustand.js +0 -32
  317. package/templates/seed.mysql.sql +0 -6
  318. package/templates/seed.pg.sql +0 -6
  319. package/templates/src/app/api/_platform/migrations/0001__create_users.mysql.sql +0 -9
  320. package/templates/src/app/api/_platform/migrations/0001__create_users.pg.sql +0 -9
  321. package/templates/src/app/api/_platform/migrations/0001__create_users.sql +0 -7
  322. package/templates/src/app/api/_platform/migrations/0002__add_users_avatar_base64.mysql.sql +0 -3
  323. package/templates/src/app/api/_platform/migrations/0002__add_users_avatar_base64.sql +0 -2
  324. package/templates/src/app/api/_platform/migrations/0003__users_source_display_name.mysql.sql +0 -5
  325. package/templates/src/app/api/_platform/migrations/0003__users_source_display_name.sql +0 -5
  326. package/templates/src/app/api/_platform/migrations/0004__sys_rbac.mysql.sql +0 -70
  327. package/templates/src/app/api/_platform/migrations/0004__sys_rbac.pg.sql +0 -67
  328. package/templates/src/app/api/_platform/migrations/0004__sys_rbac.sql +0 -67
  329. package/templates/src/app/api/_platform/migrations/0005__users_must_change.mysql.sql +0 -3
  330. package/templates/src/app/api/_platform/migrations/0005__users_must_change.sql +0 -2
  331. package/templates/src/app/api/_platform/migrations/0006__users_is_forbidden.mysql.sql +0 -3
  332. package/templates/src/app/api/_platform/migrations/0006__users_is_forbidden.sql +0 -3
  333. package/templates/src/app/api/_platform/migrations/0007__users_email.sql +0 -3
  334. package/templates/src/app/api/_platform/migrations/0008__sys_refresh_token.mysql.sql +0 -10
  335. package/templates/src/app/api/_platform/migrations/0008__sys_refresh_token.pg.sql +0 -10
  336. package/templates/src/app/api/_platform/migrations/0008__sys_refresh_token.sql +0 -11
  337. package/templates/src/app/api/_platform/migrations/0009__sys_throttle.mysql.sql +0 -12
  338. package/templates/src/app/api/_platform/migrations/0009__sys_throttle.pg.sql +0 -12
  339. package/templates/src/app/api/_platform/migrations/0009__sys_throttle.sql +0 -13
  340. package/templates/src/app/api/_platform/migrations/0010__sys_solution_route.mysql.sql +0 -17
  341. package/templates/src/app/api/_platform/migrations/0010__sys_solution_route.pg.sql +0 -16
  342. package/templates/src/app/api/_platform/migrations/0010__sys_solution_route.sql +0 -18
  343. package/templates/src/app/api/_platform/migrations/0011__sys_setting_group_label.mysql.sql +0 -2
  344. package/templates/src/app/api/_platform/migrations/0011__sys_setting_group_label.sql +0 -4
  345. package/templates/src/app/api/_platform/migrations/0012__market_history.mysql.sql +0 -13
  346. package/templates/src/app/api/_platform/migrations/0012__market_history.pg.sql +0 -12
  347. package/templates/src/app/api/_platform/migrations/0012__market_history.sql +0 -14
  348. package/templates/src/app/api/_platform/migrations/0013__users_profile.sql +0 -4
  349. package/templates/src/app/api/_platform/migrations/0014__reg_source_seq.mysql.sql +0 -9
  350. package/templates/src/app/api/_platform/migrations/0014__reg_source_seq.pg.sql +0 -7
  351. package/templates/src/app/api/_platform/migrations/0014__reg_source_seq.sql +0 -8
  352. package/templates/src/app/api/_platform/migrations/0015__tenant.mysql.sql +0 -12
  353. package/templates/src/app/api/_platform/migrations/0015__tenant.pg.sql +0 -11
  354. package/templates/src/app/api/_platform/migrations/0015__tenant.sql +0 -44
  355. package/templates/src/app/api/_platform/migrations/0016__org.mysql.sql +0 -41
  356. package/templates/src/app/api/_platform/migrations/0016__org.pg.sql +0 -40
  357. package/templates/src/app/api/_platform/migrations/0016__org.sql +0 -62
  358. package/templates/src/app/api/_platform/migrations/0017__users_employee_no.mysql.sql +0 -7
  359. package/templates/src/app/api/_platform/migrations/0017__users_employee_no.pg.sql +0 -4
  360. package/templates/src/app/api/_platform/migrations/0017__users_employee_no.sql +0 -8
  361. package/templates/src/app/api/_platform/migrations/0018__sys_role_title_key.mysql.sql +0 -3
  362. package/templates/src/app/api/_platform/migrations/0018__sys_role_title_key.pg.sql +0 -3
  363. package/templates/src/app/api/_platform/migrations/0018__sys_role_title_key.sql +0 -8
  364. package/templates/src/app/web/system/pages/login-methods/index.tsx +0 -30
  365. /package/shell-dist/assets/{nprogress-css.js → nprogress-css.1cq2pzkre0.js} +0 -0
  366. /package/shell-dist/assets/{ojm-antd-es-button.js → ojm-antd-es-button.2uriphio50.js} +0 -0
  367. /package/shell-dist/assets/{ojm-antd-es-modal.js → ojm-antd-es-modal.bf3tgdh8v0.js} +0 -0
  368. /package/shell-dist/assets/{ojm-antd-es-slider.js → ojm-antd-es-slider.xyvptuhid0.js} +0 -0
  369. /package/shell-dist/assets/{ojm-antd-es-upload.js → ojm-antd-es-upload.13gx45e0g0.js} +0 -0
@@ -10,6 +10,7 @@ import type {
10
10
  IndexRow,
11
11
  InstallInput,
12
12
  MarketHistory,
13
+ ReleasePage,
13
14
  TaskRecord,
14
15
  UninstallImpact,
15
16
  } from "../types";
@@ -33,6 +34,8 @@ export interface MarketClient {
33
34
  enable: (input: EnableInput) => Promise<{ ok: boolean, message: string }>
34
35
  /** 市场操作历史(_platform 只读端点 /_platform/market/history) */
35
36
  history: () => Promise<MarketHistory[]>
37
+ /** 发布历史(登录即可读;服务端每次读先与签名索引对账) */
38
+ releases: (input?: { page?: number, limit?: number }) => Promise<ReleasePage>
36
39
  /** 卸载影响面预检(P3 U1;服务端返回供二次确认,P1-15a 补齐后接通) */
37
40
  uninstallImpact: (name: string) => Promise<UninstallImpact>
38
41
  /** 卸载(P1-15a 补齐后接通) */
@@ -12,6 +12,7 @@ import type {
12
12
  IndexRow,
13
13
  InstallInput,
14
14
  MarketHistory,
15
+ ReleasePage,
15
16
  TaskRecord,
16
17
  UninstallImpact,
17
18
  } from "../types";
@@ -24,6 +25,7 @@ import {
24
25
  platformMarketHistoryGet,
25
26
  platformMarketInstallPost,
26
27
  platformMarketMetaGet,
28
+ platformMarketReleasesGet,
27
29
  platformMarketTaskGet,
28
30
  platformMarketTrustPost,
29
31
  platformMarketUninstallImpactGet,
@@ -109,6 +111,9 @@ export const httpMarketClient: MarketClient = {
109
111
  async history() {
110
112
  return (await platformMarketHistoryGet()) as unknown as MarketHistory[];
111
113
  },
114
+ async releases(input: { page?: number, limit?: number } = {}) {
115
+ return (await platformMarketReleasesGet(input as { page: number, limit: number })) as unknown as ReleasePage;
116
+ },
112
117
  async uninstallImpact(name: string) {
113
118
  return (await platformMarketUninstallImpactGet({ name })) as unknown as UninstallImpact;
114
119
  },
@@ -17,7 +17,9 @@ export interface CardItemProps {
17
17
  }
18
18
 
19
19
  /**
20
- * 单张方案卡片:版本/状态标识(enabled/disabled/upgradable)+ 动作按钮。
20
+ * 单张方案卡片:方案简介/详细描述 + 版本/状态标识(enabled/disabled/upgradable)+ 动作按钮。
21
+ * 卡片上先展示 summary(单行)与 description(最多 3 行,完整文案见详情抽屉),让人不必点
22
+ * 详情就能判断方案提供什么;索引未声明这两项就不占位(与 license 同口径)。
21
23
  * 双版本展示(P1-15b):已装且可升级时并列「已装 installed → 最新 latest」(upgradable 对比),
22
24
  * 否则单版本。已装方案提供回滚入口(RollbackDialog 选旧版降级安装)。
23
25
  */
@@ -44,6 +46,35 @@ export function CardItem({ row, busy, canManage = true, onInstall, onEnableToggl
44
46
  </Space>
45
47
  )}
46
48
  >
49
+ {/* 方案「提供什么」:summary 单行、description 限 3 行;title 与详情抽屉给全文 */}
50
+ {typeof row.summary === "string" && row.summary.trim() !== "" && (
51
+ <div
52
+ data-testid={`card-summary-${row.name}`}
53
+ title={row.summary}
54
+ style={{ marginBottom: 8, fontWeight: 500, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}
55
+ >
56
+ {row.summary}
57
+ </div>
58
+ )}
59
+ {typeof row.description === "string" && row.description.trim() !== "" && (
60
+ <div
61
+ data-testid={`card-description-${row.name}`}
62
+ title={row.description}
63
+ style={{
64
+ marginBottom: 12,
65
+ color: "var(--oo-text-secondary, #888)",
66
+ fontSize: 12,
67
+ lineHeight: 1.6,
68
+ display: "-webkit-box",
69
+ WebkitLineClamp: 3,
70
+ WebkitBoxOrient: "vertical",
71
+ overflow: "hidden",
72
+ whiteSpace: "pre-wrap",
73
+ }}
74
+ >
75
+ {row.description}
76
+ </div>
77
+ )}
47
78
  <div style={{ minHeight: 40, color: "var(--oo-text-secondary, #888)", marginBottom: 12 }} data-testid={`card-versions-${row.name}`}>
48
79
  {dualVersion
49
80
  ? (
@@ -85,6 +116,18 @@ export function CardItem({ row, busy, canManage = true, onInstall, onEnableToggl
85
116
  </Tag>
86
117
  </div>
87
118
  )}
119
+ {/* 发布者:展示签出的 key_id(离线可验的发布身份);无签名就不占位 */}
120
+ {typeof row.publisher_key === "string" && row.publisher_key.trim() !== "" && (
121
+ <div
122
+ data-testid={`card-publisher-${row.name}`}
123
+ title={row.publisher_key}
124
+ style={{ marginBottom: 12, color: "var(--oo-text-secondary, #888)", fontSize: 12, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}
125
+ >
126
+ {t("oj-market:card:publisher")}
127
+ :
128
+ {row.publisher_key}
129
+ </div>
130
+ )}
88
131
  <Space wrap>
89
132
  <Button type="primary" size="small" loading={busy} onClick={() => onInstall(row)} disabled={busy || !canManage} title={manageTip}>
90
133
  {installed ? t("oj-market:card:upgrade") : t("oj-market:card:install")}
@@ -14,7 +14,7 @@ export interface DetailDrawerProps {
14
14
  onRollback: (row: IndexRow) => void
15
15
  }
16
16
 
17
- /** 方案详情抽屉:只读展示卡片元信息(含双版本对比)+ 安装/回滚/历史入口 */
17
+ /** 方案详情抽屉:只读展示卡片元信息(含双版本对比)+ 完整简介/描述 + 安装/回滚/历史入口 */
18
18
  export function DetailDrawer({ row, open, onClose, canManage = true, onInstall, onHistory, onRollback }: DetailDrawerProps) {
19
19
  const { t } = useTranslation();
20
20
  // 非 superadmin:写操作禁用并解释原因,历史(只读)保持可用。
@@ -38,6 +38,22 @@ export function DetailDrawer({ row, open, onClose, canManage = true, onInstall,
38
38
  <Descriptions.Item label={t("oj-market:card:upgradable")}>
39
39
  {row.upgradable ? <Tag color="gold">{t("oj-market:card:upgradable")}</Tag> : "-"}
40
40
  </Descriptions.Item>
41
+ {typeof row.publisher_key === "string" && row.publisher_key.trim() !== "" && (
42
+ <Descriptions.Item label={t("oj-market:card:publisher")}>
43
+ <span data-testid="detail-publisher" style={{ wordBreak: "break-all" }}>{row.publisher_key}</span>
44
+ </Descriptions.Item>
45
+ )}
46
+ {/* 卡片上的 description 被限行,抽屉给全文(保留换行,长串不撑破抽屉) */}
47
+ {typeof row.summary === "string" && row.summary.trim() !== "" && (
48
+ <Descriptions.Item label={t("oj-market:card:summary")}>
49
+ <span data-testid="detail-summary">{row.summary}</span>
50
+ </Descriptions.Item>
51
+ )}
52
+ {typeof row.description === "string" && row.description.trim() !== "" && (
53
+ <Descriptions.Item label={t("oj-market:card:description")}>
54
+ <div data-testid="detail-description" style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>{row.description}</div>
55
+ </Descriptions.Item>
56
+ )}
41
57
  </Descriptions>
42
58
  <Space style={{ marginTop: 16 }}>
43
59
  <Button type="primary" onClick={() => onInstall(row)} disabled={!canManage} title={manageTip}>
@@ -1,12 +1,30 @@
1
+ import type { ModuleContext, ModuleI18n } from "@oj-module/runtime";
2
+
3
+ import { AppstoreOutlined } from "@ant-design/icons";
1
4
  import { defineModule, OutsidePageIcon } from "@oj-module/runtime";
2
5
  import { createElement } from "react";
3
6
  import MarketApp from "./pages/MarketApp";
7
+ import { onInit as publishOnInit, routes as publishRoutes } from "./publish/routes";
4
8
 
5
9
  // 方案市场前端模块(第一方专用,R29:消费 /api/_platform/market/* 编排面,第三方方案不得仿照此调用面)。
6
10
  // 菜单标题走 i18next 命名空间语法 "<moduleName>:menu.<key>"(i18n 资源在 locales/,安装时随包注册)。
11
+ //
12
+ // **单模单根**(2026-11-05):菜单只有一个「方案市场」根,下挂三个子页——
13
+ // 方案清单(index)/ 发布管理(publish)/ 发布历史(history)。
14
+ // 「发布管理」与「发布历史」都归市场:发布身份是市场的准入面,页面随市场模块同版本发布、
15
+ // 同生命周期下线;子页路径是相对父路由声明的,实际 URL 为 /oj-market、/oj-market/publish、
16
+ // /oj-market/history。
17
+ const i18nNamespaces: Record<string, ModuleI18n> = {
18
+ // 发布页沿用原命名空间:`t("publish:…")` / 菜单 `publish:menu.publish` 零改动
19
+ publish: {
20
+ "zh-CN": () => import("./publish/locales/zh-CN.json"),
21
+ "en-US": () => import("./publish/locales/en-US.json"),
22
+ },
23
+ };
24
+
7
25
  export default defineModule({
8
26
  name: "oj-market",
9
- description: "oj 方案市场应用——卡片展示/安装/卸载/历史(第一方专用,R29)",
27
+ description: "oj 方案市场应用——方案清单 / 发布管理 / 发布历史(第一方专用,R29)",
10
28
  version: "0.1.0",
11
29
  routes: [
12
30
  {
@@ -21,8 +39,12 @@ export default defineModule({
21
39
  {
22
40
  index: true,
23
41
  Component: MarketApp,
24
- handle: { title: "oj-market:menu.main" },
42
+ handle: {
43
+ title: "oj-market:menu.list",
44
+ icon: createElement(AppstoreOutlined),
45
+ },
25
46
  },
47
+ ...publishRoutes,
26
48
  ],
27
49
  },
28
50
  ],
@@ -30,4 +52,11 @@ export default defineModule({
30
52
  "zh-CN": () => import("./locales/zh-CN.json"),
31
53
  "en-US": () => import("./locales/en-US.json"),
32
54
  },
55
+ i18nNamespaces,
56
+ lifecycle: {
57
+ /** 发布页的契约前缀 /publish + scoped request 在这里接线(与市场自身的 client 互不影响) */
58
+ async onInit(ctx: ModuleContext) {
59
+ publishOnInit(ctx);
60
+ },
61
+ },
33
62
  });
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "menu": {
3
- "main": "Market"
3
+ "main": "Market",
4
+ "list": "Solutions"
4
5
  },
5
6
  "perm": {
6
7
  "view": "View solution market"
@@ -25,6 +26,9 @@
25
26
  "retry": "Retry",
26
27
  "version": "Version",
27
28
  "license": "License",
29
+ "publisher": "Publisher",
30
+ "summary": "Summary",
31
+ "description": "Description",
28
32
  "latest": "Latest",
29
33
  "installed": "Installed",
30
34
  "notInstalled": "Not installed",
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "menu": {
3
- "main": "方案市场"
3
+ "main": "方案市场",
4
+ "list": "方案清单"
4
5
  },
5
6
  "perm": {
6
7
  "view": "查看方案市场"
@@ -25,6 +26,9 @@
25
26
  "retry": "重试",
26
27
  "version": "版本",
27
28
  "license": "许可",
29
+ "publisher": "发布者",
30
+ "summary": "简介",
31
+ "description": "详细介绍",
28
32
  "latest": "最新",
29
33
  "installed": "已装",
30
34
  "notInstalled": "未安装",
@@ -0,0 +1,61 @@
1
+ /* eslint-disable */
2
+ // 生成物:ojm api 从契约生成,勿手改(改动请改契约文件后重跑 ojm api)
3
+ // AC-D15:仅供 DEV 校验动态 import,生产构建不进产物
4
+ import { z } from "@oj-module/runtime";
5
+
6
+ export const schemas = {
7
+ "publishCredentialGet": {
8
+ query: z.object({
9
+ "page": z.number().min(1).optional(),
10
+ "limit": z.number().min(1).max(200).optional(),
11
+ "tenant": z.string().optional()
12
+ }),
13
+ data: z.object({
14
+ "list": z.array(z.object({
15
+ "id": z.number(),
16
+ "product": z.string(),
17
+ "key_id": z.string(),
18
+ "username": z.string(),
19
+ "display_name": z.string().nullable().optional(),
20
+ "token_hint": z.string(),
21
+ "status": z.enum(["active", "used", "revoked", "expired"]),
22
+ "expires_at": z.number(),
23
+ "used_at": z.number().nullable().optional(),
24
+ "created_at": z.number(),
25
+ "owner_tenant": z.string().optional()
26
+ })),
27
+ "total": z.number()
28
+ }),
29
+ },
30
+ "publishCredentialPost": {
31
+ body: z.object({
32
+ "product": z.string()
33
+ }),
34
+ data: z.object({
35
+ "token": z.string(),
36
+ "key_id": z.string(),
37
+ "product": z.string(),
38
+ "token_hint": z.string().optional(),
39
+ "expires_at": z.number()
40
+ }),
41
+ },
42
+ "publishCredentialRevokePost": {
43
+ body: z.object({
44
+ "id": z.number()
45
+ }),
46
+ data: z.object({
47
+ "ok": z.boolean()
48
+ }),
49
+ },
50
+ "publishCredentialExchangePost": {
51
+ body: z.object({
52
+ "token": z.string()
53
+ }),
54
+ data: z.object({
55
+ "key_id": z.string(),
56
+ "product": z.string(),
57
+ "username": z.string(),
58
+ "display_name": z.string().nullable().optional()
59
+ }),
60
+ },
61
+ };
@@ -0,0 +1,164 @@
1
+ /* eslint-disable */
2
+ // 生成物:ojm api 从契约生成,勿手改(改动请改契约文件后重跑 ojm api)
3
+ import { ContractApiError } from "@oj-module/runtime/contract/errors";
4
+ import type { ScopedRequestLike } from "@oj-module/runtime/contract/errors";
5
+ import type { ModuleContext } from "@oj-module/runtime";
6
+ import type { z } from "@oj-module/runtime";
7
+ import type { schemas } from "./api.schemas";
8
+
9
+ /** oj 信封(AC-D16):code=0 成功;非 0 时 HTTP status=code,由 toApiError 归一为 ContractApiError */
10
+ interface OjEnvelope<T> { code: number, msg?: string, data?: T }
11
+
12
+ let req: ScopedRequestLike | undefined;
13
+
14
+ /** 线上 API 前缀(ojm api 从契约抽取,唯一真源,勿手改):请求基址 + 前缀登记用 */
15
+ export const API_PREFIX = "/publish";
16
+
17
+ /** 认领身份前缀(契约 apiPrefix,字面等于模块目录名):跨模块认领护栏对比基准 */
18
+ export const MODULE_PREFIX = "/publish";
19
+
20
+ /** 认领方模块(web.config clientOwners 指定):跨模块认领护栏对比基准 */
21
+ export const MODULE_OWNER = "/oj-market";
22
+
23
+ /**
24
+ * 模块 entry 的 onInit 里一行创建(构造即 install):完成 apiPrefix 登记 +
25
+ * scoped request 绑定,返回绑好前缀的端点函数集合。一模块一 client;
26
+ * 重复构造幂等安全(前缀重复登记同值、request 重绑同值)。
27
+ */
28
+ export function createPublishClient(ctx: ModuleContext) {
29
+ // 跨模块认领护栏(DEV):工厂知道自己该属于谁(MODULE_PREFIX = 契约 apiPrefix),
30
+ // ctx 又带 module.name——名实不符说明别的模块在替本模块创建 client,会共享 request
31
+ // 单槽、卸载互相耦合;跨模块需求应由本模块创建后经 provider 暴露。
32
+ // 注意对比基准是 MODULE_PREFIX(目录名)而非 API_PREFIX——D-M8 映射时线上前缀
33
+ // 属于别的命名空间,认领身份仍按目录名。
34
+ if (import.meta.env.DEV && ctx.module.name !== MODULE_OWNER.slice(1)) {
35
+ console.warn(`[ojm-api] 模块 "${ctx.module.name}" 正在认领 ${MODULE_PREFIX} 的 client——跨模块认领会共享 request 单槽、卸载互相耦合;应由 "${MODULE_OWNER.slice(1)}" 模块在自身 onInit 创建,跨模块需求经 provider 暴露。`);
36
+ }
37
+ ctx.register.apiPrefix(API_PREFIX);
38
+ bindRequest(ctx.utils.request);
39
+ return { publishCredentialGet, publishCredentialPost, publishCredentialRevokePost, publishCredentialExchangePost };
40
+ }
41
+
42
+ /**
43
+ * @deprecated 请改用 createPublishClient(ctx)——工厂构造即完成
44
+ * 前缀登记 + request 绑定,不会出现「登记了前缀没绑 request」的半接线状态。
45
+ */
46
+ export function bindRequest(r: ScopedRequestLike): void {
47
+ req = r;
48
+ }
49
+
50
+ function ensureReq(): ScopedRequestLike {
51
+ if (!req)
52
+ throw new ContractApiError(-1, "[ojm-api] 请求未绑定——请在模块 entry.ts 的 onInit 里调用 createPublishClient(ctx)(或 bindRequest(ctx.utils.request))。");
53
+ return req;
54
+ }
55
+
56
+ /** ky HTTPError → ContractApiError(错误体为信封时取 code/msg);契约违例与原错误原样透传 */
57
+ async function toApiError(e: unknown): Promise<unknown> {
58
+ if (e instanceof ContractApiError)
59
+ return e;
60
+ // ky 2.x 构造 HTTPError 时已用 getReader() 消费掉原 response 体(res.clone().json() 按规范抛 TypeError,
61
+ // 体方法一律失效),解析好的错误体在公开字段 error.data——故读 error.data,勿改回 clone().json()。
62
+ const err = e as { data?: { code?: unknown, msg?: string }, response?: Response } | null;
63
+ const res = err?.response;
64
+ const d = err?.data;
65
+ if (res instanceof Response && d && typeof d.code === "number")
66
+ return new ContractApiError(d.code, d.msg ?? res.statusText);
67
+ return e;
68
+ }
69
+
70
+ export type PublishCredentialGetQuery = z.input<(typeof schemas)["publishCredentialGet"]["query"]>;
71
+ export type PublishCredentialGetData = z.infer<(typeof schemas)["publishCredentialGet"]["data"]>;
72
+
73
+ export async function publishCredentialGet(query: PublishCredentialGetQuery): Promise<PublishCredentialGetData> {
74
+ const client = ensureReq();
75
+ try {
76
+ const env = await client.get(`publish/credential`, { searchParams: query as Record<string, string | number | boolean> }).json<OjEnvelope<PublishCredentialGetData>>();
77
+ // 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
78
+ if (typeof env.code === "number" && env.code !== 0)
79
+ throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
80
+ const data = env.data as PublishCredentialGetData;
81
+ if (import.meta.env.DEV) {
82
+ const { schemas } = await import("./api.schemas");
83
+ const r = schemas["publishCredentialGet"].data.safeParse(data);
84
+ if (!r.success)
85
+ throw new ContractApiError(-1, `[契约违例] publishCredentialGet 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
86
+ }
87
+ return data;
88
+ }
89
+ catch (e) {
90
+ throw await toApiError(e);
91
+ }
92
+ }
93
+
94
+ export type PublishCredentialPostBody = z.input<(typeof schemas)["publishCredentialPost"]["body"]>;
95
+ export type PublishCredentialPostData = z.infer<(typeof schemas)["publishCredentialPost"]["data"]>;
96
+
97
+ export async function publishCredentialPost(body: PublishCredentialPostBody): Promise<PublishCredentialPostData> {
98
+ const client = ensureReq();
99
+ try {
100
+ const env = await client.post(`publish/credential`, { json: body }).json<OjEnvelope<PublishCredentialPostData>>();
101
+ // 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
102
+ if (typeof env.code === "number" && env.code !== 0)
103
+ throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
104
+ const data = env.data as PublishCredentialPostData;
105
+ if (import.meta.env.DEV) {
106
+ const { schemas } = await import("./api.schemas");
107
+ const r = schemas["publishCredentialPost"].data.safeParse(data);
108
+ if (!r.success)
109
+ throw new ContractApiError(-1, `[契约违例] publishCredentialPost 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
110
+ }
111
+ return data;
112
+ }
113
+ catch (e) {
114
+ throw await toApiError(e);
115
+ }
116
+ }
117
+
118
+ export type PublishCredentialRevokePostBody = z.input<(typeof schemas)["publishCredentialRevokePost"]["body"]>;
119
+ export type PublishCredentialRevokePostData = z.infer<(typeof schemas)["publishCredentialRevokePost"]["data"]>;
120
+
121
+ export async function publishCredentialRevokePost(body: PublishCredentialRevokePostBody): Promise<PublishCredentialRevokePostData> {
122
+ const client = ensureReq();
123
+ try {
124
+ const env = await client.post(`publish/credential/revoke`, { json: body }).json<OjEnvelope<PublishCredentialRevokePostData>>();
125
+ // 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
126
+ if (typeof env.code === "number" && env.code !== 0)
127
+ throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
128
+ const data = env.data as PublishCredentialRevokePostData;
129
+ if (import.meta.env.DEV) {
130
+ const { schemas } = await import("./api.schemas");
131
+ const r = schemas["publishCredentialRevokePost"].data.safeParse(data);
132
+ if (!r.success)
133
+ throw new ContractApiError(-1, `[契约违例] publishCredentialRevokePost 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
134
+ }
135
+ return data;
136
+ }
137
+ catch (e) {
138
+ throw await toApiError(e);
139
+ }
140
+ }
141
+
142
+ export type PublishCredentialExchangePostBody = z.input<(typeof schemas)["publishCredentialExchangePost"]["body"]>;
143
+ export type PublishCredentialExchangePostData = z.infer<(typeof schemas)["publishCredentialExchangePost"]["data"]>;
144
+
145
+ export async function publishCredentialExchangePost(body: PublishCredentialExchangePostBody): Promise<PublishCredentialExchangePostData> {
146
+ const client = ensureReq();
147
+ try {
148
+ const env = await client.post(`publish/credential/exchange`, { json: body }).json<OjEnvelope<PublishCredentialExchangePostData>>();
149
+ // 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
150
+ if (typeof env.code === "number" && env.code !== 0)
151
+ throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
152
+ const data = env.data as PublishCredentialExchangePostData;
153
+ if (import.meta.env.DEV) {
154
+ const { schemas } = await import("./api.schemas");
155
+ const r = schemas["publishCredentialExchangePost"].data.safeParse(data);
156
+ if (!r.success)
157
+ throw new ContractApiError(-1, `[契约违例] publishCredentialExchangePost 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
158
+ }
159
+ return data;
160
+ }
161
+ catch (e) {
162
+ throw await toApiError(e);
163
+ }
164
+ }
@@ -0,0 +1,80 @@
1
+ {
2
+ "menu": {
3
+ "publish": "Publishing",
4
+ "history": "Release history"
5
+ },
6
+ "history": {
7
+ "title": "Release history",
8
+ "subtitle": "Every release recorded in the signed index, newest first. Product, version and publisher all come from the index itself.",
9
+ "empty": "No releases yet",
10
+ "syncFailed": "The market index is temporarily unreachable; showing records already stored",
11
+ "indexTime": "index time",
12
+ "publishedAtHint": "Uses the CDN file's Last-Modified when available; otherwise falls back to the index build time, tagged “index time”",
13
+ "total": "{{total}} in total",
14
+ "columns": {
15
+ "product": "Product",
16
+ "version": "Version",
17
+ "publisher": "Publisher key",
18
+ "publishedAt": "Published at",
19
+ "status": "Status"
20
+ },
21
+ "status": {
22
+ "active": "Available",
23
+ "yanked": "Yanked"
24
+ }
25
+ },
26
+ "page": {
27
+ "title": "Publishing",
28
+ "subtitle": "A publishing credential is single-use: redeeming it mints a long-lived publishing identity (key_id).",
29
+ "apply": "Request credential",
30
+ "empty": "No publishing credential yet",
31
+ "total": "{{total}} in total"
32
+ },
33
+ "apply": {
34
+ "title": "Request publishing credential",
35
+ "product": "Product",
36
+ "productExtra": "The solution name you are publishing (lowercase, a-z0-9- only). Identity = product + your username; it cannot be changed later.",
37
+ "productRequired": "Product is required",
38
+ "ok": "Generate",
39
+ "cancel": "Cancel"
40
+ },
41
+ "issued": {
42
+ "title": "Credential created (shown once)",
43
+ "warning": "You will not be able to view it again. Copy it now, or copy the command below.",
44
+ "token": "Credential",
45
+ "command": "Command",
46
+ "copy": "Copy",
47
+ "copied": "Copied",
48
+ "identity": "Identity",
49
+ "expires": "Valid until",
50
+ "done": "Saved"
51
+ },
52
+ "columns": {
53
+ "product": "Product",
54
+ "keyId": "Identity",
55
+ "applicant": "Applicant",
56
+ "tokenHint": "Credential",
57
+ "status": "Status",
58
+ "createdAt": "Requested",
59
+ "usedAt": "Redeemed",
60
+ "expiresAt": "Valid until",
61
+ "tenant": "Tenant",
62
+ "actions": "Actions"
63
+ },
64
+ "status": {
65
+ "active": "Pending",
66
+ "used": "Redeemed",
67
+ "revoked": "Revoked",
68
+ "expired": "Expired"
69
+ },
70
+ "revoke": {
71
+ "action": "Revoke",
72
+ "confirm": "Revoking invalidates this credential immediately. Continue?",
73
+ "ok": "Revoke",
74
+ "done": "Revoked"
75
+ },
76
+ "filter": {
77
+ "tenant": "Filter by tenant",
78
+ "tenantPlaceholder": "Leave empty for all tenants"
79
+ }
80
+ }
@@ -0,0 +1,80 @@
1
+ {
2
+ "menu": {
3
+ "publish": "发布管理",
4
+ "history": "发布历史"
5
+ },
6
+ "history": {
7
+ "title": "发布历史",
8
+ "subtitle": "签名索引里出现过的每一次发版:产品、版本与发布身份都来自索引本身,按发布时间倒序。",
9
+ "empty": "还没有发布记录",
10
+ "syncFailed": "暂时读不到市场索引,下面是已入库的历史记录",
11
+ "indexTime": "索引时间",
12
+ "publishedAtHint": "优先取分发包落 CDN 的时间(Last-Modified);源不提供时用索引生成时间,会标注「索引时间」",
13
+ "total": "共 {{total}} 条",
14
+ "columns": {
15
+ "product": "产品名",
16
+ "version": "版本",
17
+ "publisher": "发布身份",
18
+ "publishedAt": "发布时间",
19
+ "status": "状态"
20
+ },
21
+ "status": {
22
+ "active": "在架",
23
+ "yanked": "已下线"
24
+ }
25
+ },
26
+ "page": {
27
+ "title": "发布管理",
28
+ "subtitle": "发布凭证是一次性令牌:兑换后换到一个长期有效的发布身份(key_id),凭证本身随即作废。",
29
+ "apply": "申请发布凭证",
30
+ "empty": "还没有申请过发布凭证",
31
+ "total": "共 {{total}} 条"
32
+ },
33
+ "apply": {
34
+ "title": "申请发布凭证",
35
+ "product": "产品名",
36
+ "productExtra": "要发布的解决方案名(小写字母开头,仅 a-z、0-9、-)。发布身份 = 产品名.你的用户名,申请后不可更改。",
37
+ "productRequired": "请填写产品名",
38
+ "ok": "生成凭证",
39
+ "cancel": "取消"
40
+ },
41
+ "issued": {
42
+ "title": "凭证已生成(只显示这一次)",
43
+ "warning": "关闭后无法再次查看明文,只能重新申请。请先复制凭证或下方命令。",
44
+ "identity": "发布身份",
45
+ "token": "凭证",
46
+ "command": "在本机执行",
47
+ "expires": "有效期至",
48
+ "copy": "复制",
49
+ "copied": "已复制",
50
+ "done": "我已保存"
51
+ },
52
+ "columns": {
53
+ "product": "产品名",
54
+ "keyId": "发布身份",
55
+ "applicant": "申请人",
56
+ "tokenHint": "凭证标识",
57
+ "status": "状态",
58
+ "createdAt": "申请时间",
59
+ "usedAt": "兑换时间",
60
+ "expiresAt": "有效期至",
61
+ "tenant": "归属租户",
62
+ "actions": "操作"
63
+ },
64
+ "status": {
65
+ "active": "待兑换",
66
+ "used": "已兑换",
67
+ "revoked": "已撤销",
68
+ "expired": "已过期"
69
+ },
70
+ "revoke": {
71
+ "action": "撤销",
72
+ "confirm": "撤销后该凭证立刻作废,确定?",
73
+ "ok": "撤销",
74
+ "done": "已撤销"
75
+ },
76
+ "filter": {
77
+ "tenant": "按租户筛选",
78
+ "tenantPlaceholder": "留空查看全部租户"
79
+ }
80
+ }