@linyjs/plugin-docs 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 (252) hide show
  1. package/README.md +97 -0
  2. package/docs/api-reference/index.md +341 -0
  3. package/docs/best-practices/error-handling.md +462 -0
  4. package/docs/best-practices/naming-conventions.md +495 -0
  5. package/docs/best-practices/performance.md +532 -0
  6. package/docs/best-practices/security.md +620 -0
  7. package/docs/faq.md +323 -0
  8. package/docs/getting-started/first-plugin.md +358 -0
  9. package/docs/getting-started/installation.md +244 -0
  10. package/docs/getting-started/quick-start.md +174 -0
  11. package/docs/guides/client-module.md +598 -0
  12. package/docs/guides/data-persistence.md +536 -0
  13. package/docs/guides/permissions.md +440 -0
  14. package/docs/guides/server-module.md +371 -0
  15. package/docs/guides/ui-slots.md +475 -0
  16. package/docs/migration/v0-to-v1.md +354 -0
  17. package/examples/analytics-plugin/README.md +416 -0
  18. package/examples/analytics-plugin/dist/client/index.d.ts +36 -0
  19. package/examples/analytics-plugin/dist/client/index.js +173 -0
  20. package/examples/analytics-plugin/dist/index.d.ts +64 -0
  21. package/examples/analytics-plugin/dist/index.js +72 -0
  22. package/examples/analytics-plugin/dist/server/index.d.ts +119 -0
  23. package/examples/analytics-plugin/dist/server/index.js +313 -0
  24. package/examples/analytics-plugin/package.json +28 -0
  25. package/examples/analytics-plugin/src/client/index.tsx +410 -0
  26. package/examples/analytics-plugin/src/index.ts +71 -0
  27. package/examples/analytics-plugin/src/server/index.ts +348 -0
  28. package/examples/analytics-plugin/tsconfig.json +21 -0
  29. package/examples/blog-plugin/README.md +316 -0
  30. package/examples/blog-plugin/dist/client/index.d.ts +22 -0
  31. package/examples/blog-plugin/dist/client/index.js +197 -0
  32. package/examples/blog-plugin/dist/server/index.d.ts +5 -0
  33. package/examples/blog-plugin/dist/server/index.js +220 -0
  34. package/examples/blog-plugin/package.json +24 -0
  35. package/examples/blog-plugin/src/client/index.tsx +405 -0
  36. package/examples/blog-plugin/src/server/index.ts +240 -0
  37. package/examples/blog-plugin/tsconfig.json +16 -0
  38. package/examples/hello-world/README.md +101 -0
  39. package/examples/hello-world/dist/client/index.d.ts +5 -0
  40. package/examples/hello-world/dist/client/index.js +80 -0
  41. package/examples/hello-world/dist/server/index.d.ts +5 -0
  42. package/examples/hello-world/dist/server/index.js +38 -0
  43. package/examples/hello-world/node_modules/.package-lock.json +61 -0
  44. package/examples/hello-world/node_modules/@linyjs/client-module-interface/HOOKS_USAGE.md +281 -0
  45. package/examples/hello-world/node_modules/@linyjs/client-module-interface/IMPLEMENTATION_SUMMARY.md +166 -0
  46. package/examples/hello-world/node_modules/@linyjs/client-module-interface/QUICK_REFERENCE.md +130 -0
  47. package/examples/hello-world/node_modules/@linyjs/client-module-interface/README.md +214 -0
  48. package/examples/hello-world/node_modules/@linyjs/client-module-interface/package.json +26 -0
  49. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/application.ts +50 -0
  50. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/comparison-example.tsx +229 -0
  51. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/di.ts +127 -0
  52. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/domain.ts +52 -0
  53. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/hooks-example.tsx +275 -0
  54. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/hooks.ts +175 -0
  55. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/index.ts +87 -0
  56. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/interfaces.ts +117 -0
  57. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/router.ts +49 -0
  58. package/examples/hello-world/node_modules/@linyjs/client-module-interface/tsconfig.json +10 -0
  59. package/examples/hello-world/node_modules/@linyjs/server-module-interface/package.json +21 -0
  60. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/application.ts +21 -0
  61. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/di.ts +127 -0
  62. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/domain.ts +75 -0
  63. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/index.ts +55 -0
  64. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/interfaces.ts +58 -0
  65. package/examples/hello-world/node_modules/@linyjs/server-module-interface/tsconfig.json +8 -0
  66. package/examples/hello-world/node_modules/@types/react/LICENSE +21 -0
  67. package/examples/hello-world/node_modules/@types/react/README.md +15 -0
  68. package/examples/hello-world/node_modules/@types/react/canary.d.ts +129 -0
  69. package/examples/hello-world/node_modules/@types/react/compiler-runtime.d.ts +4 -0
  70. package/examples/hello-world/node_modules/@types/react/experimental.d.ts +184 -0
  71. package/examples/hello-world/node_modules/@types/react/global.d.ts +166 -0
  72. package/examples/hello-world/node_modules/@types/react/index.d.ts +4369 -0
  73. package/examples/hello-world/node_modules/@types/react/jsx-dev-runtime.d.ts +33 -0
  74. package/examples/hello-world/node_modules/@types/react/jsx-runtime.d.ts +24 -0
  75. package/examples/hello-world/node_modules/@types/react/package.json +210 -0
  76. package/examples/hello-world/node_modules/@types/react/ts5.0/canary.d.ts +129 -0
  77. package/examples/hello-world/node_modules/@types/react/ts5.0/experimental.d.ts +184 -0
  78. package/examples/hello-world/node_modules/@types/react/ts5.0/global.d.ts +166 -0
  79. package/examples/hello-world/node_modules/@types/react/ts5.0/index.d.ts +4356 -0
  80. package/examples/hello-world/node_modules/@types/react/ts5.0/jsx-dev-runtime.d.ts +33 -0
  81. package/examples/hello-world/node_modules/@types/react/ts5.0/jsx-runtime.d.ts +24 -0
  82. package/examples/hello-world/node_modules/csstype/LICENSE +19 -0
  83. package/examples/hello-world/node_modules/csstype/README.md +291 -0
  84. package/examples/hello-world/node_modules/csstype/index.d.ts +22569 -0
  85. package/examples/hello-world/node_modules/csstype/index.js.flow +6863 -0
  86. package/examples/hello-world/node_modules/csstype/package.json +70 -0
  87. package/examples/hello-world/node_modules/react/LICENSE +21 -0
  88. package/examples/hello-world/node_modules/react/README.md +37 -0
  89. package/examples/hello-world/node_modules/react/cjs/react-compiler-runtime.development.js +24 -0
  90. package/examples/hello-world/node_modules/react/cjs/react-compiler-runtime.production.js +16 -0
  91. package/examples/hello-world/node_modules/react/cjs/react-compiler-runtime.profiling.js +16 -0
  92. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.development.js +338 -0
  93. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.production.js +14 -0
  94. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.profiling.js +14 -0
  95. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.react-server.development.js +370 -0
  96. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.react-server.production.js +40 -0
  97. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.development.js +352 -0
  98. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.production.js +34 -0
  99. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.profiling.js +34 -0
  100. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.react-server.development.js +370 -0
  101. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.react-server.production.js +40 -0
  102. package/examples/hello-world/node_modules/react/cjs/react.development.js +1284 -0
  103. package/examples/hello-world/node_modules/react/cjs/react.production.js +542 -0
  104. package/examples/hello-world/node_modules/react/cjs/react.react-server.development.js +848 -0
  105. package/examples/hello-world/node_modules/react/cjs/react.react-server.production.js +423 -0
  106. package/examples/hello-world/node_modules/react/compiler-runtime.js +14 -0
  107. package/examples/hello-world/node_modules/react/index.js +7 -0
  108. package/examples/hello-world/node_modules/react/jsx-dev-runtime.js +7 -0
  109. package/examples/hello-world/node_modules/react/jsx-dev-runtime.react-server.js +7 -0
  110. package/examples/hello-world/node_modules/react/jsx-runtime.js +7 -0
  111. package/examples/hello-world/node_modules/react/jsx-runtime.react-server.js +7 -0
  112. package/examples/hello-world/node_modules/react/package.json +51 -0
  113. package/examples/hello-world/node_modules/react/react.react-server.js +7 -0
  114. package/examples/hello-world/node_modules/typescript/LICENSE.txt +55 -0
  115. package/examples/hello-world/node_modules/typescript/README.md +50 -0
  116. package/examples/hello-world/node_modules/typescript/SECURITY.md +41 -0
  117. package/examples/hello-world/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
  118. package/examples/hello-world/node_modules/typescript/bin/tsc +2 -0
  119. package/examples/hello-world/node_modules/typescript/bin/tsserver +2 -0
  120. package/examples/hello-world/node_modules/typescript/lib/_tsc.js +133818 -0
  121. package/examples/hello-world/node_modules/typescript/lib/_tsserver.js +659 -0
  122. package/examples/hello-world/node_modules/typescript/lib/_typingsInstaller.js +222 -0
  123. package/examples/hello-world/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +2122 -0
  124. package/examples/hello-world/node_modules/typescript/lib/de/diagnosticMessages.generated.json +2122 -0
  125. package/examples/hello-world/node_modules/typescript/lib/es/diagnosticMessages.generated.json +2122 -0
  126. package/examples/hello-world/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +2122 -0
  127. package/examples/hello-world/node_modules/typescript/lib/it/diagnosticMessages.generated.json +2122 -0
  128. package/examples/hello-world/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +2122 -0
  129. package/examples/hello-world/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +2122 -0
  130. package/examples/hello-world/node_modules/typescript/lib/lib.d.ts +22 -0
  131. package/examples/hello-world/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
  132. package/examples/hello-world/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
  133. package/examples/hello-world/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
  134. package/examples/hello-world/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
  135. package/examples/hello-world/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
  136. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
  137. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
  138. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
  139. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
  140. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
  141. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
  142. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
  143. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
  144. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
  145. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
  146. package/examples/hello-world/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
  147. package/examples/hello-world/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
  148. package/examples/hello-world/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
  149. package/examples/hello-world/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
  150. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
  151. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
  152. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
  153. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
  154. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
  155. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
  156. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
  157. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
  158. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
  159. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
  160. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
  161. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
  162. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
  163. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
  164. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
  165. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
  166. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
  167. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
  168. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
  169. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
  170. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
  171. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
  172. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
  173. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
  174. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
  175. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
  176. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
  177. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
  178. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
  179. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
  180. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
  181. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
  182. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
  183. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
  184. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
  185. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
  186. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
  187. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
  188. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
  189. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
  190. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
  191. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
  192. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
  193. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
  194. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
  195. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
  196. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
  197. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
  198. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
  199. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
  200. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
  201. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
  202. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
  203. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
  204. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
  205. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
  206. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
  207. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
  208. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
  209. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
  210. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
  211. package/examples/hello-world/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
  212. package/examples/hello-world/node_modules/typescript/lib/lib.es6.d.ts +23 -0
  213. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
  214. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
  215. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
  216. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
  217. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
  218. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
  219. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.float16.d.ts +445 -0
  220. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
  221. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
  222. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
  223. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
  224. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
  225. package/examples/hello-world/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
  226. package/examples/hello-world/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
  227. package/examples/hello-world/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
  228. package/examples/hello-world/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
  229. package/examples/hello-world/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
  230. package/examples/hello-world/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +2122 -0
  231. package/examples/hello-world/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +2122 -0
  232. package/examples/hello-world/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +2122 -0
  233. package/examples/hello-world/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +2122 -0
  234. package/examples/hello-world/node_modules/typescript/lib/tsc.js +8 -0
  235. package/examples/hello-world/node_modules/typescript/lib/tsserver.js +8 -0
  236. package/examples/hello-world/node_modules/typescript/lib/tsserverlibrary.d.ts +17 -0
  237. package/examples/hello-world/node_modules/typescript/lib/tsserverlibrary.js +21 -0
  238. package/examples/hello-world/node_modules/typescript/lib/typesMap.json +497 -0
  239. package/examples/hello-world/node_modules/typescript/lib/typescript.d.ts +11437 -0
  240. package/examples/hello-world/node_modules/typescript/lib/typescript.js +200276 -0
  241. package/examples/hello-world/node_modules/typescript/lib/typingsInstaller.js +8 -0
  242. package/examples/hello-world/node_modules/typescript/lib/watchGuard.js +53 -0
  243. package/examples/hello-world/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +2122 -0
  244. package/examples/hello-world/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +2122 -0
  245. package/examples/hello-world/node_modules/typescript/package.json +120 -0
  246. package/examples/hello-world/package-lock.json +74 -0
  247. package/examples/hello-world/package.json +23 -0
  248. package/examples/hello-world/src/client/index.tsx +110 -0
  249. package/examples/hello-world/src/server/index.ts +42 -0
  250. package/examples/hello-world/tsconfig.json +16 -0
  251. package/package.json +42 -0
  252. package/src/cli.ts +321 -0
@@ -0,0 +1,536 @@
1
+ # 数据持久化
2
+
3
+ 本指南介绍如何在 linyjs 插件中使用 MongoDB 进行数据持久化。
4
+
5
+ ## 概述
6
+
7
+ linyjs 提供 MongoDB 服务,支持:
8
+
9
+ - 💾 CRUD 操作(创建、读取、更新、删除)
10
+ - 🔍 复杂查询和聚合
11
+ - 📊 索引优化
12
+ - 🔗 数据关联
13
+
14
+ ## 配置 MongoDB 服务
15
+
16
+ ### 在服务端模块中注入依赖
17
+
18
+ ```typescript
19
+ import type { IModule } from '@linyjs/server-module-interface';
20
+
21
+ export const myServerModule: IModule = {
22
+ name: 'myServer',
23
+ moduleDependencies: ['mongodb'], // 依赖 MongoDB 模块
24
+ serviceDefs: [
25
+ {
26
+ serviceTag: 'articleService',
27
+ serviceImpl: ArticleService,
28
+ dependencies: ['mongodb.mongodb'], // 注入 MongoDB 服务
29
+ meta: { usageType: 'normal_service' }
30
+ }
31
+ ]
32
+ };
33
+ ```
34
+
35
+ ## 基本 CRUD 操作
36
+
37
+ ### 创建(Create)
38
+
39
+ ```typescript
40
+ import type { IMongoDBService } from '@linyjs/mongodb';
41
+
42
+ class ArticleService {
43
+ constructor(private mongodb: IMongoDBService) {}
44
+
45
+ async createArticle(data: any) {
46
+ const db = this.mongodb.getDb();
47
+ const collection = db.collection('articles');
48
+
49
+ const result = await collection.insertOne({
50
+ ...data,
51
+ createdAt: new Date(),
52
+ updatedAt: new Date()
53
+ });
54
+
55
+ return {
56
+ id: result.insertedId,
57
+ ...data
58
+ };
59
+ }
60
+ }
61
+ ```
62
+
63
+ ### 读取(Read)
64
+
65
+ #### 获取单个文档
66
+
67
+ ```typescript
68
+ async getArticleById(id: string) {
69
+ const db = this.mongodb.getDb();
70
+ const collection = db.collection('articles');
71
+
72
+ const article = await collection.findOne({
73
+ _id: new ObjectId(id)
74
+ });
75
+
76
+ if (!article) {
77
+ throw new Error('Article not found');
78
+ }
79
+
80
+ return article;
81
+ }
82
+ ```
83
+
84
+ #### 获取列表(支持分页)
85
+
86
+ ```typescript
87
+ async getArticles(page = 1, limit = 10) {
88
+ const db = this.mongodb.getDb();
89
+ const collection = db.collection('articles');
90
+
91
+ const skip = (page - 1) * limit;
92
+
93
+ // 获取总数
94
+ const total = await collection.countDocuments();
95
+
96
+ // 获取数据
97
+ const articles = await collection.find()
98
+ .skip(skip)
99
+ .limit(limit)
100
+ .sort({ createdAt: -1 })
101
+ .toArray();
102
+
103
+ return {
104
+ data: articles,
105
+ total,
106
+ page,
107
+ limit,
108
+ totalPages: Math.ceil(total / limit)
109
+ };
110
+ }
111
+ ```
112
+
113
+ #### 条件查询
114
+
115
+ ```typescript
116
+ async getArticlesByAuthor(authorId: string) {
117
+ const db = this.mongodb.getDb();
118
+ const collection = db.collection('articles');
119
+
120
+ const articles = await collection.find({
121
+ authorId
122
+ }).toArray();
123
+
124
+ return articles;
125
+ }
126
+ ```
127
+
128
+ ### 更新(Update)
129
+
130
+ #### 完整更新
131
+
132
+ ```typescript
133
+ async updateArticle(id: string, data: any) {
134
+ const db = this.mongodb.getDb();
135
+ const collection = db.collection('articles');
136
+
137
+ const result = await collection.updateOne(
138
+ { _id: new ObjectId(id) },
139
+ {
140
+ $set: {
141
+ ...data,
142
+ updatedAt: new Date()
143
+ }
144
+ }
145
+ );
146
+
147
+ if (result.matchedCount === 0) {
148
+ throw new Error('Article not found');
149
+ }
150
+
151
+ return { success: true };
152
+ }
153
+ ```
154
+
155
+ #### 部分更新
156
+
157
+ ```typescript
158
+ async updateArticleTitle(id: string, title: string) {
159
+ const db = this.mongodb.getDb();
160
+ const collection = db.collection('articles');
161
+
162
+ await collection.updateOne(
163
+ { _id: new ObjectId(id) },
164
+ {
165
+ $set: {
166
+ title,
167
+ updatedAt: new Date()
168
+ }
169
+ }
170
+ );
171
+ }
172
+ ```
173
+
174
+ ### 删除(Delete)
175
+
176
+ ```typescript
177
+ async deleteArticle(id: string) {
178
+ const db = this.mongodb.getDb();
179
+ const collection = db.collection('articles');
180
+
181
+ const result = await collection.deleteOne({
182
+ _id: new ObjectId(id)
183
+ });
184
+
185
+ if (result.deletedCount === 0) {
186
+ throw new Error('Article not found');
187
+ }
188
+
189
+ return { success: true };
190
+ }
191
+ ```
192
+
193
+ ## 高级查询
194
+
195
+ ### 复杂条件
196
+
197
+ ```typescript
198
+ async searchArticles(query: string, options: any) {
199
+ const db = this.mongodb.getDb();
200
+ const collection = db.collection('articles');
201
+
202
+ // 构建查询条件
203
+ const conditions: any = {};
204
+
205
+ if (query) {
206
+ conditions.$or = [
207
+ { title: { $regex: query, $options: 'i' } },
208
+ { content: { $regex: query, $options: 'i' } }
209
+ ];
210
+ }
211
+
212
+ if (options.authorId) {
213
+ conditions.authorId = options.authorId;
214
+ }
215
+
216
+ if (options.status) {
217
+ conditions.status = options.status;
218
+ }
219
+
220
+ // 日期范围
221
+ if (options.startDate || options.endDate) {
222
+ conditions.createdAt = {};
223
+ if (options.startDate) {
224
+ conditions.createdAt.$gte = new Date(options.startDate);
225
+ }
226
+ if (options.endDate) {
227
+ conditions.createdAt.$lte = new Date(options.endDate);
228
+ }
229
+ }
230
+
231
+ const articles = await collection.find(conditions).toArray();
232
+
233
+ return articles;
234
+ }
235
+ ```
236
+
237
+ ### 聚合管道
238
+
239
+ ```typescript
240
+ async getArticleStats() {
241
+ const db = this.mongodb.getDb();
242
+ const collection = db.collection('articles');
243
+
244
+ const stats = await collection.aggregate([
245
+ // 按作者分组
246
+ {
247
+ $group: {
248
+ _id: '$authorId',
249
+ articleCount: { $sum: 1 },
250
+ totalViews: { $sum: '$views' },
251
+ avgViews: { $avg: '$views' }
252
+ }
253
+ },
254
+ // 排序
255
+ {
256
+ $sort: { articleCount: -1 }
257
+ },
258
+ // 限制结果数
259
+ {
260
+ $limit: 10
261
+ }
262
+ ]).toArray();
263
+
264
+ return stats;
265
+ }
266
+ ```
267
+
268
+ ### 联表查询
269
+
270
+ ```typescript
271
+ async getArticlesWithAuthors() {
272
+ const db = this.mongodb.getDb();
273
+ const articlesCollection = db.collection('articles');
274
+ const usersCollection = db.collection('users');
275
+
276
+ const articles = await articlesCollection.aggregate([
277
+ // 联查用户表
278
+ {
279
+ $lookup: {
280
+ from: 'users',
281
+ localField: 'authorId',
282
+ foreignField: '_id',
283
+ as: 'author'
284
+ }
285
+ },
286
+ // 展开数组
287
+ {
288
+ $unwind: '$author'
289
+ },
290
+ // 投影字段
291
+ {
292
+ $project: {
293
+ title: 1,
294
+ content: 1,
295
+ createdAt: 1,
296
+ 'author.name': 1,
297
+ 'author.email': 1
298
+ }
299
+ }
300
+ ]).toArray();
301
+
302
+ return articles;
303
+ }
304
+ ```
305
+
306
+ ## 索引优化
307
+
308
+ ### 创建索引
309
+
310
+ ```typescript
311
+ async createIndexes() {
312
+ const db = this.mongodb.getDb();
313
+ const collection = db.collection('articles');
314
+
315
+ // 单字段索引
316
+ await collection.createIndex({ authorId: 1 });
317
+
318
+ // 复合索引
319
+ await collection.createIndex({ authorId: 1, createdAt: -1 });
320
+
321
+ // 文本索引(用于全文搜索)
322
+ await collection.createIndex({
323
+ title: 'text',
324
+ content: 'text'
325
+ });
326
+
327
+ // 唯一索引
328
+ await collection.createIndex({ slug: 1 }, { unique: true });
329
+ }
330
+ ```
331
+
332
+ ### 使用索引
333
+
334
+ ```typescript
335
+ // MongoDB 会自动使用合适的索引
336
+ async getArticlesByAuthor(authorId: string) {
337
+ const db = this.mongodb.getDb();
338
+ const collection = db.collection('articles');
339
+
340
+ // 自动使用 authorId 索引
341
+ return await collection.find({ authorId }).toArray();
342
+ }
343
+ ```
344
+
345
+ ## 事务处理
346
+
347
+ ### 使用事务
348
+
349
+ ```typescript
350
+ async transferArticleAuthor(articleId: string, newAuthorId: string) {
351
+ const db = this.mongodb.getDb();
352
+ const session = db.startSession();
353
+
354
+ try {
355
+ session.startTransaction();
356
+
357
+ const articlesCollection = db.collection('articles');
358
+ const usersCollection = db.collection('users');
359
+
360
+ // 检查新作者是否存在
361
+ const user = await usersCollection.findOne(
362
+ { _id: new ObjectId(newAuthorId) },
363
+ { session }
364
+ );
365
+
366
+ if (!user) {
367
+ throw new Error('User not found');
368
+ }
369
+
370
+ // 更新文章作者
371
+ await articlesCollection.updateOne(
372
+ { _id: new ObjectId(articleId) },
373
+ { $set: { authorId: newAuthorId } },
374
+ { session }
375
+ );
376
+
377
+ // 提交事务
378
+ await session.commitTransaction();
379
+
380
+ return { success: true };
381
+ } catch (error) {
382
+ // 回滚事务
383
+ await session.abortTransaction();
384
+ throw error;
385
+ } finally {
386
+ session.endSession();
387
+ }
388
+ }
389
+ ```
390
+
391
+ ## 数据验证
392
+
393
+ ### Schema 验证
394
+
395
+ ```typescript
396
+ async createArticle(data: any) {
397
+ // 验证必填字段
398
+ if (!data.title || !data.content) {
399
+ throw new Error('Title and content are required');
400
+ }
401
+
402
+ // 验证标题长度
403
+ if (data.title.length > 200) {
404
+ throw new Error('Title too long');
405
+ }
406
+
407
+ // 验证内容长度
408
+ if (data.content.length > 50000) {
409
+ throw new Error('Content too long');
410
+ }
411
+
412
+ const db = this.mongodb.getDb();
413
+ const collection = db.collection('articles');
414
+
415
+ return await collection.insertOne({
416
+ title: data.title.trim(),
417
+ content: data.content.trim(),
418
+ authorId: data.authorId,
419
+ status: 'draft',
420
+ createdAt: new Date(),
421
+ updatedAt: new Date()
422
+ });
423
+ }
424
+ ```
425
+
426
+ ## 最佳实践
427
+
428
+ ### 1. 错误处理
429
+
430
+ ```typescript
431
+ async safeOperation() {
432
+ try {
433
+ const db = this.mongodb.getDb();
434
+ const collection = db.collection('articles');
435
+
436
+ const result = await collection.insertOne({ /* ... */ });
437
+ return result;
438
+ } catch (error) {
439
+ console.error('Database operation failed:', error);
440
+ throw new Error('Failed to save article');
441
+ }
442
+ }
443
+ ```
444
+
445
+ ### 2. 连接池管理
446
+
447
+ MongoDB 驱动会自动管理连接池,无需手动处理。
448
+
449
+ ### 3. 避免 N+1 查询
450
+
451
+ ```typescript
452
+ // ❌ 糟糕的做法 - N+1 查询
453
+ async getArticlesWithAuthors() {
454
+ const articles = await collection.find().toArray();
455
+
456
+ for (const article of articles) {
457
+ article.author = await usersCollection.findOne({
458
+ _id: article.authorId
459
+ });
460
+ }
461
+
462
+ return articles;
463
+ }
464
+
465
+ // ✅ 好的做法 - 使用聚合
466
+ async getArticlesWithAuthors() {
467
+ return await collection.aggregate([
468
+ {
469
+ $lookup: {
470
+ from: 'users',
471
+ localField: 'authorId',
472
+ foreignField: '_id',
473
+ as: 'author'
474
+ }
475
+ },
476
+ { $unwind: '$author' }
477
+ ]).toArray();
478
+ }
479
+ ```
480
+
481
+ ### 4. 分页优化
482
+
483
+ ```typescript
484
+ async getArticlesPaginated(page: number, limit: number) {
485
+ const db = this.mongodb.getDb();
486
+ const collection = db.collection('articles');
487
+
488
+ // 使用游标分页(更高效)
489
+ const skip = (page - 1) * limit;
490
+
491
+ return await collection.find()
492
+ .skip(skip)
493
+ .limit(limit)
494
+ .sort({ createdAt: -1 })
495
+ .toArray();
496
+ }
497
+ ```
498
+
499
+ ### 5. 数据缓存
500
+
501
+ ```typescript
502
+ import NodeCache from 'node-cache';
503
+
504
+ const cache = new NodeCache({ stdTTL: 300 }); // 5分钟缓存
505
+
506
+ async getCachedArticle(id: string) {
507
+ // 检查缓存
508
+ const cached = cache.get(id);
509
+ if (cached) {
510
+ return cached;
511
+ }
512
+
513
+ // 从数据库获取
514
+ const article = await this.getArticleById(id);
515
+
516
+ // 存入缓存
517
+ cache.set(id, article);
518
+
519
+ return article;
520
+ }
521
+ ```
522
+
523
+ ## 完整示例
524
+
525
+ 查看博客插件中的数据持久化实现:
526
+
527
+ - 📁 [Blog Plugin 示例](../../examples/blog-plugin/src/server/services/ArticleService.ts)
528
+
529
+ ## 相关文档
530
+
531
+ - 🔒 [权限管理](./permissions.md)
532
+ - 🎨 [UI 扩展插槽](./ui-slots.md)
533
+
534
+ ---
535
+
536
+ **上一篇**: [权限管理](./permissions.md) | **下一篇**: [最佳实践](../best-practices/naming-conventions.md)