kerliix-oauth 1.0.1

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/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # Kerliix OAuth SDK
2
+
3
+ > Official Kerliix OAuth 2.0 SDK for Node.js and Browser
4
+
5
+ [![npm version](https://img.shields.io/npm/v/kerliix-oauth.svg?style=flat-square)](https://www.npmjs.com/package/kerliix-oauth)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=flat-square)](https://github.com/kerliix-corp/kerliix-oauth-nodejs/blob/main/LICENSE)
7
+ [![Build Status](https://github.com/kerliix-corp/kerliix-oauth-nodejs/actions/workflows/build.yml/badge.svg)](https://github.com/kerliix-corp/kerliix-oauth-nodejs/actions)
8
+
9
+ ---
10
+
11
+ ## Overview
12
+
13
+ **Kerliix OAuth** provides a simple and secure way to integrate Kerliix authentication into your Node.js or browser-based apps.
14
+ It handles the full OAuth 2.0 flow including:
15
+
16
+ * Building authorization URLs
17
+ * Exchanging authorization codes for tokens
18
+ * Token caching & auto-refresh
19
+ * Fetching user profile data
20
+ * Revoking tokens
21
+
22
+ Built with **TypeScript**, compatible with both **Node.js** and **browser environments**.
23
+
24
+ ---
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ npm install kerliix-oauth
30
+ ```
31
+
32
+ or using yarn:
33
+
34
+ ```bash
35
+ yarn add kerliix-oauth
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Quick Start
41
+
42
+ ```js
43
+ import KerliixOAuth from "kerliix-oauth";
44
+
45
+ const client = new KerliixOAuth({
46
+ clientId: "YOUR_CLIENT_ID",
47
+ clientSecret: "YOUR_CLIENT_SECRET",
48
+ redirectUri: "https://yourapp.com/callback",
49
+ baseUrl: "https://api.kerliix.com"
50
+ });
51
+
52
+ // Step 1: Redirect user to login
53
+ const authUrl = client.getAuthUrl(["openid", "profile", "email"]);
54
+ console.log("Login via:", authUrl);
55
+
56
+ // Step 2: Exchange the code for tokens
57
+ // const token = await client.exchangeCodeForToken("OAUTH_CODE");
58
+
59
+ // Step 3: Fetch user profile
60
+ // const user = await client.getUserInfo(token.access_token);
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Configuration Options
66
+
67
+ | Option | Required | Description |
68
+ | -------------- | -------- | ------------------------------------------------------------ |
69
+ | `clientId` | ✅ | Your app’s client ID from Kerliix developer portal |
70
+ | `clientSecret` | ⚙️ | Required for server-side (authorization code flow) |
71
+ | `redirectUri` | ✅ | The callback URI registered in your app |
72
+ | `baseUrl` | ✅ | Your Kerliix OAuth base URL, e.g. `https://auth.kerliix.com` |
73
+
74
+ ---
75
+
76
+ ## OAuth Flow
77
+
78
+ 1. **User clicks login** → Redirect to Kerliix via `getAuthUrl()`
79
+ 2. **Kerliix authenticates** → Redirects back with `?code=XYZ`
80
+ 3. **Your app exchanges code** → `exchangeCodeForToken(code)`
81
+ 4. **Use token** → Access user data via `getUserInfo()`
82
+ 5. **Optional** → Automatically refresh expired tokens
83
+
84
+ ---
85
+
86
+ ## API Reference
87
+
88
+ ### `new KerliixOAuth(config)`
89
+
90
+ Initializes the client.
91
+
92
+ ```js
93
+ const client = new KerliixOAuth({
94
+ clientId: "...",
95
+ clientSecret: "...",
96
+ redirectUri: "...",
97
+ baseUrl: "https://api.kerliix.com"
98
+ });
99
+ ```
100
+
101
+ ---
102
+
103
+ ### `getAuthUrl(scopes?: string[], state?: string): string`
104
+
105
+ Generates an authorization URL for login/consent.
106
+
107
+ ```js
108
+ const url = client.getAuthUrl(["openid", "profile", "email"], "xyz123");
109
+ ```
110
+
111
+ ---
112
+
113
+ ### `exchangeCodeForToken(code: string): Promise<TokenResponse>`
114
+
115
+ Exchanges an authorization code for access and refresh tokens.
116
+
117
+ ---
118
+
119
+ ### `refreshTokenIfNeeded(): Promise<TokenResponse | null>`
120
+
121
+ Checks if the token is expiring and automatically refreshes it if needed.
122
+
123
+ ---
124
+
125
+ ### `getUserInfo(accessToken?: string): Promise<UserInfo>`
126
+
127
+ Fetches the user’s profile data using a valid access token.
128
+
129
+ ---
130
+
131
+ ### `revokeToken(token: string): Promise<boolean>`
132
+
133
+ Revokes an access or refresh token.
134
+
135
+ ---
136
+
137
+ ## Token Caching
138
+
139
+ The SDK automatically caches tokens in memory and:
140
+
141
+ * Refreshes them **30 seconds before expiry**
142
+ * Clears cache when tokens are revoked
143
+ * Works seamlessly in Node.js and browser environments
144
+
145
+ ---
146
+
147
+ ## License
148
+
149
+ MIT © Kerliix Corporation
package/changelog.md ADDED
@@ -0,0 +1,78 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ---
9
+
10
+ ## Quick Start / Known Issues (Local Development)
11
+ - **TypeScript syntax cannot run directly in Node.js** without compiling. Use `tsc` to build before running.
12
+ - **Do not use `!` non-null assertions** in runtime code (`CLIENT_ID!`) – they are TypeScript-only and will break Node.js execution.
13
+ - Exported functions with TypeScript types (e.g., `code: string`) will throw syntax errors if run uncompiled.
14
+ - Always handle runtime errors from SDK methods:
15
+ - `"Missing required config: clientId, redirectUri, or baseUrl"`
16
+ - `"Token exchange failed: <statusText>"`
17
+ - `"Failed to refresh token"`
18
+ - `"Missing access token"`
19
+ - `"Failed to fetch user info"`
20
+ - `revokeToken()` may return `false` if revocation fails.
21
+ - Use compiled `dist/` files for testing locally instead of raw `.ts` files.
22
+
23
+ ---
24
+
25
+ ## [1.0.1] - 2025-10-27
26
+ ### Added
27
+ - **Runtime error documentation** for the SDK:
28
+ - `"Missing required config: clientId, redirectUri, or baseUrl"` in `KerliixOAuth` constructor.
29
+ - `"Token exchange failed: <statusText>"` in `exchangeCodeForToken()`.
30
+ - `"Failed to refresh token"` in `refreshTokenIfNeeded()`.
31
+ - `null` returned from `refreshTokenIfNeeded()` or `TokenCache.get()` if no valid token exists.
32
+ - `"Missing access token"` in `getUserInfo()` if no access token is available.
33
+ - `"Failed to fetch user info"` if user info request fails.
34
+ - `revokeToken()` returns `false` if token revocation fails.
35
+ - Enhanced **developer experience** with clearer SDK error messages and handling instructions.
36
+ - Minor improvements to TypeScript typings and internal caching logic.
37
+
38
+ ### Changed
39
+ - SDK version bumped from `1.0.0-beta.1` to `1.0.1`.
40
+ - Documentation and examples updated to highlight error handling.
41
+
42
+ ### Fixed
43
+ - N/A (no functional changes; only runtime errors clarified).
44
+
45
+ ---
46
+
47
+ ## [1.0.0-beta.1] - 2025-10-15
48
+ ### Added
49
+ - **Initial beta release** of the official **Kerliix OAuth SDK** for Node.js and browser.
50
+ - Support for **OAuth 2.0 Authorization Code Flow**.
51
+ - `KerliixOAuth` main client class for authentication and token management.
52
+ - `getAuthUrl()` method to generate authorization URLs.
53
+ - `exchangeCodeForToken()` to exchange authorization codes for tokens.
54
+ - `refreshTokenIfNeeded()` to refresh tokens automatically.
55
+ - `getUserInfo()` to fetch authenticated user profile information.
56
+ - `revokeToken()` to revoke issued tokens.
57
+ - In-memory **token caching** with early refresh via `TokenCache`.
58
+ - TypeScript support with full type definitions (`types.ts`).
59
+
60
+ ### Fixed
61
+ - N/A (initial release).
62
+
63
+ ### Changed
64
+ - N/A (initial release).
65
+
66
+ ---
67
+
68
+ ## [Unreleased]
69
+ ### Planned
70
+ - Add PKCE (Proof Key for Code Exchange) support for better security.
71
+ - Persistent caching options (file system or Redis).
72
+ - Improved browser compatibility and npm publishing.
73
+ - Unit tests and CI/CD integration.
74
+
75
+ ---
76
+
77
+ **Repository:** [kerliix-corp/kerliix-oauth-nodejs](https://github.com/kerliix-corp/kerliix-oauth-nodejs)
78
+ **License:** MIT © Kerliix Corporation
@@ -0,0 +1,7 @@
1
+ import type { TokenResponse } from "./types.js";
2
+ export declare class TokenCache {
3
+ private tokenData;
4
+ set(token: TokenResponse): void;
5
+ get(): TokenResponse | null;
6
+ clear(): void;
7
+ }
package/dist/cache.js ADDED
@@ -0,0 +1,23 @@
1
+ export class TokenCache {
2
+ constructor() {
3
+ this.tokenData = null;
4
+ }
5
+ set(token) {
6
+ token.created_at = Math.floor(Date.now() / 1000);
7
+ this.tokenData = token;
8
+ }
9
+ get() {
10
+ if (!this.tokenData)
11
+ return null;
12
+ const now = Math.floor(Date.now() / 1000);
13
+ const expiry = (this.tokenData.created_at || 0) + (this.tokenData.expires_in || 0);
14
+ if (now >= expiry - 30) {
15
+ console.warn("TokenCache: token expired or near expiry");
16
+ return null;
17
+ }
18
+ return this.tokenData;
19
+ }
20
+ clear() {
21
+ this.tokenData = null;
22
+ }
23
+ }
@@ -0,0 +1,11 @@
1
+ import type { KerliixConfig, TokenResponse, UserInfo } from "./types.js";
2
+ export default class KerliixOAuth {
3
+ private config;
4
+ private cache;
5
+ constructor(config: KerliixConfig);
6
+ getAuthUrl(scopes?: string[], state?: string): string;
7
+ exchangeCodeForToken(code: string): Promise<TokenResponse>;
8
+ refreshTokenIfNeeded(): Promise<TokenResponse | null>;
9
+ getUserInfo(accessToken?: string): Promise<UserInfo>;
10
+ revokeToken(token: string): Promise<boolean>;
11
+ }
package/dist/client.js ADDED
@@ -0,0 +1,116 @@
1
+ import { TokenCache } from "./cache.js";
2
+ export default class KerliixOAuth {
3
+ constructor(config) {
4
+ if (!config.clientId || !config.redirectUri || !config.baseUrl)
5
+ throw new Error("Missing required config: clientId, redirectUri, or baseUrl");
6
+ this.config = {
7
+ ...config,
8
+ baseUrl: config.baseUrl.replace(/\/$/, "")
9
+ };
10
+ this.cache = new TokenCache();
11
+ }
12
+ getAuthUrl(scopes = ["openid", "profile", "email"], state = "") {
13
+ const params = new URLSearchParams({
14
+ client_id: this.config.clientId,
15
+ redirect_uri: this.config.redirectUri,
16
+ response_type: "code",
17
+ scope: scopes.join(" "),
18
+ state
19
+ });
20
+ return `${this.config.baseUrl}/oauth/authorize?${params.toString()}`;
21
+ }
22
+ async exchangeCodeForToken(code) {
23
+ if (!code)
24
+ throw new Error("exchangeCodeForToken: code is required");
25
+ try {
26
+ const res = await fetch(`${this.config.baseUrl}/oauth/token`, {
27
+ method: "POST",
28
+ headers: { "Content-Type": "application/json" },
29
+ body: JSON.stringify({
30
+ grant_type: "authorization_code",
31
+ code,
32
+ redirect_uri: this.config.redirectUri,
33
+ client_id: this.config.clientId,
34
+ client_secret: this.config.clientSecret
35
+ })
36
+ });
37
+ if (!res.ok) {
38
+ throw new Error(`Token exchange failed: ${res.statusText}`);
39
+ }
40
+ const token = await res.json();
41
+ this.cache.set(token);
42
+ return token;
43
+ }
44
+ catch (err) {
45
+ console.error("exchangeCodeForToken error:", err);
46
+ throw err;
47
+ }
48
+ }
49
+ async refreshTokenIfNeeded() {
50
+ try {
51
+ const cached = this.cache.get();
52
+ if (cached)
53
+ return cached;
54
+ const last = this.cache["tokenData"];
55
+ if (!last?.refresh_token)
56
+ return null;
57
+ const res = await fetch(`${this.config.baseUrl}/oauth/token`, {
58
+ method: "POST",
59
+ headers: { "Content-Type": "application/json" },
60
+ body: JSON.stringify({
61
+ grant_type: "refresh_token",
62
+ refresh_token: last.refresh_token,
63
+ client_id: this.config.clientId,
64
+ client_secret: this.config.clientSecret
65
+ })
66
+ });
67
+ if (!res.ok)
68
+ throw new Error("Failed to refresh token");
69
+ const token = await res.json();
70
+ this.cache.set(token);
71
+ return token;
72
+ }
73
+ catch (err) {
74
+ console.error("refreshTokenIfNeeded error:", err);
75
+ return null; // Fail gracefully, user may need re-auth
76
+ }
77
+ }
78
+ async getUserInfo(accessToken) {
79
+ try {
80
+ const token = accessToken || (await this.refreshTokenIfNeeded())?.access_token;
81
+ if (!token)
82
+ throw new Error("Missing access token");
83
+ const res = await fetch(`${this.config.baseUrl}/oauth/userinfo`, {
84
+ headers: { Authorization: `Bearer ${token}` }
85
+ });
86
+ if (!res.ok)
87
+ throw new Error("Failed to fetch user info");
88
+ return res.json();
89
+ }
90
+ catch (err) {
91
+ console.error("getUserInfo error:", err);
92
+ throw err;
93
+ }
94
+ }
95
+ async revokeToken(token) {
96
+ try {
97
+ const res = await fetch(`${this.config.baseUrl}/oauth/revoke`, {
98
+ method: "POST",
99
+ headers: { "Content-Type": "application/json" },
100
+ body: JSON.stringify({ token })
101
+ });
102
+ if (!res.ok) {
103
+ console.warn("revokeToken failed: server rejected token");
104
+ this.cache.clear(); // clear cache anyway
105
+ return false;
106
+ }
107
+ this.cache.clear();
108
+ return true;
109
+ }
110
+ catch (err) {
111
+ console.error("revokeToken error:", err);
112
+ this.cache.clear();
113
+ return false;
114
+ }
115
+ }
116
+ }
@@ -0,0 +1,3 @@
1
+ import KerliixOAuth from "./client.js";
2
+ export default KerliixOAuth;
3
+ export * from "./types.js";
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import KerliixOAuth from "./client.js";
2
+ export default KerliixOAuth;
3
+ export * from "./types.js";
@@ -0,0 +1,21 @@
1
+ export interface KerliixConfig {
2
+ clientId: string;
3
+ clientSecret?: string;
4
+ redirectUri: string;
5
+ baseUrl: string;
6
+ }
7
+ export interface TokenResponse {
8
+ access_token: string;
9
+ refresh_token?: string;
10
+ token_type: string;
11
+ expires_in: number;
12
+ scope?: string;
13
+ created_at?: number;
14
+ }
15
+ export interface UserInfo {
16
+ id: string;
17
+ email?: string;
18
+ name?: string;
19
+ picture?: string;
20
+ [key: string]: any;
21
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "kerliix-oauth",
3
+ "version": "1.0.1",
4
+ "description": "Official Kerliix OAuth SDK for Node.js and browser",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "prepublishOnly": "npm run build",
11
+ "test": "node tests/client.test.js"
12
+ },
13
+ "keywords": [
14
+ "oauth2",
15
+ "kerliix",
16
+ "nodejs",
17
+ "sdk",
18
+ "authentication",
19
+ "typescript",
20
+ "oauth"
21
+ ],
22
+ "author": "Kerliix Corporation",
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/kerliix-corp/kerliix-oauth-nodejs.git"
27
+ },
28
+ "devDependencies": {
29
+ "typescript": "^5.6.3"
30
+ }
31
+ }
package/src/cache.ts ADDED
@@ -0,0 +1,28 @@
1
+ import type { TokenResponse } from "./types.js";
2
+
3
+ export class TokenCache {
4
+ private tokenData: TokenResponse | null = null;
5
+
6
+ set(token: TokenResponse) {
7
+ token.created_at = Math.floor(Date.now() / 1000);
8
+ this.tokenData = token;
9
+ }
10
+
11
+ get(): TokenResponse | null {
12
+ if (!this.tokenData) return null;
13
+
14
+ const now = Math.floor(Date.now() / 1000);
15
+ const expiry = (this.tokenData.created_at || 0) + (this.tokenData.expires_in || 0);
16
+
17
+ if (now >= expiry - 30) {
18
+ console.warn("TokenCache: token expired or near expiry");
19
+ return null;
20
+ }
21
+
22
+ return this.tokenData;
23
+ }
24
+
25
+ clear() {
26
+ this.tokenData = null;
27
+ }
28
+ }
package/src/client.ts ADDED
@@ -0,0 +1,132 @@
1
+ import type { KerliixConfig, TokenResponse, UserInfo } from "./types.js";
2
+ import { TokenCache } from "./cache.js";
3
+
4
+ export default class KerliixOAuth {
5
+ private config: KerliixConfig;
6
+ private cache: TokenCache;
7
+
8
+ constructor(config: KerliixConfig) {
9
+ if (!config.clientId || !config.redirectUri || !config.baseUrl)
10
+ throw new Error("Missing required config: clientId, redirectUri, or baseUrl");
11
+
12
+ this.config = {
13
+ ...config,
14
+ baseUrl: config.baseUrl.replace(/\/$/, "")
15
+ };
16
+ this.cache = new TokenCache();
17
+ }
18
+
19
+ getAuthUrl(scopes: string[] = ["openid", "profile", "email"], state = ""): string {
20
+ const params = new URLSearchParams({
21
+ client_id: this.config.clientId,
22
+ redirect_uri: this.config.redirectUri,
23
+ response_type: "code",
24
+ scope: scopes.join(" "),
25
+ state
26
+ });
27
+ return `${this.config.baseUrl}/oauth/authorize?${params.toString()}`;
28
+ }
29
+
30
+ async exchangeCodeForToken(code: string): Promise<TokenResponse> {
31
+ if (!code) throw new Error("exchangeCodeForToken: code is required");
32
+
33
+ try {
34
+ const res = await fetch(`${this.config.baseUrl}/oauth/token`, {
35
+ method: "POST",
36
+ headers: { "Content-Type": "application/json" },
37
+ body: JSON.stringify({
38
+ grant_type: "authorization_code",
39
+ code,
40
+ redirect_uri: this.config.redirectUri,
41
+ client_id: this.config.clientId,
42
+ client_secret: this.config.clientSecret
43
+ })
44
+ });
45
+
46
+ if (!res.ok) {
47
+ throw new Error(`Token exchange failed: ${res.statusText}`);
48
+ }
49
+
50
+ const token = await res.json() as TokenResponse;
51
+ this.cache.set(token);
52
+ return token;
53
+
54
+ } catch (err: any) {
55
+ console.error("exchangeCodeForToken error:", err);
56
+ throw err;
57
+ }
58
+ }
59
+
60
+ async refreshTokenIfNeeded(): Promise<TokenResponse | null> {
61
+ try {
62
+ const cached = this.cache.get();
63
+ if (cached) return cached;
64
+
65
+ const last = this.cache["tokenData"];
66
+ if (!last?.refresh_token) return null;
67
+
68
+ const res = await fetch(`${this.config.baseUrl}/oauth/token`, {
69
+ method: "POST",
70
+ headers: { "Content-Type": "application/json" },
71
+ body: JSON.stringify({
72
+ grant_type: "refresh_token",
73
+ refresh_token: last.refresh_token,
74
+ client_id: this.config.clientId,
75
+ client_secret: this.config.clientSecret
76
+ })
77
+ });
78
+
79
+ if (!res.ok) throw new Error("Failed to refresh token");
80
+
81
+ const token = await res.json() as TokenResponse;
82
+ this.cache.set(token);
83
+ return token;
84
+
85
+ } catch (err: any) {
86
+ console.error("refreshTokenIfNeeded error:", err);
87
+ return null; // Fail gracefully, user may need re-auth
88
+ }
89
+ }
90
+
91
+ async getUserInfo(accessToken?: string): Promise<UserInfo> {
92
+ try {
93
+ const token = accessToken || (await this.refreshTokenIfNeeded())?.access_token;
94
+ if (!token) throw new Error("Missing access token");
95
+
96
+ const res = await fetch(`${this.config.baseUrl}/oauth/userinfo`, {
97
+ headers: { Authorization: `Bearer ${token}` }
98
+ });
99
+
100
+ if (!res.ok) throw new Error("Failed to fetch user info");
101
+ return res.json() as Promise<UserInfo>;
102
+
103
+ } catch (err: any) {
104
+ console.error("getUserInfo error:", err);
105
+ throw err;
106
+ }
107
+ }
108
+
109
+ async revokeToken(token: string): Promise<boolean> {
110
+ try {
111
+ const res = await fetch(`${this.config.baseUrl}/oauth/revoke`, {
112
+ method: "POST",
113
+ headers: { "Content-Type": "application/json" },
114
+ body: JSON.stringify({ token })
115
+ });
116
+
117
+ if (!res.ok) {
118
+ console.warn("revokeToken failed: server rejected token");
119
+ this.cache.clear(); // clear cache anyway
120
+ return false;
121
+ }
122
+
123
+ this.cache.clear();
124
+ return true;
125
+
126
+ } catch (err: any) {
127
+ console.error("revokeToken error:", err);
128
+ this.cache.clear();
129
+ return false;
130
+ }
131
+ }
132
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ import KerliixOAuth from "./client.js";
2
+ export default KerliixOAuth;
3
+ export * from "./types.js";
package/src/types.ts ADDED
@@ -0,0 +1,23 @@
1
+ export interface KerliixConfig {
2
+ clientId: string;
3
+ clientSecret?: string;
4
+ redirectUri: string;
5
+ baseUrl: string;
6
+ }
7
+
8
+ export interface TokenResponse {
9
+ access_token: string;
10
+ refresh_token?: string;
11
+ token_type: string;
12
+ expires_in: number;
13
+ scope?: string;
14
+ created_at?: number;
15
+ }
16
+
17
+ export interface UserInfo {
18
+ id: string;
19
+ email?: string;
20
+ name?: string;
21
+ picture?: string;
22
+ [key: string]: any;
23
+ }
@@ -0,0 +1,12 @@
1
+ import KerliixOAuth from "../dist/index.js";
2
+
3
+ (async () => {
4
+ const client = new KerliixOAuth({
5
+ clientId: "demo-client",
6
+ redirectUri: "https://example.com/callback",
7
+ baseUrl: "https://api.kerliix.com"
8
+ });
9
+
10
+ console.log("✅ Authorization URL:");
11
+ console.log(client.getAuthUrl(["openid", "profile", "email"], "test123"));
12
+ })();
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ES2020",
5
+ "declaration": true,
6
+ "outDir": "dist",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "moduleResolution": "node",
10
+ "skipLibCheck": true
11
+ },
12
+ "include": ["src/**/*"]
13
+ }