GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fs: add directory autodetection to fsPromises.symlink() · nodejs/node@a4fa526

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • doc/api
    • fs.md
  • lib/internal/fs
    • promises.js
  • test/parallel
    • test-fs-symlink-dir.js
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎doc/api/fs.md‎

Copy file name to clipboardExpand all lines: doc/api/fs.md
+12-3Lines changed: 12 additions & 3 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1463,18 +1463,27 @@ changes:
14631463
14641464
<!-- YAML
14651465
added: v10.0.0
1466+
changes:
1467+
- version: REPLACEME
1468+
pr-url: https://github.com/nodejs/node/pull/42894
1469+
description: If the `type` argument is `null` or omitted, Node.js will
1470+
autodetect `target` type and automatically
1471+
select `dir` or `file`.
1472+
14661473
-->
14671474
14681475
* `target` {string|Buffer|URL}
14691476
* `path` {string|Buffer|URL}
1470-
* `type` {string} **Default:** `'file'`
1477+
* `type` {string|null} **Default:** `null`
14711478
* Returns: {Promise} Fulfills with `undefined` upon success.
14721479
14731480
Creates a symbolic link.
14741481
14751482
The `type` argument is only used on Windows platforms and can be one of `'dir'`,
1476-
`'file'`, or `'junction'`. Windows junction points require the destination path
1477-
to be absolute. When using `'junction'`, the `target` argument will
1483+
`'file'`, or `'junction'`. If the `type` argument is not a string, Node.js will
1484+
autodetect `target` type and use `'file'` or `'dir'`. If the `target` does not
1485+
exist, `'file'` will be used. Windows junction points require the destination
1486+
path to be absolute. When using `'junction'`, the `target` argument will
14781487
automatically be normalized to absolute path.
14791488
14801489
### `fsPromises.truncate(path[, len])`
Collapse file

‎lib/internal/fs/promises.js‎

Copy file name to clipboardExpand all lines: lib/internal/fs/promises.js
+12-1Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ const {
117117
const getDirectoryEntriesPromise = promisify(getDirents);
118118
const validateRmOptionsPromise = promisify(validateRmOptions);
119119

120+
const isWindows = process.platform === 'win32';
121+
120122
let cpPromises;
121123
function lazyLoadCpPromises() {
122124
return cpPromises ??= require('internal/fs/cp/cp').cpFn;
@@ -714,7 +716,16 @@ async function readlink(path, options) {
714716
}
715717

716718
async function symlink(target, path, type_) {
717-
const type = (typeof type_ === 'string' ? type_ : null);
719+
let type = (typeof type_ === 'string' ? type_ : null);
720+
if (isWindows && type === null) {
721+
try {
722+
const absoluteTarget = pathModule.resolve(`${path}`, '..', `${target}`);
723+
type = (await stat(absoluteTarget)).isDirectory() ? 'dir' : 'file';
724+
} catch {
725+
// Default to 'file' if path is invalid or file does not exist
726+
type = 'file';
727+
}
728+
}
718729
target = getValidatedPath(target, 'target');
719730
path = getValidatedPath(path);
720731
return binding.symlink(preprocessSymlinkDestination(target, type, path),
Collapse file

‎test/parallel/test-fs-symlink-dir.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-fs-symlink-dir.js
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ if (!common.canCreateSymLink())
1212
const assert = require('assert');
1313
const path = require('path');
1414
const fs = require('fs');
15+
const fsPromises = fs.promises;
1516

1617
const tmpdir = require('../common/tmpdir');
1718
tmpdir.refresh();
@@ -36,11 +37,18 @@ function testAsync(target, path) {
3637
}));
3738
}
3839

40+
async function testPromises(target, path) {
41+
await fsPromises.symlink(target, path);
42+
fs.readdirSync(path);
43+
}
44+
3945
for (const linkTarget of linkTargets) {
4046
fs.mkdirSync(path.resolve(tmpdir.path, linkTarget));
4147
for (const linkPath of linkPaths) {
4248
testSync(linkTarget, `${linkPath}-${path.basename(linkTarget)}-sync`);
4349
testAsync(linkTarget, `${linkPath}-${path.basename(linkTarget)}-async`);
50+
testPromises(linkTarget, `${linkPath}-${path.basename(linkTarget)}-promises`)
51+
.then(common.mustCall());
4452
}
4553
}
4654

@@ -57,10 +65,17 @@ for (const linkTarget of linkTargets) {
5765
}));
5866
}
5967

68+
async function testPromises(target, path) {
69+
await fsPromises.symlink(target, path);
70+
assert(!fs.existsSync(path));
71+
}
72+
6073
for (const linkTarget of linkTargets.map((p) => p + '-broken')) {
6174
for (const linkPath of linkPaths) {
6275
testSync(linkTarget, `${linkPath}-${path.basename(linkTarget)}-sync`);
6376
testAsync(linkTarget, `${linkPath}-${path.basename(linkTarget)}-async`);
77+
testPromises(linkTarget, `${linkPath}-${path.basename(linkTarget)}-promises`)
78+
.then(common.mustCall());
6479
}
6580
}
6681
}

0 commit comments

Comments
0 (0)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.