nadesiko3 3.4.13 → 3.4.14
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.
- package/batch/command.txt +292 -292
- package/core/package.json +1 -1
- package/core/src/nako_core_version.mjs +2 -2
- package/core/src/nako_core_version.mts +2 -2
- package/core/src/nako_from_dncl2.mjs +34 -2
- package/core/src/nako_from_dncl2.mts +31 -2
- package/core/src/nako_gen.mjs +110 -76
- package/core/src/nako_gen.mts +114 -75
- package/core/src/plugin_system.mjs +13 -3
- package/core/src/plugin_system.mts +11 -3
- package/core/test/dncl2_test.mjs +161 -152
- package/package.json +4 -33
- package/release/_hash.txt +20 -20
- package/release/_script-tags.txt +14 -14
- package/release/nako_gen_async.js +1 -1
- package/release/nako_gen_async.js.map +1 -1
- package/release/plugin_datetime.js +1 -1
- package/release/plugin_datetime.js.map +1 -1
- package/release/stats.json +1 -1
- package/release/version.js +1 -1
- package/release/version.js.map +1 -1
- package/release/wnako3.js +1 -1
- package/release/wnako3.js.map +1 -1
- package/release/wnako3webworker.js +1 -1
- package/release/wnako3webworker.js.map +1 -1
- package/src/nako_version.mjs +2 -2
- package/src/nako_version.mts +2 -2
- package/src/plugin_browser.mjs +1 -1
- package/src/plugin_browser.mts +1 -1
- package/src/plugin_browser_ajax.mjs +6 -6
- package/src/plugin_browser_ajax.mts +8 -8
- package/src/plugin_browser_canvas.mjs +2 -2
- package/src/plugin_browser_canvas.mts +2 -2
- package/src/plugin_browser_chart.mjs +17 -13
- package/src/plugin_browser_chart.mts +25 -21
- package/src/plugin_browser_crypto.mjs +1 -1
- package/src/plugin_browser_crypto.mts +2 -2
- package/src/plugin_browser_dom_basic.mjs +5 -5
- package/src/plugin_browser_dom_basic.mts +5 -5
- package/src/plugin_browser_dom_event.mjs +17 -17
- package/src/plugin_browser_dom_event.mts +17 -17
- package/src/plugin_browser_dom_parts.mjs +21 -21
- package/src/plugin_browser_dom_parts.mts +21 -21
- package/src/plugin_browser_geolocation.mjs +2 -2
- package/src/plugin_browser_geolocation.mts +2 -2
- package/src/plugin_browser_storage.mjs +3 -3
- package/src/plugin_browser_storage.mts +3 -3
- package/src/plugin_datetime.mjs +9 -9
- package/src/plugin_node.mjs +3 -3
- package/src/plugin_node.mts +3 -3
- package/test/node/plugin_node_test.mjs +181 -180
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
'位置情報取得時': {
|
|
5
5
|
type: 'func',
|
|
6
6
|
josi: [['の', 'に', 'へ']],
|
|
7
|
-
pure:
|
|
7
|
+
pure: true,
|
|
8
8
|
fn: function (func, sys) {
|
|
9
9
|
let cb = func;
|
|
10
10
|
if (typeof cb === 'string') {
|
|
@@ -26,7 +26,7 @@ export default {
|
|
|
26
26
|
'位置情報監視時': {
|
|
27
27
|
type: 'func',
|
|
28
28
|
josi: [['の', 'に', 'へ']],
|
|
29
|
-
pure:
|
|
29
|
+
pure: true,
|
|
30
30
|
fn: function (func, sys) {
|
|
31
31
|
let cb = func;
|
|
32
32
|
if (typeof cb === 'string') {
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
'位置情報取得時': { // @位置情報を取得してコールバック関数内で変数「対象」に配列で[緯度,経度]を返す // @いちじょうほうしゅとくしたとき
|
|
5
5
|
type: 'func',
|
|
6
6
|
josi: [['の', 'に', 'へ']],
|
|
7
|
-
pure:
|
|
7
|
+
pure: true,
|
|
8
8
|
fn: function (func: any, sys: any) {
|
|
9
9
|
let cb = func
|
|
10
10
|
if (typeof cb === 'string') { cb = sys.__findVar(cb) }
|
|
@@ -23,7 +23,7 @@ export default {
|
|
|
23
23
|
'位置情報監視時': { // @位置情報を監視してIDを返す。引数に指定したコールバック関数内で変数「対象」に配列で[緯度,経度]を返す // @いちじょうほうかんししたとき
|
|
24
24
|
type: 'func',
|
|
25
25
|
josi: [['の', 'に', 'へ']],
|
|
26
|
-
pure:
|
|
26
|
+
pure: true,
|
|
27
27
|
fn: function (func: any, sys: any) {
|
|
28
28
|
let cb = func
|
|
29
29
|
if (typeof cb === 'string') { cb = sys.__findVar(cb) }
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
'保存': {
|
|
5
5
|
type: 'func',
|
|
6
6
|
josi: [['を'], ['に', 'へ']],
|
|
7
|
-
pure:
|
|
7
|
+
pure: true,
|
|
8
8
|
fn: function (v, key, sys) {
|
|
9
9
|
sys.__exec('ローカルストレージ保存', [v, key, sys]);
|
|
10
10
|
},
|
|
@@ -13,7 +13,7 @@ export default {
|
|
|
13
13
|
'開': {
|
|
14
14
|
type: 'func',
|
|
15
15
|
josi: [['を', 'から', 'の']],
|
|
16
|
-
pure:
|
|
16
|
+
pure: true,
|
|
17
17
|
fn: function (key, sys) {
|
|
18
18
|
return sys.__exec('ローカルストレージ読', [key, sys]);
|
|
19
19
|
},
|
|
@@ -22,7 +22,7 @@ export default {
|
|
|
22
22
|
'読': {
|
|
23
23
|
type: 'func',
|
|
24
24
|
josi: [['を', 'から', 'の']],
|
|
25
|
-
pure:
|
|
25
|
+
pure: true,
|
|
26
26
|
fn: function (key, sys) {
|
|
27
27
|
return sys.__exec('ローカルストレージ読', [key, sys]);
|
|
28
28
|
},
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
'保存': { // @ブラウザのlocalStorageのキーKに文字列Vを保存 // @ほぞん
|
|
5
5
|
type: 'func',
|
|
6
6
|
josi: [['を'], ['に', 'へ']],
|
|
7
|
-
pure:
|
|
7
|
+
pure: true,
|
|
8
8
|
fn: function (v: any, key: any, sys: any) {
|
|
9
9
|
sys.__exec('ローカルストレージ保存', [v, key, sys])
|
|
10
10
|
},
|
|
@@ -13,7 +13,7 @@ export default {
|
|
|
13
13
|
'開': { // @ブラウザのlocalStorageからVを読む // @ひらく
|
|
14
14
|
type: 'func',
|
|
15
15
|
josi: [['を', 'から', 'の']],
|
|
16
|
-
pure:
|
|
16
|
+
pure: true,
|
|
17
17
|
fn: function (key: any, sys: any) {
|
|
18
18
|
return sys.__exec('ローカルストレージ読', [key, sys])
|
|
19
19
|
},
|
|
@@ -22,7 +22,7 @@ export default {
|
|
|
22
22
|
'読': { // @ブラウザのlocalStorageからVを読む // @よむ
|
|
23
23
|
type: 'func',
|
|
24
24
|
josi: [['を', 'から', 'の']],
|
|
25
|
-
pure:
|
|
25
|
+
pure: true,
|
|
26
26
|
fn: function (key: any, sys: any) {
|
|
27
27
|
return sys.__exec('ローカルストレージ読', [key, sys])
|
|
28
28
|
},
|
package/src/plugin_datetime.mjs
CHANGED
|
@@ -126,7 +126,7 @@ const PluginDateTime = {
|
|
|
126
126
|
'UNIX時間変換': { // @日時SをUNIX時間 (UTC(1970/1/1)からの経過秒数) に変換して返す(v1非互換) // @UNIXじかんへんかん
|
|
127
127
|
type: 'func',
|
|
128
128
|
josi: [['の', 'を', 'から']],
|
|
129
|
-
pure:
|
|
129
|
+
pure: true,
|
|
130
130
|
fn: function (s, sys) {
|
|
131
131
|
return sys.__exec('UNIXTIME変換', [s])
|
|
132
132
|
}
|
|
@@ -173,7 +173,7 @@ const PluginDateTime = {
|
|
|
173
173
|
'年数差': { // @日付AとBの差を年数で求めて返す。A<Bなら正の数、そうでないなら負の数を返す (v1非互換)。 // @ねんすうさ
|
|
174
174
|
type: 'func',
|
|
175
175
|
josi: [['と', 'から'], ['の', 'までの']],
|
|
176
|
-
pure:
|
|
176
|
+
pure: true,
|
|
177
177
|
fn: function (a, b, sys) {
|
|
178
178
|
return sys.__exec('日時差', [a, b, '年'])
|
|
179
179
|
}
|
|
@@ -181,7 +181,7 @@ const PluginDateTime = {
|
|
|
181
181
|
'月数差': { // @日付AとBの差を月数で求めて返す。A<Bなら正の数、そうでないなら負の数を返す (v1非互換)。 // @げっすうさ
|
|
182
182
|
type: 'func',
|
|
183
183
|
josi: [['と', 'から'], ['の', 'までの']],
|
|
184
|
-
pure:
|
|
184
|
+
pure: true,
|
|
185
185
|
fn: function (a, b, sys) {
|
|
186
186
|
return sys.__exec('日時差', [a, b, '月'])
|
|
187
187
|
}
|
|
@@ -189,7 +189,7 @@ const PluginDateTime = {
|
|
|
189
189
|
'日数差': { // @日付AとBの差を日数で求めて返す。A<Bなら正の数、そうでないなら負の数を返す。 // @にっすうさ
|
|
190
190
|
type: 'func',
|
|
191
191
|
josi: [['と', 'から'], ['の', 'までの']],
|
|
192
|
-
pure:
|
|
192
|
+
pure: true,
|
|
193
193
|
fn: function (a, b, sys) {
|
|
194
194
|
return sys.__exec('日時差', [a, b, '日'])
|
|
195
195
|
}
|
|
@@ -252,7 +252,7 @@ const PluginDateTime = {
|
|
|
252
252
|
'時間差': { // @時間AとBの時間の差を求めて返す。A<Bなら正の数、そうでないなら負の数を返す。 // @じかんさ
|
|
253
253
|
type: 'func',
|
|
254
254
|
josi: [['と', 'から'], ['の', 'までの']],
|
|
255
|
-
pure:
|
|
255
|
+
pure: true,
|
|
256
256
|
fn: function (a, b, sys) {
|
|
257
257
|
return sys.__exec('日時差', [a, b, '時間'])
|
|
258
258
|
}
|
|
@@ -260,7 +260,7 @@ const PluginDateTime = {
|
|
|
260
260
|
'分差': { // @時間AとBの分数の差を求めて返す。A<Bなら正の数、そうでないなら負の数を返す。 // @ふんさ
|
|
261
261
|
type: 'func',
|
|
262
262
|
josi: [['と', 'から'], ['の', 'までの']],
|
|
263
|
-
pure:
|
|
263
|
+
pure: true,
|
|
264
264
|
fn: function (a, b, sys) {
|
|
265
265
|
return sys.__exec('日時差', [a, b, '分'])
|
|
266
266
|
}
|
|
@@ -268,7 +268,7 @@ const PluginDateTime = {
|
|
|
268
268
|
'秒差': { // @時間AとBの差を秒差で求めて返す。A<Bなら正の数、そうでないなら負の数を返す。 // @びょうさ
|
|
269
269
|
type: 'func',
|
|
270
270
|
josi: [['と', 'から'], ['の', 'までの']],
|
|
271
|
-
pure:
|
|
271
|
+
pure: true,
|
|
272
272
|
fn: function (a, b, sys) {
|
|
273
273
|
return sys.__exec('日時差', [a, b, '秒'])
|
|
274
274
|
}
|
|
@@ -276,7 +276,7 @@ const PluginDateTime = {
|
|
|
276
276
|
'時間加算': { // @時間SにAを加えて返す。Aには「(+|-)hh:nn:dd」で指定する。 // @じかんかさん
|
|
277
277
|
type: 'func',
|
|
278
278
|
josi: [['に'], ['を']],
|
|
279
|
-
pure:
|
|
279
|
+
pure: true,
|
|
280
280
|
fn: function (s, a, sys) {
|
|
281
281
|
const pm = a.slice(0, 1)
|
|
282
282
|
|
|
@@ -297,7 +297,7 @@ const PluginDateTime = {
|
|
|
297
297
|
'日付加算': { // @日付SにAを加えて返す。Aには「(+|-)yyyy/mm/dd」で指定する。 // @ひづけかさん
|
|
298
298
|
type: 'func',
|
|
299
299
|
josi: [['に'], ['を']],
|
|
300
|
-
pure:
|
|
300
|
+
pure: true,
|
|
301
301
|
fn: function (s, a, sys) {
|
|
302
302
|
const pm = a.slice(0, 1)
|
|
303
303
|
|
package/src/plugin_node.mjs
CHANGED
|
@@ -82,7 +82,7 @@ export default {
|
|
|
82
82
|
'読': {
|
|
83
83
|
type: 'func',
|
|
84
84
|
josi: [['を', 'から']],
|
|
85
|
-
pure:
|
|
85
|
+
pure: true,
|
|
86
86
|
fn: function (s, sys) {
|
|
87
87
|
return sys.__exec('開', [s]);
|
|
88
88
|
}
|
|
@@ -638,7 +638,7 @@ export default {
|
|
|
638
638
|
'終了': {
|
|
639
639
|
type: 'func',
|
|
640
640
|
josi: [],
|
|
641
|
-
pure:
|
|
641
|
+
pure: true,
|
|
642
642
|
fn: function (sys) {
|
|
643
643
|
sys.__exec('終', []);
|
|
644
644
|
},
|
|
@@ -795,7 +795,7 @@ export default {
|
|
|
795
795
|
'GET送信時': {
|
|
796
796
|
type: 'func',
|
|
797
797
|
josi: [['の'], ['まで', 'へ', 'に']],
|
|
798
|
-
pure:
|
|
798
|
+
pure: true,
|
|
799
799
|
fn: function (callback, url, sys) {
|
|
800
800
|
sys.__exec('AJAX送信時', [callback, url, sys]);
|
|
801
801
|
},
|
package/src/plugin_node.mts
CHANGED
|
@@ -76,7 +76,7 @@ export default {
|
|
|
76
76
|
'読': { // @ファイルSを開く // @よむ
|
|
77
77
|
type: 'func',
|
|
78
78
|
josi: [['を', 'から']],
|
|
79
|
-
pure:
|
|
79
|
+
pure: true,
|
|
80
80
|
fn: function (s: string, sys: any) {
|
|
81
81
|
return sys.__exec('開', [s])
|
|
82
82
|
}
|
|
@@ -587,7 +587,7 @@ export default {
|
|
|
587
587
|
'終了': { // @Nodeでプログラム実行を強制終了する // @しゅうりょう
|
|
588
588
|
type: 'func',
|
|
589
589
|
josi: [],
|
|
590
|
-
pure:
|
|
590
|
+
pure: true,
|
|
591
591
|
fn: function (sys: any) {
|
|
592
592
|
sys.__exec('終', [])
|
|
593
593
|
},
|
|
@@ -730,7 +730,7 @@ export default {
|
|
|
730
730
|
'GET送信時': { // @非同期通信(Ajax)でURLにデータを送信し、成功するとcallbackが実行される。その際『対象』にデータが代入される。 // @GETそうしんしたとき
|
|
731
731
|
type: 'func',
|
|
732
732
|
josi: [['の'], ['まで', 'へ', 'に']],
|
|
733
|
-
pure:
|
|
733
|
+
pure: true,
|
|
734
734
|
fn: function (callback: any, url: string, sys: any) {
|
|
735
735
|
sys.__exec('AJAX送信時', [callback, url, sys])
|
|
736
736
|
},
|
|
@@ -1,180 +1,181 @@
|
|
|
1
|
-
/* eslint-disable no-undef */
|
|
2
|
-
// import fs from 'fs'
|
|
3
|
-
import os from 'os'
|
|
4
|
-
import fs from 'fs'
|
|
5
|
-
import assert from 'assert'
|
|
6
|
-
import path from 'path'
|
|
7
|
-
import { execSync } from 'child_process'
|
|
8
|
-
|
|
9
|
-
import { NakoCompiler } from '../../core/src/nako3.mjs'
|
|
10
|
-
import PluginNode from '../../src/plugin_node.mjs'
|
|
11
|
-
import PluginCSV from '../../core/src/plugin_csv.mjs'
|
|
12
|
-
|
|
13
|
-
// __dirname のために
|
|
14
|
-
import url from 'url'
|
|
15
|
-
// @ts-ignore
|
|
16
|
-
const __filename = url.fileURLToPath(import.meta.url)
|
|
17
|
-
const __dirname = path.dirname(__filename)
|
|
18
|
-
const testFileMe = path.join(__dirname, 'plugin_node_test.mjs')
|
|
19
|
-
|
|
20
|
-
describe('plugin_node_test', async () => {
|
|
21
|
-
const cmp = async (/** @type {string} */ code, /** @type {string | undefined} */ res) => {
|
|
22
|
-
const nako = new NakoCompiler()
|
|
23
|
-
nako.addPluginFile('PluginNode', 'plugin_node.js', PluginNode)
|
|
24
|
-
nako.addPluginFile('PluginCSV', 'plugin_csv.js', PluginCSV)
|
|
25
|
-
const g = await nako.runAsync(code, 'main')
|
|
26
|
-
assert.strictEqual(g.log, res)
|
|
27
|
-
}
|
|
28
|
-
const cmd = async (/** @type {string} */ code) => {
|
|
29
|
-
const nako = new NakoCompiler()
|
|
30
|
-
nako.addPluginFile('PluginNode', 'plugin_node.js', PluginNode)
|
|
31
|
-
nako.addPluginFile('PluginCSV', 'plugin_csv.js', PluginCSV)
|
|
32
|
-
await nako.runAsync(code, 'main')
|
|
33
|
-
}
|
|
34
|
-
// --- test ---
|
|
35
|
-
it('表示', async () => {
|
|
36
|
-
await cmp('3を表示', '3')
|
|
37
|
-
await cmp('1+2*3を表示', '7')
|
|
38
|
-
await cmp('A=30;「--{A}--」を表示', '--30--')
|
|
39
|
-
})
|
|
40
|
-
it('存在1', async () => {
|
|
41
|
-
await cmp('「/xxx/xxx/xxx/xxx」が存在;もしそうならば;「NG」と表示。違えば「OK」と表示。', 'OK')
|
|
42
|
-
})
|
|
43
|
-
it('存在2', async () => {
|
|
44
|
-
await cmp('「' + testFileMe + '」が存在;もしそうならば;「OK」と表示。違えば「NG」と表示。', 'OK')
|
|
45
|
-
})
|
|
46
|
-
it('フォルダ存在', async () => {
|
|
47
|
-
const dir = __dirname
|
|
48
|
-
await cmp('「' + dir + '」が存在;もしそうならば;「OK」と表示。違えば「NG」と表示。', 'OK')
|
|
49
|
-
await cmp('「' + dir + '/xxx」が存在;もしそうならば;「OK」と表示。違えば「NG」と表示。', 'NG')
|
|
50
|
-
})
|
|
51
|
-
it('ASSERT', async () => {
|
|
52
|
-
cmd('3と3がASSERT等')
|
|
53
|
-
})
|
|
54
|
-
it('環境変数取得', async () => {
|
|
55
|
-
const path = process.env.PATH
|
|
56
|
-
await cmp('「PATH」の環境変数取得して表示。', path)
|
|
57
|
-
})
|
|
58
|
-
it('ファイルサイズ取得', async () => {
|
|
59
|
-
await cmp('「' + testFileMe + '」のファイルサイズ取得;もし、それが2000以上ならば;「OK」と表示。違えば「NG」と表示。', 'OK')
|
|
60
|
-
})
|
|
61
|
-
it('ファイル情報取得', async () => {
|
|
62
|
-
await cmp('「' + testFileMe + '」のファイル情報取得;もし、それ["size"]が2000以上ならば;「OK」と表示。違えば「NG」と表示。', 'OK')
|
|
63
|
-
})
|
|
64
|
-
it('クリップボード', async () => {
|
|
65
|
-
try {
|
|
66
|
-
const rnd = 'a' + Math.random()
|
|
67
|
-
await cmp('クリップボード="' + rnd + '";クリップボードを表示。', rnd)
|
|
68
|
-
} catch (err) {
|
|
69
|
-
// テストは必須ではない(Linuxコンソール環境に配慮)
|
|
70
|
-
}
|
|
71
|
-
})
|
|
72
|
-
it('文字エンコーディング', async () => {
|
|
73
|
-
const sjisfile = path.join(__dirname, 'sjis.txt')
|
|
74
|
-
await cmp(`「${sjisfile}」をバイナリ読む。` +
|
|
75
|
-
'SJIS取得。CSV取得してCに代入。C[2][1]を表示',
|
|
76
|
-
'ホームセンター')
|
|
77
|
-
await cmp(`「${sjisfile}」をバイナリ読む。` +
|
|
78
|
-
'「Shift_JIS」からエンコーディング取得。' +
|
|
79
|
-
'CSV取得してCに代入。C[2][1]を表示',
|
|
80
|
-
'ホームセンター')
|
|
81
|
-
})
|
|
82
|
-
it('ハッシュ値計算', async () => {
|
|
83
|
-
await cmp('「hello world」を「sha256」の「base64」でハッシュ値計算して表示。', 'uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek=')
|
|
84
|
-
await cmp('「hello world」を「sha256」の「hex」でハッシュ値計算して表示。', 'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9')
|
|
85
|
-
await cmp('「some data to hash」を「sha256」の「hex」でハッシュ値計算して表示。', '6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50')
|
|
86
|
-
})
|
|
87
|
-
it('テンポラリフォルダ', async () => {
|
|
88
|
-
await cmp('F=「{テンポラリフォルダ}/test.txt」;「abc」をFに保存。Fを読んでトリムして表示。', 'abc')
|
|
89
|
-
})
|
|
90
|
-
it('圧縮解凍', async () => {
|
|
91
|
-
let path7z = '7z'
|
|
92
|
-
if (process.platform === 'win32') {
|
|
93
|
-
path7z = path.join(__dirname, '../../bin/7z.exe')
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
'
|
|
105
|
-
'
|
|
106
|
-
'
|
|
107
|
-
'
|
|
108
|
-
'
|
|
109
|
-
'
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
await cmp(`${pathSrc}FILE
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
'
|
|
145
|
-
|
|
146
|
-
await cmp(`${pathSrc}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
'
|
|
154
|
-
|
|
155
|
-
await cmp(`${pathSrc2}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
'
|
|
177
|
-
|
|
178
|
-
await cmp(`${pathSrc}
|
|
179
|
-
|
|
180
|
-
})
|
|
1
|
+
/* eslint-disable no-undef */
|
|
2
|
+
// import fs from 'fs'
|
|
3
|
+
import os from 'os'
|
|
4
|
+
import fs from 'fs'
|
|
5
|
+
import assert from 'assert'
|
|
6
|
+
import path from 'path'
|
|
7
|
+
import { execSync } from 'child_process'
|
|
8
|
+
|
|
9
|
+
import { NakoCompiler } from '../../core/src/nako3.mjs'
|
|
10
|
+
import PluginNode from '../../src/plugin_node.mjs'
|
|
11
|
+
import PluginCSV from '../../core/src/plugin_csv.mjs'
|
|
12
|
+
|
|
13
|
+
// __dirname のために
|
|
14
|
+
import url from 'url'
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
const __filename = url.fileURLToPath(import.meta.url)
|
|
17
|
+
const __dirname = path.dirname(__filename)
|
|
18
|
+
const testFileMe = path.join(__dirname, 'plugin_node_test.mjs')
|
|
19
|
+
|
|
20
|
+
describe('plugin_node_test', async () => {
|
|
21
|
+
const cmp = async (/** @type {string} */ code, /** @type {string | undefined} */ res) => {
|
|
22
|
+
const nako = new NakoCompiler()
|
|
23
|
+
nako.addPluginFile('PluginNode', 'plugin_node.js', PluginNode)
|
|
24
|
+
nako.addPluginFile('PluginCSV', 'plugin_csv.js', PluginCSV)
|
|
25
|
+
const g = await nako.runAsync(code, 'main')
|
|
26
|
+
assert.strictEqual(g.log, res)
|
|
27
|
+
}
|
|
28
|
+
const cmd = async (/** @type {string} */ code) => {
|
|
29
|
+
const nako = new NakoCompiler()
|
|
30
|
+
nako.addPluginFile('PluginNode', 'plugin_node.js', PluginNode)
|
|
31
|
+
nako.addPluginFile('PluginCSV', 'plugin_csv.js', PluginCSV)
|
|
32
|
+
await nako.runAsync(code, 'main')
|
|
33
|
+
}
|
|
34
|
+
// --- test ---
|
|
35
|
+
it('表示', async () => {
|
|
36
|
+
await cmp('3を表示', '3')
|
|
37
|
+
await cmp('1+2*3を表示', '7')
|
|
38
|
+
await cmp('A=30;「--{A}--」を表示', '--30--')
|
|
39
|
+
})
|
|
40
|
+
it('存在1', async () => {
|
|
41
|
+
await cmp('「/xxx/xxx/xxx/xxx」が存在;もしそうならば;「NG」と表示。違えば「OK」と表示。', 'OK')
|
|
42
|
+
})
|
|
43
|
+
it('存在2', async () => {
|
|
44
|
+
await cmp('「' + testFileMe + '」が存在;もしそうならば;「OK」と表示。違えば「NG」と表示。', 'OK')
|
|
45
|
+
})
|
|
46
|
+
it('フォルダ存在', async () => {
|
|
47
|
+
const dir = __dirname
|
|
48
|
+
await cmp('「' + dir + '」が存在;もしそうならば;「OK」と表示。違えば「NG」と表示。', 'OK')
|
|
49
|
+
await cmp('「' + dir + '/xxx」が存在;もしそうならば;「OK」と表示。違えば「NG」と表示。', 'NG')
|
|
50
|
+
})
|
|
51
|
+
it('ASSERT', async () => {
|
|
52
|
+
cmd('3と3がASSERT等')
|
|
53
|
+
})
|
|
54
|
+
it('環境変数取得', async () => {
|
|
55
|
+
const path = process.env.PATH
|
|
56
|
+
await cmp('「PATH」の環境変数取得して表示。', path)
|
|
57
|
+
})
|
|
58
|
+
it('ファイルサイズ取得', async () => {
|
|
59
|
+
await cmp('「' + testFileMe + '」のファイルサイズ取得;もし、それが2000以上ならば;「OK」と表示。違えば「NG」と表示。', 'OK')
|
|
60
|
+
})
|
|
61
|
+
it('ファイル情報取得', async () => {
|
|
62
|
+
await cmp('「' + testFileMe + '」のファイル情報取得;もし、それ["size"]が2000以上ならば;「OK」と表示。違えば「NG」と表示。', 'OK')
|
|
63
|
+
})
|
|
64
|
+
it('クリップボード', async () => {
|
|
65
|
+
try {
|
|
66
|
+
const rnd = 'a' + Math.random()
|
|
67
|
+
await cmp('クリップボード="' + rnd + '";クリップボードを表示。', rnd)
|
|
68
|
+
} catch (err) {
|
|
69
|
+
// テストは必須ではない(Linuxコンソール環境に配慮)
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
it('文字エンコーディング', async () => {
|
|
73
|
+
const sjisfile = path.join(__dirname, 'sjis.txt')
|
|
74
|
+
await cmp(`「${sjisfile}」をバイナリ読む。` +
|
|
75
|
+
'SJIS取得。CSV取得してCに代入。C[2][1]を表示',
|
|
76
|
+
'ホームセンター')
|
|
77
|
+
await cmp(`「${sjisfile}」をバイナリ読む。` +
|
|
78
|
+
'「Shift_JIS」からエンコーディング取得。' +
|
|
79
|
+
'CSV取得してCに代入。C[2][1]を表示',
|
|
80
|
+
'ホームセンター')
|
|
81
|
+
})
|
|
82
|
+
it('ハッシュ値計算', async () => {
|
|
83
|
+
await cmp('「hello world」を「sha256」の「base64」でハッシュ値計算して表示。', 'uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek=')
|
|
84
|
+
await cmp('「hello world」を「sha256」の「hex」でハッシュ値計算して表示。', 'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9')
|
|
85
|
+
await cmp('「some data to hash」を「sha256」の「hex」でハッシュ値計算して表示。', '6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50')
|
|
86
|
+
})
|
|
87
|
+
it('テンポラリフォルダ', async () => {
|
|
88
|
+
await cmp('F=「{テンポラリフォルダ}/test.txt」;「abc」をFに保存。Fを読んでトリムして表示。', 'abc')
|
|
89
|
+
})
|
|
90
|
+
it('圧縮解凍', async () => {
|
|
91
|
+
let path7z = '7z'
|
|
92
|
+
if (process.platform === 'win32') {
|
|
93
|
+
path7z = path.join(__dirname, '../../bin/7z.exe')
|
|
94
|
+
if (!fs.existsSync(path7z)) { return }
|
|
95
|
+
}
|
|
96
|
+
let tmp = '/tmp'
|
|
97
|
+
if (process.platform === 'linux') {
|
|
98
|
+
tmp = path.join(os.tmpdir(), 'nadesiko3test')
|
|
99
|
+
} else {
|
|
100
|
+
tmp = fs.mkdtempSync(os.tmpdir())
|
|
101
|
+
}
|
|
102
|
+
const code = 'FIN=「' + testFileMe + '」;' +
|
|
103
|
+
`TMP=「${tmp}」へ一時フォルダ作成。` +
|
|
104
|
+
'『' + path7z + '』に圧縮解凍ツールパス変更;' +
|
|
105
|
+
'もし、TMPが存在しないならば、TMPのフォルダ作成。' +
|
|
106
|
+
'FZIP=「{TMP}/test.zip」;\n' +
|
|
107
|
+
'FINをFZIPへ圧縮。FZIPを「{TMP}/」に解凍。\n' +
|
|
108
|
+
'S1=「{TMP}/plugin_node_test.mjs」を読む。\n' +
|
|
109
|
+
'S2=FINを読む。\n' +
|
|
110
|
+
'もし(S1=S2)ならば、"OK"と表示。\n'
|
|
111
|
+
await cmp(code, 'OK')
|
|
112
|
+
})
|
|
113
|
+
it('圧縮/解凍', async function () {
|
|
114
|
+
if (process.platform === 'win32') { return this.skip() }
|
|
115
|
+
try { execSync('which 7z').toString() } catch (e) { return this.skip() }
|
|
116
|
+
let tmp = '/tmp'
|
|
117
|
+
if (process.platform === 'linux') {
|
|
118
|
+
tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'nadesiko3zip-test'))
|
|
119
|
+
} else {
|
|
120
|
+
tmp = fs.mkdtempSync(os.tmpdir())
|
|
121
|
+
}
|
|
122
|
+
const pathSrc = `TMP="${tmp}";FILE=「{TMP}/test.txt」;ZIP=「{TMP}/test.zip」;`
|
|
123
|
+
await cmp(`${pathSrc}FILEへ「abc」を保存。FILEをZIPに圧縮。ZIPが存在。もし,そうならば「ok」と表示。`, 'ok')
|
|
124
|
+
await cmp(`${pathSrc}FILEをファイル削除。ZIPをTMPに解凍。FILEを読む。トリム。それを表示。`, 'abc')
|
|
125
|
+
})
|
|
126
|
+
it('圧縮/解凍 - OSコマンドインジェクション対策がなされているか #1325', async function () {
|
|
127
|
+
// 7z がない環境ではテストを飛ばす
|
|
128
|
+
if (process.platform === 'win32') {
|
|
129
|
+
return this.skip()
|
|
130
|
+
} else {
|
|
131
|
+
try { execSync('which 7z').toString() } catch (e) { return this.skip() }
|
|
132
|
+
}
|
|
133
|
+
let tmp = '/tmp'
|
|
134
|
+
if (process.platform === 'linux') {
|
|
135
|
+
tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'test_nako3zip'))
|
|
136
|
+
} else {
|
|
137
|
+
tmp = fs.mkdtempSync(os.tmpdir())
|
|
138
|
+
}
|
|
139
|
+
// (1) 元ファイルへのインジェクション
|
|
140
|
+
const pathSrc = '' +
|
|
141
|
+
`TMP="${tmp}"\n` +
|
|
142
|
+
'FILE=「{TMP}/`touch hoge`.txt」;ZIP=「{TMP}/test.zip」\n'
|
|
143
|
+
await cmp(pathSrc +
|
|
144
|
+
'F=「{TMP}/hoge」;Fが存在;もしそうならば、Fをファイル削除;' +
|
|
145
|
+
'FILEへ「abc」を保存。FILEをZIPに圧縮。ZIPが存在。もし,そうならば「ok」と表示。', 'ok')
|
|
146
|
+
await cmp(`${pathSrc}「{TMP}/hoge」が存在。もし,そうならば「OS_INJECTION」と表示。`, '')
|
|
147
|
+
await cmp(`${pathSrc}FILEをファイル削除。ZIPをTMPに解凍。FILEを読む。トリム。それを表示。`, 'abc')
|
|
148
|
+
// (2) ZIPファイルへのインジェクション
|
|
149
|
+
const pathSrc2 = '' +
|
|
150
|
+
`TMP="${tmp}"\n` +
|
|
151
|
+
'FILE=「{TMP}/test2.txt」;ZIP=「{TMP}/`touch bbb`.zip」;'
|
|
152
|
+
await cmp(pathSrc2 +
|
|
153
|
+
'F=「{TMP}/bbb」;Fが存在;もしそうならば、Fをファイル削除;' +
|
|
154
|
+
'FILEへ「abc」を保存。FILEをZIPに圧縮。ZIPが存在。もし,そうならば「ok」と表示。', 'ok')
|
|
155
|
+
await cmp(`${pathSrc2}「{TMP}/bbb」が存在。もし,そうならば「OS_INJECTION」と表示。`, '')
|
|
156
|
+
await cmp(`${pathSrc2}FILEをファイル削除。ZIPをTMPに解凍。FILEを読む。トリム。それを表示。`, 'abc')
|
|
157
|
+
})
|
|
158
|
+
it('圧縮/解凍 - OSコマンドインジェクション対策(修正が不完全だった件の修正) #1325', async function () {
|
|
159
|
+
// 7z がない環境ではテストを飛ばす
|
|
160
|
+
if (process.platform === 'win32') {
|
|
161
|
+
return this.skip()
|
|
162
|
+
} else {
|
|
163
|
+
try { execSync('which 7z').toString() } catch (e) { return this.skip() }
|
|
164
|
+
}
|
|
165
|
+
let tmp = '/tmp'
|
|
166
|
+
if (process.platform === 'linux') {
|
|
167
|
+
tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'test_nako3zip'))
|
|
168
|
+
} else {
|
|
169
|
+
tmp = fs.mkdtempSync(os.tmpdir())
|
|
170
|
+
}
|
|
171
|
+
// (1) 元ファイルへのインジェクション
|
|
172
|
+
const pathSrc = '' +
|
|
173
|
+
`TMP="${tmp}"\n` +
|
|
174
|
+
'FILE=「{TMP}/\'a\'`touch xxx`\'c」;ZIP=「{TMP}/test.zip」\n'
|
|
175
|
+
await cmp(pathSrc +
|
|
176
|
+
'F=「{TMP}/xxx」;Fが存在;もしそうならば、Fをファイル削除;' +
|
|
177
|
+
'FILEへ「abc」を保存。FILEをZIPに圧縮。ZIPが存在。もし,そうならば「ok」と表示。', 'ok')
|
|
178
|
+
await cmp(`${pathSrc}「{TMP}/xxx」が存在。もし,そうならば「OS_INJECTION」と表示。`, '')
|
|
179
|
+
await cmp(`${pathSrc}FILEをファイル削除。ZIPをTMPに解凍。FILEを読む。トリム。それを表示。`, 'abc')
|
|
180
|
+
})
|
|
181
|
+
})
|