SyncAsyncFileSystemDecorator.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. /** @typedef {import("./Resolver").FileSystem} FileSystem */
  7. /** @typedef {import("./Resolver").StringCallback} StringCallback */
  8. /** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */
  9. // eslint-disable-next-line jsdoc/no-restricted-syntax
  10. /** @typedef {Function} SyncOrAsyncFunction */
  11. // eslint-disable-next-line jsdoc/no-restricted-syntax
  12. /** @typedef {any} ResultOfSyncOrAsyncFunction */
  13. /**
  14. * @param {SyncFileSystem} fs file system implementation
  15. * @constructor
  16. */
  17. function SyncAsyncFileSystemDecorator(fs) {
  18. this.fs = fs;
  19. this.lstat = undefined;
  20. this.lstatSync = undefined;
  21. const { lstatSync } = fs;
  22. if (lstatSync) {
  23. this.lstat =
  24. /** @type {FileSystem["lstat"]} */
  25. (
  26. (arg, options, callback) => {
  27. let result;
  28. try {
  29. result = /** @type {SyncOrAsyncFunction | undefined} */ (callback)
  30. ? lstatSync.call(fs, arg, options)
  31. : lstatSync.call(fs, arg);
  32. } catch (err) {
  33. return (callback || options)(
  34. /** @type {NodeJS.ErrnoException | null} */
  35. (err),
  36. );
  37. }
  38. (callback || options)(
  39. null,
  40. /** @type {ResultOfSyncOrAsyncFunction} */
  41. (result),
  42. );
  43. }
  44. );
  45. this.lstatSync =
  46. /** @type {SyncFileSystem["lstatSync"]} */
  47. ((arg, options) => lstatSync.call(fs, arg, options));
  48. }
  49. this.stat =
  50. /** @type {FileSystem["stat"]} */
  51. (
  52. (arg, options, callback) => {
  53. let result;
  54. try {
  55. result = /** @type {SyncOrAsyncFunction | undefined} */ (callback)
  56. ? fs.statSync(arg, options)
  57. : fs.statSync(arg);
  58. } catch (err) {
  59. return (callback || options)(
  60. /** @type {NodeJS.ErrnoException | null} */
  61. (err),
  62. );
  63. }
  64. (callback || options)(
  65. null,
  66. /** @type {ResultOfSyncOrAsyncFunction} */
  67. (result),
  68. );
  69. }
  70. );
  71. this.statSync =
  72. /** @type {SyncFileSystem["statSync"]} */
  73. ((arg, options) => fs.statSync(arg, options));
  74. this.readdir =
  75. /** @type {FileSystem["readdir"]} */
  76. (
  77. (arg, options, callback) => {
  78. let result;
  79. try {
  80. result = /** @type {SyncOrAsyncFunction | undefined} */ (callback)
  81. ? fs.readdirSync(
  82. arg,
  83. /** @type {Exclude<Parameters<FileSystem["readdir"]>[1], (err: NodeJS.ErrnoException | null, files: string[]) => void>} */
  84. (options),
  85. )
  86. : fs.readdirSync(arg);
  87. } catch (err) {
  88. return (callback || options)(
  89. /** @type {NodeJS.ErrnoException | null} */
  90. (err),
  91. [],
  92. );
  93. }
  94. (callback || options)(
  95. null,
  96. /** @type {ResultOfSyncOrAsyncFunction} */
  97. (result),
  98. );
  99. }
  100. );
  101. this.readdirSync =
  102. /** @type {SyncFileSystem["readdirSync"]} */
  103. (
  104. (arg, options) =>
  105. fs.readdirSync(
  106. arg,
  107. /** @type {Parameters<SyncFileSystem["readdirSync"]>[1]} */ (options),
  108. )
  109. );
  110. this.readFile =
  111. /** @type {FileSystem["readFile"]} */
  112. (
  113. (arg, options, callback) => {
  114. let result;
  115. try {
  116. result = /** @type {SyncOrAsyncFunction | undefined} */ (callback)
  117. ? fs.readFileSync(arg, options)
  118. : fs.readFileSync(arg);
  119. } catch (err) {
  120. return (callback || options)(
  121. /** @type {NodeJS.ErrnoException | null} */
  122. (err),
  123. );
  124. }
  125. (callback || options)(
  126. null,
  127. /** @type {ResultOfSyncOrAsyncFunction} */
  128. (result),
  129. );
  130. }
  131. );
  132. this.readFileSync =
  133. /** @type {SyncFileSystem["readFileSync"]} */
  134. ((arg, options) => fs.readFileSync(arg, options));
  135. this.readlink =
  136. /** @type {FileSystem["readlink"]} */
  137. (
  138. (arg, options, callback) => {
  139. let result;
  140. try {
  141. result = /** @type {SyncOrAsyncFunction | undefined} */ (callback)
  142. ? fs.readlinkSync(
  143. arg,
  144. /** @type {Exclude<Parameters<FileSystem["readlink"]>[1], StringCallback>} */
  145. (options),
  146. )
  147. : fs.readlinkSync(arg);
  148. } catch (err) {
  149. return (callback || options)(
  150. /** @type {NodeJS.ErrnoException | null} */
  151. (err),
  152. );
  153. }
  154. (callback || options)(
  155. null,
  156. /** @type {ResultOfSyncOrAsyncFunction} */
  157. (result),
  158. );
  159. }
  160. );
  161. this.readlinkSync =
  162. /** @type {SyncFileSystem["readlinkSync"]} */
  163. (
  164. (arg, options) =>
  165. fs.readlinkSync(
  166. arg,
  167. /** @type {Parameters<SyncFileSystem["readlinkSync"]>[1]} */ (
  168. options
  169. ),
  170. )
  171. );
  172. this.readJson = undefined;
  173. this.readJsonSync = undefined;
  174. const { readJsonSync } = fs;
  175. if (readJsonSync) {
  176. this.readJson =
  177. /** @type {FileSystem["readJson"]} */
  178. (
  179. (arg, callback) => {
  180. let result;
  181. try {
  182. result = readJsonSync.call(fs, arg);
  183. } catch (err) {
  184. return callback(
  185. /** @type {NodeJS.ErrnoException | Error | null} */ (err),
  186. );
  187. }
  188. callback(null, result);
  189. }
  190. );
  191. this.readJsonSync =
  192. /** @type {SyncFileSystem["readJsonSync"]} */
  193. ((arg) => readJsonSync.call(fs, arg));
  194. }
  195. this.realpath = undefined;
  196. this.realpathSync = undefined;
  197. const { realpathSync } = fs;
  198. if (realpathSync) {
  199. this.realpath =
  200. /** @type {FileSystem["realpath"]} */
  201. (
  202. (arg, options, callback) => {
  203. let result;
  204. try {
  205. result = /** @type {SyncOrAsyncFunction | undefined} */ (callback)
  206. ? realpathSync.call(
  207. fs,
  208. arg,
  209. /** @type {Exclude<Parameters<NonNullable<FileSystem["realpath"]>>[1], StringCallback>} */
  210. (options),
  211. )
  212. : realpathSync.call(fs, arg);
  213. } catch (err) {
  214. return (callback || options)(
  215. /** @type {NodeJS.ErrnoException | null} */
  216. (err),
  217. );
  218. }
  219. (callback || options)(
  220. null,
  221. /** @type {ResultOfSyncOrAsyncFunction} */
  222. (result),
  223. );
  224. }
  225. );
  226. this.realpathSync =
  227. /** @type {SyncFileSystem["realpathSync"]} */
  228. (
  229. (arg, options) =>
  230. realpathSync.call(
  231. fs,
  232. arg,
  233. /** @type {Parameters<NonNullable<SyncFileSystem["realpathSync"]>>[1]} */
  234. (options),
  235. )
  236. );
  237. }
  238. }
  239. module.exports = SyncAsyncFileSystemDecorator;