* Creates the link called `path` pointing to `target`. * @param {string | Buffer | URL} target * @param {string | Buffer | URL} path * @param {string | null} [type] * @param {(err?: Error) => any} callback * @returns {void}
(target, path, type, callback)
| 2157 | * @returns {void} |
| 2158 | */ |
| 2159 | function symlink(target, path, type, callback) { |
| 2160 | if (callback === undefined) { |
| 2161 | callback = makeCallback(type); |
| 2162 | type = undefined; |
| 2163 | } else { |
| 2164 | validateOneOf(type, 'type', ['dir', 'file', 'junction', null, undefined]); |
| 2165 | } |
| 2166 | |
| 2167 | const h = vfsState.handlers; |
| 2168 | if (h !== null && vfsVoid(h.symlink(target, path, type), callback)) return; |
| 2169 | |
| 2170 | // Due to the nature of Node.js runtime, symlinks has different edge cases that can bypass |
| 2171 | // the permission model security guarantees. Thus, this API is disabled unless fs.read |
| 2172 | // and fs.write permission has been given. |
| 2173 | if (permission.isEnabled() && !permission.has('fs')) { |
| 2174 | callback(new ERR_ACCESS_DENIED('fs.symlink API requires full fs.read and fs.write permissions.')); |
| 2175 | return; |
| 2176 | } |
| 2177 | |
| 2178 | target = getValidatedPath(target, 'target'); |
| 2179 | path = getValidatedPath(path); |
| 2180 | |
| 2181 | if (isWindows && type == null) { |
| 2182 | let absoluteTarget; |
| 2183 | try { |
| 2184 | // Symlinks targets can be relative to the newly created path. |
| 2185 | // Calculate absolute file name of the symlink target, and check |
| 2186 | // if it is a directory. Ignore resolve error to keep symlink |
| 2187 | // errors consistent between platforms if invalid path is |
| 2188 | // provided. |
| 2189 | absoluteTarget = pathModule.resolve(path, '..', target); |
| 2190 | } catch { |
| 2191 | // Continue regardless of error. |
| 2192 | } |
| 2193 | if (absoluteTarget !== undefined) { |
| 2194 | stat(absoluteTarget, (err, stat) => { |
| 2195 | const resolvedType = !err && stat.isDirectory() ? 'dir' : 'file'; |
| 2196 | const resolvedFlags = stringToSymlinkType(resolvedType); |
| 2197 | const destination = preprocessSymlinkDestination(target, |
| 2198 | resolvedType, |
| 2199 | path); |
| 2200 | |
| 2201 | const req = new FSReqCallback(); |
| 2202 | req.oncomplete = callback; |
| 2203 | binding.symlink( |
| 2204 | destination, |
| 2205 | path, |
| 2206 | resolvedFlags, |
| 2207 | req, |
| 2208 | ); |
| 2209 | }); |
| 2210 | return; |
| 2211 | } |
| 2212 | } |
| 2213 | |
| 2214 | const destination = preprocessSymlinkDestination(target, type, path); |
| 2215 | |
| 2216 | const flags = stringToSymlinkType(type); |
nothing calls this directly
no test coverage detected
searching dependent graphs…