fs.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. import { promisified } from './tauri'
  2. export enum BaseDirectory {
  3. Audio = 1,
  4. Cache,
  5. Config,
  6. Data,
  7. LocalData,
  8. Desktop,
  9. Document,
  10. Download,
  11. Executable,
  12. Font,
  13. Home,
  14. Picture,
  15. Public,
  16. Runtime,
  17. Template,
  18. Video,
  19. Resource,
  20. App
  21. }
  22. export interface FsOptions {
  23. dir?: BaseDirectory
  24. }
  25. export interface FsTextFileOption {
  26. path: string
  27. contents: string
  28. }
  29. export interface FsBinaryFileOption {
  30. path: string
  31. contents: ArrayBuffer
  32. }
  33. export interface FileEntry {
  34. path: string
  35. // name of the directory/file
  36. // can be null if the path terminates with `..`
  37. name?: string
  38. // children of this entry if it's a directory; null otherwise
  39. children?: FileEntry[]
  40. }
  41. /**
  42. * @name readTextFile
  43. * @description Reads a file as text
  44. * @param {string} filePath path to the file
  45. * @param {FsOptions} [options] configuration object
  46. * @param {BaseDirectory} [options.dir] base directory
  47. * @return {Promise<string>}
  48. */
  49. async function readTextFile(
  50. filePath: string,
  51. options: FsOptions = {}
  52. ): Promise<string> {
  53. return await promisified<string>({
  54. cmd: 'readTextFile',
  55. path: filePath,
  56. options
  57. })
  58. }
  59. /**
  60. * @name readBinaryFile
  61. * @description Reads a file as binary
  62. * @param {string} filePath path to the file
  63. * @param {FsOptions} [options] configuration object
  64. * @param {BaseDirectory} [options.dir] base directory
  65. * @return {Promise<number[]>}
  66. */
  67. async function readBinaryFile(
  68. filePath: string,
  69. options: FsOptions = {}
  70. ): Promise<number[]> {
  71. return await promisified<number[]>({
  72. cmd: 'readBinaryFile',
  73. path: filePath,
  74. options
  75. })
  76. }
  77. /**
  78. * writes a text file
  79. *
  80. * @param file
  81. * @param file.path path of the file
  82. * @param file.contents contents of the file
  83. * @param [options] configuration object
  84. * @param [options.dir] base directory
  85. * @return
  86. */
  87. async function writeFile(
  88. file: FsTextFileOption,
  89. options: FsOptions = {}
  90. ): Promise<void> {
  91. if (typeof options === 'object') {
  92. Object.freeze(options)
  93. }
  94. if (typeof file === 'object') {
  95. Object.freeze(file)
  96. }
  97. return await promisified({
  98. cmd: 'writeFile',
  99. path: file.path,
  100. contents: file.contents,
  101. options
  102. })
  103. }
  104. const CHUNK_SIZE = 65536
  105. /**
  106. * convert an Uint8Array to ascii string
  107. *
  108. * @param arr
  109. * @return ASCII string
  110. */
  111. function uint8ArrayToString(arr: Uint8Array): string {
  112. if (arr.length < CHUNK_SIZE) {
  113. return String.fromCharCode.apply(null, Array.from(arr))
  114. }
  115. let result = ''
  116. const arrLen = arr.length
  117. for (let i = 0; i < arrLen; i++) {
  118. const chunk = arr.subarray(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE)
  119. result += String.fromCharCode.apply(null, Array.from(chunk))
  120. }
  121. return result
  122. }
  123. /**
  124. * convert an ArrayBuffer to base64 encoded string
  125. *
  126. * @param buffer
  127. * @return base64 encoded string
  128. */
  129. function arrayBufferToBase64(buffer: ArrayBuffer): string {
  130. const str = uint8ArrayToString(new Uint8Array(buffer))
  131. return btoa(str)
  132. }
  133. /**
  134. * writes a binary file
  135. *
  136. * @param file
  137. * @param file.path path of the file
  138. * @param file.contents contents of the file
  139. * @param [options] configuration object
  140. * @param [options.dir] base directory
  141. * @return
  142. */
  143. async function writeBinaryFile(
  144. file: FsBinaryFileOption,
  145. options: FsOptions = {}
  146. ): Promise<void> {
  147. if (typeof options === 'object') {
  148. Object.freeze(options)
  149. }
  150. if (typeof file === 'object') {
  151. Object.freeze(file)
  152. }
  153. return await promisified({
  154. cmd: 'writeFile',
  155. path: file.path,
  156. contents: arrayBufferToBase64(file.contents),
  157. options
  158. })
  159. }
  160. /**
  161. * list directory files
  162. *
  163. * @param dir path to the directory to read
  164. * @param [options] configuration object
  165. * @param [options.recursive] whether to list dirs recursively or not
  166. * @param [options.dir] base directory
  167. * @return
  168. */
  169. async function readDir(
  170. dir: string,
  171. options: FsOptions = {}
  172. ): Promise<FileEntry[]> {
  173. return await promisified({
  174. cmd: 'readDir',
  175. path: dir,
  176. options
  177. })
  178. }
  179. /**
  180. * Creates a directory
  181. * If one of the path's parent components doesn't exist
  182. * and the `recursive` option isn't set to true, it will be rejected
  183. *
  184. * @param dir path to the directory to create
  185. * @param [options] configuration object
  186. * @param [options.recursive] whether to create the directory's parent components or not
  187. * @param [options.dir] base directory
  188. * @return
  189. */
  190. async function createDir(dir: string, options: FsOptions = {}): Promise<void> {
  191. return await promisified({
  192. cmd: 'createDir',
  193. path: dir,
  194. options
  195. })
  196. }
  197. /**
  198. * Removes a directory
  199. * If the directory is not empty and the `recursive` option isn't set to true, it will be rejected
  200. *
  201. * @param dir path to the directory to remove
  202. * @param [options] configuration object
  203. * @param [options.recursive] whether to remove all of the directory's content or not
  204. * @param [options.dir] base directory
  205. * @return
  206. */
  207. async function removeDir(dir: string, options: FsOptions = {}): Promise<void> {
  208. return await promisified({
  209. cmd: 'removeDir',
  210. path: dir,
  211. options
  212. })
  213. }
  214. /**
  215. * Copy file
  216. *
  217. * @param source
  218. * @param destination
  219. * @param [options] configuration object
  220. * @param [options.dir] base directory
  221. * @return
  222. */
  223. async function copyFile(
  224. source: string,
  225. destination: string,
  226. options: FsOptions = {}
  227. ): Promise<void> {
  228. return await promisified({
  229. cmd: 'copyFile',
  230. source,
  231. destination,
  232. options
  233. })
  234. }
  235. /**
  236. * Removes a file
  237. *
  238. * @param file path to the file to remove
  239. * @param [options] configuration object
  240. * @param [options.dir] base directory
  241. * @return
  242. */
  243. async function removeFile(
  244. file: string,
  245. options: FsOptions = {}
  246. ): Promise<void> {
  247. return await promisified({
  248. cmd: 'removeFile',
  249. path: file,
  250. options: options
  251. })
  252. }
  253. /**
  254. * Renames a file
  255. *
  256. * @param oldPath
  257. * @param newPath
  258. * @param [options] configuration object
  259. * @param [options.dir] base directory
  260. * @return
  261. */
  262. async function renameFile(
  263. oldPath: string,
  264. newPath: string,
  265. options: FsOptions = {}
  266. ): Promise<void> {
  267. return await promisified({
  268. cmd: 'renameFile',
  269. oldPath,
  270. newPath,
  271. options
  272. })
  273. }
  274. export {
  275. BaseDirectory as Dir,
  276. readTextFile,
  277. readBinaryFile,
  278. writeFile,
  279. writeBinaryFile,
  280. readDir,
  281. createDir,
  282. removeDir,
  283. copyFile,
  284. removeFile,
  285. renameFile
  286. }