current commit
261015.3 · vfs: unflag
// Flags: --disable-warning=ExperimentalWarning --expose-internals
'use strict';

require('../common');
const assert = require('assert');
const path = require('path');
const vfs = require('node:vfs');

// read() reads package.json from VFS
{
  const myVfs = vfs.create();
  myVfs.mkdirSync('/pkg', { recursive: true });
  myVfs.writeFileSync('/pkg/package.json', JSON.stringify({
    name: 'test-pkg',
    type: 'module',
    main: './index.js',
    exports: { '.': './index.js' },
  }));
  const mountPoint = myVfs.mount();

  const packageJsonReader = require('internal/modules/package_json_reader');
  const result = packageJsonReader.read(
    path.join(mountPoint, 'pkg', 'package.json'), {},
  );

  assert.strictEqual(result.exists, true);
  assert.strictEqual(result.name, 'test-pkg');
  assert.strictEqual(result.type, 'module');
  assert.strictEqual(result.main, './index.js');
  assert.deepStrictEqual(result.exports, { '.': './index.js' });
  assert.strictEqual(
    result.pjsonPath,
    path.join(mountPoint, 'pkg', 'package.json'),
  );

  // Non-existent package.json returns exists: false
  const missing = packageJsonReader.read(
    path.join(mountPoint, 'nope', 'package.json'), {},
  );
  assert.strictEqual(missing.exists, false);

  myVfs.unmount();
}

// getNearestParentPackageJSON() walks up VFS directories
{
  const myVfs = vfs.create();
  myVfs.mkdirSync('/app/src/lib/deep', { recursive: true });
  myVfs.writeFileSync('/app/package.json', JSON.stringify({
    name: 'my-app',
    type: 'module',
  }));
  myVfs.writeFileSync('/app/src/lib/deep/module.js', '');
  const mountPoint = myVfs.mount();

  const packageJsonReader = require('internal/modules/package_json_reader');
  const result = packageJsonReader.getNearestParentPackageJSON(
    path.join(mountPoint, 'app', 'src', 'lib', 'deep', 'module.js'),
  );

  assert.ok(result);
  assert.strictEqual(result.exists, true);
  assert.strictEqual(result.data.name, 'my-app');
  assert.strictEqual(result.data.type, 'module');
  assert.strictEqual(
    result.path,
    path.join(mountPoint, 'app', 'package.json'),
  );

  myVfs.unmount();
}

// getPackageScopeConfig() returns correct scope from VFS
{
  const myVfs = vfs.create();
  myVfs.mkdirSync('/project/src', { recursive: true });
  myVfs.writeFileSync('/project/package.json', JSON.stringify({
    name: 'my-project',
    type: 'commonjs',
    exports: { '.': './main.js' },
  }));
  myVfs.writeFileSync('/project/src/index.js', '');
  const mountPoint = myVfs.mount();

  const packageJsonReader = require('internal/modules/package_json_reader');
  const { pathToFileURL } = require('url');
  const scopeUrl = pathToFileURL(
    path.join(mountPoint, 'project', 'src', 'index.js'),
  ).href;
  const result = packageJsonReader.getPackageScopeConfig(scopeUrl);

  assert.strictEqual(result.exists, true);
  assert.strictEqual(result.type, 'commonjs');
  assert.strictEqual(result.name, 'my-project');
  assert.strictEqual(
    result.pjsonPath,
    path.join(mountPoint, 'project', 'package.json'),
  );

  // Path with no package.json returns exists: false
  const myVfs2 = vfs.create();
  myVfs2.mkdirSync('/empty/src', { recursive: true });
  myVfs2.writeFileSync('/empty/src/file.js', '');
  const mountPoint2 = myVfs2.mount();

  const emptyUrl = pathToFileURL(
    path.join(mountPoint2, 'empty', 'src', 'file.js'),
  ).href;
  const emptyResult = packageJsonReader.getPackageScopeConfig(emptyUrl);
  assert.strictEqual(emptyResult.exists, false);

  myVfs2.unmount();
  myVfs.unmount();
}

// getPackageType() returns correct type from VFS
{
  const myVfs = vfs.create();
  myVfs.mkdirSync('/esm-app', { recursive: true });
  myVfs.writeFileSync('/esm-app/package.json', JSON.stringify({
    type: 'module',
  }));
  myVfs.writeFileSync('/esm-app/index.js', '');
  const mountPoint = myVfs.mount();

  const packageJsonReader = require('internal/modules/package_json_reader');
  const { pathToFileURL } = require('url');
  const typeUrl = pathToFileURL(
    path.join(mountPoint, 'esm-app', 'index.js'),
  ).href;
  const type = packageJsonReader.getPackageType(typeUrl);
  assert.strictEqual(type, 'module');

  // No package.json => 'none'
  const myVfs2 = vfs.create();
  myVfs2.mkdirSync('/bare', { recursive: true });
  myVfs2.writeFileSync('/bare/file.js', '');
  const mountPoint2 = myVfs2.mount();

  const noneUrl = pathToFileURL(
    path.join(mountPoint2, 'bare', 'file.js'),
  ).href;
  const noneType = packageJsonReader.getPackageType(noneUrl);
  assert.strictEqual(noneType, 'none');

  myVfs2.unmount();
  myVfs.unmount();
}

// End-to-end CJS require with package.json type detection
{
  const myVfs = vfs.create();
  myVfs.mkdirSync('/cjs-app', { recursive: true });
  myVfs.writeFileSync('/cjs-app/package.json', JSON.stringify({
    name: 'cjs-app',
    type: 'commonjs',
  }));
  myVfs.writeFileSync('/cjs-app/main.js',
                      'module.exports = { format: "cjs", ok: true };');
  const mountPoint = myVfs.mount();

  const result = require(`${mountPoint}/cjs-app/main.js`);
  assert.strictEqual(result.format, 'cjs');
  assert.strictEqual(result.ok, true);

  myVfs.unmount();
}

// End-to-end ESM import with VFS package type
{
  const myVfs = vfs.create();
  myVfs.mkdirSync('/esm', { recursive: true });
  myVfs.writeFileSync('/esm/package.json', JSON.stringify({
    type: 'module',
  }));
  myVfs.writeFileSync('/esm/mod.mjs', 'export const x = 42;');
  const mountPoint = myVfs.mount();

  const mod = require(`${mountPoint}/esm/mod.mjs`);
  assert.strictEqual(mod.x, 42);

  myVfs.unmount();
}