@edirect/oidc-client 11.0.62 → 11.0.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/README.md +136 -0
- package/dist/package.json +23 -0
- package/dist/src/connect.d.ts +11 -0
- package/dist/src/connect.d.ts.map +1 -0
- package/dist/src/connect.js +33 -0
- package/dist/src/grant-type/client_credentials.d.ts +16 -0
- package/dist/src/grant-type/client_credentials.d.ts.map +1 -0
- package/dist/src/grant-type/client_credentials.js +55 -0
- package/dist/src/grant-type/password.d.ts +16 -0
- package/dist/src/grant-type/password.d.ts.map +1 -0
- package/dist/src/grant-type/password.js +92 -0
- package/dist/src/grant-type/sso.d.ts +16 -0
- package/dist/src/grant-type/sso.d.ts.map +1 -0
- package/dist/src/grant-type/sso.js +92 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +20 -0
- package/dist/src/token.d.ts +7 -0
- package/dist/src/token.d.ts.map +1 -0
- package/dist/src/token.js +22 -0
- package/dist/src/types/connect.type.d.ts +12 -0
- package/dist/src/types/connect.type.d.ts.map +1 -0
- package/dist/src/types/connect.type.js +2 -0
- package/dist/src/types/error-handler.type.d.ts +6 -0
- package/dist/src/types/error-handler.type.d.ts.map +1 -0
- package/dist/src/types/error-handler.type.js +2 -0
- package/dist/src/types/token-set.type.d.ts +22 -0
- package/dist/src/types/token-set.type.d.ts.map +1 -0
- package/dist/src/types/token-set.type.js +2 -0
- package/dist/src/utils/error-handler.d.ts +6 -0
- package/dist/src/utils/error-handler.d.ts.map +1 -0
- package/dist/src/utils/error-handler.js +12 -0
- package/dist/src/utils/parse-token.d.ts +4 -0
- package/dist/src/utils/parse-token.d.ts.map +1 -0
- package/dist/src/utils/parse-token.js +25 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/package.json +25 -3
package/dist/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# @edirect/oidc-client
|
|
2
|
+
|
|
3
|
+
OpenID Connect client for eDirect applications. Supports three OAuth2 grant types — `password`, `client_credentials`, and `sso` — with a uniform API for acquiring and refreshing tokens.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Three grant types: `password`, `client_credentials`, `sso`
|
|
8
|
+
- Uniform `getAccessToken()` and `getRefreshToken()` API across all grant types
|
|
9
|
+
- OIDC provider discovery via configurable `baseUrl` and `oidcPath`
|
|
10
|
+
- Token set parsing utilities
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
pnpm add @edirect/oidc-client
|
|
16
|
+
# or
|
|
17
|
+
npm install @edirect/oidc-client
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Password Grant (username + password)
|
|
23
|
+
|
|
24
|
+
Used when the application authenticates on behalf of a user:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import OidcClient from '@edirect/oidc-client';
|
|
28
|
+
|
|
29
|
+
const client = await OidcClient({
|
|
30
|
+
grantType: 'password',
|
|
31
|
+
baseUrl: process.env.OIDC_PROVIDER_URL, // e.g., 'https://keycloak.example.com'
|
|
32
|
+
oidcPath: process.env.OIDC_PROVIDER_PATH, // e.g., '/realms/my-realm'
|
|
33
|
+
clientId: process.env.OIDC_CLIENT_ID,
|
|
34
|
+
clientSecret: process.env.OIDC_CLIENT_SECRET,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Acquire access token
|
|
38
|
+
const tokenSet = await client.getAccessToken({
|
|
39
|
+
username: process.env.OIDC_USERNAME,
|
|
40
|
+
password: process.env.OIDC_PASSWORD,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
console.log(tokenSet.access_token);
|
|
44
|
+
console.log(tokenSet.expires_in);
|
|
45
|
+
|
|
46
|
+
// Refresh token (not available for client_credentials)
|
|
47
|
+
const refreshed = await client.getRefreshToken(tokenSet);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Client Credentials Grant (service-to-service)
|
|
51
|
+
|
|
52
|
+
Used for machine-to-machine authentication:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import OidcClient from '@edirect/oidc-client';
|
|
56
|
+
|
|
57
|
+
const client = await OidcClient({
|
|
58
|
+
grantType: 'client_credentials',
|
|
59
|
+
baseUrl: process.env.OIDC_PROVIDER_URL,
|
|
60
|
+
oidcPath: process.env.OIDC_PROVIDER_PATH,
|
|
61
|
+
clientId: process.env.OIDC_CLIENT_ID,
|
|
62
|
+
clientSecret: process.env.OIDC_CLIENT_SECRET,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// No login data required for client_credentials
|
|
66
|
+
const tokenSet = await client.getAccessToken();
|
|
67
|
+
console.log(tokenSet.access_token);
|
|
68
|
+
|
|
69
|
+
// Note: getRefreshToken is not applicable to client_credentials
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### SSO Grant
|
|
73
|
+
|
|
74
|
+
Used for SSO-based authentication flows:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const client = await OidcClient({
|
|
78
|
+
grantType: 'sso',
|
|
79
|
+
baseUrl: process.env.OIDC_PROVIDER_URL,
|
|
80
|
+
oidcPath: process.env.OIDC_PROVIDER_PATH,
|
|
81
|
+
clientId: process.env.OIDC_CLIENT_ID,
|
|
82
|
+
clientSecret: process.env.OIDC_CLIENT_SECRET,
|
|
83
|
+
redirectUri: process.env.OIDC_CALLBACK_URL,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const tokenSet = await client.getAccessToken({ code: authorizationCode });
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## API
|
|
90
|
+
|
|
91
|
+
### `OidcClient(params: Connect): Promise<OidcConnect>`
|
|
92
|
+
|
|
93
|
+
Factory function that initializes the OIDC client for the specified grant type.
|
|
94
|
+
|
|
95
|
+
| Parameter | Type | Description |
|
|
96
|
+
| -------------- | --------------------------------------------- | ------------------------------------------ |
|
|
97
|
+
| `grantType` | `'password' \| 'client_credentials' \| 'sso'` | OAuth2 grant type |
|
|
98
|
+
| `baseUrl` | `string` | OIDC provider base URL |
|
|
99
|
+
| `oidcPath` | `string` | OIDC realm path (e.g., `/realms/my-realm`) |
|
|
100
|
+
| `clientId` | `string` | Client ID registered in the OIDC provider |
|
|
101
|
+
| `clientSecret` | `string` | Client secret |
|
|
102
|
+
| `redirectUri` | `string` | Callback URL (for `sso` grant) |
|
|
103
|
+
|
|
104
|
+
### Client Methods
|
|
105
|
+
|
|
106
|
+
| Method | Signature | Description |
|
|
107
|
+
| ----------------- | ----------------------------------- | ------------------------------------------------------------ |
|
|
108
|
+
| `getAccessToken` | `(loginData?) => Promise<TokenSet>` | Acquire an access token |
|
|
109
|
+
| `getRefreshToken` | `(tokenSet) => Promise<TokenSet>` | Refresh an existing token set (not for `client_credentials`) |
|
|
110
|
+
|
|
111
|
+
### `TokenSet`
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
interface TokenSet {
|
|
115
|
+
access_token: string;
|
|
116
|
+
token_type: string;
|
|
117
|
+
expires_in: number;
|
|
118
|
+
refresh_token?: string; // not present for client_credentials
|
|
119
|
+
refresh_expires_in?: number;
|
|
120
|
+
id_token?: string;
|
|
121
|
+
session_state?: string;
|
|
122
|
+
scope?: string;
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Environment Variables
|
|
127
|
+
|
|
128
|
+
| Variable | Description |
|
|
129
|
+
| -------------------- | ------------------------------------------------------------- |
|
|
130
|
+
| `OIDC_PROVIDER_URL` | OIDC provider base URL (e.g., `https://keycloak.example.com`) |
|
|
131
|
+
| `OIDC_PROVIDER_PATH` | OIDC realm path (e.g., `/realms/my-realm`) |
|
|
132
|
+
| `OIDC_CLIENT_ID` | Client ID |
|
|
133
|
+
| `OIDC_CLIENT_SECRET` | Client secret |
|
|
134
|
+
| `OIDC_USERNAME` | Username (for `password` grant) |
|
|
135
|
+
| `OIDC_PASSWORD` | Password (for `password` grant) |
|
|
136
|
+
| `OIDC_CALLBACK_URL` | Redirect URI (for `sso` grant) |
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@edirect/oidc-client",
|
|
3
|
+
"version": "11.0.64",
|
|
4
|
+
"main": "./dist/cjs/index.js",
|
|
5
|
+
"module": "./dist/esm/index.js",
|
|
6
|
+
"types": "./dist/types/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"require": "./dist/cjs/index.js",
|
|
10
|
+
"import": "./dist/esm/index.js",
|
|
11
|
+
"types": "./dist/types/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"openid-client": "^6.8.6",
|
|
20
|
+
"tslib": "^2.8.1"
|
|
21
|
+
},
|
|
22
|
+
"type": "commonjs"
|
|
23
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Connect } from './types/connect.type';
|
|
2
|
+
import { ErrorHandlerType } from './types/error-handler.type';
|
|
3
|
+
export declare class OidcConnect {
|
|
4
|
+
configuration: any;
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
redirectUri?: string;
|
|
7
|
+
ErrorHandler: ErrorHandlerType;
|
|
8
|
+
constructor();
|
|
9
|
+
connect(params: Connect): Promise<any>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=connect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG9D,qBAAa,WAAW;IACtB,aAAa,EAAE,GAAG,CAAC;IACnB,OAAO,EAAG,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,gBAAgB,CAAC;;IAMzB,OAAO,CAAC,MAAM,EAAE,OAAO;CAsB9B"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OidcConnect = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const error_handler_1 = tslib_1.__importDefault(require("./utils/error-handler"));
|
|
6
|
+
class OidcConnect {
|
|
7
|
+
configuration;
|
|
8
|
+
baseUrl;
|
|
9
|
+
redirectUri;
|
|
10
|
+
ErrorHandler;
|
|
11
|
+
constructor() {
|
|
12
|
+
this.ErrorHandler = error_handler_1.default;
|
|
13
|
+
}
|
|
14
|
+
async connect(params) {
|
|
15
|
+
this.baseUrl = params.baseUrl;
|
|
16
|
+
this.redirectUri = params.redirectUri;
|
|
17
|
+
const issuer = new URL(`${params.baseUrl}/${params.oidcPath}`);
|
|
18
|
+
const client = await import('openid-client');
|
|
19
|
+
this.configuration = await client.discovery(issuer, params.clientId, params.clientSecret);
|
|
20
|
+
// Set additional metadata if needed
|
|
21
|
+
if (this.configuration) {
|
|
22
|
+
this.configuration.token_endpoint_auth_method = 'client_secret_post';
|
|
23
|
+
if (params.responseTypes)
|
|
24
|
+
this.configuration.response_types = params.responseTypes;
|
|
25
|
+
if (params.grantTypes)
|
|
26
|
+
this.configuration.grant_types = params.grantTypes;
|
|
27
|
+
if (params.redirectUri)
|
|
28
|
+
this.configuration.redirect_uris = [params.redirectUri];
|
|
29
|
+
}
|
|
30
|
+
return this.configuration;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.OidcConnect = OidcConnect;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { OidcConnect } from '../connect';
|
|
2
|
+
import { Connect } from '../types/connect.type';
|
|
3
|
+
import { GrantTypeErrorHandlerType } from '../types/error-handler.type';
|
|
4
|
+
import { TokenSet } from '../types/token-set.type';
|
|
5
|
+
export declare class OidcClient extends OidcConnect {
|
|
6
|
+
errorHandler: GrantTypeErrorHandlerType;
|
|
7
|
+
token: TokenSet | null;
|
|
8
|
+
getToken: (revert?: boolean) => TokenSet | null;
|
|
9
|
+
setToken: (token: TokenSet, revert?: boolean) => TokenSet;
|
|
10
|
+
constructor();
|
|
11
|
+
connect(params: Connect): Promise<void>;
|
|
12
|
+
getAccessToken(data: Record<string, unknown>): Promise<TokenSet | null>;
|
|
13
|
+
getRefreshToken(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export declare const oidc: OidcClient;
|
|
16
|
+
//# sourceMappingURL=client_credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client_credentials.d.ts","sourceRoot":"","sources":["../../../src/grant-type/client_credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAKnD,qBAAa,UAAW,SAAQ,WAAW;IACzC,YAAY,EAAE,yBAAyB,CAAC;IACxC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,QAAQ,GAAG,IAAI,CAAC;IAChD,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,QAAQ,CAAC;;IAW3C,OAAO,CAAC,MAAM,EAAE,OAAO;IAQhC,cAAc,CAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAwBrB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;CAKvC;AAED,eAAO,MAAM,IAAI,YAAmB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.oidc = exports.OidcClient = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const connect_1 = require("../connect");
|
|
6
|
+
const token_1 = require("../token");
|
|
7
|
+
const parse_token_1 = tslib_1.__importDefault(require("../utils/parse-token"));
|
|
8
|
+
const grantType = 'client_credentials';
|
|
9
|
+
class OidcClient extends connect_1.OidcConnect {
|
|
10
|
+
errorHandler;
|
|
11
|
+
token;
|
|
12
|
+
getToken;
|
|
13
|
+
setToken;
|
|
14
|
+
constructor() {
|
|
15
|
+
super();
|
|
16
|
+
this.errorHandler = this.ErrorHandler(grantType);
|
|
17
|
+
this.token = null;
|
|
18
|
+
const tokenHelper = new token_1.Token();
|
|
19
|
+
this.getToken = tokenHelper.getToken.bind(tokenHelper);
|
|
20
|
+
this.setToken = tokenHelper.setToken.bind(tokenHelper);
|
|
21
|
+
}
|
|
22
|
+
async connect(params) {
|
|
23
|
+
await super.connect({
|
|
24
|
+
...params,
|
|
25
|
+
responseTypes: ['none'],
|
|
26
|
+
grantTypes: [grantType],
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async getAccessToken(data) {
|
|
30
|
+
if (!this.configuration)
|
|
31
|
+
throw new Error(`[${grantType}] Not initialized.`);
|
|
32
|
+
if (this.token)
|
|
33
|
+
return this.token;
|
|
34
|
+
const params = {
|
|
35
|
+
grant_type: grantType,
|
|
36
|
+
...data,
|
|
37
|
+
};
|
|
38
|
+
try {
|
|
39
|
+
const { clientCredentialsGrant } = await import('openid-client');
|
|
40
|
+
const tokenSetRaw = await clientCredentialsGrant(this.configuration, params);
|
|
41
|
+
const tokenSet = (0, parse_token_1.default)(tokenSetRaw);
|
|
42
|
+
this.token = this.setToken(tokenSet);
|
|
43
|
+
return this.token;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
this.errorHandler(error);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async getRefreshToken() {
|
|
51
|
+
throw new Error(`[${grantType}] This method is not allowed to this grant type.`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.OidcClient = OidcClient;
|
|
55
|
+
exports.oidc = new OidcClient();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { OidcConnect } from '../connect';
|
|
2
|
+
import { Connect } from '../types/connect.type';
|
|
3
|
+
import { GrantTypeErrorHandlerType } from '../types/error-handler.type';
|
|
4
|
+
import { TokenSet } from '../types/token-set.type';
|
|
5
|
+
export declare class OidcClient extends OidcConnect {
|
|
6
|
+
errorHandler: GrantTypeErrorHandlerType;
|
|
7
|
+
token: TokenSet | null;
|
|
8
|
+
getToken: (revert?: boolean) => TokenSet | null;
|
|
9
|
+
setToken: (token: TokenSet, revert?: boolean) => TokenSet;
|
|
10
|
+
constructor();
|
|
11
|
+
connect(params: Connect): Promise<void>;
|
|
12
|
+
getAccessToken(data: Record<string, unknown>): Promise<TokenSet | null>;
|
|
13
|
+
getRefreshToken(tokenSet: TokenSet): Promise<TokenSet | null>;
|
|
14
|
+
}
|
|
15
|
+
export declare const oidc: OidcClient;
|
|
16
|
+
//# sourceMappingURL=password.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../../src/grant-type/password.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAKnD,qBAAa,UAAW,SAAQ,WAAW;IACzC,YAAY,EAAE,yBAAyB,CAAC;IACxC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,QAAQ,GAAG,IAAI,CAAC;IAChD,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,QAAQ,CAAC;;IAW3C,OAAO,CAAC,MAAM,EAAE,OAAO;IAQhC,cAAc,CAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAkCrB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;CA2BpE;AAED,eAAO,MAAM,IAAI,YAAmB,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.oidc = exports.OidcClient = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const connect_1 = require("../connect");
|
|
6
|
+
const token_1 = require("../token");
|
|
7
|
+
const parse_token_1 = tslib_1.__importDefault(require("../utils/parse-token"));
|
|
8
|
+
const grantType = 'password';
|
|
9
|
+
class OidcClient extends connect_1.OidcConnect {
|
|
10
|
+
errorHandler;
|
|
11
|
+
token;
|
|
12
|
+
getToken;
|
|
13
|
+
setToken;
|
|
14
|
+
constructor() {
|
|
15
|
+
super();
|
|
16
|
+
this.errorHandler = this.ErrorHandler(grantType);
|
|
17
|
+
this.token = null;
|
|
18
|
+
const tokenHelper = new token_1.Token();
|
|
19
|
+
this.getToken = tokenHelper.getToken.bind(tokenHelper);
|
|
20
|
+
this.setToken = tokenHelper.setToken.bind(tokenHelper);
|
|
21
|
+
}
|
|
22
|
+
async connect(params) {
|
|
23
|
+
await super.connect({
|
|
24
|
+
...params,
|
|
25
|
+
responseTypes: ['none'],
|
|
26
|
+
grantTypes: [grantType, 'refresh_token'],
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async getAccessToken(data) {
|
|
30
|
+
if (!this.configuration)
|
|
31
|
+
throw new Error(`[${grantType}] Not initialized.`);
|
|
32
|
+
if (this.token)
|
|
33
|
+
return this.token;
|
|
34
|
+
const tokenEndpoint = this.configuration.server.token_endpoint;
|
|
35
|
+
const params = new URLSearchParams({
|
|
36
|
+
grant_type: grantType,
|
|
37
|
+
client_id: this.configuration.client_id,
|
|
38
|
+
client_secret: this.configuration.client_secret,
|
|
39
|
+
...Object.fromEntries(Object.entries(data).map(([k, v]) => [k, String(v)])),
|
|
40
|
+
});
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(tokenEndpoint, {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
headers: {
|
|
45
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
46
|
+
},
|
|
47
|
+
body: params.toString(),
|
|
48
|
+
});
|
|
49
|
+
if (!response.ok)
|
|
50
|
+
throw new Error(`Token endpoint error: ${response.status}`);
|
|
51
|
+
const tokenSetRaw = (await response.json());
|
|
52
|
+
const tokenSet = (0, parse_token_1.default)(tokenSetRaw);
|
|
53
|
+
this.token = this.setToken(tokenSet);
|
|
54
|
+
return this.token;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
this.errorHandler(error);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async getRefreshToken(tokenSet) {
|
|
62
|
+
if (!this.configuration)
|
|
63
|
+
throw new Error(`[${grantType}] Not initialized.`);
|
|
64
|
+
const tokenEndpoint = this.configuration.server.token_endpoint;
|
|
65
|
+
const params = new URLSearchParams({
|
|
66
|
+
grant_type: 'refresh_token',
|
|
67
|
+
client_id: this.configuration.client_id,
|
|
68
|
+
client_secret: this.configuration.client_secret,
|
|
69
|
+
refresh_token: tokenSet.refreshToken,
|
|
70
|
+
});
|
|
71
|
+
try {
|
|
72
|
+
const response = await fetch(tokenEndpoint, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: {
|
|
75
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
76
|
+
},
|
|
77
|
+
body: params.toString(),
|
|
78
|
+
});
|
|
79
|
+
if (!response.ok)
|
|
80
|
+
throw new Error(`Token endpoint error: ${response.status}`);
|
|
81
|
+
const refreshTokenSetRaw = (await response.json());
|
|
82
|
+
const refreshTokenSet = (0, parse_token_1.default)(refreshTokenSetRaw);
|
|
83
|
+
return this.setToken(refreshTokenSet);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
this.errorHandler(error);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.OidcClient = OidcClient;
|
|
92
|
+
exports.oidc = new OidcClient();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { OidcConnect } from '../connect';
|
|
2
|
+
import { Connect } from '../types/connect.type';
|
|
3
|
+
import { TokenSet } from '../types/token-set.type';
|
|
4
|
+
import { GrantTypeErrorHandlerType } from '../types/error-handler.type';
|
|
5
|
+
export declare class OidcClient extends OidcConnect {
|
|
6
|
+
errorHandler: GrantTypeErrorHandlerType;
|
|
7
|
+
token: TokenSet | null;
|
|
8
|
+
getToken: (revert?: boolean) => TokenSet | null;
|
|
9
|
+
setToken: (token: TokenSet, revert?: boolean) => TokenSet;
|
|
10
|
+
constructor();
|
|
11
|
+
connect(params: Connect): Promise<void>;
|
|
12
|
+
getAccessToken(data: Record<string, unknown>): Promise<TokenSet | null>;
|
|
13
|
+
getRefreshToken(tokenSet: TokenSet): Promise<TokenSet | null>;
|
|
14
|
+
}
|
|
15
|
+
export declare const oidc: OidcClient;
|
|
16
|
+
//# sourceMappingURL=sso.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sso.d.ts","sourceRoot":"","sources":["../../../src/grant-type/sso.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAKxE,qBAAa,UAAW,SAAQ,WAAW;IACzC,YAAY,EAAE,yBAAyB,CAAC;IACxC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,QAAQ,GAAG,IAAI,CAAC;IAChD,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,QAAQ,CAAC;;IAW3C,OAAO,CAAC,MAAM,EAAE,OAAO;IAQhC,cAAc,CAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAkCrB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;CA2BpE;AAED,eAAO,MAAM,IAAI,YAAmB,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.oidc = exports.OidcClient = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const connect_1 = require("../connect");
|
|
6
|
+
const token_1 = require("../token");
|
|
7
|
+
const parse_token_1 = tslib_1.__importDefault(require("../utils/parse-token"));
|
|
8
|
+
const grantType = 'sso';
|
|
9
|
+
class OidcClient extends connect_1.OidcConnect {
|
|
10
|
+
errorHandler;
|
|
11
|
+
token;
|
|
12
|
+
getToken;
|
|
13
|
+
setToken;
|
|
14
|
+
constructor() {
|
|
15
|
+
super();
|
|
16
|
+
this.errorHandler = this.ErrorHandler(grantType);
|
|
17
|
+
this.token = null;
|
|
18
|
+
const tokenHelper = new token_1.Token();
|
|
19
|
+
this.getToken = tokenHelper.getToken.bind(tokenHelper);
|
|
20
|
+
this.setToken = tokenHelper.setToken.bind(tokenHelper);
|
|
21
|
+
}
|
|
22
|
+
async connect(params) {
|
|
23
|
+
await super.connect({
|
|
24
|
+
...params,
|
|
25
|
+
responseTypes: ['none'],
|
|
26
|
+
grantTypes: [grantType, 'refresh_token'],
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async getAccessToken(data) {
|
|
30
|
+
if (!this.configuration)
|
|
31
|
+
throw new Error(`[${grantType}] Not initialized.`);
|
|
32
|
+
if (this.token)
|
|
33
|
+
return this.token;
|
|
34
|
+
const tokenEndpoint = this.configuration.server.token_endpoint;
|
|
35
|
+
const params = new URLSearchParams({
|
|
36
|
+
grant_type: grantType,
|
|
37
|
+
client_id: this.configuration.client_id,
|
|
38
|
+
client_secret: this.configuration.client_secret,
|
|
39
|
+
...Object.fromEntries(Object.entries(data).map(([k, v]) => [k, String(v)])),
|
|
40
|
+
});
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(tokenEndpoint, {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
headers: {
|
|
45
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
46
|
+
},
|
|
47
|
+
body: params.toString(),
|
|
48
|
+
});
|
|
49
|
+
if (!response.ok)
|
|
50
|
+
throw new Error(`Token endpoint error: ${response.status}`);
|
|
51
|
+
const tokenSetRaw = (await response.json());
|
|
52
|
+
const tokenSet = (0, parse_token_1.default)(tokenSetRaw);
|
|
53
|
+
this.token = this.setToken(tokenSet);
|
|
54
|
+
return this.token;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
this.errorHandler(error);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async getRefreshToken(tokenSet) {
|
|
62
|
+
if (!this.configuration)
|
|
63
|
+
throw new Error(`[${grantType}] Not initialized.`);
|
|
64
|
+
const tokenEndpoint = this.configuration.server.token_endpoint;
|
|
65
|
+
const params = new URLSearchParams({
|
|
66
|
+
grant_type: 'refresh_token',
|
|
67
|
+
client_id: this.configuration.client_id,
|
|
68
|
+
client_secret: this.configuration.client_secret,
|
|
69
|
+
refresh_token: tokenSet.refreshToken,
|
|
70
|
+
});
|
|
71
|
+
try {
|
|
72
|
+
const response = await fetch(tokenEndpoint, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: {
|
|
75
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
76
|
+
},
|
|
77
|
+
body: params.toString(),
|
|
78
|
+
});
|
|
79
|
+
if (!response.ok)
|
|
80
|
+
throw new Error(`Token endpoint error: ${response.status}`);
|
|
81
|
+
const refreshTokenSetRaw = (await response.json());
|
|
82
|
+
const refreshTokenSet = (0, parse_token_1.default)(refreshTokenSetRaw);
|
|
83
|
+
return this.setToken(refreshTokenSet);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
this.errorHandler(error);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.OidcClient = OidcClient;
|
|
92
|
+
exports.oidc = new OidcClient();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;yBAWzB,QAAQ,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;AAAxD,wBAWE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const client_credentials_1 = require("./grant-type/client_credentials");
|
|
4
|
+
const password_1 = require("./grant-type/password");
|
|
5
|
+
const sso_1 = require("./grant-type/sso");
|
|
6
|
+
const clients = {
|
|
7
|
+
client_credentials: client_credentials_1.oidc,
|
|
8
|
+
password: password_1.oidc,
|
|
9
|
+
sso: sso_1.oidc,
|
|
10
|
+
};
|
|
11
|
+
exports.default = async (params) => {
|
|
12
|
+
const oidc = clients[params.grantType];
|
|
13
|
+
await oidc.connect({
|
|
14
|
+
baseUrl: params.baseUrl,
|
|
15
|
+
oidcPath: params.oidcPath,
|
|
16
|
+
clientId: params.clientId,
|
|
17
|
+
clientSecret: params.clientSecret,
|
|
18
|
+
});
|
|
19
|
+
return oidc;
|
|
20
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAGlD,qBAAa,KAAK;IAChB,KAAK,EAAG,QAAQ,CAAC;IAEjB,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAQ,GAAG,QAAQ;IAKnD,QAAQ,CAAC,MAAM,UAAQ,GAAG,QAAQ,GAAG,IAAI;CAO1C"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Token = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const parse_token_1 = tslib_1.__importDefault(require("./utils/parse-token"));
|
|
6
|
+
class Token {
|
|
7
|
+
token;
|
|
8
|
+
setToken(token, revert = false) {
|
|
9
|
+
this.token = (0, parse_token_1.default)(token, revert);
|
|
10
|
+
return this.token;
|
|
11
|
+
}
|
|
12
|
+
getToken(revert = false) {
|
|
13
|
+
if (!this.token)
|
|
14
|
+
return null;
|
|
15
|
+
const expiresAt = this.token.expiresAt || this.token.expires_at;
|
|
16
|
+
const now = Math.floor(new Date().getTime() / 1000);
|
|
17
|
+
if (expiresAt - 60 <= now)
|
|
18
|
+
return null;
|
|
19
|
+
return (revert && (0, parse_token_1.default)(this.token, revert)) || this.token;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.Token = Token;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type Connect = {
|
|
2
|
+
grantType?: string;
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
oidcPath: string;
|
|
5
|
+
clientId: string;
|
|
6
|
+
clientSecret: string;
|
|
7
|
+
responseTypes?: string[];
|
|
8
|
+
grantTypes?: string[];
|
|
9
|
+
timeout?: number;
|
|
10
|
+
redirectUri?: string;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=connect.type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.type.d.ts","sourceRoot":"","sources":["../../../src/types/connect.type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.type.d.ts","sourceRoot":"","sources":["../../../src/types/error-handler.type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,KAAK,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,KAC3C,IAAI,CAAC;AAEV,MAAM,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type TokenSetParsed = {
|
|
2
|
+
accessToken: string;
|
|
3
|
+
expiresAt: number;
|
|
4
|
+
expiresIn: number;
|
|
5
|
+
idToken: string;
|
|
6
|
+
refreshToken: string;
|
|
7
|
+
scope: string;
|
|
8
|
+
sessionState: string;
|
|
9
|
+
tokenType: string;
|
|
10
|
+
};
|
|
11
|
+
export type TokenSetSource = {
|
|
12
|
+
access_token: string;
|
|
13
|
+
expires_at: number;
|
|
14
|
+
expires_in: number;
|
|
15
|
+
id_token: string;
|
|
16
|
+
refresh_token: string;
|
|
17
|
+
scope: string;
|
|
18
|
+
session_state: string;
|
|
19
|
+
token_type: string;
|
|
20
|
+
};
|
|
21
|
+
export type TokenSet = TokenSetSource & TokenSetParsed;
|
|
22
|
+
//# sourceMappingURL=token-set.type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-set.type.d.ts","sourceRoot":"","sources":["../../../src/types/token-set.type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../../src/utils/error-handler.ts"],"names":[],"mappings":"yBAAgB,WAAW,MAAM,MAC9B,OAAO,KAAK,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE;AADjD,wBAeI"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = (grantType) => (error) => {
|
|
4
|
+
const { name, code, url, message } = error;
|
|
5
|
+
if (name && code && url) {
|
|
6
|
+
throw new Error(`[${grantType}] Error: ${JSON.stringify({ name, code, url })}`);
|
|
7
|
+
}
|
|
8
|
+
if (message) {
|
|
9
|
+
throw new Error(`[${grantType}] Error: ${message}`);
|
|
10
|
+
}
|
|
11
|
+
throw error;
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-token.d.ts","sourceRoot":"","sources":["../../../src/utils/parse-token.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAGT,MAAM,yBAAyB,CAAC;yBAajB,UAAU,QAAQ,EAAE,gBAAc,KAAG,QAAQ;AAA7D,wBAgBE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tokenMapper = {
|
|
4
|
+
accessToken: 'access_token',
|
|
5
|
+
expiresAt: 'expires_at',
|
|
6
|
+
expiresIn: 'expires_in',
|
|
7
|
+
idToken: 'id_token',
|
|
8
|
+
refreshToken: 'refresh_token',
|
|
9
|
+
scope: 'scope',
|
|
10
|
+
sessionState: 'session_state',
|
|
11
|
+
tokenType: 'token_type',
|
|
12
|
+
};
|
|
13
|
+
exports.default = (tokenSet, revert = false) => {
|
|
14
|
+
const tokenSetParsed = {};
|
|
15
|
+
Object.keys(tokenMapper).forEach(mapperKey => {
|
|
16
|
+
const key = ((revert && tokenMapper[mapperKey]) ||
|
|
17
|
+
mapperKey);
|
|
18
|
+
const value = (revert && tokenSet[mapperKey]) ||
|
|
19
|
+
tokenSet[tokenMapper[mapperKey]];
|
|
20
|
+
if (typeof value !== 'undefined') {
|
|
21
|
+
tokenSetParsed[key] = value;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return tokenSetParsed;
|
|
25
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edirect/oidc-client",
|
|
3
|
-
"version": "11.0.
|
|
3
|
+
"version": "11.0.64",
|
|
4
|
+
"packageScope": "@edirect",
|
|
4
5
|
"main": "./dist/cjs/index.js",
|
|
5
6
|
"module": "./dist/esm/index.js",
|
|
6
7
|
"types": "./dist/types/index.d.ts",
|
|
@@ -19,5 +20,26 @@
|
|
|
19
20
|
"openid-client": "^6.8.6",
|
|
20
21
|
"tslib": "^2.8.1"
|
|
21
22
|
},
|
|
22
|
-
"
|
|
23
|
-
|
|
23
|
+
"nx": {
|
|
24
|
+
"name": "@edirect/oidc-client",
|
|
25
|
+
"targets": {
|
|
26
|
+
"build": {
|
|
27
|
+
"executor": "@nx/js:tsc",
|
|
28
|
+
"options": {
|
|
29
|
+
"main": "{workspaceRoot}/packages/edirect-oidc-client/src/index.ts",
|
|
30
|
+
"tsConfig": "{workspaceRoot}/packages/edirect-oidc-client/tsconfig.lib.json",
|
|
31
|
+
"outputPath": "{workspaceRoot}/packages/edirect-oidc-client/dist",
|
|
32
|
+
"assets": [
|
|
33
|
+
"{workspaceRoot}/packages/edirect-oidc-client/package.json",
|
|
34
|
+
"{workspaceRoot}/packages/edirect-oidc-client/README.md"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
42
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
|
43
|
+
"build": "pnpm run build:cjs && pnpm run build:esm"
|
|
44
|
+
}
|
|
45
|
+
}
|