@maiyunnet/kebab 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 (114) hide show
  1. package/.VSCodeCounter/2025-02-14_14-46-44/details.md +82 -0
  2. package/.VSCodeCounter/2025-02-14_14-46-44/diff-details.md +15 -0
  3. package/.VSCodeCounter/2025-02-14_14-46-44/diff.csv +2 -0
  4. package/.VSCodeCounter/2025-02-14_14-46-44/diff.md +19 -0
  5. package/.VSCodeCounter/2025-02-14_14-46-44/diff.txt +22 -0
  6. package/.VSCodeCounter/2025-02-14_14-46-44/results.csv +69 -0
  7. package/.VSCodeCounter/2025-02-14_14-46-44/results.json +1 -0
  8. package/.VSCodeCounter/2025-02-14_14-46-44/results.md +48 -0
  9. package/.VSCodeCounter/2025-02-14_14-46-44/results.txt +118 -0
  10. package/.vscode/tasks.json +15 -0
  11. package/LICENSE +201 -0
  12. package/README.md +201 -0
  13. package/bin/kebab.js +2 -0
  14. package/eslint.config.js +22 -0
  15. package/index.js +19 -0
  16. package/index.ts +33 -0
  17. package/lib/buffer.js +108 -0
  18. package/lib/buffer.ts +152 -0
  19. package/lib/captcha/zcool-addict-italic.ttf +0 -0
  20. package/lib/captcha.js +71 -0
  21. package/lib/captcha.ts +63 -0
  22. package/lib/consistent.js +171 -0
  23. package/lib/consistent.ts +219 -0
  24. package/lib/core.js +663 -0
  25. package/lib/core.ts +880 -0
  26. package/lib/crypto.js +256 -0
  27. package/lib/crypto.ts +384 -0
  28. package/lib/db.js +521 -0
  29. package/lib/db.ts +719 -0
  30. package/lib/dns.js +321 -0
  31. package/lib/dns.ts +405 -0
  32. package/lib/fs.js +405 -0
  33. package/lib/fs.ts +527 -0
  34. package/lib/jwt.js +223 -0
  35. package/lib/jwt.ts +276 -0
  36. package/lib/kv.js +1004 -0
  37. package/lib/kv.ts +1489 -0
  38. package/lib/lan.js +99 -0
  39. package/lib/lan.ts +87 -0
  40. package/lib/net/cacert.pem +3480 -0
  41. package/lib/net/formdata.js +137 -0
  42. package/lib/net/formdata.ts +166 -0
  43. package/lib/net/request.js +102 -0
  44. package/lib/net/request.ts +150 -0
  45. package/lib/net/response.js +28 -0
  46. package/lib/net/response.ts +59 -0
  47. package/lib/net.js +462 -0
  48. package/lib/net.ts +662 -0
  49. package/lib/s3.js +180 -0
  50. package/lib/s3.ts +235 -0
  51. package/lib/scan.js +276 -0
  52. package/lib/scan.ts +364 -0
  53. package/lib/session.js +177 -0
  54. package/lib/session.ts +230 -0
  55. package/lib/sql.js +818 -0
  56. package/lib/sql.ts +1151 -0
  57. package/lib/ssh/sftp.js +373 -0
  58. package/lib/ssh/sftp.ts +508 -0
  59. package/lib/ssh/shell.js +109 -0
  60. package/lib/ssh/shell.ts +123 -0
  61. package/lib/ssh.js +171 -0
  62. package/lib/ssh.ts +191 -0
  63. package/lib/text/tld.json +1 -0
  64. package/lib/text.js +452 -0
  65. package/lib/text.ts +607 -0
  66. package/lib/time.js +216 -0
  67. package/lib/time.ts +254 -0
  68. package/lib/ws.js +373 -0
  69. package/lib/ws.ts +523 -0
  70. package/lib/zip.js +381 -0
  71. package/lib/zip.ts +447 -0
  72. package/lib/zlib.js +289 -0
  73. package/lib/zlib.ts +350 -0
  74. package/main.js +51 -0
  75. package/main.ts +27 -0
  76. package/package.json +37 -0
  77. package/sys/child.js +585 -0
  78. package/sys/child.ts +678 -0
  79. package/sys/cmd.js +226 -0
  80. package/sys/cmd.ts +225 -0
  81. package/sys/ctr.js +608 -0
  82. package/sys/ctr.ts +904 -0
  83. package/sys/master.js +314 -0
  84. package/sys/master.ts +355 -0
  85. package/sys/mod.js +1273 -0
  86. package/sys/mod.ts +1871 -0
  87. package/sys/route.js +922 -0
  88. package/sys/route.ts +1113 -0
  89. package/types/index.d.ts +283 -0
  90. package/www/example/ctr/main.js +42 -0
  91. package/www/example/ctr/main.ts +9 -0
  92. package/www/example/ctr/middle.js +57 -0
  93. package/www/example/ctr/middle.ts +26 -0
  94. package/www/example/ctr/test.js +2818 -0
  95. package/www/example/ctr/test.ts +3218 -0
  96. package/www/example/data/locale/en.test.json +8 -0
  97. package/www/example/data/locale/index.html +1 -0
  98. package/www/example/data/locale/ja.test.json +8 -0
  99. package/www/example/data/locale/sc.test.json +8 -0
  100. package/www/example/data/locale/tc.test.json +8 -0
  101. package/www/example/data/test.zip +0 -0
  102. package/www/example/kebab.json +24 -0
  103. package/www/example/mod/test.js +49 -0
  104. package/www/example/mod/test.ts +47 -0
  105. package/www/example/mod/testdata.js +11 -0
  106. package/www/example/mod/testdata.ts +30 -0
  107. package/www/example/route.json +6 -0
  108. package/www/example/view/test.ejs +11 -0
  109. package/www/example/ws/mproxy.js +49 -0
  110. package/www/example/ws/mproxy.ts +16 -0
  111. package/www/example/ws/rproxy.js +47 -0
  112. package/www/example/ws/rproxy.ts +14 -0
  113. package/www/example/ws/test.js +68 -0
  114. package/www/example/ws/test.ts +36 -0
@@ -0,0 +1,2818 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const lCore = __importStar(require("~/lib/core"));
40
+ const lNet = __importStar(require("~/lib/net"));
41
+ const lDb = __importStar(require("~/lib/db"));
42
+ const lFs = __importStar(require("~/lib/fs"));
43
+ const lText = __importStar(require("~/lib/text"));
44
+ const lCrypto = __importStar(require("~/lib/crypto"));
45
+ const lKv = __importStar(require("~/lib/kv"));
46
+ const lCaptcha = __importStar(require("~/lib/captcha"));
47
+ const lTime = __importStar(require("~/lib/time"));
48
+ const lScan = __importStar(require("~/lib/scan"));
49
+ const lSql = __importStar(require("~/lib/sql"));
50
+ const lConsistent = __importStar(require("~/lib/consistent"));
51
+ const lSsh = __importStar(require("~/lib/ssh"));
52
+ const lJwt = __importStar(require("~/lib/jwt"));
53
+ const lWs = __importStar(require("~/lib/ws"));
54
+ const lS3 = __importStar(require("~/lib/s3"));
55
+ const lZip = __importStar(require("~/lib/zip"));
56
+ const lBuffer = __importStar(require("~/lib/buffer"));
57
+ const lLan = __importStar(require("~/lib/lan"));
58
+ const sCtr = __importStar(require("~/sys/ctr"));
59
+ const kebab = __importStar(require("~/index"));
60
+ const test_1 = __importDefault(require("../mod/test"));
61
+ const testdata_1 = __importDefault(require("../mod/testdata"));
62
+ class default_1 extends sCtr.Ctr {
63
+ constructor() {
64
+ super(...arguments);
65
+ this._internalUrl = '';
66
+ }
67
+ onLoad() {
68
+ if (this._config.const.hostname !== '127.0.0.1' && this._config.const.hostname !== '172.17.0.1' &&
69
+ this._config.const.hostname !== 'localhost' && this._config.const.hostname !== 'local-test.brc-app.com' &&
70
+ !this._config.const.hostname.startsWith('192.168.')) {
71
+ return [0, 'Please use 127.0.0.1 or local to access the file (' + this._config.const.host + ').'];
72
+ }
73
+ const realIp = lCore.realIP(this);
74
+ if ((this._config.const.hostname === '127.0.0.1' || this._config.const.hostname === 'localhost') &&
75
+ (realIp === '172.17.0.1')) {
76
+ this._internalUrl = 'http' + (this._config.const.https ? 's' : '') + '://' + realIp + this._config.const.urlBase;
77
+ }
78
+ else {
79
+ this._internalUrl = this._config.const.urlFull;
80
+ }
81
+ return true;
82
+ }
83
+ onUnload(rtn) {
84
+ if (!Array.isArray(rtn)) {
85
+ return rtn;
86
+ }
87
+ if (rtn[0] !== -102) {
88
+ return rtn;
89
+ }
90
+ rtn.push({
91
+ 'test': 'unload'
92
+ });
93
+ return rtn;
94
+ }
95
+ notfound() {
96
+ this._httpCode = 404;
97
+ return 'Custom 404 page.';
98
+ }
99
+ index() {
100
+ const echo = [
101
+ 'Hello world! Welcome to use <strong>Kebab ' + kebab.VER + '</strong>!',
102
+ '<br><br>Node Version: ' + process.version,
103
+ '<br>HOST: ' + this._config.const.host,
104
+ '<br>HOSTNAME: ' + this._config.const.hostname,
105
+ '<br>HOSTPORT: ' + this._config.const.hostport.toString(),
106
+ '<br>PATH: ' + this._config.const.path,
107
+ '<br>QS: ' + this._config.const.qs,
108
+ '<br>HTTPS: ' + (this._config.const.https ? 'true' : 'false'),
109
+ '<br><br>MOBILE: ' + (this._config.const.mobile ? 'true' : 'false'),
110
+ '<br>Real IP: ' + lCore.ip(this),
111
+ '<br>Client IP: ' + lCore.realIP(this),
112
+ '<br><br>URL_BASE: ' + this._config.const.urlBase,
113
+ '<br>URL_STC: ' + this._config.const.urlStc,
114
+ '<br>URL_FULL: ' + this._config.const.urlFull,
115
+ '<br>STATIC_PATH: ' + this._config.set.staticPath,
116
+ '<br>STATIC_PATH_FULL: ' + this._config.set.staticPathFull,
117
+ '<br>_internalUrl: ' + this._internalUrl,
118
+ '<br><br>headers: ' + lText.htmlescape(JSON.stringify(this._headers)),
119
+ '<br><br><b style="color: red;">Tips: The file can be deleted.</b>',
120
+ '<br><br><b>Route (route.json):</b>',
121
+ `<br><br><a href="${this._config.const.urlBase}article/123">View "article/123"</a>`,
122
+ `<br><a href="${this._config.const.urlBase}article/456">View "article/456"</a>`,
123
+ '<br><br><b>Query string:</b>',
124
+ `<br><br><a href="${this._config.const.urlBase}test/qs?a=1&b=2">View "test/qs?a=1&b=2"</a>`,
125
+ '<br><br><b>View:</b>',
126
+ `<br><br><a href="${this._config.const.urlBase}test/view">View "test/view"</a>`,
127
+ '<br><br><b>Return json:</b>',
128
+ `<br><br><a href="${this._config.const.urlBase}test/json?type=1">View "test/json?type=1"</a>`,
129
+ `<br><a href="${this._config.const.urlBase}test/json?type=2">View "test/json?type=2"</a>`,
130
+ `<br><a href="${this._config.const.urlBase}test/json?type=3">View "test/json?type=3"</a>`,
131
+ `<br><a href="${this._config.const.urlBase}test/json?type=4">View "test/json?type=4"</a>`,
132
+ `<br><a href="${this._config.const.urlBase}test/json?type=5">View "test/json?type=5"</a>`,
133
+ `<br><a href="${this._config.const.urlBase}test/json?type=6">View "test/json?type=6"</a>`,
134
+ `<br><a href="${this._config.const.urlBase}test/json?type=7">View "test/json?type=7"</a>`,
135
+ `<br><a href="${this._config.const.urlBase}test/json?type=8">View "test/json?type=8"</a>`,
136
+ `<br><a href="${this._config.const.urlBase}test/json?type=9">View "test/json?type=9"</a>`,
137
+ '<br><br><b>Ctr:</b>',
138
+ `<br><br><a href="${this._config.const.urlBase}test/ctr-xsrf">View "test/ctr-xsrf"</a>`,
139
+ `<br><a href="${this._config.const.urlBase}test/ctr-checkinput">View "test/ctr-checkinput"</a>`,
140
+ `<br><a href="${this._config.const.urlBase}test/ctr-locale">View "test/ctr-locale"</a>`,
141
+ `<br><a href="${this._config.const.urlBase}test/ctr-cachettl">View "test/ctr-cachettl"</a>`,
142
+ `<br><a href="${this._config.const.urlBase}test/ctr-httpcode">View "test/ctr-httpcode"</a>`,
143
+ `<br><a href="${this._config.const.urlBase}test/ctr-cross">View "test/ctr-cross"</a>`,
144
+ `<br><a href="${this._config.const.urlBase}test/ctr-readable">View "test/ctr-readable"</a>`,
145
+ `<br><a href="${this._config.const.urlBase}test/ctr-asynctask">View "test/ctr-asynctask"</a>`,
146
+ `<br><a href="${this._config.const.urlBase}test/ctr-timeout">View "test/ctr-timeout"</a>`,
147
+ '<br><br><b>Middle:</b>',
148
+ `<br><br><a href="${this._config.const.urlBase}test/middle">View "test/middle"</a>`,
149
+ '<br><br><b>Model test:</b>',
150
+ '<br><br><b style="color: red;">In a production environment, please delete "mod/test.ts", "mod/testdata.ts" files.</b>',
151
+ `<br><a href="${this._config.const.urlBase}test/mod-test">Click to see an example of a Test model</a>`,
152
+ `<br><a href="${this._config.const.urlBase}test/mod-split">View "test/mod-split"</a>`,
153
+ '<br><br><b>Library test:</b>',
154
+ '<br><br><b>Captcha:</b>',
155
+ `<br><br><a href="${this._config.const.urlBase}test/captcha-fastbuild">View "test/captcha-fastbuild"</a>`,
156
+ `<br><a href="${this._config.const.urlBase}test/captcha-base64">View "test/captcha-base64"</a>`,
157
+ '<br><br><b>Core:</b>',
158
+ `<br><br><a href="${this._config.const.urlBase}test/core-random">View "test/core-random"</a>`,
159
+ `<br><a href="${this._config.const.urlBase}test/core-rand">View "test/core-rand"</a>`,
160
+ `<br><a href="${this._config.const.urlBase}test/core-convert62">View "test/core-convert62"</a>`,
161
+ `<br><a href="${this._config.const.urlBase}test/core-purify">View "test/core-purify"</a>`,
162
+ `<br><a href="${this._config.const.urlBase}test/core-checktype">View "test/core-checktype"</a>`,
163
+ `<br><a href="${this._config.const.urlBase}test/core-muid">View "test/core-muid"</a>`,
164
+ `<br><a href="${this._config.const.urlBase}test/core-getlog">View "test/core-getlog"</a>`,
165
+ `<br><a href="${this._config.const.urlBase}test/core-reload">View "test/core-reload"</a>`,
166
+ `<br><a href="${this._config.const.urlBase}test/core-restart">View "test/core-restart"</a>`,
167
+ `<br><a href="${this._config.const.urlBase}test/core-global">View "test/core-global"</a>`,
168
+ `<br><a href="${this._config.const.urlBase}test/core-updatecode">View "test/core-updatecode"</a>`,
169
+ '<br><br><b>Crypto:</b>',
170
+ `<br><br><a href="${this._config.const.urlBase}test/crypto">View "test/crypto"</a>`,
171
+ '<br><br><b>Db:</b>',
172
+ `<br><br><a href="${this._config.const.urlBase}test/db">View "test/db"</a>`,
173
+ '<br><br><b>Kv:</b>',
174
+ `<br><br><a href="${this._config.const.urlBase}test/kv">View "test/kv"</a>`,
175
+ '<br><br><b>Net:</b>',
176
+ `<br><br><a href="${this._config.const.urlBase}test/net">View "test/net"</a>`,
177
+ `<br><a href="${this._config.const.urlBase}test/net-pipe">View "test/net-pipe"</a>`,
178
+ `<br><a href="${this._config.const.urlBase}test/net-post">View "test/net-post"</a>`,
179
+ `<br><a href="${this._config.const.urlBase}test/net-post-string">View "test/net-post-string"</a>`,
180
+ `<br><a href="${this._config.const.urlBase}test/net-open">View "test/net-open"</a>`,
181
+ `<br><a href="${this._config.const.urlBase}test/net-form-test">View "test/net-form-test"</a>`,
182
+ `<br><a href="${this._config.const.urlBase}test/net-upload">View "test/net-upload"</a>`,
183
+ `<br><a href="${this._config.const.urlBase}test/net-cookie">View "test/net-cookie"</a>`,
184
+ `<br><a href="${this._config.const.urlBase}test/net-save">View "test/net-save"</a>`,
185
+ `<br><a href="${this._config.const.urlBase}test/net-follow">View "test/net-follow"</a>`,
186
+ `<br><a href="${this._config.const.urlBase}test/net-reuse">View "test/net-reuse"</a>`,
187
+ `<br><a href="${this._config.const.urlBase}test/net-error">View "test/net-error"</a>`,
188
+ `<br><a href="${this._config.const.urlBase}test/net-hosts">View "test/net-hosts"</a>`,
189
+ `<br><a href="${this._config.const.urlBase}test/net-rproxy/dist/core.js">View "test/net-rproxy/dist/core.js"</a> <a href="${this._config.const.urlBase}test/net-rproxy/package.json">View "package.json"</a>`,
190
+ `<br><a href="${this._config.const.urlBase}test/net-mproxy">View "test/net-mproxy"</a>`,
191
+ '<br><br><b>Scan:</b>',
192
+ `<br><br><a href="${this._config.const.urlBase}test/scan?s=db">View "test/scan?s=db"</a>`,
193
+ `<br><a href="${this._config.const.urlBase}test/scan?s=kv">View "test/scan?s=kv"</a>`,
194
+ '<br><br><b>Session:</b>',
195
+ `<br><br><a href="${this._config.const.urlBase}test/session?s=db">View "test/session?s=db"</a>`,
196
+ `<br><a href="${this._config.const.urlBase}test/session?s=kv">View "test/session?s=kv"</a>`,
197
+ `<br><a href="${this._config.const.urlBase}test/session?s=db&auth=1">View "test/session?s=db&auth=1" Header Authorization</a>`,
198
+ `<br><a href="${this._config.const.urlBase}test/session?s=kv&auth=1">View "test/session?s=kv&auth=1" Header Authorization</a>`,
199
+ '<br><br><b>Jwt:</b>',
200
+ `<br><br><a href="${this._config.const.urlBase}test/jwt">View "test/jwt"</a>`,
201
+ `<br><a href="${this._config.const.urlBase}test/jwt?type=kv">View "test/jwt?type=kv"</a>`,
202
+ `<br><a href="${this._config.const.urlBase}test/jwt?type=auth">View "test/jwt?type=auth" Header Authorization</a>`,
203
+ '<br><br><b>Sql:</b>',
204
+ `<br><br><a href="${this._config.const.urlBase}test/sql?type=insert">View "test/sql?type=insert"</a>`,
205
+ `<br><a href="${this._config.const.urlBase}test/sql?type=select">View "test/sql?type=select"</a>`,
206
+ `<br><a href="${this._config.const.urlBase}test/sql?type=update">View "test/sql?type=update"</a>`,
207
+ `<br><a href="${this._config.const.urlBase}test/sql?type=delete">View "test/sql?type=delete"</a>`,
208
+ `<br><a href="${this._config.const.urlBase}test/sql?type=where">View "test/sql?type=where"</a>`,
209
+ `<br><a href="${this._config.const.urlBase}test/sql?type=having">View "test/sql?type=having"</a>`,
210
+ `<br><a href="${this._config.const.urlBase}test/sql?type=by">View "test/sql?type=by"</a>`,
211
+ `<br><a href="${this._config.const.urlBase}test/sql?type=field">View "test/sql?type=field"</a>`,
212
+ '<br><br><b>Consistent:</b>',
213
+ `<br><br><a href="${this._config.const.urlBase}test/consistent-hash">View "test/consistent-hash"</a>`,
214
+ `<br><a href="${this._config.const.urlBase}test/consistent-distributed">View "test/consistent-distributed"</a>`,
215
+ `<br><a href="${this._config.const.urlBase}test/consistent-migration">View "test/consistent-migration"</a>`,
216
+ `<br><a href="${this._config.const.urlBase}test/consistent-fast">View "test/consistent-fast"</a>`,
217
+ '<br><br><b>Text:</b>',
218
+ `<br><br><a href="${this._config.const.urlBase}test/text">View "test/text"</a>`,
219
+ '<br><br><b>Time:</b>',
220
+ `<br><br><a href="${this._config.const.urlBase}test/time">View "test/time"</a>`,
221
+ '<br><br><b>Ws:</b>',
222
+ `<br><br><a href="${this._config.const.urlBase}test/ws-server">View "test/ws-server"</a>`,
223
+ `<br><a href="${this._config.const.urlBase}test/ws-server?ac=rproxy">View ws rproxy</a>`,
224
+ `<br><a href="${this._config.const.urlBase}test/ws-client">View "test/ws-client"</a>`,
225
+ `<br><a href="${this._config.const.urlBase}test/ws-client?ac=mproxy">View ws mproxy</a>`,
226
+ '<br><br><b>Ssh:</b>',
227
+ `<br><br><a href="${this._config.const.urlBase}test/ssh?type=shell">View "test/ssh?type=shell"</a>`,
228
+ `<br><a href="${this._config.const.urlBase}test/ssh?type=sftp">View "test/ssh?type=sftp"</a>`,
229
+ '<br><br><b>S3:</b>',
230
+ `<br><br><a href="${this._config.const.urlBase}test/s3">View "test/s3"</a>`,
231
+ '<br><br><b>Zip:</b>',
232
+ `<br><br><a href="${this._config.const.urlBase}test/zip">View "test/zip"</a>`,
233
+ '<br><br><b>Buffer:</b>',
234
+ `<br><br><a href="${this._config.const.urlBase}test/buffer">View "test/buffer"</a>`,
235
+ '<br><br><b>Lan:</b>',
236
+ `<br><br><a href="${this._config.const.urlBase}test/lan">View "test/lan"</a>`,
237
+ ];
238
+ echo.push('<br><br>' + this._getEnd());
239
+ return echo.join('');
240
+ }
241
+ article() {
242
+ return 'Article ID: ' + lText.htmlescape(this._param[0]) + '<br><br>' + this._getEnd();
243
+ }
244
+ qs() {
245
+ return 'JSON.stringify(this._get):<br><br>' + lText.htmlescape(JSON.stringify(this._get)) + '<br><br>' + this._getEnd();
246
+ }
247
+ view() {
248
+ return this._loadView('test', {
249
+ 'test': 'ok'
250
+ });
251
+ }
252
+ json() {
253
+ switch (this._get.type) {
254
+ case '1':
255
+ return [0];
256
+ case '2':
257
+ return [0, 'Error message.'];
258
+ case '3':
259
+ return [0, { 'line': '2' }];
260
+ case '4':
261
+ return [1, 'Successful!'];
262
+ case '5':
263
+ return [1, { 'list': [{ 'id': '0' }, { 'id': '1' }, { 'id': '2' }], 'total': '3' }];
264
+ case '6':
265
+ return { 'oh': 'yeah', 'sb': 'is me' };
266
+ case '7':
267
+ return [1, 'success', { 'list': [1, 2, 3] }];
268
+ case '8':
269
+ return [-101, 'Test middle onUnload'];
270
+ case '9':
271
+ return [-102, 'Test ctr onUnload'];
272
+ default:
273
+ return [];
274
+ }
275
+ }
276
+ ctrXsrf() {
277
+ this._enabledXsrf();
278
+ return `XSRF-TOKEN: ${this._xsrf}<br><br>
279
+ <input type="button" value="Post with xsrf token" onclick="document.getElementById('result').innerText='Waiting...';fetch('${this._config.const.urlBase}test/ctr-xsrf1',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:'key=val&_xsrf=${this._xsrf}'}).then(function(r){return r.text();}).then(function(t){document.getElementById('result').innerText=t;});">
280
+ <input type='button' value="Post without xsrf token" style="margin-left: 10px;" onclick="document.getElementById('result').innerText='Waiting...';fetch('${this._config.const.urlBase}test/ctr-xsrf1',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:'key=val'}).then(function(r){return r.text();}).then(function(t){document.getElementById('result').innerText=t;});"><br><br>
281
+ Result:<pre id="result">Nothing.</pre>${this._getEnd()}`;
282
+ }
283
+ ctrXsrf1() {
284
+ const retur = [];
285
+ if (!this._checkXInput(this._post, {}, retur)) {
286
+ return retur;
287
+ }
288
+ return [1, { 'post': this._post }];
289
+ }
290
+ ctrCheckinput() {
291
+ const echo = [`rule:
292
+ <pre>{
293
+ 'he': ['require', [0, 'The he param does not exist.']],
294
+ 'num': ['> 10', [0, 'The num param must > 10.']],
295
+ 'num2': ['> 0', '<= 100', [0, 'The num2 param must > 0.']],
296
+ 'reg': ['/^[A-CX-Z5-7]+$/', [0, 'The reg param is incorrect.']],
297
+ 'arr': [['a', 'x', 'hehe'], [0, 'The arr param is incorrect.']],
298
+ 'type': [{ 'type': { 'a': 1, 'b': '' } }, [0, 'The reg param is incorrect']],
299
+ 'json': [{ 'type': { 'a': '1', 'b': [ { 'c': 1 } ] } }, [0, 'The type param is incorrect']],
300
+ }</pre>`];
301
+ const post = [
302
+ {},
303
+ {
304
+ 'he': 'ok'
305
+ },
306
+ {
307
+ 'he': 'ok',
308
+ 'num': '5'
309
+ },
310
+ {
311
+ 'he': 'ok',
312
+ 'num2': '0'
313
+ },
314
+ {
315
+ 'he': 'ok',
316
+ 'num': '12',
317
+ 'reg': 'Hello'
318
+ },
319
+ {
320
+ 'he': 'ok',
321
+ 'num': '12',
322
+ 'reg': 'BBB6YYY6',
323
+ 'arr': 'heihei'
324
+ },
325
+ {
326
+ 'he': 'ok',
327
+ 'num': '12',
328
+ 'reg': 'BBB6YYY6',
329
+ 'arr': 'hehe'
330
+ },
331
+ {
332
+ 'he': 'ok',
333
+ 'num': '12',
334
+ 'reg': 'BBB6YYY6',
335
+ 'arr': 'hehe',
336
+ 'type': { 'a': false, 'b': '1' }
337
+ },
338
+ {
339
+ 'he': 'ok',
340
+ 'num': '12',
341
+ 'reg': 'BBB6YYY6',
342
+ 'arr': 'hehe',
343
+ 'type': { 'a': 0, 'b': 'ok' }
344
+ },
345
+ {
346
+ 'he': 'ok',
347
+ 'num': '12',
348
+ 'reg': 'BBB6YYY6',
349
+ 'arr': 'hehe',
350
+ 'type': { 'a': 0, 'b': 'ok' },
351
+ 'json': { 'a': 'a', 'b': [] },
352
+ },
353
+ {
354
+ 'he': 'ok',
355
+ 'num': '12',
356
+ 'reg': 'BBB6YYY6',
357
+ 'arr': 'hehe',
358
+ 'type': { 'a': 0, 'b': 'ok' },
359
+ 'json': { 'a': 'a', 'b': [{ 'c': 'a' }] },
360
+ },
361
+ {
362
+ 'he': 'ok',
363
+ 'num': '12',
364
+ 'reg': 'BBB6YYY6',
365
+ 'arr': 'hehe',
366
+ 'type': { 'a': 0, 'b': 'ok' },
367
+ 'json': { 'a': 'a', 'b': [{ 'c': 1, 'd': 2 }] },
368
+ },
369
+ {
370
+ 'he': 'ok',
371
+ 'num': '12',
372
+ 'reg': 'BBB6YYY6',
373
+ 'arr': 'hehe',
374
+ 'type': { 'a': 0, 'b': 'ok' },
375
+ 'json': { 'a': 'a', 'b': [{ 'c': 1 }] },
376
+ }
377
+ ];
378
+ for (const item of post) {
379
+ if (item.type) {
380
+ item.type = JSON.stringify(item.type);
381
+ }
382
+ if (item.json) {
383
+ item.json = JSON.stringify(item.json);
384
+ }
385
+ echo.push(`<input type="button" value="Post '${lText.queryStringify(item, false).replace(/"/g, '&quot;')}'" onclick="post('${lText.queryStringify(item)}')"><br>`);
386
+ }
387
+ echo.push(`<input type="button" value="Post FormData (fd.append('he', 'ho'))" onclick="postFd()"><br>`);
388
+ echo.push(`<script>
389
+ function post(p) {
390
+ document.getElementById('result').innerText = 'Waiting...';
391
+ fetch('${this._config.const.urlBase}test/ctr-checkinput1', {
392
+ method: 'POST',
393
+ headers: {
394
+ 'Content-Type': 'application/x-www-form-urlencoded'
395
+ },
396
+ body: p
397
+ }).then(function(r) {
398
+ return r.text();
399
+ }).then(function(t) {
400
+ document.getElementById('result').innerText = t;
401
+ });
402
+ }
403
+
404
+ function postFd() {
405
+ var fd = new FormData();
406
+ fd.append('he', 'ho');
407
+ document.getElementById('result').innerText = 'Waiting...';
408
+ fetch('${this._config.const.urlBase}test/ctr-checkinput1', {
409
+ method: 'POST',
410
+ body: fd
411
+ }).then(function(r) {
412
+ return r.text();
413
+ }).then(function(t) {
414
+ document.getElementById('result').innerText = t;
415
+ });
416
+ }
417
+ </script>
418
+ <br>Result:<pre id="result">Nothing.</pre>`);
419
+ return echo.join('') + this._getEnd();
420
+ }
421
+ async ctrCheckinput1() {
422
+ if (!await this._handleFormData()) {
423
+ return [0];
424
+ }
425
+ const retur = [];
426
+ if (this._post['type']) {
427
+ this._post['type'] = lText.parseJson(this._post['type']);
428
+ }
429
+ if (this._post['json']) {
430
+ this._post['json'] = lText.parseJson(this._post['json']);
431
+ }
432
+ if (this._post['num2'] !== undefined) {
433
+ this._post['num2'] = parseFloat(this._post['num2']);
434
+ }
435
+ if (!this._checkInput(this._post, {
436
+ 'he': ['require', [0, 'The he param does not exist.']],
437
+ 'num': ['> 10', [0, 'The num param must > 10.']],
438
+ 'num2': ['> 0', '<= 100', [0, 'The num2 param must > 0.']],
439
+ 'reg': ['/^[A-CX-Z5-7]+$/', [0, 'The reg param is incorrect.']],
440
+ 'arr': [['a', 'x', 'hehe'], [0, 'The arr param is incorrect.']],
441
+ 'type': [{ 'type': { 'a': 1, 'b': '' } }, [0, 'The type param is incorrect']],
442
+ 'json': [{ 'type': { 'a': '1', 'b': [{ 'c': 1 }] } }, [0, 'The type param is incorrect']],
443
+ }, retur)) {
444
+ return retur;
445
+ }
446
+ return [1, { 'post': this._post }];
447
+ }
448
+ async ctrLocale() {
449
+ const rtn = [];
450
+ if (!this._checkInput(this._get, {
451
+ 'lang': [['en', 'sc', 'tc', 'ja'], [0, 'Wrong language.']]
452
+ }, rtn)) {
453
+ return rtn;
454
+ }
455
+ const echo = [
456
+ '<a href="' + this._config.const.urlBase + 'test/ctr-locale">English</a> | ' +
457
+ '<a href="' + this._config.const.urlBase + 'test/ctr-locale?lang=sc">简体中文</a> | ' +
458
+ '<a href="' + this._config.const.urlBase + 'test/ctr-locale?lang=tc">繁體中文</a> | ' +
459
+ '<a href="' + this._config.const.urlBase + 'test/ctr-locale?lang=ja">日本語</a> | ' +
460
+ '<a href="' + this._config.const.urlBase + 'test">Return</a>'
461
+ ];
462
+ const r = await this._loadLocale(this._get['lang'], 'test');
463
+ echo.push(`<pre>await this._loadLocale(this._get['lang'], 'test');</pre>${r ? 'true' : 'false'}`);
464
+ echo.push("<pre>l('hello')</pre>" + this._l('hello'));
465
+ echo.push("<pre>l('copy')</pre>" + this._l('copy'));
466
+ echo.push("<pre>l('test', ['a1', 'a2'])</pre>" + this._l('test', ['a1', 'a2']));
467
+ return echo.join('') + '<br><br>' + this._getEnd();
468
+ }
469
+ ctrCachettl() {
470
+ this._cacheTTL = 60;
471
+ return 'This page is cache ttl is 60s.';
472
+ }
473
+ ctrHttpcode() {
474
+ this._httpCode = 404;
475
+ return 'This page is a custom httpcode (404).';
476
+ }
477
+ ctrCross() {
478
+ return `<input type="button" value="Fetch localhost" onclick="document.getElementById('result').innerText='Waiting...';fetch('http://localhost:${this._config.const.hostport}${this._config.const.urlBase}test/ctr-cross1').then(function(r){return r.text();}).then(function(t){document.getElementById('result').innerText=t;}).catch(()=>{document.getElementById('result').innerText='Failed.';});">
479
+ <input type='button' value="Fetch localhost with cross" style="margin-left: 10px;" onclick="document.getElementById('result').innerText='Waiting...';fetch('http://localhost:${this._config.const.hostport}${this._config.const.urlBase}test/ctr-cross2').then(function(r){return r.text();}).then(function(t){document.getElementById('result').innerText=t;});">
480
+ <input type='button' value="Fetch local-test.brc-app.com with cross" style="margin-left: 10px;" onclick="document.getElementById('result').innerText='Waiting...';fetch('http://local-test.brc-app.com:${this._config.const.hostport}${this._config.const.urlBase}test/ctr-cross2').then(function(r){return r.text();}).then(function(t){document.getElementById('result').innerText=t;});"><br><br>
481
+ Result:<pre id="result">Nothing.</pre>` + this._getEnd();
482
+ }
483
+ ctrCross1() {
484
+ return [1, { 'value': 'done' }];
485
+ }
486
+ ctrCross2() {
487
+ if (!this._cross()) {
488
+ return [0];
489
+ }
490
+ return [1, { 'value': 'done' }];
491
+ }
492
+ ctrReadable() {
493
+ this._res.setHeader('content-type', 'text/plain; charset=utf-8');
494
+ return lFs.createReadStream(kebab.SYS_PATH + 'route.js');
495
+ }
496
+ ctrAsynctask() {
497
+ this._asyncTask(async () => {
498
+ lCore.debug('ASYNCTASK IN');
499
+ await lCore.sleep(1000);
500
+ lCore.debug('ASYNCTASK TIME1');
501
+ await lCore.sleep(1000);
502
+ lCore.debug('ASYNCTASK TIME2');
503
+ await lCore.sleep(1000);
504
+ lCore.debug('ASYNCTASK OVER');
505
+ });
506
+ return [1];
507
+ }
508
+ async ctrTimeout() {
509
+ this.timeout = 70_000;
510
+ const echo = ['1'];
511
+ await lCore.sleep(15_000);
512
+ echo.push('2');
513
+ await lCore.sleep(15_000);
514
+ echo.push('3');
515
+ await lCore.sleep(15_000);
516
+ echo.push('4');
517
+ await lCore.sleep(15_000);
518
+ echo.push('5');
519
+ return [1, echo];
520
+ }
521
+ async modTest() {
522
+ const retur = [];
523
+ if (!(this._checkInput(this._get, {
524
+ 'action': [['', 'remove'], [0, 'Error']]
525
+ }, retur))) {
526
+ return retur;
527
+ }
528
+ const echo = ['<b style="color: red;">In a production environment, please delete the "mod/test.ts" file.</b>'];
529
+ const db = lDb.get(this);
530
+ let stmt = await db.query('SELECT * FROM `m_test` WHERE `token` LIMIT 1;');
531
+ if (!stmt.rows) {
532
+ return [0, 'Failed("m_test" not found).'];
533
+ }
534
+ if (this._get['action'] === 'remove') {
535
+ await test_1.default.removeByWhere(db, [
536
+ ['token', 'LIKE', 'test_%']
537
+ ], {
538
+ 'pre': this
539
+ });
540
+ return this._location('test/mod-test');
541
+ }
542
+ else {
543
+ const time = lTime.stamp();
544
+ const test = test_1.default.getCreate(db, {
545
+ 'ctr': this
546
+ });
547
+ test.set({
548
+ 'point': { 'x': lCore.rand(0, 99), 'y': lCore.rand(0, 99) },
549
+ 'polygon': [
550
+ [
551
+ { 'x': 1, 'y': 1 },
552
+ { 'x': 2, 'y': 2 },
553
+ { 'x': 3, 'y': 3 },
554
+ { 'x': 1, 'y': 1 }
555
+ ]
556
+ ],
557
+ 'json': { 'x': { 'y': 'abc' } },
558
+ 'time_add': time
559
+ });
560
+ const result = await test.create();
561
+ echo.push(`<pre>const time = lTime.stamp();
562
+ const test = mTest.getCreate<mTest>(db, {
563
+ 'ctr': this
564
+ });
565
+ test.set({
566
+ 'point': { 'x': lCore.rand(0, 99), 'y': lCore.rand(0, 99) },
567
+ 'polygon': [
568
+ [
569
+ { 'x': 1, 'y': 1 },
570
+ { 'x': 2, 'y': 2 },
571
+ { 'x': 3, 'y': 3 },
572
+ { 'x': 1, 'y': 1 }
573
+ ]
574
+ ],
575
+ 'json': { 'x': { 'y': 'abc' } },
576
+ 'time_add': time
577
+ });
578
+ const result = await test.create();
579
+ JSON.stringify(result));</pre>` + JSON.stringify(result));
580
+ echo.push('<pre>JSON.stringify(test.toArray());</pre>' + lText.htmlescape(JSON.stringify(test.toArray())));
581
+ echo.push('<br><br>Test table:');
582
+ stmt = await db.query('SELECT * FROM `m_test` WHERE `token` LIKE \'test_%\' ORDER BY `id` ASC;');
583
+ this._dbTable(stmt, echo);
584
+ const ls = test_1.default.where(db, [
585
+ ['time_add', '>', time - 60 * 5]
586
+ ], {
587
+ 'ctr': this
588
+ });
589
+ const r = await ls.explain();
590
+ echo.push(`<pre>const ls = mTest.where<mTest>(db, [
591
+ ['time_add', '>', time - 60 * 5]
592
+ ], {
593
+ 'ctr': this
594
+ });
595
+ const r = await ls.explain();</pre>` + lText.htmlescape(JSON.stringify(r)));
596
+ const r2 = await ls.explain(true);
597
+ echo.push('<pre>ls->explain(true);</pre>');
598
+ if (r2) {
599
+ echo.push('<table style="width: 100%;">');
600
+ for (const k in r2) {
601
+ const v = r2[k];
602
+ echo.push('<tr><th>' + lText.htmlescape(k) + '</th><td>' + (v === null ? 'null' : lText.htmlescape((typeof v === 'string' || typeof v === 'number') ? v.toString() : '[object]')) + '</td></tr>');
603
+ }
604
+ echo.push('</table>');
605
+ }
606
+ else {
607
+ echo.push('<div>false</div>');
608
+ }
609
+ let ft = await test_1.default.one(db, [
610
+ ['time_add', '>', '0']
611
+ ], {
612
+ 'ctr': this
613
+ });
614
+ echo.push(`<pre>await mTest.one<mTest>(db, [
615
+ ['time_add', '>', '0']
616
+ ], {
617
+ 'ctr': this
618
+ });</pre>`);
619
+ if (ft) {
620
+ echo.push('<table style="width: 100%;">');
621
+ echo.push('<tr><th>id</th><td>' + ft.id.toString() + '</td></tr>');
622
+ echo.push('<tr><th>token</th><td>' + ft.token + '</td></tr>');
623
+ echo.push('<tr><th>point</th><td>' + JSON.stringify(ft.point) + '</td></tr>');
624
+ echo.push('<tr><th>polygon</th><td>' + JSON.stringify(ft.polygon) + '</td></tr>');
625
+ echo.push('<tr><th>json</th><td>' + JSON.stringify(ft.json) + '</td></tr>');
626
+ echo.push('<tr><th>time_add</th><td>' + ft.time_add.toString() + '</td></tr>');
627
+ echo.push('</table>');
628
+ ft.set('point', {
629
+ 'x': 20,
630
+ 'y': 20
631
+ });
632
+ await ft.save();
633
+ echo.push(`<pre>ft.set('point', {
634
+ 'x': 20,
635
+ 'y': 20
636
+ });
637
+ await ft.save();</pre>`);
638
+ ft = await test_1.default.find(db, ft.id, {
639
+ 'ctr': this
640
+ });
641
+ if (!ft) {
642
+ return '';
643
+ }
644
+ echo.push('<table style="width: 100%;">');
645
+ echo.push('<tr><th>id</th><td>' + ft.id.toString() + '</td></tr>');
646
+ echo.push('<tr><th>token</th><td>' + ft.token + '</td></tr>');
647
+ echo.push('<tr><th>point</th><td>' + JSON.stringify(ft.point) + '</td></tr>');
648
+ echo.push('<tr><th>polygon</th><td>' + JSON.stringify(ft.polygon) + '</td></tr>');
649
+ echo.push('<tr><th>json</th><td>' + JSON.stringify(ft.json) + '</td></tr>');
650
+ echo.push('<tr><th>time_add</th><td>' + ft.time_add.toString() + '</td></tr>');
651
+ echo.push('</table>');
652
+ ft.set({
653
+ 'point': {
654
+ 'x': 40,
655
+ 'y': 40
656
+ },
657
+ 'polygon': [
658
+ [
659
+ { 'x': 5, 'y': 1 },
660
+ { 'x': 6, 'y': 2 },
661
+ { 'x': 7, 'y': 3 },
662
+ { 'x': 5, 'y': 1 }
663
+ ]
664
+ ],
665
+ 'json': { 'x': { 'y': 'def' } }
666
+ });
667
+ await ft.save();
668
+ await ft.refresh();
669
+ echo.push(`<pre>ft.set({
670
+ 'point': {
671
+ 'x': 40,
672
+ 'y': 40
673
+ },
674
+ 'polygon': [
675
+ [
676
+ { 'x': 5, 'y': 1 },
677
+ { 'x': 6, 'y': 2 },
678
+ { 'x': 7, 'y': 3 },
679
+ { 'x': 5, 'y': 1 }
680
+ ]
681
+ ],
682
+ 'json': { 'x': { 'y': 'def' } }
683
+ });
684
+ await ft.save();
685
+ await ft.refresh();</pre>`);
686
+ echo.push('<table style="width: 100%;">');
687
+ echo.push('<tr><th>id</th><td>' + ft.id.toString() + '</td></tr>');
688
+ echo.push('<tr><th>token</th><td>' + ft.token + '</td></tr>');
689
+ echo.push('<tr><th>point</th><td>' + JSON.stringify(ft.point) + '</td></tr>');
690
+ echo.push('<tr><th>polygon</th><td>' + JSON.stringify(ft.polygon) + '</td></tr>');
691
+ echo.push('<tr><th>json</th><td>' + JSON.stringify(ft.json) + '</td></tr>');
692
+ echo.push('<tr><th>time_add</th><td>' + ft.time_add.toString() + '</td></tr>');
693
+ echo.push('</table>');
694
+ }
695
+ else {
696
+ echo.push('<div>false</div>');
697
+ }
698
+ echo.push('<br><a href="' + this._config.const.urlBase + 'test/mod-test?action=remove">Remove all test data</a> | <a href="' + this._config.const.urlBase + 'test">Return</a>');
699
+ return echo.join('') + '<br><br>' + this._getEnd();
700
+ }
701
+ }
702
+ async modSplit() {
703
+ const echo = ['<b style="color: red;">In a production environment, please delete "mod/test.php" and "mod/testdata.php" files.</b>'];
704
+ const db = lDb.get(this);
705
+ echo.push(`<br><br>Test SQL:<pre>CREATE TABLE \`m_test\` (
706
+ \`id\` INT NOT NULL AUTO_INCREMENT,
707
+ \`token\` CHAR(16) NOT NULL COLLATE 'ascii_bin',
708
+ \`point\` POINT NOT NULL,
709
+ \`time_add\` BIGINT NOT NULL,
710
+ PRIMARY KEY (\`id\`) USING BTREE,
711
+ UNIQUE INDEX \`token\` (\`token\`) USING BTREE,
712
+ INDEX \`time_add\` (\`time_add\`) USING BTREE
713
+ ) ENGINE=InnoDB COLLATE=utf8mb4_general_ci;
714
+ CREATE TABLE \`m_test_data_0\` (
715
+ \`id\` bigint NOT NULL AUTO_INCREMENT,
716
+ \`test_id\` bigint NOT NULL,
717
+ \`content\` varchar(128) COLLATE ascii_bin NOT NULL,
718
+ \`time_add\` bigint NOT NULL,
719
+ PRIMARY KEY (\`id\`)
720
+ ) ENGINE=InnoDB DEFAULT CHARSET=ascii COLLATE=ascii_bin;</pre>m_test_data_0 - m_test_data_4<br><br>`);
721
+ echo.push(`<input type="button" value="Create user" onclick="this.value='Waiting...';fetch('${this._config.const.urlBase}test/mod-split1',{method:'GET',headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then(function(r){window.location.href=window.location.href})">
722
+ <input type="button" value="Random post" onclick="this.value='Waiting...';fetch('${this._config.const.urlBase}test/mod-split2',{method:'GET',headers:{'Content-Type':'application/x-www-form-urlencoded'}}).then(function(r){return r.json()}).then(function(j){alert('TESTID:'+j.id+'\\nTABLEINDEX:'+j.index);window.location.href=window.location.href})">`);
723
+ let stmt = await db.query('SELECT * FROM `m_test` ORDER BY `id` DESC LIMIT 0, 20;');
724
+ echo.push('<br><br><b>m_test</b> table:');
725
+ this._dbTable(stmt, echo);
726
+ for (let i = 0; i < 5; ++i) {
727
+ stmt = await db.query('SELECT * FROM `m_test_data_' + i.toString() + '` ORDER BY `id` DESC LIMIT 0, 20;');
728
+ echo.push('<br><b>m_test_data_' + i.toString() + '</b> table:');
729
+ this._dbTable(stmt, echo);
730
+ }
731
+ return echo.join('') + '<br>' + this._getEnd();
732
+ }
733
+ async modSplit1() {
734
+ const db = lDb.get(this);
735
+ const test = test_1.default.getCreate(db, {
736
+ 'ctr': this
737
+ });
738
+ test.set({
739
+ 'token': lCore.random(lCore.rand(8, 32)),
740
+ 'point': {
741
+ 'x': 10,
742
+ 'y': 10
743
+ },
744
+ 'time_add': lTime.stamp()
745
+ });
746
+ await test.create();
747
+ }
748
+ async modSplit2() {
749
+ const db = lDb.get(this);
750
+ const ids = [];
751
+ const ls = await test_1.default.select(db, ['id'], {
752
+ 'ctr': this
753
+ }).by('time_add').limit(0, 50).all();
754
+ if (ls) {
755
+ for (const item of ls) {
756
+ if (!item.id) {
757
+ continue;
758
+ }
759
+ ids.push(item.id);
760
+ }
761
+ }
762
+ if (ids.length === 0) {
763
+ return [0, 'The "test" table not found.'];
764
+ }
765
+ const id = ids[lCore.rand(0, ids.length - 1)];
766
+ const index = lConsistent.fast(id.toString(), ['0', '1', '2', '3', '4']);
767
+ const testData = testdata_1.default.getCreate(db, {
768
+ 'ctr': this,
769
+ 'index': index ?? ''
770
+ });
771
+ testData.set({
772
+ 'test_id': id,
773
+ 'content': lCore.random(lCore.rand(8, 32)),
774
+ 'time_add': lTime.stamp()
775
+ });
776
+ await testData.create();
777
+ return [1, { 'id': id, 'index': index }];
778
+ }
779
+ captchaFastbuild() {
780
+ return lCaptcha.get(400, 100).getBuffer();
781
+ }
782
+ captchaBase64() {
783
+ const echo = [`<pre>const cap = lCaptcha.get(400, 100);
784
+ const phrase = cap.getPhrase();
785
+ const base64 = cap.getBase64();</pre>phrase:`];
786
+ const cap = lCaptcha.get(400, 100);
787
+ const phrase = cap.getPhrase();
788
+ const base64 = cap.getBase64();
789
+ echo.push('<pre>' + phrase + '</pre>');
790
+ echo.push('base64:');
791
+ echo.push('<pre style="white-space: pre-wrap; word-wrap: break-word; overflow-y: auto; max-height: 200px;">' + base64 + '</pre>');
792
+ echo.push('&lt;img src="&lt;?php echo $base64 ?&gt;" style="width: 200px; height: 50px;"&gt;');
793
+ echo.push('<pre><img alt="captcha" src="' + base64 + '" style="width: 200px; height: 50px;"></pre>');
794
+ return echo.join('') + this._getEnd();
795
+ }
796
+ coreRandom() {
797
+ return '<pre>lCore.random(16, lCore.RANDOM_LUNS);</pre>' + lText.htmlescape(lCore.random(16, lCore.RANDOM_LUNS)) +
798
+ '<pre>lCore.random(4, lCore.RANDOM_V);</pre>' + lText.htmlescape(lCore.random(4, lCore.RANDOM_V)) +
799
+ '<pre>lCore.random(8, lCore.RANDOM_N, \'0349\');</pre>' + lText.htmlescape(lCore.random(8, lCore.RANDOM_N, '0349')) +
800
+ '<pre>lCore.random(8, lCore.RANDOM_LNU);</pre>' + lText.htmlescape(lCore.random(8, lCore.RANDOM_LUN)) +
801
+ '<pre>lCore.random(16, lCore.RANDOM_LNU);</pre>' + lText.htmlescape(lCore.random(16, lCore.RANDOM_LUN)) +
802
+ '<br><br>' + this._getEnd();
803
+ }
804
+ coreRand() {
805
+ return '<pre>lCore.rand(1.2, 7.1, 1);</pre>' + lCore.rand(1.2, 7.1, 1).toString() +
806
+ '<pre>lCore.rand(1.2, 7.1, 5);</pre>' + lCore.rand(1.2, 7.1, 5).toString() +
807
+ '<pre>lCore.rand(1.298, 7.1891, 2);</pre>' + lCore.rand(1.298, 7.1891, 2).toString() +
808
+ '<br><br>' + this._getEnd();
809
+ }
810
+ coreConvert62() {
811
+ return '<pre>lCore.convert62(10);</pre>' + lCore.convert62(10) +
812
+ '<pre>lCore.convert62(100);</pre>' + lCore.convert62(100) +
813
+ '<pre>lCore.convert62(1992199519982001n);</pre>' + lCore.convert62(1992199519982001n) +
814
+ '<pre>lCore.convert62(9223372036854770000n);</pre>' + lCore.convert62(9223372036854770000n) +
815
+ '<pre>lCore.convert62(9223372036854775807n);</pre>' + lCore.convert62(9223372036854775807n) +
816
+ '<pre>lCore.unconvert62(\'a\');</pre>' + lCore.unconvert62('a').toString() +
817
+ '<pre>lCore.unconvert62(\'100\');</pre>' + lCore.unconvert62('100').toString() +
818
+ '<pre>lCore.unconvert62(\'zzz\');</pre>' + lCore.unconvert62('zzz').toString() +
819
+ '<pre>lCore.unconvert62(\'ZZZ\');</pre>' + lCore.unconvert62('ZZZ').toString() +
820
+ '<pre>lCore.unconvert62(\'97HMXKQql\');</pre>' + lCore.unconvert62('97HMXKQql').toString() +
821
+ '<pre>lCore.unconvert62(\'aZl8N0y57gs\');</pre>' + lCore.unconvert62('aZl8N0y57gs').toString() +
822
+ '<pre>lCore.unconvert62(\'aZl8N0y58M7\');</pre>' + lCore.unconvert62('aZl8N0y58M7').toString() +
823
+ '<br><br>' + this._getEnd();
824
+ }
825
+ corePurify() {
826
+ const html = `<html>
827
+ <head>
828
+ <title>Title</title>
829
+ </head>
830
+ <body>
831
+ <!-- h1 -->
832
+ <h1>Hello</h1>
833
+ <h2>World</h2>
834
+ <div>// abc</div>
835
+ <script>
836
+ // --- test ---
837
+ if (a) {
838
+ alert('zzz');
839
+ }
840
+ /* --- test 2 --- */
841
+ if (b) {
842
+ alert('zzz');
843
+ }
844
+ </script>
845
+ </body>
846
+ </html>`;
847
+ return '<pre>lCore.purify(`' + lText.htmlescape(html) + '`);</pre>' + lText.htmlescape(lCore.purify(html)) + '<br><br>' + this._getEnd();
848
+ }
849
+ coreChecktype() {
850
+ const type1 = {
851
+ 'a': '1',
852
+ 'b': 0,
853
+ 'c': false,
854
+ 'd': {
855
+ 'e': 0,
856
+ 'f': false,
857
+ 'g': [
858
+ {
859
+ 'h': 0
860
+ }
861
+ ]
862
+ }
863
+ };
864
+ const type2 = [
865
+ {
866
+ 'a': '',
867
+ 'b': '1',
868
+ 'c': /^a.c$/
869
+ }
870
+ ];
871
+ const o1 = 0;
872
+ const o2 = {
873
+ 'a': '',
874
+ 'b': ''
875
+ };
876
+ const o3 = [{
877
+ 'a': '',
878
+ 'b': 'ok',
879
+ 'c': 'acd'
880
+ }];
881
+ const o4 = {
882
+ 'a': 'aaa',
883
+ 'b': 21424,
884
+ 'c': true,
885
+ 'd': {
886
+ 'e': 0,
887
+ 'f': false,
888
+ 'g': 'ok'
889
+ }
890
+ };
891
+ const o5 = {
892
+ 'a': 'aaa',
893
+ 'b': 21424,
894
+ 'c': true,
895
+ 'd': {
896
+ 'e': 0,
897
+ 'f': false,
898
+ 'g': [
899
+ {
900
+ 'x': 'ok'
901
+ }
902
+ ]
903
+ }
904
+ };
905
+ const o6 = {
906
+ 'a': 'aaa',
907
+ 'b': 21424,
908
+ 'c': true,
909
+ 'd': {
910
+ 'e': 0,
911
+ 'f': false,
912
+ 'g': [
913
+ {
914
+ 'h': 138
915
+ }
916
+ ]
917
+ }
918
+ };
919
+ const o7 = [
920
+ {
921
+ 'a': '',
922
+ 'b': 'ok'
923
+ },
924
+ {
925
+ 'a': '',
926
+ 'b': 'ok2'
927
+ },
928
+ {
929
+ 'a': '',
930
+ 'b': 0
931
+ }
932
+ ];
933
+ const o8 = [{
934
+ 'a': '',
935
+ 'b': 'ok',
936
+ 'c': 'abc'
937
+ }];
938
+ return `type1:<pre>${JSON.stringify(type1)}</pre>
939
+ type2:<pre>${JSON.stringify(type2)}</pre>
940
+ o1:<pre>${JSON.stringify(o1)}</pre>
941
+ lCore.checkType(o1, type1): ${lCore.checkType(o1, type1)}<br>
942
+ lCore.checkType(o1, type2): ${lCore.checkType(o1, type2)}<br><br>
943
+ o2:<pre>${JSON.stringify(o2)}</pre>
944
+ lCore.checkType(o2, type1): ${lCore.checkType(o2, type1)}<br>
945
+ lCore.checkType(o2, type2): ${lCore.checkType(o2, type2)}<br><br>
946
+ o3:<pre>${JSON.stringify(o3)}</pre>
947
+ lCore.checkType(o3, type1): ${lCore.checkType(o3, type1)}<br>
948
+ lCore.checkType(o3, type2): ${lCore.checkType(o3, type2)}<br><br>
949
+ o4:<pre>${JSON.stringify(o4)}</pre>
950
+ lCore.checkType(o4, type1): ${lCore.checkType(o4, type1)}<br>
951
+ lCore.checkType(o4, type2): ${lCore.checkType(o4, type2)}<br><br>
952
+ o5:<pre>${JSON.stringify(o5)}</pre>
953
+ lCore.checkType(o5, type1): ${lCore.checkType(o5, type1)}<br>
954
+ lCore.checkType(o5, type2): ${lCore.checkType(o5, type2)}<br><br>
955
+ o6:<pre>${JSON.stringify(o6)}</pre>
956
+ lCore.checkType(o6, type1): ${lCore.checkType(o6, type1)}<br>
957
+ lCore.checkType(o6, type2): ${lCore.checkType(o6, type2)}<br><br>
958
+ o7:<pre>${JSON.stringify(o7)}</pre>
959
+ lCore.checkType(o7, type1): ${lCore.checkType(o7, type1)}<br>
960
+ lCore.checkType(o7, type2): ${lCore.checkType(o7, type2)}<br><br>
961
+ o8:<pre>${JSON.stringify(o8)}</pre>
962
+ lCore.checkType(o8, type1): ${lCore.checkType(o8, type1)}<br>
963
+ lCore.checkType(o8, type2): ${lCore.checkType(o8, type2)}
964
+ <br><br>${this._getEnd()}`;
965
+ }
966
+ coreMuid() {
967
+ const ac = this._get['ac'] ? this._get['ac'] : '';
968
+ const echo = [
969
+ '<a href="' + this._config.const.urlBase + 'test/core-muid">Default</a> | ' +
970
+ '<a href="' + this._config.const.urlBase + 'test/core-muid?ac=big">Big</a> | ' +
971
+ '<a href="' + this._config.const.urlBase + 'test">Return</a>'
972
+ ];
973
+ if (ac === '') {
974
+ let muid = lCore.muid(this);
975
+ echo.push('<pre>lCore.muid(this);</pre>' + muid + ' (' + muid.length.toString() + ')');
976
+ muid = lCore.muid(this);
977
+ echo.push('<pre>lCore.muid(this);</pre>' + muid + ' (' + muid.length.toString() + ')');
978
+ muid = lCore.muid(this, { 'bin': false });
979
+ echo.push(`<pre>lCore.muid(this, { 'bin': false });</pre>` + muid + ' (' + muid.length.toString() + ')');
980
+ muid = lCore.muid(this, { 'len': 16 });
981
+ echo.push(`<pre>lCore.muid(this, { 'len': 16 });</pre>` + muid + ' (' + muid.length.toString() + ')');
982
+ muid = lCore.muid(this, { 'len': 16, 'bin': false });
983
+ echo.push(`<pre>lCore.muid(this, { 'len': 16, 'bin': false });</pre>` + muid + ' (' + muid.length.toString() + ')');
984
+ muid = lCore.muid(this, { 'insert': 'Aa', 'len': 32 });
985
+ echo.push(`<pre>lCore.muid(this, { 'insert': 'Aa', 'len': 32 });</pre>` + muid + ' (' + muid.length.toString() + ')');
986
+ muid = lCore.muid(this, { 'key': 'M' });
987
+ echo.push(`<pre>lCore.muid(this, { 'key': 'M' });</pre>` + muid + ' (' + muid.length.toString() + ')');
988
+ echo.push('<br><br>');
989
+ }
990
+ else {
991
+ const parr = [];
992
+ const oarr = [];
993
+ for (let i = 0; i < 30000; ++i) {
994
+ const muid = lCore.muid(this, { 'insert': '0' });
995
+ const sp = oarr.indexOf(muid);
996
+ if (sp > -1) {
997
+ parr.push(muid + '[' + sp.toString() + ']' + oarr[sp]);
998
+ continue;
999
+ }
1000
+ oarr.push(muid);
1001
+ }
1002
+ echo.push(`<pre>
1003
+ const parr: string[] = [];
1004
+ const oarr: string[] = [];
1005
+ for (let i = 0; i < 30000; ++i) {
1006
+ const muid = lText.muid(this);
1007
+ const sp = oarr.indexOf(muid);
1008
+ if (sp > -1) {
1009
+ parr.push(muid + '[' + sp.toString() + ']' + oarr[sp]);
1010
+ continue;
1011
+ }
1012
+ oarr.push(muid);
1013
+ }</pre>parr length: ${parr.length}<br>oarr length: ${oarr.length}<br><br>parr:<pre>${JSON.stringify(parr)}</pre>oarr:<pre>${JSON.stringify(oarr.slice(0, 100)).slice(0, -1)}...</pre>`);
1014
+ }
1015
+ return echo.join('') + this._getEnd();
1016
+ }
1017
+ async coreGetlog() {
1018
+ const path = lTime.format(null, 'Y/m/d/H');
1019
+ const list = await lCore.getLog({
1020
+ 'host': this._config.const.hostname,
1021
+ 'path': path,
1022
+ 'fend': '-visit',
1023
+ });
1024
+ const echo = [];
1025
+ echo.push('<table style="width: 100%;"><tr>');
1026
+ if (list) {
1027
+ for (const row of list) {
1028
+ echo.push('<tr>');
1029
+ for (const item of row) {
1030
+ echo.push('<td>' + lText.htmlescape(item) + '</td>');
1031
+ }
1032
+ echo.push('</tr>');
1033
+ }
1034
+ }
1035
+ else {
1036
+ echo.push('<th>' + JSON.stringify(list) + '</th></tr>');
1037
+ }
1038
+ echo.push('</table>');
1039
+ return echo.join('') + '<br>' + this._getEnd();
1040
+ }
1041
+ async coreUpdatecode() {
1042
+ const zip = `${this._config.const.dataPath}test.zip`;
1043
+ const to = '';
1044
+ const echo = [
1045
+ `zip: ${zip}<br>
1046
+ to: ${to}`
1047
+ ];
1048
+ const list = await lCore.updateCode(zip, to);
1049
+ echo.push(`<pre>const list = lCore.updateCode(zip, to);</pre>${JSON.stringify(list)}`);
1050
+ return echo.join('') + '<br><br>' + this._getEnd();
1051
+ }
1052
+ async coreReload() {
1053
+ await lCore.sendReload();
1054
+ return 'The reload request has been sent, please review the console.<br><br>' + this._getEnd();
1055
+ }
1056
+ async coreRestart() {
1057
+ await lCore.sendRestart();
1058
+ return 'The restart request has been sent, please review the console.<br><br>' + this._getEnd();
1059
+ }
1060
+ async coreGlobal() {
1061
+ const ts = lTime.stamp().toString();
1062
+ const echo = [
1063
+ `<pre>lCore.global.tglobal</pre>`,
1064
+ lCore.global.tglobal === undefined ? 'undefined' : JSON.stringify(lCore.global.tglobal),
1065
+ `<pre>lCore.setGlobal('tglobal', 'ts:${ts}');</pre>`
1066
+ ];
1067
+ await lCore.setGlobal('tglobal', 'ts:' + ts);
1068
+ await lCore.sleep(50);
1069
+ echo.push(JSON.stringify(lCore.global.tglobal));
1070
+ return echo.join('') + '<br><br>' + this._getEnd();
1071
+ }
1072
+ async crypto() {
1073
+ const echo = ['<b>AES-256-ECB:</b>'];
1074
+ const key = 'testkeyatestkeyatestkeyatestkeya';
1075
+ let text = lCrypto.aesEncrypt('Original text', key);
1076
+ echo.push(`<pre>const key = 'testkeyatestkeyatestkeyatestkeya';
1077
+ const text = lCrypto.aesEncrypt('Original text', key);
1078
+ JSON.stringify(text);</pre>${JSON.stringify(text)}`);
1079
+ let orig = lCrypto.aesDecrypt(text || '', key);
1080
+ echo.push(`<pre>let orig = lCrypto.aesDecrypt(text || '', key);
1081
+ JSON.stringify(orig);</pre>${JSON.stringify(orig)}`);
1082
+ orig = lCrypto.aesDecrypt(text || '', 'otherKey');
1083
+ echo.push(`<pre>orig = lCrypto.aesDecrypt(text || '', 'otherKey');
1084
+ JSON.stringify(orig);</pre>${JSON.stringify(orig)}`);
1085
+ echo.push('<br><br><b>AES-256-CFB:</b>');
1086
+ const iv = 'iloveuiloveuilov';
1087
+ text = lCrypto.aesEncrypt('Original text', key, iv);
1088
+ echo.push(`<pre>const iv = 'iloveuiloveuilov';
1089
+ text = lCrypto.aesEncrypt('Original text', key, iv);
1090
+ JSON.stringify(text);</pre>${JSON.stringify(text)}`);
1091
+ orig = lCrypto.aesDecrypt(text || '', key, iv);
1092
+ echo.push(`<pre>orig = lCrypto.aesDecrypt(text || '', key, iv);
1093
+ JSON.stringify(orig);</pre>${JSON.stringify(orig)}`);
1094
+ orig = lCrypto.aesDecrypt(text || '', key, 'otherIv');
1095
+ echo.push(`<pre>orig = lCrypto.aesDecrypt(text || '', key, 'otherIv');
1096
+ orig ? 'true' : 'false';</pre>${orig ? 'true' : 'false'}`);
1097
+ echo.push('<br><br><b>AES-256-CBC:</b>');
1098
+ text = lCrypto.aesEncrypt('Original text', key, iv, lCrypto.AES_256_CBC);
1099
+ echo.push(`<pre>const key = 'testkeyatestkeyatestkeyatestkeya';
1100
+ const text = lCrypto.aesEncrypt('Original text', key);
1101
+ text = lCrypto.aesEncrypt('Original text', key, iv, lCrypto.AES_256_CBC);
1102
+ JSON.stringify(text);</pre>${JSON.stringify(text)}`);
1103
+ orig = lCrypto.aesDecrypt(text || '', key, iv, lCrypto.AES_256_CBC);
1104
+ echo.push(`<pre>orig = lCrypto.aesDecrypt(text || '', key, iv, lCrypto.AES_256_CBC);
1105
+ JSON.stringify(orig);</pre>${JSON.stringify(orig)}`);
1106
+ orig = lCrypto.aesDecrypt(text || '', key, 'otherIv', lCrypto.AES_256_CBC);
1107
+ echo.push(`<pre>orig = lCrypto.aesDecrypt(text || '', key, 'otherIv', lCrypto.AES_256_CBC);
1108
+ JSON.stringify(orig);</pre>${JSON.stringify(orig)}`);
1109
+ const res = await lCrypto.generateKeyPair('ec', {
1110
+ 'namedCurve': 'sm2',
1111
+ 'privateKeyEncoding': {
1112
+ 'type': 'sec1'
1113
+ }
1114
+ });
1115
+ echo.push(`<pre>const res = lCrypto.generateKeyPair('ec', {
1116
+ 'namedCurve': 'sm2',
1117
+ 'privateKeyEncoding': {
1118
+ 'type': 'sec1'
1119
+ }
1120
+ });
1121
+ JSON.stringify(res);</pre>${JSON.stringify(res)}`);
1122
+ const sign = lCrypto.sign('Hello MAIYUN.NET', res.private, 'base64', 'sm3');
1123
+ echo.push(`<pre>const sign = lCrypto.sign('Hello MAIYUN.NET', res.private, 'base64', 'sm3');
1124
+ JSON.stringify(sign);</pre>${JSON.stringify(sign)}`);
1125
+ const r = lCrypto.verify('Hello MAIYUN.NET', res.public, Buffer.from(sign, 'base64'), 'sm3');
1126
+ echo.push(`<pre>const r = lCrypto.verify('Hello MAIYUN.NET', res.public, Buffer.from(sign, 'base64'), 'sm3');
1127
+ JSON.stringify(r);</pre>${JSON.stringify(r)}`);
1128
+ return echo.join('') + '<br><br>' + this._getEnd();
1129
+ }
1130
+ async db() {
1131
+ const echo = [(Math.round(this._getRunTime() * 10000000) / 10000).toString()];
1132
+ const db = lDb.get(this);
1133
+ let stmt = await db.query('SELECT * FROM `m_test` ORDER BY `id` DESC LIMIT 10;');
1134
+ if (!stmt.rows) {
1135
+ return [0, stmt.error ? (stmt.error.message + '(' + stmt.error.errno.toString() + ')') : 'Failed("m_test" not found).'];
1136
+ }
1137
+ echo.push(`<pre>const db = lDb.get(this);
1138
+ const stmt = await db.query('SELECT * FROM \`m_test\` ORDER BY \`id\` DESC LIMIT 10;');</pre>`);
1139
+ this._dbTable(stmt, echo);
1140
+ echo.push('<br>ms: ' + (Math.round(this._getRunTime() * 10000000) / 10000).toString());
1141
+ const time = lTime.stamp().toString();
1142
+ let exec = await db.execute('INSERT INTO `m_test` (`token`, `point`, `time_add`) VALUES (\'test-token\', ST_POINTFROMTEXT(\'POINT(10 10)\'), \'' + time + '\');');
1143
+ let ms = (Math.round(this._getRunTime() * 10000000) / 10000).toString();
1144
+ let insertId = 0;
1145
+ if (exec.error?.errno === 1062) {
1146
+ insertId = (await db.query('SELECT * FROM `m_test` WHERE `token` = \'test-token\';')).rows?.[0].id ?? 0;
1147
+ ms += ', ' + (Math.round(this._getRunTime() * 10000000) / 10000).toString();
1148
+ }
1149
+ else {
1150
+ insertId = exec.packet?.insertId ?? 0;
1151
+ }
1152
+ echo.push(`<pre>const time = lTime.stamp().toString();
1153
+ const exec = await db.execute('INSERT INTO \`m_test\` (\`token\`, \`data\`, \`time_update\`, \`time_add\`) VALUES (\\'test-token\\', ST_POINTFROMTEXT(\\'POINT(10 10)\\'), \\'' + time + '\\');');
1154
+ let insertId: number = 0;
1155
+ if (exec.error?.errno === 1062) {
1156
+ insertId = (await db.query('SELECT * FROM \`m_test\` WHERE \`token\` = \\'test-token\\';')).rows?.[0].id ?? 0;
1157
+ }
1158
+ else {
1159
+ insertId = exec.packet?.insertId ?? 0;
1160
+ }</pre>
1161
+ exec: ${JSON.stringify(exec)}<br>
1162
+ insertId: ${JSON.stringify(insertId)}<br>
1163
+ errno: ${JSON.stringify(exec.error?.errno)}<br>
1164
+ error: ${JSON.stringify(exec.error)}<br>
1165
+ ms: ${ms}<br><br>`);
1166
+ stmt = await db.query('SELECT * FROM `m_test` ORDER BY `id` DESC LIMIT 1;');
1167
+ this._dbTable(stmt, echo);
1168
+ exec = await db.execute('INSERT INTO `m_test` (`token`, `point`, `time_add`) VALUES (\'test-token\', ST_POINTFROMTEXT(\'POINT(10 10)\'), \'' + time + '\');');
1169
+ insertId = exec.packet?.insertId ?? 0;
1170
+ echo.push(`<pre>exec = await db.execute('INSERT INTO \`m_test\` (\`token\`, \`point\`, \`time_add\`) VALUES (\\'test-token\\', ST_POINTFROMTEXT(\\'POINT(10 10)\\'), \\'' + time + '\\');');
1171
+ insertId = exec.packet?.insertId ?? 0;</pre>
1172
+ exec: ${JSON.stringify(exec)}<br>
1173
+ insertId: ${JSON.stringify(insertId)}<br>
1174
+ errno: ${JSON.stringify(exec.error?.errno)}<br>
1175
+ error: ${JSON.stringify(exec.error)}<br>
1176
+ ms: ${(Math.round(this._getRunTime() * 10000000) / 10000).toString()}<br>`);
1177
+ exec = await db.execute('REPLACE INTO `m_test` (`token`, `point`, `time_add`) VALUES (\'test-token\', ST_POINTFROMTEXT(\'POINT(20 20)\'), \'' + time + '\');');
1178
+ insertId = exec.packet?.insertId ?? 0;
1179
+ echo.push(`<pre>exec = await db.execute('REPLACE INTO \`m_session\` (\`token\`, \`point\`, \`time_add\`) VALUES (\\'test-token\\', ST_POINTFROMTEXT(\\'POINT(20 20)\\'), \\'' + time + '\\');');
1180
+ insertId = exec.packet?.insertId ?? 0;</pre>
1181
+ exec: ${JSON.stringify(exec)}<br>
1182
+ insertId: ${JSON.stringify(insertId)}<br>
1183
+ errno: ${JSON.stringify(exec.error?.errno)}<br>
1184
+ error: ${JSON.stringify(exec.error)}<br>
1185
+ ms: ${(Math.round(this._getRunTime() * 10000000) / 10000).toString()}<br><br>`);
1186
+ stmt = await db.query('SELECT * FROM `m_test` ORDER BY `id` DESC LIMIT 10;');
1187
+ this._dbTable(stmt, echo);
1188
+ const explain = 'EXPLAIN';
1189
+ stmt = await db.query(explain + ' SELECT * FROM `m_test` LIMIT 10;');
1190
+ echo.push(`<pre>stmt = await db.query('${explain} SELECT * FROM \`m_test\` LIMIT 10;');</pre>`);
1191
+ this._dbTable(stmt, echo);
1192
+ echo.push('<br>ms: ' + (Math.round(this._getRunTime() * 10000000) / 10000).toString());
1193
+ exec = await db.execute('DELETE FROM `m_test` WHERE `token` = \'test-token\';');
1194
+ echo.push(`<pre>exec = await db.execute('DELETE FROM \`m_test\` WHERE \`token\` = \\'test-token\\';');</pre>
1195
+ exec: ${JSON.stringify(exec)}<br><br>`);
1196
+ stmt = await db.query('SELECT * FROM `m_test` ORDER BY `id` DESC LIMIT 10;');
1197
+ this._dbTable(stmt, echo);
1198
+ return echo.join('') + '<br>queries: ' + db.getQueries().toString() + '<br>' + this._getEnd();
1199
+ }
1200
+ _dbTable(stmt, echo) {
1201
+ echo.push('<table style="width: 100%;"><tr>');
1202
+ if (stmt.rows) {
1203
+ for (const item of stmt.fields) {
1204
+ echo.push('<th>' + lText.htmlescape(item.name) + '</th>');
1205
+ }
1206
+ echo.push('</tr>');
1207
+ for (const row of stmt.rows) {
1208
+ echo.push('<tr>');
1209
+ for (const key in row) {
1210
+ const val = row[key];
1211
+ echo.push('<td>' + (val === null ? 'null' : lText.htmlescape(JSON.stringify(val))) + '</td>');
1212
+ }
1213
+ echo.push('</tr>');
1214
+ }
1215
+ }
1216
+ else {
1217
+ echo.push('<th>No data</th></tr>');
1218
+ }
1219
+ echo.push('</table>');
1220
+ }
1221
+ async kv() {
1222
+ const kv = lKv.get(this);
1223
+ if (!await kv.ping()) {
1224
+ return [0, 'Failed.'];
1225
+ }
1226
+ const value = this._get['value'] ?? '';
1227
+ const ac = this._get['ac'] ?? '';
1228
+ const echo = [`<pre>const kv = lKv.get(this);
1229
+ if (!await kv.ping()) {
1230
+ return [0, 'Failed.'];
1231
+ }
1232
+ JSON.stringify(await kv.ping());</pre>${JSON.stringify(await kv.ping())}`];
1233
+ if (ac == 'delete') {
1234
+ echo.push("<pre>JSON.stringify(await kv.get('test'));</pre>" + JSON.stringify(await kv.get('test')));
1235
+ echo.push("<pre>JSON.stringify(await kv.del('test'));</pre>" + JSON.stringify(await kv.del('test')));
1236
+ echo.push("<pre>JSON.stringify(await kv.get('test'));</pre>" + JSON.stringify(await kv.get('test')));
1237
+ }
1238
+ else if (ac === 'ttl') {
1239
+ echo.push("<pre>JSON.stringify(await kv.ttl('test'));</pre>" + JSON.stringify(await kv.ttl('test')));
1240
+ echo.push("<pre>JSON.stringify(await kv.pttl('test'));</pre>" + JSON.stringify(await kv.pttl('test')));
1241
+ echo.push("<pre>JSON.stringify(await kv.set('test', 'ttl', 10));</pre>" + JSON.stringify(await kv.set('test', 'ttl', 10)));
1242
+ echo.push("<pre>JSON.stringify(await kv.ttl('test'));</pre>" + JSON.stringify(await kv.ttl('test')));
1243
+ echo.push("<pre>JSON.stringify(await kv.pttl('test'));</pre>" + JSON.stringify(await kv.pttl('test')));
1244
+ }
1245
+ else if (ac == 'incr-decr-replace') {
1246
+ echo.push("<pre>JSON.stringify(await kv.del('test'));</pre>" + JSON.stringify(await kv.del('test')));
1247
+ echo.push("<pre>JSON.stringify(await kv.replace('test', 'QAQ'));</pre>" + JSON.stringify(await kv.replace('test', 'QAQ')));
1248
+ echo.push("<pre>JSON.stringify(await kv.incr('test'));</pre>" + JSON.stringify(await kv.incr('test')));
1249
+ echo.push("<pre>JSON.stringify(await kv.get('test'));</pre>" + JSON.stringify(await kv.get('test')));
1250
+ echo.push("<pre>JSON.stringify(await kv.set('test', 666));</pre>" + JSON.stringify(await kv.set('test', 666)));
1251
+ echo.push("<pre>JSON.stringify(await kv.incr('test'));</pre>" + JSON.stringify(await kv.incr('test')));
1252
+ echo.push("<pre>JSON.stringify(await kv.get('test'));</pre>" + JSON.stringify(await kv.get('test')));
1253
+ echo.push("<pre>JSON.stringify(await kv.decr('test', 10));</pre>" + JSON.stringify(await kv.decr('test', 10)));
1254
+ echo.push("<pre>JSON.stringify(await kv.get('test'));</pre>" + JSON.stringify(await kv.get('test')));
1255
+ echo.push("<pre>JSON.stringify(await kv.replace('test', 111));</pre>" + JSON.stringify(await kv.replace('test', 111)));
1256
+ echo.push("<pre>JSON.stringify(await kv.get('test'));</pre>" + JSON.stringify(await kv.get('test')));
1257
+ echo.push("<pre>JSON.stringify(await kv.replace('test', 'QAQ'));</pre>" + JSON.stringify(await kv.replace('test', 'QAQ')));
1258
+ echo.push("<pre>SON.stringify(await kv.incr('test', 10));</pre>" + JSON.stringify(await kv.incr('test', 10)));
1259
+ echo.push("<pre>JSON.stringify(await kv.get('test'));</pre>" + JSON.stringify(await kv.get('test')));
1260
+ }
1261
+ else if (ac === 'append-prepend') {
1262
+ echo.push("<pre>SON.stringify(await kv.prepend('test', '0'));</pre>" + JSON.stringify(await kv.prepend('test', '0')));
1263
+ echo.push("<pre>JSON.stringify(await kv.get('test'));</pre>" + JSON.stringify(await kv.get('test')));
1264
+ echo.push("<pre>JSON.stringify(await kv.set('test', 'bbb'));</pre>" + JSON.stringify(await kv.set('test', 'bbb')));
1265
+ echo.push("<pre>JSON.stringify(await kv.append('test', 'end'));</pre>" + JSON.stringify(await kv.append('test', 'end')));
1266
+ echo.push("<pre>JSON.stringify(await kv.get('test'));</pre>" + JSON.stringify(await kv.get('test')));
1267
+ echo.push("<pre>JSON.stringify(await kv.prepend('test', 'pre'));</pre>" + JSON.stringify(await kv.prepend('test', 'pre')));
1268
+ echo.push("<pre>JSON.stringify(await kv.get('test'));</pre>" + JSON.stringify(await kv.get('test')));
1269
+ echo.push("<pre>JSON.stringify(await kv.add('test', 'aaa'));</pre>" + JSON.stringify(await kv.add('test', 'aaa')));
1270
+ echo.push("<pre>JSON.stringify(await kv.append('tmp_test', 'hehe'));</pre>" + JSON.stringify(await kv.append('tmp_test', 'hehe')));
1271
+ echo.push("<pre>JSON.stringify(await kv.get('tmp_test'));</pre>" + JSON.stringify(await kv.get('tmp_test')));
1272
+ echo.push("<pre>JSON.stringify(await kv.del('tmp_test'));</pre>" + JSON.stringify(await kv.del('tmp_test')));
1273
+ }
1274
+ else if (ac === 'hash') {
1275
+ echo.push("<pre>JSON.stringify(await kv.hSet('hTest', 'name', 'Cheng Xin'));</pre>" + JSON.stringify(await kv.hSet('hTest', 'name', 'Cheng Xin')));
1276
+ echo.push("<pre>JSON.stringify(await kv.hSet('hTest', 'age', '16', 'nx'));</pre>" + JSON.stringify(await kv.hSet('hTest', 'age', '16', 'nx')));
1277
+ echo.push(`<pre>JSON.stringify(await kv.hMSet('hTest', {
1278
+ 'age': '16',
1279
+ 'sex': 'female'
1280
+ }));</pre>`);
1281
+ echo.push(JSON.stringify(await kv.hMSet('hTest', {
1282
+ 'age': '16',
1283
+ 'sex': 'female'
1284
+ })));
1285
+ echo.push("<pre>JSON.stringify(await kv.hSet('hTest', 'age', '16', 'nx'));</pre>" + JSON.stringify(await kv.hSet('hTest', 'age', '16', 'nx')));
1286
+ echo.push("<pre>JSON.stringify(await kv.hGet('hTest', 'name'));</pre>" + JSON.stringify(await kv.hGet('hTest', 'name')));
1287
+ echo.push("<pre>JSON.stringify(await kv.hDel('hTest', 'name'));</pre>" + JSON.stringify(await kv.hDel('hTest', 'name')));
1288
+ echo.push(`<pre>JSON.stringify(await kv.hMSet('hTest', {
1289
+ 'ok1': 'bye',
1290
+ 'ok2': [
1291
+ '1', '2', '5', '8', '0'
1292
+ ]
1293
+ }));</pre>`);
1294
+ echo.push(JSON.stringify(await kv.hMSet('hTest', {
1295
+ 'ok1': 'bye',
1296
+ 'ok2': [
1297
+ '1', '2', '5', '8', '0'
1298
+ ]
1299
+ })));
1300
+ echo.push("<pre>JSON.stringify(await kv.hSet('hTest', 'ok1', ['a', 'b']));</pre>" + JSON.stringify(await kv.hSet('hTest', 'ok1', ['a', 'b'])));
1301
+ echo.push("<pre>JSON.stringify(await kv.hGetAll('hTest'));</pre>" + JSON.stringify(await kv.hGetAll('hTest')));
1302
+ echo.push("<pre>JSON.stringify(await kv.hGetJson('hTest', 'ok1'));</pre>" + JSON.stringify(await kv.hGetJson('hTest', 'ok1')));
1303
+ echo.push("<pre>JSON.stringify(await kv.hKeys('hTest'));</pre>" + JSON.stringify(await kv.hKeys('hTest')));
1304
+ echo.push("<pre>JSON.stringify(await kv.hExists('hTest', 'age'));</pre>" + JSON.stringify(await kv.hExists('hTest', 'age')));
1305
+ echo.push("<pre>SON.stringify(await kv.hMGet('hTest', ['age', 'sex', 'school']));</pre>" + JSON.stringify(await kv.hMGet('hTest', ['age', 'sex', 'school'])));
1306
+ echo.push("<pre>JSON.stringify(await kv.del('hTest'));</pre>" + JSON.stringify(await kv.del('hTest')));
1307
+ echo.push("<pre>JSON.stringify(await kv.hGet('hTest', 'name'));</pre>" + JSON.stringify(await kv.hGet('hTest', 'name')));
1308
+ echo.push("<pre>JSON.stringify(await kv.hGetAll('hTest'));</pre>" + JSON.stringify(await kv.hGetAll('hTest')));
1309
+ }
1310
+ else if (ac === 'other') {
1311
+ echo.push(`<pre>for (let i = 0; i < 50; ++i) {
1312
+ await kv.add('t' + i.toString(), i, 10);
1313
+ }
1314
+ echo.push('Added.');</pre>`);
1315
+ for (let i = 0; i < 50; ++i) {
1316
+ await kv.add('t' + i.toString(), i, 10);
1317
+ }
1318
+ echo.push('Added.');
1319
+ echo.push("<pre>JSON.stringify(await kv.keys('t*'));</pre>" + JSON.stringify(await kv.keys('t*')));
1320
+ echo.push('<pre>JSON.stringify(await kv.scan());</pre>' + JSON.stringify(await kv.scan()));
1321
+ echo.push(`<pre>let cursor = 0;
1322
+ while (true) {
1323
+ echo.push('WHILE (' + JSON.stringify(cursor) + ')&lt;br&gt;');
1324
+ const r = await kv.scan(cursor, '*2*', 5);
1325
+ if (r === false || r.nextCursor === 0) {
1326
+ echo.push('DONE&lt;br&gt;');
1327
+ break;
1328
+ }
1329
+ echo.push(JSON.stringify(r.items) + '&lt;br&gt;');
1330
+ cursor = r.nextCursor;
1331
+ }
1332
+ echo[echo.length - 1] = echo[echo.length - 1].slice(0, -4);</pre>`);
1333
+ let cursor = 0;
1334
+ while (true) {
1335
+ echo.push('WHILE (' + JSON.stringify(cursor) + ')<br>');
1336
+ const r = await kv.scan(cursor, '*2*', 5);
1337
+ if (r === false || r.nextCursor === 0) {
1338
+ echo.push('DONE<br>');
1339
+ break;
1340
+ }
1341
+ echo.push(JSON.stringify(r.items) + '<br>');
1342
+ cursor = r.nextCursor;
1343
+ }
1344
+ echo[echo.length - 1] = echo[echo.length - 1].slice(0, -4);
1345
+ }
1346
+ else {
1347
+ echo.push("<pre>JSON.stringify(await kv.exists(['test', 'heheda']));</pre>" + JSON.stringify(await kv.exists(['test', 'heheda'])));
1348
+ echo.push("<pre>JSON.stringify(await kv.mGet(['test', 'heheda']));</pre>" + JSON.stringify(await kv.mGet(['test', 'heheda'])));
1349
+ echo.push("<pre>JSON.stringify(await kv.get('test'));</pre>" + JSON.stringify(await kv.get('test')));
1350
+ echo.push("<pre>JSON.stringify(await kv.set('test', $value ? $value : 'ok'));</pre>" + JSON.stringify(await kv.set('test', value ? value : 'ok')));
1351
+ echo.push("<pre>JSON.stringify(await kv.get('test'));</pre>" + JSON.stringify(await kv.get('test')));
1352
+ }
1353
+ return '<a href="' + this._config.const.urlBase + 'test/kv">Default</a> | ' +
1354
+ '<a href="' + this._config.const.urlBase + 'test/kv?value=aaa">Set "aaa"</a> | ' +
1355
+ '<a href="' + this._config.const.urlBase + 'test/kv?value=bbb">Set "bbb"</a> | ' +
1356
+ '<a href="' + this._config.const.urlBase + 'test/kv?ac=delete">Delete</a> | ' +
1357
+ '<a href="' + this._config.const.urlBase + 'test/kv?ac=ttl">ttl</a> | ' +
1358
+ '<a href="' + this._config.const.urlBase + 'test/kv?ac=incr-decr-replace">Incr/Decr/Replace</a> | ' +
1359
+ '<a href="' + this._config.const.urlBase + 'test/kv?ac=append-prepend">Append/Prepend</a> | ' +
1360
+ '<a href="' + this._config.const.urlBase + 'test/kv?ac=hash">Hash</a> | ' +
1361
+ '<a href="' + this._config.const.urlBase + 'test/kv?ac=other">Other</a> | ' +
1362
+ '<a href="' + this._config.const.urlBase + 'test">Return</a>' + echo.join('') + '<br><br>' + this._getEnd();
1363
+ }
1364
+ async net() {
1365
+ const echo = [];
1366
+ const res = await lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/package.json');
1367
+ echo.push(`<pre>Net.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/package.json');</pre>
1368
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1369
+ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>
1370
+ error: ${JSON.stringify(res.error)}`);
1371
+ return echo.join('') + '<br><br>' + this._getEnd();
1372
+ }
1373
+ async netPipe() {
1374
+ const echo = [];
1375
+ const res = await lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/package.json');
1376
+ echo.push(`<pre>Net.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/package.json');</pre>
1377
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1378
+ content: <pre>`, res, `</pre>
1379
+ error: ${JSON.stringify(res.error)}
1380
+ <br><br>` + this._getEnd());
1381
+ return echo;
1382
+ }
1383
+ async netPost() {
1384
+ const echo = [];
1385
+ const res = await lNet.post(this._internalUrl + 'test/netPost1', { 'a': '1', 'b': '2', 'c': ['1', '2', '3'] });
1386
+ echo.push(`<pre>lNet.post('${this._internalUrl}test/netPost1', { 'a': '1', 'b': '2', 'c': ['1', '2', '3'] });</pre>
1387
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1388
+ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>
1389
+ error: ${JSON.stringify(res.error)}`);
1390
+ return echo.join('') + '<br><br>' + this._getEnd();
1391
+ }
1392
+ netPost1() {
1393
+ return `_post:\n\n${JSON.stringify(this._post)}\n\nRequest headers:\n\n${JSON.stringify(this._headers, null, 4)}\n\nIP: ${this._req.socket.remoteAddress ?? ''}`;
1394
+ }
1395
+ async netPostString() {
1396
+ const echo = [];
1397
+ const res = await lNet.post(this._internalUrl + 'test/netPostString1', 'HeiHei');
1398
+ echo.push(`<pre>lNet.post('${this._internalUrl}test/netPostString1', 'HeiHei');</pre>
1399
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1400
+ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>
1401
+ error: ${JSON.stringify(res.error)}`);
1402
+ return echo.join('') + '<br><br>' + this._getEnd();
1403
+ }
1404
+ netPostString1() {
1405
+ return [1, this._input];
1406
+ }
1407
+ async netOpen() {
1408
+ const echo = [];
1409
+ const res = await lNet.open(this._internalUrl + 'test/netPost1').post().data({ 'a': '2', 'b': '0', 'c': ['0', '1', '3'] }).request();
1410
+ echo.push(`<pre>lNet.open('${this._internalUrl}test/netPost1').post().data({ 'a': '2', 'b': '0', 'c': ['0', '1', '3'] }).request();</pre>
1411
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1412
+ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>
1413
+ error: ${JSON.stringify(res.error)}`);
1414
+ return echo.join('') + this._getEnd();
1415
+ }
1416
+ async netFormTest() {
1417
+ if (!await this._handleFormData()) {
1418
+ return '';
1419
+ }
1420
+ const echo = [
1421
+ '<pre>',
1422
+ JSON.stringify(this._post, null, 4),
1423
+ '\n-----\n',
1424
+ JSON.stringify(this._files, null, 4),
1425
+ '</pre>'
1426
+ ];
1427
+ echo.push(`<form enctype="multipart/form-data" method="post">
1428
+ text a: <input type="text" name="a" value="a1"> <input type="text" name="a" value="a2"><br>
1429
+ file b: <input type="file" name="b"><br>
1430
+ file c: <input type="file" name="c"><input type="file" name="c"><br>
1431
+ fi d[]: <input type="file" name="d[]"><input type="file" name="d[]"><br>
1432
+ <input type="submit" value="Upload">
1433
+ </form>
1434
+ <hr>
1435
+ <form method="post">
1436
+ name a: <input type="text" name="a" value="a&1"> <input type="text" name="a" value="a&2"><br>
1437
+ na b[]: <input type="text" name="b[]" value="b1"> <input type="text" name="b[]" value="b2"><br>
1438
+ name d: <input type="text" name="d" value="d"><br>
1439
+ <input type="submit" value="Default post">
1440
+ </form>`);
1441
+ return echo.join('') + this._getEnd();
1442
+ }
1443
+ async netUpload() {
1444
+ const echo = [];
1445
+ const fd = lNet.getFormData();
1446
+ fd.putString('a', '1');
1447
+ await fd.putFile('file', kebab.LIB_PATH + 'net/cacert.pem');
1448
+ await fd.putFile('multiple', kebab.LIB_PATH + 'net/cacert.pem');
1449
+ await fd.putFile('multiple', kebab.LIB_PATH + 'net/cacert.pem');
1450
+ const res = await lNet.post(this._internalUrl + 'test/net-upload1', fd);
1451
+ echo.push(`<pre>const fd = lNet.getFormData();
1452
+ fd.putString('a', '1');
1453
+ await fd.putFile('file', def.LIB_PATH + 'net/cacert.pem');
1454
+ await fd.putFile('multiple', def.LIB_PATH + 'net/cacert.pem');
1455
+ await fd.putFile('multiple', def.LIB_PATH + 'net/cacert.pem');
1456
+ lNet.post('${this._internalUrl}test/net-upload1', fd);</pre>
1457
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1458
+ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>
1459
+ error: ${JSON.stringify(res.error)}`);
1460
+ return echo.join('') + '<br><br>' + this._getEnd();
1461
+ }
1462
+ async netUpload1() {
1463
+ if (!await this._handleFormData()) {
1464
+ return '{}';
1465
+ }
1466
+ return JSON.stringify(this._post, null, 4) + '\n\n' + JSON.stringify(this._files, null, 4);
1467
+ }
1468
+ async netCookie() {
1469
+ const echo = [];
1470
+ const cookie = {};
1471
+ let res = await lNet.get(this._internalUrl + 'test/net-cookie1', {
1472
+ 'cookie': cookie
1473
+ });
1474
+ echo.push(`<pre>const cookie = {};
1475
+ lNet.get(this._internalUrl + 'test/net-cookie1', {
1476
+ 'cookie': cookie
1477
+ });</pre>
1478
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1479
+ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>
1480
+ cookie: <pre>${JSON.stringify(cookie, null, 4)}</pre><hr>`);
1481
+ res = await lNet.get(this._internalUrl + 'test/net-cookie2', {
1482
+ 'cookie': cookie
1483
+ });
1484
+ echo.push(`<pre>lNet.get(this._internalUrl + 'test/net-cookie2', {
1485
+ 'cookie': cookie
1486
+ });</pre>
1487
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1488
+ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>`);
1489
+ lNet.setCookie(cookie, 'custom1', 'abc1', this._config.const.host);
1490
+ lNet.setCookie(cookie, 'custom2', 'abc2', '172.17.0.1');
1491
+ res = await lNet.get(this._internalUrl + 'test/net-cookie2', {
1492
+ 'cookie': cookie
1493
+ });
1494
+ echo.push(`<pre>lNet.setCookie(cookie, 'custom1', 'abc1', ${this._config.const.host});
1495
+ lNet.setCookie(cookie, 'custom2', 'abc2', '172.17.0.1');
1496
+ lNet.get(this._internalUrl + 'test/net-cookie2', {
1497
+ 'cookie': cookie
1498
+ });</pre>
1499
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1500
+ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>`);
1501
+ return echo.join('') + this._getEnd();
1502
+ }
1503
+ netCookie1() {
1504
+ lCore.setCookie(this, 'test0', 'session');
1505
+ lCore.setCookie(this, 'test1', 'normal', {
1506
+ 'ttl': 10
1507
+ });
1508
+ lCore.setCookie(this, 'test2', 'baidu.com', {
1509
+ 'ttl': 20,
1510
+ 'path': '/',
1511
+ 'domain': 'baidu.com'
1512
+ });
1513
+ lCore.setCookie(this, 'test3', this._config.const.hostname, {
1514
+ 'ttl': 30,
1515
+ 'path': '/',
1516
+ 'domain': this._config.const.hostname
1517
+ });
1518
+ lCore.setCookie(this, 'test4', '/ok/', {
1519
+ 'ttl': 40,
1520
+ 'path': '/ok/'
1521
+ });
1522
+ lCore.setCookie(this, 'test5', 'secure', {
1523
+ 'ttl': 50,
1524
+ 'ssl': true
1525
+ });
1526
+ lCore.setCookie(this, 'test6', '0.1', {
1527
+ 'ttl': 40,
1528
+ 'path': '/',
1529
+ 'domain': '0.1'
1530
+ });
1531
+ lCore.setCookie(this, 'test7', 'localhost', {
1532
+ 'ttl': 30,
1533
+ 'path': '/',
1534
+ 'domain': 'localhost'
1535
+ });
1536
+ lCore.setCookie(this, 'test8', 'com', {
1537
+ 'ttl': 20,
1538
+ 'path': '/',
1539
+ 'domain': 'com'
1540
+ });
1541
+ lCore.setCookie(this, 'test9', 'com.cn', {
1542
+ 'ttl': 10,
1543
+ 'path': '/',
1544
+ 'domain': 'com.cn'
1545
+ });
1546
+ lCore.setCookie(this, 'test10', 'httponly', {
1547
+ 'ttl': 60,
1548
+ 'httponly': true
1549
+ });
1550
+ return `lCore.setCookie(this, 'test0', 'session');
1551
+ lCore.setCookie(this, 'test1', 'normal', {
1552
+ 'ttl': 10
1553
+ });
1554
+ lCore.setCookie(this, 'test2', 'baidu.com', {
1555
+ 'ttl': 20,
1556
+ 'path': '/',
1557
+ 'domain': 'baidu.com'
1558
+ });
1559
+ lCore.setCookie(this, 'test3', this._config.const.hostname, {
1560
+ 'ttl': 30,
1561
+ 'path': '/',
1562
+ 'domain': this._config.const.hostname
1563
+ });
1564
+ lCore.setCookie(this, 'test4', '/ok/', {
1565
+ 'ttl': 40,
1566
+ 'path': '/ok/'
1567
+ });
1568
+ lCore.setCookie(this, 'test5', 'secure', {
1569
+ 'ttl': 50,
1570
+ 'ssl': true
1571
+ });
1572
+ lCore.setCookie(this, 'test6', '0.1', {
1573
+ 'ttl': 40,
1574
+ 'path': '/',
1575
+ 'domain': '0.1'
1576
+ });
1577
+ lCore.setCookie(this, 'test7', 'localhost', {
1578
+ 'ttl': 30,
1579
+ 'path': '/',
1580
+ 'domain': 'localhost'
1581
+ });
1582
+ lCore.setCookie(this, 'test8', 'com', {
1583
+ 'ttl': 20,
1584
+ 'path': '/',
1585
+ 'domain': 'com'
1586
+ });
1587
+ lCore.setCookie(this, 'test9', 'com.cn', {
1588
+ 'ttl': 10,
1589
+ 'path': '/',
1590
+ 'domain': 'com.cn'
1591
+ });
1592
+ lCore.setCookie(this, 'test10', 'httponly', {
1593
+ 'ttl': 60,
1594
+ 'httponly': true
1595
+ });`;
1596
+ }
1597
+ netCookie2() {
1598
+ return 'this._cookie: \n\n' + JSON.stringify(this._cookie, null, 4);
1599
+ }
1600
+ async netSave() {
1601
+ const echo = [];
1602
+ const res = await lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/package.json', {
1603
+ 'follow': 5,
1604
+ 'save': kebab.LOG_CWD + 'test-must-remove.json'
1605
+ });
1606
+ echo.push(`<pre>lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/package.json', {
1607
+ 'follow': 5,
1608
+ 'save': def.LOG_PATH + 'test-must-remove.json'
1609
+ });</pre>
1610
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1611
+ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>
1612
+ error: ${JSON.stringify(res.error)}</pre>`);
1613
+ return echo.join('') + this._getEnd();
1614
+ }
1615
+ async netFollow() {
1616
+ const echo = [];
1617
+ const res = await lNet.post(this._internalUrl + 'test/net-follow1', {
1618
+ 'a': '1',
1619
+ 'b': '2'
1620
+ }, {
1621
+ 'follow': 5
1622
+ });
1623
+ echo.push(`<pre>lNet.post(this._internalUrl + 'test/net-follow1', {
1624
+ 'a': '1',
1625
+ 'b': '2'
1626
+ }, {
1627
+ 'follow': 5
1628
+ });</pre>
1629
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1630
+ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>
1631
+ error: ${JSON.stringify(res.error)}</pre>`);
1632
+ return echo.join('') + this._getEnd();
1633
+ }
1634
+ netFollow1() {
1635
+ this._location('test/net-follow2');
1636
+ }
1637
+ netFollow2() {
1638
+ return [1, { 'post': this._post['a'] + ',' + this._post['b'] }];
1639
+ }
1640
+ async netReuse() {
1641
+ const echo = [];
1642
+ echo.push('<strong>Reuse:</strong>');
1643
+ let time0 = Date.now();
1644
+ await lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/package.json');
1645
+ let time1 = Date.now();
1646
+ echo.push("<pre>lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/package.json');</pre>" + Math.round(time1 - time0).toString() + 'ms.');
1647
+ time0 = Date.now();
1648
+ await lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/README.md');
1649
+ time1 = Date.now();
1650
+ echo.push("<pre>lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/README.md');</pre>" + Math.round(time1 - time0).toString() + 'ms.');
1651
+ time0 = Date.now();
1652
+ await lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/LICENSE');
1653
+ time1 = Date.now();
1654
+ echo.push("<pre>lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/LICENSE');</pre>" + Math.round(time1 - time0).toString() + 'ms.<hr>');
1655
+ return echo.join('') + this._getEnd();
1656
+ }
1657
+ async netError() {
1658
+ const echo = [];
1659
+ const res = await lNet.get('https://192.111.000.222/xxx.zzz');
1660
+ echo.push(`<pre>lNet.get('https://192.111.000.222/xxx.zzz');</pre>
1661
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1662
+ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>
1663
+ error: <pre>${JSON.stringify(res.error, null, 4)}</pre>`);
1664
+ return echo.join('') + this._getEnd();
1665
+ }
1666
+ async netHosts() {
1667
+ const echo = [];
1668
+ const res = await lNet.get('http://nodejs.org:' + this._config.const.hostport.toString() + this._config.const.urlBase + 'test', {
1669
+ 'hosts': {
1670
+ 'nodejs.org': '127.0.0.1'
1671
+ }
1672
+ });
1673
+ echo.push(`<pre>lNet.get('http://nodejs.org:${this._config.const.hostport.toString() + this._config.const.urlBase}test', {
1674
+ 'hosts': {
1675
+ 'nodejs.org': '127.0.0.1'
1676
+ }
1677
+ });</pre>
1678
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1679
+ content: <pre>${lText.htmlescape((await res.getContent())?.toString() ?? '')}</pre>
1680
+ error: <pre>${JSON.stringify(res.error, null, 4)}</pre>`);
1681
+ return echo.join('') + this._getEnd();
1682
+ }
1683
+ async netRproxy() {
1684
+ if (await lNet.rproxy(this, {
1685
+ 'test/net-rproxy/': 'https://cdn.jsdelivr.net/npm/deskrt@2.0.10/'
1686
+ })) {
1687
+ return false;
1688
+ }
1689
+ return 'Nothing';
1690
+ }
1691
+ async netMproxy() {
1692
+ const echo = [];
1693
+ const res = await lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/package.json', {
1694
+ 'mproxy': {
1695
+ 'url': this._internalUrl + 'test/net-mproxy1',
1696
+ 'auth': '123456',
1697
+ 'data': { 'test': '123' }
1698
+ }
1699
+ });
1700
+ echo.push(`<pre>lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/package.json', {
1701
+ 'mproxy': {
1702
+ 'url': '${this._internalUrl}test/net-mproxy1',
1703
+ 'auth': '123456',
1704
+ 'data': { 'test': '123' }
1705
+ }
1706
+ });</pre>
1707
+ headers: <pre>${JSON.stringify(res.headers, null, 4)}</pre>
1708
+ content: <pre>${(await res.getContent())?.toString() ?? 'null'}</pre>
1709
+ error: ${JSON.stringify(res.error)}`);
1710
+ return echo.join('') + '<br><br>' + this._getEnd();
1711
+ }
1712
+ async netMproxy1() {
1713
+ const data = lNet.mproxyData(this);
1714
+ lCore.debug('Got data', data);
1715
+ const rtn = await lNet.mproxy(this, '123456');
1716
+ if (rtn > 0) {
1717
+ return false;
1718
+ }
1719
+ return 'Nothing(' + rtn + ')';
1720
+ }
1721
+ async scan() {
1722
+ const link = await this._scanLink();
1723
+ if (!link) {
1724
+ return [0, 'Failed, link can not be connected.'];
1725
+ }
1726
+ const s = this._get['s'] ?? 'db';
1727
+ const echo = [];
1728
+ const scan = await lScan.get(link, undefined, { 'ttl': 30, 'sqlPre': this });
1729
+ const token = scan.getToken();
1730
+ echo.push(`<pre>const scan = await lScan.get(this, link, undefined, { 'ttl': 30, 'sqlPre': this });
1731
+ const token = scan.getToken();</pre>
1732
+ token: ${token ?? 'null'}<br><br>
1733
+ Scan status: <b id="status" style="color: red;">Waiting...</b><br>
1734
+ Poll count: <span id="count">0</span>, expiration date: <span id="exp"></span><br><br>
1735
+ Simulated scan URL: http://www.test.simu/scan?token=${token ?? 'null'} (QR Code can be generated)<br><br>
1736
+ <input type="button" value="Visit the simulated URL" onclick="this.disabled=true;document.getElementById('url').innerText='http://www.test.simu/scan?token=${token ?? 'null'}';visit();"><br><br>
1737
+ <div style="border: solid 1px rgba(0,0,0,.3); box-shadow: 0 5px 20px rgba(0, 0, 0, .25); width: 90%; margin: auto;">
1738
+ <div id="url" style="background: rgba(0,0,0,.07); border-bottom: solid 1px rgba(0,0,0,.3); padding: 10px;">about:blank</div>
1739
+ <div id="content" style="height: 200px; font-size: 16px; display: flex; justify-content: center; align-items: center; flex-direction: column;"></div>
1740
+ </div>
1741
+ <script>
1742
+ var token = '${token ?? 'null'}';
1743
+ var count = 0;
1744
+ function poll() {
1745
+ fetch('${this._config.const.urlBase}test/scan1?s=${s}', {
1746
+ method: 'POST',
1747
+ headers: {
1748
+ 'Content-Type': 'application/x-www-form-urlencoded'
1749
+ },
1750
+ body: 'token=${token ?? 'null'}'
1751
+ }).then(function(r) {
1752
+ return r.json();
1753
+ }).then(function(j) {
1754
+ ++count;
1755
+ document.getElementById('status').innerText = j.msg;
1756
+ document.getElementById('count').innerText = count;
1757
+ if (j.result > 0) {
1758
+ document.getElementById('exp').innerText = j.exp;
1759
+ setTimeout(poll, 1000);
1760
+ }
1761
+ }).catch(function(e) {
1762
+ ++count;
1763
+ document.getElementById('status').innerText = 'Network error.';
1764
+ document.getElementById('count').innerText = count;
1765
+ setTimeout(poll, 1000);
1766
+ });
1767
+ }
1768
+ poll();
1769
+
1770
+ function visit() {
1771
+ document.getElementById('content').innerText = 'Loading...';
1772
+ fetch('${this._config.const.urlBase}test/scan2?s=${s}', {
1773
+ method: 'POST',
1774
+ headers: {
1775
+ 'Content-Type': 'application/x-www-form-urlencoded'
1776
+ },
1777
+ body: 'token=${token ?? 'null'}'
1778
+ }).then(function(r) {
1779
+ return r.json();
1780
+ }).then(function(j) {
1781
+ if (j.result > 0) {
1782
+ document.getElementById('content').innerHTML = 'Are you sure logged in the computer?<br><br><button id="confirm" style="padding: 10px 20px;" onclick="this.disabled=true;confirm()">Confirm</button>';
1783
+ }
1784
+ else {
1785
+ document.getElementById('content').innerText = j.msg;
1786
+ }
1787
+ });
1788
+ }
1789
+
1790
+ function confirm() {
1791
+ fetch('${this._config.const.urlBase}test/scan3?s=${s}', {
1792
+ method: 'POST',
1793
+ headers: {
1794
+ 'Content-Type': 'application/x-www-form-urlencoded'
1795
+ },
1796
+ body: 'token=${token ?? 'null'}'
1797
+ }).then(function(r) {
1798
+ return r.json();
1799
+ }).then(function(j) {
1800
+ if (j.result > 0) {
1801
+ document.getElementById('content').innerText = 'Finish the operation!';
1802
+ }
1803
+ else {
1804
+ document.getElementById('content').innerText = j.msg;
1805
+ }
1806
+ });
1807
+ }
1808
+ </script>`);
1809
+ return '<a href="' + this._config.const.urlBase + 'test/scan?s=db">db</a> | ' +
1810
+ '<a href="' + this._config.const.urlBase + 'test/scan?s=kv">kv</a> | ' +
1811
+ '<a href="' + this._config.const.urlBase + 'test">Return</a>' + echo.join('') + '<br>' + this._getEnd();
1812
+ }
1813
+ async scan1() {
1814
+ const link = await this._scanLink();
1815
+ if (!link) {
1816
+ return [0, 'Failed, link can not be connected.'];
1817
+ }
1818
+ const scan = await lScan.get(link, this._post['token'], {
1819
+ 'sqlPre': this
1820
+ });
1821
+ const rtn = await scan.poll();
1822
+ switch (rtn) {
1823
+ case -3: {
1824
+ return [0, 'System error.'];
1825
+ }
1826
+ case -2: {
1827
+ return [0, 'Token has expired.'];
1828
+ }
1829
+ case -1: {
1830
+ return [1, 'Waiting...', { 'exp': scan.getTimeLeft() }];
1831
+ }
1832
+ case 0: {
1833
+ return [1, 'Scanned, waiting for confirmation...', { 'exp': scan.getTimeLeft() }];
1834
+ }
1835
+ }
1836
+ return [0, 'Scan result: ' + JSON.stringify(rtn)];
1837
+ }
1838
+ async scan2() {
1839
+ const link = await this._scanLink();
1840
+ if (!link) {
1841
+ return [0, 'Failed, link can not be connected.'];
1842
+ }
1843
+ if (!await lScan.scanned(link, this._post['token'], {
1844
+ 'sqlPre': this
1845
+ })) {
1846
+ return [0, 'Token has expired.'];
1847
+ }
1848
+ return [1];
1849
+ }
1850
+ async scan3() {
1851
+ const link = await this._scanLink();
1852
+ if (!link) {
1853
+ return [0, 'Failed, link can not be connected.'];
1854
+ }
1855
+ if (!await lScan.setData(link, this._post['token'], {
1856
+ 'uid': '5'
1857
+ }, {
1858
+ 'sqlPre': this
1859
+ })) {
1860
+ return [0, 'Token has expired.'];
1861
+ }
1862
+ return [1];
1863
+ }
1864
+ async _scanLink() {
1865
+ const s = this._get['s'] ?? 'db';
1866
+ let link;
1867
+ if (s === 'db') {
1868
+ const db = lDb.get(this);
1869
+ link = db;
1870
+ }
1871
+ else {
1872
+ const kv = lKv.get(this);
1873
+ if (!await kv.ping()) {
1874
+ return false;
1875
+ }
1876
+ link = kv;
1877
+ }
1878
+ return link;
1879
+ }
1880
+ async session() {
1881
+ const retur = [];
1882
+ if (!(this._checkInput(this._get, {
1883
+ 's': ['require', ['db', 'kv'], [0, 'Object not found.']],
1884
+ 'auth': [['', '1'], [0, 'Bad request.']],
1885
+ 'value': []
1886
+ }, retur))) {
1887
+ return retur;
1888
+ }
1889
+ const echo = ['<pre>'];
1890
+ let link;
1891
+ if (this._get['s'] === 'db') {
1892
+ link = lDb.get(this);
1893
+ echo.push('link = lDb.get(this);\n');
1894
+ }
1895
+ else {
1896
+ link = lKv.get(this);
1897
+ if (!await link.ping()) {
1898
+ return [0, 'Failed, Redis can not be connected.'];
1899
+ }
1900
+ echo.push('link = lKv.get(this);\n');
1901
+ }
1902
+ if (this._get['auth'] === '') {
1903
+ await this._startSession(link, false, { 'ttl': 60 });
1904
+ echo.push(`await this._startSession(link, false, {'ttl': 60});
1905
+ JSON.stringify(this._session);</pre>` + lText.htmlescape(JSON.stringify(this._session)));
1906
+ this._session['value'] = this._get['value'] ? this._get['value'] : 'ok';
1907
+ echo.push(`<pre>this._session['value'] = '${this._get['value'] ? this._get['value'] : 'ok'}';
1908
+ JSON.stringify(this._session);</pre>` + lText.htmlescape(JSON.stringify(this._session)));
1909
+ return '<a href="' + this._config.const.urlBase + 'test/session?s=' + this._get['s'] + '">Default</a> | ' +
1910
+ '<a href="' + this._config.const.urlBase + 'test/session?s=' + this._get['s'] + '&value=aaa">Set "aaa"</a> | ' +
1911
+ '<a href="' + this._config.const.urlBase + 'test/session?s=' + this._get['s'] + '&value=bbb">Set "bbb"</a> | ' +
1912
+ '<a href="' + this._config.const.urlBase + 'test">Return</a>' + echo.join('') + '<br><br>' + this._getEnd();
1913
+ }
1914
+ else {
1915
+ await this._startSession(link, true, { 'ttl': 60 });
1916
+ if (Object.keys(this._post).length > 0) {
1917
+ if (this._session['count'] === undefined) {
1918
+ this._session['count'] = 1;
1919
+ }
1920
+ else {
1921
+ ++this._session['count'];
1922
+ }
1923
+ return [1, { 'txt': 'this._session: ' + JSON.stringify(this._session) + '\nToken: ' + this._sess.getToken(), 'token': this._sess?.getToken(), '_auth': this._getBasicAuth('token', this._sess.getToken()) }];
1924
+ }
1925
+ else {
1926
+ echo.push(`await this._startSession(link, true, {'ttl': 60});
1927
+ JSON.stringify(this._session));</pre>` + lText.htmlescape(JSON.stringify(this._session)));
1928
+ this._session['value'] = lTime.format(this, 'H:i:s');
1929
+ echo.push(`<pre>this._session['value'] = '${lTime.format(this, 'H:i:s')}';
1930
+ JSON.stringify(this._session);</pre>` + lText.htmlescape(JSON.stringify(this._session)));
1931
+ echo.push(`<br><br><input type="button" value="Post with header" onclick="document.getElementById('result').innerText='Waiting...';fetch('${this._config.const.urlBase}test/session?s=${this._get['s']}&auth=1',{method:'POST',credentials:'omit',headers:{'Authorization':document.getElementById('_auth').innerText,'content-type':'application/x-www-form-urlencoded'},body:'key=val'}).then(function(r){return r.json();}).then(function(j){document.getElementById('result').innerText=j.txt;document.getElementById('token').innerText=j.token;document.getElementById('_auth').innerText=j._auth;});"><input type='button' value="Post without header" style="margin-left: 10px;" onclick="document.getElementById('result').innerText='Waiting...';fetch('${this._config.const.urlBase}test/session?s=${this._get['s']}&auth=1',{method:'POST',credentials:'omit',headers:{'content-type':'application/x-www-form-urlencoded'},body:'key=val'}).then(function(r){return r.json();}).then(function(j){document.getElementById('result').innerText=j.txt;});"><br><br>
1932
+ Token: <span id="token">${this._sess.getToken()}</span><br>
1933
+ Post Authorization header: <span id="_auth">${this._getBasicAuth('token', this._sess.getToken())}</span><br><br>
1934
+ Result:<pre id="result">Nothing.</pre>`);
1935
+ return '<a href="' + this._config.const.urlBase + 'test">Return</a>' + echo.join('') + this._getEnd();
1936
+ }
1937
+ }
1938
+ }
1939
+ async jwt() {
1940
+ const retur = [];
1941
+ if (!(this._checkInput(this._get, {
1942
+ 'type': [['', 'kv', 'auth'], [0, 'Bad request.']]
1943
+ }, retur))) {
1944
+ return retur;
1945
+ }
1946
+ const echo = ['<pre>'];
1947
+ let link = undefined;
1948
+ if (this._get['type'] === 'kv') {
1949
+ link = lKv.get(this);
1950
+ echo.push('link = lKv.get(this);\n');
1951
+ }
1952
+ const origin = lJwt.getOrigin(this);
1953
+ echo.push(`const origin = lJwt.getOrigin(this);
1954
+ JSON.stringify(origin);</pre>`);
1955
+ echo.push(JSON.stringify(origin));
1956
+ const jwt = await lJwt.get(this, {}, link);
1957
+ echo.push(`<pre>const jwt = lJwt.get(this, {}, ${link ? 'link' : 'undefined'});
1958
+ JSON.stringify(this._jwt);</pre>`);
1959
+ echo.push(JSON.stringify(this._jwt));
1960
+ this._jwt['test'] = 'a';
1961
+ const value = jwt.renew();
1962
+ echo.push(`<pre>this._jwt['test'] = 'a';
1963
+ const value = jwt.renew();
1964
+ JSON.stringify(this._jwt);</pre>`);
1965
+ echo.push(JSON.stringify(this._jwt));
1966
+ echo.push(`<pre>JSON.stringify(value);</pre>`);
1967
+ echo.push(JSON.stringify(value));
1968
+ const token = this._jwt['token'];
1969
+ const rtn = await jwt.destory();
1970
+ echo.push(`<pre>const token = this._jwt['token'];
1971
+ const rtn = await jwt.destory();
1972
+ JSON.stringify(rtn);</pre>`);
1973
+ echo.push(JSON.stringify(rtn));
1974
+ echo.push('<pre>JSON.stringify(this._jwt);</pre>');
1975
+ echo.push(JSON.stringify(this._jwt));
1976
+ const rtn2 = await lJwt.decode(this, origin, link);
1977
+ echo.push(`<pre>const rtn2 = await lJwt.decode(this, origin, ${link ? 'link' : 'undefined'});
1978
+ JSON.stringify(rtn2);</pre>`);
1979
+ echo.push(JSON.stringify(rtn2));
1980
+ if (this._get['type'] === 'auth') {
1981
+ echo.push(`<br><br><input type="button" value="Post with header" onclick="document.getElementById('result').innerText='Waiting...';fetch('${this._config.const.urlBase}test/jwt1',{method:'POST',credentials:'omit',headers:{'Authorization':document.getElementById('_auth').innerText,'content-type':'application/x-www-form-urlencoded'},body:'key=val'}).then(function(r){return r.json();}).then(function(j){document.getElementById('result').innerText=j.txt;});"><input type='button' value="Post without header" style="margin-left: 10px;" onclick="document.getElementById('result').innerText='Waiting...';fetch('${this._config.const.urlBase}test/jwt1',{method:'POST',credentials:'omit',headers:{'content-type':'application/x-www-form-urlencoded'},body:'key=val'}).then(function(r){return r.json();}).then(function(j){document.getElementById('result').innerText=j.txt;});"><br><br>
1982
+ Token: <span id="token">${token}</span><br>
1983
+ Post Authorization header: <span id="_auth">Bearer ${origin}</span><br><br>
1984
+ Result:<pre id="result">Nothing.</pre>`);
1985
+ }
1986
+ else {
1987
+ echo.push('<br><br>');
1988
+ }
1989
+ return echo.join('') + this._getEnd();
1990
+ }
1991
+ async jwt1() {
1992
+ await lJwt.get(this, {
1993
+ 'auth': true
1994
+ });
1995
+ return [1, { 'txt': JSON.stringify(this._jwt) }];
1996
+ }
1997
+ sql() {
1998
+ const echo = [];
1999
+ let sql = lSql.get('test_');
2000
+ switch (this._get['type']) {
2001
+ case 'insert': {
2002
+ let s = sql.insert('user').values(['name', 'age'], [
2003
+ ['Ah', '16'],
2004
+ ['Bob', '24']
2005
+ ]).getSql();
2006
+ let sd = sql.getData();
2007
+ echo.push(`<pre>sql.insert('user').values(['name', 'age'], [
2008
+ ['Ah', '16'],
2009
+ ['Bob', '24']
2010
+ ]);</pre>
2011
+ <b>getSql() :</b> ${s}<br>
2012
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2013
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2014
+ s = sql.insert('user').values(['name', 'age'], ['Ah', '16']).getSql();
2015
+ sd = sql.getData();
2016
+ echo.push(`<pre>sql.insert('user').values(['name', 'age'], ['Ah', '16']);</pre>
2017
+ <b>getSql() :</b> ${s}<br>
2018
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2019
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2020
+ s = sql.insert('user').values({ 'name': 'Bob', 'age': '24' }).getSql();
2021
+ sd = sql.getData();
2022
+ echo.push(`<pre>sql.insert('user').values({ 'name': 'Bob', 'age': '24' });</pre>
2023
+ <b>getSql() :</b> ${s}<br>
2024
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2025
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2026
+ s = sql.replace('user').values({ 'token': '20200202', 'name': 'Bob' }).getSql();
2027
+ sd = sql.getData();
2028
+ echo.push(`<pre>sql.replace('user').values({ 'token': '20200202', 'name': 'Bob' });</pre>
2029
+ <b>getSql() :</b> ${s}<br>
2030
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2031
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2032
+ s = sql.insert('order').notExists('order', { 'name': 'Amy', 'age': '16', 'time_add': lTime.stamp(), 'point': ['POINT(?)', ['20']] }, { 'name': 'Amy' }).getSql();
2033
+ sd = sql.getData();
2034
+ echo.push(`<pre>sql.insert('order').notExists('order', { 'name': 'Amy', 'age': '16', 'time_add': lTime.stamp(), 'point': ['POINT(?)', ['20']] }, { 'name': 'Amy' });</pre>
2035
+ <b>getSql() :</b> ${s}<br>
2036
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2037
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2038
+ s = sql.insert('verify').values({ 'token': 'abc', 'time_update': '10' }).duplicate({ 'time_update': ['CONCAT(`time_update`, ?)', ['01']] }).getSql();
2039
+ sd = sql.getData();
2040
+ echo.push(`<pre>sql.insert('verify').values({ 'token': 'abc', 'time_update': '10' }).duplicate({ 'time_update': ['CONCAT(\`time_update\`, ?)', ['01']] });</pre>
2041
+ <b>getSql() :</b> ${s}<br>
2042
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2043
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2044
+ s = sql.insert('geo').values({ 'point': ['ST_POINTFROMTEXT(?)', ['POINT(122.147775 30.625014)']] }).getSql();
2045
+ sd = sql.getData();
2046
+ echo.push(`<pre>sql.insert('geo').values({ 'point': ['ST_POINTFROMTEXT(?)', ['POINT(122.147775 30.625014)']] });</pre>
2047
+ <b>getSql() :</b> ${s}<br>
2048
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2049
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2050
+ s = sql.insert('geo').values(['name', 'point', 'point2', 'polygon', 'json'], [
2051
+ [
2052
+ 'POINT A', ['ST_POINTFROMTEXT(?)', ['POINT(122.147775 30.625015)']], { 'x': 1, 'y': 1 }, [
2053
+ [
2054
+ { 'x': 1, 'y': 1 },
2055
+ { 'x': 2, 'y': 2 },
2056
+ { 'x': 3, 'y': 3 },
2057
+ { 'x': 1, 'y': 1 }
2058
+ ],
2059
+ [
2060
+ { 'x': 6, 'y': 1 },
2061
+ { 'x': 7, 'y': 2 },
2062
+ { 'x': 8, 'y': 3 },
2063
+ { 'x': 6, 'y': 1 }
2064
+ ]
2065
+ ],
2066
+ { 'x': { 'y': 'ghi' } }
2067
+ ],
2068
+ [
2069
+ 'POINT B', ['ST_POINTFROMTEXT(?)', ['POINT(123.147775 30.625016)']], { 'x': 1, 'y': 1 }, null, null
2070
+ ]
2071
+ ]).getSql();
2072
+ sd = sql.getData();
2073
+ echo.push(`<pre>sql.insert('geo').values(['name', 'point', 'point2', 'polygon', 'json'], [
2074
+ [
2075
+ 'POINT A', ['ST_POINTFROMTEXT(?)', ['POINT(122.147775 30.625015)']], { 'x': 1, 'y': 1 }, [
2076
+ [
2077
+ { 'x': 1, 'y': 1 },
2078
+ { 'x': 2, 'y': 2 },
2079
+ { 'x': 3, 'y': 3 },
2080
+ { 'x': 1, 'y': 1 }
2081
+ ],
2082
+ [
2083
+ { 'x': 6, 'y': 1 },
2084
+ { 'x': 7, 'y': 2 },
2085
+ { 'x': 8, 'y': 3 },
2086
+ { 'x': 6, 'y': 1 }
2087
+ ]
2088
+ ],
2089
+ { 'x': { 'y': 'ghi' } }
2090
+ ],
2091
+ [
2092
+ 'POINT B', ['ST_POINTFROMTEXT(?)', ['POINT(123.147775 30.625016)']], { 'x': 1, 'y': 1 }, null, null
2093
+ ]
2094
+ ]);</pre>
2095
+ <b>getSql() :</b> ${s}<br>
2096
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2097
+ <b>format() :</b> ${sql.format(s, sd)}`);
2098
+ break;
2099
+ }
2100
+ case 'select': {
2101
+ let s = sql.select('*', 'user').getSql();
2102
+ let sd = sql.getData();
2103
+ echo.push(`<pre>sql.select('*', 'user');</pre>
2104
+ <b>getSql() :</b> ${s}<br>
2105
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2106
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2107
+ s = sql.select(['id', 'name'], 'user').getSql();
2108
+ sd = sql.getData();
2109
+ echo.push(`<pre>sql.select(['id', 'name'], 'user');</pre>
2110
+ <b>getSql() :</b> ${s}<br>
2111
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2112
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2113
+ s = sql.select('*', ['user', 'order']).getSql();
2114
+ sd = sql.getData();
2115
+ echo.push(`<pre>sql.select('*', ['user', 'order']);</pre>
2116
+ <b>getSql() :</b> ${s}<br>
2117
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2118
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2119
+ s = sql.select('*', ['db1.user', 'db2.user']).getSql();
2120
+ sd = sql.getData();
2121
+ echo.push(`<pre>sql.select('*', ['db1.user', 'db2.user']);</pre>
2122
+ <b>getSql() :</b> ${s}<br>
2123
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2124
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2125
+ s = sql.select(['order.no', 'user.nick'], ['order']).leftJoin('user', { 'order.user_id': lSql.column('user.id'), 'state': '1' }).getSql();
2126
+ sd = sql.getData();
2127
+ echo.push(`<pre>sql.select(['order.no', 'user.nick'], ['order']).leftJoin('user', { 'order.user_id': lSql.column('user.id'), 'state': '1' });</pre>
2128
+ <b>getSql() :</b> ${s}<br>
2129
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2130
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2131
+ s = sql.select(['o.*', 'u.nick as unick'], ['order o']).leftJoin('`user` AS u', { 'o.user_id': lSql.column('u.id'), 'state': '1' }).getSql();
2132
+ sd = sql.getData();
2133
+ echo.push(`<pre>sql.select(['o.*', 'u.nick as unick'], ['order o']).leftJoin('\`user\` AS u', { 'o.user_id': lSql.column('u.id'), 'state': '1' });</pre>
2134
+ <b>getSql() :</b> ${s}<br>
2135
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2136
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2137
+ s = sql.select(['SUM(user.age) age', 'UTC_TIMESTAMP', 'FROM_UNIXTIME(user.time, \'%Y-%m\') as time'], 'order').leftJoin('user', { 'order.user_id': lSql.column('user.id') }).getSql();
2138
+ sd = sql.getData();
2139
+ echo.push(`<pre>sql.select(['SUM(user.age) age', 'UTC_TIMESTAMP', 'FROM_UNIXTIME(user.time, \\'%Y-%m\\') as time'], 'order').leftJoin('user', { 'order.user_id': lSql.column('user.id') });</pre>
2140
+ <b>getSql() :</b> ${s}<br>
2141
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2142
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2143
+ s = sql.select('*', 'order').leftJoin('user', { 'order.user_id': lSql.column('user.id') }, '_0').leftJoin('group a', { 'order.group_id': lSql.column('a.id') }, '_0').getSql();
2144
+ sd = sql.getData();
2145
+ echo.push(`<pre>sql.select('*', 'order').leftJoin('user', { 'order.user_id': lSql.column('user.id') }, '_0').leftJoin('group a', { 'order.group_id': lSql.column('a.id') }, '_0');</pre>
2146
+ <b>getSql() :</b> ${s}<br>
2147
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2148
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2149
+ s = sql.select('*', 'order').where({ 'a': 1, 'b': 2 }).unionAll(sql.copy('abc')).getSql();
2150
+ sd = sql.getData();
2151
+ echo.push(`<pre>sql.select('*', 'order').where({ 'a': 1, 'b': 2 }).unionAll(sql.copy('abc'));</pre>
2152
+ <b>getSql() :</b> ${s}<br>
2153
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2154
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2155
+ sql = sql.copy('abcd', { 'where': { 'c': 2 } });
2156
+ s = sql.getSql();
2157
+ sd = sql.getData();
2158
+ echo.push(`<pre>sql.copy('abcd', { 'where': { 'c': 2 } });</pre>
2159
+ <b>getSql() :</b> ${s}<br>
2160
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2161
+ <b>format() :</b> ${sql.format(s, sd)}`);
2162
+ break;
2163
+ }
2164
+ case 'update': {
2165
+ let s = sql.update('user', [['age', '+', '1'], ['month', '=', '5'], { 'name': 'Serene', 'nick': lSql.column('name') }, ['year', '+', lSql.column('age')]]).where({ 'name': 'Ah' }).getSql();
2166
+ let sd = sql.getData();
2167
+ echo.push(`<pre>sql.update('user', [['age', '+', '1'], ['month', '=', '5'], { 'name': 'Serene', 'nick': lSql.column('name') }, ['year', '+', lSql.column('age')]]).where({ 'name': 'Ah' });</pre>
2168
+ <b>getSql() :</b> ${s}<br>
2169
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2170
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2171
+ s = sql.update('user', { 'name': 'Serene', 'type': ['(CASE `id` WHEN 1 THEN ? WHEN 2 THEN ? END)', ['val1', 'val2']] }).where({ 'name': 'Ah' }).getSql();
2172
+ sd = sql.getData();
2173
+ echo.push(`<pre>sql.update('user', { 'name': 'Serene', 'type': ['(CASE \`id\` WHEN 1 THEN ? WHEN 2 THEN ? END)', ['val1', 'val2']] }).where({ 'name': 'Ah' });</pre>
2174
+ <b>getSql() :</b> ${s}<br>
2175
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2176
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2177
+ s = sql.update('user', { 'age': lSql.column('age_verify'), 'date': '#12', 'he': ['he2'] }).where({ 'date_birth': '2001' }).getSql();
2178
+ sd = sql.getData();
2179
+ echo.push(`<pre>sql.update('user', { 'age': lSql.column('age_verify'), 'date': '#12', 'he': ['he2'] }).where({ 'date_birth': '2001' });</pre>
2180
+ <b>getSql() :</b> ${s}<br>
2181
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2182
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2183
+ s = sql.update('user', { 'he': 'he2' }).where([['birth', '>', '2001']]).by('birth').limit(0, 10).getSql();
2184
+ sd = sql.getData();
2185
+ echo.push(`<pre>sql.update('user', { 'he': 'he2' }).where([ ['birth', '>', '2001'] ]).by('birth').limit(0, 10);</pre>
2186
+ <b>getSql() :</b> ${s}<br>
2187
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2188
+ <b>format() :</b> ${sql.format(s, sd)}`);
2189
+ s = sql.update('json', { 'json1': { 'key': 'val', 'key2': 'val2' }, 'json2': [{ 'k1': 'v1' }, { 'k2': 'v2' }], 'json3': { 'x': 1, 'y': 2 }, 'json4': [], 'json5': {} }).where({ 'id': 1 }).getSql();
2190
+ sd = sql.getData();
2191
+ echo.push(`<pre>sql.update('json', { 'json1': { 'key': 'val', 'key2': 'val2' }, 'json2': [ { 'k1': 'v1' }, { 'k2': 'v2' } ], 'json3': { 'x': 1, 'y': 2 }, 'json4': [], 'json5': {} }).where({ 'id': 1 });</pre>
2192
+ <b>getSql() :</b> ${s}<br>
2193
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2194
+ <b>format() :</b> ${sql.format(s, sd)}`);
2195
+ break;
2196
+ }
2197
+ case 'delete': {
2198
+ const s = sql.delete('user').where({ 'id': '1' }).getSql();
2199
+ const sd = sql.getData();
2200
+ echo.push(`<pre>sql.delete('user').where({ 'id': '1' });</pre>
2201
+ <b>getSql() :</b> ${s}<br>
2202
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2203
+ <b>format() :</b> ${sql.format(s, sd)}`);
2204
+ break;
2205
+ }
2206
+ case 'where': {
2207
+ let s = sql.select('*', 'user').where([{ 'city': 'la' }, ['age', '>', '10'], ['level', 'in', ['1', '2', '3']], ['age + age2 + age3 + 10', '>', 20]]).getSql();
2208
+ let sd = sql.getData();
2209
+ echo.push(`<pre>sql.select('*', 'user').where([{ 'city': 'la' }, ['age', '>', '10'], ['level', 'in', ['1', '2', '3']], ['age + age2 + age3 + 10', '>', 20]]);</pre>
2210
+ <b>getSql() :</b> ${s}<br>
2211
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2212
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2213
+ s = sql.update('order', { 'state': '1' }).where({
2214
+ '$or': [{
2215
+ 'type': '1'
2216
+ }, {
2217
+ 'type': '2'
2218
+ }],
2219
+ '$or-2': [{
2220
+ 'type2': '3'
2221
+ }, {
2222
+ 'type2': '4'
2223
+ }],
2224
+ '$or-other': [{
2225
+ 'type3': '5'
2226
+ }, {
2227
+ 'type3': '6'
2228
+ }]
2229
+ }).getSql();
2230
+ sd = sql.getData();
2231
+ echo.push(`<pre>sql.update('order', { 'state': '1' }).where({
2232
+ '$or': [{
2233
+ 'type': '1'
2234
+ }, {
2235
+ 'type': '2'
2236
+ }],
2237
+ '$or-2': [{
2238
+ 'type2': '3'
2239
+ }, {
2240
+ 'type2': '4'
2241
+ }],
2242
+ '$or-other': [{
2243
+ 'type3': '5'
2244
+ }, {
2245
+ 'type3': '6'
2246
+ }]
2247
+ });</pre>
2248
+ <b>getSql() :</b> ${s}<br>
2249
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2250
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2251
+ s = sql.update('order', { 'state': '1' }).where({
2252
+ 'user_id': '2',
2253
+ 'state': ['1', '2', '3'],
2254
+ '$or': [{ 'type': '1', 'find': '0' }, { 'type': '2', 'find': '1' }, [['type', '<', '-1']]]
2255
+ }).getSql();
2256
+ sd = sql.getData();
2257
+ echo.push(`<pre>sql.update('order', { 'state': '1' }).where({
2258
+ 'user_id': '2',
2259
+ 'state': ['1', '2', '3'],
2260
+ '$or': [{ 'type': '1', 'find': '0' }, { 'type': '2', 'find': '1' }, [['type', '<', '-1']]]
2261
+ });</pre>
2262
+ <b>getSql() :</b> ${s}<br>
2263
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2264
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2265
+ s = sql.select('*', 'user').where({
2266
+ 'time_verify': lSql.column('time_add')
2267
+ }).getSql();
2268
+ sd = sql.getData();
2269
+ echo.push(`<pre>sql.select('*', 'user').where({
2270
+ 'time_verify': lSql.column('time_add')
2271
+ });</pre>
2272
+ <b>getSql() :</b> ${s}<br>
2273
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2274
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2275
+ s = sql.delete('user').where([
2276
+ [['MATCH(name_sc, name_tc) AGAINST(?)', ['search']], '>=', '0.9']
2277
+ ]).getSql();
2278
+ sd = sql.getData();
2279
+ echo.push(`<pre>sql.delete('user').where([
2280
+ [['MATCH(name_sc, name_tc) AGAINST(?)', ['search']], '>=', '0.9']
2281
+ ]);</pre>
2282
+ <b>getSql() :</b> ${s}<br>
2283
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2284
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2285
+ s = sql.select('*', 'user').where([{ 'city': 'la', 'area': null }, ['age', '>', '10'], ['soft', '<>', null], ['ware', 'IS', null]]).getSql();
2286
+ sd = sql.getData();
2287
+ echo.push(`<pre>sql.select('*', 'user').where([{ 'city': 'la', 'area': null }, ['age', '>', '10'], ['soft', '<>', null], ['ware', 'IS', null]]);</pre>
2288
+ <b>getSql() :</b> ${s}<br>
2289
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2290
+ <b>format() :</b> ${sql.format(s, sd)}`);
2291
+ break;
2292
+ }
2293
+ case 'having': {
2294
+ let s = sql.select(['id', 'name', '(6371 * ACOS(COS(RADIANS(31.239845)) * COS(RADIANS(`lat`)) * COS(RADIANS(`lng`) - RADIANS(121.499662)) + SIN(RADIANS(31.239845)) * SIN(RADIANS(`lat`)))) AS distance'], 'location').having([
2295
+ ['distance', '<', '2']
2296
+ ]).getSql();
2297
+ let sd = sql.getData();
2298
+ echo.push(`<pre>sql.select(['id', 'name', '(6371 * ACOS(COS(RADIANS(31.239845)) * COS(RADIANS(\`lat\`)) * COS(RADIANS(\`lng\`) - RADIANS(121.499662)) + SIN(RADIANS(31.239845)) * SIN(RADIANS(\`lat\`)))) AS distance'], 'location').having([
2299
+ ['distance', '<', '2']
2300
+ ]);</pre>
2301
+ <b>getSql() :</b> ${s}<br>
2302
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2303
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2304
+ s = sql.select(['id', 'name',
2305
+ [
2306
+ '(6371 * ACOS(COS(RADIANS(?)) * COS(RADIANS(`lat`)) * COS(RADIANS(`lng`) - RADIANS(?)) + SIN(RADIANS(?)) * SIN(RADIANS(`lat`)))) AS distance',
2307
+ ['31.239845', '121.499662', '31.239845']
2308
+ ]
2309
+ ], 'location').having([
2310
+ ['distance', '<', '2']
2311
+ ]).getSql();
2312
+ sd = sql.getData();
2313
+ echo.push(`<pre>sql.select(['id', 'name',
2314
+ [
2315
+ '(6371 * ACOS(COS(RADIANS(?)) * COS(RADIANS(\`lat\`)) * COS(RADIANS(\`lng\`) - RADIANS(?)) + SIN(RADIANS(?)) * SIN(RADIANS(\`lat\`)))) AS distance',
2316
+ ['31.239845', '121.499662', '31.239845']
2317
+ ]
2318
+ ], 'location')->having([
2319
+ ['distance', '<', '2']
2320
+ ]);</pre>
2321
+ <b>getSql() :</b> ${s}<br>
2322
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2323
+ <b>format() :</b> ${sql.format(s, sd)}`);
2324
+ break;
2325
+ }
2326
+ case 'by': {
2327
+ let s = sql.select('*', 'test').by('id').getSql();
2328
+ let sd = sql.getData();
2329
+ echo.push(`<pre>sql.select('*', 'test').by('id');</pre>
2330
+ <b>getSql() :</b> ${s}<br>
2331
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2332
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2333
+ s = sql.select('*', 'test').by(['index', 'id']).getSql();
2334
+ sd = sql.getData();
2335
+ echo.push(`<pre>sql.select('*', 'test').by(['index', 'id']);</pre>
2336
+ <b>getSql() :</b> ${s}<br>
2337
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2338
+ <b>format() :</b> ${sql.format(s, sd)}<hr>`);
2339
+ s = sql.select('*', 'test').by(['index', ['id', 'ASC']], 'DESC').getSql();
2340
+ sd = sql.getData();
2341
+ echo.push(`<pre>sql.select('*', 'test').by(['index', ['id', 'ASC']], 'DESC');</pre>
2342
+ <b>getSql() :</b> ${s}<br>
2343
+ <b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
2344
+ <b>format() :</b> ${sql.format(s, sd)}`);
2345
+ break;
2346
+ }
2347
+ case 'field': {
2348
+ echo.push(`<pre>sql.field('abc');</pre>` + sql.field('abc'));
2349
+ echo.push(`<pre>sql.field('abc', 'a_');</pre>` + sql.field('abc', 'a_'));
2350
+ echo.push(`<pre>sql.field('x.abc');</pre>` + sql.field('x.abc'));
2351
+ echo.push(`<pre>sql.field('def f');</pre>` + sql.field('def f'));
2352
+ echo.push(`<pre>sql.field('def \`f\`', 'a_');</pre>` + sql.field('def `f`', 'a_'));
2353
+ echo.push(`<pre>sql.field('x.def f');</pre>` + sql.field('x.def f'));
2354
+ echo.push(`<pre>sql.field('x.def as f');</pre>` + sql.field('x.def as f'));
2355
+ echo.push(`<pre>sql.field('SUM(num) all');</pre>` + sql.field('SUM(num) all'));
2356
+ echo.push(`<pre>sql.field('SUM(x.num) all');</pre>` + sql.field('SUM(x.num) all'));
2357
+ echo.push(`<pre>sql.field('SUM(x.\`num\`) all');</pre>` + sql.field('SUM(x.`num`) all'));
2358
+ echo.push(`<pre>sql.field('FROM_UNIXTIME(time, \\'%Y-%m-%d\\') time');</pre>` + sql.field('FROM_UNIXTIME(time, \'%Y-%m-%d\') time'));
2359
+ echo.push(`<pre>sql.field('(6371 * ACOS(COS(RADIANS(31.239845)) * COS(RADIANS(lat)) * COS(RADIANS(\`lng\`) - RADIANS(121.499662)) + SIN(RADIANS(31.239845)) * SIN(RADIANS(\`lat\`))))');</pre>` + sql.field('(6371 * ACOS(COS(RADIANS(31.239845)) * COS(RADIANS(lat)) * COS(RADIANS(`lng`) - RADIANS(121.499662)) + SIN(RADIANS(31.239845)) * SIN(RADIANS(`lat`))))'));
2360
+ echo.push(`<pre>sql.field('MATCH(name_sc, name_tc) AGAINST("ok") tmp'));</pre>` + sql.field('MATCH(name_sc, name_tc) AGAINST("ok") tmp'));
2361
+ echo.push(`<pre>sql.field('a\\'bc');</pre>` + sql.field('a\'bc'));
2362
+ echo.push(`<pre>sql.field('\`a\`WHERE\`q\` = SUM(0) AND \`b\` = "abc" LEFT JOIN \`abc\`');</pre>` + sql.field('`a`WHERE`q` = SUM(0) AND `b` = "abc" LEFT JOIN `abc`'));
2363
+ echo.push(`<pre>sql.field('TEST(UTC_TIMESTAMP)');</pre>` + sql.field('TEST(UTC_TIMESTAMP)'));
2364
+ echo.push(`<pre>sql.field('a + b + 10 + c');</pre>` + sql.field('a + b + 10 + c'));
2365
+ echo.push(`<pre>sql.field('*');</pre>` + sql.field('*'));
2366
+ break;
2367
+ }
2368
+ }
2369
+ return echo.join('') + '<br><br>' + this._getEnd();
2370
+ }
2371
+ consistentHash() {
2372
+ const echo = [];
2373
+ echo.push(`<pre>lConsistent.hash('abc');</pre>` + lConsistent.hash('abc').toString());
2374
+ echo.push(`<pre>lConsistent.hash('thisisnone');</pre>` + lConsistent.hash('thisisnone').toString());
2375
+ echo.push(`<pre>lConsistent.hash('haha');</pre>` + lConsistent.hash('haha').toString());
2376
+ return echo.join('') + '<br><br>' + this._getEnd();
2377
+ }
2378
+ consistentDistributed() {
2379
+ const echo = [];
2380
+ const servers = ['srv-sh.test.simu', 'srv-cd.test.simu', 'srv-tk.test.simu'];
2381
+ const files = [8, 12, 18, 32, 89, 187, 678, 1098, 3012, 8901, 38141, 76291, 99981];
2382
+ const map = {};
2383
+ const cons = lConsistent.get();
2384
+ cons.add(servers);
2385
+ for (const file of files) {
2386
+ map[file] = cons.find(file);
2387
+ }
2388
+ echo.push(`<pre>const servers = ['srv-sh.test.simu', 'srv-cd.test.simu', 'srv-tk.test.simu'];
2389
+ const files = [8, 12, 18, 32, 89, 187, 678, 1098, 3012, 8901, 38141, 76291, 99981];
2390
+ const map: Record<string, string | null> = {};
2391
+ const cons = lConsistent.get();
2392
+ cons.add(servers);
2393
+ for (const file of files) {
2394
+ map[file] = cons.find(file);
2395
+ }</pre>`);
2396
+ echo.push('<table style="width: 100%;">');
2397
+ for (const k in map) {
2398
+ const v = map[k];
2399
+ echo.push('<tr><th>' + lText.htmlescape(k) + '</th><td>' + lText.htmlescape(v ?? 'null') + ' (' + lConsistent.hash(k).toString() + ')</td></tr>');
2400
+ }
2401
+ echo.push('</table>');
2402
+ cons.add('srv-sg.test.simu');
2403
+ const file = files[lCore.rand(0, files.length - 1)];
2404
+ const oldSrv = map[file];
2405
+ const newSrv = cons.find(file);
2406
+ echo.push(`<pre>cons.add('srv-sg.test.simu');
2407
+ const file = files[lText.rand(0, files.length - 1)];
2408
+ const oldSrv = map[file];
2409
+ const newSrv = cons.find(file);</pre>`);
2410
+ echo.push(`<table style="width: 100%;">
2411
+ <tr><th>File</th><td>${file}</td></tr>
2412
+ <tr><th>Old</th><td>${oldSrv ?? 'null'}</td></tr>
2413
+ <tr><th>New</th><td>${newSrv ?? 'null'}</td></tr>
2414
+ <tr><th>State</th><td>${((oldSrv === newSrv) ? '<b>Hit</b>' : 'Miss')}</td></tr>
2415
+ </table>`);
2416
+ return echo.join('') + '<br>' + this._getEnd();
2417
+ }
2418
+ consistentMigration() {
2419
+ const echo = [];
2420
+ const tables = ['table-0', 'table-1', 'table-2', 'table-3', 'table-4'];
2421
+ const rows = [];
2422
+ for (let i = 1; i <= 5000; ++i) {
2423
+ rows.push(i);
2424
+ }
2425
+ const cons = lConsistent.get();
2426
+ cons.add(tables);
2427
+ echo.push('Row length: ' + rows.length.toString() + '<br>Old tables:');
2428
+ for (const table of tables) {
2429
+ echo.push(' ' + table);
2430
+ }
2431
+ echo.push(`<pre>const newTables = ['table-5', 'table-6', 'table-7', 'table-8', 'table-9'];
2432
+ const rtn = cons.migration(rows, newTables);</pre>`);
2433
+ const newTables = ['table-5', 'table-6', 'table-7', 'table-8', 'table-9'];
2434
+ const rtn = cons.migration(rows, newTables);
2435
+ const count = Object.keys(rtn).length;
2436
+ echo.push('Migration length: ' + count.toString() + '<br>Added new tables: ');
2437
+ for (const table of newTables) {
2438
+ echo.push(' ' + table);
2439
+ }
2440
+ echo.push('<br><br>');
2441
+ let i = 0;
2442
+ echo.push('<table style="width: 100%;">');
2443
+ for (const key in rtn) {
2444
+ const item = rtn[key];
2445
+ echo.push('<tr><th>' + key + '</th><td>' + item.old + '</td><td>' + item.new + '</td></tr>');
2446
+ if (i === 199) {
2447
+ break;
2448
+ }
2449
+ ++i;
2450
+ }
2451
+ echo.push('</table>');
2452
+ return echo.join('') + '... More ' + (count - 200).toString() + ' ...<br><br>' + this._getEnd();
2453
+ }
2454
+ consistentFast() {
2455
+ const echo = [];
2456
+ let rtn = lConsistent.fast('a', lConsistent.getRange(0, 30));
2457
+ echo.push(`<pre>Consistent.fast('a', lConsistent.getRange(0, 30))</pre>`);
2458
+ echo.push(JSON.stringify(rtn));
2459
+ rtn = lConsistent.fast('b', lConsistent.getRange(0, 30));
2460
+ echo.push(`<pre>Consistent.fast('b', lConsistent.getRange(0, 30))</pre>`);
2461
+ echo.push(JSON.stringify(rtn));
2462
+ return echo.join('') + '<br><br>' + this._getEnd();
2463
+ }
2464
+ text() {
2465
+ const echo = `<pre>json_encode(lText.parseUrl('HtTp://uSer:pAss@sUBDom.TopdOm23.CoM:29819/Adm@xw2Ksiz/dszas?Mdi=KdiMs1&a=JDd#hehHe'))</pre>
2466
+ ${lText.htmlescape(JSON.stringify(lText.parseUrl('HtTp://uSer:pAss@sUBDom.TopdOm23.CoM:29819/Adm@xw2Ksiz/dszas?Mdi=KdiMs1&a=JDd#hehHe')))}
2467
+ <pre>json_encode(lText.parseUrl('HtTp://uSer@sUBDom.TopdOm23.CoM/Admx%20w2Ksiz/dszas'))</pre>
2468
+ ${lText.htmlescape(JSON.stringify(lText.parseUrl('HtTp://uSer@sUBDom.TopdOm23.CoM/Admx%20w2Ksiz/dszas')))}
2469
+ <pre>json_encode(lText.parseUrl('C:\\Windows\\Mi@sc'))</pre>
2470
+ ${lText.htmlescape(JSON.stringify(lText.parseUrl('C:\\Windows\\Mi@sc')))}
2471
+ <pre>json_encode(lText.parseUrl('../../abc?q=e'))</pre>
2472
+ ${lText.htmlescape(JSON.stringify(lText.parseUrl('../../abc?q=e')))}
2473
+ <pre>lText.urlResolve('/', 'path?id=1');</pre>
2474
+ ${lText.htmlescape(lText.urlResolve('/', 'path?id=1'))}
2475
+ <pre>lText.urlResolve('https://www.url.com/view/path', 'find');</pre>
2476
+ ${lText.htmlescape(lText.urlResolve('https://www.url.com/view/path', 'find'))}
2477
+ <pre>lText.urlResolve('https://www.url.com/view/path', '/');</pre>
2478
+ ${lText.htmlescape(lText.urlResolve('https://www.url.com/view/path', '/'))}
2479
+ <pre>lText.urlResolve('https://www.url.com/view/path/oh', '../ok/./index.js');</pre>
2480
+ ${lText.htmlescape(lText.urlResolve('https://www.url.com/view/path/oh', '../ok/./index.js'))}
2481
+ <pre>lText.urlResolve('https://www.url.com/view/path/oh', '../hah/../dodo/../112/666/777/../en');</pre>
2482
+ ${lText.htmlescape(lText.urlResolve('https://www.url.com/view/path/oh', '../hah/../dodo/../112/666/777/../en'))}
2483
+ <pre>lText.urlResolve('/hehe/ooo/', '../../../../../index.html');</pre>
2484
+ ${lText.htmlescape(lText.urlResolve('/hehe/ooo/', '../../../../../index.html'))}
2485
+ <pre>lText.urlResolve('https://www.url.com/view/path', '/xxx/yyy');</pre>
2486
+ ${lText.htmlescape(lText.urlResolve('https://www.url.com/view/path', '/xxx/yyy'))}
2487
+ <pre>lText.urlResolve('/', '//www.url.com/path');</pre>
2488
+ ${lText.htmlescape(lText.urlResolve('/', '//www.url.com/path'))}
2489
+ <pre>lText.urlResolve('http://www.url.com/path', 'hTtps://www.url.com/path');</pre>
2490
+ ${lText.htmlescape(lText.urlResolve('http://www.url.com/path', 'hTtps://www.url.com/path'))}
2491
+ <pre>lText.urlResolve('hTtp://www.url.com/path?ok=b', '?do=some');</pre>
2492
+ ${lText.htmlescape(lText.urlResolve('hTtp://www.url.com/path?ok=b', '?do=some'))}
2493
+ <pre>lText.urlResolve('/', 'C:\\Windows\\Boot');</pre>
2494
+ ${lText.htmlescape(lText.urlResolve('/', 'C:\\Windows\\Boot'))}
2495
+ <pre>lText.urlResolve('C:\\Windows\\Misc', '/');</pre>
2496
+ ${lText.htmlescape(lText.urlResolve('C:\\Windows\\Misc', '/'))}
2497
+ <pre>lText.urlResolve('C:\\Windows\\Misc', '/xxx/yyy');</pre>
2498
+ ${lText.htmlescape(lText.urlResolve('C:\\Windows\\Misc', '/xxx/yyy'))}
2499
+ <pre>lText.urlResolve('/abc/def/', '');</pre>
2500
+ ${lText.htmlescape(lText.urlResolve('/abc/def/', ''))}
2501
+ <pre>lText.isEMail('test@gmail.com');</pre>
2502
+ ${JSON.stringify(lText.isEMail('test@gmail.com'))}
2503
+ <pre>lText.isEMail('test@x');</pre>
2504
+ ${JSON.stringify(lText.isEMail('test@x'))}
2505
+ <pre>lText.isIPv4('192.168.0.1');</pre>
2506
+ ${JSON.stringify(lText.isIPv4('192.168.0.1'))}
2507
+ <pre>lText.isIPv4('192.168.0');</pre>
2508
+ ${JSON.stringify(lText.isIPv4('192.168.0'))}
2509
+ <pre>lText.isIPv6(':');</pre>
2510
+ ${JSON.stringify(lText.isIPv6(':'))}
2511
+ <pre>lText.isIPv6('::');</pre>
2512
+ ${JSON.stringify(lText.isIPv6('::'))}
2513
+ <pre>lText.isIPv6('::1');</pre>
2514
+ ${JSON.stringify(lText.isIPv6('::1'))}
2515
+ <pre>lText.isIPv6('::FFFF:C0A8:0201');</pre>
2516
+ ${JSON.stringify(lText.isIPv6('::FFFF:C0A8:0201'))}
2517
+ <pre>lText.isIPv6('2031:0000:1F1F:0000:0000:0100:11A0:ADDF');</pre>
2518
+ ${JSON.stringify(lText.isIPv6('2031:0000:1F1F:0000:0000:0100:11A0:ADDF'))}
2519
+ <pre>lText.isIPv6('2031:0000:1F1F:0000:0000:0100:11A0:ADDF:AZ');</pre>
2520
+ ${JSON.stringify(lText.isIPv6('2031:0000:1F1F:0000:0000:0100:11A0:ADDF:AZ'))}
2521
+ <pre>lText.isIPv6('::FFFF:192.168.0.1');</pre>
2522
+ ${JSON.stringify(lText.isIPv6('::FFFF:192.168.0.1'))}
2523
+ <pre>lText.isDomain('::FFFF:192.168.0.1');</pre>
2524
+ ${JSON.stringify(lText.isDomain('::FFFF:192.168.0.1'))}
2525
+ <pre>lText.isDomain('www.xxx.com.cn');</pre>
2526
+ ${JSON.stringify(lText.isDomain('www.xxx.com.cn'))}
2527
+ <pre>lText.isDomain('com');</pre>
2528
+ ${JSON.stringify(lText.isDomain('com'))}
2529
+ <pre>lText.parseDomain('www.xxx.com.cn');</pre>
2530
+ ${JSON.stringify(lText.parseDomain('www.xxx.com.cn'))}
2531
+ <pre>lText.parseDomain('www.xxx.us');</pre>
2532
+ ${JSON.stringify(lText.parseDomain('www.xxx.us'))}
2533
+ <pre>lText.parseDomain('xxx.co.jp');</pre>
2534
+ ${JSON.stringify(lText.parseDomain('xxx.co.jp'))}
2535
+ <pre>lText.parseDomain('js.cn');</pre>
2536
+ ${JSON.stringify(lText.parseDomain('js.cn'))}
2537
+ <pre>lText.parseDomain('xxx.cn');</pre>
2538
+ ${JSON.stringify(lText.parseDomain('xxx.cn'))}
2539
+ <pre>lText.parseJson('{"num":90071992547409993149,"num2":3242354,"num3":"16565","str":"abc","bool":false}');</pre>
2540
+ ${lText.stringifyJson(lText.parseJson('{"num":90071992547409993149,"num2":3242354,"num3":"16565","str":"abc","bool":false}'))}
2541
+ <pre>lText.isIdCardCN('110101200007284901')</pre>
2542
+ ${JSON.stringify(lText.isIdCardCN('110101200007284901'))}`;
2543
+ return echo + '<br><br>' + this._getEnd();
2544
+ }
2545
+ time() {
2546
+ const echo = `<pre>lTime.format(this, 'Y-m-d H:i:s');</pre>
2547
+ ${lTime.format(this, 'Y-m-d H:i:s')}
2548
+ <pre>lTime.format(0, 'Y-m-d H:i:s');</pre>
2549
+ ${lTime.format(0, 'Y-m-d H:i:s')}
2550
+ <pre>lTime.format(null, 'Y-m-d H:i:s');</pre>
2551
+ ${lTime.format(null, 'Y-m-d H:i:s')}
2552
+ <pre>lTime.format(9, 'Y-m-d H:i:s');</pre>
2553
+ ${lTime.format(9, 'Y-m-d H:i:s')}
2554
+ <pre>lTime.format(9.5, 'Y-m-d H:i:s');</pre>
2555
+ ${lTime.format(9.5, 'Y-m-d H:i:s')}
2556
+ <pre>lTime.format(null, 'd|D|j|l|N|w|Y|y|F|M|m|H|h|i|s|T');</pre>
2557
+ ${lTime.format(null, 'd|D|j|l|N|w|Y|y|F|M|m|H|h|i|s|T')}`;
2558
+ return echo + '<br><br>' + this._getEnd();
2559
+ }
2560
+ wsServer() {
2561
+ const echo = '<a href="' + this._config.const.urlBase + 'test/ws-server">Default</a> | ' +
2562
+ '<a href="' + this._config.const.urlBase + 'test/ws-server?ac=rproxy">rproxy</a> | ' +
2563
+ '<a href="' + this._config.const.urlBase + 'test">Return</a><br><br>' +
2564
+ `Nick: <input id="nick"> <input id="btn" type="button" value="Enter" onclick="enter()"> <input id="stop" type="button" value="Stop" onclick="stop()" disabled>
2565
+ <div id="list" style="border: solid 1px #000; line-height: 1.5; height: 300px; overflow-y: scroll; margin-top: 10px; padding: 10px;"></div>
2566
+ <div style="margin-top: 10px; display: flex;">
2567
+ <input id="text" style="flex: 1;">
2568
+ <input id="send" type="button" value="Send" onclick="send()" disabled style="margin-left: 10px;">
2569
+ </div>
2570
+ <script>
2571
+ var ws = null;
2572
+ var nickEl = document.getElementById('nick');
2573
+ var listEl = document.getElementById('list');
2574
+ var btnEl = document.getElementById('btn');
2575
+ var stopEl = document.getElementById('stop');
2576
+
2577
+ var textEl = document.getElementById('text');
2578
+ var sendEl = document.getElementById('send');
2579
+ function enter() {
2580
+ var nick = nickEl.value.trim();
2581
+ if (nick === '') {
2582
+ alert('Must input nick.');
2583
+ return;
2584
+ }
2585
+ nickEl.disabled = true;
2586
+ btnEl.disabled = true;
2587
+ listEl.insertAdjacentHTML('afterbegin', '<div>Connecting...</div>');
2588
+ ws = new WebSocket('ws${this._config.const.https ? 's' : ''}://${this._config.const.host}/${this._get['ac'] === 'rproxy' ? 'rproxy' : 'test'}');
2589
+ ws.onopen = function() {
2590
+ listEl.insertAdjacentHTML('afterbegin', '<div>Event: onOpen.</div>');
2591
+ ws.send('Hello: ' + nick);
2592
+ listEl.insertAdjacentHTML('afterbegin', '<div>Client: send "Hello: ' + nick + '".</div>');
2593
+ stopEl.disabled = false;
2594
+ sendEl.disabled = false;
2595
+ };
2596
+ ws.onmessage = function(ev) {
2597
+ listEl.insertAdjacentHTML('afterbegin', '<div>Server: ' + ev.data + '.</div>');
2598
+ };
2599
+ ws.onclose = function() {
2600
+ listEl.insertAdjacentHTML('afterbegin', '<div>Event: onClose.</div>');
2601
+ nickEl.disabled = false;
2602
+ btnEl.disabled = false;
2603
+ stopEl.disabled = true;
2604
+ sendEl.disabled = true;
2605
+ };
2606
+ ws.onerror = function(ev) {
2607
+ listEl.insertAdjacentHTML('afterbegin', '<div>Event: onError.</div>');
2608
+ nickEl.disabled = false;
2609
+ btnEl.disabled = false;
2610
+ stopEl.disabled = true;
2611
+ sendEl.disabled = true;
2612
+ };
2613
+ }
2614
+ function stop() {
2615
+ ws.close();
2616
+ ws = null;
2617
+ }
2618
+ function send() {
2619
+ ws.send(textEl.value);
2620
+ textEl.value = '';
2621
+ }
2622
+ </script>`;
2623
+ return echo + '<br>' + this._getEnd();
2624
+ }
2625
+ async wsClient() {
2626
+ const ws = await lWs.connect('ws' + (this._config.const.https ? 's' : '') + '://' + this._config.const.host + '/test', {
2627
+ 'mproxy': this._get['ac'] === 'mproxy' ? {
2628
+ 'url': `ws${this._config.const.https ? 's' : ''}://${this._config.const.host}/mproxy`,
2629
+ 'auth': '123456'
2630
+ } : undefined
2631
+ });
2632
+ if (!ws) {
2633
+ return '<div>Connect "ws' + (this._config.const.https ? 's' : '') + '://' + this._config.const.host + '/test" failed.</div><br>' + this._getEnd();
2634
+ }
2635
+ const echo = ['<div>Connected "ws' + (this._config.const.https ? 's' : '') + '://' + this._config.const.host + '/test".</div>'];
2636
+ await new Promise((resolve) => {
2637
+ (async () => {
2638
+ ws.on('message', (frame) => {
2639
+ echo.push('<div>Server: ' + frame.data.toString() + '.</div>');
2640
+ });
2641
+ ws.on('close', () => {
2642
+ resolve();
2643
+ });
2644
+ ws.writeText('Hello: clientws');
2645
+ echo.push('<div>Client: send "Hello: clientws".</div>');
2646
+ await lCore.sleep(1000);
2647
+ ws.writeText('aaa');
2648
+ await lCore.sleep(1000);
2649
+ ws.writeText('abc');
2650
+ await lCore.sleep(1000);
2651
+ ws.writeText('ok');
2652
+ await lCore.sleep(1000);
2653
+ ws.end();
2654
+ })().catch(() => {
2655
+ });
2656
+ });
2657
+ return echo.join('') + '<br>' + this._getEnd();
2658
+ }
2659
+ async ssh() {
2660
+ const retur = [];
2661
+ if (!(this._checkInput(this._get, {
2662
+ 'type': ['require', ['shell', 'sftp'], [0, 'Type not found.']]
2663
+ }, retur))) {
2664
+ return retur;
2665
+ }
2666
+ const host = '1.1.1.1';
2667
+ const port = 22;
2668
+ const user = 'root';
2669
+ const pwd = 'xxx';
2670
+ let ms = Date.now();
2671
+ const ssh = await lSsh.get({
2672
+ 'host': host,
2673
+ 'port': port,
2674
+ 'username': user,
2675
+ 'password': pwd
2676
+ });
2677
+ const echo = [
2678
+ `<pre>const ssh = await lSsh.get({
2679
+ 'host': '${host}',
2680
+ 'port': ${port},
2681
+ 'username': '${user}',
2682
+ 'password': '${pwd}'
2683
+ });</pre>`
2684
+ ];
2685
+ if (!ssh) {
2686
+ echo.push('Connection failed.');
2687
+ return echo.join('') + '<br><br>' + this._getEnd();
2688
+ }
2689
+ echo.push(`Connection successful, ${Date.now() - ms}ms.`);
2690
+ echo.push(`<pre>const rtn = await ssh.exec('ls');</pre>`);
2691
+ const rtn = await ssh.exec('ls');
2692
+ if (!rtn) {
2693
+ echo.push('Execution failed.');
2694
+ return echo.join('') + '<br><br>' + this._getEnd();
2695
+ }
2696
+ echo.push(lText.htmlescape(rtn.toString()));
2697
+ if (this._get['type'] === 'shell') {
2698
+ ms = Date.now();
2699
+ const shell = await ssh.getShell();
2700
+ echo.push(`<pre>const shell = await ssh.getShell();</pre>`);
2701
+ if (!shell) {
2702
+ echo.push(`Get failed.`);
2703
+ return echo.join('') + '<br><br>' + this._getEnd();
2704
+ }
2705
+ echo.push(`Get successful, ${Date.now() - ms}ms:<pre>${lText.htmlescape((await shell.getContent()).toString())}</pre>`);
2706
+ ms = Date.now();
2707
+ await shell.sendLine('cd ../../');
2708
+ echo.push(`await shell.sendLine('cd ../../'), ${Date.now() - ms}ms:<pre>${lText.htmlescape((await shell.getContent()).toString())}</pre>`);
2709
+ await shell.sendLine('ls');
2710
+ ms = Date.now();
2711
+ echo.push(`await shell.sendLine('ls'), ${Date.now() - ms}ms:<pre>${lText.htmlescape((await shell.getContent()).toString())}</pre>`);
2712
+ await shell.close();
2713
+ }
2714
+ else {
2715
+ ms = Date.now();
2716
+ const sftp = await ssh.getSftp();
2717
+ echo.push(`<pre>const sftp = await ssh.getSftp();</pre>`);
2718
+ if (!sftp) {
2719
+ echo.push(`Get failed.`);
2720
+ return echo.join('') + '<br><br>' + this._getEnd();
2721
+ }
2722
+ echo.push(`Get successful, ${Date.now() - ms}ms, ${sftp.pwd()}:`);
2723
+ const list = await sftp.readDir('./');
2724
+ echo.push(`<table width="100%"><tr><th>Name</th><th>Size</th><th>Uid</th><th>Gid</th><th>PMSN</th><th>Mode</th><th>Atime</th><th>Mtime</th></tr>`);
2725
+ for (const item of list) {
2726
+ echo.push(`<tr><td>${item.filename}</td><td>${lText.sizeFormat(item.attrs.size)}</td><td>${item.attrs.uid}</td><td>${item.attrs.gid}</td><td>${item.attrs.mode}</td><td>${item.attrs.mode.toString(8).slice(-4)}</td><td>${lTime.format(this, 'Y-m-d H:i:s', new Date(item.attrs.atime * 1000))}</td><td>${lTime.format(this, 'Y-m-d H:i:s', new Date(item.attrs.mtime * 1000))}</td></tr>`);
2727
+ }
2728
+ echo.push(`</table><br>`);
2729
+ }
2730
+ ssh.disconnect();
2731
+ return '<a href="' + this._config.const.urlBase + 'test/ssh?type=shell">shell</a> | ' +
2732
+ '<a href="' + this._config.const.urlBase + 'test/ssh?type=sftp">sftp</a> | ' +
2733
+ '<a href="' + this._config.const.urlBase + 'test">Return</a>' + echo.join('') + this._getEnd();
2734
+ }
2735
+ async s3() {
2736
+ const s3 = lS3.get(this, {
2737
+ 'service': lS3.ESERVICE.AMAZON,
2738
+ 'region': 'ap-southeast-1',
2739
+ 'bucket': 'xxx'
2740
+ });
2741
+ const echo = [`<pre>const s3 = lS3.get(this, {
2742
+ 'service': lS3.SERVICE.AMAZON,
2743
+ 'region': 'ap-southeast-1',
2744
+ 'bucket': 'xxx'
2745
+ });</pre>`];
2746
+ const putr = await s3.putObject('a/b.txt', 'x');
2747
+ echo.push(`<pre>await s3.putObject('a/b.txt', 'x');</pre>` + (putr ? JSON.stringify(putr) : 'false'));
2748
+ const r = await s3.headObject('a.txt');
2749
+ echo.push(`<pre>await s3.headObject('a.txt');</pre>` + (r ? JSON.stringify(r) : 'false'));
2750
+ const r2 = await s3.deleteObjects(['a.txt', 'a/b.txt']);
2751
+ echo.push(`<pre>s3.deleteObjects(['a.txt', 'a/b.txt']);</pre>` + (r2 ? 'true' : 'false'));
2752
+ return echo.join('') + '<br><br>' + this._getEnd();
2753
+ }
2754
+ async zip() {
2755
+ const path = this._config.const.dataPath + 'test.zip';
2756
+ const echo = ['Path: ' + path + '<br><br>'];
2757
+ const buf = await lFs.getContent(path);
2758
+ if (!buf) {
2759
+ return 'Failed<br><br>' + this._getEnd();
2760
+ }
2761
+ const z = await lZip.get(buf);
2762
+ if (!z) {
2763
+ return 'Failed<br><br>' + this._getEnd();
2764
+ }
2765
+ const ls = await z.getList();
2766
+ echo.push('<table style="width: 100%;"><tr>');
2767
+ if (Object.keys(ls).length) {
2768
+ for (const path in ls) {
2769
+ echo.push('<tr>');
2770
+ echo.push('<td>' + lText.htmlescape(path) + '</td>');
2771
+ echo.push('<td>' + lText.sizeFormat(z.stats(path)?.uncompressedSize ?? 0) + '</td>');
2772
+ echo.push('<td>' + Object.prototype.toString.call(ls[path]) + '</td>');
2773
+ echo.push('</tr>');
2774
+ }
2775
+ }
2776
+ else {
2777
+ echo.push('<th>Empty</th></tr>');
2778
+ }
2779
+ echo.push('</table>');
2780
+ return echo.join('') + '<br>' + this._getEnd();
2781
+ }
2782
+ buffer() {
2783
+ const writer = lBuffer.getWriter(8);
2784
+ writer.writeUInt8(8);
2785
+ writer.writeUInt16BE(2024);
2786
+ writer.writeBCDString('1213141516');
2787
+ const b = writer.get();
2788
+ const echo = [`<pre>const buf = lBuffer.getWriter(8);
2789
+ writer.writeUInt8(8);
2790
+ writer.writeUInt16BE(2024);
2791
+ writer.writeBCDString('1213141516');
2792
+ const b = writer.get();</pre>${b.toString('hex').replace(/(.{2})/g, '$1 ')}`];
2793
+ const reader = lBuffer.getReader(b);
2794
+ const rtn = [];
2795
+ rtn.push(reader.readUInt8());
2796
+ rtn.push(reader.readUInt16BE());
2797
+ rtn.push(reader.readBCDString());
2798
+ echo.push(`<pre>const reader = lBuffer.getReader(b);
2799
+ const rtn: any[] = [];
2800
+ rtn.push(reader.readUInt8());
2801
+ rtn.push(reader.readUInt16BE());
2802
+ rtn.push(reader.readBCDString());</pre>${JSON.stringify(rtn)}`);
2803
+ return echo.join('') + '<br><br>' + this._getEnd();
2804
+ }
2805
+ async lan() {
2806
+ const echo = [];
2807
+ const r = await lLan.card();
2808
+ echo.push(`<pre>lLan.card();</pre>` + JSON.stringify(r));
2809
+ const r2 = await lLan.scan();
2810
+ echo.push(`<pre>await lLan.scan();</pre>` + JSON.stringify(r2));
2811
+ return echo.join('') + '<br><br>' + this._getEnd();
2812
+ }
2813
+ _getEnd() {
2814
+ const rt = this._getRunTime();
2815
+ return 'Processed in ' + rt.toString() + ' second(s), ' + (Math.round(rt * 10000000) / 10000).toString() + 'ms, ' + (Math.round(this._getMemoryUsage() / 1024 * 100) / 100).toString() + ' K.<style>*{font-family:Consolas,"Courier New",Courier,FreeMono,monospace;line-height: 1.5;font-size:12px;}pre{padding:10px;background-color:rgba(0,0,0,.07);white-space:pre-wrap;word-break:break-all;}hr{margin:20px 0;border-color:#000;border-style:dashed;border-width:1px 0 0 0;}td,th{padding:5px;border:solid 1px #000;}</style><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">';
2816
+ }
2817
+ }
2818
+ exports.default = default_1;