file.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. 'use strict'
  2. const { Blob, File } = require('node:buffer')
  3. const { kState } = require('./symbols')
  4. const { webidl } = require('./webidl')
  5. // TODO(@KhafraDev): remove
  6. class FileLike {
  7. constructor (blobLike, fileName, options = {}) {
  8. // TODO: argument idl type check
  9. // The File constructor is invoked with two or three parameters, depending
  10. // on whether the optional dictionary parameter is used. When the File()
  11. // constructor is invoked, user agents must run the following steps:
  12. // 1. Let bytes be the result of processing blob parts given fileBits and
  13. // options.
  14. // 2. Let n be the fileName argument to the constructor.
  15. const n = fileName
  16. // 3. Process FilePropertyBag dictionary argument by running the following
  17. // substeps:
  18. // 1. If the type member is provided and is not the empty string, let t
  19. // be set to the type dictionary member. If t contains any characters
  20. // outside the range U+0020 to U+007E, then set t to the empty string
  21. // and return from these substeps.
  22. // TODO
  23. const t = options.type
  24. // 2. Convert every character in t to ASCII lowercase.
  25. // TODO
  26. // 3. If the lastModified member is provided, let d be set to the
  27. // lastModified dictionary member. If it is not provided, set d to the
  28. // current date and time represented as the number of milliseconds since
  29. // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]).
  30. const d = options.lastModified ?? Date.now()
  31. // 4. Return a new File object F such that:
  32. // F refers to the bytes byte sequence.
  33. // F.size is set to the number of total bytes in bytes.
  34. // F.name is set to n.
  35. // F.type is set to t.
  36. // F.lastModified is set to d.
  37. this[kState] = {
  38. blobLike,
  39. name: n,
  40. type: t,
  41. lastModified: d
  42. }
  43. }
  44. stream (...args) {
  45. webidl.brandCheck(this, FileLike)
  46. return this[kState].blobLike.stream(...args)
  47. }
  48. arrayBuffer (...args) {
  49. webidl.brandCheck(this, FileLike)
  50. return this[kState].blobLike.arrayBuffer(...args)
  51. }
  52. slice (...args) {
  53. webidl.brandCheck(this, FileLike)
  54. return this[kState].blobLike.slice(...args)
  55. }
  56. text (...args) {
  57. webidl.brandCheck(this, FileLike)
  58. return this[kState].blobLike.text(...args)
  59. }
  60. get size () {
  61. webidl.brandCheck(this, FileLike)
  62. return this[kState].blobLike.size
  63. }
  64. get type () {
  65. webidl.brandCheck(this, FileLike)
  66. return this[kState].blobLike.type
  67. }
  68. get name () {
  69. webidl.brandCheck(this, FileLike)
  70. return this[kState].name
  71. }
  72. get lastModified () {
  73. webidl.brandCheck(this, FileLike)
  74. return this[kState].lastModified
  75. }
  76. get [Symbol.toStringTag] () {
  77. return 'File'
  78. }
  79. }
  80. webidl.converters.Blob = webidl.interfaceConverter(Blob)
  81. // If this function is moved to ./util.js, some tools (such as
  82. // rollup) will warn about circular dependencies. See:
  83. // https://github.com/nodejs/undici/issues/1629
  84. function isFileLike (object) {
  85. return (
  86. (object instanceof File) ||
  87. (
  88. object &&
  89. (typeof object.stream === 'function' ||
  90. typeof object.arrayBuffer === 'function') &&
  91. object[Symbol.toStringTag] === 'File'
  92. )
  93. )
  94. }
  95. module.exports = { FileLike, isFileLike }