@tailwindcss/oxide-wasm32-wasi 4.2.4 → 4.3.1

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 (57) hide show
  1. package/node_modules/@emnapi/core/dist/emnapi-core.cjs.js +854 -307
  2. package/node_modules/@emnapi/core/dist/emnapi-core.cjs.min.d.ts +3 -2
  3. package/node_modules/@emnapi/core/dist/emnapi-core.cjs.min.js +1 -1
  4. package/node_modules/@emnapi/core/dist/emnapi-core.d.mts +3 -2
  5. package/node_modules/@emnapi/core/dist/emnapi-core.d.ts +3 -2
  6. package/node_modules/@emnapi/core/dist/emnapi-core.esm-bundler.js +892 -313
  7. package/node_modules/@emnapi/core/dist/emnapi-core.js +904 -328
  8. package/node_modules/@emnapi/core/dist/emnapi-core.min.d.mts +3 -2
  9. package/node_modules/@emnapi/core/dist/emnapi-core.min.js +1 -1
  10. package/node_modules/@emnapi/core/dist/emnapi-core.min.mjs +1 -1
  11. package/node_modules/@emnapi/core/dist/emnapi-core.mjs +854 -307
  12. package/node_modules/@emnapi/core/package.json +2 -2
  13. package/node_modules/@emnapi/runtime/dist/emnapi.cjs.js +32 -5
  14. package/node_modules/@emnapi/runtime/dist/emnapi.cjs.min.d.ts +8 -2
  15. package/node_modules/@emnapi/runtime/dist/emnapi.cjs.min.js +1 -1
  16. package/node_modules/@emnapi/runtime/dist/emnapi.d.mts +8 -2
  17. package/node_modules/@emnapi/runtime/dist/emnapi.d.ts +8 -2
  18. package/node_modules/@emnapi/runtime/dist/emnapi.esm-bundler.js +33 -5
  19. package/node_modules/@emnapi/runtime/dist/emnapi.iife.d.ts +8 -2
  20. package/node_modules/@emnapi/runtime/dist/emnapi.iife.js +33 -5
  21. package/node_modules/@emnapi/runtime/dist/emnapi.js +33 -5
  22. package/node_modules/@emnapi/runtime/dist/emnapi.min.d.mts +8 -2
  23. package/node_modules/@emnapi/runtime/dist/emnapi.min.js +1 -1
  24. package/node_modules/@emnapi/runtime/dist/emnapi.min.mjs +1 -1
  25. package/node_modules/@emnapi/runtime/dist/emnapi.mjs +32 -5
  26. package/node_modules/@emnapi/runtime/package.json +1 -1
  27. package/node_modules/@emnapi/wasi-threads/dist/wasi-threads.cjs.js +17 -20
  28. package/node_modules/@emnapi/wasi-threads/dist/wasi-threads.cjs.min.d.ts +2 -0
  29. package/node_modules/@emnapi/wasi-threads/dist/wasi-threads.cjs.min.js +1 -1
  30. package/node_modules/@emnapi/wasi-threads/dist/wasi-threads.d.mts +2 -0
  31. package/node_modules/@emnapi/wasi-threads/dist/wasi-threads.d.ts +2 -0
  32. package/node_modules/@emnapi/wasi-threads/dist/wasi-threads.esm-bundler.js +17 -20
  33. package/node_modules/@emnapi/wasi-threads/dist/wasi-threads.js +17 -20
  34. package/node_modules/@emnapi/wasi-threads/dist/wasi-threads.min.d.mts +2 -0
  35. package/node_modules/@emnapi/wasi-threads/dist/wasi-threads.min.js +1 -1
  36. package/node_modules/@emnapi/wasi-threads/dist/wasi-threads.min.mjs +1 -1
  37. package/node_modules/@emnapi/wasi-threads/dist/wasi-threads.mjs +17 -20
  38. package/node_modules/@emnapi/wasi-threads/package.json +1 -1
  39. package/node_modules/@napi-rs/wasm-runtime/dist/fs-proxy.cjs +47 -12
  40. package/node_modules/@napi-rs/wasm-runtime/dist/fs.js +14310 -10201
  41. package/node_modules/@napi-rs/wasm-runtime/fs-proxy.js +47 -12
  42. package/node_modules/@napi-rs/wasm-runtime/package.json +6 -4
  43. package/node_modules/@tybys/wasm-util/dist/wasm-util.esm-bundler.js +164 -2
  44. package/node_modules/@tybys/wasm-util/dist/wasm-util.esm.js +164 -2
  45. package/node_modules/@tybys/wasm-util/dist/wasm-util.esm.min.js +1 -1
  46. package/node_modules/@tybys/wasm-util/dist/wasm-util.js +164 -2
  47. package/node_modules/@tybys/wasm-util/dist/wasm-util.min.js +1 -1
  48. package/node_modules/@tybys/wasm-util/lib/cjs/wasi/path.js +142 -0
  49. package/node_modules/@tybys/wasm-util/lib/cjs/wasi/preview1.js +22 -2
  50. package/node_modules/@tybys/wasm-util/lib/mjs/wasi/path.mjs +142 -0
  51. package/node_modules/@tybys/wasm-util/lib/mjs/wasi/preview1.mjs +22 -2
  52. package/node_modules/@tybys/wasm-util/package.json +1 -1
  53. package/package.json +6 -6
  54. package/tailwindcss-oxide.wasi-browser.js +1 -0
  55. package/tailwindcss-oxide.wasi.cjs +1 -1
  56. package/tailwindcss-oxide.wasm32-wasi.wasm +0 -0
  57. package/wasi-worker-browser.mjs +2 -0
@@ -15,6 +15,21 @@ const getType = (value) => {
15
15
  return -1
16
16
  }
17
17
 
18
+ const RESPONSE_HEADER_SIZE = 16
19
+ const RESPONSE_PAYLOAD_SIZE = 10240
20
+ const RESPONSE_BUFFER_SIZE = RESPONSE_HEADER_SIZE + RESPONSE_PAYLOAD_SIZE
21
+
22
+ /**
23
+ * @param {Int32Array} sab
24
+ * @param {Uint8Array} payload
25
+ */
26
+ const writeResponsePayload = (sab, payload) => {
27
+ if (payload.length > RESPONSE_PAYLOAD_SIZE) {
28
+ throw new RangeError('payload overflow')
29
+ }
30
+ new Uint8Array(sab.buffer).set(payload, RESPONSE_HEADER_SIZE)
31
+ }
32
+
18
33
  /**
19
34
  * @param {import('memfs').IFs} memfs
20
35
  * @param {any} value
@@ -89,9 +104,7 @@ const encodeValue = (memfs, value, type) => {
89
104
  return view
90
105
  }
91
106
  case 9: {
92
- const view = new BigInt64Array(1)
93
- view[0] = value
94
- return new Uint8Array(view.buffer)
107
+ return new TextEncoder().encode(String(value))
95
108
  }
96
109
  case -1:
97
110
  default:
@@ -176,8 +189,9 @@ const decodeValue = (memfs, payload, type) => {
176
189
  }
177
190
  return obj
178
191
  }
179
- if (type === 9)
180
- return new BigInt64Array(payload.buffer, payload.byteOffset, 1)[0]
192
+ if (type === 9) {
193
+ return BigInt(new TextDecoder().decode(payload.slice()))
194
+ }
181
195
  throw new Error('unsupported data')
182
196
  }
183
197
 
@@ -192,7 +206,7 @@ export const createOnMessage = (fs) =>
192
206
  /**
193
207
  * 0..4 status(int32_t): 21(waiting) 0(success) 1(error)
194
208
  * 5..8 type(napi_valuetype): 0(undefined) 1(null) 2(boolean) 3(number) 4(string) 6(jsonstring) 9(bigint) -1(unsupported)
195
- * 9..16 payload_size(uint32_t) <= 1024
209
+ * 9..16 payload_size(uint32_t) <= 10240
196
210
  * 16..16 + payload_size payload_content
197
211
  */
198
212
  const { sab, type, payload } = e.data.__fs__
@@ -203,14 +217,35 @@ export const createOnMessage = (fs) =>
203
217
  Atomics.store(sab, 1, t)
204
218
  const v = encodeValue(fs, ret, t)
205
219
  Atomics.store(sab, 2, v.length)
206
- new Uint8Array(sab.buffer).set(v, 16)
220
+ writeResponsePayload(sab, v)
207
221
  Atomics.store(sab, 0, 0) // success
208
222
  } catch (/** @type {any} */ err) {
209
- const t = getType(err)
223
+ let t = getType(err)
224
+ let v
225
+ try {
226
+ if (t === -1) {
227
+ throw new Error('unsupported data')
228
+ }
229
+ v = encodeValue(fs, err, t)
230
+ } catch {
231
+ const fallback = (() => {
232
+ try {
233
+ return String(err)
234
+ } catch {
235
+ return 'Unserializable thrown value'
236
+ }
237
+ })()
238
+ t = getType(fallback)
239
+ v = encodeValue(fs, fallback, t)
240
+ }
241
+ if (v.length > RESPONSE_PAYLOAD_SIZE) {
242
+ const overflowErr = new RangeError('payload overflow')
243
+ t = getType(overflowErr)
244
+ v = encodeValue(fs, overflowErr, t)
245
+ }
210
246
  Atomics.store(sab, 1, t)
211
- const v = encodeValue(fs, err, t)
212
247
  Atomics.store(sab, 2, v.length)
213
- new Uint8Array(sab.buffer).set(v, 16)
248
+ writeResponsePayload(sab, v)
214
249
  Atomics.store(sab, 0, 1) // error
215
250
  } finally {
216
251
  Atomics.notify(sab, 0)
@@ -230,7 +265,7 @@ export const createFsProxy = (memfs) =>
230
265
  * @param {any[]} args
231
266
  */
232
267
  return function (...args) {
233
- const sab = new SharedArrayBuffer(16 + 10240)
268
+ const sab = new SharedArrayBuffer(RESPONSE_BUFFER_SIZE)
234
269
  const i32arr = new Int32Array(sab)
235
270
  Atomics.store(i32arr, 0, 21)
236
271
 
@@ -247,7 +282,7 @@ export const createFsProxy = (memfs) =>
247
282
  const status = Atomics.load(i32arr, 0)
248
283
  const type = Atomics.load(i32arr, 1)
249
284
  const size = Atomics.load(i32arr, 2)
250
- const content = new Uint8Array(sab, 16, size)
285
+ const content = new Uint8Array(sab, RESPONSE_HEADER_SIZE, size)
251
286
  const value = decodeValue(memfs, content, type)
252
287
  if (status === 1) {
253
288
  throw value
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@napi-rs/wasm-runtime",
3
- "version": "1.1.1",
3
+ "version": "1.1.4",
4
4
  "type": "module",
5
5
  "description": "Runtime and polyfill for wasm targets",
6
6
  "homepage": "https://napi.rs/",
@@ -11,7 +11,7 @@
11
11
  "repository": {
12
12
  "type": "git",
13
13
  "url": "git+https://github.com/napi-rs/napi-rs.git",
14
- "directory": "wasi-runtime"
14
+ "directory": "wasm-runtime"
15
15
  },
16
16
  "license": "MIT",
17
17
  "publishConfig": {
@@ -44,10 +44,12 @@
44
44
  "tslib": "^2.8.1"
45
45
  },
46
46
  "dependencies": {
47
- "@emnapi/core": "^1.7.1",
48
- "@emnapi/runtime": "^1.7.1",
49
47
  "@tybys/wasm-util": "^0.10.1"
50
48
  },
49
+ "peerDependencies": {
50
+ "@emnapi/core": "^1.7.1",
51
+ "@emnapi/runtime": "^1.7.1"
52
+ },
51
53
  "scripts": {
52
54
  "build": "rollup -c rollup.config.js",
53
55
  "test": "node --test"
@@ -306,6 +306,141 @@ function asyncifyLoadSync(asyncify, buffer, imports) {
306
306
 
307
307
  const CHAR_DOT = 46; /* . */
308
308
  const CHAR_FORWARD_SLASH = 47; /* / */
309
+ const CHAR_BACKWARD_SLASH = 92; /* \ */
310
+ const CHAR_COLON = 58; /* : */
311
+ const CHAR_UPPERCASE_A = 65; /* A */
312
+ const CHAR_UPPERCASE_Z = 90; /* Z */
313
+ const CHAR_LOWERCASE_A = 97; /* a */
314
+ const CHAR_LOWERCASE_Z = 122; /* z */
315
+ function isPathSeparatorWin(code) {
316
+ return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
317
+ }
318
+ function isWindowsDeviceRoot(code) {
319
+ return (code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) ||
320
+ (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z);
321
+ }
322
+ const _isWin32 = typeof process !== 'undefined' && process.platform === 'win32';
323
+ /**
324
+ * Windows variant of `resolve()`. Mirrors Node's `path.win32.resolve`
325
+ * semantics enough for the WASI shim's needs (drive-letter absolutes
326
+ * + UNC paths + per-drive cwd lookups via `process.env`/`process.cwd`).
327
+ *
328
+ * Why this is needed: on Windows, `FileDescriptor.realPath` is the
329
+ * host realpath returned by `fs.realpathSync(realPath, 'utf8')` — the
330
+ * backslash form `D:\…`. The POSIX-only `resolveImpl` below only
331
+ * treats `/` as a separator, reads `D` as non-`/`, decides realPath
332
+ * is "relative", and produces a garbage joined path. Downstream
333
+ * `fs.openSync(garbage)` then returns `EINVAL` and the WASI caller
334
+ * sees a permanent failure. This function gives us the correct
335
+ * Windows-style resolution without taking a Node-only `path` import
336
+ * (which would break browser bundles of this package).
337
+ *
338
+ * Cribbed from Node's `lib/path.js` `win32.resolve()` (MIT-licensed),
339
+ * trimmed to what WASI realpath resolution actually exercises.
340
+ */
341
+ function resolveWin32(args) {
342
+ let resolvedDevice = '';
343
+ let resolvedTail = '';
344
+ let resolvedAbsolute = false;
345
+ for (let i = args.length - 1; i >= -1; i--) {
346
+ let path;
347
+ if (i >= 0) {
348
+ path = args[i];
349
+ validateString(path, 'path');
350
+ if (path.length === 0)
351
+ continue;
352
+ }
353
+ else if (resolvedDevice.length === 0) {
354
+ path = (typeof process !== 'undefined' && typeof process.cwd === 'function')
355
+ ? process.cwd()
356
+ : '';
357
+ }
358
+ else {
359
+ // Look up per-drive cwd via the `=X:` env var convention; fall back
360
+ // to the global cwd if absent.
361
+ const envKey = `=${resolvedDevice}`;
362
+ const env = (typeof process !== 'undefined') ? process.env : undefined;
363
+ path = (env && typeof env[envKey] === 'string')
364
+ ? env[envKey]
365
+ : (typeof process !== 'undefined' && typeof process.cwd === 'function')
366
+ ? process.cwd()
367
+ : '';
368
+ if (path === undefined ||
369
+ (path.slice(0, 2).toLowerCase() !== resolvedDevice.toLowerCase() &&
370
+ path.charCodeAt(2) === CHAR_BACKWARD_SLASH)) {
371
+ path = `${resolvedDevice}\\`;
372
+ }
373
+ }
374
+ const len = path.length;
375
+ let rootEnd = 0;
376
+ let device = '';
377
+ let isAbsolute = false;
378
+ const code = path.charCodeAt(0);
379
+ if (len === 1) {
380
+ if (isPathSeparatorWin(code)) {
381
+ rootEnd = 1;
382
+ isAbsolute = true;
383
+ }
384
+ }
385
+ else if (isPathSeparatorWin(code)) {
386
+ isAbsolute = true;
387
+ if (isPathSeparatorWin(path.charCodeAt(1))) {
388
+ // UNC path: `\\server\share\…`
389
+ let j = 2;
390
+ let last = j;
391
+ while (j < len && !isPathSeparatorWin(path.charCodeAt(j)))
392
+ j++;
393
+ if (j < len && j !== last) {
394
+ const firstPart = path.slice(last, j);
395
+ last = j;
396
+ while (j < len && isPathSeparatorWin(path.charCodeAt(j)))
397
+ j++;
398
+ if (j < len && j !== last) {
399
+ last = j;
400
+ while (j < len && !isPathSeparatorWin(path.charCodeAt(j)))
401
+ j++;
402
+ if (j === len || j !== last) {
403
+ device = `\\\\${firstPart}\\${path.slice(last, j)}`;
404
+ rootEnd = j;
405
+ }
406
+ }
407
+ }
408
+ }
409
+ else {
410
+ rootEnd = 1;
411
+ }
412
+ }
413
+ else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {
414
+ device = path.slice(0, 2);
415
+ rootEnd = 2;
416
+ if (len > 2 && isPathSeparatorWin(path.charCodeAt(2))) {
417
+ isAbsolute = true;
418
+ rootEnd = 3;
419
+ }
420
+ }
421
+ if (device.length > 0) {
422
+ if (resolvedDevice.length > 0) {
423
+ if (device.toLowerCase() !== resolvedDevice.toLowerCase())
424
+ continue;
425
+ }
426
+ else {
427
+ resolvedDevice = device;
428
+ }
429
+ }
430
+ if (resolvedAbsolute) {
431
+ if (resolvedDevice.length > 0)
432
+ break;
433
+ }
434
+ else {
435
+ resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`;
436
+ resolvedAbsolute = isAbsolute;
437
+ if (isAbsolute && resolvedDevice.length > 0)
438
+ break;
439
+ }
440
+ }
441
+ resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, '\\', isPathSeparatorWin);
442
+ return resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail || '.';
443
+ }
309
444
  function isPosixPathSeparator(code) {
310
445
  return code === CHAR_FORWARD_SLASH;
311
446
  }
@@ -381,6 +516,13 @@ function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
381
516
  return res;
382
517
  }
383
518
  function resolve(...args) {
519
+ // On Windows, host paths are `D:\…` style. The POSIX-only resolver
520
+ // below treats `D` as a non-`/` character and produces garbage; route
521
+ // to the Windows-aware variant. POSIX hosts (Linux/macOS/browser)
522
+ // run the original code path unchanged — `_isWin32` is constant-folded
523
+ // away on those targets.
524
+ if (_isWin32)
525
+ return resolveWin32(args);
384
526
  let resolvedPath = '';
385
527
  let resolvedAbsolute = false;
386
528
  for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
@@ -1017,6 +1159,26 @@ function wrapExports(exports, needWrap) {
1017
1159
  });
1018
1160
  }
1019
1161
 
1162
+ // Linux fcntl flag bits ↔ Windows libuv flag bits. `pathOpen()` builds
1163
+ // `flagsRes` using Linux constants (O_CREAT=0x40, O_EXCL=0x80,
1164
+ // O_APPEND=0x400). Windows libuv expects different bits (O_CREAT=0x100,
1165
+ // O_EXCL=0x400, O_APPEND=0x8). Without translation,
1166
+ // `fs.openSync(path, 0x241 /* L:WRONLY|CREAT|TRUNC */)` is rejected
1167
+ // with EINVAL because Linux's 0x40 happens to mean O_TEMPORARY on
1168
+ // Windows — and O_TEMPORARY without O_CREAT is invalid.
1169
+ const _isWin32Flags = typeof process !== 'undefined' && process.platform === 'win32';
1170
+ function _toWinOpenFlags(f) {
1171
+ let r = f & 3; // RDONLY/WRONLY/RDWR — same on both
1172
+ if ((f & 0x40) !== 0)
1173
+ r |= 0x100; // O_CREAT: Linux 0x40 -> Windows 0x100
1174
+ if ((f & 0x80) !== 0)
1175
+ r |= 0x400; // O_EXCL: Linux 0x80 -> Windows 0x400
1176
+ if ((f & 0x200) !== 0)
1177
+ r |= 0x200; // O_TRUNC: same value on both
1178
+ if ((f & 0x400) !== 0)
1179
+ r |= 0x8; // O_APPEND: Linux 0x400 -> Windows 0x8
1180
+ return r;
1181
+ }
1020
1182
  function copyMemory(targets, src) {
1021
1183
  if (targets.length === 0 || src.length === 0)
1022
1184
  return 0;
@@ -2273,7 +2435,7 @@ class WASI$1 {
2273
2435
  const pathString = decoder.decode(unsharedSlice(HEAPU8, path, path + path_len));
2274
2436
  const fs = getFs(this);
2275
2437
  const resolved_path = resolvePathSync(fs, fileDescriptor, pathString, dirflags);
2276
- const r = fs.openSync(resolved_path, flagsRes, 0o666);
2438
+ const r = fs.openSync(resolved_path, _isWin32Flags ? _toWinOpenFlags(flagsRes) : flagsRes, 0o666);
2277
2439
  const filetype = wasi.fds.getFileTypeByFd(r);
2278
2440
  if ((filetype !== 3 /* WasiFileType.DIRECTORY */) &&
2279
2441
  ((o_flags & 2 /* WasiFileControlFlag.O_DIRECTORY */) !== 0 ||
@@ -2309,7 +2471,7 @@ class WASI$1 {
2309
2471
  const pathString = decoder.decode(unsharedSlice(HEAPU8, path, path + path_len));
2310
2472
  const fs = getFs(this);
2311
2473
  const resolved_path = await resolvePathAsync(fs, fileDescriptor, pathString, dirflags);
2312
- const r = await fs.promises.open(resolved_path, flagsRes, 0o666);
2474
+ const r = await fs.promises.open(resolved_path, _isWin32Flags ? _toWinOpenFlags(flagsRes) : flagsRes, 0o666);
2313
2475
  const filetype = await wasi.fds.getFileTypeByFd(r);
2314
2476
  if ((o_flags & 2 /* WasiFileControlFlag.O_DIRECTORY */) !== 0 && filetype !== 3 /* WasiFileType.DIRECTORY */) {
2315
2477
  return 54 /* WasiErrno.ENOTDIR */;
@@ -306,6 +306,141 @@ function asyncifyLoadSync(asyncify, buffer, imports) {
306
306
 
307
307
  const CHAR_DOT = 46; /* . */
308
308
  const CHAR_FORWARD_SLASH = 47; /* / */
309
+ const CHAR_BACKWARD_SLASH = 92; /* \ */
310
+ const CHAR_COLON = 58; /* : */
311
+ const CHAR_UPPERCASE_A = 65; /* A */
312
+ const CHAR_UPPERCASE_Z = 90; /* Z */
313
+ const CHAR_LOWERCASE_A = 97; /* a */
314
+ const CHAR_LOWERCASE_Z = 122; /* z */
315
+ function isPathSeparatorWin(code) {
316
+ return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
317
+ }
318
+ function isWindowsDeviceRoot(code) {
319
+ return (code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) ||
320
+ (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z);
321
+ }
322
+ const _isWin32 = typeof process !== 'undefined' && process.platform === 'win32';
323
+ /**
324
+ * Windows variant of `resolve()`. Mirrors Node's `path.win32.resolve`
325
+ * semantics enough for the WASI shim's needs (drive-letter absolutes
326
+ * + UNC paths + per-drive cwd lookups via `process.env`/`process.cwd`).
327
+ *
328
+ * Why this is needed: on Windows, `FileDescriptor.realPath` is the
329
+ * host realpath returned by `fs.realpathSync(realPath, 'utf8')` — the
330
+ * backslash form `D:\…`. The POSIX-only `resolveImpl` below only
331
+ * treats `/` as a separator, reads `D` as non-`/`, decides realPath
332
+ * is "relative", and produces a garbage joined path. Downstream
333
+ * `fs.openSync(garbage)` then returns `EINVAL` and the WASI caller
334
+ * sees a permanent failure. This function gives us the correct
335
+ * Windows-style resolution without taking a Node-only `path` import
336
+ * (which would break browser bundles of this package).
337
+ *
338
+ * Cribbed from Node's `lib/path.js` `win32.resolve()` (MIT-licensed),
339
+ * trimmed to what WASI realpath resolution actually exercises.
340
+ */
341
+ function resolveWin32(args) {
342
+ let resolvedDevice = '';
343
+ let resolvedTail = '';
344
+ let resolvedAbsolute = false;
345
+ for (let i = args.length - 1; i >= -1; i--) {
346
+ let path;
347
+ if (i >= 0) {
348
+ path = args[i];
349
+ validateString(path, 'path');
350
+ if (path.length === 0)
351
+ continue;
352
+ }
353
+ else if (resolvedDevice.length === 0) {
354
+ path = (typeof process !== 'undefined' && typeof process.cwd === 'function')
355
+ ? process.cwd()
356
+ : '';
357
+ }
358
+ else {
359
+ // Look up per-drive cwd via the `=X:` env var convention; fall back
360
+ // to the global cwd if absent.
361
+ const envKey = `=${resolvedDevice}`;
362
+ const env = (typeof process !== 'undefined') ? process.env : undefined;
363
+ path = (env && typeof env[envKey] === 'string')
364
+ ? env[envKey]
365
+ : (typeof process !== 'undefined' && typeof process.cwd === 'function')
366
+ ? process.cwd()
367
+ : '';
368
+ if (path === undefined ||
369
+ (path.slice(0, 2).toLowerCase() !== resolvedDevice.toLowerCase() &&
370
+ path.charCodeAt(2) === CHAR_BACKWARD_SLASH)) {
371
+ path = `${resolvedDevice}\\`;
372
+ }
373
+ }
374
+ const len = path.length;
375
+ let rootEnd = 0;
376
+ let device = '';
377
+ let isAbsolute = false;
378
+ const code = path.charCodeAt(0);
379
+ if (len === 1) {
380
+ if (isPathSeparatorWin(code)) {
381
+ rootEnd = 1;
382
+ isAbsolute = true;
383
+ }
384
+ }
385
+ else if (isPathSeparatorWin(code)) {
386
+ isAbsolute = true;
387
+ if (isPathSeparatorWin(path.charCodeAt(1))) {
388
+ // UNC path: `\\server\share\…`
389
+ let j = 2;
390
+ let last = j;
391
+ while (j < len && !isPathSeparatorWin(path.charCodeAt(j)))
392
+ j++;
393
+ if (j < len && j !== last) {
394
+ const firstPart = path.slice(last, j);
395
+ last = j;
396
+ while (j < len && isPathSeparatorWin(path.charCodeAt(j)))
397
+ j++;
398
+ if (j < len && j !== last) {
399
+ last = j;
400
+ while (j < len && !isPathSeparatorWin(path.charCodeAt(j)))
401
+ j++;
402
+ if (j === len || j !== last) {
403
+ device = `\\\\${firstPart}\\${path.slice(last, j)}`;
404
+ rootEnd = j;
405
+ }
406
+ }
407
+ }
408
+ }
409
+ else {
410
+ rootEnd = 1;
411
+ }
412
+ }
413
+ else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {
414
+ device = path.slice(0, 2);
415
+ rootEnd = 2;
416
+ if (len > 2 && isPathSeparatorWin(path.charCodeAt(2))) {
417
+ isAbsolute = true;
418
+ rootEnd = 3;
419
+ }
420
+ }
421
+ if (device.length > 0) {
422
+ if (resolvedDevice.length > 0) {
423
+ if (device.toLowerCase() !== resolvedDevice.toLowerCase())
424
+ continue;
425
+ }
426
+ else {
427
+ resolvedDevice = device;
428
+ }
429
+ }
430
+ if (resolvedAbsolute) {
431
+ if (resolvedDevice.length > 0)
432
+ break;
433
+ }
434
+ else {
435
+ resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`;
436
+ resolvedAbsolute = isAbsolute;
437
+ if (isAbsolute && resolvedDevice.length > 0)
438
+ break;
439
+ }
440
+ }
441
+ resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, '\\', isPathSeparatorWin);
442
+ return resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail || '.';
443
+ }
309
444
  function isPosixPathSeparator(code) {
310
445
  return code === CHAR_FORWARD_SLASH;
311
446
  }
@@ -381,6 +516,13 @@ function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
381
516
  return res;
382
517
  }
383
518
  function resolve(...args) {
519
+ // On Windows, host paths are `D:\…` style. The POSIX-only resolver
520
+ // below treats `D` as a non-`/` character and produces garbage; route
521
+ // to the Windows-aware variant. POSIX hosts (Linux/macOS/browser)
522
+ // run the original code path unchanged — `_isWin32` is constant-folded
523
+ // away on those targets.
524
+ if (_isWin32)
525
+ return resolveWin32(args);
384
526
  let resolvedPath = '';
385
527
  let resolvedAbsolute = false;
386
528
  for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
@@ -1017,6 +1159,26 @@ function wrapExports(exports, needWrap) {
1017
1159
  });
1018
1160
  }
1019
1161
 
1162
+ // Linux fcntl flag bits ↔ Windows libuv flag bits. `pathOpen()` builds
1163
+ // `flagsRes` using Linux constants (O_CREAT=0x40, O_EXCL=0x80,
1164
+ // O_APPEND=0x400). Windows libuv expects different bits (O_CREAT=0x100,
1165
+ // O_EXCL=0x400, O_APPEND=0x8). Without translation,
1166
+ // `fs.openSync(path, 0x241 /* L:WRONLY|CREAT|TRUNC */)` is rejected
1167
+ // with EINVAL because Linux's 0x40 happens to mean O_TEMPORARY on
1168
+ // Windows — and O_TEMPORARY without O_CREAT is invalid.
1169
+ const _isWin32Flags = typeof process !== 'undefined' && process.platform === 'win32';
1170
+ function _toWinOpenFlags(f) {
1171
+ let r = f & 3; // RDONLY/WRONLY/RDWR — same on both
1172
+ if ((f & 0x40) !== 0)
1173
+ r |= 0x100; // O_CREAT: Linux 0x40 -> Windows 0x100
1174
+ if ((f & 0x80) !== 0)
1175
+ r |= 0x400; // O_EXCL: Linux 0x80 -> Windows 0x400
1176
+ if ((f & 0x200) !== 0)
1177
+ r |= 0x200; // O_TRUNC: same value on both
1178
+ if ((f & 0x400) !== 0)
1179
+ r |= 0x8; // O_APPEND: Linux 0x400 -> Windows 0x8
1180
+ return r;
1181
+ }
1020
1182
  function copyMemory(targets, src) {
1021
1183
  if (targets.length === 0 || src.length === 0)
1022
1184
  return 0;
@@ -2273,7 +2435,7 @@ class WASI$1 {
2273
2435
  const pathString = decoder.decode(unsharedSlice(HEAPU8, path, path + path_len));
2274
2436
  const fs = getFs(this);
2275
2437
  const resolved_path = resolvePathSync(fs, fileDescriptor, pathString, dirflags);
2276
- const r = fs.openSync(resolved_path, flagsRes, 0o666);
2438
+ const r = fs.openSync(resolved_path, _isWin32Flags ? _toWinOpenFlags(flagsRes) : flagsRes, 0o666);
2277
2439
  const filetype = wasi.fds.getFileTypeByFd(r);
2278
2440
  if ((filetype !== 3 /* WasiFileType.DIRECTORY */) &&
2279
2441
  ((o_flags & 2 /* WasiFileControlFlag.O_DIRECTORY */) !== 0 ||
@@ -2309,7 +2471,7 @@ class WASI$1 {
2309
2471
  const pathString = decoder.decode(unsharedSlice(HEAPU8, path, path + path_len));
2310
2472
  const fs = getFs(this);
2311
2473
  const resolved_path = await resolvePathAsync(fs, fileDescriptor, pathString, dirflags);
2312
- const r = await fs.promises.open(resolved_path, flagsRes, 0o666);
2474
+ const r = await fs.promises.open(resolved_path, _isWin32Flags ? _toWinOpenFlags(flagsRes) : flagsRes, 0o666);
2313
2475
  const filetype = await wasi.fds.getFileTypeByFd(r);
2314
2476
  if ((o_flags & 2 /* WasiFileControlFlag.O_DIRECTORY */) !== 0 && filetype !== 3 /* WasiFileType.DIRECTORY */) {
2315
2477
  return 54 /* WasiErrno.ENOTDIR */;