Skip to content

Commit

Permalink
feat: add unsafe option (#13)
Browse files Browse the repository at this point in the history
* feat: add `unsafe` option

* fix(types): strict `Options` interplay

* chore: add `options.unsafe` docs
  • Loading branch information
lukeed authored Oct 15, 2021
1 parent c6814c4 commit 0b69d12
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 4 deletions.
6 changes: 5 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
export interface Options {
export type Options = {
browser?: boolean;
conditions?: string[];
require?: boolean;
unsafe?: false;
} | {
conditions?: string[];
unsafe?: true;
}

export function resolve<T=any>(pkg: T, entry: string, options?: Options): string | void;
Expand Down
36 changes: 36 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,42 @@ resolve(contents, '.', {
}); //=> "./index.worker.js"
```

#### options.unsafe
Type: `boolean` <br>
Default: `false`

> **Important:** You probably do not want this option! <br>It will break out of Node's default resolution conditions.
When enabled, this option will ignore **all other options** except [`options.conditions`](#optionsconditions). This is because, when enabled, `options.unsafe` **does not** assume or provide any default conditions except the `"default"` condition.

```js
resolve(contents);
//=> Conditions: ["default", "import", "node"]

resolve(contents, { unsafe: true });
//=> Conditions: ["default"]

resolve(contents, { unsafe: true, require: true, browser: true });
//=> Conditions: ["default"]
```

In other words, this means that trying to use `options.require` or `options.browser` alongside `options.unsafe` will have no effect. In order to enable these conditions, you must provide them manually into the `options.conditions` list:

```js
resolve(contents, {
unsafe: true,
conditions: ["require"]
});
//=> Conditions: ["default", "require"]

resolve(contents, {
unsafe: true,
conditions: ["browser", "require", "custom123"]
});
//=> Conditions: ["default", "browser", "require", "custom123"]
```


### legacy(pkg, options?)
Returns: `string` or `undefined`

Expand Down
7 changes: 4 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ function toName(name, entry) {
* @param {boolean} [options.browser]
* @param {boolean} [options.require]
* @param {string[]} [options.conditions]
* @param {boolean} [options.unsafe]
*/
export function resolve(pkg, entry='.', options={}) {
let { name, exports } = pkg;

if (exports) {
let { browser, require, conditions=[] } = options;
let { browser, require, unsafe, conditions=[] } = options;

let target = toName(name, entry);
if (target[0] !== '.') target = './' + target;
Expand All @@ -68,8 +69,8 @@ export function resolve(pkg, entry='.', options={}) {
}

let allows = new Set(['default', ...conditions]);
allows.add(require ? 'require' : 'import');
allows.add(browser ? 'browser' : 'node');
unsafe || allows.add(require ? 'require' : 'import');
unsafe || allows.add(browser ? 'browser' : 'node');

let key, tmp, isSingle=false;

Expand Down
99 changes: 99 additions & 0 deletions test/resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -610,3 +610,102 @@ conditions('should throw an error if no known conditions', ctx => {
});

conditions.run();

// ---

const unsafe = suite('options.unsafe', {
"exports": {
".": {
"production": "$prod",
"development": "$dev",
"default": "$default",
},
"./spec/type": {
"import": "$import",
"require": "$require",
"default": "$default"
},
"./spec/env": {
"worker": {
"default": "$worker"
},
"browser": "$browser",
"node": "$node",
"default": "$default"
}
}
});

unsafe('should ignore unknown conditions by default', pkg => {
pass(pkg, '$default', '.', {
unsafe: true,
});
});

unsafe('should ignore "import" and "require" conditions by default', pkg => {
pass(pkg, '$default', './spec/type', {
unsafe: true,
});

pass(pkg, '$default', './spec/type', {
unsafe: true,
require: true,
});
});

unsafe('should ignore "node" and "browser" conditions by default', pkg => {
pass(pkg, '$default', './spec/type', {
unsafe: true,
});

pass(pkg, '$default', './spec/type', {
unsafe: true,
browser: true,
});
});

unsafe('should respect/accept any custom condition(s) when specified', pkg => {
// root, dev only
pass(pkg, '$dev', '.', {
unsafe: true,
conditions: ['development']
});

// root, defined order
pass(pkg, '$prod', '.', {
unsafe: true,
conditions: ['development', 'production']
});

// import vs require, defined order
pass(pkg, '$require', './spec/type', {
unsafe: true,
conditions: ['require']
});

// import vs require, defined order
pass(pkg, '$import', './spec/type', {
unsafe: true,
conditions: ['import', 'require']
});

// import vs require, defined order
pass(pkg, '$node', './spec/env', {
unsafe: true,
conditions: ['node']
});

// import vs require, defined order
pass(pkg, '$browser', './spec/env', {
unsafe: true,
conditions: ['browser', 'node']
});

// import vs require, defined order
pass(pkg, '$worker', './spec/env', {
unsafe: true,
conditions: ['browser', 'node', 'worker']
});
});

unsafe.run();

0 comments on commit 0b69d12

Please sign in to comment.