Skip to content

Commit

Permalink
feat(jest-resolve): expose PackageFilter, PathFilter and `Package…
Browse files Browse the repository at this point in the history
…JSON` types (#12712)
  • Loading branch information
mrazauskas committed Apr 22, 2022
1 parent a293b75 commit 3c6f14b
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 35 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -46,7 +46,7 @@
- `[jest-resolve, jest-runtime]` Add support for `data:` URI import and mock ([#12392](https://github.com/facebook/jest/pull/12392))
- `[jest-resolve, jest-runtime]` Add support for async resolver ([#11540](https://github.com/facebook/jest/pull/11540))
- `[jest-resolve]` [**BREAKING**] Remove `browser?: boolean` from resolver options, `conditions: ['browser']` should be used instead ([#12707](https://github.com/facebook/jest/pull/12707))
- `[jest-resolve]` Expose `JestResolver`, `AsyncResolver` and `SyncResolver` types ([#12707](https://github.com/facebook/jest/pull/12707))
- `[jest-resolve]` Expose `JestResolver`, `AsyncResolver`, `SyncResolver`, `PackageFilter`, `PathFilter` and `PackageJSON` types ([#12707](https://github.com/facebook/jest/pull/12707), ([#12712](https://github.com/facebook/jest/pull/12712))
- `[jest-runner]` Allow `setupFiles` module to export an async function ([#12042](https://github.com/facebook/jest/pull/12042))
- `[jest-runner]` Allow passing `testEnvironmentOptions` via docblocks ([#12470](https://github.com/facebook/jest/pull/12470))
- `[jest-runner]` Exposing `CallbackTestRunner`, `EmittingTestRunner` abstract classes to help typing third party runners ([#12646](https://github.com/facebook/jest/pull/12646))
Expand Down
6 changes: 2 additions & 4 deletions docs/Configuration.md
Expand Up @@ -927,8 +927,6 @@ This option allows the use of a custom resolver. This resolver must be a module
The options object provided to resolvers has the shape:

```ts
type PackageJson = Record<string, unknown>;

type ResolverOptions = {
/** Directory to begin resolving from. */
basedir: string;
Expand All @@ -943,9 +941,9 @@ type ResolverOptions = {
/** List of `require.paths` to use if nothing is found in `node_modules`. */
paths?: Array<string>;
/** Allows transforming parsed `package.json` contents. */
packageFilter?: (pkg: PackageJson, file: string, dir: string) => PackageJson;
packageFilter?: (pkg: PackageJSON, file: string, dir: string) => PackageJSON;
/** Allows transforms a path within a package. */
pathFilter?: (pkg: PackageJson, path: string, relativePath: string) => string;
pathFilter?: (pkg: PackageJSON, path: string, relativePath: string) => string;
/** Current root directory. */
rootDir?: string;
};
Expand Down
48 changes: 35 additions & 13 deletions packages/jest-resolve/__typetests__/resolver.test.ts
Expand Up @@ -6,19 +6,41 @@
*/

import {expectAssignable, expectError, expectType} from 'tsd-lite';
import type {AsyncResolver, JestResolver, SyncResolver} from 'jest-resolve';

type PackageJson = Record<string, unknown>;
type PackageFilter = (
pkg: PackageJson,
file: string,
dir: string,
) => PackageJson;
type PathFilter = (
pkg: PackageJson,
path: string,
relativePath: string,
) => string;
import type {
AsyncResolver,
JestResolver,
PackageFilter,
PackageJSON,
PathFilter,
SyncResolver,
} from 'jest-resolve';

// PackageJSON

expectAssignable<PackageJSON>({
caption: 'test',
count: 100,
isTest: true,
location: {name: 'test', start: [1, 2], valid: false, x: 10, y: 20},
values: [0, 10, 20, {x: 1, y: 2}, true, 'test', ['a', 'b']],
});

expectError<PackageJSON>({
filter: () => {},
});

// PackageFilter

const packageFilter = (pkg: PackageJSON, file: string, dir: string) => pkg;

expectAssignable<PackageFilter>(packageFilter);

// PathFilter

const pathFilter = (pkg: PackageJSON, path: string, relativePath: string) =>
relativePath;

expectAssignable<PathFilter>(pathFilter);

// AsyncResolver

Expand Down
2 changes: 1 addition & 1 deletion packages/jest-resolve/package.json
Expand Up @@ -30,7 +30,7 @@
"devDependencies": {
"@tsd/typescript": "~4.6.2",
"@types/graceful-fs": "^4.1.3",
"@types/resolve": "^1.20.0",
"@types/resolve": "^1.20.2",
"tsd-lite": "^0.5.1"
},
"engines": {
Expand Down
39 changes: 34 additions & 5 deletions packages/jest-resolve/src/defaultResolver.ts
Expand Up @@ -13,13 +13,43 @@ import {
resolve as resolveExports,
} from 'resolve.exports';
import {
PackageJson,
findClosestPackageJson,
isDirectory,
isFile,
readPackageCached,
realpathSync,
} from './fileWalkers';
import type {PackageJSON} from './types';

/**
* Allows transforming parsed `package.json` contents.
*
* @param pkg - Parsed `package.json` contents.
* @param file - Path to `package.json` file.
* @param dir - Directory that contains the `package.json`.
*
* @returns Transformed `package.json` contents.
*/
export type PackageFilter = (
pkg: PackageJSON,
file: string,
dir: string,
) => PackageJSON;

/**
* Allows transforms a path within a package.
*
* @param pkg - Parsed `package.json` contents.
* @param path - Path being resolved.
* @param relativePath - Path relative from the `package.json` location.
*
* @returns Relative path that will be joined from the `package.json` location.
*/
export type PathFilter = (
pkg: PackageJSON,
path: string,
relativePath: string,
) => string;

type ResolverOptions = {
/** Directory to begin resolving from. */
Expand All @@ -45,9 +75,9 @@ type ResolverOptions = {
*/
paths?: Array<string>;
/** Allows transforming parsed `package.json` contents. */
packageFilter?: (pkg: PackageJson, file: string, dir: string) => PackageJson;
packageFilter?: PackageFilter;
/** Allows transforms a path within a package. */
pathFilter?: (pkg: PackageJson, path: string, relativePath: string) => string;
pathFilter?: PathFilter;
/** Current root directory. */
rootDir?: string;
};
Expand Down Expand Up @@ -79,7 +109,6 @@ const defaultResolver: SyncResolver = (path, options) => {
return pnpResolver(path, options);
}

// @ts-expect-error: TODO remove after merging https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59990
const resolveOptions: UpstreamResolveOptionsWithConditions = {
...options,
isDirectory,
Expand Down Expand Up @@ -108,7 +137,7 @@ export default defaultResolver;
* helper functions
*/

function readPackageSync(_: unknown, file: string): PackageJson {
function readPackageSync(_: unknown, file: string): PackageJSON {
return readPackageCached(file);
}

Expand Down
9 changes: 4 additions & 5 deletions packages/jest-resolve/src/fileWalkers.ts
Expand Up @@ -8,6 +8,7 @@
import {dirname, resolve} from 'path';
import * as fs from 'graceful-fs';
import {tryRealpath} from 'jest-util';
import type {PackageJSON} from './types';

export function clearFsCache(): void {
checkedPaths.clear();
Expand Down Expand Up @@ -71,17 +72,15 @@ function realpathCached(path: string): string {
return result;
}

export type PackageJson = Record<string, unknown>;

const packageContents = new Map<string, PackageJson>();
export function readPackageCached(path: string): PackageJson {
const packageContents = new Map<string, PackageJSON>();
export function readPackageCached(path: string): PackageJSON {
let result = packageContents.get(path);

if (result != null) {
return result;
}

result = JSON.parse(fs.readFileSync(path, 'utf8')) as PackageJson;
result = JSON.parse(fs.readFileSync(path, 'utf8')) as PackageJSON;

packageContents.set(path, result);

Expand Down
8 changes: 7 additions & 1 deletion packages/jest-resolve/src/index.ts
Expand Up @@ -7,12 +7,18 @@

import Resolver from './resolver';

export type {AsyncResolver, SyncResolver} from './defaultResolver';
export type {
AsyncResolver,
SyncResolver,
PackageFilter,
PathFilter,
} from './defaultResolver';
export type {
FindNodeModuleConfig,
ResolveModuleConfig,
ResolverObject as JestResolver,
} from './resolver';
export type {PackageJSON} from './types';
export * from './utils';

export default Resolver;
8 changes: 8 additions & 0 deletions packages/jest-resolve/src/types.ts
Expand Up @@ -21,3 +21,11 @@ type ModuleNameMapperConfig = {
regex: RegExp;
moduleName: string | Array<string>;
};

// https://github.com/Microsoft/TypeScript/issues/3496#issuecomment-128553540
type JSONValue = string | number | boolean | JSONObject | Array<JSONValue>;
interface JSONObject {
[key: string]: JSONValue;
}

export type PackageJSON = JSONObject;
10 changes: 5 additions & 5 deletions yarn.lock
Expand Up @@ -5373,10 +5373,10 @@ __metadata:
languageName: node
linkType: hard

"@types/resolve@npm:^1.20.0":
version: 1.20.1
resolution: "@types/resolve@npm:1.20.1"
checksum: d035d5aaadbd455027fa9457a4a263563d49647f088876aebd2b0388d4c35400b85c0382fdc2ec5253c35442abfc2d25431c989345b97fefe26a367811214343
"@types/resolve@npm:^1.20.2":
version: 1.20.2
resolution: "@types/resolve@npm:1.20.2"
checksum: 61c2cad2499ffc8eab36e3b773945d337d848d3ac6b7b0a87c805ba814bc838ef2f262fc0f109bfd8d2e0898ff8bd80ad1025f9ff64f1f71d3d4294c9f14e5f6
languageName: node
linkType: hard

Expand Down Expand Up @@ -13446,7 +13446,7 @@ __metadata:
dependencies:
"@tsd/typescript": ~4.6.2
"@types/graceful-fs": ^4.1.3
"@types/resolve": ^1.20.0
"@types/resolve": ^1.20.2
chalk: ^4.0.0
graceful-fs: ^4.2.9
jest-haste-map: ^28.0.0-alpha.11
Expand Down

0 comments on commit 3c6f14b

Please sign in to comment.