mwoffliner 1.17.4 → 2.0.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 (227) hide show
  1. package/README.md +355 -62
  2. package/docs/functional_architecture.md +34 -38
  3. package/extensions/wiktionary_fr.js +18 -17
  4. package/jest.config.cjs +2 -2
  5. package/lib/DOMUtils.js +0 -1
  6. package/lib/DOMUtils.js.map +1 -1
  7. package/lib/Downloader.d.ts +39 -31
  8. package/lib/Downloader.js +418 -349
  9. package/lib/Downloader.js.map +1 -1
  10. package/lib/Dump.d.ts +24 -10
  11. package/lib/Dump.js +95 -50
  12. package/lib/Dump.js.map +1 -1
  13. package/lib/Gadgets.d.ts +2 -1
  14. package/lib/Gadgets.js +7 -5
  15. package/lib/Gadgets.js.map +1 -1
  16. package/lib/Logger.d.ts +6 -6
  17. package/lib/Logger.js +33 -33
  18. package/lib/Logger.js.map +1 -1
  19. package/lib/MediaWiki.d.ts +14 -31
  20. package/lib/MediaWiki.js +119 -172
  21. package/lib/MediaWiki.js.map +1 -1
  22. package/lib/RedisStore.d.ts +3 -3
  23. package/lib/RedisStore.js +21 -23
  24. package/lib/RedisStore.js.map +1 -1
  25. package/lib/S3.js +1 -1
  26. package/lib/S3.js.map +1 -1
  27. package/lib/Templates.d.ts +3 -10
  28. package/lib/Templates.js +5 -14
  29. package/lib/Templates.js.map +1 -1
  30. package/lib/cli.js +7 -6
  31. package/lib/cli.js.map +1 -1
  32. package/lib/config.d.ts +10 -16
  33. package/lib/config.js +33 -55
  34. package/lib/config.js.map +1 -1
  35. package/lib/error.manager.d.ts +2 -2
  36. package/lib/error.manager.js +42 -49
  37. package/lib/error.manager.js.map +1 -1
  38. package/lib/i18n.d.ts +2 -0
  39. package/lib/i18n.js +53 -0
  40. package/lib/i18n.js.map +1 -0
  41. package/lib/mutex.d.ts +2 -1
  42. package/lib/mutex.js +2 -1
  43. package/lib/mutex.js.map +1 -1
  44. package/lib/mwoffliner.lib.js +370 -222
  45. package/lib/mwoffliner.lib.js.map +1 -1
  46. package/lib/parameterList.d.ts +20 -8
  47. package/lib/parameterList.js +30 -18
  48. package/lib/parameterList.js.map +1 -1
  49. package/lib/renderers/abstract.renderer.d.ts +48 -55
  50. package/lib/renderers/abstract.renderer.js +377 -98
  51. package/lib/renderers/abstract.renderer.js.map +1 -1
  52. package/lib/renderers/action-parse.renderer.d.ts +22 -3
  53. package/lib/renderers/action-parse.renderer.js +123 -81
  54. package/lib/renderers/action-parse.renderer.js.map +1 -1
  55. package/lib/renderers/renderer.builder.js +6 -69
  56. package/lib/renderers/renderer.builder.js.map +1 -1
  57. package/lib/renderers/rendering.context.d.ts +2 -3
  58. package/lib/renderers/rendering.context.js +6 -14
  59. package/lib/renderers/rendering.context.js.map +1 -1
  60. package/lib/sanitize-argument.d.ts +7 -4
  61. package/lib/sanitize-argument.js +99 -41
  62. package/lib/sanitize-argument.js.map +1 -1
  63. package/lib/util/FileManager.d.ts +36 -0
  64. package/lib/util/FileManager.js +246 -0
  65. package/lib/util/FileManager.js.map +1 -0
  66. package/lib/util/RedisKvs.js +4 -4
  67. package/lib/util/RedisKvs.js.map +1 -1
  68. package/lib/util/RedisQueue.js +1 -1
  69. package/lib/util/RedisQueue.js.map +1 -1
  70. package/lib/util/builders/url/action-parse.director.d.ts +2 -2
  71. package/lib/util/builders/url/action-parse.director.js +7 -7
  72. package/lib/util/builders/url/action-parse.director.js.map +1 -1
  73. package/lib/util/builders/url/api.director.d.ts +2 -4
  74. package/lib/util/builders/url/api.director.js +10 -17
  75. package/lib/util/builders/url/api.director.js.map +1 -1
  76. package/lib/util/builders/url/base.director.d.ts +0 -4
  77. package/lib/util/builders/url/base.director.js +0 -25
  78. package/lib/util/builders/url/base.director.js.map +1 -1
  79. package/lib/util/builders/url/basic.director.d.ts +1 -1
  80. package/lib/util/builders/url/basic.director.js +1 -1
  81. package/lib/util/builders/url/web.director.d.ts +1 -1
  82. package/lib/util/builders/url/web.director.js +2 -2
  83. package/lib/util/builders/url/web.director.js.map +1 -1
  84. package/lib/util/categories.d.ts +5 -5
  85. package/lib/util/categories.js +175 -174
  86. package/lib/util/categories.js.map +1 -1
  87. package/lib/util/const.d.ts +4 -8
  88. package/lib/util/const.js +9 -17
  89. package/lib/util/const.js.map +1 -1
  90. package/lib/util/customCssJs.d.ts +6 -0
  91. package/lib/util/customCssJs.js +70 -0
  92. package/lib/util/customCssJs.js.map +1 -0
  93. package/lib/util/dump.d.ts +15 -4
  94. package/lib/util/dump.js +282 -86
  95. package/lib/util/dump.js.map +1 -1
  96. package/lib/util/index.d.ts +1 -1
  97. package/lib/util/index.js +1 -1
  98. package/lib/util/index.js.map +1 -1
  99. package/lib/util/metaData.js.map +1 -1
  100. package/lib/util/misc.d.ts +23 -13
  101. package/lib/util/misc.js +90 -59
  102. package/lib/util/misc.js.map +1 -1
  103. package/lib/util/mw-api.d.ts +7 -5
  104. package/lib/util/mw-api.js +167 -221
  105. package/lib/util/mw-api.js.map +1 -1
  106. package/lib/util/pageListMainPage.d.ts +3 -0
  107. package/lib/util/pageListMainPage.js +10 -0
  108. package/lib/util/pageListMainPage.js.map +1 -0
  109. package/lib/util/pages.d.ts +30 -0
  110. package/lib/util/pages.js +146 -0
  111. package/lib/util/pages.js.map +1 -0
  112. package/lib/util/rewriteUrls.d.ts +2 -2
  113. package/lib/util/rewriteUrls.js +33 -31
  114. package/lib/util/rewriteUrls.js.map +1 -1
  115. package/lib/util/savePages.d.ts +8 -0
  116. package/lib/util/savePages.js +182 -0
  117. package/lib/util/savePages.js.map +1 -0
  118. package/lib/version.d.ts +1 -1
  119. package/lib/version.js +1 -1
  120. package/lib/version.js.map +1 -1
  121. package/offliner-definition.json +178 -90
  122. package/package.json +50 -49
  123. package/res/page_list_home.js +20 -0
  124. package/res/{article_not_found.svg → page_not_found.svg} +1 -1
  125. package/res/script.js +30 -45
  126. package/res/style.css +52 -68
  127. package/res/templates/download_error_placeholder.html +7 -8
  128. package/res/templates/javaScript.html +19 -0
  129. package/res/templates/pageFallback.html +9 -7
  130. package/res/templates/pageVector2022.html +9 -7
  131. package/res/templates/pageVectorLegacy.html +9 -7
  132. package/res/templates/{article_list_home.html → page_list_home.html} +1 -2
  133. package/translation/ar.json +21 -21
  134. package/translation/bn.json +1 -1
  135. package/translation/de.json +46 -19
  136. package/translation/en.json +54 -21
  137. package/translation/es.json +17 -19
  138. package/translation/fi.json +23 -3
  139. package/translation/fr.json +57 -21
  140. package/translation/he.json +8 -6
  141. package/translation/ia.json +19 -19
  142. package/translation/id.json +13 -13
  143. package/translation/it.json +13 -8
  144. package/translation/ko.json +55 -3
  145. package/translation/lb.json +5 -2
  146. package/translation/mk.json +5 -5
  147. package/translation/nl.json +57 -22
  148. package/translation/or.json +2 -2
  149. package/translation/pt.json +2 -2
  150. package/translation/qqq.json +55 -22
  151. package/translation/ru.json +2 -2
  152. package/translation/sc.json +2 -2
  153. package/translation/sk.json +62 -0
  154. package/translation/sl.json +54 -21
  155. package/translation/sv.json +20 -19
  156. package/translation/sw.json +45 -2
  157. package/translation/zh-hans.json +56 -22
  158. package/translation/zh-hant.json +26 -19
  159. package/lib/renderers/abstractDesktop.render.d.ts +0 -12
  160. package/lib/renderers/abstractDesktop.render.js +0 -67
  161. package/lib/renderers/abstractDesktop.render.js.map +0 -1
  162. package/lib/renderers/abstractMobile.render.d.ts +0 -12
  163. package/lib/renderers/abstractMobile.render.js +0 -54
  164. package/lib/renderers/abstractMobile.render.js.map +0 -1
  165. package/lib/renderers/rest-api.renderer.d.ts +0 -7
  166. package/lib/renderers/rest-api.renderer.js +0 -68
  167. package/lib/renderers/rest-api.renderer.js.map +0 -1
  168. package/lib/renderers/visual-editor.renderer.d.ts +0 -7
  169. package/lib/renderers/visual-editor.renderer.js +0 -76
  170. package/lib/renderers/visual-editor.renderer.js.map +0 -1
  171. package/lib/renderers/wikimedia-desktop.renderer.d.ts +0 -4
  172. package/lib/renderers/wikimedia-desktop.renderer.js +0 -7
  173. package/lib/renderers/wikimedia-desktop.renderer.js.map +0 -1
  174. package/lib/renderers/wikimedia-mobile.renderer.d.ts +0 -19
  175. package/lib/renderers/wikimedia-mobile.renderer.js +0 -243
  176. package/lib/renderers/wikimedia-mobile.renderer.js.map +0 -1
  177. package/lib/util/articleListMainPage.d.ts +0 -3
  178. package/lib/util/articleListMainPage.js +0 -10
  179. package/lib/util/articleListMainPage.js.map +0 -1
  180. package/lib/util/articles.d.ts +0 -26
  181. package/lib/util/articles.js +0 -102
  182. package/lib/util/articles.js.map +0 -1
  183. package/lib/util/builders/url/desktop.director.d.ts +0 -8
  184. package/lib/util/builders/url/desktop.director.js +0 -15
  185. package/lib/util/builders/url/desktop.director.js.map +0 -1
  186. package/lib/util/builders/url/mobile.director.d.ts +0 -8
  187. package/lib/util/builders/url/mobile.director.js +0 -15
  188. package/lib/util/builders/url/mobile.director.js.map +0 -1
  189. package/lib/util/builders/url/rest-api.director.d.ts +0 -8
  190. package/lib/util/builders/url/rest-api.director.js +0 -18
  191. package/lib/util/builders/url/rest-api.director.js.map +0 -1
  192. package/lib/util/builders/url/visual-editor.director.d.ts +0 -9
  193. package/lib/util/builders/url/visual-editor.director.js +0 -18
  194. package/lib/util/builders/url/visual-editor.director.js.map +0 -1
  195. package/lib/util/saveArticles.d.ts +0 -8
  196. package/lib/util/saveArticles.js +0 -411
  197. package/lib/util/saveArticles.js.map +0 -1
  198. package/res/article_list_home.js +0 -24
  199. package/res/content.parsoid.css +0 -196
  200. package/res/inserted_style.css +0 -45
  201. package/res/templates/categories.html +0 -11
  202. package/res/templates/lead_section_wrapper.html +0 -6
  203. package/res/templates/pageWikimediaDesktop.html +0 -24
  204. package/res/templates/pageWikimediaMobile.html +0 -24
  205. package/res/templates/section_wrapper.html +0 -5
  206. package/res/templates/subcategories.html +0 -23
  207. package/res/templates/subpages.html +0 -17
  208. package/res/templates/subsection_wrapper.html +0 -5
  209. package/res/webpHandler.js +0 -165
  210. package/res/wm_mobile_override_script.js +0 -15
  211. package/res/wm_mobile_override_style.css +0 -20
  212. package/translation/br.json +0 -8
  213. package/translation/dag.json +0 -9
  214. package/translation/es-formal.json +0 -29
  215. package/translation/ha.json +0 -10
  216. package/translation/hi.json +0 -9
  217. package/translation/ig.json +0 -10
  218. package/translation/kaa.json +0 -9
  219. package/translation/nb.json +0 -9
  220. package/translation/nqo.json +0 -8
  221. package/translation/pt-br.json +0 -10
  222. package/translation/ro.json +0 -9
  223. package/translation/scn.json +0 -8
  224. package/translation/sq.json +0 -9
  225. package/translation/te.json +0 -9
  226. package/translation/tn.json +0 -9
  227. package/translation/tr.json +0 -10
package/lib/Logger.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Logger.js","sourceRoot":"","sources":["../src/Logger.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;AAGlE,IAAI,YAAY,GAAG,OAAO,CAAA;AAE1B,MAAM,SAAS,GAAG,CAAC,KAAe,EAAE,EAAE;IACpC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,iBAAiB,GAAG,SAAS,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IACzD,MAAM,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC9C,OAAO,aAAa,IAAI,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAA;AAC1D,CAAC,CAAA;AAED,MAAM,KAAK,GAAG,CAAC,IAAc,EAAE,IAAW,EAAE,EAAE;IAC5C,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,MAAM,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;IAClD,CAAC;AACH,CAAC,CAAA;AAED,MAAM,KAAK,GAAG,GAAG,EAAE;IACjB,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;AACjC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAsB,EAAE,EAAE;IACxD,YAAY,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAA;AAChD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE;IACrC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;AACrB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE;IACpC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;AACpB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE;IACrC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;AACrB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE;IACtC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;AACtB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAU,EAAE,EAAE;IACxC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,GAAG;aACZ,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,SAAS,CAAC;aACnC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;QAC9B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"Logger.js","sourceRoot":"","sources":["../src/Logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,UAAU,MAAM,aAAa,CAAA;AAEpC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAU,CAAA;AAG9E,2FAA2F;AAC3F,sFAAsF;AACtF,MAAM,MAAM,GAAG,UAAU,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK;IACvC,WAAW,EAAE,OAAO,CAAC,MAAM;IAC3B,MAAM,EAAE,cAAc;IACtB,aAAa,EAAE,2BAA2B;CAC3C,CAAC,CAAA;AACF,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAA;AAE/C,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAe,EAAE,EAAE;IAC7C,KAAK,CAAC,KAAK,GAAG,KAAK,CAAA;AACrB,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,SAA8C,EAAE,EAAE;IACnE,OAAO,CAAC,GAAW,EAAE,GAAG,IAAW,EAAE,EAAE;QACrC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,KAAK,EAAE,CAAC;YAClD,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;QACzC,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAA;QACxC,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;AACvC,MAAM,CAAC,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;AACrC,MAAM,CAAC,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;AACrC,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;AAEvC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAU,EAAE,EAAE;IACxC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,GAAG;aACZ,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,SAAS,CAAC;aACnC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;QAC9B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;AACH,CAAC,CAAA"}
@@ -1,17 +1,15 @@
1
1
  import { Gadget } from './Gadgets.js';
2
2
  import BaseURLDirector from './util/builders/url/base.director.js';
3
- import WikimediaDesktopURLDirector from './util/builders/url/desktop.director.js';
4
- import WikimediaMobileURLDirector from './util/builders/url/mobile.director.js';
5
- import VisualEditorURLDirector from './util/builders/url/visual-editor.director.js';
6
- import RestApiURLDirector from './util/builders/url/rest-api.director.js';
7
3
  import ActionParseURLDirector from './util/builders/url/action-parse.director.js';
8
4
  export interface QueryOpts {
9
5
  action: string;
10
6
  format: string;
11
7
  prop: string;
12
8
  rdlimit: string;
13
- rdnamespace: string | number;
14
9
  rdprop: string;
10
+ ppprop: string;
11
+ clprop: string;
12
+ cllimit: string;
15
13
  redirects?: boolean;
16
14
  formatversion: string;
17
15
  maxlag: string;
@@ -68,6 +66,7 @@ export interface SiteInfoGeneral {
68
66
  variants?: {
69
67
  code: string;
70
68
  }[];
69
+ categorycollation: string;
71
70
  }
72
71
  export interface SiteInfoSkin {
73
72
  code: string;
@@ -82,30 +81,21 @@ declare class MediaWiki {
82
81
  metaData: MWMetaData;
83
82
  baseUrl: URL;
84
83
  getCategories: boolean;
84
+ categoriesPageSize: number;
85
85
  namespaces: MWNamespaces;
86
86
  namespacesToMirror: string[];
87
- apiCheckArticleId: string;
87
+ apiCheckPageTitle: PageTitle;
88
88
  queryOpts: QueryOpts;
89
89
  urlDirector: BaseURLDirector;
90
90
  skin: string;
91
- wikimediaDesktopUrlDirector: WikimediaDesktopURLDirector;
92
- wikimediaMobileUrlDirector: WikimediaMobileURLDirector;
93
- visualEditorUrlDirector: VisualEditorURLDirector;
94
- restApiUrlDirector: RestApiURLDirector;
95
91
  actionParseUrlDirector: ActionParseURLDirector;
96
- visualEditorApiUrl: URL;
97
92
  actionApiUrl: URL;
98
- restApiUrl: URL;
99
93
  webUrl: URL;
100
- wikimediaDesktopApiUrl: URL;
101
- wikimediaMobileApiUrl: URL;
102
94
  modulePath: string;
103
- mobileModulePath: string;
104
95
  set username(value: string);
105
96
  set password(value: string);
106
97
  get actionApiPath(): string;
107
98
  set actionApiPath(value: string);
108
- set restApiPath(value: string);
109
99
  set domain(value: string);
110
100
  set wikiPath(value: string);
111
101
  set indexPhpPath(value: string);
@@ -113,39 +103,32 @@ declare class MediaWiki {
113
103
  set modulePathOpt(value: string);
114
104
  private initializeMediaWikiDefaults;
115
105
  private constructor();
116
- hasWikimediaDesktopApi(): Promise<boolean>;
117
- hasWikimediaMobileApi(): Promise<boolean>;
118
- hasVisualEditorApi(): Promise<boolean>;
119
- hasRestApi(): Promise<boolean>;
120
106
  hasActionParseApi(): Promise<boolean>;
121
107
  hasCoordinates(): Promise<boolean>;
122
108
  hasModuleApi(): Promise<boolean>;
123
- private setWikimediaDesktopApiUrl;
124
- private setWikimediaMobileApiUrl;
125
- private setRestApiURL;
126
- private setVisualEditorURL;
109
+ hasFlaggedRevs(): Promise<boolean>;
127
110
  private setModuleURL;
128
- private setMobileModuleUrl;
129
- login(): Promise<void>;
130
- setNamespaces(json: SiteInfoQueryResponse, addNamespaces: number[]): void;
131
- extractPageTitleFromHref(href: any): any;
111
+ login(mightBeAlreadyLoggedIn?: boolean): Promise<void>;
112
+ setNamespaces(json: SiteInfoQueryResponse, addNamespaces: number[], onlyNamespaces: number[]): void;
113
+ extractPageTitleFromHref(href: any): PageTitle;
132
114
  getCreatorName(): string;
133
115
  getDefaultSkin(skins: SiteInfoSkin[]): string;
134
- getSiteInfo({ mwWikiPath, mwIndexPhpPath, addNamespaces, mwRestApiPath, mwModulePath, forceSkin, langVariant }?: SiteInfoArgv): Promise<{
116
+ getSiteInfo({ addNamespaces, onlyNamespaces, mwModulePath, forceSkin, langVariants }?: GetSiteInfoArgv): Promise<{
135
117
  mainPage: string;
136
118
  mainPageIsDomainRoot: boolean;
137
119
  siteName: string;
138
120
  textDir: string;
139
121
  langMw: string;
140
- langVar: string;
141
122
  langIso2: any;
142
123
  langIso3: any;
143
124
  logo: string;
144
125
  licenseName: string;
145
126
  licenseUrl: string;
146
127
  subTitle: string;
128
+ categoryCollation: string;
129
+ versionMw: string;
147
130
  }>;
148
- getMwMetaData(argvOpts?: SiteInfoArgv): Promise<MWMetaData>;
131
+ getMwMetaData(argvOpts?: GetSiteInfoArgv): Promise<MWMetaData>;
149
132
  reset(): void;
150
133
  }
151
134
  declare const _default: MediaWiki;
package/lib/MediaWiki.js CHANGED
@@ -8,10 +8,6 @@ import semver from 'semver';
8
8
  import basicURLDirector from './util/builders/url/basic.director.js';
9
9
  import BaseURLDirector from './util/builders/url/base.director.js';
10
10
  import ApiURLDirector from './util/builders/url/api.director.js';
11
- import WikimediaDesktopURLDirector from './util/builders/url/desktop.director.js';
12
- import WikimediaMobileURLDirector from './util/builders/url/mobile.director.js';
13
- import VisualEditorURLDirector from './util/builders/url/visual-editor.director.js';
14
- import RestApiURLDirector from './util/builders/url/rest-api.director.js';
15
11
  import ActionParseURLDirector from './util/builders/url/action-parse.director.js';
16
12
  import { checkApiAvailability } from './util/mw-api.js';
17
13
  import { BLACKLISTED_NS } from './util/const.js';
@@ -27,9 +23,10 @@ class MediaWiki {
27
23
  metaData;
28
24
  baseUrl;
29
25
  getCategories;
26
+ categoriesPageSize;
30
27
  namespaces = {};
31
28
  namespacesToMirror = [];
32
- apiCheckArticleId;
29
+ apiCheckPageTitle;
33
30
  queryOpts;
34
31
  urlDirector;
35
32
  skin = 'vector'; // Default fallback
@@ -37,31 +34,18 @@ class MediaWiki {
37
34
  #indexPhpPath;
38
35
  #actionApiPath;
39
36
  #modulePathOpt;
40
- #restApiPath;
41
37
  #username;
42
38
  #password;
43
39
  #domain;
44
- wikimediaDesktopUrlDirector;
45
- wikimediaMobileUrlDirector;
46
- visualEditorUrlDirector;
47
- restApiUrlDirector;
48
40
  actionParseUrlDirector;
49
- visualEditorApiUrl;
50
41
  actionApiUrl;
51
- restApiUrl;
52
42
  webUrl;
53
- wikimediaDesktopApiUrl;
54
- wikimediaMobileApiUrl;
55
43
  modulePath; // only for reading
56
- mobileModulePath;
57
44
  #apiUrlDirector;
58
- #hasWikimediaDesktopApi;
59
- #hasWikimediaMobileApi;
60
- #hasVisualEditorApi;
61
- #hasRestApi;
62
45
  #hasActionParseApi;
63
46
  #hasCoordinates;
64
47
  #hasModuleApi;
48
+ #hasFlaggedRevs;
65
49
  set username(value) {
66
50
  this.#username = value;
67
51
  }
@@ -75,13 +59,7 @@ class MediaWiki {
75
59
  if (value) {
76
60
  this.#actionApiPath = value;
77
61
  this.actionApiUrl = this.urlDirector.buildURL(this.#actionApiPath);
78
- this.setVisualEditorURL();
79
- }
80
- }
81
- set restApiPath(value) {
82
- if (value) {
83
- this.#restApiPath = value;
84
- this.setRestApiURL();
62
+ this.#apiUrlDirector = new ApiURLDirector(this.actionApiUrl.href);
85
63
  }
86
64
  }
87
65
  set domain(value) {
@@ -91,7 +69,7 @@ class MediaWiki {
91
69
  if (value) {
92
70
  this.#wikiPath = value;
93
71
  this.webUrl = this.urlDirector.buildURL(this.#wikiPath);
94
- logger.log(`webUrl: ${this.webUrl}`);
72
+ logger.info(`webUrl: ${this.webUrl}`);
95
73
  }
96
74
  }
97
75
  set indexPhpPath(value) {
@@ -105,12 +83,8 @@ class MediaWiki {
105
83
  this.urlDirector = new BaseURLDirector(this.baseUrl.href);
106
84
  this.webUrl = this.urlDirector.buildURL(this.#wikiPath);
107
85
  this.actionApiUrl = this.urlDirector.buildURL(this.#actionApiPath);
108
- this.setWikimediaDesktopApiUrl();
109
- this.setWikimediaMobileApiUrl();
110
- this.setRestApiURL();
111
- this.setVisualEditorURL();
86
+ this.#apiUrlDirector = new ApiURLDirector(this.actionApiUrl.href);
112
87
  this.setModuleURL();
113
- this.setMobileModuleUrl();
114
88
  }
115
89
  }
116
90
  set modulePathOpt(value) {
@@ -130,98 +104,58 @@ class MediaWiki {
130
104
  this.#password = '';
131
105
  this.getCategories = false;
132
106
  this.#actionApiPath = '/w/api.php';
133
- this.#restApiPath = '/w/rest.php';
134
107
  this.#wikiPath = '/wiki/';
135
108
  this.#indexPhpPath = '/w/index.php';
136
109
  this.#modulePathOpt = '/w/load.php';
137
110
  this.namespaces = {};
138
111
  this.namespacesToMirror = [];
139
- this.apiCheckArticleId = 'MediaWiki:Sidebar';
112
+ this.apiCheckPageTitle = 'MediaWiki:Sidebar';
140
113
  this.queryOpts = {
141
114
  action: 'query',
142
115
  format: 'json',
143
- prop: 'info|redirects|revisions',
116
+ prop: 'info|redirects|revisions|categoryinfo|pageprops|categories',
144
117
  rdlimit: 'max',
145
- rdnamespace: '0',
146
118
  // pageid in rdprop is not mandatory in general, but required for proper
147
119
  // mdwiki API operation
148
120
  rdprop: 'pageid|title|fragment',
121
+ ppprop: 'nogallery',
122
+ clprop: 'hidden',
123
+ cllimit: 'max',
149
124
  redirects: false,
150
125
  formatversion: '2',
151
126
  maxlag: config.defaults.maxlag,
152
127
  };
153
- this.#hasWikimediaDesktopApi = null;
154
- this.#hasWikimediaMobileApi = null;
155
- this.#hasVisualEditorApi = null;
156
- this.#hasRestApi = null;
157
128
  this.#hasActionParseApi = null;
158
129
  this.#hasCoordinates = null;
159
130
  this.#hasModuleApi = null;
131
+ this.#hasFlaggedRevs = null;
160
132
  this.metaData = null;
161
133
  }
162
134
  constructor() {
163
135
  this.initializeMediaWikiDefaults();
164
136
  }
165
- async hasWikimediaDesktopApi() {
166
- if (this.#hasWikimediaDesktopApi === null) {
167
- this.wikimediaDesktopUrlDirector = new WikimediaDesktopURLDirector(this.wikimediaDesktopApiUrl.href);
168
- const checkUrl = this.wikimediaDesktopUrlDirector.buildArticleURL(this.apiCheckArticleId);
169
- this.#hasWikimediaDesktopApi = await checkApiAvailability(checkUrl);
170
- logger.log('Checked for WikimediaDesktopApi at', checkUrl, '-- result is: ', this.#hasWikimediaDesktopApi);
171
- }
172
- return this.#hasWikimediaDesktopApi;
173
- }
174
- async hasWikimediaMobileApi() {
175
- if (this.#hasWikimediaMobileApi === null) {
176
- this.wikimediaMobileUrlDirector = new WikimediaMobileURLDirector(this.wikimediaMobileApiUrl.href);
177
- const checkUrl = this.wikimediaMobileUrlDirector.buildArticleURL(this.apiCheckArticleId);
178
- this.#hasWikimediaMobileApi = await checkApiAvailability(checkUrl);
179
- logger.log('Checked for WikimediaMobileApi at', checkUrl, '-- result is: ', this.#hasWikimediaMobileApi);
180
- }
181
- return this.#hasWikimediaMobileApi;
182
- }
183
- async hasVisualEditorApi() {
184
- if (this.#hasVisualEditorApi === null) {
185
- this.visualEditorUrlDirector = new VisualEditorURLDirector(this.visualEditorApiUrl.href);
186
- const checkUrl = this.visualEditorUrlDirector.buildArticleURL(this.apiCheckArticleId);
187
- this.#hasVisualEditorApi = await checkApiAvailability(checkUrl, this.visualEditorUrlDirector.validMimeTypes);
188
- logger.log('Checked for VisualEditorApi at', checkUrl, '-- result is: ', this.#hasVisualEditorApi);
189
- }
190
- return this.#hasVisualEditorApi;
191
- }
192
- async hasRestApi() {
193
- if (this.#hasRestApi === null) {
194
- this.restApiUrlDirector = new RestApiURLDirector(this.restApiUrl.href);
195
- const checkUrl = this.restApiUrlDirector.buildArticleURL(this.apiCheckArticleId);
196
- this.#hasRestApi = await checkApiAvailability(checkUrl);
197
- logger.log('Checked for RestApi at', checkUrl, '-- result is: ', this.#hasRestApi);
198
- }
199
- return this.#hasRestApi;
200
- }
201
137
  async hasActionParseApi() {
202
138
  if (this.#hasActionParseApi === null) {
203
- this.actionParseUrlDirector = new ActionParseURLDirector(this.actionApiUrl.href, this.skin, this.metaData.langVar);
204
- const checkUrl = this.actionParseUrlDirector.buildArticleURL(this.apiCheckArticleId);
139
+ this.actionParseUrlDirector = new ActionParseURLDirector(this.actionApiUrl.href, this.skin);
140
+ const checkUrl = this.actionParseUrlDirector.buildPageUrl(this.apiCheckPageTitle);
205
141
  this.#hasActionParseApi = await checkApiAvailability(checkUrl);
206
- logger.log(`Checked for ActionParseApi at ${checkUrl} -- result is: ${this.#hasActionParseApi}`);
142
+ logger.info(`Checked for ActionParseApi at ${checkUrl} -- result is: ${this.#hasActionParseApi}`);
207
143
  }
208
144
  return this.#hasActionParseApi;
209
145
  }
210
146
  async hasCoordinates() {
211
147
  if (this.#hasCoordinates === null) {
212
- const validNamespaceIds = this.namespacesToMirror.map((ns) => this.namespaces[ns].num);
213
148
  const reqOpts = {
214
149
  ...this.queryOpts,
215
150
  prop: this.queryOpts.prop + '|coordinates', // add coordinates for this call to get proper warning if not supported
216
- rdnamespace: validNamespaceIds.join('|'),
217
151
  };
218
152
  const resp = await Downloader.getJSON(this.#apiUrlDirector.buildQueryURL(reqOpts));
219
153
  const isCoordinateWarning = JSON.stringify(resp?.warnings?.query ?? '').includes('coordinates');
220
154
  if (isCoordinateWarning) {
221
- logger.log('Coordinates not available on this wiki');
155
+ logger.info('Coordinates not available on this wiki');
222
156
  return (this.#hasCoordinates = false);
223
157
  }
224
- logger.log('Coordinates available on this wiki');
158
+ logger.info('Coordinates available on this wiki');
225
159
  return (this.#hasCoordinates = true);
226
160
  }
227
161
  return this.#hasCoordinates;
@@ -231,30 +165,32 @@ class MediaWiki {
231
165
  // startup JS module is supposed to be available on all Mediawikis
232
166
  const checkUrl = `${this.modulePath}lang=en&modules=startup&only=scripts`;
233
167
  this.#hasModuleApi = await checkApiAvailability(checkUrl);
234
- logger.log('Checked for Module API at', checkUrl, '-- result is: ', this.#hasRestApi);
168
+ logger.info('Checked for Module API at', checkUrl, '-- result is: ', this.#hasModuleApi);
235
169
  }
236
170
  return this.#hasModuleApi;
237
171
  }
238
- setWikimediaDesktopApiUrl() {
239
- this.wikimediaDesktopApiUrl = this.urlDirector.buildWikimediaDesktopApiUrl();
240
- }
241
- setWikimediaMobileApiUrl() {
242
- this.wikimediaMobileApiUrl = this.urlDirector.buildWikimediaMobileApiUrl();
243
- }
244
- setRestApiURL() {
245
- this.restApiUrl = this.urlDirector.buildRestApiUrl(this.#restApiPath);
246
- }
247
- setVisualEditorURL() {
248
- this.#apiUrlDirector = new ApiURLDirector(this.actionApiUrl.href);
249
- this.visualEditorApiUrl = this.#apiUrlDirector.buildVisualEditorURL();
172
+ async hasFlaggedRevs() {
173
+ if (this.#hasFlaggedRevs === null) {
174
+ const reqOpts = {
175
+ ...this.queryOpts,
176
+ prop: 'info|flagged',
177
+ titles: this.apiCheckPageTitle,
178
+ };
179
+ const resp = await Downloader.getJSON(this.#apiUrlDirector.buildQueryURL(reqOpts));
180
+ const isFlaggedWarning = JSON.stringify(resp?.warnings?.query ?? '').includes('flagged');
181
+ if (isFlaggedWarning) {
182
+ logger.info('FlaggedRevs not available on this wiki');
183
+ return (this.#hasFlaggedRevs = false);
184
+ }
185
+ logger.info('FlaggedRevs available on this wiki');
186
+ return (this.#hasFlaggedRevs = true);
187
+ }
188
+ return this.#hasFlaggedRevs;
250
189
  }
251
190
  setModuleURL() {
252
191
  this.modulePath = this.urlDirector.buildModuleURL(this.#modulePathOpt);
253
192
  }
254
- setMobileModuleUrl() {
255
- this.mobileModulePath = this.urlDirector.buildMobileModuleURL();
256
- }
257
- async login() {
193
+ async login(mightBeAlreadyLoggedIn = false) {
258
194
  if (this.#username && this.#password) {
259
195
  let url = this.actionApiUrl.href + '?';
260
196
  // Add domain if configured
@@ -281,17 +217,25 @@ class MediaWiki {
281
217
  if (resp.data.login?.result !== 'Success') {
282
218
  const reason = resp.data.login?.reason;
283
219
  if (reason) {
284
- logger.error(reason);
220
+ if (mightBeAlreadyLoggedIn && reason.includes('Cannot log in when using MediaWiki\\Session\\BotPasswordSessionProvider sessions')) {
221
+ logger.info('Already logged in');
222
+ }
223
+ else {
224
+ logger.error(reason);
225
+ throw new Error('Login Failed');
226
+ }
227
+ }
228
+ else {
229
+ throw new Error('Login Failed');
285
230
  }
286
- throw new Error('Login Failed');
287
231
  }
288
232
  else {
289
- logger.log('Login Success');
233
+ logger.info('Login Success');
290
234
  }
291
235
  });
292
236
  }
293
237
  }
294
- setNamespaces(json, addNamespaces) {
238
+ setNamespaces(json, addNamespaces, onlyNamespaces) {
295
239
  ;
296
240
  ['namespaces', 'namespacealiases'].forEach((type) => {
297
241
  const entries = json[type];
@@ -300,10 +244,8 @@ class MediaWiki {
300
244
  const name = type === 'namespaces' ? entry.name : entry.alias;
301
245
  const num = entry.id;
302
246
  const allowedSubpages = 'subpages' in entry;
303
- const isContent = type === 'namespaces' ? !!(entry.content || util.contains(addNamespaces, num)) : !!(entry.content !== undefined || util.contains(addNamespaces, num));
304
- const isBlacklisted = BLACKLISTED_NS.includes(name);
305
247
  const canonical = entry.canonical ? entry.canonical : '';
306
- const details = { num, allowedSubpages, isContent };
248
+ const details = { num, allowedSubpages };
307
249
  /* Namespaces in local language */
308
250
  this.namespaces[util.lcFirst(name)] = details;
309
251
  this.namespaces[util.ucFirst(name)] = details;
@@ -312,50 +254,63 @@ class MediaWiki {
312
254
  this.namespaces[util.lcFirst(canonical)] = details;
313
255
  this.namespaces[util.ucFirst(canonical)] = details;
314
256
  }
315
- /* Is content to mirror */
316
- if (isContent && !isBlacklisted) {
317
- this.namespacesToMirror.push(name);
257
+ /* Is namespace to mirror */
258
+ if (onlyNamespaces.length) {
259
+ if (util.contains(onlyNamespaces, num)) {
260
+ this.namespacesToMirror.push(name);
261
+ }
262
+ }
263
+ else {
264
+ const isContent = type === 'namespaces' ? !!entry.content : !!(entry.content !== undefined);
265
+ const isBlacklisted = BLACKLISTED_NS.includes(name);
266
+ if ((isContent || util.contains(addNamespaces, num)) && !isBlacklisted) {
267
+ this.namespacesToMirror.push(name);
268
+ }
318
269
  }
319
270
  });
320
271
  });
321
272
  }
322
273
  extractPageTitleFromHref(href) {
323
- try {
324
- const pathname = new URL(href, this.baseUrl).pathname;
325
- // Link to domain root when main page is domain root
326
- if (href === '/' && this.metaData.mainPageIsDomainRoot) {
327
- return this.metaData.mainPage;
328
- }
329
- // Link to index.php with query parameters like "/w/index.php?title=Blue_whale"
330
- if (pathname === this.#indexPhpPath) {
331
- const queryString = href.split('?')[1];
332
- const params = new URLSearchParams(queryString);
333
- return params.get('title');
334
- }
335
- // Local relative URL
336
- if (href.indexOf('./') === 0) {
337
- return util.decodeURIComponent(pathname.substr(1));
338
- }
339
- // Absolute path
340
- if (pathname.startsWith(this.webUrl.pathname)) {
341
- return util.decodeURIComponent(pathname.substr(this.webUrl.pathname.length));
342
- }
343
- const isPaginatedRegExp = /\/[0-9]+(\.|$)/;
344
- const isPaginated = isPaginatedRegExp.test(href);
345
- if (isPaginated) {
346
- const withoutDotHtml = href.split('.').slice(0, -1).join('.');
347
- const lastTwoSlashes = withoutDotHtml.split('/').slice(-2).join('/');
348
- return lastTwoSlashes;
274
+ const extractPageTitleOrIdFromHref = (href) => {
275
+ try {
276
+ const pathname = new URL(href, this.baseUrl).pathname;
277
+ // Link to domain root when main page is domain root
278
+ if (href === '/' && this.metaData.mainPageIsDomainRoot) {
279
+ return this.metaData.mainPage;
280
+ }
281
+ // Link to index.php with query parameters like "/w/index.php?title=Blue_whale"
282
+ if (pathname === this.#indexPhpPath) {
283
+ const queryString = href.split('?')[1];
284
+ const params = new URLSearchParams(queryString);
285
+ return params.get('title');
286
+ }
287
+ // Local relative URL
288
+ if (href.indexOf('./') === 0) {
289
+ return util.decodeURIComponent(pathname.substr(1));
290
+ }
291
+ // Absolute path
292
+ if (pathname.startsWith(this.webUrl.pathname)) {
293
+ return util.decodeURIComponent(pathname.substr(this.webUrl.pathname.length));
294
+ }
295
+ const isPaginatedRegExp = /\/[0-9]+(\.|$)/;
296
+ const isPaginated = isPaginatedRegExp.test(href);
297
+ if (isPaginated) {
298
+ const withoutDotHtml = href.split('.').slice(0, -1).join('.');
299
+ const lastTwoSlashes = withoutDotHtml.split('/').slice(-2).join('/');
300
+ return lastTwoSlashes;
301
+ }
302
+ if (pathParser.parse(href).dir.includes('../')) {
303
+ return pathParser.parse(href).name;
304
+ }
305
+ return null; /* Interwiki link? -- return null */
349
306
  }
350
- if (pathParser.parse(href).dir.includes('../')) {
351
- return pathParser.parse(href).name;
307
+ catch {
308
+ logger.warn(`Unable to parse href ${href}`);
309
+ return null;
352
310
  }
353
- return null; /* Interwiki link? -- return null */
354
- }
355
- catch {
356
- logger.warn(`Unable to parse href ${href}`);
357
- return null;
358
- }
311
+ };
312
+ const pageLink = extractPageTitleOrIdFromHref(href);
313
+ return pageLink && pageLink.replace(/_/g, ' ');
359
314
  }
360
315
  getCreatorName() {
361
316
  /*
@@ -377,7 +332,7 @@ class MediaWiki {
377
332
  }
378
333
  getDefaultSkin(skins) {
379
334
  const defaultSkins = skins.filter((skin) => skin.default).map((skin) => skin.code);
380
- if (defaultSkins.length == 0) {
335
+ if (defaultSkins.length === 0) {
381
336
  throw new Error(`This wiki has no default skin:\n${JSON.stringify(skins)}`);
382
337
  }
383
338
  if (defaultSkins.length > 1) {
@@ -385,8 +340,8 @@ class MediaWiki {
385
340
  }
386
341
  return defaultSkins[0];
387
342
  }
388
- async getSiteInfo({ mwWikiPath, mwIndexPhpPath, addNamespaces, mwRestApiPath, mwModulePath, forceSkin, langVariant } = {}) {
389
- logger.log('Getting site info...');
343
+ async getSiteInfo({ addNamespaces, onlyNamespaces, mwModulePath, forceSkin, langVariants } = {}) {
344
+ logger.info('Getting site info...');
390
345
  const body = await Downloader.querySiteInfo();
391
346
  const generalEntries = body.query.general;
392
347
  // Checking mediawiki version
@@ -395,17 +350,18 @@ class MediaWiki {
395
350
  if (!generalEntries.generator || !semver.satisfies(mwVersion, `>=${mwMinimalVersion}`)) {
396
351
  throw new Error(`Mediawiki version ${mwVersion} not supported should be >=${mwMinimalVersion}`);
397
352
  }
398
- this.setNamespaces(body.query, addNamespaces || []);
353
+ this.setNamespaces(body.query, addNamespaces || [], onlyNamespaces || []);
399
354
  Gadgets.setGadgets(body.query.gadgets);
400
355
  const { url: licenseUrl, text: licenseName } = body.query.rightsinfo;
401
356
  const subTitle = body.query.allmessages[0].content || '';
402
- const mainPage = generalEntries.mainpage.replace(/ /g, '_');
357
+ const mainPage = generalEntries.mainpage;
403
358
  const mainPageIsDomainRoot = generalEntries.mainpageisdomainroot;
404
359
  const siteName = generalEntries.sitename;
360
+ const categoryCollation = generalEntries.categorycollation;
405
361
  const logo = generalEntries.logo;
406
362
  const langMw = generalEntries.lang;
407
363
  const textDir = generalEntries.rtl ? 'rtl' : 'ltr';
408
- logger.log(`Text direction is [${textDir}]`);
364
+ logger.info(`Text direction is [${textDir}]`);
409
365
  // Gather languages codes (en remove the 'dialect' part)
410
366
  const langs = [langMw].concat(generalEntries.fallback.map((e) => e.code)).map(function (e) {
411
367
  return e.replace(/-.*/, '');
@@ -429,46 +385,39 @@ class MediaWiki {
429
385
  return possibleLangPairs[0] || ['en', 'eng'];
430
386
  });
431
387
  // Use CLI parameter and set MediaWiki config
432
- if (mwWikiPath) {
433
- mwWikiPath = mwWikiPath + '$1';
434
- if (mwWikiPath !== generalEntries.articlepath) {
435
- logger.warn(`mwWikiPath [${mwWikiPath}] does not match the path [${generalEntries.articlepath}] returned by the wiki.`);
436
- }
437
- }
438
- const articlepath = mwWikiPath || generalEntries.articlepath;
388
+ const articlepath = generalEntries.articlepath;
439
389
  if (articlepath.includes('?') || !articlepath.endsWith('$1')) {
440
390
  throw new Error(`Article path [${articlepath}] is not supported`);
441
391
  }
442
392
  this.wikiPath = articlepath.replace('$1', '');
443
- if (mwIndexPhpPath && mwIndexPhpPath !== generalEntries.script) {
444
- logger.warn(`mwIndexPhpPath [${mwIndexPhpPath}] does not match the path [${generalEntries.script}] returned by the wiki.`);
445
- }
446
- this.indexPhpPath = mwIndexPhpPath || generalEntries.script;
447
- this.restApiPath = mwRestApiPath || generalEntries.scriptpath + '/rest.php';
393
+ this.indexPhpPath = generalEntries.script;
448
394
  this.modulePathOpt = mwModulePath || generalEntries.scriptpath + '/load.php';
449
395
  const skins = body.query.skins.filter((skin) => !skin.unusable);
450
396
  if (forceSkin && !skins.map((skin) => skin.code).includes(forceSkin)) {
451
397
  throw new Error(`Skin [${forceSkin}] is not usable on the wiki`);
452
398
  }
453
399
  this.skin = forceSkin || this.getDefaultSkin(skins);
454
- const validLangVars = (generalEntries.variants || []).map((e) => e.code);
455
- if (langVariant && !validLangVars.includes(langVariant)) {
456
- throw new Error(`Language variant [${langVariant}] is not available on the wiki`);
400
+ if (langVariants) {
401
+ const validLangVars = (generalEntries.variants || []).map((e) => e.code);
402
+ const invalidLangVars = langVariants.filter((langVariant) => langVariant && !validLangVars.includes(langVariant));
403
+ if (invalidLangVars.length) {
404
+ throw new Error(`Language variants [${invalidLangVars.join(', ')}] is not available on the wiki`);
405
+ }
457
406
  }
458
- const langVar = langVariant || null;
459
407
  return {
460
408
  mainPage,
461
409
  mainPageIsDomainRoot,
462
410
  siteName,
463
411
  textDir,
464
412
  langMw,
465
- langVar,
466
413
  langIso2,
467
414
  langIso3,
468
415
  logo,
469
416
  licenseName,
470
417
  licenseUrl,
471
418
  subTitle,
419
+ categoryCollation,
420
+ versionMw: mwVersion,
472
421
  };
473
422
  }
474
423
  async getMwMetaData(argvOpts = {}) {
@@ -476,24 +425,20 @@ class MediaWiki {
476
425
  return this.metaData;
477
426
  }
478
427
  const creator = this.getCreatorName() || 'Kiwix';
479
- const { langIso2, langIso3, mainPage, mainPageIsDomainRoot, siteName, logo, langMw, langVar, textDir, licenseName, licenseUrl, subTitle } = await this.getSiteInfo(argvOpts);
428
+ const { langIso2, langIso3, mainPage, mainPageIsDomainRoot, siteName, logo, langMw, textDir, licenseName, licenseUrl, subTitle, categoryCollation, versionMw } = await this.getSiteInfo(argvOpts);
480
429
  const mwMetaData = {
481
430
  webUrl: this.webUrl.href,
482
431
  actionApiUrl: this.actionApiUrl.href,
483
- restApiUrl: this.restApiUrl.href,
484
432
  modulePathOpt: this.#modulePathOpt,
485
433
  modulePath: this.modulePath,
486
- mobileModulePath: this.mobileModulePath,
487
434
  webUrlPath: this.webUrl.pathname,
488
435
  wikiPath: this.#wikiPath,
489
436
  indexPhpPath: this.#indexPhpPath,
490
437
  baseUrl: this.baseUrl.href,
491
438
  actionApiPath: this.#actionApiPath,
492
- restApiPath: this.#restApiPath,
493
439
  domain: this.#domain,
494
440
  textDir: textDir,
495
441
  langMw,
496
- langVar,
497
442
  langIso2,
498
443
  langIso3,
499
444
  title: siteName,
@@ -504,6 +449,8 @@ class MediaWiki {
504
449
  logo,
505
450
  licenseName,
506
451
  licenseUrl,
452
+ categoryCollation,
453
+ versionMw,
507
454
  };
508
455
  this.metaData = mwMetaData;
509
456
  return mwMetaData;