@cooperation/vc-storage 1.0.7 → 1.0.10

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.
@@ -73,7 +73,7 @@ export class GoogleDriveStorage {
73
73
  const fileMetadata = {
74
74
  name: data.fileName,
75
75
  parents: [folderId], // Specify the folder ID
76
- mimeType: 'application/json', // Use provided MIME type or default to JSON
76
+ mimeType: data.mimeType,
77
77
  };
78
78
  let uploadUrl = 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart';
79
79
  const formData = new FormData();
@@ -167,16 +167,66 @@ export class GoogleDriveStorage {
167
167
  * @returns file content
168
168
  */
169
169
  async retrieve(id) {
170
+ const metadataUrl = `https://www.googleapis.com/drive/v3/files/${id}?fields=name`;
171
+ const dataUrl = `https://www.googleapis.com/drive/v3/files/${id}?alt=media`;
170
172
  try {
171
- const file = await this.fetcher({
173
+ console.log(`Starting retrieval for file ID: ${id}`);
174
+ // Fetch file metadata to get the name
175
+ const metadataResponse = await fetch(metadataUrl, {
172
176
  method: 'GET',
173
- headers: {},
174
- url: `https://www.googleapis.com/drive/v3/files/${id}?alt=media`,
177
+ headers: {
178
+ Authorization: `Bearer ${this.accessToken}`,
179
+ },
175
180
  });
176
- return file;
181
+ if (!metadataResponse.ok) {
182
+ const errorData = await metadataResponse.json();
183
+ console.error(`Failed to retrieve metadata for file ID ${id}:`, errorData);
184
+ return null;
185
+ }
186
+ const metadata = await metadataResponse.json();
187
+ const fileName = metadata.name;
188
+ console.log(`File name retrieved: ${fileName}`);
189
+ // Fetch actual file data
190
+ const dataResponse = await fetch(dataUrl, {
191
+ method: 'GET',
192
+ headers: {
193
+ Authorization: `Bearer ${this.accessToken}`,
194
+ },
195
+ });
196
+ if (!dataResponse.ok) {
197
+ const errorData = await dataResponse.json();
198
+ console.error(`Failed to retrieve file data for ID ${id}:`, errorData);
199
+ return null;
200
+ }
201
+ const contentType = dataResponse.headers.get('Content-Type');
202
+ console.log(`File content type: ${contentType}`);
203
+ let fileData;
204
+ if (contentType?.includes('application/json')) {
205
+ fileData = await dataResponse.json();
206
+ }
207
+ else if (contentType?.includes('text') || contentType?.includes('image/svg+xml')) {
208
+ fileData = await dataResponse.text(); // Fetch SVG files as text for easy manipulation
209
+ }
210
+ else if (contentType?.includes('image') ||
211
+ contentType?.includes('video') ||
212
+ contentType?.includes('audio') ||
213
+ contentType?.includes('application/octet-stream') ||
214
+ contentType?.includes('application/pdf') ||
215
+ contentType?.includes('application/msword') ||
216
+ contentType?.includes('application/vnd.openxmlformats-officedocument.wordprocessingml.document') ||
217
+ contentType?.includes('application/vnd.ms-excel') ||
218
+ contentType?.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')) {
219
+ fileData = await dataResponse.blob();
220
+ }
221
+ else {
222
+ fileData = await dataResponse.arrayBuffer(); // Fallback for other binary types
223
+ }
224
+ console.log('🚀 ~ GoogleDriveStorage ~ retrieve ~ fileData:', fileData);
225
+ // Return file ID, name, and data
226
+ return { id, name: fileName, data: fileData };
177
227
  }
178
228
  catch (error) {
179
- console.error('Error retrieving file:', error);
229
+ console.error(`Error retrieving file with ID ${id}:`, error.message);
180
230
  return null;
181
231
  }
182
232
  }
@@ -309,6 +359,31 @@ export class GoogleDriveStorage {
309
359
  return []; // Return an empty array on error
310
360
  }
311
361
  }
362
+ /**
363
+ * Update the name of a file in Google Drive
364
+ * @param fileId - The ID of the file to update
365
+ * @param newFileName - The new name for the file
366
+ * @returns The updated file metadata, including the new name
367
+ */
368
+ async updateFileName(fileId, newFileName) {
369
+ try {
370
+ const metadata = {
371
+ name: newFileName, // New name for the file
372
+ };
373
+ const updatedFile = await this.fetcher({
374
+ method: 'PATCH',
375
+ headers: { 'Content-Type': 'application/json' },
376
+ body: JSON.stringify(metadata),
377
+ url: `https://www.googleapis.com/drive/v3/files/${fileId}`,
378
+ });
379
+ console.log('File name updated successfully:', updatedFile.name);
380
+ return updatedFile;
381
+ }
382
+ catch (error) {
383
+ console.error('Error updating file name:', error.message);
384
+ throw error;
385
+ }
386
+ }
312
387
  /**
313
388
  * Delete file by id
314
389
  * @param id
@@ -45,7 +45,11 @@ export declare class GoogleDriveStorage {
45
45
  * @param id
46
46
  * @returns file content
47
47
  */
48
- retrieve(id: string): Promise<any>;
48
+ retrieve(id: string): Promise<{
49
+ id: string;
50
+ name: string;
51
+ data: any;
52
+ } | null>;
49
53
  /**
50
54
  * Get folder by folderId, if folderId == null you will have them all
51
55
  * @param id [Optional]
@@ -64,7 +68,14 @@ export declare class GoogleDriveStorage {
64
68
  * @param type
65
69
  * @returns
66
70
  */
67
- getAllFilesByType(type: 'KEYPAIRs' | 'VCs' | 'SESSIONs' | 'DIDs' | 'RECOMMENDATIONs'): Promise<FileContent[]>;
71
+ getAllFilesByType(type: 'KEYPAIRs' | 'VCs' | 'SESSIONs' | 'DIDs' | 'RECOMMENDATIONs' | 'MEDIAs'): Promise<FileContent[]>;
72
+ /**
73
+ * Update the name of a file in Google Drive
74
+ * @param fileId - The ID of the file to update
75
+ * @param newFileName - The new name for the file
76
+ * @returns The updated file metadata, including the new name
77
+ */
78
+ updateFileName(fileId: string, newFileName: string): Promise<any>;
68
79
  /**
69
80
  * Delete file by id
70
81
  * @param id
@@ -10,5 +10,15 @@ import { GoogleDriveStorage } from '../models/GoogleDriveStorage.js';
10
10
  * @throws Will throw an error if the save operation fails.
11
11
  */
12
12
  export declare function saveToGoogleDrive(storage: GoogleDriveStorage, data: any, type: 'VC' | 'DID' | 'SESSION' | 'RECOMMENDATION' | 'KEYPAIR', uuid?: string): Promise<object>;
13
+ /**
14
+ * Upload an image to Google Drive in the Credentials/MEDIAs folder.
15
+ * @param {GoogleDriveStorage} storage - The GoogleDriveStorage instance.
16
+ * @param {File} imageFile - The image file to upload.
17
+ * @returns {Promise<>} - The uploaded image file object.
18
+ * @throws Will throw an error if the upload operation fails.
19
+ */
20
+ export declare function uploadImageToGoogleDrive(storage: GoogleDriveStorage, imageFile: File): Promise<{
21
+ id: string;
22
+ }>;
13
23
  export declare function generateViewLink(fileId: string): string;
14
24
  export declare function extractGoogleDriveFileId(url: string): string | null;
@@ -59,6 +59,53 @@ export async function saveToGoogleDrive(storage, data, type, uuid) {
59
59
  throw error;
60
60
  }
61
61
  }
62
+ /**
63
+ * Upload an image to Google Drive in the Credentials/MEDIAs folder.
64
+ * @param {GoogleDriveStorage} storage - The GoogleDriveStorage instance.
65
+ * @param {File} imageFile - The image file to upload.
66
+ * @returns {Promise<>} - The uploaded image file object.
67
+ * @throws Will throw an error if the upload operation fails.
68
+ */
69
+ export async function uploadImageToGoogleDrive(storage, imageFile) {
70
+ try {
71
+ // Get all root folders
72
+ const rootFolders = await storage.findFolders();
73
+ // Find or create the "Credentials" folder
74
+ let credentialsFolder = rootFolders.find((f) => f.name === 'Credentials');
75
+ let credentialsFolderId;
76
+ if (!credentialsFolder) {
77
+ credentialsFolderId = await storage.createFolder('Credentials');
78
+ }
79
+ else {
80
+ credentialsFolderId = credentialsFolder.id;
81
+ }
82
+ // Get subfolders within the "Credentials" folder
83
+ const subfolders = await storage.findFolders(credentialsFolderId);
84
+ // Find or create the "MEDIAs" folder
85
+ let mediasFolder = subfolders.find((f) => f.name === 'MEDIAs');
86
+ let mediasFolderId;
87
+ if (!mediasFolder) {
88
+ mediasFolderId = await storage.createFolder('MEDIAs', credentialsFolderId);
89
+ }
90
+ else {
91
+ mediasFolderId = mediasFolder.id;
92
+ }
93
+ // Prepare the image file data
94
+ const imageData = {
95
+ fileName: imageFile.name,
96
+ mimeType: imageFile.type,
97
+ body: imageFile,
98
+ };
99
+ // Save the image in the "MEDIAs" folder
100
+ const uploadedImage = await storage.save(imageData, mediasFolderId);
101
+ console.log(`Image uploaded: ${uploadedImage?.id} to MEDIAs folder in Credentials`);
102
+ return uploadedImage;
103
+ }
104
+ catch (error) {
105
+ console.error('Error uploading image to Google Drive:', error);
106
+ throw error;
107
+ }
108
+ }
62
109
  export function generateViewLink(fileId) {
63
110
  if (!fileId) {
64
111
  throw new Error('File ID is required to generate a view link.');
@@ -36,7 +36,7 @@ export const createAndSignVerifiablePresentation = async (accessTokens, vcFileId
36
36
  }
37
37
  }
38
38
  // Create Verifiable Presentation (VP) with the retrieved VC
39
- const presentation = await engine.createPresentation([verifiableCredential, ...recommendations]); //! do not edit the array order!!
39
+ const presentation = await engine.createPresentation([verifiableCredential.data, ...recommendations]); //! do not edit the array order!!
40
40
  // Use the key pair to sign the presentation
41
41
  const signedPresentation = await engine.signPresentation(presentation);
42
42
  return { signedPresentation };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cooperation/vc-storage",
3
3
  "type": "module",
4
- "version": "1.0.7",
4
+ "version": "1.0.10",
5
5
  "description": "Sign and store your verifiable credentials.",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/types/index.d.ts",