@things-factory/attachment-base 6.1.154 → 6.1.156

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,8 +1,10 @@
1
1
  "use strict";
2
+ var _a, _b;
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.multipleUpload = exports.singleUpload = exports.generateUploadURL = exports.deleteAttachmentsByRef = exports.deleteAttachment = exports.createAttachments = exports.createAttachment = exports.AttachmentMutation = void 0;
4
+ exports.importAttachments = exports.multipleUpload = exports.singleUpload = exports.generateUploadURL = exports.deleteAttachmentsByRef = exports.deleteAttachment = exports.createAttachments = exports.createAttachment = exports.AttachmentMutation = void 0;
4
5
  const tslib_1 = require("tslib");
5
- const GraphQLUpload_js_1 = tslib_1.__importDefault(require("graphql-upload/GraphQLUpload.js"));
6
+ const GraphQLUpload_js_1 = require("graphql-upload/GraphQLUpload.js");
7
+ const GraphQLUpload_js_2 = tslib_1.__importDefault(require("graphql-upload/GraphQLUpload.js"));
6
8
  const promises_all_1 = tslib_1.__importDefault(require("promises-all"));
7
9
  const type_graphql_1 = require("type-graphql");
8
10
  const typeorm_1 = require("typeorm");
@@ -42,6 +44,9 @@ let AttachmentMutation = class AttachmentMutation {
42
44
  async generateUploadURL(type, context) {
43
45
  return await generateUploadURL(null, { type }, context);
44
46
  }
47
+ async importAttachments(file, context) {
48
+ return await importAttachments(file, context);
49
+ }
45
50
  };
46
51
  tslib_1.__decorate([
47
52
  (0, type_graphql_1.Directive)('@transaction'),
@@ -92,16 +97,16 @@ tslib_1.__decorate([
92
97
  tslib_1.__decorate([
93
98
  (0, type_graphql_1.Directive)('@transaction'),
94
99
  (0, type_graphql_1.Mutation)(returns => attachment_1.Attachment),
95
- tslib_1.__param(0, (0, type_graphql_1.Arg)('file', type => GraphQLUpload_js_1.default)),
100
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('file', type => GraphQLUpload_js_2.default)),
96
101
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
97
102
  tslib_1.__metadata("design:type", Function),
98
- tslib_1.__metadata("design:paramtypes", [Object, Object]),
103
+ tslib_1.__metadata("design:paramtypes", [typeof (_a = typeof GraphQLUpload_js_1.FileUpload !== "undefined" && GraphQLUpload_js_1.FileUpload) === "function" ? _a : Object, Object]),
99
104
  tslib_1.__metadata("design:returntype", Promise)
100
105
  ], AttachmentMutation.prototype, "singleUpload", null);
101
106
  tslib_1.__decorate([
102
107
  (0, type_graphql_1.Directive)('@transaction'),
103
108
  (0, type_graphql_1.Mutation)(returns => [attachment_1.Attachment]),
104
- tslib_1.__param(0, (0, type_graphql_1.Arg)('files', type => [GraphQLUpload_js_1.default])),
109
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('files', type => [GraphQLUpload_js_2.default])),
105
110
  tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
106
111
  tslib_1.__metadata("design:type", Function),
107
112
  tslib_1.__metadata("design:paramtypes", [Array, Object]),
@@ -115,6 +120,15 @@ tslib_1.__decorate([
115
120
  tslib_1.__metadata("design:paramtypes", [String, Object]),
116
121
  tslib_1.__metadata("design:returntype", Promise)
117
122
  ], AttachmentMutation.prototype, "generateUploadURL", null);
123
+ tslib_1.__decorate([
124
+ (0, type_graphql_1.Directive)('@transaction'),
125
+ (0, type_graphql_1.Mutation)(returns => [attachment_1.Attachment], { description: 'To import some Attachments' }),
126
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('file', () => GraphQLUpload_js_2.default)),
127
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
128
+ tslib_1.__metadata("design:type", Function),
129
+ tslib_1.__metadata("design:paramtypes", [typeof (_b = typeof GraphQLUpload_js_1.FileUpload !== "undefined" && GraphQLUpload_js_1.FileUpload) === "function" ? _b : Object, Object]),
130
+ tslib_1.__metadata("design:returntype", Promise)
131
+ ], AttachmentMutation.prototype, "importAttachments", null);
118
132
  AttachmentMutation = tslib_1.__decorate([
119
133
  (0, type_graphql_1.Resolver)(attachment_1.Attachment)
120
134
  ], AttachmentMutation);
@@ -158,7 +172,7 @@ async function deleteAttachment(_, { id }, context) {
158
172
  where: { domain: { id: domain.id }, id }
159
173
  });
160
174
  if (attachment) {
161
- await repository.delete(attachment.id);
175
+ await repository.delete({ id: attachment.id });
162
176
  await attachment_const_1.STORAGE.deleteFile(attachment.path);
163
177
  return true;
164
178
  }
@@ -201,4 +215,91 @@ async function multipleUpload(_, { files }, context) {
201
215
  return await createAttachments(null, { attachments: { files } }, context);
202
216
  }
203
217
  exports.multipleUpload = multipleUpload;
218
+ async function parseJSONFile(uploadedFile) {
219
+ var { createReadStream } = await uploadedFile;
220
+ return new Promise((resolve, reject) => {
221
+ const chunks = [];
222
+ createReadStream()
223
+ .on('data', (chunk) => {
224
+ chunks.push(chunk);
225
+ })
226
+ .on('end', () => {
227
+ try {
228
+ const fileContents = Buffer.concat(chunks).toString('utf-8');
229
+ const jsonData = JSON.parse(fileContents);
230
+ resolve(jsonData);
231
+ }
232
+ catch (error) {
233
+ reject(error);
234
+ }
235
+ })
236
+ .on('error', (error) => {
237
+ reject(error);
238
+ });
239
+ });
240
+ }
241
+ function dataURLToFileUpload(dataURL, filename, mimeType) {
242
+ const indexOfComma = dataURL.indexOf(',');
243
+ if (indexOfComma === -1) {
244
+ throw new Error('Invalid Data URL');
245
+ }
246
+ const base64Data = dataURL.slice(indexOfComma + 1);
247
+ const buffer = Buffer.from(base64Data, 'base64');
248
+ return {
249
+ filename,
250
+ mimetype: mimeType,
251
+ encoding: 'base64',
252
+ createReadStream: () => {
253
+ const stream = require('stream');
254
+ const readable = new stream.Readable();
255
+ readable.push(buffer);
256
+ readable.push(null);
257
+ return readable;
258
+ }
259
+ };
260
+ }
261
+ async function importAttachments(upload, context) {
262
+ const { domain, user, notify, tx } = context.state;
263
+ const repository = tx.getRepository(attachment_1.Attachment);
264
+ const attachments = [];
265
+ const parsed = await parseJSONFile(upload);
266
+ for (const id in parsed) {
267
+ var { name, description, category, mimetype, encoding, contents } = parsed[id];
268
+ if (!name || !contents || !mimetype) {
269
+ throw 'Malformed attachments import file';
270
+ }
271
+ var sameIdAttachment = await repository.findOneBy({ id });
272
+ if (sameIdAttachment) {
273
+ if (sameIdAttachment.domainId != domain.id) {
274
+ throw `Attachment with id/name(${id}/${name}) is already taken in another domain`;
275
+ }
276
+ // 동일 아이디 첨부파일이 있다면, 스킵한다.
277
+ continue;
278
+ }
279
+ const file = dataURLToFileUpload(contents, name, mimetype);
280
+ var { path, size, contents } = await attachment_const_1.STORAGE.uploadFile({ id, file, context });
281
+ attachments.push(await repository.save({
282
+ domain,
283
+ creator: user,
284
+ updater: user,
285
+ id,
286
+ description,
287
+ name,
288
+ mimetype,
289
+ encoding,
290
+ category: category || mimetype.split('/').shift(),
291
+ size: size,
292
+ path,
293
+ contents
294
+ }));
295
+ }
296
+ notify &&
297
+ notify({
298
+ mode: 'in-app',
299
+ title: `${attachments.length} Attachment(s) are imported`,
300
+ body: `${attachments.length} Attachment(s) are imported by ${user.name}`
301
+ });
302
+ return attachments;
303
+ }
304
+ exports.importAttachments = importAttachments;
204
305
  //# sourceMappingURL=attachment-mutation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachment-mutation.js","sourceRoot":"","sources":["../../../server/service/attachment/attachment-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.js'\nimport promisesAll from 'promises-all'\nimport { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'\nimport { In } from 'typeorm'\n\nimport { logger } from '@things-factory/env'\nimport { getRepository } from '@things-factory/shell'\n\nimport { STORAGE } from '../../attachment-const'\nimport { Attachment } from './attachment'\nimport { AttachmentPatch, NewAttachment, UploadURL } from './attachment-types'\n\n@Resolver(Attachment)\nexport class AttachmentMutation {\n @Directive('@transaction')\n @Mutation(returns => Attachment)\n async createAttachment(\n @Arg('attachment', type => NewAttachment) attachment: NewAttachment,\n @Ctx() context: ResolverContext\n ): Promise<Attachment> {\n return await createAttachment(null, { attachment }, context)\n }\n\n @Directive('@transaction')\n @Mutation(returns => [Attachment])\n async createAttachments(\n @Arg('attachments', type => [NewAttachment]) attachments: NewAttachment[],\n @Ctx() context: ResolverContext\n ): Promise<Attachment[]> {\n return await createAttachments(null, { attachments }, context)\n }\n\n @Directive('@transaction')\n @Mutation(returns => Attachment)\n async updateAttachment(\n @Arg('id') id: string,\n @Arg('patch', type => AttachmentPatch) patch: AttachmentPatch,\n @Ctx() context: ResolverContext\n ): Promise<Attachment> {\n const attachment = await getRepository(Attachment).findOne({\n where: {\n domain: { id: context.state.domain.id },\n id\n }\n })\n\n return await getRepository(Attachment).save({\n ...attachment,\n ...patch,\n updater: context.state.user\n })\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean)\n async deleteAttachment(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n return await deleteAttachment(null, { id }, context)\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean)\n async deleteAttachmentsByRef(\n @Arg('refBys', type => [String]) refBys: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n return await deleteAttachmentsByRef(null, { refBys }, context)\n }\n\n @Directive('@transaction')\n @Mutation(returns => Attachment)\n async singleUpload(\n @Arg('file', type => GraphQLUpload) file: FileUpload,\n @Ctx() context: ResolverContext\n ): Promise<Attachment> {\n return await singleUpload(null, { file }, context)\n }\n\n @Directive('@transaction')\n @Mutation(returns => [Attachment])\n async multipleUpload(\n @Arg('files', type => [GraphQLUpload]) files: FileUpload[],\n @Ctx() context: ResolverContext\n ): Promise<Attachment[]> {\n return await multipleUpload(null, { files }, context)\n }\n\n @Mutation(returns => UploadURL)\n async generateUploadURL(\n @Arg('type', type => String) type: string,\n @Ctx() context: ResolverContext\n ): Promise<{ url: string; fields: { [key: string]: string } }> {\n return await generateUploadURL(null, { type }, context)\n }\n}\n\nexport async function createAttachment(_: any, { attachment }, context: ResolverContext): Promise<Attachment> {\n const { file, category, refType = '', refBy, description } = attachment\n\n const { id, path, size, filename, mimetype, encoding, contents } = await STORAGE.uploadFile({ file, context })\n const { domain, user, tx } = context.state\n\n const repository = tx ? tx.getRepository(Attachment) : getRepository(Attachment)\n\n return await repository.save({\n domain,\n creator: user,\n updater: user,\n id,\n description,\n name: filename,\n mimetype,\n encoding,\n refType,\n refBy,\n category: category || mimetype.split('/').shift(),\n size: size as any,\n path,\n contents\n })\n}\n\nexport async function createAttachments(_: any, { attachments }, context: ResolverContext): Promise<Attachment[]> {\n const { resolve, reject } = await promisesAll.all(\n attachments.map(attachment => createAttachment(_, { attachment }, context))\n )\n\n if (reject.length) {\n reject.forEach(({ name, message }) => logger.error(`${name}: ${message}`))\n\n return reject\n }\n\n return resolve\n}\n\nexport async function deleteAttachment(_: any, { id }, context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n const repository = tx ? tx.getRepository(Attachment) : getRepository(Attachment)\n const attachment = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n if (attachment) {\n await repository.delete(attachment.id)\n await STORAGE.deleteFile(attachment.path)\n return true\n } else {\n return false\n }\n}\n\nexport async function deleteAttachmentsByRef(_: any, { refBys }, context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n const repository = tx ? tx.getRepository(Attachment) : getRepository(Attachment)\n const attachments = await repository.find({\n where: { domain: { id: domain.id }, refBy: In(refBys) }\n })\n\n //remove attachment from repo\n await repository.delete({\n refBy: In(refBys)\n })\n\n //remove files from attachments folder\n if (attachments.length) {\n await Promise.all(\n attachments.map(async attachment => {\n await STORAGE.deleteFile(attachment.path)\n })\n )\n\n return true\n } else {\n return false\n }\n}\n\nexport async function generateUploadURL(\n _: any,\n { type },\n context: ResolverContext\n): Promise<{ url: string; fields: { [key: string]: string } }> {\n return await STORAGE.generateUploadURL(type)\n}\n\nexport async function singleUpload(_: any, { file }, context: ResolverContext): Promise<Attachment> {\n return await createAttachment(null, { attachment: { file } }, context)\n}\n\nexport async function multipleUpload(_: any, { files }, context: ResolverContext): Promise<Attachment[]> {\n return await createAttachments(null, { attachments: { files } }, context)\n}\n"]}
1
+ {"version":3,"file":"attachment-mutation.js","sourceRoot":"","sources":["../../../server/service/attachment/attachment-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { FileUpload } from 'graphql-upload/GraphQLUpload.js'\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.js'\nimport promisesAll from 'promises-all'\n\nimport { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'\nimport { In } from 'typeorm'\n\nimport { logger } from '@things-factory/env'\nimport { getRepository } from '@things-factory/shell'\n\nimport { STORAGE } from '../../attachment-const'\nimport { Attachment } from './attachment'\nimport { AttachmentPatch, NewAttachment, UploadURL } from './attachment-types'\n\n@Resolver(Attachment)\nexport class AttachmentMutation {\n @Directive('@transaction')\n @Mutation(returns => Attachment)\n async createAttachment(\n @Arg('attachment', type => NewAttachment) attachment: NewAttachment,\n @Ctx() context: ResolverContext\n ): Promise<Attachment> {\n return await createAttachment(null, { attachment }, context)\n }\n\n @Directive('@transaction')\n @Mutation(returns => [Attachment])\n async createAttachments(\n @Arg('attachments', type => [NewAttachment]) attachments: NewAttachment[],\n @Ctx() context: ResolverContext\n ): Promise<Attachment[]> {\n return await createAttachments(null, { attachments }, context)\n }\n\n @Directive('@transaction')\n @Mutation(returns => Attachment)\n async updateAttachment(\n @Arg('id') id: string,\n @Arg('patch', type => AttachmentPatch) patch: AttachmentPatch,\n @Ctx() context: ResolverContext\n ): Promise<Attachment> {\n const attachment = await getRepository(Attachment).findOne({\n where: {\n domain: { id: context.state.domain.id },\n id\n }\n })\n\n return await getRepository(Attachment).save({\n ...attachment,\n ...patch,\n updater: context.state.user\n })\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean)\n async deleteAttachment(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n return await deleteAttachment(null, { id }, context)\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean)\n async deleteAttachmentsByRef(\n @Arg('refBys', type => [String]) refBys: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n return await deleteAttachmentsByRef(null, { refBys }, context)\n }\n\n @Directive('@transaction')\n @Mutation(returns => Attachment)\n async singleUpload(\n @Arg('file', type => GraphQLUpload) file: FileUpload,\n @Ctx() context: ResolverContext\n ): Promise<Attachment> {\n return await singleUpload(null, { file }, context)\n }\n\n @Directive('@transaction')\n @Mutation(returns => [Attachment])\n async multipleUpload(\n @Arg('files', type => [GraphQLUpload]) files: FileUpload[],\n @Ctx() context: ResolverContext\n ): Promise<Attachment[]> {\n return await multipleUpload(null, { files }, context)\n }\n\n @Mutation(returns => UploadURL)\n async generateUploadURL(\n @Arg('type', type => String) type: string,\n @Ctx() context: ResolverContext\n ): Promise<{ url: string; fields: { [key: string]: string } }> {\n return await generateUploadURL(null, { type }, context)\n }\n\n @Directive('@transaction')\n @Mutation(returns => [Attachment], { description: 'To import some Attachments' })\n async importAttachments(\n @Arg('file', () => GraphQLUpload) file: FileUpload,\n @Ctx() context: ResolverContext\n ): Promise<Attachment[]> {\n return await importAttachments(file, context)\n }\n}\n\nexport async function createAttachment(_: any, { attachment }, context: ResolverContext): Promise<Attachment> {\n const { file, category, refType = '', refBy, description } = attachment\n\n const { id, path, size, filename, mimetype, encoding, contents } = await STORAGE.uploadFile({ file, context })\n const { domain, user, tx } = context.state\n\n const repository = tx ? tx.getRepository(Attachment) : getRepository(Attachment)\n\n return await repository.save({\n domain,\n creator: user,\n updater: user,\n id,\n description,\n name: filename,\n mimetype,\n encoding,\n refType,\n refBy,\n category: category || mimetype.split('/').shift(),\n size: size as any,\n path,\n contents\n })\n}\n\nexport async function createAttachments(_: any, { attachments }, context: ResolverContext): Promise<Attachment[]> {\n const { resolve, reject } = await promisesAll.all(\n attachments.map(attachment => createAttachment(_, { attachment }, context))\n )\n\n if (reject.length) {\n reject.forEach(({ name, message }) => logger.error(`${name}: ${message}`))\n\n return reject\n }\n\n return resolve\n}\n\nexport async function deleteAttachment(_: any, { id }, context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n const repository = tx ? tx.getRepository(Attachment) : getRepository(Attachment)\n const attachment = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n if (attachment) {\n await repository.delete({ id: attachment.id })\n await STORAGE.deleteFile(attachment.path)\n return true\n } else {\n return false\n }\n}\n\nexport async function deleteAttachmentsByRef(_: any, { refBys }, context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n const repository = tx ? tx.getRepository(Attachment) : getRepository(Attachment)\n const attachments = await repository.find({\n where: { domain: { id: domain.id }, refBy: In(refBys) }\n })\n\n //remove attachment from repo\n await repository.delete({\n refBy: In(refBys)\n })\n\n //remove files from attachments folder\n if (attachments.length) {\n await Promise.all(\n attachments.map(async attachment => {\n await STORAGE.deleteFile(attachment.path)\n })\n )\n\n return true\n } else {\n return false\n }\n}\n\nexport async function generateUploadURL(\n _: any,\n { type },\n context: ResolverContext\n): Promise<{ url: string; fields: { [key: string]: string } }> {\n return await STORAGE.generateUploadURL(type)\n}\n\nexport async function singleUpload(_: any, { file }, context: ResolverContext): Promise<Attachment> {\n return await createAttachment(null, { attachment: { file } }, context)\n}\n\nexport async function multipleUpload(_: any, { files }, context: ResolverContext): Promise<Attachment[]> {\n return await createAttachments(null, { attachments: { files } }, context)\n}\n\nasync function parseJSONFile(uploadedFile: FileUpload): Promise<any> {\n var { createReadStream } = await uploadedFile\n\n return new Promise((resolve, reject) => {\n const chunks: Uint8Array[] = []\n\n createReadStream()\n .on('data', (chunk: Uint8Array) => {\n chunks.push(chunk)\n })\n .on('end', () => {\n try {\n const fileContents = Buffer.concat(chunks).toString('utf-8')\n const jsonData = JSON.parse(fileContents)\n resolve(jsonData)\n } catch (error) {\n reject(error)\n }\n })\n .on('error', (error: Error) => {\n reject(error)\n })\n })\n}\n\nfunction dataURLToFileUpload(dataURL: string, filename: string, mimeType: string): FileUpload {\n const indexOfComma = dataURL.indexOf(',')\n if (indexOfComma === -1) {\n throw new Error('Invalid Data URL')\n }\n\n const base64Data = dataURL.slice(indexOfComma + 1)\n const buffer = Buffer.from(base64Data, 'base64')\n\n return {\n filename,\n mimetype: mimeType,\n encoding: 'base64',\n createReadStream: () => {\n const stream = require('stream')\n const readable = new stream.Readable()\n readable.push(buffer)\n readable.push(null)\n return readable\n }\n }\n}\n\nexport async function importAttachments(upload: FileUpload, context: ResolverContext): Promise<Attachment[]> {\n const { domain, user, notify, tx } = context.state\n\n const repository = tx.getRepository(Attachment)\n\n const attachments = []\n\n const parsed = await parseJSONFile(upload)\n\n for (const id in parsed) {\n var { name, description, category, mimetype, encoding, contents } = parsed[id]\n if (!name || !contents || !mimetype) {\n throw 'Malformed attachments import file'\n }\n\n var sameIdAttachment = await repository.findOneBy({ id })\n\n if (sameIdAttachment) {\n if (sameIdAttachment.domainId != domain.id) {\n throw `Attachment with id/name(${id}/${name}) is already taken in another domain`\n }\n\n // 동일 아이디 첨부파일이 있다면, 스킵한다.\n continue\n }\n\n const file = dataURLToFileUpload(contents, name, mimetype)\n\n var { path, size, contents } = await STORAGE.uploadFile({ id, file, context })\n\n attachments.push(\n await repository.save({\n domain,\n creator: user,\n updater: user,\n id,\n description,\n name,\n mimetype,\n encoding,\n category: category || mimetype.split('/').shift(),\n size: size as any,\n path,\n contents\n })\n )\n }\n\n notify &&\n notify({\n mode: 'in-app',\n title: `${attachments.length} Attachment(s) are imported`,\n body: `${attachments.length} Attachment(s) are imported by ${user.name}`\n })\n\n return attachments\n}\n"]}
@@ -8,7 +8,7 @@ const attachment_1 = require("./service/attachment/attachment");
8
8
  const attachment_const_1 = require("./attachment-const");
9
9
  const crypto = require('crypto');
10
10
  if (attachment_const_1.STORAGE && attachment_const_1.STORAGE.type == 'database') {
11
- attachment_const_1.STORAGE.uploadFile = async ({ file, context }) => {
11
+ attachment_const_1.STORAGE.uploadFile = async ({ id, file, context }) => {
12
12
  var _a, e_1, _b, _c;
13
13
  var { createReadStream, filename, mimetype, encoding } = await file;
14
14
  filename = Buffer.from(filename, 'latin1').toString('utf-8'); /* Because busboy uses latin1 encoding */
@@ -36,7 +36,7 @@ if (attachment_const_1.STORAGE && attachment_const_1.STORAGE.type == 'database')
36
36
  }
37
37
  finally { if (e_1) throw e_1.error; }
38
38
  }
39
- const id = crypto.randomUUID();
39
+ id = id || crypto.randomUUID();
40
40
  const ext = filename.split('.').pop();
41
41
  const path = ext ? `${id}.${ext}` : id;
42
42
  const contents = Buffer.concat(chunks);
@@ -1 +1 @@
1
- {"version":3,"file":"storage-database.js","sourceRoot":"","sources":["../server/storage-database.ts"],"names":[],"mappings":"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","sourcesContent":["import contentDisposition from 'content-disposition'\n\nimport { logger } from '@things-factory/env'\nimport { getRepository } from '@things-factory/shell'\n\nimport { Attachment } from './service/attachment/attachment'\nimport { ATTACHMENT_PATH, STORAGE } from './attachment-const'\n\nconst crypto = require('crypto')\n\nif (STORAGE && STORAGE.type == 'database') {\n STORAGE.uploadFile = async ({ file, context }) => {\n var { createReadStream, filename, mimetype, encoding } = await file\n filename = Buffer.from(filename, 'latin1').toString('utf-8') /* Because busboy uses latin1 encoding */\n\n const stream = createReadStream()\n\n const chunks: Buffer[] = []\n for await (const chunk of stream) {\n if (chunk instanceof Buffer) {\n chunks.push(chunk)\n }\n }\n\n const id = crypto.randomUUID()\n const ext = filename.split('.').pop()\n const path = ext ? `${id}.${ext}` : id\n\n const contents = Buffer.concat(chunks)\n\n return {\n id,\n filename,\n mimetype,\n encoding,\n contents,\n path,\n size: contents.length\n }\n }\n\n STORAGE.deleteFile = async path => {}\n\n STORAGE.sendFile = async (context, attachment, next) => {\n const id = attachment.split('.')[0]\n\n const entity = await getRepository(Attachment).findOne({\n select: ['name', 'contents'],\n where: { id }\n })\n\n context.set('Content-Disposition', contentDisposition(entity.name))\n context.body = entity.contents\n context.type = entity.mimetype\n }\n\n STORAGE.readFile = async (attachment, encoding) => {\n const id = attachment.split('.')[0]\n\n const entity = await getRepository(Attachment).findOne({\n select: ['name', 'contents'],\n where: { id }\n })\n\n return await entity.contents\n }\n\n STORAGE.generateUploadURL = async (type: string): Promise<{ url: string; fields: { [key: string]: string } }> => {\n const id = crypto.randomUUID()\n\n return await {\n url: `/${ATTACHMENT_PATH}`,\n fields: {}\n }\n }\n\n logger.info('File Storage is Ready.')\n}\n"]}
1
+ {"version":3,"file":"storage-database.js","sourceRoot":"","sources":["../server/storage-database.ts"],"names":[],"mappings":"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","sourcesContent":["import contentDisposition from 'content-disposition'\n\nimport { logger } from '@things-factory/env'\nimport { getRepository } from '@things-factory/shell'\n\nimport { Attachment } from './service/attachment/attachment'\nimport { ATTACHMENT_PATH, STORAGE } from './attachment-const'\n\nconst crypto = require('crypto')\n\nif (STORAGE && STORAGE.type == 'database') {\n STORAGE.uploadFile = async ({ id, file, context }) => {\n var { createReadStream, filename, mimetype, encoding } = await file\n filename = Buffer.from(filename, 'latin1').toString('utf-8') /* Because busboy uses latin1 encoding */\n\n const stream = createReadStream()\n\n const chunks: Buffer[] = []\n for await (const chunk of stream) {\n if (chunk instanceof Buffer) {\n chunks.push(chunk)\n }\n }\n\n id = id || crypto.randomUUID()\n const ext = filename.split('.').pop()\n const path = ext ? `${id}.${ext}` : id\n\n const contents = Buffer.concat(chunks)\n\n return {\n id,\n filename,\n mimetype,\n encoding,\n contents,\n path,\n size: contents.length\n }\n }\n\n STORAGE.deleteFile = async path => {}\n\n STORAGE.sendFile = async (context, attachment, next) => {\n const id = attachment.split('.')[0]\n\n const entity = await getRepository(Attachment).findOne({\n select: ['name', 'contents'],\n where: { id }\n })\n\n context.set('Content-Disposition', contentDisposition(entity.name))\n context.body = entity.contents\n context.type = entity.mimetype\n }\n\n STORAGE.readFile = async (attachment, encoding) => {\n const id = attachment.split('.')[0]\n\n const entity = await getRepository(Attachment).findOne({\n select: ['name', 'contents'],\n where: { id }\n })\n\n return await entity.contents\n }\n\n STORAGE.generateUploadURL = async (type: string): Promise<{ url: string; fields: { [key: string]: string } }> => {\n const id = crypto.randomUUID()\n\n return await {\n url: `/${ATTACHMENT_PATH}`,\n fields: {}\n }\n }\n\n logger.info('File Storage is Ready.')\n}\n"]}
@@ -10,12 +10,12 @@ const crypto = require('crypto');
10
10
  const send = require('koa-send');
11
11
  if (attachment_const_1.STORAGE && attachment_const_1.STORAGE.type == 'file') {
12
12
  const uploadDir = env_1.config.getPath(null, attachment_const_1.STORAGE.base || 'attachments');
13
- attachment_const_1.STORAGE.uploadFile = async ({ file }) => {
13
+ attachment_const_1.STORAGE.uploadFile = async ({ id, file }) => {
14
14
  var { createReadStream, filename, mimetype, encoding } = await file;
15
15
  filename = Buffer.from(filename, 'latin1').toString('utf-8'); /* Because busboy uses latin1 encoding */
16
16
  const stream = createReadStream();
17
17
  mkdirp.sync(uploadDir);
18
- const id = crypto.randomUUID();
18
+ id = id || crypto.randomUUID();
19
19
  const ext = filename.split('.').pop();
20
20
  const path = ext ? (0, path_1.resolve)(uploadDir, `${id}.${ext}`) : (0, path_1.resolve)(uploadDir, id);
21
21
  const relativePath = path.split('\\').pop().split('/').pop();
@@ -1 +1 @@
1
- {"version":3,"file":"storage-file.js","sourceRoot":"","sources":["../server/storage-file.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs'\nimport * as mkdirp from 'mkdirp'\nimport { resolve } from 'path'\n\nimport { config, logger } from '@things-factory/env'\n\nimport { ATTACHMENT_PATH, STORAGE } from './attachment-const'\n\nconst crypto = require('crypto')\nconst send = require('koa-send')\n\nif (STORAGE && STORAGE.type == 'file') {\n const uploadDir = config.getPath(null, STORAGE.base || 'attachments')\n\n STORAGE.uploadFile = async ({ file }) => {\n var { createReadStream, filename, mimetype, encoding } = await file\n filename = Buffer.from(filename, 'latin1').toString('utf-8') /* Because busboy uses latin1 encoding */\n\n const stream = createReadStream()\n\n mkdirp.sync(uploadDir)\n\n const id = crypto.randomUUID()\n const ext = filename.split('.').pop()\n const path = ext ? resolve(uploadDir, `${id}.${ext}`) : resolve(uploadDir, id)\n const relativePath = path.split('\\\\').pop().split('/').pop()\n var size: number = 0\n\n return new Promise<{\n id: string\n filename: string\n path: string\n size: number\n mimetype: string\n encoding: string\n }>((resolve, reject) =>\n stream\n .on('error', error => {\n if (stream.truncated)\n // Delete the truncated file\n fs.unlinkSync(path)\n reject(error)\n })\n .on('data', chunk => {\n size += chunk.length\n })\n .pipe(fs.createWriteStream(path))\n .on('finish', () => resolve({ id, filename, path: relativePath, size, mimetype, encoding }))\n )\n }\n\n STORAGE.deleteFile = async path => {\n const fullpath = resolve(uploadDir, path)\n\n await fs.unlink(fullpath, logger.error)\n }\n\n STORAGE.sendFile = async (context, attachment, next) => {\n await send(context, attachment, { root: uploadDir })\n }\n\n STORAGE.readFile = (attachment, encoding) => {\n const fullpath = resolve(uploadDir, attachment)\n\n return fs.readFileSync(fullpath, encoding)\n }\n\n STORAGE.generateUploadURL = async (type: string): Promise<{ url: string; fields: { [key: string]: string } }> => {\n const id = crypto.randomUUID()\n\n return await {\n url: `/${ATTACHMENT_PATH}`,\n fields: {}\n }\n }\n\n logger.info('File Storage is Ready.')\n}\n"]}
1
+ {"version":3,"file":"storage-file.js","sourceRoot":"","sources":["../server/storage-file.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs'\nimport * as mkdirp from 'mkdirp'\nimport { resolve } from 'path'\n\nimport { config, logger } from '@things-factory/env'\n\nimport { ATTACHMENT_PATH, STORAGE } from './attachment-const'\n\nconst crypto = require('crypto')\nconst send = require('koa-send')\n\nif (STORAGE && STORAGE.type == 'file') {\n const uploadDir = config.getPath(null, STORAGE.base || 'attachments')\n\n STORAGE.uploadFile = async ({ id, file }) => {\n var { createReadStream, filename, mimetype, encoding } = await file\n filename = Buffer.from(filename, 'latin1').toString('utf-8') /* Because busboy uses latin1 encoding */\n\n const stream = createReadStream()\n\n mkdirp.sync(uploadDir)\n\n id = id || crypto.randomUUID()\n const ext = filename.split('.').pop()\n const path = ext ? resolve(uploadDir, `${id}.${ext}`) : resolve(uploadDir, id)\n const relativePath = path.split('\\\\').pop().split('/').pop()\n var size: number = 0\n\n return new Promise<{\n id: string\n filename: string\n path: string\n size: number\n mimetype: string\n encoding: string\n }>((resolve, reject) =>\n stream\n .on('error', error => {\n if (stream.truncated)\n // Delete the truncated file\n fs.unlinkSync(path)\n reject(error)\n })\n .on('data', chunk => {\n size += chunk.length\n })\n .pipe(fs.createWriteStream(path))\n .on('finish', () => resolve({ id, filename, path: relativePath, size, mimetype, encoding }))\n )\n }\n\n STORAGE.deleteFile = async path => {\n const fullpath = resolve(uploadDir, path)\n\n await fs.unlink(fullpath, logger.error)\n }\n\n STORAGE.sendFile = async (context, attachment, next) => {\n await send(context, attachment, { root: uploadDir })\n }\n\n STORAGE.readFile = (attachment, encoding) => {\n const fullpath = resolve(uploadDir, attachment)\n\n return fs.readFileSync(fullpath, encoding)\n }\n\n STORAGE.generateUploadURL = async (type: string): Promise<{ url: string; fields: { [key: string]: string } }> => {\n const id = crypto.randomUUID()\n\n return await {\n url: `/${ATTACHMENT_PATH}`,\n fields: {}\n }\n }\n\n logger.info('File Storage is Ready.')\n}\n"]}
@@ -22,11 +22,11 @@ if (attachment_const_1.STORAGE && attachment_const_1.STORAGE.type == 's3') {
22
22
  stream.once('error', reject);
23
23
  });
24
24
  /* upload file */
25
- attachment_const_1.STORAGE.uploadFile = async ({ file }) => {
25
+ attachment_const_1.STORAGE.uploadFile = async ({ id, file }) => {
26
26
  var { createReadStream, filename, mimetype, encoding } = await file;
27
27
  filename = Buffer.from(filename, 'latin1').toString('utf-8'); /* Because busboy uses latin1 encoding */
28
28
  const stream = createReadStream();
29
- const id = crypto.randomUUID();
29
+ id = id || crypto.randomUUID();
30
30
  const ext = filename.split('.').pop();
31
31
  const key = ext ? `${id}.${ext}` : id;
32
32
  const upload = new lib_storage_1.Upload({
@@ -1 +1 @@
1
- {"version":3,"file":"storage-s3.js","sourceRoot":"","sources":["../server/storage-s3.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Readable } from 'stream'\n\nimport {\n DeleteObjectCommand,\n GetObjectCommand,\n GetObjectCommandInput,\n HeadObjectCommand,\n S3Client\n} from '@aws-sdk/client-s3'\nimport { Upload } from '@aws-sdk/lib-storage'\nimport { createPresignedPost } from '@aws-sdk/s3-presigned-post'\nimport { logger } from '@things-factory/env'\n\nimport { STORAGE } from './attachment-const'\n\nconst crypto = require('crypto')\nconst mime = require('mime')\n\nif (STORAGE && STORAGE.type == 's3') {\n const client = new S3Client({\n credentials: {\n accessKeyId: STORAGE.accessKeyId,\n secretAccessKey: STORAGE.secretAccessKey\n },\n region: STORAGE.region\n })\n\n const streamToBuffer = (stream: Readable) =>\n new Promise<Buffer>((resolve, reject) => {\n const chunks: Buffer[] = []\n stream.on('data', chunk => chunks.push(chunk))\n stream.once('end', () => resolve(Buffer.concat(chunks)))\n stream.once('error', reject)\n })\n\n /* upload file */\n STORAGE.uploadFile = async ({ file }) => {\n var { createReadStream, filename, mimetype, encoding } = await file\n filename = Buffer.from(filename, 'latin1').toString('utf-8') /* Because busboy uses latin1 encoding */\n\n const stream = createReadStream()\n const id = crypto.randomUUID()\n const ext = filename.split('.').pop()\n const key = ext ? `${id}.${ext}` : id\n\n const upload = new Upload({\n client,\n params: {\n Bucket: STORAGE.bucketName,\n Key: key,\n Body: stream\n }\n })\n\n await upload.done()\n\n const headObjectCommand = new HeadObjectCommand({\n Bucket: STORAGE.bucketName,\n Key: key\n })\n\n const { ContentLength } = await client.send(headObjectCommand)\n\n return {\n id,\n path: key,\n filename,\n size: ContentLength,\n mimetype,\n encoding\n }\n }\n\n STORAGE.deleteFile = async (path: string) => {\n const command = new DeleteObjectCommand({\n Bucket: STORAGE.bucketName,\n Key: path\n })\n\n return await client.send(command)\n }\n\n /* TODO Streaming to Streaming 으로 구현하라. */\n STORAGE.sendFile = async (context, attachment, next) => {\n const result = await client.send(\n new GetObjectCommand({\n Bucket: STORAGE.bucketName,\n Key: attachment\n } as GetObjectCommandInput)\n )\n\n context.set({\n 'Content-Length': result.ContentLength,\n 'Content-Type': mime.getType(attachment),\n 'Last-Modified': result.LastModified.toUTCString(),\n ETag: result.ETag,\n 'Cache-Control': 'public, max-age=31556926'\n })\n\n context.body = result.Body\n }\n\n STORAGE.readFile = async (attachment: string, encoding: string) => {\n /*\n * refered to\n * https://transang.me/modern-fetch-and-how-to-get-buffer-output-from-aws-sdk-v3-getobjectcommand/#the-body-type\n */\n const result = await client.send(\n new GetObjectCommand({\n Bucket: STORAGE.bucketName,\n Key: attachment\n } as GetObjectCommandInput)\n )\n\n var body = result.Body as Readable\n var buffer = await streamToBuffer(body)\n\n switch (encoding) {\n case 'base64':\n return buffer.toString('base64')\n default:\n return await buffer\n }\n }\n\n STORAGE.generateUploadURL = async (type: string): Promise<{ url: string; fields: { [key: string]: string } }> => {\n const expiresInMinutes = 1\n const id = crypto.randomUUID()\n\n return await createPresignedPost(client, {\n Bucket: STORAGE.bucketName,\n Key: id,\n Expires: expiresInMinutes * 60,\n Conditions: [['eq', '$Content-Type', type]]\n })\n }\n\n logger.info('S3 Bucket Storage is Ready.')\n}\n"]}
1
+ {"version":3,"file":"storage-s3.js","sourceRoot":"","sources":["../server/storage-s3.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Readable } from 'stream'\n\nimport {\n DeleteObjectCommand,\n GetObjectCommand,\n GetObjectCommandInput,\n HeadObjectCommand,\n S3Client\n} from '@aws-sdk/client-s3'\nimport { Upload } from '@aws-sdk/lib-storage'\nimport { createPresignedPost } from '@aws-sdk/s3-presigned-post'\nimport { logger } from '@things-factory/env'\n\nimport { STORAGE } from './attachment-const'\n\nconst crypto = require('crypto')\nconst mime = require('mime')\n\nif (STORAGE && STORAGE.type == 's3') {\n const client = new S3Client({\n credentials: {\n accessKeyId: STORAGE.accessKeyId,\n secretAccessKey: STORAGE.secretAccessKey\n },\n region: STORAGE.region\n })\n\n const streamToBuffer = (stream: Readable) =>\n new Promise<Buffer>((resolve, reject) => {\n const chunks: Buffer[] = []\n stream.on('data', chunk => chunks.push(chunk))\n stream.once('end', () => resolve(Buffer.concat(chunks)))\n stream.once('error', reject)\n })\n\n /* upload file */\n STORAGE.uploadFile = async ({ id, file }) => {\n var { createReadStream, filename, mimetype, encoding } = await file\n filename = Buffer.from(filename, 'latin1').toString('utf-8') /* Because busboy uses latin1 encoding */\n\n const stream = createReadStream()\n id = id || crypto.randomUUID()\n const ext = filename.split('.').pop()\n const key = ext ? `${id}.${ext}` : id\n\n const upload = new Upload({\n client,\n params: {\n Bucket: STORAGE.bucketName,\n Key: key,\n Body: stream\n }\n })\n\n await upload.done()\n\n const headObjectCommand = new HeadObjectCommand({\n Bucket: STORAGE.bucketName,\n Key: key\n })\n\n const { ContentLength } = await client.send(headObjectCommand)\n\n return {\n id,\n path: key,\n filename,\n size: ContentLength,\n mimetype,\n encoding\n }\n }\n\n STORAGE.deleteFile = async (path: string) => {\n const command = new DeleteObjectCommand({\n Bucket: STORAGE.bucketName,\n Key: path\n })\n\n return await client.send(command)\n }\n\n /* TODO Streaming to Streaming 으로 구현하라. */\n STORAGE.sendFile = async (context, attachment, next) => {\n const result = await client.send(\n new GetObjectCommand({\n Bucket: STORAGE.bucketName,\n Key: attachment\n } as GetObjectCommandInput)\n )\n\n context.set({\n 'Content-Length': result.ContentLength,\n 'Content-Type': mime.getType(attachment),\n 'Last-Modified': result.LastModified.toUTCString(),\n ETag: result.ETag,\n 'Cache-Control': 'public, max-age=31556926'\n })\n\n context.body = result.Body\n }\n\n STORAGE.readFile = async (attachment: string, encoding: string) => {\n /*\n * refered to\n * https://transang.me/modern-fetch-and-how-to-get-buffer-output-from-aws-sdk-v3-getobjectcommand/#the-body-type\n */\n const result = await client.send(\n new GetObjectCommand({\n Bucket: STORAGE.bucketName,\n Key: attachment\n } as GetObjectCommandInput)\n )\n\n var body = result.Body as Readable\n var buffer = await streamToBuffer(body)\n\n switch (encoding) {\n case 'base64':\n return buffer.toString('base64')\n default:\n return await buffer\n }\n }\n\n STORAGE.generateUploadURL = async (type: string): Promise<{ url: string; fields: { [key: string]: string } }> => {\n const expiresInMinutes = 1\n const id = crypto.randomUUID()\n\n return await createPresignedPost(client, {\n Bucket: STORAGE.bucketName,\n Key: id,\n Expires: expiresInMinutes * 60,\n Conditions: [['eq', '$Content-Type', type]]\n })\n }\n\n logger.info('S3 Bucket Storage is Ready.')\n}\n"]}