angular/packages/zone.js/lib/node/fs.ts
arturovt 9e07b621ea fix(zone.js): add missing APIs to Node.js fs patch (#54396)
This commit updates the list of Node.js `fs` APIs to be patched because
they haven't been updated for a long time. It adds `opendir,lutimes,writev`.
For example, the `opendir` method was added to Node.js in version 12.12.0 in
2019, causing some of the APIs to potentially be always called within the
`<root>` context.

**Note:** There are missing unit tests for these changes because in unit tests,
`fs` is patched by Bazel's Node.js rules and its `node_patches.cjs`. However,
the APIs are successfully patched in the real production code and are called
with the correct context.

PR Close #54396
2024-05-03 08:03:25 -07:00

89 lines
2.2 KiB
TypeScript

/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {patchMacroTask} from '../common/utils';
import {ZoneType} from '../zone-impl';
export function patchFs(Zone: ZoneType): void {
Zone.__load_patch('fs', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
let fs: any;
try {
fs = require('fs');
} catch (err) {}
if (!fs) return;
// watch, watchFile, unwatchFile has been patched
// because EventEmitter has been patched
const TO_PATCH_MACROTASK_METHODS = [
'access',
'appendFile',
'chmod',
'chown',
'close',
'exists',
'fchmod',
'fchown',
'fdatasync',
'fstat',
'fsync',
'ftruncate',
'futimes',
'lchmod',
'lchown',
'lutimes',
'link',
'lstat',
'mkdir',
'mkdtemp',
'open',
'opendir',
'read',
'readdir',
'readFile',
'readlink',
'realpath',
'rename',
'rmdir',
'stat',
'symlink',
'truncate',
'unlink',
'utimes',
'write',
'writeFile',
'writev',
];
TO_PATCH_MACROTASK_METHODS.filter(
(name) => !!fs[name] && typeof fs[name] === 'function',
).forEach((name) => {
patchMacroTask(fs, name, (self: any, args: any[]) => {
return {
name: 'fs.' + name,
args: args,
cbIdx: args.length > 0 ? args.length - 1 : -1,
target: self,
};
});
});
const realpathOriginalDelegate = fs.realpath?.[api.symbol('OriginalDelegate')];
// This is the only specific method that should be additionally patched because the previous
// `patchMacroTask` has overridden the `realpath` function and its `native` property.
if (realpathOriginalDelegate?.native) {
fs.realpath.native = realpathOriginalDelegate.native;
patchMacroTask(fs.realpath, 'native', (self, args) => ({
args,
target: self,
cbIdx: args.length > 0 ? args.length - 1 : -1,
name: 'fs.realpath.native',
}));
}
});
}