@eggjs/multipart 5.0.0-beta.34 → 5.0.0-beta.36

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.
@@ -1,275 +1,198 @@
1
- import assert from 'node:assert';
2
- import path from 'node:path';
3
- import { randomUUID } from 'node:crypto';
4
- import fs from 'node:fs/promises';
5
- import { createWriteStream } from 'node:fs';
6
- import { Readable, PassThrough } from 'node:stream';
7
- import { pipeline } from 'node:stream/promises';
8
- // @ts-expect-error no types
9
- import parse from 'co-busboy';
10
- import dayjs from 'dayjs';
11
- import { Context } from 'egg';
12
1
  import { humanizeBytes } from "../../lib/utils.js";
13
2
  import { LimitError } from "../../lib/LimitError.js";
14
3
  import { MultipartFileTooLargeError } from "../../lib/MultipartFileTooLargeError.js";
15
- const HAS_CONSUMED = Symbol('Context#multipartHasConsumed');
16
- export default class MultipartContext extends Context {
17
- /**
18
- * create multipart.parts instance, to get separated files.
19
- * @function Context#multipart
20
- * @param {Object} [options] - override default multipart configurations
21
- * - {Boolean} options.autoFields
22
- * - {String} options.defaultCharset
23
- * - {String} options.defaultParamCharset
24
- * - {Object} options.limits
25
- * - {Function} options.checkFile
26
- * @return {Yieldable | AsyncIterable<Yieldable>} parts
27
- */
28
- multipart(options = {}) {
29
- // eslint-disable-next-line @typescript-eslint/no-this-alias
30
- const ctx = this;
31
- // multipart/form-data
32
- if (!ctx.is('multipart'))
33
- ctx.throw(400, 'Content-Type must be multipart/*');
34
- assert(!ctx[HAS_CONSUMED], "the multipart request can't be consumed twice");
35
- ctx[HAS_CONSUMED] = true;
36
- const { autoFields, defaultCharset, defaultParamCharset, checkFile } = ctx.app.config.multipart;
37
- const { fieldNameSize, fieldSize, fields, fileSize, files } = ctx.app.config.multipart;
38
- options = extractOptions(options);
39
- const parseOptions = Object.assign({
40
- autoFields,
41
- defCharset: defaultCharset,
42
- defParamCharset: defaultParamCharset,
43
- checkFile,
44
- }, options);
45
- // https://github.com/mscdex/busboy#busboy-methods
46
- // merge limits
47
- parseOptions.limits = Object.assign({
48
- fieldNameSize,
49
- fieldSize,
50
- fields,
51
- fileSize,
52
- files,
53
- }, options.limits);
54
- // mount asyncIterator, so we can use `for await` to get parts
55
- const parts = parse(this, parseOptions);
56
- parts[Symbol.asyncIterator] = async function* () {
57
- let part;
58
- do {
59
- part = await parts();
60
- if (!part)
61
- continue;
62
- if (Array.isArray(part)) {
63
- if (part[3])
64
- throw new LimitError('Request_fieldSize_limit', 'Reach fieldSize limit');
65
- // TODO: still not support at busboy 1.x (only support at urlencoded)
66
- // https://github.com/mscdex/busboy/blob/v0.3.1/lib/types/multipart.js#L5
67
- // https://github.com/mscdex/busboy/blob/master/lib/types/multipart.js#L251
68
- // if (part[2]) throw new LimitError('Request_fieldNameSize_limit', 'Reach fieldNameSize limit');
69
- }
70
- else {
71
- // user click `upload` before choose a file, `part` will be file stream, but `part.filename` is empty must handler this, such as log error.
72
- if (!part.filename) {
73
- ctx.coreLogger.debug('[egg-multipart] file field `%s` is upload without file stream, will drop it.', part.fieldname);
74
- await pipeline(part, new PassThrough());
75
- continue;
76
- }
77
- // TODO: check whether filename is malicious input
78
- // busboy only set truncated when consume the stream
79
- if (part.truncated) {
80
- // in case of emit 'limit' too fast
81
- throw new LimitError('Request_fileSize_limit', 'Reach fileSize limit');
82
- }
83
- else {
84
- part.once('limit', function () {
85
- this.emit('error', new LimitError('Request_fileSize_limit', 'Reach fileSize limit'));
86
- this.resume();
87
- });
88
- }
89
- }
90
- // dispatch part to outter logic such as for-await-of
91
- yield part;
92
- } while (part !== undefined);
93
- };
94
- return parts;
95
- }
96
- /**
97
- * save request multipart data and files to `ctx.request`
98
- * @function Context#saveRequestFiles
99
- * @param {Object} options - { limits, checkFile, ... }
100
- */
101
- async saveRequestFiles(options = {}) {
102
- // eslint-disable-next-line @typescript-eslint/no-this-alias
103
- const ctx = this;
104
- const allowArrayField = ctx.app.config.multipart.allowArrayField;
105
- let storeDir;
106
- const requestBody = {};
107
- const requestFiles = [];
108
- options.autoFields = false;
109
- const parts = ctx.multipart(options);
110
- try {
111
- for await (const part of parts) {
112
- if (Array.isArray(part)) {
113
- // fields
114
- const [fieldName, fieldValue] = part;
115
- if (!allowArrayField) {
116
- requestBody[fieldName] = fieldValue;
117
- }
118
- else {
119
- if (!requestBody[fieldName]) {
120
- requestBody[fieldName] = fieldValue;
121
- }
122
- else if (!Array.isArray(requestBody[fieldName])) {
123
- requestBody[fieldName] = [requestBody[fieldName], fieldValue];
124
- }
125
- else {
126
- requestBody[fieldName].push(fieldValue);
127
- }
128
- }
129
- }
130
- else {
131
- // stream
132
- const { filename, fieldname, encoding, mime } = part;
133
- if (!storeDir) {
134
- // ${tmpdir}/YYYY/MM/DD/HH
135
- storeDir = path.join(ctx.app.config.multipart.tmpdir, dayjs().format('YYYY/MM/DD/HH'));
136
- await fs.mkdir(storeDir, { recursive: true });
137
- }
138
- // write to tmp file
139
- const filepath = path.join(storeDir, randomUUID() + path.extname(filename));
140
- const target = createWriteStream(filepath);
141
- await pipeline(part, target);
142
- const meta = {
143
- filepath,
144
- field: fieldname,
145
- filename,
146
- encoding,
147
- mime,
148
- // keep same property name as file stream, https://github.com/cojs/busboy/blob/master/index.js#L114
149
- fieldname,
150
- transferEncoding: encoding,
151
- mimeType: mime,
152
- };
153
- requestFiles.push(meta);
154
- }
155
- }
156
- }
157
- catch (err) {
158
- await ctx.cleanupRequestFiles(requestFiles);
159
- throw err;
160
- }
161
- ctx.request.body = requestBody;
162
- ctx.request.files = requestFiles;
163
- }
164
- /**
165
- * get upload file stream
166
- * @example
167
- * ```js
168
- * const stream = await ctx.getFileStream();
169
- * // get other fields
170
- * console.log(stream.fields);
171
- * ```
172
- * @function Context#getFileStream
173
- * @param {Object} options
174
- * - {Boolean} options.requireFile - required file submit, default is true
175
- * - {String} options.defaultCharset
176
- * - {String} options.defaultParamCharset
177
- * - {Object} options.limits
178
- * - {Function} options.checkFile
179
- * @return {ReadStream} stream
180
- * @since 1.0.0
181
- * @deprecated Not safe enough, use `ctx.multipart()` instead
182
- */
183
- async getFileStream(options = {}) {
184
- options.autoFields = true;
185
- const parts = this.multipart(options);
186
- let stream = await parts();
187
- if (options.requireFile !== false) {
188
- // stream not exists, treat as an exception
189
- if (!stream || !stream.filename) {
190
- this.throw(400, "Can't found upload file");
191
- }
192
- }
193
- if (!stream) {
194
- stream = Readable.from([]);
195
- }
196
- if (stream.truncated) {
197
- throw new LimitError('Request_fileSize_limit', 'Request file too large, please check multipart config');
198
- }
199
- stream.fields = parts.field;
200
- stream.once('limit', () => {
201
- const err = new MultipartFileTooLargeError('Request file too large, please check multipart config', stream.fields, stream.filename);
202
- if (stream.listenerCount('error') > 0) {
203
- stream.emit('error', err);
204
- this.coreLogger.warn(err);
205
- }
206
- else {
207
- this.coreLogger.error(err);
208
- // ignore next error event
209
- stream.on('error', () => { });
210
- }
211
- // ignore all data
212
- stream.resume();
213
- });
214
- return stream;
215
- }
216
- /**
217
- * clean up request tmp files helper
218
- * @function Context#cleanupRequestFiles
219
- * @param {Array<String>} [files] - file paths need to cleanup, default is `ctx.request.files`.
220
- */
221
- async cleanupRequestFiles(files) {
222
- if (!files || !files.length) {
223
- files = this.request.files;
224
- }
225
- if (Array.isArray(files)) {
226
- for (const file of files) {
227
- try {
228
- await fs.rm(file.filepath, { force: true, recursive: true });
229
- }
230
- catch (err) {
231
- // warning log
232
- this.coreLogger.warn('[egg-multipart-cleanupRequestFiles-error] file: %j, error: %s', file, err);
233
- }
234
- }
235
- }
236
- }
237
- }
4
+ import assert from "node:assert";
5
+ import path from "node:path";
6
+ import { Context } from "egg";
7
+ import { randomUUID } from "node:crypto";
8
+ import { createWriteStream } from "node:fs";
9
+ import fs from "node:fs/promises";
10
+ import { PassThrough, Readable } from "node:stream";
11
+ import { pipeline } from "node:stream/promises";
12
+ import parse from "co-busboy";
13
+ import dayjs from "dayjs";
14
+
15
+ //#region src/app/extend/context.ts
16
+ const HAS_CONSUMED = Symbol("Context#multipartHasConsumed");
17
+ var MultipartContext = class extends Context {
18
+ /**
19
+ * create multipart.parts instance, to get separated files.
20
+ * @function Context#multipart
21
+ * @param {Object} [options] - override default multipart configurations
22
+ * - {Boolean} options.autoFields
23
+ * - {String} options.defaultCharset
24
+ * - {String} options.defaultParamCharset
25
+ * - {Object} options.limits
26
+ * - {Function} options.checkFile
27
+ * @return {Yieldable | AsyncIterable<Yieldable>} parts
28
+ */
29
+ multipart(options = {}) {
30
+ const ctx = this;
31
+ if (!ctx.is("multipart")) ctx.throw(400, "Content-Type must be multipart/*");
32
+ assert(!ctx[HAS_CONSUMED], "the multipart request can't be consumed twice");
33
+ ctx[HAS_CONSUMED] = true;
34
+ const { autoFields, defaultCharset, defaultParamCharset, checkFile } = ctx.app.config.multipart;
35
+ const { fieldNameSize, fieldSize, fields, fileSize, files } = ctx.app.config.multipart;
36
+ options = extractOptions(options);
37
+ const parseOptions = Object.assign({
38
+ autoFields,
39
+ defCharset: defaultCharset,
40
+ defParamCharset: defaultParamCharset,
41
+ checkFile
42
+ }, options);
43
+ parseOptions.limits = Object.assign({
44
+ fieldNameSize,
45
+ fieldSize,
46
+ fields,
47
+ fileSize,
48
+ files
49
+ }, options.limits);
50
+ const parts = parse(this, parseOptions);
51
+ parts[Symbol.asyncIterator] = async function* () {
52
+ let part;
53
+ do {
54
+ part = await parts();
55
+ if (!part) continue;
56
+ if (Array.isArray(part)) {
57
+ if (part[3]) throw new LimitError("Request_fieldSize_limit", "Reach fieldSize limit");
58
+ } else {
59
+ if (!part.filename) {
60
+ ctx.coreLogger.debug("[egg-multipart] file field `%s` is upload without file stream, will drop it.", part.fieldname);
61
+ await pipeline(part, new PassThrough());
62
+ continue;
63
+ }
64
+ if (part.truncated) throw new LimitError("Request_fileSize_limit", "Reach fileSize limit");
65
+ else part.once("limit", function() {
66
+ this.emit("error", new LimitError("Request_fileSize_limit", "Reach fileSize limit"));
67
+ this.resume();
68
+ });
69
+ }
70
+ yield part;
71
+ } while (part !== void 0);
72
+ };
73
+ return parts;
74
+ }
75
+ /**
76
+ * save request multipart data and files to `ctx.request`
77
+ * @function Context#saveRequestFiles
78
+ * @param {Object} options - { limits, checkFile, ... }
79
+ */
80
+ async saveRequestFiles(options = {}) {
81
+ const ctx = this;
82
+ const allowArrayField = ctx.app.config.multipart.allowArrayField;
83
+ let storeDir;
84
+ const requestBody = {};
85
+ const requestFiles = [];
86
+ options.autoFields = false;
87
+ const parts = ctx.multipart(options);
88
+ try {
89
+ for await (const part of parts) if (Array.isArray(part)) {
90
+ const [fieldName, fieldValue] = part;
91
+ if (!allowArrayField) requestBody[fieldName] = fieldValue;
92
+ else if (!requestBody[fieldName]) requestBody[fieldName] = fieldValue;
93
+ else if (!Array.isArray(requestBody[fieldName])) requestBody[fieldName] = [requestBody[fieldName], fieldValue];
94
+ else requestBody[fieldName].push(fieldValue);
95
+ } else {
96
+ const { filename, fieldname, encoding, mime } = part;
97
+ if (!storeDir) {
98
+ storeDir = path.join(ctx.app.config.multipart.tmpdir, dayjs().format("YYYY/MM/DD/HH"));
99
+ await fs.mkdir(storeDir, { recursive: true });
100
+ }
101
+ const filepath = path.join(storeDir, randomUUID() + path.extname(filename));
102
+ await pipeline(part, createWriteStream(filepath));
103
+ const meta = {
104
+ filepath,
105
+ field: fieldname,
106
+ filename,
107
+ encoding,
108
+ mime,
109
+ fieldname,
110
+ transferEncoding: encoding,
111
+ mimeType: mime
112
+ };
113
+ requestFiles.push(meta);
114
+ }
115
+ } catch (err) {
116
+ await ctx.cleanupRequestFiles(requestFiles);
117
+ throw err;
118
+ }
119
+ ctx.request.body = requestBody;
120
+ ctx.request.files = requestFiles;
121
+ }
122
+ /**
123
+ * get upload file stream
124
+ * @example
125
+ * ```js
126
+ * const stream = await ctx.getFileStream();
127
+ * // get other fields
128
+ * console.log(stream.fields);
129
+ * ```
130
+ * @function Context#getFileStream
131
+ * @param {Object} options
132
+ * - {Boolean} options.requireFile - required file submit, default is true
133
+ * - {String} options.defaultCharset
134
+ * - {String} options.defaultParamCharset
135
+ * - {Object} options.limits
136
+ * - {Function} options.checkFile
137
+ * @return {ReadStream} stream
138
+ * @since 1.0.0
139
+ * @deprecated Not safe enough, use `ctx.multipart()` instead
140
+ */
141
+ async getFileStream(options = {}) {
142
+ options.autoFields = true;
143
+ const parts = this.multipart(options);
144
+ let stream = await parts();
145
+ if (options.requireFile !== false) {
146
+ if (!stream || !stream.filename) this.throw(400, "Can't found upload file");
147
+ }
148
+ if (!stream) stream = Readable.from([]);
149
+ if (stream.truncated) throw new LimitError("Request_fileSize_limit", "Request file too large, please check multipart config");
150
+ stream.fields = parts.field;
151
+ stream.once("limit", () => {
152
+ const err = new MultipartFileTooLargeError("Request file too large, please check multipart config", stream.fields, stream.filename);
153
+ if (stream.listenerCount("error") > 0) {
154
+ stream.emit("error", err);
155
+ this.coreLogger.warn(err);
156
+ } else {
157
+ this.coreLogger.error(err);
158
+ stream.on("error", () => {});
159
+ }
160
+ stream.resume();
161
+ });
162
+ return stream;
163
+ }
164
+ /**
165
+ * clean up request tmp files helper
166
+ * @function Context#cleanupRequestFiles
167
+ * @param {Array<String>} [files] - file paths need to cleanup, default is `ctx.request.files`.
168
+ */
169
+ async cleanupRequestFiles(files) {
170
+ if (!files || !files.length) files = this.request.files;
171
+ if (Array.isArray(files)) for (const file of files) try {
172
+ await fs.rm(file.filepath, {
173
+ force: true,
174
+ recursive: true
175
+ });
176
+ } catch (err) {
177
+ this.coreLogger.warn("[egg-multipart-cleanupRequestFiles-error] file: %j, error: %s", file, err);
178
+ }
179
+ }
180
+ };
238
181
  function extractOptions(options = {}) {
239
- const opts = {};
240
- if (typeof options.autoFields === 'boolean') {
241
- opts.autoFields = options.autoFields;
242
- }
243
- if (options.limits) {
244
- opts.limits = options.limits;
245
- }
246
- if (options.checkFile) {
247
- opts.checkFile = options.checkFile;
248
- }
249
- if (options.defCharset) {
250
- opts.defCharset = options.defCharset;
251
- }
252
- if (options.defParamCharset) {
253
- opts.defParamCharset = options.defParamCharset;
254
- }
255
- // compatible with config names
256
- if (options.defaultCharset) {
257
- opts.defCharset = options.defaultCharset;
258
- }
259
- if (options.defaultParamCharset) {
260
- opts.defParamCharset = options.defaultParamCharset;
261
- }
262
- // limits
263
- if (options.limits) {
264
- const limits = (opts.limits = {
265
- ...options.limits,
266
- });
267
- for (const key in limits) {
268
- if (key.endsWith('Size') && limits[key]) {
269
- limits[key] = humanizeBytes(limits[key]);
270
- }
271
- }
272
- }
273
- return opts;
182
+ const opts = {};
183
+ if (typeof options.autoFields === "boolean") opts.autoFields = options.autoFields;
184
+ if (options.limits) opts.limits = options.limits;
185
+ if (options.checkFile) opts.checkFile = options.checkFile;
186
+ if (options.defCharset) opts.defCharset = options.defCharset;
187
+ if (options.defParamCharset) opts.defParamCharset = options.defParamCharset;
188
+ if (options.defaultCharset) opts.defCharset = options.defaultCharset;
189
+ if (options.defaultParamCharset) opts.defParamCharset = options.defaultParamCharset;
190
+ if (options.limits) {
191
+ const limits = opts.limits = { ...options.limits };
192
+ for (const key in limits) if (key.endsWith("Size") && limits[key]) limits[key] = humanizeBytes(limits[key]);
193
+ }
194
+ return opts;
274
195
  }
275
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcHAvZXh0ZW5kL2NvbnRleHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBQ2pDLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUM3QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2xDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM1QyxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNwRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFaEQsNEJBQTRCO0FBQzVCLE9BQU8sS0FBSyxNQUFNLFdBQVcsQ0FBQztBQUM5QixPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFDMUIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEtBQUssQ0FBQztBQUU5QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3JELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBRXJGLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0FBc0Q1RCxNQUFNLENBQUMsT0FBTyxPQUFPLGdCQUFpQixTQUFRLE9BQU87SUFDbkQ7Ozs7Ozs7Ozs7T0FVRztJQUNILFNBQVMsQ0FBQyxVQUE0QixFQUFFO1FBQ3RDLDREQUE0RDtRQUM1RCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUM7UUFDakIsc0JBQXNCO1FBQ3RCLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQztZQUFFLEdBQUcsQ0FBQyxLQUFL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
196
+
197
+ //#endregion
198
+ export { MultipartContext as default };
@@ -1,4 +1,7 @@
1
- import type { Application, MiddlewareFunc } from 'egg';
2
- import type { MultipartConfig } from '../../config/config.default.ts';
1
+ import { MultipartConfig } from "../../config/config.default.js";
2
+ import { Application, MiddlewareFunc } from "egg";
3
+
4
+ //#region src/app/middleware/multipart.d.ts
3
5
  declare const _default: (options: MultipartConfig, _app: Application) => MiddlewareFunc;
4
- export default _default;
6
+ //#endregion
7
+ export { _default as default };
@@ -1,18 +1,15 @@
1
- import { pathMatching } from '@eggjs/path-matching';
2
- export default (options, _app) => {
3
- // normalize options
4
- const matchFn = options.fileModeMatch &&
5
- pathMatching({
6
- match: options.fileModeMatch,
7
- // pathToRegexpModule: app.options.pathToRegexpModule,
8
- });
9
- return async function multipart(ctx, next) {
10
- if (!ctx.is('multipart'))
11
- return next();
12
- if (matchFn && !matchFn(ctx))
13
- return next();
14
- await ctx.saveRequestFiles();
15
- return next();
16
- };
1
+ import { pathMatching } from "@eggjs/path-matching";
2
+
3
+ //#region src/app/middleware/multipart.ts
4
+ var multipart_default = (options, _app) => {
5
+ const matchFn = options.fileModeMatch && pathMatching({ match: options.fileModeMatch });
6
+ return async function multipart(ctx, next) {
7
+ if (!ctx.is("multipart")) return next();
8
+ if (matchFn && !matchFn(ctx)) return next();
9
+ await ctx.saveRequestFiles();
10
+ return next();
11
+ };
17
12
  };
18
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGlwYXJ0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcC9taWRkbGV3YXJlL211bHRpcGFydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFLcEQsZUFBZSxDQUFDLE9BQXdCLEVBQUUsSUFBaUIsRUFBa0IsRUFBRTtJQUM3RSxvQkFBb0I7SUFDcEIsTUFBTSxPQUFPLEdBQ1gsT0FBTyxDQUFDLGFBQWE7UUFDckIsWUFBWSxDQUFDO1lBQ1gsS0FBSyxFQUFFLE9BQU8sQ0FBQyxhQUFhO1lBQzVCLHNEQUFzRDtTQUN2RCxDQUFDLENBQUM7SUFFTCxPQUFPLEtBQUssVUFBVSxTQUFTLENBQUMsR0FBRyxFQUFFLElBQUk7UUFDdkMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDO1lBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUN4QyxJQUFJLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFBRSxPQUFPLElBQUksRUFBRSxDQUFDO1FBRTVDLE1BQU0sR0FBRyxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDN0IsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUNoQixDQUFDLENBQUM7QUFDSixDQUFDLENBQUMifQ==
13
+
14
+ //#endregion
15
+ export { multipart_default as default };
@@ -1,3 +1,6 @@
1
- import type { Application, Subscription } from 'egg';
1
+ import { Application, Subscription } from "egg";
2
+
3
+ //#region src/app/schedule/clean_tmpdir.d.ts
2
4
  declare const _default: (app: Application) => typeof Subscription;
3
- export default _default;
5
+ //#endregion
6
+ export { _default as default };