diff --git a/src/client/handlers/VaultsSecretsGetFileTree.ts b/src/client/handlers/VaultsSecretsGetFileTree.ts index 7ae493385..438638ed0 100644 --- a/src/client/handlers/VaultsSecretsGetFileTree.ts +++ b/src/client/handlers/VaultsSecretsGetFileTree.ts @@ -1,10 +1,10 @@ import type { DB } from '@matrixai/db'; import type VaultManager from '../../vaults/VaultManager'; import type { ClientRPCRequestParams, ClientRPCResponseResult } from '../types'; -import type { TreeNode } from '../../vaults/types'; -import type { SecretFilesMessage } from '../types'; +import type { SecretFilesMessage, VaultFileNode } from '../types'; +import path from 'path'; import { ServerHandler } from '@matrixai/rpc'; -import { fileTree } from '../../vaults'; +import { generateStats } from '../../vaults/fileTree'; import * as vaultsUtils from '../../vaults/utils'; import * as vaultsErrors from '../../vaults/errors'; @@ -14,12 +14,12 @@ class VaultsSecretsGetFileTree extends ServerHandler< db: DB; }, ClientRPCRequestParams, - ClientRPCResponseResult + ClientRPCResponseResult > { public async *handle( input: ClientRPCRequestParams, _cancel: any, - ): AsyncGenerator, void, void> { + ): AsyncGenerator, void, void> { const { vaultManager, db } = this.container; const vaultId = await db.withTransactionF(async (tran) => { const vaultIdFromName = await vaultManager.getVaultId( @@ -34,20 +34,23 @@ class VaultsSecretsGetFileTree extends ServerHandler< yield* vaultManager.withVaultsG([vaultId], (vault) => { return vault.readG(async function* (fs): AsyncGenerator< - TreeNode, + VaultFileNode, void, void > { - yield* fileTree.globWalk({ - fs: fs, - basePath: '.', - pattern: input.pattern, - yieldStats: input.yieldStats, - yieldRoot: input.yieldRoot, - yieldFiles: input.yieldFiles, - yieldParents: input.yieldParents, - yieldDirectories: input.yieldDirectories, - }); + // @ts-ignore: While the types don't fully match, it matches enough for our usage. + let files: Array = await fs.promises.readdir(input.pattern); + files = files.map((file) => path.join(input.pattern, file)); + + for await (const file of files) { + const stat = await fs.promises.stat(file); + const type = stat.isFile() ? 'FILE' : 'DIRECTORY'; + yield { + path: file, + type: type, + stat: input.yieldStats ? generateStats(stat) : undefined, + }; + } }); }); } diff --git a/src/client/types.ts b/src/client/types.ts index 2ff158abf..d1f2016d9 100644 --- a/src/client/types.ts +++ b/src/client/types.ts @@ -13,7 +13,12 @@ import type { VaultIdEncoded, } from '../ids'; import type { GestaltAction } from '../gestalts/types'; -import type { CommitId, VaultAction, VaultName } from '../vaults/types'; +import type { + CommitId, + StatEncoded, + VaultAction, + VaultName, +} from '../vaults/types'; import type { CertificatePEM, JWKEncrypted, PublicKeyJWK } from '../keys/types'; import type { Notification } from '../notifications/types'; import type { ProviderToken } from '../identities/types'; @@ -300,18 +305,11 @@ type VaultsLatestVersionMessage = { }; // Secrets - type SecretFilesMessage = VaultIdentifierMessage & { pattern: string; yieldStats: boolean; - yieldRoot: boolean; - yieldFiles: boolean; - yieldParents: boolean; - yieldDirectories: boolean; }; -// NOTE: we used to use SecretNameMessage before. do we need to keep it? look into this. - type SecretNameMessage = { secretName: string; }; @@ -338,6 +336,12 @@ type SecretRenameMessage = SecretIdentifierMessage & { newSecretName: string; }; +type VaultFileNode = { + path: string; + type: 'FILE' | 'DIRECTORY'; + stat?: StatEncoded; +}; + // Stat is the 'JSON.stringify version of the file stat type SecretStatMessage = { stat: { @@ -429,6 +433,7 @@ export type { SecretMkdirMessage, SecretDirMessage, SecretRenameMessage, + VaultFileNode, SecretStatMessage, SignatureMessage, OverrideRPClientType, diff --git a/tests/client/handlers/vaults.test.ts b/tests/client/handlers/vaults.test.ts index 9ba69942a..71a190f8a 100644 --- a/tests/client/handlers/vaults.test.ts +++ b/tests/client/handlers/vaults.test.ts @@ -1591,12 +1591,8 @@ describe('vaultsSecretsNewDir and vaultsSecretsList', () => { // List secrets with names of directories const secrets = await rpcClient.methods.vaultsSecretsGetFileTree({ nameOrId: vaultsIdEncoded, - pattern: '**/*', + pattern: 'secretDir', yieldStats: false, - yieldRoot: false, - yieldFiles: true, - yieldParents: false, - yieldDirectories: true, }); // Extract secret file paths @@ -1604,10 +1600,9 @@ describe('vaultsSecretsNewDir and vaultsSecretsList', () => { for await (const file of secrets) { parsedFiles.push(file.path); } - expect(parsedFiles).toIncludeAllMembers([ - ...secretList.map((secret) => path.join('secretDir', secret)), - 'secretDir', - ]); + expect(parsedFiles).toIncludeAllMembers( + secretList.map((secret) => path.join('secretDir', secret)), + ); }); }); describe('vaultsSecretsRename', () => {