@midwayjs/upload 3.0.2 → 3.0.5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midwayjs/upload",
3
- "version": "3.0.2",
3
+ "version": "3.0.5",
4
4
  "description": "Midway Component for upload",
5
5
  "main": "dist/index.js",
6
6
  "typings": "index.d.ts",
@@ -15,8 +15,7 @@
15
15
  "files": [
16
16
  "dist/**/*.js",
17
17
  "dist/**/*.d.ts",
18
- "index.d.ts",
19
- "dist/**/*.js.map"
18
+ "index.d.ts"
20
19
  ],
21
20
  "engines": {
22
21
  "node": ">=12"
@@ -26,14 +25,14 @@
26
25
  "raw-body": "2.4.2"
27
26
  },
28
27
  "devDependencies": {
29
- "@midwayjs/core": "^3.0.2",
30
- "@midwayjs/decorator": "^3.0.2",
31
- "@midwayjs/express": "^3.0.2",
32
- "@midwayjs/faas": "^3.0.2",
33
- "@midwayjs/koa": "^3.0.2",
34
- "@midwayjs/mock": "^3.0.2",
35
- "@midwayjs/serverless-app": "^3.0.2",
36
- "@midwayjs/web": "^3.0.2"
28
+ "@midwayjs/core": "^3.0.4",
29
+ "@midwayjs/decorator": "^3.0.4",
30
+ "@midwayjs/express": "^3.0.5",
31
+ "@midwayjs/faas": "^3.0.5",
32
+ "@midwayjs/koa": "^3.0.5",
33
+ "@midwayjs/mock": "^3.0.5",
34
+ "@midwayjs/serverless-app": "^3.0.5",
35
+ "@midwayjs/web": "^3.0.5"
37
36
  },
38
- "gitHead": "ca77247d229978a736e79bb208579c014ed226fc"
37
+ "gitHead": "9b17898f10faeef2e7f1011eaea67f1d0b085261"
39
38
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.default.js","sourceRoot":"","sources":["../../src/config/config.default.ts"],"names":[],"mappings":";;;AACA,+BAA4B;AAC5B,2BAA4B;AAC5B,4CAA+C;AAElC,QAAA,MAAM,GAAkB;IACnC,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,2BAAe;IAC1B,MAAM,EAAE,IAAA,WAAI,EAAC,IAAA,WAAM,GAAE,EAAE,qBAAqB,CAAC;IAC7C,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;CAC5B,CAAC","sourcesContent":["import { UploadOptions } from '../interface';\nimport { join } from 'path';\nimport { tmpdir } from 'os';\nimport { uploadWhiteList } from '../constants';\n\nexport const upload: UploadOptions = {\n mode: 'file',\n fileSize: '10mb',\n whitelist: uploadWhiteList,\n tmpdir: join(tmpdir(), 'midway-upload-files'),\n cleanTimeout: 5 * 60 * 1000,\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"configuration.js","sourceRoot":"","sources":["../src/configuration.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mDAAoE;AACpE,yDAAyD;AACzD,yCAA0D;AAC1D,6CAAgD;AAChD,mCAIiB;AAUjB,IAAa,mBAAmB,GAAhC,MAAa,mBAAmB;IAO9B,KAAK,CAAC,OAAO;QACX,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC;QACnD,IAAI,MAAM,EAAE;YACV,MAAM,IAAA,iBAAS,EAAC,MAAM,CAAC,CAAC;YACxB,IAAI,YAAY,EAAE;gBAChB,IAAA,+BAAuB,EAAC,MAAM,EAAE,YAAY,CAAC,CAAC;aAC/C;SACF;QACD,IAAI,CAAC,kBAAkB;aACpB,eAAe,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;aAClD,OAAO,CAAC,GAAG,CAAC,EAAE;YACb,GAAG,CAAC,aAAa,CAAC,6BAAgB,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,IAAA,mCAA2B,GAAE,CAAC;IACtC,CAAC;CACF,CAAA;AAvBC;IADC,IAAA,kBAAM,GAAE;8BACW,+BAAwB;+DAAC;AAG7C;IADC,IAAA,kBAAM,EAAC,QAAQ,CAAC;;yDACW;AALjB,mBAAmB;IAR/B,IAAA,yBAAa,EAAC;QACb,SAAS,EAAE,QAAQ;QACnB,aAAa,EAAE;YACb;gBACE,OAAO,EAAE,aAAa;aACvB;SACF;KACF,CAAC;GACW,mBAAmB,CAyB/B;AAzBY,kDAAmB","sourcesContent":["import { Config, Configuration, Inject } from '@midwayjs/decorator';\nimport * as DefaultConfig from './config/config.default';\nimport { MidwayApplicationManager } from '@midwayjs/core';\nimport { UploadMiddleware } from './middleware';\nimport {\n autoRemoveUploadTmpFile,\n ensureDir,\n stopAutoRemoveUploadTmpFile,\n} from './utils';\nimport { UploadOptions } from './interface';\n@Configuration({\n namespace: 'upload',\n importConfigs: [\n {\n default: DefaultConfig,\n },\n ],\n})\nexport class UploadConfiguration {\n @Inject()\n applicationManager: MidwayApplicationManager;\n\n @Config('upload')\n uploadConfig: UploadOptions;\n\n async onReady() {\n const { tmpdir, cleanTimeout } = this.uploadConfig;\n if (tmpdir) {\n await ensureDir(tmpdir);\n if (cleanTimeout) {\n autoRemoveUploadTmpFile(tmpdir, cleanTimeout);\n }\n }\n this.applicationManager\n .getApplications(['koa', 'faas', 'express', 'egg'])\n .forEach(app => {\n app.useMiddleware(UploadMiddleware);\n });\n }\n\n async onStop() {\n await stopAutoRemoveUploadTmpFile();\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG;IAC7B,SAAS;IACT,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,KAAK;IACL,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,OAAO;IACP,QAAQ;IACR,MAAM;IACN,MAAM;IACN,MAAM;CACP,CAAC","sourcesContent":["export const uploadWhiteList = [\n // images\n '.jpg',\n '.jpeg', // image/jpeg\n '.png', // image/png, image/x-png\n '.gif', // image/gif\n '.bmp', // image/bmp\n '.wbmp', // image/vnd.wap.wbmp\n '.webp',\n '.tif',\n '.psd',\n // text\n '.svg',\n '.js',\n '.jsx',\n '.json',\n '.css',\n '.less',\n '.html',\n '.htm',\n '.xml',\n '.pdf',\n // tar\n '.zip',\n '.gz',\n '.tgz',\n '.gzip',\n // video\n '.mp3',\n '.mp4',\n '.avi',\n];\n"]}
package/dist/error.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":";;;AAAA,yCAA2C;AAE3C,MAAa,6BAA8B,SAAQ,gBAAS,CAAC,eAAe;IAC1E,YAAY,QAAgB;QAC1B,KAAK,CAAC,4BAA4B,QAAQ,mBAAmB,CAAC,CAAC;IACjE,CAAC;CACF;AAJD,sEAIC","sourcesContent":["import { httpError } from '@midwayjs/core';\n\nexport class MultipartInvalidFilenameError extends httpError.BadRequestError {\n constructor(filename: string) {\n super(`Invalid update file name ${filename}, please check it`);\n }\n}\n"]}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,iDAAuE;AAA9D,8GAAA,mBAAmB,OAAiB;AAC7C,8CAA4B;AAC5B,+CAA6B;AAC7B,0CAAwB;AACxB,8CAA4B","sourcesContent":["export { UploadConfiguration as Configuration } from './configuration';\nexport * from './interface';\nexport * from './middleware';\nexport * from './error';\nexport * from './constants';\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"interface.js","sourceRoot":"","sources":["../src/interface.ts"],"names":[],"mappings":"","sourcesContent":["import { Readable } from \"stream\";\n\nexport type UploadMode = 'stream' | 'file';\n\nexport interface UploadOptions {\n mode?: UploadMode,\n fileSize?: string; // Max file size (in bytes), default is `10mb`\n whitelist?: string[]; // The white ext file names, default is `null`\n tmpdir?: string; // 临时文件目录\n cleanTimeout?: number; // 临时文件自动清理时间\n}\n\nexport interface UploadFileInfo<T> {\n filename: string;\n fieldName: string;\n mimeType: string;\n data: T extends string ? string : Readable ;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Config,\n Logger,\n Middleware,\n MidwayFrameworkType,\n} from '@midwayjs/decorator';\nimport { IMiddleware, IMidwayLogger } from '@midwayjs/core';\nimport { resolve, extname } from 'path';\nimport { promises } from 'fs';\nimport { Readable, Stream } from 'stream';\nimport {\n MultipartInvalidFilenameError,\n UploadFileInfo,\n UploadOptions,\n} from '.';\nimport { parseFromReadableStream, parseMultipart } from './parse';\nimport * as getRawBody from 'raw-body';\nconst { unlink, writeFile } = promises;\n\n@Middleware()\nexport class UploadMiddleware implements IMiddleware<any, any> {\n @Config('upload')\n upload: UploadOptions;\n\n @Logger()\n logger: IMidwayLogger;\n\n resolve(app) {\n if (app.getFrameworkType() === MidwayFrameworkType.WEB_EXPRESS) {\n return async (req: any, res: any, next: any) => {\n return this.execUpload(req, req, res, next, true);\n };\n } else {\n return async (ctx, next) => {\n const req = ctx.request?.req || ctx.request;\n return this.execUpload(ctx, req, ctx, next, false);\n };\n }\n }\n\n async execUpload(ctx, req, res, next, isExpress) {\n const { mode, tmpdir, fileSize } = this.upload;\n const boundary = this.getUploadBoundary(req);\n if (!boundary) {\n return next();\n }\n ctx.fields = {};\n ctx.files = [];\n ctx.cleanupRequestFiles = async (): Promise<Array<boolean>> => {\n if (!ctx.files?.length) {\n return [];\n }\n return Promise.all(\n ctx.files.map(async (fileInfo: UploadFileInfo<any>) => {\n if (typeof fileInfo.data !== 'string') {\n return false;\n }\n try {\n await unlink(fileInfo.data);\n return true;\n } catch {\n return false;\n }\n })\n );\n };\n\n let body;\n if (this.isReadableStream(req, isExpress)) {\n if (mode === 'stream') {\n const { fields, fileInfo } = await parseFromReadableStream(\n req,\n boundary\n );\n if (!this.checkExt(fileInfo.filename)) {\n throw new MultipartInvalidFilenameError(fileInfo.filename);\n } else {\n ctx.fields = fields;\n ctx.files = [fileInfo];\n return next();\n }\n }\n body = await getRawBody(req, {\n limit: fileSize,\n });\n } else {\n body = req.body;\n }\n\n const data = await parseMultipart(body, boundary);\n if (!data) {\n return next();\n }\n\n ctx.fields = data.fields;\n const requireId = `upload_${Date.now()}.${Math.random()}`;\n const files = data.files;\n const notCheckFile = files.find(fileInfo => {\n if (!this.checkExt(fileInfo.filename)) {\n return fileInfo;\n }\n });\n\n if (notCheckFile) {\n throw new MultipartInvalidFilenameError(notCheckFile.filename);\n }\n ctx.files = await Promise.all(\n files.map(async (file, index) => {\n const { data, filename } = file;\n if (mode === 'file') {\n const ext = extname(filename);\n const tmpFileName = resolve(tmpdir, `${requireId}.${index}${ext}`);\n await writeFile(tmpFileName, data, 'binary');\n file.data = tmpFileName;\n } else if (mode === 'stream') {\n file.data = new Readable({\n read() {\n this.push(data);\n this.push(null);\n },\n });\n }\n return file;\n })\n );\n\n return next();\n }\n\n getUploadBoundary(request): false | string {\n const method = (request.method || request.httpMethod || '').toUpperCase();\n if (!request.headers?.['content-type'] || method !== 'POST') {\n return false;\n }\n const contentType: string = request.headers['content-type'];\n if (!contentType.startsWith('multipart/form-data;')) {\n return false;\n }\n\n const boundaryMatch = /boundary=(.*)(;|\\s|$)/.exec(contentType);\n if (!boundaryMatch?.[1]) {\n return false;\n }\n return boundaryMatch[1];\n }\n\n isReadableStream(req: any, isExpress): boolean {\n // ref: https://github.com/rvagg/isstream/blob/master/isstream.js#L10\n if (\n req instanceof Stream &&\n typeof (req as any)._read === 'function' &&\n typeof (req as any)._readableState === 'object' &&\n (!(req as any).body || isExpress)\n ) {\n return true;\n }\n if (req.pipe && req.on && !req.body) {\n return true;\n }\n return false;\n }\n\n checkExt(filename): boolean {\n const ext = extname(filename).toLowerCase();\n const { whitelist } = this.upload;\n if (!Array.isArray(whitelist)) {\n return true;\n }\n return whitelist.includes(ext);\n }\n\n static getName() {\n return 'upload';\n }\n}\n"]}
package/dist/parse.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"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","sourcesContent":["import { Readable, Transform, Writable } from 'stream';\nimport { UploadFileInfo } from './interface';\nconst headSeparator = Buffer.from('\\r\\n\\r\\n');\nexport const parseMultipart = async (body: any, boundary: string) => {\n if (typeof body === 'string') {\n body = Buffer.from(body);\n }\n const bufferSeparator = Buffer.from('\\r\\n--' + boundary);\n const fields = {};\n const files = [];\n bufferSplit(body, bufferSeparator).forEach(buf => {\n const [headerBuf, data] = bufferSplit(buf, headSeparator, 2);\n const head = parseHead(headerBuf);\n if (!head['content-disposition']) {\n return;\n }\n if (!head['content-disposition'].filename) {\n if (head['content-disposition'].name) {\n fields[head['content-disposition'].name] = data.toString();\n }\n return;\n }\n files.push({\n filename: head['content-disposition'].filename,\n data,\n fieldName: head['content-disposition'].name,\n mimeType: head['content-type'],\n });\n });\n\n return {\n files,\n fields,\n };\n};\n\nconst pre = Buffer.from('\\r\\n');\nexport const parseFromReadableStream = (\n readStream: Readable,\n boundary\n): Promise<{ fields: any; fileInfo: UploadFileInfo<Readable> }> => {\n const bufferSeparator = Buffer.from(`\\r\\n--${boundary}`);\n const fields = {};\n const fileInfo: UploadFileInfo<Readable> = {\n filename: '',\n data: null,\n fieldName: '',\n mimeType: '',\n };\n const emptyBuf = Buffer.alloc(0);\n // 上一次遗留的 chunk\n let lastChunk = emptyBuf;\n // 前一个chunk的后缀\n let preChunk = emptyBuf;\n let isTransformFileData = false;\n let isTransformFileDataEnd = false;\n // let isEnd = false;\n let isFirst = true;\n let allChuns = Buffer.alloc(0);\n return new Promise(resolve => {\n fileInfo.data = new Transform({\n highWaterMark: 1000,\n transform(chunk, encoding, callback) {\n if (isFirst) {\n chunk = Buffer.concat([pre, chunk]);\n isFirst = false;\n }\n // 已经结束了\n if (isTransformFileDataEnd) {\n return callback(null, null);\n }\n\n // 正在传输中的话\n if (isTransformFileData) {\n if (lastChunk.length) {\n chunk = Buffer.concat([lastChunk, chunk]);\n lastChunk = emptyBuf;\n }\n const newPreChunk = Buffer.concat([preChunk, chunk]);\n const newBlockIndex = bufferIndexOf(newPreChunk, bufferSeparator);\n // 存在新的块则代表已经结束了\n if (newBlockIndex !== -1) {\n // 上一个块的最后一部分数据,需要追加写入\n const lastDataBlock = newPreChunk.slice(\n preChunk.length,\n newBlockIndex\n );\n isTransformFileDataEnd = true;\n callback(null, lastDataBlock);\n return;\n }\n // 块尚未结束,则继续写入\n callback(null, chunk);\n preChunk = newPreChunk.slice(-bufferSeparator.length);\n return;\n }\n\n // 未在传输过程中\n allChuns = Buffer.concat([allChuns, chunk]);\n\n const splitAllChuns = bufferSplit(allChuns, bufferSeparator);\n for (\n let chunkIndex = 0;\n chunkIndex < splitAllChuns.length;\n chunkIndex++\n ) {\n const [headerBuf, data] = bufferSplit(\n splitAllChuns[chunkIndex],\n headSeparator\n );\n const head = parseHead(headerBuf);\n if (!head['content-disposition']) {\n continue;\n }\n if (!head['content-disposition'].filename) {\n if (head['content-disposition'].name) {\n fields[head['content-disposition'].name] = data.toString();\n }\n continue;\n }\n // 这里就是找到了 file 的段,如果没有数据,则需要继续等待\n if (!data.length) {\n continue;\n }\n\n fileInfo.filename = head['content-disposition'].filename;\n fileInfo.fieldName = head['content-disposition'].name;\n fileInfo.mimeType = head['content-type'];\n isTransformFileData = true;\n lastChunk = data;\n allChuns = emptyBuf;\n this.pause();\n resolve({ fileInfo, fields });\n break;\n }\n\n callback(null, emptyBuf);\n },\n });\n readStream.pipe(fileInfo.data as any);\n const empty = new Writable();\n empty._write = function (chunk, encoding, cb) {\n cb();\n };\n fileInfo.data.pipe(empty);\n });\n};\n\n// search buffer index\nexport const bufferIndexOf = (\n buffer: Buffer,\n search: Buffer,\n offset?: number\n) => {\n return buffer.indexOf(search, offset);\n};\n\n// split buffer to buffer list\nexport const bufferSplit = (\n buffer: Buffer,\n separator: Buffer,\n limit?: number\n) => {\n let index = 0;\n const result: Buffer[] = [];\n let find: number = bufferIndexOf(buffer, separator, index);\n\n while (find !== -1) {\n result.push(buffer.slice(index, find));\n index = find + separator.length;\n if (limit && result.length + 1 === limit) {\n break;\n }\n find = bufferIndexOf(buffer, separator, index);\n }\n\n result.push(buffer.slice(index));\n return result;\n};\n\nconst headReg = /^([^:]+):[ \\t]?(.+)?$/;\nexport const parseHead = (headBuf: Buffer) => {\n const head = {};\n const headStrList = headBuf.toString().split('\\r\\n');\n for (const headStr of headStrList) {\n const matched = headReg.exec(headStr);\n if (!matched) {\n continue;\n }\n const name = matched[1].toLowerCase();\n const value = matched[2]\n ? matched[2].replace(/&#(\\d+);/g, (origin: string, code: string) => {\n try {\n return String.fromCharCode(parseInt(code));\n } catch {\n return origin;\n }\n })\n : '';\n if (name === 'content-disposition') {\n const headCol = {};\n value.split(/;\\s+/).forEach((kv: string) => {\n const [k, v] = kv.split('=');\n headCol[k] = v ? v.replace(/^\"/, '').replace(/\"$/, '') : v ?? true;\n });\n head[name] = headCol;\n } else {\n head[name] = value;\n }\n }\n return head;\n};\n"]}
package/dist/utils.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAA,2BAAyC;AACzC,+BAA4B;AAC5B,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,aAAQ,CAAC;AAC1D,IAAI,qCAAqC,CAAC;AAC1C,IAAI,8BAA8B,CAAC;AAC5B,MAAM,uBAAuB,GAAG,KAAK,EAC1C,MAAc,EACd,YAAoB,EACpB,EAAE;IACF,YAAY,CAAC,qCAAqC,CAAC,CAAC;IACpD,IAAI,QAAQ,GAAG,YAAY,GAAG,CAAC,CAAC;IAChC,IAAI,QAAQ,GAAG,IAAI,EAAE;QACnB,QAAQ,GAAG,IAAI,CAAC;KACjB;IAED,IAAI,8BAA8B,EAAE;QAClC,MAAM,MAAM,GAAG,MAAM,IAAA,mBAAW,EAAC,MAAM,CAAC,CAAC;QACzC,IAAI,MAAM,EAAE;YACV,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,GAAG,CAAC,KAAK,EAAC,IAAI,EAAC,EAAE;gBACrB,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACpC,IAAI;oBACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACtC,IAAI,QAAQ,CAAC,MAAM,EAAE,IAAI,GAAG,GAAG,QAAQ,CAAC,OAAO,GAAG,YAAY,EAAE;wBAC9D,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;qBACxB;iBACF;gBAAC,WAAM;oBACN,OAAO,KAAK,CAAC;iBACd;YACH,CAAC,CAAC,CACH,CAAC;SACH;KACF;IAED,qCAAqC,GAAG,UAAU,CAAC,GAAG,EAAE;QACtD,8BAA8B,GAAG,IAAA,+BAAuB,EACtD,MAAM,EACN,YAAY,CACb,CAAC;IACJ,CAAC,EAAE,QAAQ,CAAC,CAAC;AACf,CAAC,CAAC;AArCW,QAAA,uBAAuB,2BAqClC;AAEK,MAAM,2BAA2B,GAAG,KAAK,IAAI,EAAE;IACpD,IAAI,8BAA8B,EAAE;QAClC,MAAM,8BAA8B,CAAC;QACrC,8BAA8B,GAAG,IAAI,CAAC;KACvC;IACD,YAAY,CAAC,qCAAqC,CAAC,CAAC;AACtD,CAAC,CAAC;AANW,QAAA,2BAA2B,+BAMtC;AAEK,MAAM,WAAW,GAAG,KAAK,EAAE,IAAY,EAAoB,EAAE;IAClE,IAAI;QACF,MAAM,MAAM,CAAC,IAAI,EAAE,cAAS,CAAC,IAAI,GAAG,cAAS,CAAC,IAAI,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;KACb;IAAC,WAAM;QACN,OAAO,KAAK,CAAC;KACd;AACH,CAAC,CAAC;AAPW,QAAA,WAAW,eAOtB;AAEK,MAAM,SAAS,GAAG,KAAK,EAAE,OAAe,EAAoB,EAAE;IACnE,MAAM,QAAQ,GAAG,MAAM,IAAA,mBAAW,EAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,QAAQ,EAAE;QACZ,OAAO,IAAI,CAAC;KACb;IACD,IAAI;QACF,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;KACb;IAAC,WAAM;QACN,OAAO,KAAK,CAAC;KACd;AACH,CAAC,CAAC;AAXW,QAAA,SAAS,aAWpB","sourcesContent":["import { promises, constants } from 'fs';\nimport { join } from 'path';\nconst { readdir, access, stat, unlink, mkdir } = promises;\nlet autoRemoveUploadTmpFileTimeoutHandler;\nlet autoRemoveUploadTmpFilePromise;\nexport const autoRemoveUploadTmpFile = async (\n tmpDir: string,\n cleanTimeout: number\n) => {\n clearTimeout(autoRemoveUploadTmpFileTimeoutHandler);\n let waitTime = cleanTimeout / 3;\n if (waitTime < 1000) {\n waitTime = 1000;\n }\n\n if (autoRemoveUploadTmpFilePromise) {\n const exists = await checkExists(tmpDir);\n if (exists) {\n const paths = await readdir(tmpDir);\n const now = Date.now();\n await Promise.all(\n paths.map(async path => {\n const filePath = join(tmpDir, path);\n try {\n const statInfo = await stat(filePath);\n if (statInfo.isFile() && now - statInfo.ctimeMs > cleanTimeout) {\n await unlink(filePath);\n }\n } catch {\n return false;\n }\n })\n );\n }\n }\n\n autoRemoveUploadTmpFileTimeoutHandler = setTimeout(() => {\n autoRemoveUploadTmpFilePromise = autoRemoveUploadTmpFile(\n tmpDir,\n cleanTimeout\n );\n }, waitTime);\n};\n\nexport const stopAutoRemoveUploadTmpFile = async () => {\n if (autoRemoveUploadTmpFilePromise) {\n await autoRemoveUploadTmpFilePromise;\n autoRemoveUploadTmpFilePromise = null;\n }\n clearTimeout(autoRemoveUploadTmpFileTimeoutHandler);\n};\n\nexport const checkExists = async (path: string): Promise<boolean> => {\n try {\n await access(path, constants.W_OK | constants.R_OK);\n return true;\n } catch {\n return false;\n }\n};\n\nexport const ensureDir = async (dirPath: string): Promise<boolean> => {\n const isExists = await checkExists(dirPath);\n if (isExists) {\n return true;\n }\n try {\n await mkdir(dirPath, { recursive: true });\n return true;\n } catch {\n return false;\n }\n};\n"]}