Skip to content

Commit 8907470

Browse files
authored
Merge pull request #240 from ardriveapp/PE-6232-improve-gql-queries
feat(gql): utilize drive ID in conflict resolution and list folder qu…
2 parents bd6f0d1 + 7a50cfb commit 8907470

File tree

8 files changed

+115
-53
lines changed

8 files changed

+115
-53
lines changed

src/ardrive.ts

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,11 @@ export class ArDrive extends ArDriveAnonymous {
191191
}
192192

193193
// Assert that there are no duplicate names in the destination folder
194-
const entityNamesInParentFolder = await this.arFsDao.getPublicEntityNamesInFolder(newParentFolderId, owner);
194+
const entityNamesInParentFolder = await this.arFsDao.getPublicEntityNamesInFolder(
195+
newParentFolderId,
196+
owner,
197+
destFolderDriveId
198+
);
195199
if (entityNamesInParentFolder.includes(originalFileMetaData.name)) {
196200
// TODO: Add optional interactive prompt to resolve name conflicts in ticket PE-599
197201
throw new Error(errorMessage.entityNameExists);
@@ -269,7 +273,8 @@ export class ArDrive extends ArDriveAnonymous {
269273
const entityNamesInParentFolder = await this.arFsDao.getPrivateEntityNamesInFolder(
270274
newParentFolderId,
271275
owner,
272-
driveKey
276+
driveKey,
277+
destFolderDriveId
273278
);
274279
if (entityNamesInParentFolder.includes(originalFileMetaData.name)) {
275280
// TODO: Add optional interactive prompt to resolve name conflicts in ticket PE-599
@@ -353,7 +358,11 @@ export class ArDrive extends ArDriveAnonymous {
353358
}
354359

355360
// Assert that there are no duplicate names in the destination folder
356-
const entityNamesInParentFolder = await this.arFsDao.getPublicEntityNamesInFolder(newParentFolderId, owner);
361+
const entityNamesInParentFolder = await this.arFsDao.getPublicEntityNamesInFolder(
362+
newParentFolderId,
363+
owner,
364+
destFolderDriveId
365+
);
357366
if (entityNamesInParentFolder.includes(originalFolderMetaData.name)) {
358367
// TODO: Add optional interactive prompt to resolve name conflicts in ticket PE-599
359368
throw new Error(errorMessage.entityNameExists);
@@ -439,7 +448,8 @@ export class ArDrive extends ArDriveAnonymous {
439448
const entityNamesInParentFolder = await this.arFsDao.getPrivateEntityNamesInFolder(
440449
newParentFolderId,
441450
owner,
442-
driveKey
451+
driveKey,
452+
destFolderDriveId
443453
);
444454
if (entityNamesInParentFolder.includes(originalFolderMetaData.name)) {
445455
// TODO: Add optional interactive prompt to resolve name conflicts in ticket PE-599
@@ -523,14 +533,14 @@ export class ArDrive extends ArDriveAnonymous {
523533
const resolvedEntitiesToUpload: UploadStats[] = [];
524534

525535
for (const entity of entitiesToUpload) {
526-
const { destFolderId, wrappedEntity, driveKey, owner, destName } = entity;
536+
const { destFolderId, wrappedEntity, driveKey, owner, destName, destDriveId } = entity;
527537

528538
const resolveConflictParams = {
529539
conflictResolution,
530540
getConflictInfoFn: (folderId: FolderID) =>
531541
driveKey
532-
? this.arFsDao.getPrivateNameConflictInfoInFolder(folderId, owner, driveKey)
533-
: this.arFsDao.getPublicNameConflictInfoInFolder(folderId, owner),
542+
? this.arFsDao.getPrivateNameConflictInfoInFolder(folderId, owner, driveKey, destDriveId)
543+
: this.arFsDao.getPublicNameConflictInfoInFolder(folderId, owner, destDriveId),
534544
prompts,
535545
destFolderId
536546
};
@@ -729,6 +739,7 @@ export class ArDrive extends ArDriveAnonymous {
729739
destinationFolderId
730740
}: RetryPublicArFSFileByDestFolderIdParams): Promise<ArFSResult> {
731741
const metaDataTx = await this.deriveMetaDataTxFromPublicFolder(destinationFolderId, dataTxId);
742+
const driveId = await this.arFsDao.getDriveIdForFolderId(destinationFolderId);
732743

733744
let metaDataTxId: undefined | TransactionID = undefined;
734745
let createMetaDataPlan: undefined | ArFSCreateFileMetaDataV2Plan = undefined;
@@ -743,7 +754,8 @@ export class ArDrive extends ArDriveAnonymous {
743754
const isValidUpload = await this.assertWriteFileMetaData({
744755
wrappedFile,
745756
conflictResolution,
746-
destinationFolderId
757+
destinationFolderId,
758+
driveId
747759
});
748760

749761
if (!isValidUpload) {
@@ -827,11 +839,13 @@ export class ArDrive extends ArDriveAnonymous {
827839
dataTxId: TransactionID
828840
): Promise<ArFSPublicFile | undefined> {
829841
const owner = await this.wallet.getAddress();
842+
const driveId = await this.arFsDao.getDriveIdForFolderId(destinationFolderId);
830843
await this.assertFolderExists(destinationFolderId, owner);
831844

832845
const allFileMetaDataTxInFolder = await this.arFsDao.getPublicFilesWithParentFolderIds(
833846
[destinationFolderId],
834-
owner
847+
owner,
848+
driveId
835849
);
836850
const metaDataTxsForThisTx = allFileMetaDataTxInFolder.filter((f) => `${f.dataTxId}` === `${dataTxId}`);
837851

@@ -853,19 +867,22 @@ export class ArDrive extends ArDriveAnonymous {
853867
private async assertWriteFileMetaData({
854868
wrappedFile,
855869
destinationFolderId,
856-
conflictResolution
870+
conflictResolution,
871+
driveId
857872
}: {
858873
wrappedFile: ArFSFileToUpload;
859874
destinationFolderId: FolderID;
860875
conflictResolution: FileNameConflictResolution;
876+
driveId: DriveID;
861877
}): Promise<boolean> {
862878
const owner = await this.wallet.getAddress();
863879
await resolveFileNameConflicts({
864880
wrappedFile,
865881
conflictResolution,
866882
destFolderId: destinationFolderId,
867883
destinationFileName: wrappedFile.destinationBaseName,
868-
getConflictInfoFn: (folderId: FolderID) => this.arFsDao.getPublicNameConflictInfoInFolder(folderId, owner)
884+
getConflictInfoFn: (folderId: FolderID) =>
885+
this.arFsDao.getPublicNameConflictInfoInFolder(folderId, owner, driveId)
869886
});
870887

871888
if (wrappedFile.conflictResolution) {
@@ -1019,7 +1036,11 @@ export class ArDrive extends ArDriveAnonymous {
10191036
const owner = await this.wallet.getAddress();
10201037

10211038
// Assert that there are no duplicate names in the destination folder
1022-
const entityNamesInParentFolder = await this.arFsDao.getPublicEntityNamesInFolder(parentFolderId, owner);
1039+
const entityNamesInParentFolder = await this.arFsDao.getPublicEntityNamesInFolder(
1040+
parentFolderId,
1041+
owner,
1042+
driveId
1043+
);
10231044
if (entityNamesInParentFolder.includes(folderName)) {
10241045
// TODO: Add optional interactive prompt to resolve name conflicts in ticket PE-599
10251046
throw new Error(errorMessage.entityNameExists);
@@ -1083,7 +1104,8 @@ export class ArDrive extends ArDriveAnonymous {
10831104
const entityNamesInParentFolder = await this.arFsDao.getPrivateEntityNamesInFolder(
10841105
parentFolderId,
10851106
owner,
1086-
driveKey
1107+
driveKey,
1108+
driveId
10871109
);
10881110
if (entityNamesInParentFolder.includes(folderName)) {
10891111
// TODO: Add optional interactive prompt to resolve name conflicts in ticket PE-599
@@ -1438,10 +1460,11 @@ export class ArDrive extends ArDriveAnonymous {
14381460
await fileToDownload.write();
14391461
}
14401462

1441-
async assertUniqueNameWithinPublicFolder(name: string, folderId: FolderID): Promise<void> {
1463+
async assertUniqueNameWithinPublicFolder(name: string, folderId: FolderID, driveId: DriveID): Promise<void> {
14421464
const allSiblingNames = await this.arFsDao.getPublicEntityNamesInFolder(
14431465
folderId,
1444-
await this.wallet.getAddress()
1466+
await this.wallet.getAddress(),
1467+
driveId
14451468
);
14461469
const collidesWithExistingSiblingName = allSiblingNames.reduce((accumulator, siblingName) => {
14471470
return accumulator || siblingName === name;
@@ -1451,11 +1474,17 @@ export class ArDrive extends ArDriveAnonymous {
14511474
}
14521475
}
14531476

1454-
async assertUniqueNameWithinPrivateFolder(name: string, folderId: FolderID, driveKey: DriveKey): Promise<void> {
1477+
async assertUniqueNameWithinPrivateFolder(
1478+
name: string,
1479+
folderId: FolderID,
1480+
driveKey: DriveKey,
1481+
driveId: DriveID
1482+
): Promise<void> {
14551483
const allSiblingNames = await this.arFsDao.getPrivateEntityNamesInFolder(
14561484
folderId,
14571485
await this.wallet.getAddress(),
1458-
driveKey
1486+
driveKey,
1487+
driveId
14591488
);
14601489
const collidesWithExistingSiblingName = allSiblingNames.reduce((accumulator, siblingName) => {
14611490
return accumulator || siblingName === name;
@@ -1467,13 +1496,14 @@ export class ArDrive extends ArDriveAnonymous {
14671496

14681497
async renamePublicFile({ fileId, newName }: RenamePublicFileParams): Promise<ArFSResult> {
14691498
const owner = await this.wallet.getAddress();
1499+
const driveId = await this.getDriveIdForFileId(fileId);
14701500

14711501
const file = await this.getPublicFile({ fileId, owner });
14721502
if (file.name === newName) {
14731503
throw new Error(`To rename a file, the new name must be different`);
14741504
}
14751505
assertValidArFSFileName(newName);
1476-
await this.assertUniqueNameWithinPublicFolder(newName, file.parentFolderId);
1506+
await this.assertUniqueNameWithinPublicFolder(newName, file.parentFolderId, driveId);
14771507
const fileMetadataTxDataStub = new ArFSPublicFileMetadataTransactionData(
14781508
newName,
14791509
file.size,
@@ -1527,11 +1557,12 @@ export class ArDrive extends ArDriveAnonymous {
15271557
async renamePrivateFile({ fileId, newName, driveKey }: RenamePrivateFileParams): Promise<ArFSResult> {
15281558
const owner = await this.wallet.getAddress();
15291559
const file = await this.getPrivateFile({ fileId, driveKey, owner });
1560+
const driveId = await this.getDriveIdForFileId(fileId);
15301561
if (file.name === newName) {
15311562
throw new Error(`To rename a file, the new name must be different`);
15321563
}
15331564
assertValidArFSFileName(newName);
1534-
await this.assertUniqueNameWithinPrivateFolder(newName, file.parentFolderId, driveKey);
1565+
await this.assertUniqueNameWithinPrivateFolder(newName, file.parentFolderId, driveKey, driveId);
15351566
const fileMetadataTxDataStub = await ArFSPrivateFileMetadataTransactionData.from(
15361567
newName,
15371568
file.size,
@@ -1590,6 +1621,7 @@ export class ArDrive extends ArDriveAnonymous {
15901621
async renamePublicFolder({ folderId, newName }: RenamePublicFolderParams): Promise<ArFSResult> {
15911622
const owner = await this.wallet.getAddress();
15921623
const folder = await this.getPublicFolder({ folderId, owner });
1624+
const driveId = await this.getDriveIdForFolderId(folderId);
15931625
if (`${folder.parentFolderId}` === ROOT_FOLDER_ID_PLACEHOLDER) {
15941626
throw new Error(
15951627
`The root folder with ID '${folderId}' cannot be renamed as it shares its name with its parent drive. Consider renaming the drive instead.`
@@ -1599,7 +1631,7 @@ export class ArDrive extends ArDriveAnonymous {
15991631
throw new Error(`New folder name '${newName}' must be different from the current folder name!`);
16001632
}
16011633
assertValidArFSFolderName(newName);
1602-
await this.assertUniqueNameWithinPublicFolder(newName, folder.parentFolderId);
1634+
await this.assertUniqueNameWithinPublicFolder(newName, folder.parentFolderId, driveId);
16031635
const folderMetadataTxDataStub = new ArFSPublicFolderTransactionData(newName, folder.customMetaDataJson);
16041636

16051637
const metadataRewardSettings = this.uploadPlanner.isTurboUpload()
@@ -1647,6 +1679,7 @@ export class ArDrive extends ArDriveAnonymous {
16471679
async renamePrivateFolder({ folderId, newName, driveKey }: RenamePrivateFolderParams): Promise<ArFSResult> {
16481680
const owner = await this.wallet.getAddress();
16491681
const folder = await this.getPrivateFolder({ folderId, driveKey, owner });
1682+
const driveId = await this.getDriveIdForFolderId(folderId);
16501683
if (`${folder.parentFolderId}` === ROOT_FOLDER_ID_PLACEHOLDER) {
16511684
throw new Error(
16521685
`The root folder with ID '${folderId}' cannot be renamed as it shares its name with its parent drive. Consider renaming the drive instead.`
@@ -1656,7 +1689,7 @@ export class ArDrive extends ArDriveAnonymous {
16561689
throw new Error(`New folder name '${newName}' must be different from the current folder name!`);
16571690
}
16581691
assertValidArFSFolderName(newName);
1659-
await this.assertUniqueNameWithinPrivateFolder(newName, folder.parentFolderId, driveKey);
1692+
await this.assertUniqueNameWithinPrivateFolder(newName, folder.parentFolderId, driveKey, driveId);
16601693
const folderMetadataTxDataStub = await ArFSPrivateFolderTransactionData.from(
16611694
newName,
16621695
driveKey,

src/arfs/arfs_builders/arfs_builders.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,9 @@ export abstract class ArFSFileOrFolderBuilder<
193193
> extends ArFSMetadataEntityBuilder<T> {
194194
parentFolderId?: FolderID;
195195

196-
protected async parseFromArweaveNode(node?: GQLNodeInterface): Promise<GQLTagInterface[]> {
196+
protected async parseFromArweaveNode(node?: GQLNodeInterface, owner?: ArweaveAddress): Promise<GQLTagInterface[]> {
197197
const unparsedTags: GQLTagInterface[] = [];
198-
const tags = await super.parseFromArweaveNode(node);
198+
const tags = await super.parseFromArweaveNode(node, owner);
199199
tags.forEach((tag: GQLTagInterface) => {
200200
const key = tag.name;
201201
const { value } = tag;

src/arfs/arfs_builders/arfs_drive_builders.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
ArFSMetadataEntityBuilderParams,
2121
ArFSPrivateMetadataEntityBuilderParams
2222
} from './arfs_builders';
23-
import { ArFSPrivateDriveKeyless } from '../../exports';
23+
import { ArFSPrivateDriveKeyless, ArweaveAddress } from '../../exports';
2424
import { GatewayAPI } from '../../utils/gateway_api';
2525

2626
export interface DriveMetaDataTransactionData extends EntityMetaDataTransactionData {
@@ -54,9 +54,9 @@ export class ArFSPublicDriveBuilder extends ArFSDriveBuilder<ArFSPublicDrive> {
5454
];
5555
}
5656

57-
protected async parseFromArweaveNode(node?: GQLNodeInterface): Promise<GQLTagInterface[]> {
57+
protected async parseFromArweaveNode(node?: GQLNodeInterface, owner?: ArweaveAddress): Promise<GQLTagInterface[]> {
5858
const unparsedTags: GQLTagInterface[] = [];
59-
const tags = await super.parseFromArweaveNode(node);
59+
const tags = await super.parseFromArweaveNode(node, owner);
6060
tags.forEach((tag: GQLTagInterface) => {
6161
const key = tag.name;
6262
const { value } = tag;
@@ -155,9 +155,9 @@ export class ArFSPrivateDriveBuilder extends ArFSDriveBuilder<ArFSPrivateDrive>
155155
return fileBuilder;
156156
}
157157

158-
protected async parseFromArweaveNode(node?: GQLNodeInterface): Promise<GQLTagInterface[]> {
158+
protected async parseFromArweaveNode(node?: GQLNodeInterface, owner?: ArweaveAddress): Promise<GQLTagInterface[]> {
159159
const unparsedTags: GQLTagInterface[] = [];
160-
const tags = await super.parseFromArweaveNode(node);
160+
const tags = await super.parseFromArweaveNode(node, owner);
161161
tags.forEach((tag: GQLTagInterface) => {
162162
const key = tag.name;
163163
const { value } = tag;
@@ -286,9 +286,9 @@ export class SafeArFSDriveBuilder extends ArFSDriveBuilder<ArFSDriveEntity> {
286286
return driveBuilder;
287287
}
288288

289-
protected async parseFromArweaveNode(node?: GQLNodeInterface): Promise<GQLTagInterface[]> {
289+
protected async parseFromArweaveNode(node?: GQLNodeInterface, owner?: ArweaveAddress): Promise<GQLTagInterface[]> {
290290
const unparsedTags: GQLTagInterface[] = [];
291-
const tags = await super.parseFromArweaveNode(node);
291+
const tags = await super.parseFromArweaveNode(node, owner);
292292
tags.forEach((tag: GQLTagInterface) => {
293293
const key = tag.name;
294294
const { value } = tag;

src/arfs/arfs_builders/arfs_file_builders.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ export abstract class ArFSFileBuilder<T extends ArFSPublicFile | ArFSPrivateFile
4343
];
4444
}
4545

46-
protected async parseFromArweaveNode(node?: GQLNodeInterface): Promise<GQLTagInterface[]> {
47-
const tags = await super.parseFromArweaveNode(node);
46+
protected async parseFromArweaveNode(node?: GQLNodeInterface, owner?: ArweaveAddress): Promise<GQLTagInterface[]> {
47+
const tags = await super.parseFromArweaveNode(node, owner);
4848
return tags.filter((tag) => tag.name !== 'File-Id');
4949
}
5050

@@ -148,9 +148,9 @@ export class ArFSPrivateFileBuilder extends ArFSFileBuilder<ArFSPrivateFile> {
148148
return fileBuilder;
149149
}
150150

151-
protected async parseFromArweaveNode(node?: GQLNodeInterface): Promise<GQLTagInterface[]> {
151+
protected async parseFromArweaveNode(node?: GQLNodeInterface, owner?: ArweaveAddress): Promise<GQLTagInterface[]> {
152152
const unparsedTags: GQLTagInterface[] = [];
153-
const tags = await super.parseFromArweaveNode(node);
153+
const tags = await super.parseFromArweaveNode(node, owner);
154154
tags.forEach((tag: GQLTagInterface) => {
155155
const key = tag.name;
156156
const { value } = tag;

src/arfs/arfs_builders/arfs_folder_builders.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ export abstract class ArFSFolderBuilder<T extends ArFSPublicFolder | ArFSPrivate
3030
'folder',
3131
T
3232
> {
33-
protected async parseFromArweaveNode(node?: GQLNodeInterface): Promise<GQLTagInterface[]> {
34-
const tags = await super.parseFromArweaveNode(node);
33+
protected async parseFromArweaveNode(node?: GQLNodeInterface, owner?: ArweaveAddress): Promise<GQLTagInterface[]> {
34+
const tags = await super.parseFromArweaveNode(node, owner);
3535
return tags.filter((tag) => tag.name !== 'Folder-Id');
3636
}
3737

@@ -135,9 +135,9 @@ export class ArFSPrivateFolderBuilder extends ArFSFolderBuilder<ArFSPrivateFolde
135135
return folderBuilder;
136136
}
137137

138-
protected async parseFromArweaveNode(node?: GQLNodeInterface): Promise<GQLTagInterface[]> {
138+
protected async parseFromArweaveNode(node?: GQLNodeInterface, owner?: ArweaveAddress): Promise<GQLTagInterface[]> {
139139
const unparsedTags: GQLTagInterface[] = [];
140-
const tags = await super.parseFromArweaveNode(node);
140+
const tags = await super.parseFromArweaveNode(node, owner);
141141
tags.forEach((tag: GQLTagInterface) => {
142142
const key = tag.name;
143143
const { value } = tag;

src/arfs/arfs_entities.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ export class ArFSEntity {
3434
readonly contentType: ContentType; // the mime type of the file uploaded. in the case of drives and folders, it is always a JSON file. Public drive/folders must use "application/json" and private drives use "application/octet-stream" since this data is encrypted.
3535
readonly driveId: DriveID; // the unique drive identifier, created with uuidv4 https://www.npmjs.com/package/uuidv4 eg. 41800747-a852-4dc9-9078-6c20f85c0f3a
3636
readonly entityType: EntityType; // the type of ArFS entity this is. this can only be set to "drive", "folder", "file"
37-
readonly name: string; // user defined entity name, cannot be longer than 64 characters. This is stored in the JSON file that is uploaded along with the drive/folder/file metadata transaction
38-
readonly txId: TransactionID; // the arweave transaction id for this entity. 43 numbers/letters eg. 1xRhN90Mu5mEgyyrmnzKgZP0y3aK8AwSucwlCOAwsaI
37+
readonly name: string; // user defined entity name, cannot be longer than 64 characters. This is stored in the JSON file that is uploaded along with the drive/folder/file metadata transaction cspell:disable
38+
readonly txId: TransactionID; // the arweave transaction id for this entity. 43 numbers/letters eg. 1xRhN90Mu5mEgyyrmnzKgZP0y3aK8AwSucwlCOAwsaI cspell:enable
3939
readonly unixTime: UnixTime; // seconds since unix epoch, taken at the time of upload, 10 numbers eg. 1620068042
4040

4141
readonly boost?: FeeMultiple;

0 commit comments

Comments
 (0)