dsh-drawai 0.2.4 → 0.2.6

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/raster.js CHANGED
@@ -13,6 +13,8 @@
13
13
  */
14
14
 
15
15
  import { inflateSync } from 'node:zlib'
16
+ import { createRequire } from 'node:module'
17
+ import { pathToFileURL } from 'node:url'
16
18
 
17
19
  /** PNG 的 8 字节签名。 */
18
20
  const PNG_SIGNATURE = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]
@@ -267,24 +269,70 @@ export function looksLikeRaster(bytes) {
267
269
  return false
268
270
  }
269
271
 
272
+ /**
273
+ * sharp 可能装在哪:包名 + DSH profile 里那份(本机是这么装的)。
274
+ *
275
+ * 为什么本机路径写死:sharp 是可选依赖,没装它的部署不该因为我们 import 不到就崩;
276
+ * 而宿主进程的 cwd 是**用户的工作区**、不在插件的 node_modules 链上,所以裸包名
277
+ * 在这种部署里注定解析不到(package.json 里 sharp 也不是依赖)。
278
+ */
279
+ const SHARP_CANDIDATES = [
280
+ 'sharp',
281
+ 'C:/Users/86476/AppData/Roaming/npm/node_modules/@deepseek-ai/dsh/node_modules/sharp',
282
+ ]
283
+
284
+ /**
285
+ * 把候选解成**可 import 的入口文件 URL**。
286
+ *
287
+ * 这里踩过两个坑,都只能在真机上才发现:
288
+ * · 动态 import 的说明符必须是 URL 或裸包名,**给文件系统路径会抛
289
+ * ERR_UNSUPPORTED_ESM_URL_SCHEME**(`C:/…/sharp` 和 `C:/…/sharp/dist/index.cjs` 都是);
290
+ * · 给**目录**还会抛 ERR_UNSUPPORTED_DIR_IMPORT —— ESM 不认目录,哪怕那个目录里有 package.json
291
+ * (sharp 0.35 是 CJS,main 指向 ./dist/index.cjs)。
292
+ * 所以:先用 createRequire 的 require.resolve 解出**入口文件**,再用 pathToFileURL 转成
293
+ * file:// URL。require.resolve 只用来"定位"、不用来加载任何东西;也正因为它认 package.json 的
294
+ * exports/main,这条不依赖 sharp 内部目录布局(比写死 /dist/index.cjs 耐升级)。
295
+ */
296
+ function resolveSharpImport() {
297
+ const urls = []
298
+ const req = createRequire(import.meta.url)
299
+ const add = (candidate) => {
300
+ try {
301
+ const entry = req.resolve(candidate)
302
+ const url = pathToFileURL(entry).href
303
+ if (urls.indexOf(url) < 0) urls.push(url)
304
+ } catch (error) {
305
+ /* 这个候选不在(没装 / 解析不到),换下一个 */
306
+ }
307
+ }
308
+ for (const candidate of SHARP_CANDIDATES) add(candidate)
309
+ // 兜底:require.resolve 那条也可能失败(例如导出图把它藏了),此时按目录试常见入口。
310
+ // pathToFileURL 会把目录路径照常编成 file:// URL,import 再按 package.json 的 main 解析。
311
+ for (const candidate of SHARP_CANDIDATES) {
312
+ if (candidate === 'sharp') continue
313
+ add(candidate)
314
+ add(candidate + '/dist/index.cjs')
315
+ }
316
+ // 去重:兜底可能补出与前一条相同的 URL(entry 与 /dist/index.cjs 同址时)
317
+ const unique = urls.filter((value, index) => urls.indexOf(value) === index)
318
+ return unique
319
+ }
320
+
270
321
  /**
271
322
  * 非 PNG 的解码回退:**可选** sharp(宿主没装就返回 null,由调用方给一句人话报错)。
272
323
  *
273
324
  * 用动态 import 而不是顶层 import:没装 sharp 的部署不该连模块都加载不了。
274
- * 路径依次试:包名、DSH profile 里的那份(本机是这么装的)。
275
325
  */
276
326
  async function decodeWithSharp(bytes) {
277
- const candidates = [
278
- 'sharp',
279
- 'C:/Users/86476/AppData/Roaming/npm/node_modules/@deepseek-ai/dsh/node_modules/sharp',
280
- ]
281
- for (const spec of candidates) {
327
+ for (const spec of resolveSharpImport()) {
282
328
  let sharp
283
329
  try {
284
- sharp = (await import(spec)).default
330
+ const mod = await import(spec)
331
+ sharp = mod.default !== undefined && mod.default !== null ? mod.default : mod
285
332
  } catch (error) {
286
333
  continue
287
334
  }
335
+ if (typeof sharp !== 'function') continue
288
336
  try {
289
337
  const got = await sharp(Buffer.from(bytes)).ensureAlpha().raw().toBuffer({ resolveWithObject: true })
290
338
  return { width: got.info.width, height: got.info.height, data: got.data }