From 43c9bc8330bdec02157c5e9593b351597458906e Mon Sep 17 00:00:00 2001 From: Dhairya Date: Wed, 29 Nov 2023 11:29:21 +0100 Subject: [PATCH] enable image key generation --- components/js-api-client/package.json | 2 + .../js-api-client/src/core/uploadImage.ts | 94 +++++++++++++++++++ components/js-api-client/src/index.ts | 1 + 3 files changed, 97 insertions(+) create mode 100644 components/js-api-client/src/core/uploadImage.ts diff --git a/components/js-api-client/package.json b/components/js-api-client/package.json index 39a284a3..052c55aa 100644 --- a/components/js-api-client/package.json +++ b/components/js-api-client/package.json @@ -27,7 +27,9 @@ }, "dependencies": { "dotenv": "^16.0.0", + "fs": "^0.0.1-security", "json-to-graphql-query": "^2.2.4", + "mime-lite": "^1.0.3", "node-fetch": "^2", "tiny-invariant": "^1.2.0", "typescript": "^4.6.3", diff --git a/components/js-api-client/src/core/uploadImage.ts b/components/js-api-client/src/core/uploadImage.ts new file mode 100644 index 00000000..15fcbd11 --- /dev/null +++ b/components/js-api-client/src/core/uploadImage.ts @@ -0,0 +1,94 @@ +import * as fs from 'fs'; +import * as mime from 'mime-lite'; +import { ClientInterface } from './client'; + +type ImageInputWithReferenceId = { + id: string; + filename: string; + mimeType: string; +}; + +type UploadHandler = ImageInputWithReferenceId & { + buffer: Buffer; + stats: fs.Stats; + apiClient: ClientInterface; +}; + +const MUTATION_UPLOAD_FILE = `#graphql +mutation UPLOAD_FILE ($tenantId: ID!, $filename: String!, $mimeType: String!) { + fileUpload { + generatePresignedRequest( + tenantId: $tenantId + filename: $filename + contentType: $mimeType + type: MEDIA + ) { + url + fields { + name + value + } + } + } +}`; + +export async function uploadImageToTenant({ + id, + mimeType, + filename, + buffer, + stats, + apiClient, +}: UploadHandler): Promise { + const signedRequestResult = await apiClient.pimApi(MUTATION_UPLOAD_FILE, { + tenantId: id, + filename, + mimeType, + }); + + const payload = signedRequestResult.fileUpload.generatePresignedRequest; + const formData: FormData = new FormData(); + payload.fields.forEach((field: { name: string; value: string }) => { + formData.append(field.name, field.value); + }); + formData.append('file', new Blob([buffer])); + + const response = await fetch(payload.url, { + method: 'POST', + headers: new Headers({ 'Content-Length': String(stats.size) }), + body: formData, + }); + + return response.status === 201 ? (formData.get('key') as string) : false; +} + +export async function handleImageUpload(imagePath: any, apiClient: ClientInterface, tenantId: string): Promise { + if (!imagePath) return; + + const extension = imagePath.split('.').pop() as string; + const mimeType = mime.getType(extension); + const filename = imagePath.split('T/').pop() as string; + + if (!mimeType) { + console.log('Could not find mime type for file. Halting upload'); + return null; + } + + const stats = fs.statSync(imagePath); + const buffer = fs.readFileSync(imagePath); + + const data: Omit = { + mimeType, + filename, + stats, + buffer, + apiClient, + }; + + const imageKey = await uploadImageToTenant({ + id: tenantId, + ...data, + }); + + return imageKey; +} diff --git a/components/js-api-client/src/index.ts b/components/js-api-client/src/index.ts index 0853adc0..03c0b471 100644 --- a/components/js-api-client/src/index.ts +++ b/components/js-api-client/src/index.ts @@ -19,6 +19,7 @@ export * from './types/address'; export * from './types/customer'; export * from './types/signature'; export * from './types/pricing'; +export * from './core/uploadImage'; import { createClient } from './core/client'; import { createNavigationFetcher } from './core/navigation';