wikiploy 1.8.0 → 1.8.2

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.
@@ -1,10 +1,8 @@
1
1
  # Building your project
2
2
 
3
- There are various ways to build scripts. You can use browserify, webpack, TypeScript compiler etc... or even don't build at all. This is all fine, but not all solution are equally well suite for the wiki world and choosing the right solution takes time.
3
+ There are various ways to build scripts. You can use [browserify](https://browserify.org/), webpack, TypeScript compiler, etc., or even choose not to build at all. Wikiploy doesn't force the use of any specific tool (you are free to choose whatever you are comfortable with). However, not all solutions are equally well-suited for the wiki world, and choosing the right solution takes time.
4
4
 
5
- So here is a recommended project setup to save you some time :)
6
-
7
- Some of this is based on a real script. So if you want you can take a look at [wikibot-jsbot-core](https://github.com/Eccenux/wikibot-jsbot-core). Also you might want to take a look at a template repository for Wikiploy: [wikiploy-rollout-example](https://github.com/Eccenux/wikiploy-rollout-example).
5
+ Let me save you some time. Below is a recommended project setup based on some of my real scripts and years of experience building gadgets. If you're interested, you can take a look at a real-world script: [wikibot-jsbot-core](https://github.com/Eccenux/wikibot-jsbot-core) (it's a bit experimental, but you might find some interesting constructs there). For a more stable example, you might want to explore the template repository for Wikiploy: [wikiploy-rollout-example](https://github.com/Eccenux/wikiploy-rollout-example).
8
6
 
9
7
  ## Recommended setup for building scripts
10
8
 
@@ -13,24 +11,29 @@ Example `.gitignore` for your project:
13
11
  /node_modules
14
12
  *.lnk
15
13
  *.priv.*
16
- bot.config.js
14
+ bot.config.*
17
15
  ```
18
16
 
19
17
  Your `package.json` (crucial part being `scripts`):
20
18
  ```js
21
19
  {
22
- "name": "wiki-gadget-yourname",
20
+ "name": "wiki-gadget-yourgadgetname",
23
21
  "type": "commonjs",
24
22
  "scripts": {
25
23
  "test": "mocha",
26
- "build": "browserify src/main.js -o yourname.js",
24
+ "build-less": "lessc src/less/main.less dist/yourGadgetName.css",
25
+ "build-js": "browserify src/main.js -o dist/yourGadgetName.js",
26
+ "build": "npm run build-less && npm run build-js && node -e \"console.log('Build done');\" ",
27
+ "deploy-dev": "node wikiploy-dev.mjs",
27
28
  "deploy": "node wikiploy.mjs",
29
+ "rollout-dev": "npm run build && npm run deploy-dev",
28
30
  "rollout": "npm run build && npm run deploy"
29
31
  },
30
32
  "devDependencies": {
31
33
  "browserify": "17.x",
32
34
  "chai": "4.x",
33
35
  "eslint": "8.x",
36
+ "less": "4.x",
34
37
  "mocha": "10.x"
35
38
  },
36
39
  "dependencies": {
@@ -39,24 +42,65 @@ Your `package.json` (crucial part being `scripts`):
39
42
  }
40
43
  ```
41
44
 
42
- Your `main.js` could look something like this:
45
+ Your `src/main.js` could look something like this:
43
46
  ```js
44
47
  var { MyGadget } = require("./MyGadget");
45
48
 
46
- // bot instance
49
+ // instance
47
50
  var gadget = new MyGadget();
48
51
 
52
+ // init elements
49
53
  $(function(){
50
54
  gadget.init();
51
55
  })
52
56
  ```
53
57
 
54
- ## Visual Studio Code setup
58
+ Your `src/MyGadget.js` could look something like this:
59
+ ```js
60
+ function MyGadget() {
61
+ /** Initialize things when DOM is ready. */
62
+ this.init = function() {
63
+ console.log("init done");
64
+ }
65
+ }
66
+
67
+ module.exports = { MyGadget };
68
+ ```
69
+
70
+ Also should also create a starting point for your CSS `src/less/main.less`:
71
+ ```css
72
+ @primary-color: darken(#3498db, 10%);
73
+ @secondary-color: darken(#e74c3c, 20%);
74
+
75
+ .yourGadgetName {
76
+ background-color: @primary-color;
77
+ color: white;
78
+
79
+ .header {
80
+ background-color: @secondary-color;
81
+ text-align: center;
82
+ }
83
+ }
84
+ ```
55
85
 
56
- [VSC](https://code.visualstudio.com/) is a free editor that over years became almost like an IDE.
86
+ Remember to install tools after changing `package.json`:
87
+ ```bash
88
+ npm i
89
+ ```
57
90
 
58
- VSCode helper to install a set of extensions `.vscode/extensions.json`:
91
+ And now you should already be able to build the script:
92
+ ```bash
93
+ npm run build
59
94
  ```
95
+
96
+ Now we just need to setup things so that we don't have to build and deploy things manually.
97
+
98
+ ## Visual Studio Code setup
99
+
100
+ [VSC](https://code.visualstudio.com/) is a free editor that has evolved over the years to become almost like an IDE. It is great for developing JS scripts.
101
+
102
+ Add `.vscode/extensions.json` to help install a set of **extensions**:
103
+ ```js
60
104
  {
61
105
  "recommendations": [
62
106
  "gsppvo.vscode-commandbar",
@@ -66,72 +110,502 @@ VSCode helper to install a set of extensions `.vscode/extensions.json`:
66
110
  }
67
111
  ```
68
112
 
69
- VSC settings `.vscode/settings.json`:
70
- ```
113
+ VSC **settings** `.vscode/settings.json`:
114
+ ```js
71
115
  {
72
- "search.exclude": {
73
- "package-lock.json": true,
74
- },
75
116
  "editor.detectIndentation": false,
76
117
  "editor.useTabStops": true,
77
118
  "editor.insertSpaces": false,
119
+ "search.exclude": {
120
+ "package-lock.json": true,
121
+ "**/dist/": true,
122
+ },
78
123
  }
79
124
  ```
80
125
 
81
- ## Basic script and dst
126
+ Using tabs vs spaces is obviously your preference. People tend to have conflicting opinions on that. The simple truth is that a tab is one byte, and 4 spaces are 4 bytes, but use whatever works for your project. Just remember to enforce it at the project level so that the style is consistent.
82
127
 
83
- Your minimal `wikiploy.mjs`:
128
+ VSC **tasks** `.vscode/tasks.json`:
84
129
  ```js
85
- import {DeployConfig, WikiployLite, userPrompt} from 'wikiploy';
130
+ {
131
+ "version": "2.0.0",
132
+ "tasks": [
133
+ {
134
+ "type": "npm",
135
+ "script": "test",
136
+ "group": "test",
137
+ "problemMatcher": [],
138
+ "label": "Run tests",
139
+ "detail": "mocha"
140
+ },
141
+ {
142
+ "type": "npm",
143
+ "script": "deploy-dev",
144
+ "group": "none",
145
+ "problemMatcher": [],
146
+ "label": "Run dev deploy",
147
+ "detail": "Run deploy script (wikiploy)"
148
+ },
149
+ {
150
+ "type": "npm",
151
+ "script": "deploy",
152
+ "group": "none",
153
+ "problemMatcher": [],
154
+ "label": "Run deploy",
155
+ "detail": "Run deploy script (wikiploy)"
156
+ },
157
+ {
158
+ "type": "npm",
159
+ "script": "rollout-dev",
160
+ "group": "none",
161
+ "problemMatcher": [],
162
+ "label": "Run dev rollout",
163
+ "detail": "Run rollout script (browserify & wikiploy)"
164
+ },
165
+ {
166
+ "type": "npm",
167
+ "script": "rollout",
168
+ "group": "none",
169
+ "problemMatcher": [],
170
+ "label": "Run rollout",
171
+ "detail": "Run rollout script (browserify & wikiploy)"
172
+ },
173
+ {
174
+ "type": "npm",
175
+ "script": "install",
176
+ "group": "none",
177
+ "problemMatcher": [],
178
+ "label": "npm install",
179
+ "detail": "install dependencies from package"
180
+ }
181
+ ]
182
+ }
183
+ ```
86
184
 
87
- import * as botpass from './bot.config.js';
88
- const ployBot = new WikiployLite(botpass);
185
+ When you use tasks, VSC runs an interactive terminal. This makes some scripts work better:
186
+ - Any scripts that use colors in the terminal will work with tasks.
187
+ - An interactive shell is required for the `userPrompt` helper (see *Deploy script*).
188
+ - Text progress (like in npm install) looks much better with tasks.
89
189
 
90
- // default site for DeployConfig
91
- ployBot.site = "en.wikipedia.org";
190
+ VCS **commandbar** `.vscode/commandbar.json`:
191
+ ```js
192
+ // Remember to change VSC settings (UI): in `files.associations` add `commandbar.json: jsonc`
193
+ {
194
+ "skipTerminateQuickPick": true,
195
+ "skipSwitchToOutput": false,
196
+ "skipErrorMessage": true,
197
+ "commands": [
198
+ // "commandType": "script" runs npm script directly
199
+ {
200
+ "text": "test",
201
+ "tooltip": "Run mocha tests.",
202
+ "color": "lightgreen",
203
+ "commandType": "script",
204
+ "command": "test",
205
+ "priority": 0
206
+ },
207
+
208
+ {
209
+ "text": "build",
210
+ "tooltip": "Run the browserify build.",
211
+ "color": "lightgreen",
212
+ "commandType": "script",
213
+ "command": "build",
214
+ "priority": 0
215
+ },
216
+
217
+ // running deployment as a task (so that prompts work)
218
+ // note that "Run dev deploy" is a label from tasks.json
219
+ {
220
+ "text": "wikiploy-dev",
221
+ "tooltip": "Deploy pre-built script.",
222
+ "color": "lightgreen",
223
+ "commandType": "palette",
224
+ "command": "workbench.action.tasks.runTask|Run dev deploy",
225
+ "priority": 0
226
+ },
92
227
 
93
- // run asynchronously to be able to wait for results
94
- (async () => {
95
- // Note! The `userPrompt` requires an interactive terminal.
96
- // In VSC you can use tasks to get an interactive terminal and still run wikiploy from your commandbar.
228
+ // this our one-click rollout
229
+ {
230
+ "text": "build & deploy-dev",
231
+ "tooltip": "Build (browserify) and deploy (wikiploy).",
232
+ "color": "lightgreen",
233
+ "commandType": "palette",
234
+ "command": "workbench.action.tasks.runTask|Run dev rollout",
235
+ "priority": 0
236
+ }
237
+ ]
238
+ }
239
+ ```
240
+
241
+ Note: You should also change VSC settings (UI) under `files.associations` to add `commandbar.json: jsonc` (JSON with comments). This allows comments in JSON, making it more understandable. Otherwise, VSC will complain about inline comments.
242
+
243
+ Also, note: Above, we only added dev tasks to the command bar. This is just for brevity. The same commands can be added for other tasks.
244
+
245
+ ## Deploy script
246
+
247
+ Your **bot password** configuration `bot.config.mjs`:
248
+ ```js
249
+ /**
250
+ Bot with edit&create rights.
251
+
252
+ https://test.wikipedia.org/wiki/Special:BotPasswords/Wikiploy
253
+
254
+ The new password to log in with Nux@Wikiploy.
255
+ Where "Nux" is a Wikipedia username and "Wikiploy" is a bot name choosen in [[Special:BotPasswords]].
256
+ */
257
+ export const username = 'Nux@Wikiploy';
258
+ export const password = '0abc...fckgw';
259
+ ```
260
+
261
+ Your **common deployment script** `wikiploy-common.mjs`:
262
+ ```js
263
+ import { DeployConfig, userPrompt } from 'wikiploy';
264
+
265
+ /**
266
+ * Add config.
267
+ * @param {Array} configs DeployConfig array.
268
+ * @param {String} site Domian of a MW site.
269
+ */
270
+ export function addConfig(configs, site) {
271
+ configs.push(new DeployConfig({
272
+ src: 'dist/yourGadgetName.js',
273
+ dst: '~/yourGadgetName.js',
274
+ site,
275
+ nowiki: true,
276
+ }));
277
+ configs.push(new DeployConfig({
278
+ src: 'dist/yourGadgetName.css',
279
+ dst: '~/yourGadgetName.css',
280
+ site,
281
+ }));
282
+ }
283
+
284
+ /**
285
+ * Read and setup summary.
286
+ * @param {WikiployLite} ployBot
287
+ */
288
+ export async function setupSummary(ployBot) {
97
289
  const summary = await userPrompt('Summary of changes (empty for default summary):');
98
290
  if (typeof summary === 'string' && summary.length) {
99
291
  ployBot.summary = () => {
100
292
  return summary;
101
- }
293
+ };
102
294
  }
295
+ }
296
+ ```
297
+ We use a separate file to define common functions, making changes to both release and dev Wikiploy scripts simpler.
298
+
299
+ Note that `~` in `dst` properties will be replaced with `User:SomeName`, representing the user space of the currently logged-in user (your user space). For more details about this basic code and `DeployConfig` properties, refer to the [Wikiploy rollout example](https://github.com/Eccenux/wikiploy-rollout-example/).
300
+
301
+ Your minimal **developer deployment script** `wikiploy-dev.mjs`:
302
+ ```js
303
+ import { WikiployLite } from 'wikiploy';
304
+
305
+ import * as botpass from './bot.config.mjs';
306
+ const ployBot = new WikiployLite(botpass);
307
+
308
+ // common deploy function(s)
309
+ import { addConfig, setupSummary } from './wikiploy-common.mjs';
310
+
311
+ // run asynchronously to be able to wait for results
312
+ (async () => {
313
+ // custom summary from a prompt
314
+ await setupSummary(ployBot);
103
315
 
104
316
  // push out file(s) to wiki
105
317
  const configs = [];
106
- configs.push(new DeployConfig({
107
- src: 'test.js',
108
- dst: '~/test-wikiploy--test.js',
109
- nowiki: true,
110
- }));
318
+ addConfig(configs, 'en.wikipedia.org');
319
+
320
+ await ployBot.deploy(configs);
321
+
322
+ })().catch(err => {
323
+ console.error(err);
324
+ process.exit(1);
325
+ });
326
+ ```
327
+
328
+ Your **main deployment script** `wikiploy.mjs`:
329
+ ```js
330
+ import { WikiployLite } from 'wikiploy';
331
+
332
+ import * as botpass from './bot.config.mjs';
333
+ const ployBot = new WikiployLite(botpass);
334
+
335
+ // common deploy function(s)
336
+ import { addConfig, setupSummary } from './wikiploy-common.mjs';
337
+
338
+ // run asynchronously to be able to wait for results
339
+ (async () => {
340
+ // custom summary from a prompt
341
+ await setupSummary(ployBot);
342
+
343
+ // push out file(s) to wiki
344
+ const configs = [];
345
+ addConfig(configs, 'pl.wikipedia.org');
346
+ addConfig(configs, 'en.wikipedia.org');
347
+ addConfig(configs, 'pl.wikisource.org');
348
+
111
349
  await ployBot.deploy(configs);
350
+
112
351
  })().catch(err => {
113
352
  console.error(err);
114
353
  process.exit(1);
115
354
  });
116
355
  ```
117
356
 
118
- Note that `~` will be `User:SomeName` so the user space of a currently logged in user (you user space).
119
- You can omit `dst` and it will default to `dst: '~/${src}'`.
357
+ ## Appendix: Release vs dev release
358
+
359
+ ### Deploying as a gadget
360
+
361
+ There are various ways you could develop gadgets. The most standard way would be to deploy to the `MediaWiki:Gadget-` namespace.
362
+
363
+ In `wikiploy-common.mjs` add:
364
+ ```js
365
+ export function addConfigRelease(configs, site) {
366
+ configs.push(new DeployConfig({
367
+ src: 'dist/yourGadgetName.js',
368
+ dst: 'MediaWiki:Gadget-yourGadgetName.js',
369
+ site,
370
+ nowiki: true,
371
+ }));
372
+ configs.push(new DeployConfig({
373
+ src: 'dist/yourGadgetName.css',
374
+ dst: 'MediaWiki:Gadget-yourGadgetName.css',
375
+ site,
376
+ }));
377
+ }
378
+ ```
379
+
380
+ In your main deployment script you could have something like (`wikiploy.mjs`):
381
+ ```js
382
+ // dev version
383
+ addConfig(configs, 'en.wikipedia.org');
384
+ // release versions
385
+ addConfigRelease(configs, 'pl.wikipedia.org');
386
+ addConfigRelease(configs, 'pl.wikisource.org');
387
+ addConfigRelease(configs, 'en.wikipedia.org');
388
+ ```
389
+ The script doesn't have any limits. However, you do need interface-admin rights to deploy to the `MediaWiki:Gadget-` namespace. So, you might need to use `~/` to deploy to your user-space.
120
390
 
121
- More about this basic code and `dst` in the [Wikiploy rollout example](https://github.com/Eccenux/wikiploy-rollout-example/).
391
+ ### Release version in your user space
122
392
 
123
- ## Exporting stuff
393
+ **If you do *not* have interface-admin rights**, the functions could look like this:
124
394
 
125
- Your `main.js` could look something like this:
395
+ ```js
396
+ export function addConfig(configs, site, isRelease) {
397
+ let deploymentName = isRelease ? '~/yourGadgetName' : '~/yourGadgetName-dev';
398
+ configs.push(new DeployConfig({
399
+ src: 'dist/yourGadgetName.js',
400
+ dst: `${deploymentName}.js`,
401
+ site,
402
+ nowiki: true,
403
+ }));
404
+ configs.push(new DeployConfig({
405
+ src: 'dist/yourGadgetName.css',
406
+ dst: `${deploymentName}.css`,
407
+ site,
408
+ }));
409
+ }
410
+ export function addConfigRelease(configs, site) {
411
+ addConfig(configs, site, true);
412
+ }
413
+ ```
414
+
415
+ In this case, you have both dev and release versions in your user space. Frankly, this might be the best choice, even if you have admin rights, especially if you use the *loader pattern*.
416
+
417
+ ### Loader pattern for gadgets
418
+
419
+ Even if you have all administrative rights on a wiki, you might still want to load the main script from a small loader. The **loader pattern** allows you to provide conditions for loading the main script from the gadget file.
420
+
421
+ The loader pattern is most useful when you want to test specific capabilities of a device and only then load the script. This is how you could load popups (which don't work well on touch devices, i.e., devices that cannot hover).
422
+
423
+ Example of what `MediaWiki:Gadget-Popups.js` could look like:
424
+ ```js
425
+ // only on devices that can hover (not on touch-only, so not on smartphones)
426
+ if (window.matchMedia && !window.matchMedia("(hover: none)").matches) {
427
+ importScript('User:Nux/Popups.js');
428
+ }
429
+ ```
430
+
431
+ You could also have a gadget that is default, but only works on specific pages:
432
+ ```js
433
+ // load config
434
+ var config = mw.config.get( [
435
+ 'wgNamespaceNumber',
436
+ 'wgTitle',
437
+ ] );
438
+ // only on AfD subpages
439
+ if ( config.wgNamespaceNumber == 4 && config.wgTitle.startsWith('Articles for deletion/') ) {
440
+ importScript('User:Nux/AfD-helper.js');
441
+ }
442
+ ```
443
+ The loader pattern is beneficial because it improves website performance. In this pattern, the main gadget code is only loaded when it can be useful.
444
+
445
+ Loading from the `User` namespace might also help make it clear who is responsible for the gadget. However, it might not work when there is no single user responsible, such as when the main author becomes inactive. The community can always decide to fork the script, so that should not be a problem in practice.
446
+
447
+ ## Appendix: Exporting stuff
448
+
449
+ Note that *browserify* will wrap your code with a function automatically, so you don't have to worry about leaking variables to the global scope (you should still remember to define variables with `var`, `let`, or `const`).
450
+
451
+ If you want to ***intentionally* expose** a variable, there are two ways to do that:
452
+
453
+ 1. Use the `window` object (only if you have to).
454
+ 2. Use *userjs* hooks (`mw.hook`).
455
+
456
+ Exposing things in `main.js` could look something like this:
126
457
  ```js
127
458
  var { MyGadget } = require("./MyGadget");
128
459
 
129
- // bot instance
460
+ // instance
130
461
  var gadget = new MyGadget();
131
462
 
463
+ // expose for external usage (*not* recommended)
464
+ window.yourGadgetName = gadget;
465
+
466
+ // hook when object is ready
467
+ mw.hook('userjs.yourGadgetName.loaded').fire(gadget);
468
+
132
469
  $(function(){
133
- gadget.init();
134
- })
470
+ // load Mediwiki core dependency
471
+ // (in this case util is for `mw.util.addPortletLink`)
472
+ mw.loader.using(["mediawiki.util"]).then( function() {
473
+ gadget.init();
474
+
475
+ // hook when initial elements are ready
476
+ mw.hook('userjs.yourGadgetName.ready').fire(gadget);
477
+ });
478
+ });
479
+ ```
480
+
481
+ As you can see, hooks are better because you can keep the name of the variable short. It's also much easier to make sure each dependency is loaded so other devs can use your hooks in other gadgets, and your users can customize the script.
482
+
483
+ User options:
484
+ ```js
485
+ mw.hook('userjs.yourGadgetName.loaded').add(function (gadget) {
486
+ gadget.options.createTool = false;
487
+ });
488
+ importScript('User:Nux/yourGadgetName.js');
489
+ ```
490
+ A more advanced customization:
491
+ ```js
492
+ mw.hook('userjs.yourGadgetName.ready').add(function (gadget) {
493
+ var $tool = $('#some-unique-gadget-tool a');
494
+ $tool.text($tool.text() + ' & plugin');
495
+ });
496
+ ```
497
+
498
+ ## Appendix: Using classes
499
+
500
+ JS has classes for a long time. They don't work in IE and you cannot use them in default gadgets on Wikipedia. If you are building a default gadget you might want to add [babeljs](https://babeljs.io/) as a build step.
501
+ ```bash
502
+ # install
503
+ npm install --save-dev babelify @babel/core
504
+ # build
505
+ browserify script.js -t babelify --outfile bundle.js
506
+ ```
507
+
508
+ If the gadget is intended for advanced users it is safe to assume they won't use IE. So for most scripts you can probably skip babelify. But as of 2023 you will need `requiresES6` option in the gadget definition.
509
+
510
+ ```
511
+ yourClassyGadgetName [ResourceLoader | requiresES6 | dependencies = mediawiki.util] | yourGadgetName.js | yourGadgetName.css
512
+ ```
513
+
514
+
515
+ Example `MyGadget.js` with a link in the toolbar:
516
+ ```js
517
+ /**
518
+ * Wikiploy gadget example.
519
+ *
520
+ * History and docs:
521
+ * https://github.com/Eccenux/wikiploy-rollout-example
522
+ *
523
+ * Deployed using: [[Wikipedia:Wikiploy]]
524
+ */
525
+ class MyGadget {
526
+ constructor() {
527
+ this.options = {
528
+ createTool: true,
529
+ };
530
+ }
531
+
532
+ /** Initialize things when DOM is ready. */
533
+ init() {
534
+ // Example link in the tools sidebar
535
+ if (this.options.createTool) {
536
+ var portletId = mw.config.get('skin') === 'timeless' ? 'p-pagemisc' : 'p-tb';
537
+ var linkLabel = 'My gadget dialog';
538
+ var itemId = 'some-unique-gadget-tool';
539
+ var item = mw.util.addPortletLink(portletId, '#', linkLabel, itemId);
540
+ $(item).on('click', (evt) => {
541
+ evt.preventDefault();
542
+ this.openDialog();
543
+ });
544
+ }
545
+ }
546
+
547
+ /** Open some dialog. */
548
+ openDialog() {
549
+ // Open a dialog window here
550
+ }
551
+ }
552
+
553
+ module.exports = { MyGadget };
554
+ ```
555
+
556
+ This MyGadget class will work with the `main.js` example from the section above.
557
+
558
+ ## Appendix: Unit testing
559
+
560
+ Unit testing is important for the stability of tools. Not everything needs to be unit tested, but if you perform any kind of parsing or other complicated tasks, it is a good habit to add automatic tests.
561
+
562
+ There are many testing frameworks, but I mostly use Mocha/Chai. This is mainly because the [Chai assert API](https://www.chaijs.com/api/assert/) is very functional.
563
+
564
+ Below is an example test of `imdb.redir()` function. The test file `test/imdb.test.js`:
565
+ ```js
566
+ /* global require, describe, it */
567
+ const { assert } = require('chai');
568
+ const imdb = require('../src/imdb');
569
+
570
+ describe('imdb', function () {
571
+ describe('imdb redir', function () {
572
+ // test function specific to *imdb redir*
573
+ function test(text, expected) {
574
+ // wrap
575
+ let result = imdb.redir(text);
576
+ if (result !== expected) {
577
+ console.log({text, result, expected});
578
+ }
579
+ assert.equal(result, expected);
580
+ }
581
+ // actual test
582
+ it('should resolve redirs', function () {
583
+ test(`[[IMDb.com]]`, `[[IMDb]]`);
584
+ test(`[[IMDb.com|abc]]`, `[[IMDb|abc]]`);
585
+ });
586
+ });
587
+ });
588
+ ```
589
+ You don't have to define a `test` function, but having a function like that can help test many different cases quickly.
590
+
591
+ Visual Studio Code will let you run or even debug each `it` function separately, thanks to the *Vscode Test Explorer* extension.
592
+
593
+ ## Appendix: Wiki2git
594
+
595
+ So now that we have everthing setup we need code right? If you already have a gadget you might to import it from Wikipedia.
596
+
597
+ ```bash
598
+ # install
599
+ npm i -g wiki-to-git
600
+
601
+ # get metadata and insert commits to `src/NavFrame.js`
602
+ wiki2git-load --site pl.wikipedia.org -p "MediaWiki:Gadget-NavFrame.js"
603
+ wiki2git-commit --site pl.wikipedia.org --repo "gadget-NavFrame" -o "src/NavFrame.js"
604
+
605
+ # get metadata and insert commits to `src/NavFrame.css`
606
+ wiki2git-load --site pl.wikipedia.org -p "MediaWiki:Gadget-NavFrame.css"
607
+ wiki2git-commit --site pl.wikipedia.org --repo "gadget-NavFrame" -o "src/NavFrame.css"
135
608
  ```
136
609
 
137
- Note that browserify will wrap your code with a function automatically. So you don't have to worry about leaking variables to global scope.
610
+ Note that in the example above `gadget-NavFrame` is a repository folder.
611
+ This can be a repo that already exists or something that you've already setup.
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  Wikiploy
2
2
  ==========================
3
3
 
4
- Wikiploy is a one-click solution to deploy JS and CSS to Wikipedia.
4
+ Wikiploy is a one-click solution to deploy JS and CSS to Wikipedia.
5
5
 
6
- After initial setup you can quickly build and deploy your user scripts and gadgets. Thought this was designed to work with Wikipedia you should be able to deploy to any [MediaWiki](https://www.mediawiki.org/) based wiki. You can even deploy to multiple websites with one-click (to whatever you have access to).
6
+ After the initial setup, you can quickly build and deploy your user scripts and gadgets. Though this was designed to work with Wikipedia, you should be able to deploy to any [MediaWiki](https://www.mediawiki.org/)-based wiki. You can even deploy to multiple websites with just one click on your commandbar. Your only limitation is your access level to the wikis.
7
7
 
8
8
  See also:
9
9
 
10
- - [README: building your project](README.building your project.md) recommendation on how to build JS and CSS for your gadgets.
10
+ - [README: building your project](https://github.com/Eccenux/Wikiploy/blob/main/README.building%20your%20project.md) recommendation on how to build JS and CSS for your gadgets (includes unit testing setup).
11
11
  - [Wikipedia:Wikiploy on pl.wiki](https://pl.wikipedia.org/wiki/Wikipedia:Wikiploy) for Polish description.
12
12
  - (more links on the bottom)
13
13
 
@@ -15,7 +15,14 @@ See also:
15
15
 
16
16
  ### nowiki (v1.7)
17
17
 
18
- Note! It is recommended that you use `nowiki: true` for all JS files. The `nowiki` property is a new option in `DeployConfig` since Wikiploy v1.7.
18
+ The `nowiki` property is a new option in `DeployConfig` since Wikiploy v1.7. It is now recommended to use `nowiki: true` for all JS files.
19
+ ```js
20
+ configs.push(new DeployConfig({
21
+ src: 'dist/test.js',
22
+ dst: '~/test.js',
23
+ nowiki: true,
24
+ }));
25
+ ```
19
26
 
20
27
  JavaScript page is still a wiki page... Kind of. It can be added to a category or link to other pages. To avoid this use the nowiki option.
21
28
 
@@ -23,7 +30,9 @@ Don't add this option to CSS though. It won't work correctly.
23
30
 
24
31
  ### userPrompt (v1.8)
25
32
 
26
- Prompt for summary so that you don't forget to change it. This is a bit more tricky to setup, but can still work as a one-click build (see [README: building your project](README.building your project.md)).
33
+ Use the `userPrompt` helper function to prompt for a summary in your Wikiploy script. This is only a helper. You can still set up a static summary, but a prompt helps to ensure you don't forget to change the summary.
34
+
35
+ Note that when using `userPrompt` you have to use an interactive terminal. This might be a bit more tricky to set up but can still function as a one-click build from a commandbar (see [README: building your project](https://github.com/Eccenux/Wikiploy/blob/main/README.building%20your%20project.md)).
27
36
 
28
37
  ## Wikiploy types
29
38
 
@@ -43,7 +52,7 @@ The `WikiployLite` class is using a bot API to deploy scripts. You can use stand
43
52
  Botpass configuration:
44
53
  * Setup on e.g.: https://test.wikipedia.org/wiki/Special:BotPasswords
45
54
  * Rights you should setup (if you can): `assets\Bot passwords - Test Wikipedia.png`.
46
- * Example config file in: `assets\bot.config.public.js`.
55
+ * Example config file in: `assets\public--bot.config.mjs`.
47
56
 
48
57
  **Warning!** Never, ever publish your bot password. If you do spill your password, reset/remove the password ASAP (on Special:BotPasswords).
49
58
 
package/assets/test.css CHANGED
@@ -5,4 +5,4 @@
5
5
  .tavern {
6
6
  display: block;
7
7
  }
8
- /* puppeteer 21.6.1 xor mwn 2.0.2 */
8
+ /* puppeteer 21.7.0 xor mwn 2.0.2 */
package/assets/test.js CHANGED
@@ -7,4 +7,4 @@
7
7
  */
8
8
  // test.js
9
9
  console.log('test');
10
- /* puppeteer 21.6.1 xor mwn 2.0.2 */
10
+ /* puppeteer 21.7.0 xor mwn 2.0.2 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wikiploy",
3
- "version": "1.8.0",
3
+ "version": "1.8.2",
4
4
  "description": "User scripts and gadgets deployment for MediaWiki (Wikipedia).",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -27,7 +27,7 @@
27
27
  "homepage": "https://github.com/Eccenux/Wikiploy#readme",
28
28
  "dependencies": {
29
29
  "mwn": "2.0.x",
30
- "puppeteer": "21.6.x"
30
+ "puppeteer": "21.7.x"
31
31
  },
32
32
  "devDependencies": {
33
33
  "bump-version": "0.5.0",
@@ -7,7 +7,7 @@ import * as ver from './version.js';
7
7
 
8
8
  // https://test.wikipedia.org/wiki/Special:BotPasswords
9
9
  // Note that username should contain `@`.
10
- import * as botpass from './bot.config.js';
10
+ import * as botpass from './bot.config.mjs';
11
11
 
12
12
  const version = await ver.readVersion('./package.json');
13
13
 
@@ -3,7 +3,7 @@ import WikiployLite from './WikiployLite.js';
3
3
 
4
4
  // https://test.wikipedia.org/wiki/Special:BotPasswords
5
5
  // Note that username should contain `@`.
6
- import * as botpass from './bot.config.js';
6
+ import * as botpass from './bot.config.mjs';
7
7
 
8
8
  const ployBot = new WikiployLite(botpass);
9
9
  // mock