Skip to content

Commit 820f4d9

Browse files
frederikprijckjonkoopsewanharris
committed
Avoid using default exports (#175)
Co-authored-by: Jon Koops <jonkoops@gmail.com> Co-authored-by: Ewan Harris <ewan.harris@okta.com>
1 parent 946918d commit 820f4d9

9 files changed

+59
-55
lines changed

README.md

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ Run `npm install jwt-decode` or `yarn add jwt-decode` to install the library.
2424
### Usage
2525

2626
```js
27-
import jwt_decode from "jwt-decode";
27+
import { jwtDecode } from "jwt-decode";
2828

29-
var token = "eyJ0eXAiO.../// jwt token";
30-
var decoded = jwt_decode(token);
29+
const token = "eyJ0eXAiO.../// jwt token";
30+
const decoded = jwtDecode(token);
3131

3232
console.log(decoded);
3333

@@ -40,7 +40,7 @@ console.log(decoded);
4040
*/
4141

4242
// decode header by passing in options (useful for when you need `kid` to verify a JWT):
43-
var decodedHeader = jwt_decode(token, { header: true });
43+
const decodedHeader = jwtDecode(token, { header: true });
4444
console.log(decodedHeader);
4545

4646
/* prints:
@@ -69,35 +69,50 @@ Not adhering to the format will result in a `InvalidTokenError` with one of the
6969
- `Invalid token specified: invalid base64 for part #` => the part could not be base64 decoded (the message should contain the error the base64 decoder gave)
7070
- `Invalid token specified: invalid json for part #` => the part was correctly base64 decoded, however, the decoded value was not valid JSON (the message should contain the error the JSON parser gave)
7171

72-
#### Use with typescript
72+
#### Use with TypeScript
7373

74-
The return type of the `jwt_decode` function is determined by the `header` property of the object passed as the second argument. If omitted (or set to false), it'll use `JwtPayload`, when true it will use `JwtHeader`.
75-
If needed, you can specify what the expected return type should be by passing a type argument to the `jwt_decode` function.
74+
The return type of the `jwtDecode` function is determined by the `header` property of the object passed as the second argument. If omitted (or set to false), it'll use `JwtPayload`, when true it will use `JwtHeader`.
75+
If needed, you can specify what the expected return type should be by passing a type argument to the `jwtDecode` function.
7676

7777
You can extend both `JwtHeader` and `JwtPayload` to include non-standard claims or properties.
7878

7979
```typescript
80-
import jwtDecode from "jwt-decode";
80+
import { jwtDecode } from "jwt-decode";
8181

82-
const token: string = "eyJhsw5c";
82+
const token = "eyJhsw5c";
8383
const decoded = jwtDecode<JwtPayload>(token); // Returns with the JwtPayload type
8484
```
8585

8686
#### Use as a CommonJS package
8787

8888
```javascript
89-
const jwt_decode = require('jwt-decode');
89+
const { jwtDecode } = require('jwt-decode');
9090
...
9191
```
9292

9393
#### Include with a script tag
9494

95-
Copy the file `jwt-decode.js` from the `build/` folder to your project somewhere, then include it like so:
95+
Copy the file `jwt-decode.js` from the root of the `build/` folder to your project somewhere, then include it like so:
9696

9797
```html
9898
<script src="jwt-decode.js"></script>
9999
```
100100

101+
Once this script has loaded, the `jwt_decode` function will be exposed as a global:
102+
103+
```javascript
104+
const token = "eyJhsw5c";
105+
const decoded = jwt_decode(token);
106+
```
107+
108+
Alternatively, if you are using the [Asynchronous Module Definition (AMD) API](https://github.com/amdjs/amdjs-api/blob/master/AMD.md), you can load the same function as follows:
109+
110+
```javascript
111+
define(["jwt_decode"], (jwtDecode) => {
112+
const token = "eyJhsw5c";
113+
const decoded = jwtDecode(token);
114+
});
115+
```
101116

102117
## Feedback
103118

lib/base64_url_decode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function b64DecodeUnicode(str: string) {
1010
);
1111
}
1212

13-
export default function(str: string) {
13+
export function base64UrlDecode(str: string) {
1414
let output = str.replace(/-/g, "+").replace(/_/g, "/");
1515
switch (output.length % 4) {
1616
case 0:

lib/index.cjs.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

lib/index.standalone.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

lib/index.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import base64_url_decode from "./base64_url_decode";
1+
import { base64UrlDecode } from "./base64_url_decode";
22

33
export interface JwtDecodeOptions {
44
header?: boolean;
@@ -28,12 +28,12 @@ export class InvalidTokenError extends Error {
2828

2929
InvalidTokenError.prototype.name = "InvalidTokenError";
3030

31-
function jwtDecode<T = JwtHeader>(
31+
export function jwtDecode<T = JwtHeader>(
3232
token: string,
3333
options: JwtDecodeOptions & { header: true }
3434
): T;
35-
function jwtDecode<T = JwtPayload>(token: string, options?: JwtDecodeOptions): T;
36-
function jwtDecode(token: string, options?: JwtDecodeOptions) {
35+
export function jwtDecode<T = JwtPayload>(token: string, options?: JwtDecodeOptions): T;
36+
export function jwtDecode(token: string, options?: JwtDecodeOptions) {
3737
if (typeof token !== "string") {
3838
throw new InvalidTokenError("Invalid token specified: must be a string");
3939
}
@@ -50,7 +50,7 @@ function jwtDecode(token: string, options?: JwtDecodeOptions) {
5050

5151
let decoded: string;
5252
try {
53-
decoded = base64_url_decode(part);
53+
decoded = base64UrlDecode(part);
5454
} catch (e: any) {
5555
throw new InvalidTokenError(
5656
"Invalid token specified: invalid base64 for part #" +
@@ -74,4 +74,3 @@ function jwtDecode(token: string, options?: JwtDecodeOptions) {
7474
}
7575
}
7676

77-
export default jwtDecode;

lib/index.umd.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { jwtDecode as default } from './index';

rollup.config.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { defineConfig } from "rollup";
44
import livereload from "rollup-plugin-livereload";
55
import serve from "rollup-plugin-serve";
66

7-
const EXPORT_NAME = "jwt-decode";
87
const isProduction = process.env.NODE_ENV === "production";
98
const tsPlugin = typescript({
109
rootDir: "lib",
@@ -16,8 +15,10 @@ const plugins = [
1615
isProduction && terser(),
1716
];
1817

18+
const input = "lib/index.ts";
19+
1920
export default defineConfig([{
20-
input: "lib/index.standalone.ts",
21+
input: "lib/index.umd.ts",
2122
output: {
2223
name: "jwt_decode",
2324
file: "build/jwt-decode.js",
@@ -29,24 +30,21 @@ export default defineConfig([{
2930
]
3031
},
3132
{
32-
input: "lib/index.cjs.ts",
33-
output: [{
34-
name: EXPORT_NAME,
33+
input,
34+
output: {
3535
file: "build/cjs/jwt-decode.js",
3636
format: "cjs",
37-
exports: "auto",
3837
sourcemap: true,
39-
}, ],
38+
},
4039
plugins,
4140
},
4241
{
43-
input: "lib/index.ts",
44-
output: [{
45-
name: EXPORT_NAME,
42+
input,
43+
output: {
4644
file: "build/esm/jwt-decode.js",
4745
format: "esm",
4846
sourcemap: true,
49-
}, ],
47+
},
5048
plugins: [!isProduction &&
5149
serve({
5250
contentBase: ["build", "static"],

static/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ <h2>decoded:</h2>
1313
<pre><code class="js-error3"></code></pre>
1414

1515
<script type="module">
16-
import jwtDecode from "/jwt-decode.esm.js";
16+
import { jwtDecode } from "/esm/jwt-decode.js";
1717
var token =
1818
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIiLCJleHAiOjEzOTMyODY4OTMsImlhdCI6MTM5MzI2ODg5M30.4-iaDojEVl0pJQMjrbM1EzUIfAZgsbK_kgnVyVxFSVo";
1919
var decoded = jwtDecode(token);

test/tests.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,69 @@
1-
import jwt_decode, { InvalidTokenError, JwtPayload } from "./../lib/index";
1+
import { jwtDecode, InvalidTokenError, JwtPayload } from "./../lib/index";
22
import { describe, expect, it } from "@jest/globals";
33

44
var token =
55
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIiLCJleHAiOjEzOTMyODY4OTMsImlhdCI6MTM5MzI2ODg5M30.4-iaDojEVl0pJQMjrbM1EzUIfAZgsbK_kgnVyVxFSVo";
66

77
describe("jwt-decode", function () {
88
it("should return default and custom claims", function () {
9-
var decoded = jwt_decode<JwtPayload & { foo: string }>(token);
9+
var decoded = jwtDecode<JwtPayload & { foo: string }>(token);
1010
expect(decoded.exp).toEqual(1393286893);
1111
expect(decoded.iat).toEqual(1393268893);
1212
expect(decoded.foo).toEqual("bar");
1313
});
1414

1515
it("should return header information", function () {
16-
var decoded = jwt_decode(token, { header: true });
16+
var decoded = jwtDecode(token, { header: true });
1717
expect(decoded.typ).toEqual("JWT");
1818
expect(decoded.alg).toEqual("HS256");
1919
});
2020

2121
it("should work with utf8 tokens", function () {
2222
var utf8_token =
2323
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiSm9zw6kiLCJpYXQiOjE0MjU2NDQ5NjZ9.1CfFtdGUPs6q8kT3OGQSVlhEMdbuX0HfNSqum0023a0";
24-
var decoded = jwt_decode<JwtPayload & { name: string }>(utf8_token);
24+
var decoded = jwtDecode<JwtPayload & { name: string }>(utf8_token);
2525
expect(decoded.name).toEqual("José");
2626
});
2727

2828
it("should work with binary tokens", function () {
2929
var binary_token =
3030
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiSm9z6SIsImlhdCI6MTQyNTY0NDk2Nn0.cpnplCBxiw7Xqz5thkqs4Mo_dymvztnI0CI4BN0d1t8";
31-
var decoded = jwt_decode<JwtPayload & { name: string }>(binary_token);
31+
var decoded = jwtDecode<JwtPayload & { name: string }>(binary_token);
3232
expect(decoded.name).toEqual("José");
3333
});
3434

3535
it("should work with double padding", function () {
3636
var utf8_token =
3737
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpvc8OpIiwiaWF0IjoxNTE2MjM5MDIyfQ.7A3F5SUH2gbBSYVon5mas_Y-KCrWojorKQg7UKGVEIA";
38-
var decoded = jwt_decode<JwtPayload & { name: string }>(utf8_token);
38+
var decoded = jwtDecode<JwtPayload & { name: string }>(utf8_token);
3939
expect(decoded.name).toEqual("José");
4040
});
4141

4242
it("should work with single padding", function () {
4343
var utf8_token =
4444
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpvc8OpZSIsImlhdCI6MTUxNjIzOTAyMn0.tbjJzDAylkKSV0_YGR5xBJBlFK01C82nZPLIcA3JX1g";
45-
var decoded = jwt_decode<JwtPayload & { name: string }>(utf8_token);
45+
var decoded = jwtDecode<JwtPayload & { name: string }>(utf8_token);
4646
expect(decoded.name).toEqual("Josée");
4747
});
4848

4949
it("should throw InvalidTokenError on nonstring", function () {
5050
var bad_token = null;
5151
expect(function () {
52-
jwt_decode(bad_token as any);
52+
jwtDecode(bad_token as any);
5353
}).toThrow(InvalidTokenError);
5454
});
5555

5656
it("should throw InvalidTokenError on string that is not a token", function () {
5757
var bad_token = "fubar";
5858
expect(function () {
59-
jwt_decode(bad_token);
59+
jwtDecode(bad_token);
6060
}).toThrow(InvalidTokenError);
6161
});
6262

6363
it("should throw InvalidTokenErrors when token is null", function () {
6464
var bad_token = null;
6565
expect(function () {
66-
jwt_decode(bad_token as any, { header: true });
66+
jwtDecode(bad_token as any, { header: true });
6767
}).toThrow(
6868
new InvalidTokenError("Invalid token specified: must be a string")
6969
);
@@ -72,28 +72,28 @@ describe("jwt-decode", function () {
7272
it("should throw InvalidTokenErrors when missing part #1", function () {
7373
var bad_token = ".FAKE_TOKEN";
7474
expect(function () {
75-
jwt_decode(bad_token, { header: true });
75+
jwtDecode(bad_token, { header: true });
7676
}).toThrow(/Invalid token specified: invalid json for part #1/);
7777
});
7878

7979
it("should throw InvalidTokenErrors when part #1 is not valid base64", function () {
8080
var bad_token = "TOKEN";
8181
expect(function () {
82-
jwt_decode(bad_token, { header: true });
82+
jwtDecode(bad_token, { header: true });
8383
}).toThrow(/Invalid token specified: invalid base64 for part #1/);
8484
});
8585

8686
it("should throw InvalidTokenErrors when part #1 is not valid JSON", function () {
8787
var bad_token = "FAKE.TOKEN";
8888
expect(function () {
89-
jwt_decode(bad_token, { header: true });
89+
jwtDecode(bad_token, { header: true });
9090
}).toThrow(/Invalid token specified: invalid json for part #1/);
9191
});
9292

9393
it("should throw InvalidTokenErrors when missing part #2", function () {
9494
var bad_token = "FAKE_TOKEN";
9595
expect(function () {
96-
jwt_decode(bad_token);
96+
jwtDecode(bad_token);
9797
}).toThrow(
9898
new InvalidTokenError("Invalid token specified: missing part #2")
9999
);
@@ -102,14 +102,14 @@ describe("jwt-decode", function () {
102102
it("should throw InvalidTokenErrors when part #2 is not valid base64", function () {
103103
var bad_token = "FAKE.TOKEN";
104104
expect(function () {
105-
jwt_decode(bad_token);
105+
jwtDecode(bad_token);
106106
}).toThrow(/Invalid token specified: invalid base64 for part #2/);
107107
});
108108

109109
it("should throw InvalidTokenErrors when part #2 is not valid JSON", function () {
110110
var bad_token = "FAKE.TOKEN2";
111111
expect(function () {
112-
jwt_decode(bad_token);
112+
jwtDecode(bad_token);
113113
}).toThrow(/Invalid token specified: invalid json for part #2/);
114114
});
115115
});

0 commit comments

Comments
 (0)