nadesiko3 3.7.20 → 3.7.21

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 (40) hide show
  1. package/batch/command.txt +115 -113
  2. package/core/package.json +2 -2
  3. package/core/src/README.md +98 -0
  4. package/core/src/nako_core_version.mjs +2 -2
  5. package/core/src/nako_core_version.mts +2 -2
  6. package/package.json +21 -27
  7. package/release/_hash.txt +36 -36
  8. package/release/_script-tags.txt +16 -16
  9. package/release/command.json +1 -1
  10. package/release/command.json.js +1 -1
  11. package/release/command_cnako3.json +1 -1
  12. package/release/command_list.json +1 -1
  13. package/release/edit_main.js +2 -2
  14. package/release/edit_main.js.map +3 -3
  15. package/release/editor.js +2 -2
  16. package/release/plugin_datetime.js +1 -1
  17. package/release/plugin_datetime.js.map +3 -3
  18. package/release/plugin_markup.js +28 -28
  19. package/release/plugin_markup.js.map +3 -3
  20. package/release/version.js +2 -2
  21. package/release/version_main.js +2 -2
  22. package/release/version_main.js.map +2 -2
  23. package/release/wnako3.js +13 -13
  24. package/release/wnako3.js.map +2 -2
  25. package/release/wnako3webworker.js +1 -1
  26. package/release/wnako3webworker.js.map +1 -1
  27. package/src/cnako3mod.mjs +1 -2
  28. package/src/cnako3mod.mts +1 -2
  29. package/src/nako_version.mjs +2 -2
  30. package/src/nako_version.mts +2 -2
  31. package/src/plugin_httpserver.mjs +184 -13
  32. package/src/plugin_httpserver.mts +176 -10
  33. package/src/plugin_node.mjs +0 -1
  34. package/src/plugin_node.mts +0 -1
  35. package/src/wnako3mod.mjs +3 -0
  36. package/src/wnako3mod.mts +3 -0
  37. package/test/common/wnako3mod_test.mjs +48 -0
  38. package/test/node/package_json_test.mjs +17 -0
  39. package/test/node/plugin_httpserver_test.mjs +239 -0
  40. package/tools/nako3server/index.nako3 +4 -2
@@ -0,0 +1,239 @@
1
+ /* eslint-disable no-undef */
2
+ import assert from 'assert'
3
+ import path from 'path'
4
+ import fs from 'fs'
5
+ import http from 'http'
6
+ import os from 'os'
7
+ import { NakoCompiler } from '../../core/src/nako3.mjs'
8
+ import PluginHttpServer from '../../src/plugin_httpserver.mjs'
9
+
10
+ // __dirname のために
11
+ import url from 'url'
12
+ const __filename = url.fileURLToPath(import.meta.url)
13
+ const __dirname = path.dirname(__filename)
14
+
15
+ describe('plugin_httpserver_test', () => {
16
+ let nako
17
+ let serverDp
18
+
19
+ const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
20
+
21
+ beforeEach(() => {
22
+ serverDp = null
23
+ nako = new NakoCompiler()
24
+ // PluginHttpServerの登録。名前は 'plugin_httpserver.js' とする。
25
+ nako.addPluginFile('PluginHttpServer', 'plugin_httpserver.js', PluginHttpServer)
26
+ })
27
+
28
+ afterEach(async () => {
29
+ if (serverDp && serverDp.server) {
30
+ await new Promise((resolve) => {
31
+ serverDp.server.close(() => {
32
+ resolve()
33
+ })
34
+ })
35
+ }
36
+ })
37
+
38
+ it('クエリパラメータ付きのURLで静的ファイルが取得できること', async () => {
39
+ // テスト用のダミーファイルを作成
40
+ const tempDir = path.join(__dirname, 'fixtures_http')
41
+ if (!fs.existsSync(tempDir)) {
42
+ fs.mkdirSync(tempDir, { recursive: true })
43
+ }
44
+ const tempFile = path.join(tempDir, 'test.txt')
45
+ fs.writeFileSync(tempFile, 'hello world')
46
+
47
+ let port = 0
48
+ // `簡易HTTPサーバ起動時`を呼ぶ
49
+ const code = `
50
+ ●ダミー起動
51
+ 戻る。
52
+ ここまで。
53
+ 「ダミー起動」を${port}で簡易HTTPサーバ起動時。
54
+ 「/」を「${tempDir.replace(/\\/g, '/')}」に簡易HTTPサーバ静的パス指定。
55
+ `
56
+ const g = await nako.runAsync(code, 'main')
57
+ serverDp = g.__httpserver
58
+ await wait(100)
59
+ port = serverDp.server.address().port
60
+
61
+ // クエリパラメータ付きでリクエストを送る
62
+ const resText = await new Promise((resolve, reject) => {
63
+ http.get(`http://localhost:${port}/test.txt?foo=bar&baz=123`, (res) => {
64
+ let data = ''
65
+ res.on('data', (chunk) => { data += chunk })
66
+ res.on('end', () => { resolve(data) })
67
+ }).on('error', reject)
68
+ })
69
+
70
+ assert.strictEqual(resText, 'hello world')
71
+
72
+ // 一時ファイルを削除
73
+ try {
74
+ fs.unlinkSync(tempFile)
75
+ fs.rmdirSync(tempDir)
76
+ } catch (e) {}
77
+ })
78
+
79
+ it('POSTメソッドで送信されたJSONデータを取得できること', async () => {
80
+ let port = 0
81
+ const code = `
82
+ ●ダミー起動
83
+ 戻る。
84
+ ここまで。
85
+ ●受信処理
86
+ POSTデータ["message"]を簡易HTTPサーバ出力。
87
+ ここまで。
88
+ 「ダミー起動」を${port}で簡易HTTPサーバ起動時。
89
+ 「受信処理」を「/post-json」に簡易HTTPサーバ受信時。
90
+ `
91
+ const g = await nako.runAsync(code, 'main')
92
+ serverDp = g.__httpserver
93
+ await wait(100)
94
+ port = serverDp.server.address().port
95
+
96
+ const postData = JSON.stringify({ message: 'hello post json' })
97
+ const resText = await new Promise((resolve, reject) => {
98
+ const req = http.request({
99
+ hostname: 'localhost',
100
+ port: port,
101
+ path: '/post-json',
102
+ method: 'POST',
103
+ headers: {
104
+ 'Content-Type': 'application/json',
105
+ 'Content-Length': Buffer.byteLength(postData)
106
+ }
107
+ }, (res) => {
108
+ let data = ''
109
+ res.on('data', (chunk) => { data += chunk })
110
+ res.on('end', () => { resolve(data) })
111
+ })
112
+ req.on('error', reject)
113
+ req.write(postData)
114
+ req.end()
115
+ })
116
+
117
+ assert.strictEqual(resText, 'hello post json')
118
+ })
119
+
120
+ it('POSTメソッドで送信されたurlencodedデータを取得できること', async () => {
121
+ let port = 0
122
+ const code = `
123
+ ●ダミー起動
124
+ 戻る。
125
+ ここまで。
126
+ ●受信処理
127
+ POSTデータ["message"]を簡易HTTPサーバ出力。
128
+ ここまで。
129
+ 「ダミー起動」を${port}で簡易HTTPサーバ起動時。
130
+ 「受信処理」を「/post-urlencoded」に簡易HTTPサーバ受信時。
131
+ `
132
+ const g = await nako.runAsync(code, 'main')
133
+ serverDp = g.__httpserver
134
+ await wait(100)
135
+ port = serverDp.server.address().port
136
+
137
+ const postData = 'message=hello+post+urlencoded'
138
+ const resText = await new Promise((resolve, reject) => {
139
+ const req = http.request({
140
+ hostname: 'localhost',
141
+ port: port,
142
+ path: '/post-urlencoded',
143
+ method: 'POST',
144
+ headers: {
145
+ 'Content-Type': 'application/x-www-form-urlencoded',
146
+ 'Content-Length': Buffer.byteLength(postData)
147
+ }
148
+ }, (res) => {
149
+ let data = ''
150
+ res.on('data', (chunk) => { data += chunk })
151
+ res.on('end', () => { resolve(data) })
152
+ })
153
+ req.on('error', reject)
154
+ req.write(postData)
155
+ req.end()
156
+ })
157
+
158
+ assert.strictEqual(resText, 'hello post urlencoded')
159
+ })
160
+
161
+ it('POSTメソッドでファイルをアップロードしてFILESデータを取得できること', async () => {
162
+ const originalWriteFileSync = fs.writeFileSync
163
+ fs.writeFileSync = () => {
164
+ throw new Error('writeFileSync should not be used during upload handling')
165
+ }
166
+
167
+ let port = 0
168
+ const code = `
169
+ ●ダミー起動
170
+ 戻る。
171
+ ここまで。
172
+ ●受信処理
173
+ ファイル情報=FILESデータ[0]
174
+ もし、ファイル情報["path"]が空でなければ
175
+ ファイル名=ファイル情報["name"]
176
+ ファイルサイズ=ファイル情報["size"]
177
+ 「OK:{ファイル名}:{ファイルサイズ}」を簡易HTTPサーバ出力。
178
+ 違えば
179
+ 「NG」を簡易HTTPサーバ出力。
180
+ ここまで。
181
+ ここまで。
182
+ 「ダミー起動」を${port}で簡易HTTPサーバ起動時。
183
+ 「受信処理」を「/upload」に簡易HTTPサーバ受信時。
184
+ `
185
+ const g = await nako.runAsync(code, 'main')
186
+ serverDp = g.__httpserver
187
+ await wait(100)
188
+ port = serverDp.server.address().port
189
+
190
+ const boundary = '----TestBoundary'
191
+ const parts = [
192
+ `--${boundary}\r\n`,
193
+ `Content-Disposition: form-data; name="file1"; filename="hello.txt"\r\n`,
194
+ `Content-Type: text/plain\r\n\r\n`,
195
+ `hello world nako3 upload\r\n`,
196
+ `--${boundary}--\r\n`
197
+ ]
198
+ const postData = Buffer.from(parts.join(''))
199
+
200
+ const resText = await new Promise((resolve, reject) => {
201
+ const req = http.request({
202
+ hostname: 'localhost',
203
+ port: port,
204
+ path: '/upload',
205
+ method: 'POST',
206
+ headers: {
207
+ 'Content-Type': `multipart/form-data; boundary=${boundary}`,
208
+ 'Content-Length': postData.length
209
+ }
210
+ }, (res) => {
211
+ let data = ''
212
+ res.on('data', (chunk) => { data += chunk })
213
+ res.on('end', () => { resolve(data) })
214
+ })
215
+ req.on('error', reject)
216
+ req.write(postData)
217
+ req.end()
218
+ })
219
+
220
+ try {
221
+ assert.strictEqual(resText, 'OK:hello.txt:24')
222
+
223
+ const uploadDir = path.join(os.tmpdir(), 'nako3-plugin_httpserver_upload')
224
+ if (fs.existsSync(uploadDir)) {
225
+ const files = fs.readdirSync(uploadDir)
226
+ for (const file of files) {
227
+ try {
228
+ fs.unlinkSync(path.join(uploadDir, file))
229
+ } catch (e) {}
230
+ }
231
+ try {
232
+ fs.rmdirSync(uploadDir)
233
+ } catch (e) {}
234
+ }
235
+ } finally {
236
+ fs.writeFileSync = originalWriteFileSync
237
+ }
238
+ })
239
+ })
@@ -2,9 +2,11 @@
2
2
 
3
3
  ルート=母艦パスを「../../」で相対パス展開。
4
4
  DEMOパス=ルート&「/demo」
5
+ PORT=8888
5
6
 
6
- 8888で簡易HTTPサーバ起動時には
7
- 「起動しました」と表示。
7
+ PORTで簡易HTTPサーバ起動時には
8
+ 「起動しました。ブラウザで以下のURLにアクセスしてください。」と表示。
9
+ 「http://localhost:{PORT}」と表示。
8
10
  ここまで。
9
11
 
10
12
  # 挨拶