Useful methods for file-related functions.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

45 lines
1.3 KiB

  1. import NodeBlob from 'node-blob'
  2. type DataUriToBlob = (dataUri: string, name?: string) => Blob
  3. const DATA_URI_PREFIX = 'data:'
  4. const DATA_TYPE_DELIMITER = ';'
  5. const DATA_START = ','
  6. interface NodeFileConfig {
  7. lastModified: number
  8. }
  9. class NodeFile extends NodeBlob {
  10. public readonly name: string
  11. public readonly lastModified: number
  12. constructor(blobParts: unknown[], name: string, config: Partial<NodeFileConfig>) {
  13. super(blobParts, config)
  14. this.name = name
  15. this.lastModified = typeof config.lastModified! === 'number' ? config.lastModified : Date.now()
  16. }
  17. }
  18. const dataUriToBlob: DataUriToBlob = (dataUri, name?) => {
  19. if ((typeof dataUri as unknown) !== 'string') {
  20. throw TypeError('Argument should be a string.')
  21. }
  22. const [encoding, base64] = dataUri.slice(DATA_URI_PREFIX.length).split(DATA_START)
  23. const binary = atob(base64)
  24. const [type] = encoding.split(DATA_TYPE_DELIMITER)
  25. const ab = new ArrayBuffer(binary.length)
  26. const ia = new Uint8Array(ab)
  27. for (let i = 0; i < binary.length; i++) {
  28. ia[i] = binary.charCodeAt(i)
  29. }
  30. if (typeof name! === 'string') {
  31. const FileCtor = typeof window !== 'undefined' ? window.File : NodeFile
  32. return new FileCtor([ab], name, { type })
  33. }
  34. const BlobCtor = typeof window !== 'undefined' ? window.Blob : NodeBlob
  35. return new BlobCtor([ab], { type })
  36. }
  37. export default dataUriToBlob