coffee-pay-sdk 1.0.0

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,142 @@
1
+ # COFFEE-PAY SDK for Node.js
2
+
3
+ Node.js SDK to integrate with the **COFFEE-PAY** payment gateway easily and securely using TypeScript/JavaScript.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/coffee-pay-sdk)](https://www.npmjs.com/package/coffee-pay-sdk)
6
+ [![license](https://img.shields.io/npm/l/coffee-pay-sdk)](https://github.com/coffee-pay/sdk-nodejs/blob/main/LICENSE)
7
+
8
+ ---
9
+
10
+ ## โœจ Features
11
+
12
+ - ๐Ÿ” **Automatic JWT Authentication**: Handles `apiKey` and `apiSecret` encryption automatically.
13
+ - ๐Ÿงพ **Subscription Management**: Full CRUD support for subscription plans.
14
+ - ๐Ÿ›ก๏ธ **Web Signing Utilities**: Easy signature generation for secure web payment buttons.
15
+ - ๐Ÿง  **Fully Typed**: Built with TypeScript for excellent developer experience.
16
+ - โš™๏ธ **Modern**: Compatible with Node.js v18+.
17
+
18
+ ---
19
+
20
+ ## ๐Ÿ“ฆ Installation
21
+
22
+ ```bash
23
+ npm install coffee-pay-sdk
24
+ # or
25
+ yarn add coffee-pay-sdk
26
+ ```
27
+
28
+ ---
29
+
30
+ ## ๐Ÿš€ Quick Start
31
+
32
+ ### 1. Initialize the Client
33
+
34
+ The SDK automatically handles JWT token generation (valid for 30s) for every request.
35
+
36
+ ```typescript
37
+ import { CoffeeSDK } from 'coffee-pay-sdk';
38
+
39
+ const coffee = new CoffeeSDK({
40
+ apiKey: 'YOUR_API_KEY',
41
+ apiSecret: 'YOUR_API_SECRET',
42
+ // baseUrl: 'https://staging.coffee-pay.co/api/v1' // Optional: default is production
43
+ });
44
+ ```
45
+
46
+ ### 2. Manage Subscription Plans (CRUD)
47
+
48
+ ```typescript
49
+ // List plans
50
+ const plans = await coffee.subscriptionsPlans.list(10, 1);
51
+
52
+ // Create a new plan
53
+ const newPlan = await coffee.subscriptionsPlans.create({
54
+ name: 'Monthly Premium',
55
+ description: 'Pro access',
56
+ price: 25000,
57
+ currencyId: '...', // Bogota UUID
58
+ interval: 'monthly',
59
+ accountId: '...',
60
+ billingDay: 1,
61
+ freeDays: 0,
62
+ status: true,
63
+ source: 'API'
64
+ });
65
+
66
+ // Get by ID
67
+ const plan = await coffee.subscriptionsPlans.get('PLAN_ID');
68
+
69
+ // Update plan
70
+ await coffee.subscriptionsPlans.update('PLAN_ID', {
71
+ description: 'Updated description'
72
+ });
73
+
74
+ // Delete plan
75
+ await coffee.subscriptionsPlans.delete('PLAN_ID');
76
+ ```
77
+
78
+ ### 3. Consult Currencies
79
+
80
+ ```typescript
81
+ // List currencies
82
+ const currencies = await coffee.currencies.list(10, 1);
83
+
84
+ // Get currency by ID
85
+ const currency = await coffee.currencies.get('CURRENCY_ID');
86
+ ```
87
+
88
+ ### 4. Signing for Web Payments
89
+
90
+ Use this utility to sign requests made from the browser (e.g., for payment buttons).
91
+
92
+ ```typescript
93
+ import { CryptoUtils } from 'coffee-pay-sdk';
94
+
95
+ const accountKey = "YOUR_ACCOUNT_KEY";
96
+ const integrityKey = "YOUR_INTEGRITY_KEY";
97
+ const timestamp = Math.floor(Date.now() / 1000);
98
+
99
+ const signature = CryptoUtils.generateWebSignature(accountKey, integrityKey, timestamp);
100
+ ```
101
+
102
+ ---
103
+
104
+ ## ๐Ÿ› ๏ธ API Reference
105
+
106
+ ### `CoffeeSDK`
107
+
108
+ | Option | Type | Description |
109
+ | --- | --- | --- |
110
+ | `apiKey` | `string` | Your Coffee-Pay API Key. |
111
+ | `apiSecret` | `string` | Your Coffee-Pay API Secret. |
112
+ | `baseUrl` | `string` | (Optional) API endpoint URL. |
113
+ | `timeout` | `number` | (Optional) Request timeout in ms (default: 30000). |
114
+
115
+ ### `subscriptionsPlans`
116
+
117
+ | Method | Description |
118
+ | --- | --- |
119
+ | `list(limit, page)` | Returns a paginated list of plans. |
120
+ | `create(data)` | Creates a new plan. |
121
+ | `get(id)` | Retrieves a plan by ID. |
122
+ | `update(id, data)` | Partially updates a plan. |
123
+ | `delete(id)` | Deletes a plan. |
124
+
125
+ ### `currencies`
126
+
127
+ | Method | Description |
128
+ | --- | --- |
129
+ | `list(limit, page)` | Returns a list of supported currencies. |
130
+ | `get(id)` | Retrieves detailed information for a specific currency. |
131
+
132
+ ---
133
+
134
+ ## ๐Ÿค Contributing
135
+
136
+ Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
137
+
138
+ ---
139
+
140
+ ## ๐Ÿ“ License
141
+
142
+ MIT ยฉ [Coffee-Pay](https://coffee-pay.co)
@@ -0,0 +1,10 @@
1
+ import { CoffeeConfig } from './types';
2
+ import { SubscriptionsPlans } from './resources/subscriptions-plans';
3
+ import { Currencies } from './resources/currencies';
4
+ export declare class CoffeeSDK {
5
+ private axiosInstance;
6
+ private config;
7
+ subscriptionsPlans: SubscriptionsPlans;
8
+ currencies: Currencies;
9
+ constructor(config: CoffeeConfig);
10
+ }
package/dist/client.js ADDED
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CoffeeSDK = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const auth_1 = require("./utils/auth");
9
+ const subscriptions_plans_1 = require("./resources/subscriptions-plans");
10
+ const currencies_1 = require("./resources/currencies");
11
+ class CoffeeSDK {
12
+ axiosInstance;
13
+ config;
14
+ subscriptionsPlans;
15
+ currencies;
16
+ constructor(config) {
17
+ this.config = config;
18
+ this.axiosInstance = axios_1.default.create({
19
+ baseURL: config.baseUrl || 'https://production.coffee-pay.co/api/v1',
20
+ timeout: config.timeout || 30000,
21
+ });
22
+ // Add interceptor to include JWT token in every request
23
+ this.axiosInstance.interceptors.request.use((config) => {
24
+ const token = auth_1.AuthUtils.generateJWT(this.config.apiKey, this.config.apiSecret);
25
+ config.headers.Authorization = `Bearer ${token}`;
26
+ return config;
27
+ });
28
+ this.subscriptionsPlans = new subscriptions_plans_1.SubscriptionsPlans(this.axiosInstance);
29
+ this.currencies = new currencies_1.Currencies(this.axiosInstance);
30
+ }
31
+ }
32
+ exports.CoffeeSDK = CoffeeSDK;
@@ -0,0 +1,5 @@
1
+ export * from './client';
2
+ export * from './types';
3
+ export { CryptoUtils } from './utils/crypto';
4
+ export { AuthUtils } from './utils/auth';
5
+ export { Currencies } from './resources/currencies';
package/dist/index.js ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.Currencies = exports.AuthUtils = exports.CryptoUtils = void 0;
18
+ __exportStar(require("./client"), exports);
19
+ __exportStar(require("./types"), exports);
20
+ var crypto_1 = require("./utils/crypto");
21
+ Object.defineProperty(exports, "CryptoUtils", { enumerable: true, get: function () { return crypto_1.CryptoUtils; } });
22
+ var auth_1 = require("./utils/auth");
23
+ Object.defineProperty(exports, "AuthUtils", { enumerable: true, get: function () { return auth_1.AuthUtils; } });
24
+ var currencies_1 = require("./resources/currencies");
25
+ Object.defineProperty(exports, "Currencies", { enumerable: true, get: function () { return currencies_1.Currencies; } });
@@ -0,0 +1,16 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import { ApiResponse, Currency, ListResponse } from '../types';
3
+ export declare class Currencies {
4
+ private axios;
5
+ constructor(axios: AxiosInstance);
6
+ /**
7
+ * Retrieves a list of currencies.
8
+ * @param limit Number of items to retrieve (default: 100)
9
+ * @param page Page number (default: 1)
10
+ */
11
+ list(limit?: number, page?: number): Promise<ListResponse<Currency>>;
12
+ /**
13
+ * Retrieves a currency by ID.
14
+ */
15
+ get(id: string): Promise<ApiResponse<Currency>>;
16
+ }
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Currencies = void 0;
4
+ class Currencies {
5
+ axios;
6
+ constructor(axios) {
7
+ this.axios = axios;
8
+ }
9
+ /**
10
+ * Retrieves a list of currencies.
11
+ * @param limit Number of items to retrieve (default: 100)
12
+ * @param page Page number (default: 1)
13
+ */
14
+ async list(limit = 100, page = 1) {
15
+ const response = await this.axios.get('/admin/currencies', {
16
+ params: { limit, page },
17
+ });
18
+ return response.data;
19
+ }
20
+ /**
21
+ * Retrieves a currency by ID.
22
+ */
23
+ async get(id) {
24
+ const response = await this.axios.get(`/admin/currencies/${id}`);
25
+ return response.data;
26
+ }
27
+ }
28
+ exports.Currencies = Currencies;
@@ -0,0 +1,28 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import { ApiResponse, CreateSubscriptionPlanDto, ListResponse, SubscriptionPlan, UpdateSubscriptionPlanDto } from '../types';
3
+ export declare class SubscriptionsPlans {
4
+ private axios;
5
+ constructor(axios: AxiosInstance);
6
+ /**
7
+ * Retrieves a list of subscription plans.
8
+ * @param limit Number of items to retrieve (default: 100)
9
+ * @param page Page number (default: 1)
10
+ */
11
+ list(limit?: number, page?: number): Promise<ListResponse<SubscriptionPlan>>;
12
+ /**
13
+ * Creates a new subscription plan.
14
+ */
15
+ create(data: CreateSubscriptionPlanDto): Promise<ApiResponse<SubscriptionPlan>>;
16
+ /**
17
+ * Retrieves a subscription plan by ID.
18
+ */
19
+ get(id: string): Promise<ApiResponse<SubscriptionPlan>>;
20
+ /**
21
+ * Updates an existing subscription plan.
22
+ */
23
+ update(id: string, data: UpdateSubscriptionPlanDto): Promise<ApiResponse<SubscriptionPlan>>;
24
+ /**
25
+ * Deletes a subscription plan by ID.
26
+ */
27
+ delete(id: string): Promise<ApiResponse<any>>;
28
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SubscriptionsPlans = void 0;
4
+ class SubscriptionsPlans {
5
+ axios;
6
+ constructor(axios) {
7
+ this.axios = axios;
8
+ }
9
+ /**
10
+ * Retrieves a list of subscription plans.
11
+ * @param limit Number of items to retrieve (default: 100)
12
+ * @param page Page number (default: 1)
13
+ */
14
+ async list(limit = 100, page = 1) {
15
+ const response = await this.axios.get('/subscriptions-plans', {
16
+ params: { limit, page },
17
+ });
18
+ return response.data;
19
+ }
20
+ /**
21
+ * Creates a new subscription plan.
22
+ */
23
+ async create(data) {
24
+ const response = await this.axios.post('/subscriptions-plans', data);
25
+ return response.data;
26
+ }
27
+ /**
28
+ * Retrieves a subscription plan by ID.
29
+ */
30
+ async get(id) {
31
+ const response = await this.axios.get(`/subscriptions-plans/${id}`);
32
+ return response.data;
33
+ }
34
+ /**
35
+ * Updates an existing subscription plan.
36
+ */
37
+ async update(id, data) {
38
+ const response = await this.axios.patch(`/subscriptions-plans/${id}`, data);
39
+ return response.data;
40
+ }
41
+ /**
42
+ * Deletes a subscription plan by ID.
43
+ */
44
+ async delete(id) {
45
+ const response = await this.axios.delete(`/subscriptions-plans/${id}`);
46
+ return response.data;
47
+ }
48
+ }
49
+ exports.SubscriptionsPlans = SubscriptionsPlans;
@@ -0,0 +1,82 @@
1
+ export interface CoffeeConfig {
2
+ apiKey: string;
3
+ apiSecret: string;
4
+ baseUrl?: string;
5
+ timeout?: number;
6
+ }
7
+ export interface AuthPayload {
8
+ iss: string;
9
+ jti: string;
10
+ iat: number;
11
+ exp: number;
12
+ }
13
+ export interface SubscriptionPlan {
14
+ id: string;
15
+ accountId: string;
16
+ name: string;
17
+ reference: string;
18
+ description: string;
19
+ price: number;
20
+ currencyId: string;
21
+ interval: 'daily' | 'weekly' | 'monthly' | 'yearly';
22
+ intervalCount: number;
23
+ billingDay: number;
24
+ freeDays: number;
25
+ allowProrate: boolean;
26
+ redirectUrl: string;
27
+ urlBack: string;
28
+ source: string;
29
+ status: boolean;
30
+ isDeleted: boolean;
31
+ createdBy: string;
32
+ updatedBy: string;
33
+ createdAt: string;
34
+ updatedAt: string;
35
+ }
36
+ export interface ApiResponse<T> {
37
+ error: boolean;
38
+ data: T;
39
+ message: string;
40
+ }
41
+ export interface ListResponse<T> {
42
+ error: boolean;
43
+ data: T[];
44
+ message: string;
45
+ options: {
46
+ total: number;
47
+ page: number;
48
+ limit: number;
49
+ };
50
+ }
51
+ export interface CreateSubscriptionPlanDto {
52
+ name: string;
53
+ description: string;
54
+ price: number;
55
+ currencyId: string;
56
+ interval: 'daily' | 'weekly' | 'monthly' | 'yearly';
57
+ accountId: string;
58
+ billingDay: number;
59
+ freeDays: number;
60
+ status: boolean;
61
+ source: string;
62
+ intervalCount?: number;
63
+ reference?: string;
64
+ allowProrate?: boolean;
65
+ redirectUrl?: string;
66
+ urlBack?: string;
67
+ }
68
+ export type UpdateSubscriptionPlanDto = Partial<CreateSubscriptionPlanDto>;
69
+ export interface Currency {
70
+ id: string;
71
+ isoCode: string;
72
+ tim: number;
73
+ symbol: string;
74
+ decimalSeparator: string;
75
+ thousandSeparator: string;
76
+ visaCode: string;
77
+ isDeleted: boolean;
78
+ createdBy: string;
79
+ updatedBy: string;
80
+ createdAt: string;
81
+ updatedAt: string;
82
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ export declare class AuthUtils {
2
+ static generateJWT(apiKey: string, apiSecret: string): string;
3
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.AuthUtils = void 0;
37
+ const crypto = __importStar(require("crypto-js"));
38
+ const uuid_1 = require("uuid");
39
+ class AuthUtils {
40
+ static generateJWT(apiKey, apiSecret) {
41
+ const header = { alg: 'HS256', typ: 'JWT' };
42
+ const now = Math.floor(Date.now() / 1000);
43
+ const payload = {
44
+ iss: apiKey,
45
+ jti: (0, uuid_1.v4)(),
46
+ iat: now,
47
+ exp: now + 30, // 30 seconds expiration as requested
48
+ };
49
+ const base64url = (source) => {
50
+ let encodedSource = typeof source === 'string'
51
+ ? crypto.enc.Base64.stringify(crypto.enc.Utf8.parse(source))
52
+ : crypto.enc.Base64.stringify(source);
53
+ return encodedSource
54
+ .replace(/=+$/, '')
55
+ .replace(/\+/g, '-')
56
+ .replace(/\//g, '_');
57
+ };
58
+ const encodedHeader = base64url(JSON.stringify(header));
59
+ const encodedPayload = base64url(JSON.stringify(payload));
60
+ const signatureSource = `${encodedHeader}.${encodedPayload}`;
61
+ const signature = base64url(crypto.HmacSHA256(signatureSource, apiSecret));
62
+ return `${encodedHeader}.${encodedPayload}.${signature}`;
63
+ }
64
+ }
65
+ exports.AuthUtils = AuthUtils;
@@ -0,0 +1,7 @@
1
+ export declare class CryptoUtils {
2
+ /**
3
+ * Generates a signature for web payment requests using accountKey and integrityKey.
4
+ * This matches the logic provided in the requirements.
5
+ */
6
+ static generateWebSignature(accountKey: string, integrityKey: string, timestamp: number): string;
7
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CryptoUtils = void 0;
37
+ const crypto = __importStar(require("crypto-js"));
38
+ class CryptoUtils {
39
+ /**
40
+ * Generates a signature for web payment requests using accountKey and integrityKey.
41
+ * This matches the logic provided in the requirements.
42
+ */
43
+ static generateWebSignature(accountKey, integrityKey, timestamp) {
44
+ const dataToSign = `${accountKey}${timestamp}${integrityKey}`;
45
+ const hash = crypto.SHA256(dataToSign);
46
+ return hash.toString(crypto.enc.Hex);
47
+ }
48
+ }
49
+ exports.CryptoUtils = CryptoUtils;
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "coffee-pay-sdk",
3
+ "version": "1.0.0",
4
+ "description": "Node.js SDK for Coffee-Pay payment gateway",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "prepublishOnly": "npm run build",
10
+ "test": "echo \"Error: no test specified\" && exit 1"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "keywords": [
18
+ "coffee-pay",
19
+ "payments",
20
+ "sdk",
21
+ "nodejs",
22
+ "typescript"
23
+ ],
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/coffee-pay-co/node-sdk.git"
27
+ },
28
+ "author": "Coffee-Pay",
29
+ "license": "MIT",
30
+ "dependencies": {
31
+ "axios": "^1.13.4",
32
+ "crypto-js": "^4.2.0",
33
+ "uuid": "^13.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/crypto-js": "^4.2.2",
37
+ "@types/node": "^25.2.1",
38
+ "@types/uuid": "^10.0.0",
39
+ "ts-node": "^10.9.2",
40
+ "typescript": "^5.9.3"
41
+ }
42
+ }