@inventec/dsh-onetree-log 0.1.2 → 0.1.3

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/lib/client.js CHANGED
@@ -231,7 +231,7 @@ window.__ModuleLoader__.load({
231
231
  },
232
232
  }, data.content),
233
233
  data && data.truncated && h('div', { style: { fontSize: '11px', opacity: 0.6, marginTop: '4px' } },
234
- `(仅显示前 ${humanBytes(data.content ? data.content.length : 0)},完整内容请到服务器查看解压目录)`),
234
+ `(仅显示前 ${humanBytes(data.previewBytes ?? (data.content ? data.content.length : 0))},完整内容请到服务器查看解压目录)`),
235
235
  )
236
236
  }
237
237
 
package/lib/index.js CHANGED
@@ -20,7 +20,6 @@
20
20
  import fs from 'node:fs'
21
21
  import path from 'node:path'
22
22
  import { pipeline } from 'node:stream/promises'
23
- import { Readable } from 'node:stream'
24
23
  import { DumpStore } from './store.js'
25
24
 
26
25
  export const name = '@inventec/dsh-onetree-log'
@@ -62,7 +61,6 @@ function readJsonBody(req) {
62
61
  /** 上传字节流 → 临时文件(限额流式落盘,不进内存)。 */
63
62
  async function saveUpload(req, destPath) {
64
63
  let received = 0
65
- const counter = new Readable().wrap(req) // 仅用于错误传播;直接流 req
66
64
  const out = fs.createWriteStream(destPath)
67
65
  await new Promise((resolve, reject) => {
68
66
  req.on('data', chunk => {
@@ -82,7 +80,6 @@ async function saveUpload(req, destPath) {
82
80
  req.on('error', reject)
83
81
  out.on('error', reject)
84
82
  })
85
- void counter
86
83
  }
87
84
 
88
85
  function sanitizeUploadName(raw) {
@@ -151,11 +148,14 @@ function previewFile(absPath) {
151
148
  if (looksBinary(buf)) {
152
149
  return { binary: true, size: stat.size, truncated: stat.size > len }
153
150
  }
151
+ const content = buf.toString('utf8')
154
152
  return {
155
153
  binary: false,
156
154
  size: stat.size,
157
155
  truncated: stat.size > len,
158
- content: buf.toString('utf8'),
156
+ content,
157
+ // UTF-8 实际字节数(content.length 是 UTF-16 字符数,中文日志会偏小)
158
+ previewBytes: Buffer.byteLength(content, 'utf8'),
159
159
  }
160
160
  } finally {
161
161
  fs.closeSync(handle)
@@ -188,7 +188,8 @@ async function dispatch(req, res, log) {
188
188
  return writeJson(res, 200, detail)
189
189
  }
190
190
  if (method === 'DELETE') {
191
- return writeJson(res, store.remove(id) ? 200 : 404, { ok: true })
191
+ const removed = store.remove(id)
192
+ return writeJson(res, removed ? 200 : 404, removed ? { ok: true } : { ok: false, error: 'dump 不存在' })
192
193
  }
193
194
  return writeJson(res, 405, { error: 'method not allowed' })
194
195
  }
package/lib/store.js CHANGED
@@ -77,7 +77,7 @@ export class DumpStore {
77
77
  return this.cache.get(key)
78
78
  }
79
79
 
80
- /** ingest 完成后的完整详情:meta + 现算的文件清单(带内存缓存)。 */
80
+ /** ingest 完成后的完整详情:meta + 现算的文件清单(每次调用全量重建)。 */
81
81
  detail(id) {
82
82
  const meta = this.get(id)
83
83
  if (!meta) return undefined
@@ -167,13 +167,10 @@ export class DumpStore {
167
167
  remove(id) {
168
168
  const meta = this.get(id)
169
169
  if (!meta) return false
170
- // path-dir:rootDir 是用户目录,绝不能删;只清登记目录(里面只有 meta.json)
170
+ // path-dir:rootDir 是用户目录,绝不能删;登记目录里只有 meta.json,
171
+ // 与其他类型一样整体清掉即可
171
172
  const home = path.join(this.dumpsDir, id)
172
- if (meta.sourceKind === 'path-dir') {
173
- fs.rmSync(home, { recursive: true, force: true })
174
- } else {
175
- fs.rmSync(home, { recursive: true, force: true })
176
- }
173
+ fs.rmSync(home, { recursive: true, force: true })
177
174
  this.cache.delete(id)
178
175
  return true
179
176
  }
@@ -183,7 +180,9 @@ export class DumpStore {
183
180
  const meta = this.get(id)
184
181
  if (!meta) throw new Error('dump 不存在')
185
182
  const rel = String(relPath ?? '')
186
- if (rel.includes('..') || rel.startsWith('/') || rel.includes('\0')) {
183
+ // 只按路径段拒绝 '..'('a..b.log' 这类合法文件名不误伤);越界仍由下方
184
+ // 前缀包含检查兜底,fail-safe 方向不变
185
+ if (rel.split(/[\\/]+/).includes('..') || rel.startsWith('/') || rel.includes('\0')) {
187
186
  throw new Error('非法的文件路径')
188
187
  }
189
188
  const target = path.resolve(meta.rootDir, ...rel.split('/').filter(s => s !== '' && s !== '.'))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inventec/dsh-onetree-log",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "AMI MegaRAC OneTree 一键日志(OpenBMC dreport dump)上传与分析框架:设置面板「OneTree 日志」上传压缩包或登记服务器本地路径,安全解包、自动探测 dump 根、文件清单分类,为第二阶段逐域解析提供内核。",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",