sumba 2.0.0 → 2.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 (280) hide show
  1. package/.github/FUNDING.yml +13 -0
  2. package/.github/workflows/repo-lockdown.yml +24 -0
  3. package/.jsdoc.conf.json +45 -0
  4. package/LICENSE +1 -1
  5. package/README.md +40 -7
  6. package/docs/Sumba.html +3 -0
  7. package/docs/data/search.json +1 -0
  8. package/docs/fonts/Inconsolata-Regular.ttf +0 -0
  9. package/docs/fonts/OpenSans-Regular.ttf +0 -0
  10. package/docs/fonts/WorkSans-Bold.ttf +0 -0
  11. package/docs/global.html +3 -0
  12. package/docs/index.html +3 -0
  13. package/docs/index.js.html +538 -0
  14. package/docs/scripts/core.js +726 -0
  15. package/docs/scripts/core.min.js +23 -0
  16. package/docs/scripts/resize.js +90 -0
  17. package/docs/scripts/search.js +265 -0
  18. package/docs/scripts/search.min.js +6 -0
  19. package/docs/scripts/third-party/Apache-License-2.0.txt +202 -0
  20. package/docs/scripts/third-party/fuse.js +9 -0
  21. package/docs/scripts/third-party/hljs-line-num-original.js +369 -0
  22. package/docs/scripts/third-party/hljs-line-num.js +1 -0
  23. package/docs/scripts/third-party/hljs-original.js +5171 -0
  24. package/docs/scripts/third-party/hljs.js +1 -0
  25. package/docs/scripts/third-party/popper.js +5 -0
  26. package/docs/scripts/third-party/tippy.js +1 -0
  27. package/docs/scripts/third-party/tocbot.js +672 -0
  28. package/docs/scripts/third-party/tocbot.min.js +1 -0
  29. package/docs/static/bitcoin.jpeg +0 -0
  30. package/docs/static/home.md +25 -0
  31. package/docs/static/logo-ecosystem.png +0 -0
  32. package/docs/static/logo.png +0 -0
  33. package/docs/styles/clean-jsdoc-theme-base.css +1159 -0
  34. package/docs/styles/clean-jsdoc-theme-dark.css +412 -0
  35. package/docs/styles/clean-jsdoc-theme-light.css +482 -0
  36. package/docs/styles/clean-jsdoc-theme-scrollbar.css +30 -0
  37. package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +1 -0
  38. package/docs/styles/clean-jsdoc-theme.min.css +1 -0
  39. package/extend/bajo/hook/{dobo.sumba-contact-form@after-record-create.js → dobo.sumba-contact-form@after-create-record.js} +3 -3
  40. package/extend/bajo/hook/{dobo.sumba-contact-form@before-record-create.js → dobo.sumba-contact-form@before-create-record.js} +3 -3
  41. package/extend/bajo/hook/{dobo.sumba-user@after-record-create.js → dobo.sumba-user@after-create-record.js} +3 -3
  42. package/extend/bajo/hook/dobo.sumba-user@after-record-validation.js +3 -3
  43. package/extend/bajo/hook/{dobo.sumba-user@after-record-update.js → dobo.sumba-user@after-update-record.js} +5 -5
  44. package/extend/bajo/hook/{dobo.sumba-user@before-record-create.js → dobo.sumba-user@before-create-record.js} +2 -2
  45. package/extend/bajo/hook/dobo.sumba-user@before-record-validation.js +3 -3
  46. package/extend/bajo/hook/{dobo.sumba-user@before-record-update.js → dobo.sumba-user@before-update-record.js} +2 -2
  47. package/extend/bajo/hook/dobo@before-count-record.js +8 -0
  48. package/extend/bajo/hook/{dobo@before-record-create.js → dobo@before-create-record.js} +6 -6
  49. package/extend/bajo/hook/dobo@before-find-one-record.js +8 -0
  50. package/extend/bajo/hook/{dobo@before-record-find.js → dobo@before-find-record.js} +10 -10
  51. package/extend/bajo/hook/dobo@before-get-record.js +23 -0
  52. package/extend/bajo/hook/dobo@before-remove-record.js +10 -0
  53. package/extend/bajo/hook/dobo@before-update-record.js +10 -0
  54. package/extend/bajo/hook/waibu-mpa.sumba@after-build-locals.js +0 -0
  55. package/extend/bajo/hook/waibu-mpa@pre-parsing.js +0 -0
  56. package/extend/bajo/hook/waibu-rest-api@pre-parsing.js +0 -0
  57. package/extend/bajo/hook/waibu-static@pre-parsing.js +0 -0
  58. package/extend/bajo/hook/waibu@after-app-boot.js +2 -2
  59. package/extend/bajo/hook/waibu@after-create-context.js +0 -0
  60. package/extend/bajo/hook/waibu@on-request.js +0 -0
  61. package/extend/bajo/intl/en-US.json +1 -0
  62. package/extend/bajo/intl/id.json +0 -0
  63. package/extend/bajoTemplate/layout/centered.html +0 -0
  64. package/extend/bajoTemplate/layout/default.html +0 -0
  65. package/extend/bajoTemplate/layout/error.html +0 -0
  66. package/extend/bajoTemplate/layout/info.html +0 -0
  67. package/extend/bajoTemplate/partial/403.html +0 -0
  68. package/extend/bajoTemplate/partial/_admin/reset-user-password.html +0 -0
  69. package/extend/bajoTemplate/partial/_mail/help-contact-form.html +0 -0
  70. package/extend/bajoTemplate/partial/_mail/help-contact-form.id.html +0 -0
  71. package/extend/bajoTemplate/partial/_mail/mystuff-change-password.html +0 -0
  72. package/extend/bajoTemplate/partial/_mail/mystuff-change-password.id.html +0 -0
  73. package/extend/bajoTemplate/partial/_mail/mystuff-reset-api-key.html +0 -0
  74. package/extend/bajoTemplate/partial/_mail/mystuff-reset-api-key.id.html +0 -0
  75. package/extend/bajoTemplate/partial/_mail/user-activation-success.html +0 -0
  76. package/extend/bajoTemplate/partial/_mail/user-activation-success.id.html +0 -0
  77. package/extend/bajoTemplate/partial/_mail/user-forgot-password-changed.html +0 -0
  78. package/extend/bajoTemplate/partial/_mail/user-forgot-password-changed.id.html +0 -0
  79. package/extend/bajoTemplate/partial/_mail/user-forgot-password-link.html +0 -0
  80. package/extend/bajoTemplate/partial/_mail/user-forgot-password-link.id.html +0 -0
  81. package/extend/bajoTemplate/partial/_mail/user-signup-success-active.html +0 -0
  82. package/extend/bajoTemplate/partial/_mail/user-signup-success-active.id.html +0 -0
  83. package/extend/bajoTemplate/partial/_mail/user-signup-success.html +0 -0
  84. package/extend/bajoTemplate/partial/_mail/user-signup-success.id.html +0 -0
  85. package/extend/bajoTemplate/partial/api-key-modal.html +0 -0
  86. package/extend/bajoTemplate/partial/app-launcher.html +0 -0
  87. package/extend/bajoTemplate/partial/help/contact-form/form.html +0 -0
  88. package/extend/bajoTemplate/partial/help/contact-form/success.html +0 -0
  89. package/extend/bajoTemplate/partial/help/trouble-tickets/add.html +0 -0
  90. package/extend/bajoTemplate/partial/help/trouble-tickets/details.html +0 -0
  91. package/extend/bajoTemplate/partial/help/trouble-tickets/list.html +0 -0
  92. package/extend/bajoTemplate/partial/layout/address.html +0 -0
  93. package/extend/bajoTemplate/partial/layout/breadcrumb.html +0 -0
  94. package/extend/bajoTemplate/partial/layout/footer.html +0 -0
  95. package/extend/bajoTemplate/partial/layout/more-info.html +0 -0
  96. package/extend/bajoTemplate/partial/layout/more-info.id.html +0 -0
  97. package/extend/bajoTemplate/partial/layout/navbar.html +0 -0
  98. package/extend/bajoTemplate/partial/layout/sidebar.html +0 -0
  99. package/extend/bajoTemplate/partial/layout/socmed.html +0 -0
  100. package/extend/bajoTemplate/partial/list-item/change-password.html +0 -0
  101. package/extend/bajoTemplate/partial/list-item/forgot-password.html +0 -0
  102. package/extend/bajoTemplate/partial/list-item/goto-home.html +0 -0
  103. package/extend/bajoTemplate/partial/list-item/member-links.html +0 -0
  104. package/extend/bajoTemplate/partial/list-item/oauth-signin.html +0 -0
  105. package/extend/bajoTemplate/partial/list-item/signin.html +0 -0
  106. package/extend/bajoTemplate/partial/list-item/signout.html +0 -0
  107. package/extend/bajoTemplate/partial/list-item/user-signup.html +0 -0
  108. package/extend/bajoTemplate/partial/list-item/your-profile.html +0 -0
  109. package/extend/bajoTemplate/partial/signin.html +0 -0
  110. package/extend/bajoTemplate/partial/signout.html +0 -0
  111. package/extend/bajoTemplate/partial/user/activation.html +0 -0
  112. package/extend/bajoTemplate/partial/user/forgot-password-nomail.id.md +0 -0
  113. package/extend/bajoTemplate/partial/user/forgot-password-nomail.md +0 -0
  114. package/extend/bajoTemplate/partial/user/forgot-password.html +0 -0
  115. package/extend/bajoTemplate/partial/user/fpl-invalid.html +0 -0
  116. package/extend/bajoTemplate/partial/user/fpl-invalid.id.md +0 -0
  117. package/extend/bajoTemplate/partial/user/fpl-invalid.md +0 -0
  118. package/extend/bajoTemplate/partial/user/fpl.html +0 -0
  119. package/extend/bajoTemplate/partial/user/signup/form.html +0 -0
  120. package/extend/bajoTemplate/partial/user/signup/success-mail.id.md +0 -0
  121. package/extend/bajoTemplate/partial/user/signup/success-mail.md +0 -0
  122. package/extend/bajoTemplate/partial/user/signup/success-nomail.id.md +0 -0
  123. package/extend/bajoTemplate/partial/user/signup/success-nomail.md +0 -0
  124. package/extend/bajoTemplate/partial/user/signup/success.html +0 -0
  125. package/extend/bajoTemplate/partial/your-stuff/change-password.html +0 -0
  126. package/extend/bajoTemplate/partial/your-stuff/profile/edit.html +0 -0
  127. package/extend/bajoTemplate/partial/your-stuff/profile/view.html +0 -0
  128. package/extend/bajoTemplate/partial/your-stuff/reset-api-key.html +0 -0
  129. package/extend/bajoTemplate/template/403.html +0 -0
  130. package/extend/bajoTemplate/template/_admin/reset-user-password.html +0 -0
  131. package/extend/bajoTemplate/template/_mail/help-contact-form.html +0 -0
  132. package/extend/bajoTemplate/template/_mail/mystuff-change-password.html +0 -0
  133. package/extend/bajoTemplate/template/_mail/mystuff-reset-api-key.html +0 -0
  134. package/extend/bajoTemplate/template/_mail/user-activation-success.html +0 -0
  135. package/extend/bajoTemplate/template/_mail/user-forgot-password-changed.html +0 -0
  136. package/extend/bajoTemplate/template/_mail/user-forgot-password-link.html +0 -0
  137. package/extend/bajoTemplate/template/_mail/user-signup-success-active.html +0 -0
  138. package/extend/bajoTemplate/template/_mail/user-signup-success.html +0 -0
  139. package/extend/bajoTemplate/template/help/contact-form/form.html +0 -0
  140. package/extend/bajoTemplate/template/help/contact-form/success.html +0 -0
  141. package/extend/bajoTemplate/template/help/trouble-tickets/add.html +0 -0
  142. package/extend/bajoTemplate/template/help/trouble-tickets/details.html +0 -0
  143. package/extend/bajoTemplate/template/help/trouble-tickets/list.html +0 -0
  144. package/extend/bajoTemplate/template/info/about-us.md +0 -0
  145. package/extend/bajoTemplate/template/info/cookie-policy.md +0 -0
  146. package/extend/bajoTemplate/template/info/privacy.md +0 -0
  147. package/extend/bajoTemplate/template/info/terms-conditions.md +0 -0
  148. package/extend/bajoTemplate/template/signin.html +0 -0
  149. package/extend/bajoTemplate/template/signout.html +0 -0
  150. package/extend/bajoTemplate/template/user/activation.html +0 -0
  151. package/extend/bajoTemplate/template/user/forgot-password.html +0 -0
  152. package/extend/bajoTemplate/template/user/fpl-invalid.html +0 -0
  153. package/extend/bajoTemplate/template/user/fpl.html +0 -0
  154. package/extend/bajoTemplate/template/user/signup/form.html +0 -0
  155. package/extend/bajoTemplate/template/user/signup/success.html +0 -0
  156. package/extend/bajoTemplate/template/your-stuff/change-password.html +0 -0
  157. package/extend/bajoTemplate/template/your-stuff/profile/edit.html +0 -0
  158. package/extend/bajoTemplate/template/your-stuff/profile/view.html +0 -0
  159. package/extend/bajoTemplate/template/your-stuff/reset-api-key.html +0 -0
  160. package/extend/dobo/feature/address.js +1 -1
  161. package/extend/dobo/feature/category.js +0 -0
  162. package/extend/dobo/feature/country.js +1 -1
  163. package/extend/dobo/feature/email.js +0 -0
  164. package/extend/dobo/feature/lat-lng.js +3 -3
  165. package/extend/dobo/feature/lat.js +2 -2
  166. package/extend/dobo/feature/lng.js +2 -2
  167. package/extend/dobo/feature/person-in-charge.js +0 -0
  168. package/extend/dobo/feature/phone.js +0 -0
  169. package/extend/dobo/feature/site-id.js +3 -3
  170. package/extend/dobo/feature/slug.js +7 -8
  171. package/extend/dobo/feature/social.js +0 -0
  172. package/extend/dobo/feature/status.js +2 -2
  173. package/extend/dobo/feature/team-id.js +3 -3
  174. package/extend/dobo/feature/ts.js +0 -0
  175. package/extend/dobo/feature/url.js +6 -6
  176. package/extend/dobo/feature/user-id.js +5 -5
  177. package/extend/dobo/fixture/contact-form-cat.json +0 -0
  178. package/extend/dobo/fixture/site.json +0 -4
  179. package/extend/dobo/fixture/team-user.json +0 -0
  180. package/extend/dobo/fixture/team.json +2 -1
  181. package/extend/dobo/fixture/ticket-cat.json +0 -0
  182. package/extend/dobo/fixture/user.json +0 -0
  183. package/extend/dobo/model/contact-form-cat.json +3 -0
  184. package/extend/dobo/model/contact-form.json +16 -0
  185. package/extend/dobo/model/download.json +19 -0
  186. package/extend/dobo/model/site-setting.json +8 -0
  187. package/extend/dobo/{schema → model}/site.json +4 -8
  188. package/extend/dobo/{schema → model}/team-user.json +5 -10
  189. package/extend/dobo/model/team.json +15 -0
  190. package/extend/dobo/model/ticket-cat.json +3 -0
  191. package/extend/dobo/model/ticket-detail.json +7 -0
  192. package/extend/dobo/model/ticket.json +18 -0
  193. package/extend/dobo/{schema → model}/user.json +14 -11
  194. package/extend/masohiSocketIo/middleware/server/auth.js +1 -1
  195. package/extend/sumba/route/anonymous.json +0 -0
  196. package/extend/sumba/route/secure.json +0 -0
  197. package/extend/waibuBootstrap/theme/component/factory/nav-dropdown-user.js +5 -5
  198. package/extend/waibuDb/schema/contact-form-cat.json +0 -0
  199. package/extend/waibuDb/schema/contact-form.json +0 -0
  200. package/extend/waibuDb/schema/download.js +1 -1
  201. package/extend/waibuDb/schema/site.json +2 -2
  202. package/extend/waibuDb/schema/team-user.js +2 -2
  203. package/extend/waibuDb/schema/team.json +0 -0
  204. package/extend/waibuDb/schema/ticket-cat.json +0 -0
  205. package/extend/waibuDb/schema/user.json +0 -0
  206. package/extend/waibuMpa/extend/waibuAdmin/route/contact-form/@action.js +0 -0
  207. package/extend/waibuMpa/extend/waibuAdmin/route/contact-form-cat/@action.js +0 -0
  208. package/extend/waibuMpa/extend/waibuAdmin/route/download/@action.js +0 -0
  209. package/extend/waibuMpa/extend/waibuAdmin/route/reset-user-password.js +5 -6
  210. package/extend/waibuMpa/extend/waibuAdmin/route/session/@action.js +0 -0
  211. package/extend/waibuMpa/extend/waibuAdmin/route/site.js +25 -0
  212. package/extend/waibuMpa/extend/waibuAdmin/route/team/@action.js +0 -0
  213. package/extend/waibuMpa/extend/waibuAdmin/route/team-user/@action.js +0 -0
  214. package/extend/waibuMpa/extend/waibuAdmin/route/ticket/@action.js +0 -0
  215. package/extend/waibuMpa/extend/waibuAdmin/route/ticket-cat/@action.js +0 -0
  216. package/extend/waibuMpa/extend/waibuAdmin/route/user/@action.js +0 -0
  217. package/extend/waibuMpa/route/access-token.js +1 -2
  218. package/extend/waibuMpa/route/help/contact-form.js +5 -5
  219. package/extend/waibuMpa/route/help/trouble-tickets/add.js +4 -4
  220. package/extend/waibuMpa/route/help/trouble-tickets/details/@id.js +5 -5
  221. package/extend/waibuMpa/route/help/trouble-tickets/list.js +2 -2
  222. package/extend/waibuMpa/route/info/@item.js +0 -0
  223. package/extend/waibuMpa/route/signin.js +0 -0
  224. package/extend/waibuMpa/route/signout.js +1 -14
  225. package/extend/waibuMpa/route/user/activation.js +4 -6
  226. package/extend/waibuMpa/route/user/forgot-password/@fpl.js +9 -10
  227. package/extend/waibuMpa/route/user/forgot-password.js +5 -7
  228. package/extend/waibuMpa/route/user/signup.js +4 -4
  229. package/extend/waibuMpa/route/your-stuff/change-password.js +5 -6
  230. package/extend/waibuMpa/route/your-stuff/download/@action.js +0 -0
  231. package/extend/waibuMpa/route/your-stuff/download/get.js +0 -0
  232. package/extend/waibuMpa/route/your-stuff/profile/edit.js +5 -5
  233. package/extend/waibuMpa/route/your-stuff/profile.js +2 -2
  234. package/extend/waibuMpa/route/your-stuff/reset-api-key.js +8 -9
  235. package/extend/waibuRestApi/route/info/get.js +2 -2
  236. package/extend/waibuRestApi/route/manage/team/model-builder.json +0 -0
  237. package/extend/waibuRestApi/route/manage/user/model-builder.json +0 -0
  238. package/extend/waibuRestApi/route/user/access-token/@type/create.js +0 -0
  239. package/extend/waibuRestApi/route/user/api-key/get.js +1 -2
  240. package/extend/waibuRestApi/route/your-stuff/api-key/get.js +1 -2
  241. package/extend/waibuRestApi/route/your-stuff/api-key/update.js +5 -6
  242. package/extend/waibuRestApi/route/your-stuff/change-password/update.js +2 -3
  243. package/extend/waibuRestApi/route/your-stuff/profile/get.js +2 -2
  244. package/extend/waibuRestApi/route/your-stuff/profile/update.js +3 -3
  245. package/extend/waibuSocketIo/middleware/server/auth.js +2 -3
  246. package/extend/waibuStatic/asset/user-profile.png +0 -0
  247. package/index.js +78 -54
  248. package/lib/check-iconset.js +4 -6
  249. package/lib/check-team.js +1 -1
  250. package/lib/check-theme.js +4 -7
  251. package/lib/check-user-id.js +4 -3
  252. package/lib/collect-redirects.js +0 -0
  253. package/lib/collect-routes.js +4 -4
  254. package/lib/collect-team.js +3 -3
  255. package/lib/lat-lng-hook.js +2 -2
  256. package/lib/password-rule.js +0 -0
  257. package/lib/reset-token.js +1 -1
  258. package/lib/token-schema.js +0 -0
  259. package/logo.png +0 -0
  260. package/package.json +41 -34
  261. package/wiki/CHANGES.md +6 -0
  262. package/wiki/CONFIG.md +2 -0
  263. package/wiki/CONTRIBUTING.md +5 -0
  264. package/wiki/DEV-GUIDE.md +1 -0
  265. package/wiki/ECOSYSTEM.md +28 -0
  266. package/wiki/GETTING-STARTED.md +1 -0
  267. package/wiki/USER-GUIDE.md +1 -0
  268. package/extend/bajo/hook/dobo@before-record-count.js +0 -8
  269. package/extend/bajo/hook/dobo@before-record-find-one.js +0 -8
  270. package/extend/bajo/hook/dobo@before-record-get.js +0 -23
  271. package/extend/bajo/hook/dobo@before-record-remove.js +0 -10
  272. package/extend/bajo/hook/dobo@before-record-update.js +0 -10
  273. package/extend/dobo/schema/contact-form-cat.json +0 -3
  274. package/extend/dobo/schema/contact-form.json +0 -20
  275. package/extend/dobo/schema/download.json +0 -24
  276. package/extend/dobo/schema/site-setting.json +0 -8
  277. package/extend/dobo/schema/team.json +0 -19
  278. package/extend/dobo/schema/ticket-cat.json +0 -3
  279. package/extend/dobo/schema/ticket-detail.json +0 -7
  280. package/extend/dobo/schema/ticket.json +0 -17
package/index.js CHANGED
@@ -1,13 +1,22 @@
1
1
  import path from 'path'
2
2
 
3
+ /**
4
+ * Plugin factory
5
+ *
6
+ * @param {string} pkgName - NPM package name
7
+ * @returns {class}
8
+ */
3
9
  async function factory (pkgName) {
4
10
  const me = this
5
11
 
6
- return class Sumba extends this.lib.Plugin {
12
+ /**
13
+ * Sumba class
14
+ *
15
+ * @class
16
+ */
17
+ class Sumba extends this.app.baseClass.Base {
7
18
  constructor () {
8
19
  super(pkgName, me.app)
9
- this.alias = 'sumba'
10
- this.dependencies = ['bajo-extra', 'bajo-common-db', 'bajo-config']
11
20
  this.config = {
12
21
  multiSite: false,
13
22
  waibu: {
@@ -119,8 +128,8 @@ async function factory (pkgName) {
119
128
 
120
129
  init = async () => {
121
130
  const { getPluginDataDir } = this.app.bajo
122
- this.downloadDir = `${getPluginDataDir(this.name)}/download`
123
- this.lib.fs.ensureDirSync(this.downloadDir)
131
+ this.downloadDir = `${getPluginDataDir(this.ns)}/download`
132
+ this.app.lib.fs.ensureDirSync(this.downloadDir)
124
133
  for (const type of ['secure', 'anonymous', 'team']) {
125
134
  this[`${type}Routes`] = this[`${type}Routes`] ?? []
126
135
  this[`${type}NegRoutes`] = this[`${type}NegRoutes`] ?? []
@@ -128,8 +137,8 @@ async function factory (pkgName) {
128
137
  }
129
138
 
130
139
  _getSetting = async (type, source) => {
131
- const { defaultsDeep } = this.lib.aneka
132
- const { get } = this.lib._
140
+ const { defaultsDeep } = this.app.lib.aneka
141
+ const { get } = this.app.lib._
133
142
 
134
143
  const setting = defaultsDeep(get(this.config, `auth.${source}.${type}`, {}), get(this.config, `auth.common.${type}`, {}))
135
144
  if (type === 'basic') setting.type = 'Basic'
@@ -137,7 +146,7 @@ async function factory (pkgName) {
137
146
  }
138
147
 
139
148
  _getToken = async (type, req, source) => {
140
- const { isEmpty } = this.lib._
149
+ const { isEmpty } = this.app.lib._
141
150
 
142
151
  const setting = await this._getSetting(type, source)
143
152
  let token = req.headers[setting.headerKey.toLowerCase()]
@@ -153,7 +162,7 @@ async function factory (pkgName) {
153
162
  adminMenu = async (locals, req) => {
154
163
  if (!this.app.waibuAdmin) return
155
164
  const { getPluginPrefix } = this.app.waibu
156
- const prefix = getPluginPrefix(this.name)
165
+ const prefix = getPluginPrefix(this.ns)
157
166
  return [{
158
167
  title: 'supportSystem',
159
168
  children: [
@@ -181,37 +190,41 @@ async function factory (pkgName) {
181
190
  }
182
191
 
183
192
  getUser = async (rec, safe = true) => {
184
- const { recordGet } = this.app.dobo
185
- const { omit, isPlainObject } = this.lib._
193
+ const { omit, isPlainObject } = this.app.lib._
186
194
  let user
187
195
  if (isPlainObject(rec)) user = rec
188
- else user = await recordGet('SumbaUser', rec, { noHook: true })
196
+ else {
197
+ const mdl = this.app.dobo.getModel('SumbaUser')
198
+ user = await mdl.getRecord(rec, { noHook: true, throwNotFound: false })
199
+ }
200
+ if (!user) return null
189
201
  return safe ? omit(user, this.unsafeUserFields) : user
190
202
  }
191
203
 
192
204
  mergeTeam = async (user, site) => {
193
205
  if (!user) return
194
- const { map, pick } = this.lib._
195
- const { recordFindAll } = this.app.dobo
206
+ const { map, pick } = this.app.lib._
196
207
  user.teams = []
197
208
  const query = { userId: user.id, siteId: site.id }
198
- const userTeam = await recordFindAll('SumbaTeamUser', { query })
209
+ let mdl = this.app.dobo.getModel('SumbaTeamUser')
210
+ const userTeam = await mdl.findAllRecord({ query })
199
211
  if (userTeam.length === 0) return
200
212
  delete query.userId
201
- query.id = { $in: map(userTeam, 'id'), status: 'ENABLED' }
202
- const team = await recordFindAll('SumbaTeam', { query })
213
+ query.id = { $in: map(userTeam, 'id') }
214
+ query.status = 'ENABLED'
215
+ mdl = this.app.dobo.getModel('SumbaTeam')
216
+ const team = await mdl.findAllRecord({ query })
203
217
  if (team.length > 0) user.teams.push(...map(team, t => pick(t, ['id', 'alias'])))
204
218
  }
205
219
 
206
220
  getUserFromUsernamePassword = async (username = '', password = '', req) => {
207
221
  const { importPkg } = this.app.bajo
208
- const { recordFind, validate } = this.app.dobo
209
- const model = 'SumbaUser'
210
- await validate({ username, password }, model, { ns: ['sumba', 'dobo'], fields: ['username', 'password'] })
222
+ const model = this.app.dobo.getModel('SumbaUser')
223
+ await model.validate({ username, password }, null, { partial: true, ns: ['sumba', 'dobo'], fields: ['username', 'password'] })
211
224
  const bcrypt = await importPkg('bajoExtra:bcrypt')
212
225
 
213
226
  const query = { username, provider: 'local' }
214
- const rows = await recordFind(model, { query }, { req, forceNoHidden: true, noHook: true })
227
+ const rows = await model.findRecord({ query }, { req, forceNoHidden: true, noHook: true })
215
228
  if (rows.length === 0) throw this.error('validationError', { details: [{ field: 'username', error: 'Unknown username' }], statusCode: 401 })
216
229
  const rec = rows[0]
217
230
  if (rec.status !== 'ACTIVE') throw this.error('validationError', { details: ['User is inactive or temporarily disabled'], statusCode: 401 })
@@ -222,9 +235,9 @@ async function factory (pkgName) {
222
235
 
223
236
  createJwtFromUserRecord = async (rec) => {
224
237
  const { importPkg } = this.app.bajo
225
- const { dayjs } = this.lib
238
+ const { dayjs } = this.app.lib
226
239
  const { hash } = this.app.bajoExtra
227
- const { get, pick } = this.lib._
240
+ const { get, pick } = this.app.lib._
228
241
 
229
242
  const fastJwt = await importPkg('bajoExtra:fast-jwt')
230
243
  const { createSigner } = fastJwt
@@ -254,16 +267,15 @@ async function factory (pkgName) {
254
267
  }
255
268
 
256
269
  verifyApiKey = async (req, reply, source, payload) => {
257
- const { merge } = this.lib._
270
+ const { merge } = this.app.lib._
258
271
  const { isMd5, hash } = this.app.bajoExtra
259
272
  const { getUser } = this
260
- const { recordFind } = this.app.dobo
261
273
 
262
274
  let token = await this._getToken('apiKey', req, source)
263
275
  if (!isMd5(token)) return false
264
276
  token = await hash(token)
265
277
  const query = { token }
266
- const rows = await recordFind('SumbaUser', { query }, { req, noHook: true })
278
+ const rows = await this.app.dobo.getModel('SumbaUser').findRecord({ query }, { req, noHook: true })
267
279
  if (rows.length === 0) throw this.error('invalidKey', merge({ statusCode: 401 }, payload))
268
280
  if (rows[0].status !== 'ACTIVE') throw this.error('userInactive', merge({ details: [{ field: 'status', error: 'inactive' }], statusCode: 401 }, payload))
269
281
  req.user = await getUser(rows[0])
@@ -273,10 +285,10 @@ async function factory (pkgName) {
273
285
  verifyBasic = async (req, reply, source, payload) => {
274
286
  const { getUserFromUsernamePassword } = this
275
287
  const { getUser } = this
276
- const { isEmpty, merge } = this.lib._
288
+ const { isEmpty, merge } = this.app.lib._
277
289
 
278
290
  const setHeader = async (setting, reply) => {
279
- const { isString } = this.lib._
291
+ const { isString } = this.app.lib._
280
292
 
281
293
  let header = setting.type
282
294
  const exts = []
@@ -314,9 +326,8 @@ async function factory (pkgName) {
314
326
 
315
327
  verifyJwt = async (req, reply, source, payload) => {
316
328
  const { importPkg } = this.app.bajo
317
- const { recordGet } = this.app.dobo
318
329
  const { getUser } = this
319
- const { isEmpty, merge } = this.lib._
330
+ const { isEmpty, merge } = this.app.lib._
320
331
 
321
332
  const fastJwt = await importPkg('bajoExtra:fast-jwt')
322
333
  const { createVerifier } = fastJwt
@@ -330,7 +341,7 @@ async function factory (pkgName) {
330
341
  const decoded = await verifier(token)
331
342
  const id = decoded.payload.uid
332
343
  try {
333
- const rec = await recordGet('SumbaUser', id, { req, noHook: true })
344
+ const rec = await this.app.dobo.getModel('SumbaUser').getRecord(id, { req, noHook: true })
334
345
  if (!rec) throw this.error('invalidToken', { statusCode: 401 })
335
346
  if (rec.status !== 'ACTIVE') throw this.error('userInactive', { details: [{ field: 'status', error: 'inactive' }], statusCode: 401 })
336
347
  req.user = await getUser(rec)
@@ -342,8 +353,8 @@ async function factory (pkgName) {
342
353
  }
343
354
 
344
355
  checkPathsByTeam = ({ paths = [], method = 'GET', teams = [], guards = [] }) => {
345
- const { includes } = this.lib.aneka
346
- const { outmatch } = this.lib
356
+ const { includes } = this.app.lib.aneka
357
+ const { outmatch } = this.app.lib
347
358
 
348
359
  for (const item of guards) {
349
360
  const matchPath = outmatch(item.path)
@@ -360,7 +371,7 @@ async function factory (pkgName) {
360
371
  }
361
372
 
362
373
  checkPathsByRoute = ({ paths = [], method = 'GET', guards = [] }) => {
363
- const { outmatch } = this.lib
374
+ const { outmatch } = this.app.lib
364
375
 
365
376
  for (const item of guards) {
366
377
  const matchPath = outmatch(item.path)
@@ -374,7 +385,7 @@ async function factory (pkgName) {
374
385
  }
375
386
 
376
387
  checkPathsByGuard = ({ guards, paths }) => {
377
- const { outmatch } = this.lib
388
+ const { outmatch } = this.app.lib
378
389
  const matcher = outmatch(guards)
379
390
  let guarded
380
391
  for (const path of paths) {
@@ -384,23 +395,22 @@ async function factory (pkgName) {
384
395
  }
385
396
 
386
397
  getSite = async (hostname, useId) => {
387
- const { omit } = this.lib._
388
- const { recordFind } = this.app.dobo
398
+ const { omit } = this.app.lib._
389
399
  const omitted = ['status']
390
400
 
391
401
  const mergeSetting = async (site) => {
392
- const { defaultsDeep } = this.lib.aneka
393
- const { parseObject } = this.app.bajo
394
- const { trim, get, filter } = this.lib._
395
- const { recordFind, recordGet } = this.app.dobo
402
+ const { defaultsDeep } = this.app.lib.aneka
403
+ const { parseObject } = this.app.lib
404
+ const { trim, get, filter } = this.app.lib._
396
405
  const defSetting = {}
397
406
  const nsSetting = {}
407
+ const names = this.app.getAllNs()
398
408
  const query = {
399
- ns: { $in: this.app.bajo.pluginNames },
409
+ ns: { $in: names },
400
410
  siteId: site.id
401
411
  }
402
- const all = await recordFind('SumbaSiteSetting', { query, limit: -1 })
403
- for (const ns of this.app.bajo.pluginNames) {
412
+ const all = await this.app.dobo.getModel('SumbaSiteSetting').findRecord({ query, limit: -1 })
413
+ for (const ns of names) {
404
414
  nsSetting[ns] = {}
405
415
  defSetting[ns] = get(this, `app.${ns}.config.siteSetting`, {})
406
416
  const items = filter(all, { ns })
@@ -414,14 +424,14 @@ async function factory (pkgName) {
414
424
  }
415
425
  site.setting = parseObject(defaultsDeep({}, nsSetting, defSetting))
416
426
  // additional fields
417
- const country = await recordGet('CdbCountry', site.country, { noHook: true })
427
+ const country = await this.app.dobo.getModel('CdbCountry').getRecord(site.country, { noHook: true })
418
428
  site.countryName = (country ?? {}).name ?? site.country
419
429
  }
420
430
 
421
431
  let site = {}
422
432
 
423
433
  if (!this.config.multiSite) {
424
- const resp = await recordFind('SumbaSite', { query: { alias: 'default' } }, { noHook: true })
434
+ const resp = await this.app.dobo.getModel('SumbaSite').findRecord({ query: { alias: 'default' } }, { noHook: true })
425
435
  site = omit(resp[0], omitted)
426
436
  await mergeSetting(site)
427
437
  return site
@@ -437,7 +447,7 @@ async function factory (pkgName) {
437
447
  }
438
448
  }
439
449
  const filter = { query, limit: 1 }
440
- const rows = await recordFind('SumbaSite', filter, { noHook: true })
450
+ const rows = await this.app.dobo.getModel('SumbaSite').findRecord(filter, { noHook: true })
441
451
  if (rows.length === 0) throw this.error('unknownSite')
442
452
  const row = omit(rows[0], omitted)
443
453
  if (row.status !== 'ACTIVE') throw this.error('siteInactiveInfo')
@@ -446,17 +456,30 @@ async function factory (pkgName) {
446
456
  return site
447
457
  }
448
458
 
459
+ signout = async ({ req, reply, reason }) => {
460
+ const { runHook } = this.app.bajo
461
+ const { getSessionId } = this.app.waibuMpa
462
+ const sid = await getSessionId(req.headers.cookie)
463
+ req.session.userId = null
464
+ await runHook(`${this.ns}:afterSignout`, sid, req)
465
+ const { query, params } = req
466
+ // const url = !isEmpty(referer) ? referer : this.config.redirect.home
467
+ const url = this.config.redirect.afterSignout
468
+ req.flash('notify', req.t(reason ?? 'signoutSuccessfully'))
469
+ return reply.redirectTo(url, { query, params })
470
+ }
471
+
449
472
  signin = async ({ user, req, reply }) => {
450
473
  const { getSessionId } = this.app.waibuMpa
451
474
  const { runHook } = this.app.bajo
452
- const { isEmpty, omit } = this.lib._
475
+ const { isEmpty, omit } = this.app.lib._
453
476
  let { referer } = req.body || {}
454
477
  if (req.session.ref) referer = req.session.ref
455
478
  req.session.ref = null
456
479
  const _user = omit(user, ['password', 'token'])
457
480
  req.session.userId = _user.id
458
481
  const sid = await getSessionId(req.headers.cookie)
459
- await runHook(`${this.name}:afterSignin`, _user, sid, req)
482
+ await runHook(`${this.ns}:afterSignin`, _user, sid, req)
460
483
  const { query, params } = req
461
484
  const url = !isEmpty(referer) ? referer : this.config.redirect.afterSignin
462
485
  req.flash('notify', req.t('signinSuccessfully'))
@@ -464,7 +487,7 @@ async function factory (pkgName) {
464
487
  }
465
488
 
466
489
  generatePassword = (req) => {
467
- const { generateId } = this.app.bajo
490
+ const { generateId } = this.app.lib.aneka
468
491
  const cfg = req ? req.site.setting.sumba.userPassword : this.config.siteSetting.userPassword
469
492
  let passwd = generateId()
470
493
  if (cfg.minLowercase) passwd += generateId({ pattern: 'abcdefghijklmnopqrstuvwxyz', length: cfg.minLowercase })
@@ -476,7 +499,7 @@ async function factory (pkgName) {
476
499
 
477
500
  pushDownload = async ({ description, worker, data, source, req, file, type }) => {
478
501
  const { getPlugin } = this.app.bajo
479
- const { recordCreate } = getPlugin('waibuDb')
502
+ const { createRecord } = getPlugin('waibuDb')
480
503
  const { push } = getPlugin('bajoQueue')
481
504
  description = description ?? file
482
505
  const jobQueue = {
@@ -490,19 +513,20 @@ async function factory (pkgName) {
490
513
  if (!type) type = path.extname(file)
491
514
  if (type[0] === '.') type = type.slice(1)
492
515
  const body = { file, description, jobQueue, type }
493
- const rec = await recordCreate({ model: 'SumbaDownload', body, req, options: { noFlash: true } })
516
+ const rec = await createRecord({ model: 'SumbaDownload', body, req, options: { noFlash: true } })
494
517
  jobQueue.payload.data.download = { id: rec.data.id, file }
495
518
  await push(jobQueue)
496
519
  }
497
520
 
498
521
  getApiKeyFromUserId = async id => {
499
522
  const { hash } = this.app.bajoExtra
500
- const { recordGet } = this.app.dobo
501
523
  const options = { forceNoHidden: true, noHook: true, noCache: true, attachment: true, mimeType: true }
502
- const resp = await recordGet('SumbaUser', id, options)
524
+ const resp = await this.app.dobo.getModel('SumbaUser').getRecord(id, options)
503
525
  return await hash(resp.salt)
504
526
  }
505
527
  }
528
+
529
+ return Sumba
506
530
  }
507
531
 
508
532
  export default factory
@@ -1,13 +1,11 @@
1
1
  async function checkIconset (req, reply) {
2
- const { get } = this.lib._
2
+ const { get } = this.app.lib._
3
3
  const mpa = this.app.waibuMpa
4
4
 
5
5
  if (!req.site) return
6
- if (mpa.iconsets.length === 1) req.iconset = mpa.iconsets[0].name
7
- else {
8
- const siteIconset = get(req, 'site.setting.waibuMpa.iconset')
9
- req.iconset = get(mpa, 'config.iconset.default', siteIconset)
10
- }
6
+ const siteIconset = get(req, 'site.setting.waibuMpa.iconset')
7
+ req.iconset = get(mpa, 'config.iconset.set', siteIconset)
8
+ req.iconset = req.iconset ?? 'default'
11
9
  }
12
10
 
13
11
  export default checkIconset
package/lib/check-team.js CHANGED
@@ -2,7 +2,7 @@ import { pathsToCheck } from './check-user-id.js'
2
2
 
3
3
  async function checkTeam (req, reply, source) {
4
4
  if (!req.user) return
5
- const { map } = this.lib._
5
+ const { map } = this.app.lib._
6
6
  await this.mergeTeam(req.user, req.site)
7
7
  const paths = pathsToCheck.call(this, req, true)
8
8
  const teams = map(req.user.teams, 'alias')
@@ -1,14 +1,11 @@
1
1
  async function checkTheme (req, reply) {
2
- const { get } = this.lib._
2
+ const { get } = this.app.lib._
3
3
  const mpa = this.app.waibuMpa
4
4
 
5
5
  if (!req.site) return
6
- if (mpa.themes.length === 1) req.theme = mpa.themes[0].name
7
- else {
8
- const siteTheme = get(req, 'site.setting.waibuMpa.theme')
9
- req.theme = get(mpa, 'config.theme.set', siteTheme)
10
- req.theme = req.theme ?? mpa.themes[0].name
11
- }
6
+ const siteTheme = get(req, 'site.setting.waibuMpa.theme')
7
+ req.theme = get(mpa, 'config.theme.set', siteTheme)
8
+ req.theme = req.theme ?? 'default'
12
9
  }
13
10
 
14
11
  export default checkTheme
@@ -1,10 +1,10 @@
1
1
  export function pathsToCheck (req, withHome) {
2
- const { uniq, without } = this.lib._
2
+ const { uniq, without } = this.app.lib._
3
3
  return uniq(without([req.routeOptions.url, req.url], undefined, null))
4
4
  }
5
5
 
6
6
  async function setUser (req) {
7
- const { get } = this.lib._
7
+ const { get } = this.app.lib._
8
8
  const id = get(req, 'session.userId')
9
9
  if (!id) return
10
10
  try {
@@ -12,12 +12,13 @@ async function setUser (req) {
12
12
  if (user) req.user = user
13
13
  else req.session.userId = null
14
14
  } catch (err) {
15
+ console.log(err)
15
16
  req.session.userId = null
16
17
  }
17
18
  }
18
19
 
19
20
  async function checkUserId (req, reply, source) {
20
- const { merge, isEmpty, camelCase, get } = this.lib._
21
+ const { merge, isEmpty, camelCase, get } = this.app.lib._
21
22
  const { routePath } = this.app.waibu
22
23
  const userId = get(req, 'session.userId')
23
24
  if (req.session) req.session.siteId = req.site.id
File without changes
@@ -1,7 +1,7 @@
1
1
  export async function collect ({ type = '', handler, container, file, ns, dir }) {
2
2
  const { readConfig } = this.app.bajo
3
3
  const { routePath, routePathHandlers } = this.app.waibu
4
- const { camelCase, find, isString, isEmpty } = this.lib._
4
+ const { camelCase, find, isString, isEmpty } = this.app.lib._
5
5
  let items = await readConfig(file, { ignoreError: true })
6
6
  if (isEmpty(items)) items = []
7
7
 
@@ -24,7 +24,7 @@ export async function collect ({ type = '', handler, container, file, ns, dir })
24
24
  }
25
25
 
26
26
  function handler (item) {
27
- const { isString } = this.lib._
27
+ const { isString } = this.app.lib._
28
28
  for (const k of ['methods']) {
29
29
  item[k] = item[k] ?? []
30
30
  if (isString(item[k])) item[k] = item[k].split(',')
@@ -35,9 +35,9 @@ async function collectRoutes (type) {
35
35
  const { eachPlugins } = this.app.bajo
36
36
  const me = this
37
37
  await eachPlugins(async function ({ file, dir }) {
38
- const { name: ns } = this
38
+ const { ns } = this
39
39
  await collect.call(me, { type, container: 'Routes', handler, file, ns, dir })
40
- }, { glob: `route/${type}.*`, prefix: this.name })
40
+ }, { glob: `route/${type}.*`, prefix: this.ns })
41
41
  }
42
42
 
43
43
  export default collectRoutes
@@ -1,7 +1,7 @@
1
1
  import { collect } from './collect-routes.js'
2
2
 
3
3
  function handler (item) {
4
- const { isString } = this.lib._
4
+ const { isString } = this.app.lib._
5
5
  for (const k of ['methods', 'teams', 'features']) {
6
6
  item[k] = item[k] ?? []
7
7
  if (isString(item[k])) item[k] = item[k].split(',')
@@ -12,9 +12,9 @@ async function collectTeam () {
12
12
  const { eachPlugins } = this.app.bajo
13
13
  const me = this
14
14
  await eachPlugins(async function ({ file, dir }) {
15
- const { name: ns } = this
15
+ const { ns } = this
16
16
  await collect.call(me, { type: 'team', container: 'Routes', handler, file, ns, dir })
17
- }, { glob: 'route/team.*', prefix: this.name })
17
+ }, { glob: 'route/team.*', prefix: this.ns })
18
18
  }
19
19
 
20
20
  export default collectTeam
@@ -1,6 +1,6 @@
1
1
  async function hook (body, options) {
2
- const { isSet } = this.lib.aneka
3
- const { round } = this.lib.aneka
2
+ const { isSet } = this.app.lib.aneka
3
+ const { round } = this.app.lib.aneka
4
4
  if (!isSet(body[options.fieldName])) return
5
5
  body[options.fieldName] = round(body[options.fieldName], options.scale)
6
6
  }
File without changes
@@ -1,5 +1,5 @@
1
1
  async function resetToken (salt) {
2
- const { generateId } = this.app.bajo
2
+ const { generateId } = this.app.lib.aneka
3
3
  const { hash } = this.app.bajoExtra
4
4
  salt = salt ?? generateId()
5
5
  const token = await hash(await hash(salt))
File without changes
package/logo.png CHANGED
File without changes
package/package.json CHANGED
@@ -1,34 +1,41 @@
1
- {
2
- "name": "sumba",
3
- "version": "2.0.0",
4
- "description": "Bajo Framework's Biz Suite",
5
- "main": "index.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "type": "module",
10
- "bajo": {
11
- "type": "plugin"
12
- },
13
- "repository": {
14
- "type": "git",
15
- "url": "git+https://github.com/ardhi/sumba.git"
16
- },
17
- "keywords": [
18
- "sumba",
19
- "bajo",
20
- "framework",
21
- "addons",
22
- "multidomain"
23
- ],
24
- "author": "Ardhi Lukianto <ardhi@lukianto.com>",
25
- "license": "MIT",
26
- "bugs": {
27
- "url": "https://github.com/ardhi/sumba/issues"
28
- },
29
- "homepage": "https://github.com/ardhi/sumba#readme",
30
- "dependencies": {
31
- "joi-password": "^4.2.0",
32
- "slug": "^10.0.0"
33
- }
34
- }
1
+ {
2
+ "name": "sumba",
3
+ "version": "2.1.0",
4
+ "description": "Biz Suite for Bajo Framework",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "build-doc": "jsdoc -c .jsdoc.conf.json",
8
+ "test": "mocha"
9
+ },
10
+ "type": "module",
11
+ "bajo": {
12
+ "type": "plugin",
13
+ "alias": "sumba",
14
+ "dependencies": ["bajo-extra", "bajo-common-db", "bajo-config", "bajo-markdown"]
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/ardhi/sumba.git"
19
+ },
20
+ "keywords": [
21
+ "sumba",
22
+ "bajo",
23
+ "framework",
24
+ "addons",
25
+ "multidomain"
26
+ ],
27
+ "author": "Ardhi Lukianto <ardhi@lukianto.com>",
28
+ "license": "MIT",
29
+ "bugs": {
30
+ "url": "https://github.com/ardhi/sumba/issues"
31
+ },
32
+ "homepage": "https://github.com/ardhi/sumba#readme",
33
+ "dependencies": {
34
+ "joi-password": "^4.3.0",
35
+ "slug": "^11.0.1"
36
+ },
37
+ "devDependencies": {
38
+ "clean-jsdoc-theme": "^4.3.0",
39
+ "jsdoc-plugin-intersection": "^1.0.4"
40
+ }
41
+ }
@@ -0,0 +1,6 @@
1
+ # Changes
2
+
3
+ ## 2026-01-01
4
+
5
+ - [2.1.0] Ported to match ```bajo@2.2.x``` & ```dobo@2.2.x``` specs
6
+ - [2.1.0] Upgrade to ```slug@11.0.1```
package/wiki/CONFIG.md ADDED
@@ -0,0 +1,2 @@
1
+ # Config Object
2
+
@@ -0,0 +1,5 @@
1
+ # Contributing
2
+
3
+ Thanks very much to everyone who wants to join as a contributor, but I have committed to devoting 100% of my time to this project. Therefore, I'm currently unable to accept pull requests from anyone until the project is large enough for me to manage it independently.
4
+
5
+ However, I am available if you encounter any bugs that require immediate fixes. Please report your issues in a GitHub issue, and I'll try to address them promptly. I'm also open to criticism and suggestions for improvements or requests for new features.
@@ -0,0 +1 @@
1
+ # Developer Guide
@@ -0,0 +1,28 @@
1
+ # Ecosystem
2
+
3
+ ## Opensource Plugins
4
+
5
+ | Package | Docs | NS | Alias | Description |
6
+ | ------- | ---- | -- | ----- | ----------- |
7
+ | [sumba-cms](https://github.com/ardhi/sumba-cms) | [Docs](https://ardhi.github.io/sumba-cms) | sumbaCms | cms | Sumba CMS |
8
+ | [sumba-geonames](https://github.com/ardhi/sumba-geonames) | [Docs](https://ardhi.github.io/sumba-geonames) | sumbaGeonames | geonames | Sumba Geonames |
9
+ | [sumba-nominatim](https://github.com/ardhi/sumba-nominatim) | [Docs](https://ardhi.github.io/sumba-nominatim) | sumbaNominatim | nominatim | Sumba OSM Nominatim |
10
+ | [sumba-oauth](https://github.com/ardhi/sumba-oauth) | [Docs](https://ardhi.github.io/sumba-oauth) | sumbaOauth | oauth | Sumba OAuth Providers |
11
+
12
+ ## Premium Plugins
13
+
14
+ | Package | Docs | NS | Alias | Description |
15
+ | ------- | ---- | -- | ----- | ----------- |
16
+ | [@sumba/geofence](https://bajo.app/premium-plugins/sumba-geofence) | [Docs](https://ardhi.github.io/sumba-geofence) | sumbaGeofence | geofence | Sumba Geofence |
17
+ | [@sumba/maps](https://bajo.app/premium-plugins/sumba-maps) | [Docs](https://ardhi.github.io/sumba-maps) | sumbaMaps | smaps | Sumba Maps |
18
+ | [@sumba/proxy](https://bajo.app/premium-plugins/sumba-proxy) | [Docs](https://ardhi.github.io/sumba-proxy) | sumbaProxy | proxy | Sumba Proxy: Cache any web resources locally |
19
+ | [@sumba/seatrack](https://bajo.app/premium-plugins/sumba-seatrack) | [Docs](https://ardhi.github.io/sumba-seatrack) | sumbaSeatrack | seatrack | Sumba Seatrack: AIS tracking |
20
+ | [@sumba/seatrack-global](https://bajo.app/premium-plugins/sumba-seatrack-global) | [Docs](https://ardhi.github.io/sumba-seatrack-global) | sumbaSeatrackGlobal | seatrack-global | Sumba Seatrack Global: AIS tracking by Rappid Datahub |
21
+ | [@sumba/seatrack-vts](https://bajo.app/premium-plugins/sumba-seatrack-vts) | [Docs](https://ardhi.github.io/sumba-seatrack-vts) | sumbaSeatrackVts | seatrack-vts | Sumba Seatrack VTS: VTS Support for Sumba Seatrack |
22
+ | [@sumba/seatrack-wpi](https://bajo.app/premium-plugins/sumba-seatrack-wpi) | [Docs](https://ardhi.github.io/sumba-seatrack-wpi) | sumbaSeatrackWpi | seatrack-wpi | Sumba Seatrack WPI: WPI Support for Sumba Seatrack |
23
+ | [@sumba/skytrack](https://bajo.app/premium-plugins/sumba-skytrack) | [Docs](https://ardhi.github.io/sumba-skytrack) | sumbaSkytrack | skytrack | Sumba Skytrack: ADSB tracking |
24
+ | [@sumba/skytrack-global](https://bajo.app/premium-plugins/sumba-skytrack-global) | [Docs](https://ardhi.github.io/sumba-skytrack-global) | sumbaSkytrackGlobal | skytrack-global | Sumba Skytrack: ADSB tracking by Rappid Datahub |
25
+ | [@sumba/store](https://bajo.app/premium-plugins/sumba-store) | [Docs](https://ardhi.github.io/sumba-store) | sumbaStore | store | Sumba Store: E-Commerce & online stores |
26
+ | [@sumba/subscription](https://bajo.app/premium-plugins/sumba-subscription) | [Docs](https://ardhi.github.io/sumba-subscription) | sumbaSubscription | subs | Sumba Subscription: Member subscriptions |
27
+ | [@sumba/weather](https://bajo.app/premium-plugins/sumba-weather) | [Docs](https://ardhi.github.io/sumba-weather) | sumbaWeather | weather | Sumba Weather by Rappid Datahub |
28
+ | [@sumba/webstat](https://bajo.app/premium-plugins/sumba-webstat) | [Docs](https://ardhi.github.io/sumba-webstat) | sumbaWebstat | webstat | Sumba Web Statistic |
@@ -0,0 +1 @@
1
+ # Getting Started
@@ -0,0 +1 @@
1
+ # User Guide
@@ -1,8 +0,0 @@
1
- import { handler } from './dobo@before-record-find.js'
2
-
3
- const doboBeforeRecordCount = {
4
- level: 1000,
5
- handler
6
- }
7
-
8
- export default doboBeforeRecordCount
@@ -1,8 +0,0 @@
1
- import { handler } from './dobo@before-record-find.js'
2
-
3
- const doboBeforeRecordFindOne = {
4
- level: 1000,
5
- handler
6
- }
7
-
8
- export default doboBeforeRecordFindOne