@linyjs/plugin-docs 0.0.13

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 (254) hide show
  1. package/README.md +137 -0
  2. package/docs/api-reference/index.md +361 -0
  3. package/docs/best-practices/error-handling.md +462 -0
  4. package/docs/best-practices/naming-conventions.md +496 -0
  5. package/docs/best-practices/performance.md +532 -0
  6. package/docs/best-practices/security.md +620 -0
  7. package/docs/best-practices/service-definition.md +332 -0
  8. package/docs/faq.md +322 -0
  9. package/docs/getting-started/first-plugin.md +358 -0
  10. package/docs/getting-started/installation.md +244 -0
  11. package/docs/getting-started/quick-start.md +235 -0
  12. package/docs/guides/authentication.md +428 -0
  13. package/docs/guides/client-module.md +604 -0
  14. package/docs/guides/data-persistence.md +640 -0
  15. package/docs/guides/permissions.md +440 -0
  16. package/docs/guides/server-module.md +377 -0
  17. package/docs/guides/ui-slots.md +475 -0
  18. package/docs/migration/v0-to-v1.md +354 -0
  19. package/examples/analytics-plugin/README.md +416 -0
  20. package/examples/analytics-plugin/dist/client/index.d.ts +36 -0
  21. package/examples/analytics-plugin/dist/client/index.js +173 -0
  22. package/examples/analytics-plugin/dist/index.d.ts +64 -0
  23. package/examples/analytics-plugin/dist/index.js +72 -0
  24. package/examples/analytics-plugin/dist/server/index.d.ts +119 -0
  25. package/examples/analytics-plugin/dist/server/index.js +313 -0
  26. package/examples/analytics-plugin/package.json +28 -0
  27. package/examples/analytics-plugin/src/client/index.tsx +414 -0
  28. package/examples/analytics-plugin/src/index.ts +71 -0
  29. package/examples/analytics-plugin/src/server/index.ts +349 -0
  30. package/examples/analytics-plugin/tsconfig.json +21 -0
  31. package/examples/blog-plugin/README.md +319 -0
  32. package/examples/blog-plugin/dist/client/index.d.ts +22 -0
  33. package/examples/blog-plugin/dist/client/index.js +197 -0
  34. package/examples/blog-plugin/dist/server/index.d.ts +5 -0
  35. package/examples/blog-plugin/dist/server/index.js +220 -0
  36. package/examples/blog-plugin/package.json +24 -0
  37. package/examples/blog-plugin/src/client/index.tsx +409 -0
  38. package/examples/blog-plugin/src/server/index.ts +240 -0
  39. package/examples/blog-plugin/tsconfig.json +16 -0
  40. package/examples/hello-world/README.md +101 -0
  41. package/examples/hello-world/dist/client/index.d.ts +5 -0
  42. package/examples/hello-world/dist/client/index.js +80 -0
  43. package/examples/hello-world/dist/server/index.d.ts +5 -0
  44. package/examples/hello-world/dist/server/index.js +38 -0
  45. package/examples/hello-world/node_modules/.package-lock.json +61 -0
  46. package/examples/hello-world/node_modules/@linyjs/client-module-interface/HOOKS_USAGE.md +281 -0
  47. package/examples/hello-world/node_modules/@linyjs/client-module-interface/IMPLEMENTATION_SUMMARY.md +166 -0
  48. package/examples/hello-world/node_modules/@linyjs/client-module-interface/QUICK_REFERENCE.md +130 -0
  49. package/examples/hello-world/node_modules/@linyjs/client-module-interface/README.md +214 -0
  50. package/examples/hello-world/node_modules/@linyjs/client-module-interface/package.json +26 -0
  51. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/application.ts +50 -0
  52. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/comparison-example.tsx +229 -0
  53. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/di.ts +127 -0
  54. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/domain.ts +52 -0
  55. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/hooks-example.tsx +275 -0
  56. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/hooks.ts +175 -0
  57. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/index.ts +87 -0
  58. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/interfaces.ts +117 -0
  59. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/router.ts +49 -0
  60. package/examples/hello-world/node_modules/@linyjs/client-module-interface/tsconfig.json +10 -0
  61. package/examples/hello-world/node_modules/@linyjs/server-module-interface/package.json +21 -0
  62. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/application.ts +21 -0
  63. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/di.ts +127 -0
  64. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/domain.ts +75 -0
  65. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/index.ts +55 -0
  66. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/interfaces.ts +58 -0
  67. package/examples/hello-world/node_modules/@linyjs/server-module-interface/tsconfig.json +8 -0
  68. package/examples/hello-world/node_modules/@types/react/LICENSE +21 -0
  69. package/examples/hello-world/node_modules/@types/react/README.md +15 -0
  70. package/examples/hello-world/node_modules/@types/react/canary.d.ts +129 -0
  71. package/examples/hello-world/node_modules/@types/react/compiler-runtime.d.ts +4 -0
  72. package/examples/hello-world/node_modules/@types/react/experimental.d.ts +184 -0
  73. package/examples/hello-world/node_modules/@types/react/global.d.ts +166 -0
  74. package/examples/hello-world/node_modules/@types/react/index.d.ts +4369 -0
  75. package/examples/hello-world/node_modules/@types/react/jsx-dev-runtime.d.ts +33 -0
  76. package/examples/hello-world/node_modules/@types/react/jsx-runtime.d.ts +24 -0
  77. package/examples/hello-world/node_modules/@types/react/package.json +210 -0
  78. package/examples/hello-world/node_modules/@types/react/ts5.0/canary.d.ts +129 -0
  79. package/examples/hello-world/node_modules/@types/react/ts5.0/experimental.d.ts +184 -0
  80. package/examples/hello-world/node_modules/@types/react/ts5.0/global.d.ts +166 -0
  81. package/examples/hello-world/node_modules/@types/react/ts5.0/index.d.ts +4356 -0
  82. package/examples/hello-world/node_modules/@types/react/ts5.0/jsx-dev-runtime.d.ts +33 -0
  83. package/examples/hello-world/node_modules/@types/react/ts5.0/jsx-runtime.d.ts +24 -0
  84. package/examples/hello-world/node_modules/csstype/LICENSE +19 -0
  85. package/examples/hello-world/node_modules/csstype/README.md +291 -0
  86. package/examples/hello-world/node_modules/csstype/index.d.ts +22569 -0
  87. package/examples/hello-world/node_modules/csstype/index.js.flow +6863 -0
  88. package/examples/hello-world/node_modules/csstype/package.json +70 -0
  89. package/examples/hello-world/node_modules/react/LICENSE +21 -0
  90. package/examples/hello-world/node_modules/react/README.md +37 -0
  91. package/examples/hello-world/node_modules/react/cjs/react-compiler-runtime.development.js +24 -0
  92. package/examples/hello-world/node_modules/react/cjs/react-compiler-runtime.production.js +16 -0
  93. package/examples/hello-world/node_modules/react/cjs/react-compiler-runtime.profiling.js +16 -0
  94. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.development.js +338 -0
  95. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.production.js +14 -0
  96. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.profiling.js +14 -0
  97. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.react-server.development.js +370 -0
  98. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.react-server.production.js +40 -0
  99. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.development.js +352 -0
  100. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.production.js +34 -0
  101. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.profiling.js +34 -0
  102. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.react-server.development.js +370 -0
  103. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.react-server.production.js +40 -0
  104. package/examples/hello-world/node_modules/react/cjs/react.development.js +1284 -0
  105. package/examples/hello-world/node_modules/react/cjs/react.production.js +542 -0
  106. package/examples/hello-world/node_modules/react/cjs/react.react-server.development.js +848 -0
  107. package/examples/hello-world/node_modules/react/cjs/react.react-server.production.js +423 -0
  108. package/examples/hello-world/node_modules/react/compiler-runtime.js +14 -0
  109. package/examples/hello-world/node_modules/react/index.js +7 -0
  110. package/examples/hello-world/node_modules/react/jsx-dev-runtime.js +7 -0
  111. package/examples/hello-world/node_modules/react/jsx-dev-runtime.react-server.js +7 -0
  112. package/examples/hello-world/node_modules/react/jsx-runtime.js +7 -0
  113. package/examples/hello-world/node_modules/react/jsx-runtime.react-server.js +7 -0
  114. package/examples/hello-world/node_modules/react/package.json +51 -0
  115. package/examples/hello-world/node_modules/react/react.react-server.js +7 -0
  116. package/examples/hello-world/node_modules/typescript/LICENSE.txt +55 -0
  117. package/examples/hello-world/node_modules/typescript/README.md +50 -0
  118. package/examples/hello-world/node_modules/typescript/SECURITY.md +41 -0
  119. package/examples/hello-world/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
  120. package/examples/hello-world/node_modules/typescript/bin/tsc +2 -0
  121. package/examples/hello-world/node_modules/typescript/bin/tsserver +2 -0
  122. package/examples/hello-world/node_modules/typescript/lib/_tsc.js +133818 -0
  123. package/examples/hello-world/node_modules/typescript/lib/_tsserver.js +659 -0
  124. package/examples/hello-world/node_modules/typescript/lib/_typingsInstaller.js +222 -0
  125. package/examples/hello-world/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +2122 -0
  126. package/examples/hello-world/node_modules/typescript/lib/de/diagnosticMessages.generated.json +2122 -0
  127. package/examples/hello-world/node_modules/typescript/lib/es/diagnosticMessages.generated.json +2122 -0
  128. package/examples/hello-world/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +2122 -0
  129. package/examples/hello-world/node_modules/typescript/lib/it/diagnosticMessages.generated.json +2122 -0
  130. package/examples/hello-world/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +2122 -0
  131. package/examples/hello-world/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +2122 -0
  132. package/examples/hello-world/node_modules/typescript/lib/lib.d.ts +22 -0
  133. package/examples/hello-world/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
  134. package/examples/hello-world/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
  135. package/examples/hello-world/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
  136. package/examples/hello-world/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
  137. package/examples/hello-world/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
  138. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
  139. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
  140. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
  141. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
  142. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
  143. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
  144. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
  145. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
  146. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
  147. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
  148. package/examples/hello-world/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
  149. package/examples/hello-world/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
  150. package/examples/hello-world/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
  151. package/examples/hello-world/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
  152. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
  153. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
  154. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
  155. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
  156. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
  157. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
  158. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
  159. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
  160. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
  161. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
  162. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
  163. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
  164. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
  165. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
  166. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
  167. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
  168. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
  169. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
  170. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
  171. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
  172. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
  173. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
  174. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
  175. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
  176. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
  177. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
  178. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
  179. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
  180. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
  181. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
  182. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
  183. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
  184. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
  185. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
  186. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
  187. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
  188. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
  189. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
  190. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
  191. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
  192. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
  193. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
  194. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
  195. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
  196. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
  197. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
  198. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
  199. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
  200. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
  201. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
  202. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
  203. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
  204. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
  205. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
  206. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
  207. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
  208. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
  209. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
  210. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
  211. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
  212. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
  213. package/examples/hello-world/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
  214. package/examples/hello-world/node_modules/typescript/lib/lib.es6.d.ts +23 -0
  215. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
  216. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
  217. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
  218. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
  219. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
  220. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
  221. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.float16.d.ts +445 -0
  222. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
  223. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
  224. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
  225. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
  226. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
  227. package/examples/hello-world/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
  228. package/examples/hello-world/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
  229. package/examples/hello-world/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
  230. package/examples/hello-world/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
  231. package/examples/hello-world/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
  232. package/examples/hello-world/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +2122 -0
  233. package/examples/hello-world/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +2122 -0
  234. package/examples/hello-world/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +2122 -0
  235. package/examples/hello-world/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +2122 -0
  236. package/examples/hello-world/node_modules/typescript/lib/tsc.js +8 -0
  237. package/examples/hello-world/node_modules/typescript/lib/tsserver.js +8 -0
  238. package/examples/hello-world/node_modules/typescript/lib/tsserverlibrary.d.ts +17 -0
  239. package/examples/hello-world/node_modules/typescript/lib/tsserverlibrary.js +21 -0
  240. package/examples/hello-world/node_modules/typescript/lib/typesMap.json +497 -0
  241. package/examples/hello-world/node_modules/typescript/lib/typescript.d.ts +11437 -0
  242. package/examples/hello-world/node_modules/typescript/lib/typescript.js +200276 -0
  243. package/examples/hello-world/node_modules/typescript/lib/typingsInstaller.js +8 -0
  244. package/examples/hello-world/node_modules/typescript/lib/watchGuard.js +53 -0
  245. package/examples/hello-world/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +2122 -0
  246. package/examples/hello-world/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +2122 -0
  247. package/examples/hello-world/node_modules/typescript/package.json +120 -0
  248. package/examples/hello-world/package-lock.json +74 -0
  249. package/examples/hello-world/package.json +23 -0
  250. package/examples/hello-world/src/client/index.tsx +110 -0
  251. package/examples/hello-world/src/server/index.ts +42 -0
  252. package/examples/hello-world/tsconfig.json +16 -0
  253. package/package.json +46 -0
  254. package/src/cli.ts +321 -0
@@ -0,0 +1,440 @@
1
+ # 权限管理
2
+
3
+ 本指南介绍如何在 linyjs 插件中实现基于角色的访问控制(RBAC)。
4
+
5
+ ## 概述
6
+
7
+ linyjs 提供完整的权限管理系统,支持:
8
+
9
+ - 🔐 基于角色的访问控制(RBAC)
10
+ - 🎯 细粒度的权限定义
11
+ - 🛡️ 服务端和客户端双重验证
12
+ - 🔗 路由级别的权限保护
13
+
14
+ ## 声明权限需求
15
+
16
+ 在插件的 `manifest.json` 中声明需要的权限:
17
+
18
+ ```json
19
+ {
20
+ "name": "blog-plugin",
21
+ "version": "1.0.0",
22
+ "permissions": [
23
+ "article:read",
24
+ "article:write",
25
+ "article:delete",
26
+ "admin:access"
27
+ ]
28
+ }
29
+ ```
30
+
31
+ ### 权限命名规范
32
+
33
+ 使用 `资源:操作` 格式:
34
+
35
+ ```
36
+ article:read # 读取文章
37
+ article:write # 创建/更新文章
38
+ article:delete # 删除文章
39
+ user:manage # 管理用户
40
+ admin:access # 访问管理后台
41
+ ```
42
+
43
+ ## 服务端权限检查
44
+
45
+ ### 在控制器中检查权限
46
+
47
+ ```typescript
48
+ class ArticleController {
49
+ getRoutes() {
50
+ return [
51
+ {
52
+ method: 'POST',
53
+ path: '/api/articles',
54
+ middlewares: ['auth'],
55
+ responseType: 'json',
56
+ handler: async (params: any, ctx: any) => {
57
+ const user = ctx.user;
58
+
59
+ // 检查权限
60
+ if (!user.roles?.includes('admin')) {
61
+ return {
62
+ status: 403,
63
+ data: { error: 'Admin access required' }
64
+ };
65
+ }
66
+
67
+ // 业务逻辑...
68
+ const article = await createArticle(params.body);
69
+ return { success: true, data: article };
70
+ }
71
+ }
72
+ ];
73
+ }
74
+ }
75
+ ```
76
+
77
+ ### 创建权限中间件
78
+
79
+ ```typescript
80
+ import type { IMiddlewareService } from '@linyjs/server-module-interface';
81
+
82
+ class PermissionMiddleware implements IMiddlewareService {
83
+ getMiddlewares() {
84
+ return [{
85
+ middlewareId: 'checkPermission',
86
+ handler: async (params: any, ctx: any, next: any) => {
87
+ const user = ctx.user;
88
+ const requiredPermission = params.route?.meta?.requiredPermission;
89
+
90
+ if (requiredPermission && !hasPermission(user, requiredPermission)) {
91
+ throw new Error('Insufficient permissions');
92
+ }
93
+
94
+ await next();
95
+ }
96
+ }];
97
+ }
98
+ }
99
+
100
+ function hasPermission(user: any, permission: string): boolean {
101
+ // 检查用户角色是否拥有该权限
102
+ const rolePermissions = {
103
+ admin: ['article:read', 'article:write', 'article:delete'],
104
+ editor: ['article:read', 'article:write'],
105
+ viewer: ['article:read']
106
+ };
107
+
108
+ return user.roles?.some((role: string) =>
109
+ rolePermissions[role]?.includes(permission)
110
+ );
111
+ }
112
+
113
+ export const permissionMiddlewareDef = {
114
+ serviceTag: 'permissionMiddleware',
115
+ serviceImpl: PermissionMiddleware,
116
+ meta: { usageType: 'middleware' }
117
+ };
118
+ ```
119
+
120
+ ### 使用权限中间件
121
+
122
+ ```typescript
123
+ {
124
+ method: 'DELETE',
125
+ path: '/api/articles/:id',
126
+ middlewares: ['auth', 'checkPermission'],
127
+ meta: {
128
+ requiredPermission: 'article:delete'
129
+ },
130
+ handler: async (params, ctx) => {
131
+ // 只有拥有 article:delete 权限的用户才能到达这里
132
+ await deleteArticle(params.id);
133
+ return { success: true };
134
+ }
135
+ }
136
+ ```
137
+
138
+ ## 客户端权限检查
139
+
140
+ ### 使用 usePermission Hook
141
+
142
+ ```typescript
143
+ import { usePermission } from '@linyjs/permission';
144
+
145
+ function ArticleEditor() {
146
+ const { hasPermission } = usePermission();
147
+ const canEdit = hasPermission('article:write');
148
+ const canDelete = hasPermission('article:delete');
149
+
150
+ return (
151
+ <div>
152
+ <h1>Edit Article</h1>
153
+
154
+ {canEdit && (
155
+ <button onClick={handleSave}>Save</button>
156
+ )}
157
+
158
+ {canDelete && (
159
+ <button onClick={handleDelete} style={{ color: 'red' }}>
160
+ Delete
161
+ </button>
162
+ )}
163
+
164
+ {!canEdit && (
165
+ <p>You don't have permission to edit this article.</p>
166
+ )}
167
+ </div>
168
+ );
169
+ }
170
+ ```
171
+
172
+ ### 条件渲染组件
173
+
174
+ ```typescript
175
+ import { usePermission } from '@linyjs/permission';
176
+
177
+ function ProtectedComponent({ children }: { children: React.ReactNode }) {
178
+ const { hasPermission } = usePermission();
179
+
180
+ if (!hasPermission('admin:access')) {
181
+ return null; // 不渲染
182
+ }
183
+
184
+ return <>{children}</>;
185
+ }
186
+
187
+ // 使用
188
+ function AdminPanel() {
189
+ return (
190
+ <ProtectedComponent>
191
+ <div>Admin Content</div>
192
+ </ProtectedComponent>
193
+ );
194
+ }
195
+ ```
196
+
197
+ ## 路由权限保护
198
+
199
+ ### 在路由元数据中声明权限
200
+
201
+ ```typescript
202
+ class BlogRouteService {
203
+ basePath = '/blog';
204
+
205
+ getRoutes() {
206
+ return [
207
+ {
208
+ path: '/admin',
209
+ component: ArticleManagement,
210
+ key: 'article-management',
211
+ meta: {
212
+ requiresAuth: true,
213
+ requiredPermissions: ['admin:access', 'article:write']
214
+ }
215
+ },
216
+ {
217
+ path: '/edit/:id',
218
+ component: ArticleEditor,
219
+ key: 'article-edit',
220
+ meta: {
221
+ requiresAuth: true,
222
+ requiredPermissions: ['article:write']
223
+ }
224
+ }
225
+ ];
226
+ }
227
+ }
228
+ ```
229
+
230
+ ### 路由守卫
231
+
232
+ ```typescript
233
+ {
234
+ path: '/admin',
235
+ component: AdminPanel,
236
+ key: 'admin',
237
+ guard: {
238
+ canEnter: async ({ location }) => {
239
+ const { hasPermission } = usePermission();
240
+
241
+ if (!hasPermission('admin:access')) {
242
+ return '/forbidden'; // 重定向
243
+ }
244
+
245
+ return true; // 允许访问
246
+ }
247
+ }
248
+ }
249
+ ```
250
+
251
+ ## 自定义权限逻辑
252
+
253
+ ### 基于资源的权限
254
+
255
+ ```typescript
256
+ function canEditArticle(user: any, article: any): boolean {
257
+ // 管理员可以编辑所有文章
258
+ if (user.roles?.includes('admin')) {
259
+ return true;
260
+ }
261
+
262
+ // 作者可以编辑自己的文章
263
+ if (article.authorId === user.id) {
264
+ return true;
265
+ }
266
+
267
+ // 编辑可以编辑任何文章
268
+ if (user.roles?.includes('editor')) {
269
+ return true;
270
+ }
271
+
272
+ return false;
273
+ }
274
+
275
+ // 在组件中使用
276
+ function ArticlePage({ articleId }: { articleId: number }) {
277
+ const { user } = useAuth();
278
+ const [article, setArticle] = useState(null);
279
+ const [canEdit, setCanEdit] = useState(false);
280
+
281
+ useEffect(() => {
282
+ fetch(`/api/articles/${articleId}`)
283
+ .then(res => res.json())
284
+ .then(data => {
285
+ setArticle(data);
286
+ setCanEdit(canEditArticle(user, data));
287
+ });
288
+ }, [articleId, user]);
289
+
290
+ return (
291
+ <div>
292
+ <h1>{article?.title}</h1>
293
+ {canEdit && <EditButton />}
294
+ </div>
295
+ );
296
+ }
297
+ ```
298
+
299
+ ### 动态权限检查
300
+
301
+ ```typescript
302
+ function useArticlePermission(articleId: number) {
303
+ const { user } = useAuth();
304
+ const [permissions, setPermissions] = useState({
305
+ canRead: false,
306
+ canWrite: false,
307
+ canDelete: false
308
+ });
309
+
310
+ useEffect(() => {
311
+ fetch(`/api/articles/${articleId}/permissions`)
312
+ .then(res => res.json())
313
+ .then(setPermissions);
314
+ }, [articleId]);
315
+
316
+ return permissions;
317
+ }
318
+
319
+ // 使用
320
+ function ArticleActions({ articleId }: { articleId: number }) {
321
+ const { canWrite, canDelete } = useArticlePermission(articleId);
322
+
323
+ return (
324
+ <div>
325
+ {canWrite && <EditButton />}
326
+ {canDelete && <DeleteButton />}
327
+ </div>
328
+ );
329
+ }
330
+ ```
331
+
332
+ ## 权限层级
333
+
334
+ ### 定义权限层级
335
+
336
+ ```typescript
337
+ const permissionHierarchy = {
338
+ 'article:delete': ['article:write', 'article:read'],
339
+ 'article:write': ['article:read'],
340
+ 'admin:access': ['article:read', 'article:write', 'article:delete']
341
+ };
342
+
343
+ function hasPermissionWithHierarchy(
344
+ user: any,
345
+ requiredPermission: string
346
+ ): boolean {
347
+ // 直接检查
348
+ if (user.permissions?.includes(requiredPermission)) {
349
+ return true;
350
+ }
351
+
352
+ // 检查父权限
353
+ const parentPermissions = Object.entries(permissionHierarchy)
354
+ .filter(([_, children]) => children.includes(requiredPermission))
355
+ .map(([parent]) => parent);
356
+
357
+ return parentPermissions.some(parent =>
358
+ user.permissions?.includes(parent)
359
+ );
360
+ }
361
+ ```
362
+
363
+ ## 最佳实践
364
+
365
+ ### 1. 最小权限原则
366
+
367
+ 只授予必要的权限:
368
+
369
+ ```typescript
370
+ // ✅ 好的做法 - 精确权限
371
+ permissions: ['article:read']
372
+
373
+ // ❌ 避免 - 过度授权
374
+ permissions: ['admin:access']
375
+ ```
376
+
377
+ ### 2. 服务端验证
378
+
379
+ 永远不要仅依赖客户端权限检查:
380
+
381
+ ```typescript
382
+ // 服务端必须再次验证
383
+ handler: async (params, ctx) => {
384
+ // 即使客户端已检查,服务端仍需验证
385
+ if (!hasPermission(ctx.user, 'article:delete')) {
386
+ return { status: 403, data: { error: 'Forbidden' } };
387
+ }
388
+
389
+ // 执行删除
390
+ }
391
+ ```
392
+
393
+ ### 3. 清晰的错误消息
394
+
395
+ ```typescript
396
+ if (!hasPermission(user, 'article:write')) {
397
+ return {
398
+ status: 403,
399
+ data: {
400
+ error: 'You do not have permission to edit articles',
401
+ requiredPermission: 'article:write'
402
+ }
403
+ };
404
+ }
405
+ ```
406
+
407
+ ### 4. 权限缓存
408
+
409
+ ```typescript
410
+ import { useMemo } from 'react';
411
+
412
+ function useUserPermissions() {
413
+ const { user } = useAuth();
414
+
415
+ const permissions = useMemo(() => {
416
+ return new Set(user?.permissions || []);
417
+ }, [user]);
418
+
419
+ const hasPermission = useCallback((permission: string) => {
420
+ return permissions.has(permission);
421
+ }, [permissions]);
422
+
423
+ return { hasPermission };
424
+ }
425
+ ```
426
+
427
+ ## 完整示例
428
+
429
+ 查看博客插件中的权限实现:
430
+
431
+ - 📁 [Blog Plugin 示例](../../examples/blog-plugin/)
432
+
433
+ ## 相关文档
434
+
435
+ - 🎨 [UI 扩展插槽](./ui-slots.md)
436
+ - 💾 [数据持久化](./data-persistence.md)
437
+
438
+ ---
439
+
440
+ **上一篇**: [UI 扩展插槽](./ui-slots.md) | **下一篇**: [数据持久化](./data-persistence.md)