Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | 5x 14x 10x 10x 5x 5x 5x 5x 10x 7x 7x 3x 3x 4x 5x 10x 24x 24x 24x 24x 7x 24x 13x 13x 8x 11x 6x 10x 21x | import type {
PathLike,
SyncPathCaveat,
ReadFile,
Access,
ExistsSync,
FsConfig,
FsCapability,
} from './types.ts';
import { fsConfigStruct } from './types.ts';
import { makeCapabilitySpecification } from '../../specification.ts';
/**
* Cross-platform FS operation wrapper with validation (async version)
*
* @param operation - The underlying operation to wrap
* @param syncPathCaveat - The caveat to apply to path arguments
* @returns The operation restricted by the provided caveat
*/
export const makeCaveatedFsOperation = <
Operation extends (...args: never[]) => Promise<unknown>,
>(
operation: Operation,
syncPathCaveat: SyncPathCaveat,
): Operation => {
return harden(async (...args: Parameters<Operation>) => {
try {
// Assuming first argument is always the path
syncPathCaveat(args[0] as unknown as PathLike);
// We don't need async caveats yet, but we could await one here.
} catch (cause) {
const message = cause instanceof Error ? cause.message : 'Caveat failed';
throw new Error(`fs.${operation.name}: ${message}`, { cause });
}
return operation(...args);
}) as Operation;
};
/**
* Cross-platform synchronous FS operation wrapper with validation
*
* @param operation - The underlying synchronous operation to wrap
* @param syncPathCaveat - The caveat to apply to path arguments
* @returns The operation restricted by the provided caveat
*/
export const makeCaveatedSyncFsOperation = <
Operation extends (...args: never[]) => unknown,
>(
operation: Operation,
syncPathCaveat: SyncPathCaveat,
): Operation => {
return harden((...args: Parameters<Operation>) => {
try {
// Assuming first argument is always the path
syncPathCaveat(args[0] as unknown as PathLike);
} catch (cause) {
const message = cause instanceof Error ? cause.message : 'Caveat failed';
throw new Error(`fs.${operation.name}: ${message}`, { cause });
}
return operation(...args);
}) as Operation;
};
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/**
* Cross-platform FS capability specification factory
*
* @param config - The configuration for the capability specification
* @param config.makeExistsSync - The factory returning an existsSync operation
* @param config.promises - Object containing promise-based operation factories
* @param config.promises.makeReadFile - The factory returning a read file operation
* @param config.promises.makeAccess - The factory returning an access operation
* @param config.makePathCaveat - Factory function to create path caveats
* @returns The capability specification
*/
export const makeFsSpecification = ({
makeExistsSync,
promises,
makePathCaveat,
}: {
makeExistsSync: () => ExistsSync;
promises: {
makeReadFile: () => ReadFile;
makeAccess: () => Access;
};
makePathCaveat: (rootDir: string) => SyncPathCaveat;
}) =>
makeCapabilitySpecification(
fsConfigStruct,
(config: FsConfig): FsCapability => {
// The construction of this capability left ad-hoc until additional
// requirements dictate additional structure.
const { rootDir, existsSync, promises: promisesConfig } = config;
const caveat = makePathCaveat(rootDir);
const toExport: FsCapability = {};
if (existsSync) {
toExport.existsSync = makeCaveatedSyncFsOperation(
// eslint-disable-next-line n/no-sync
makeExistsSync(),
caveat,
);
}
if (promisesConfig) {
const promisesObj: FsCapability['promises'] = {};
if (promisesConfig.readFile) {
promisesObj.readFile = makeCaveatedFsOperation(
promises.makeReadFile(),
caveat,
);
}
if (promisesConfig.access) {
promisesObj.access = makeCaveatedFsOperation(
promises.makeAccess(),
caveat,
);
}
toExport.promises = harden(promisesObj);
}
return harden(toExport);
},
);
/* eslint-enable @typescript-eslint/explicit-function-return-type */
|