@alyvro/api-service 1.2.1 → 1.3.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 CHANGED
@@ -8,163 +8,183 @@
8
8
 
9
9
  ### 🚀 Features
10
10
 
11
- - ✅ Effortless HTTP requests on the client built on top of Axios
12
- - ✅ Built-in fetch support for client-side requests
13
- - ✅ Express middleware support add it once and manage everything centrally
14
- - ✅ Auto error reporting to Telegram just provide your bot token & chat ID
15
- - ✅ Fully configurable via a simple object
16
- - ✅ Plugin system for extra features (Cache, Compressor, Retry, Cancel, …)
17
- - ✅ Lightweight, fast, and production-ready
18
- - ✅ Typed Axios response
19
-
20
- ---
21
-
22
- ## Examples
23
-
24
- - [Basic Express Usage](./examples/express-basic)
25
- <!-- - [Express + Telegram Logging](./examples/express-with-telegram) -->
11
+ - ✅ **Universal Support** Works seamlessly on both Client and Server
12
+ - ✅ **Modular Middleware** Dedicated imports for Fastify & Express (Tree-shakable)
13
+ - ✅ **Typed Axios**Full TypeScript inference for your API endpoints
14
+ - ✅ **Built-in Plugins**Cache, Retry, Compressor, and Cancellation
15
+ - ✅ **Auto Error Reporting** Send server errors directly to Telegram
16
+ - ✅ **Zero Config Start** Works out of the box with minimal setup
26
17
 
27
18
  ---
28
19
 
29
20
  ### 📦 Installation
30
21
 
31
- ```bash
22
+ bash
32
23
  pnpm add @alyvro/api-service
24
+
33
25
  # or
26
+
34
27
  npm install @alyvro/api-service
35
- # or
36
- yarn add @alyvro/api-service
37
- ```
28
+
29
+ If you are using a specific framework, make sure it is installed (e.g., `fastify` or `express`).
38
30
 
39
31
  ---
40
32
 
41
- ## ✨ Usage
33
+ ## ✨ Server-Side Usage
34
+
35
+ Initialize the service once in your application entry point.
36
+
37
+ ### ➤ Fastify
42
38
 
43
- ### Client-side
39
+ Import the middleware directly from the fastify subpath. This ensures no Express dependencies are loaded.
44
40
 
45
41
  ```ts
42
+ import Fastify from "fastify";
46
43
  import { ApiService } from "@alyvro/api-service";
47
- import { cache, createAbortController } from "@alyvro/api-service/plugins";
44
+ import middleware from "@alyvro/api-service/fastify";
48
45
 
49
- const api = new ApiService({ api_url: "https://api.alyvro.com" });
46
+ const fastify = Fastify();
50
47
 
51
- // Example: Request with cache, compressor, and retry
52
- const controller = createAbortController();
48
+ new ApiService({
49
+ url: "http://localhost:3000",
50
+ setting: { telegram: true }, // Optional: Enable Telegram error logs
51
+ middleware: {
52
+ skip_routers: ["/health"],
53
+ },
54
+ });
53
55
 
54
- // Using Axios
55
- const axiosResponse = await api.client.axios.request().post(
56
- "/user",
57
- { index: "foo" },
58
- {
59
- secret: { body: true },
60
- signal: controller.signal,
61
- plugins: {
62
- // cache:cache or ApiService.plugins.cache,
63
- compressor: true,
64
- retry: { retries: 5, retryDelay: 500, backoff: true },
65
- },
66
- }
67
- );
56
+ // Add the hook to handle API security and logging
57
+ fastify.addHook("preHandler", middleware);
68
58
 
69
- // Using fetch
70
- const fetchResponse = await api.client.fetch.request("/user", {
71
- method: "POST",
72
- body: { index: "foo" },
73
- signal: controller.signal,
59
+ fastify.get("/", async (request, reply) => {
60
+ return { hello: "world" };
74
61
  });
75
62
 
76
- // Cancel request if needed
77
- controller.abort();
63
+ fastify.listen({ port: 3000 });
78
64
  ```
79
65
 
80
- - `cache` → stores and reuses previous responses to reduce duplicate requests (client & server safe)
81
- - `compressor` → automatically compresses/decompresses payloads when supported by the server
82
- - `retry` → automatic per-request retry with configurable attempts, delay, and backoff
83
- - `createAbortController` → allows canceling requests on demand
84
- - ⚠️ **Note:** Plugins currently only work with Axios. Fetch does **not** support Axios plugins yet.
85
-
86
- ---
87
-
88
- ### ➤ Server-side (Express)
66
+ ### Express
89
67
 
90
68
  ```ts
91
69
  import express from "express";
92
70
  import { ApiService } from "@alyvro/api-service";
71
+ import middleware from "@alyvro/api-service/express";
93
72
 
94
73
  const app = express();
95
74
 
96
- const api = new ApiService({
97
- url: "https://alyvro.com",
98
- settings: { telegram: true }, // enables Telegram error reporting
99
- middleware: {
100
- skip_routers: ["/health", "/status"],
101
- },
75
+ new ApiService({
76
+ url: "http://localhost:3000",
102
77
  });
103
78
 
104
- // Middleware with skip_routers option
105
- app.use((req, res, next) => api.server.middleware(req, res, next));
79
+ app.use(middleware);
106
80
 
107
81
  app.get("/", (req, res) => {
108
- res.json({ message: "Hello world!" });
82
+ res.json({ message: "Hello from Express" });
109
83
  });
110
84
  ```
111
85
 
112
- Middleware now supports skipping routes via `skip_routers`. Requests matching any path in this array will bypass the middleware.
113
-
114
- All server errors will automatically be sent to your Telegram bot.
115
-
116
86
  ---
117
87
 
118
- ### Typed Axios Example
88
+ ## Client-Side Usage
119
89
 
120
- With this setup, you can define a strongly-typed mapping of your API endpoints and their expected responses. This allows TypeScript to infer the correct response type automatically based on the URL you pass.
90
+ You can use either the supercharged Axios client or the native Fetch wrapper.
121
91
 
122
- #### Example
92
+ ### ➤ Using Axios (Recommended)
123
93
 
124
94
  ```ts
125
- // Define your API schema mapping endpoints to their response types
126
- const apis = new ApiService({
127
- url: "https://api.example.com",
128
- }).client.axios.request<{
129
- "/": { index: number };
130
- "/auth": { success: boolean };
131
- "/profile": { id: string; name: string; email: string };
132
- }>();
133
-
134
- // GET request - TypeScript infers the response type as { index: number }
135
- apis.get("/").then((res) => {
136
- console.log(res.data.index); // ✅ res.data.index is a number
95
+ import { ApiService } from "@alyvro/api-service";
96
+
97
+ const api = new ApiService({
98
+ url: "https://api.alyvro.com",
137
99
  });
138
100
 
139
- // POST request - TypeScript infers the response type as { success: boolean }
140
- apis.post("/auth", { username: "john", password: "secret" }).then((res) => {
141
- if (res.data.success) {
142
- console.log("Login successful ✅");
143
- }
101
+ const response = await api.client.axios.request().post(
102
+ "/user",
103
+ { name: "John Doe" },
104
+ {
105
+ plugins: {
106
+ retry: { retries: 3 },
107
+ compressor: true,
108
+ },
109
+ },
110
+ );
111
+ ```
112
+
113
+ ### ➤ Using Fetch
114
+
115
+ ```ts
116
+ const response = await api.client.fetch.request("/user", {
117
+ method: "GET",
118
+ headers: {
119
+ "Content-Type": "application/json",
120
+ },
144
121
  });
122
+ ```
123
+
124
+ ---
125
+
126
+ ## 💎 Typed API (TypeScript Magic)
127
+
128
+ Define your API schema once and get full auto-completion and type inference for every request.
129
+
130
+ ```ts
131
+ import { ApiService } from "@alyvro/api-service";
145
132
 
146
- // PATCH request - TypeScript infers the response type as { id: string; name: string; email: string }
147
- apis.patch("/profile", { name: "John Doe" }).then((res) => {
148
- console.log(res.data.email); // res.data.email is a string
133
+ type ApiSchema = {
134
+ "/users": { id: number; name: string }[];
135
+ "/auth/login": { token: string };
136
+ };
137
+
138
+ const api = new ApiService({
139
+ url: "https://api.example.com",
140
+ }).client.axios.request<ApiSchema>();
141
+
142
+ // ✅ TypeScript knows this returns { token: string }
143
+ api.post("/auth/login", { username: "admin" }).then((res) => {
144
+ console.log(res.data.token);
149
145
  });
150
146
 
151
- // DELETE request - also fully typed
152
- apis.delete("/profile").then((res) => {
153
- console.log(res.data.id); // ✅ res.data.id is a string
147
+ // TypeScript knows this returns Array<{ id: number; name: string }>
148
+ api.get("/users").then((res) => {
149
+ console.log(res.data[0].name);
154
150
  });
155
151
  ```
156
152
 
157
- #### Benefits
153
+ ---
154
+
155
+ ## 🧩 Plugins (Axios Only)
158
156
 
159
- - **Type-safe endpoints**: Each endpoint URL is strongly typed, so you can’t accidentally mistype.
160
- - **Automatic inference**: No need to manually annotate response types, they are inferred from the schema.
161
- - **Better DX**: Autocomplete and IntelliSense show the correct response structure per endpoint.
157
+ Plugins allow extending the functionality of requests per call.
162
158
 
163
- This pattern combines the flexibility of Axios with the type-safety of a predefined API schema.
159
+ | Plugin | Description |
160
+ | :------------- | :----------------------------------------------------------- |
161
+ | **Retry** | Automatically retries failed requests with backoff strategy. |
162
+ | **Cache** | Stores responses to prevent redundant network calls. |
163
+ | **Compressor** | Handles gzip compression/decompression automatically. |
164
+ | **Cancel** | specific signal to abort requests. |
165
+
166
+ **Example:**
167
+
168
+ ```ts
169
+ import { createAbortController } from "@alyvro/api-service/plugins";
170
+
171
+ const controller = createAbortController();
172
+
173
+ api.client.axios.request().get("/large-data", {
174
+ signal: controller.signal,
175
+ plugins: {
176
+ retry: { retries: 5, retryDelay: 1000 },
177
+ cache: true,
178
+ },
179
+ });
180
+
181
+ // Cancel the request
182
+ controller.abort();
183
+ ```
164
184
 
165
185
  ---
166
186
 
167
- ## ⚙️ Config Options
187
+ ## ⚙️ Configuration
168
188
 
169
189
  | Key | Type | Required | Description |
170
190
  | ------------------------- | -------------------------------------- | ------------------------------------------ | -------------------------------------------------------------- |
@@ -184,65 +204,23 @@ This pattern combines the flexibility of Axios with the type-safety of a predefi
184
204
 
185
205
  ---
186
206
 
187
- ## 🧩 Plugins
188
-
189
- Plugins allow extending the functionality of requests and middleware. They are configured **per-request**.
190
-
191
- ### Built-in Plugins
192
-
193
- - **Cache**
194
- Stores last response and prevents duplicate requests with identical payloads.
195
-
196
- - **Compressor**
197
- Compresses request payloads and automatically decompresses gzip responses.
207
+ ## 📫 Telegram Integration
198
208
 
199
- - **Retry**
200
- Automatically retries failed requests.
209
+ To enable error reporting:
201
210
 
202
- ```ts
203
- plugins: { retry: { retries: 5, retryDelay: 500, backoff: true } }
204
- ```
211
+ 1. Set `TELEGRAM_TOKEN` and `TELEGRAM_CHAT_ID` in your environment variables.
212
+ 2. Enable it in the config:
205
213
 
206
- - **Cancel**
207
- Allows canceling requests using `AbortController`.
208
-
209
- ```ts
210
- import { createAbortController } from "@alyvro/api-service/plugins";
211
- const controller = createAbortController();
212
- api.get("/users", { signal: controller.signal });
213
- controller.abort();
214
- ```
215
-
216
- > ⚠️ **Note:** Plugins currently only work with Axios. Fetch does **not** support Axios plugins yet.
217
-
218
- ---
219
-
220
- ## 📫 Telegram Error Reporting
214
+ ts
215
+ new ApiService({
216
+ url: "...",
217
+ setting: { telegram: true }
218
+ });
221
219
 
222
- Errors can be automatically sent to Telegram. Just provide your bot token and chat ID in the config.
220
+ Any 500/403 errors on the server will now be sent to your Telegram chat instantly.
223
221
 
224
222
  ---
225
223
 
226
- ## 📘 License
227
-
228
- MIT License
229
-
230
- Copyright (c) 2025 Alyvro
231
-
232
- Permission is hereby granted, free of charge, to any person obtaining a copy
233
- of this software and associated documentation files (the "Software"), to deal
234
- in the Software without restriction, including without limitation the rights
235
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
236
- copies of the Software, and to permit persons to whom the Software is
237
- furnished to do so, subject to the following conditions:
238
-
239
- The above copyright notice and this permission notice shall be included in all
240
- copies or substantial portions of the Software.
224
+ ## License
241
225
 
242
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
243
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
244
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
245
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
246
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
247
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
248
- SOFTWARE.
226
+ MIT © [Alyvro](https://github.com/Alyvro)
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var y=null;function B(c){y=c}function E(){return y}var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto);var _zlib = require('zlib'); var _zlib2 = _interopRequireDefault(_zlib);var m=c=>{let s=_nullishCoalesce(process.env.PRIVATE_KEY, () => (_optionalChain([c, 'optionalAccess', _ => _.PRIVATE_KEY]))),i=_nullishCoalesce(process.env.PUBLIC_KEY, () => (_optionalChain([c, 'optionalAccess', _2 => _2.PUBLIC_KEY])));if(!s||!i)throw new Error(`Please set ${s?"PUBLIC_KEY":"PRIVATE_KEY"} in env file or set in ApiService Config`);return{encryptSecureBlob:p=>{let t=_crypto2.default.createECDH("secp256k1");t.setPrivateKey(Buffer.from(s,"base64"));let e=t.computeSecret(Buffer.from(i,"base64")).slice(0,32),r=_crypto2.default.randomBytes(12),f=_crypto2.default.createCipheriv("aes-256-gcm",e,r),a=Buffer.concat([f.update(p,"utf8"),f.final()]),o=f.getAuthTag(),g={version:"1",iv:r.toString("base64"),tag:o.toString("base64"),encrypted:a.toString("base64"),senderPublicKey:t.getPublicKey().toString("base64")},S=JSON.stringify(g);return _zlib2.default.gzipSync(Buffer.from(S,"utf8")).toString("hex")},decryptSecureBlob:p=>{let t=Buffer.from(p,"hex"),u=_zlib2.default.gunzipSync(t),e=JSON.parse(u.toString("utf8")),r=_crypto2.default.createECDH("secp256k1");r.setPrivateKey(Buffer.from(s,"base64"));let a=r.computeSecret(Buffer.from(i||e.senderPublicKey,"base64")).slice(0,32),o=_crypto2.default.createDecipheriv("aes-256-gcm",a,Buffer.from(e.iv,"base64"));return o.setAuthTag(Buffer.from(e.tag,"base64")),Buffer.concat([o.update(Buffer.from(e.encrypted,"base64")),o.final()]).toString("utf8")}}},K= exports.c =m;exports.a = B; exports.b = E; exports.c = K;
2
+ //# sourceMappingURL=chunk-MPSUEEQG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["d:\\AlyvroService\\api-service\\dist\\chunk-MPSUEEQG.js"],"names":[],"mappings":"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","file":"D:\\AlyvroService\\api-service\\dist\\chunk-MPSUEEQG.js","sourcesContent":[null]}
@@ -0,0 +1,14 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;function r(t,e){console[e].call(console,t)}var _axios = require('axios'); var _axios2 = _interopRequireDefault(_axios);function h(t){return t.replace(/([_\*\[\]\(\)~`>#+\-=|{}.!\\])/g,"\\$1")}var s= (_class =class{constructor(e,o,n,a){;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);if(!e||!o)throw new Error("Missing token or chat_id");this.token=e,this.chat_id=o,this.obj=n,this.logger=a}get request(){return _axios2.default.create({baseURL:`https://api.telegram.org/bot${this.token}`})}__init() {this.methods={send_message:"/sendMessage"}}__init2() {this.sendMessage=async()=>{try{await this.request.post(this.methods.send_message,{chat_id:this.chat_id,text:h(`**[Server Side Error]:**
2
+
3
+ code:${this.obj.status_code}
4
+ method:${this.obj.method}
5
+ message:${this.obj.message}
6
+ request url: ${this.obj.originalUrl}
7
+
8
+ Time: ${new Date().toISOString()}`),parse_mode:"MarkdownV2"}),this.logger&&r("[Success Log]: Telegram Message Send","log")}catch(e){this.logger&&(e instanceof _axios.AxiosError?r(`[Error Log]: Error to send Telegram Message
9
+
10
+ Status: ${_optionalChain([e, 'access', _5 => _5.response, 'optionalAccess', _6 => _6.status])}
11
+ Data Error: ${_optionalChain([e, 'access', _7 => _7.response, 'optionalAccess', _8 => _8.data])}`,"error"):r(`[Error Log]: Error to send Telegram Message
12
+
13
+ Unknown Error: ${e.message}`,"error"))}}}}, _class);exports.a = s;
14
+ //# sourceMappingURL=chunk-MTW6IRZT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["d:\\AlyvroService\\api-service\\dist\\chunk-MTW6IRZT.js"],"names":[],"mappings":"AAAA,ksBAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,4EAAoB,SAA6C,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,iCAAiC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAC,KAAK,CAAC,WAAoC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,yEAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,eAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,4BAA4B,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;AACA;AACA,KAAA;AACA,OAAA;AACA,QAAA;AACA,aAAA;AACA;AACA,MAAA;AACA;AACA,QAAA;AACA,YAAA;AACA;AACA,eAAA","file":"D:\\AlyvroService\\api-service\\dist\\chunk-MTW6IRZT.js","sourcesContent":[null]}
@@ -19,7 +19,7 @@ type ConfigMiddlewareType = {
19
19
  headers: Partial<ConfigMiddlewareHeadersType>;
20
20
  errors: Partial<ConfigMiddlewareErrorsType>;
21
21
  skip_routers: string[];
22
- powerd_by: string;
22
+ powered_by: string;
23
23
  };
24
24
  type ConfigType = {
25
25
  url: string;
@@ -19,7 +19,7 @@ type ConfigMiddlewareType = {
19
19
  headers: Partial<ConfigMiddlewareHeadersType>;
20
20
  errors: Partial<ConfigMiddlewareErrorsType>;
21
21
  skip_routers: string[];
22
- powerd_by: string;
22
+ powered_by: string;
23
23
  };
24
24
  type ConfigType = {
25
25
  url: string;
@@ -0,0 +1,14 @@
1
+ function r(t,e){console[e].call(console,t)}import c from"axios";import{AxiosError as h}from"axios";function l(t){return t.replace(/([_\*\[\]\(\)~`>#+\-=|{}.!\\])/g,"\\$1")}var s=class{token;chat_id;obj;logger;constructor(e,o,n,a){if(!e||!o)throw new Error("Missing token or chat_id");this.token=e,this.chat_id=o,this.obj=n,this.logger=a}get request(){return c.create({baseURL:`https://api.telegram.org/bot${this.token}`})}methods={send_message:"/sendMessage"};sendMessage=async()=>{try{await this.request.post(this.methods.send_message,{chat_id:this.chat_id,text:l(`**[Server Side Error]:**
2
+
3
+ code:${this.obj.status_code}
4
+ method:${this.obj.method}
5
+ message:${this.obj.message}
6
+ request url: ${this.obj.originalUrl}
7
+
8
+ Time: ${new Date().toISOString()}`),parse_mode:"MarkdownV2"}),this.logger&&r("[Success Log]: Telegram Message Send","log")}catch(e){this.logger&&(e instanceof h?r(`[Error Log]: Error to send Telegram Message
9
+
10
+ Status: ${e.response?.status}
11
+ Data Error: ${e.response?.data}`,"error"):r(`[Error Log]: Error to send Telegram Message
12
+
13
+ Unknown Error: ${e.message}`,"error"))}}};export{s as a};
14
+ //# sourceMappingURL=chunk-EY444KLS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/logger.ts","../../src/network/telegram.ts"],"sourcesContent":["export default function Logger(log: string, type: keyof Console) {\r\n console[type].call(console, log);\r\n}\r\n","import { TelegramNetworkObjectType } from \"@/types/telegram\";\r\nimport Logger from \"@/utils/logger\";\r\nimport axios from \"axios\";\r\nimport { AxiosError } from \"axios\";\r\n\r\nfunction escapeMarkdownV2(text: string): string {\r\n return text.replace(/([_\\*\\[\\]\\(\\)~`>#+\\-=|{}.!\\\\])/g, \"\\\\$1\");\r\n}\r\n\r\nexport class TelegramNetwork {\r\n private token: string;\r\n private chat_id: string;\r\n private obj: TelegramNetworkObjectType;\r\n private logger?: boolean;\r\n\r\n constructor(\r\n token: string,\r\n chat_id: string,\r\n obj: TelegramNetworkObjectType,\r\n logger?: boolean\r\n ) {\r\n if (!token || !chat_id) throw new Error(\"Missing token or chat_id\");\r\n\r\n this.token = token;\r\n this.chat_id = chat_id;\r\n this.obj = obj;\r\n this.logger = logger;\r\n }\r\n\r\n private get request() {\r\n return axios.create({\r\n baseURL: `https://api.telegram.org/bot${this.token}`,\r\n });\r\n }\r\n\r\n private methods = {\r\n send_message: \"/sendMessage\",\r\n };\r\n\r\n sendMessage = async () => {\r\n try {\r\n await this.request.post(this.methods.send_message, {\r\n chat_id: this.chat_id,\r\n text: escapeMarkdownV2(\r\n `**[Server Side Error]:**\\n\\ncode:${this.obj.status_code}\\nmethod:${\r\n this.obj.method\r\n }\\nmessage:${this.obj.message}\\nrequest url: ${\r\n this.obj.originalUrl\r\n }\\n\\nTime: ${new Date().toISOString()}`\r\n ),\r\n parse_mode: \"MarkdownV2\",\r\n });\r\n\r\n if (this.logger) {\r\n Logger(\"[Success Log]: Telegram Message Send\", \"log\");\r\n }\r\n } catch (error) {\r\n if (this.logger) {\r\n if (error instanceof AxiosError) {\r\n Logger(\r\n `[Error Log]: Error to send Telegram Message\\n\\nStatus: ${error.response?.status}\\nData Error: ${error.response?.data}`,\r\n \"error\"\r\n );\r\n } else {\r\n Logger(\r\n `[Error Log]: Error to send Telegram Message\\n\\nUnknown Error: ${\r\n (error as Error).message\r\n }`,\r\n \"error\"\r\n );\r\n }\r\n }\r\n }\r\n };\r\n}\r\n"],"mappings":"AAAe,SAARA,EAAwBC,EAAaC,EAAqB,CAC/D,QAAQA,CAAI,EAAE,KAAK,QAASD,CAAG,CACjC,CCAA,OAAOE,MAAW,QAClB,OAAS,cAAAC,MAAkB,QAE3B,SAASC,EAAiBC,EAAsB,CAC9C,OAAOA,EAAK,QAAQ,kCAAmC,MAAM,CAC/D,CAEO,IAAMC,EAAN,KAAsB,CACnB,MACA,QACA,IACA,OAER,YACEC,EACAC,EACAC,EACAC,EACA,CACA,GAAI,CAACH,GAAS,CAACC,EAAS,MAAM,IAAI,MAAM,0BAA0B,EAElE,KAAK,MAAQD,EACb,KAAK,QAAUC,EACf,KAAK,IAAMC,EACX,KAAK,OAASC,CAChB,CAEA,IAAY,SAAU,CACpB,OAAOR,EAAM,OAAO,CAClB,QAAS,+BAA+B,KAAK,KAAK,EACpD,CAAC,CACH,CAEQ,QAAU,CAChB,aAAc,cAChB,EAEA,YAAc,SAAY,CACxB,GAAI,CACF,MAAM,KAAK,QAAQ,KAAK,KAAK,QAAQ,aAAc,CACjD,QAAS,KAAK,QACd,KAAME,EACJ;AAAA;AAAA,OAAoC,KAAK,IAAI,WAAW;AAAA,SACtD,KAAK,IAAI,MACX;AAAA,UAAa,KAAK,IAAI,OAAO;AAAA,eAC3B,KAAK,IAAI,WACX;AAAA;AAAA,QAAa,IAAI,KAAK,EAAE,YAAY,CAAC,EACvC,EACA,WAAY,YACd,CAAC,EAEG,KAAK,QACPO,EAAO,uCAAwC,KAAK,CAExD,OAASC,EAAO,CACV,KAAK,SACHA,aAAiBT,EACnBQ,EACE;AAAA;AAAA,UAA0DC,EAAM,UAAU,MAAM;AAAA,cAAiBA,EAAM,UAAU,IAAI,GACrH,OACF,EAEAD,EACE;AAAA;AAAA,iBACGC,EAAgB,OACnB,GACA,OACF,EAGN,CACF,CACF","names":["Logger","log","type","axios","AxiosError","escapeMarkdownV2","text","TelegramNetwork","token","chat_id","obj","logger","Logger","error"]}
@@ -0,0 +1,2 @@
1
+ var y=null;function E(c){y=c}function h(){return y}import n from"crypto";import d from"zlib";var b=c=>{let s=process.env.PRIVATE_KEY??c?.PRIVATE_KEY,i=process.env.PUBLIC_KEY??c?.PUBLIC_KEY;if(!s||!i)throw new Error(`Please set ${s?"PUBLIC_KEY":"PRIVATE_KEY"} in env file or set in ApiService Config`);return{encryptSecureBlob:p=>{let t=n.createECDH("secp256k1");t.setPrivateKey(Buffer.from(s,"base64"));let e=t.computeSecret(Buffer.from(i,"base64")).slice(0,32),r=n.randomBytes(12),f=n.createCipheriv("aes-256-gcm",e,r),a=Buffer.concat([f.update(p,"utf8"),f.final()]),o=f.getAuthTag(),g={version:"1",iv:r.toString("base64"),tag:o.toString("base64"),encrypted:a.toString("base64"),senderPublicKey:t.getPublicKey().toString("base64")},S=JSON.stringify(g);return d.gzipSync(Buffer.from(S,"utf8")).toString("hex")},decryptSecureBlob:p=>{let t=Buffer.from(p,"hex"),u=d.gunzipSync(t),e=JSON.parse(u.toString("utf8")),r=n.createECDH("secp256k1");r.setPrivateKey(Buffer.from(s,"base64"));let a=r.computeSecret(Buffer.from(i||e.senderPublicKey,"base64")).slice(0,32),o=n.createDecipheriv("aes-256-gcm",a,Buffer.from(e.iv,"base64"));return o.setAuthTag(Buffer.from(e.tag,"base64")),Buffer.concat([o.update(Buffer.from(e.encrypted,"base64")),o.final()]).toString("utf8")}}},T=b;export{E as a,h as b,T as c};
2
+ //# sourceMappingURL=chunk-OO3Q5EY3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/storage/index.ts","../../src/utils/enc.ts"],"sourcesContent":["// storage.ts\r\nimport { ConfigType } from \"@/types/config\";\r\n\r\nlet _configStorage: ConfigType | null = null;\r\n\r\nexport function setConfigStorage(config: ConfigType) {\r\n _configStorage = config;\r\n}\r\n\r\nexport function getConfigStorage(): ConfigType | null {\r\n return _configStorage;\r\n}\r\n","import { ConfigEnvType } from \"@/types/config\";\r\nimport crypto from \"crypto\";\r\nimport zlib from \"zlib\";\r\n\r\nconst Encrypt = (env?: ConfigEnvType) => {\r\n const MY_PRIV_KEY = process.env.PRIVATE_KEY ?? env?.PRIVATE_KEY;\r\n const THEIR_PUB_KEY = process.env.PUBLIC_KEY ?? env?.PUBLIC_KEY;\r\n\r\n if (!MY_PRIV_KEY || !THEIR_PUB_KEY)\r\n throw new Error(\r\n `Please set ${\r\n !MY_PRIV_KEY ? \"PRIVATE_KEY\" : \"PUBLIC_KEY\"\r\n } in env file or set in ApiService Config`\r\n );\r\n\r\n return {\r\n encryptSecureBlob: (message: string) => {\r\n const ecdh = crypto.createECDH(\"secp256k1\");\r\n ecdh.setPrivateKey(Buffer.from(MY_PRIV_KEY!, \"base64\"));\r\n\r\n const sharedSecret = ecdh.computeSecret(\r\n Buffer.from(THEIR_PUB_KEY!, \"base64\")\r\n );\r\n const key = sharedSecret.slice(0, 32);\r\n\r\n const iv = crypto.randomBytes(12);\r\n const cipher = crypto.createCipheriv(\"aes-256-gcm\", key, iv);\r\n\r\n const encrypted = Buffer.concat([\r\n cipher.update(message, \"utf8\"),\r\n cipher.final(),\r\n ]);\r\n const tag = cipher.getAuthTag();\r\n\r\n const blob = {\r\n version: \"1\",\r\n iv: iv.toString(\"base64\"),\r\n tag: tag.toString(\"base64\"),\r\n encrypted: encrypted.toString(\"base64\"),\r\n senderPublicKey: ecdh.getPublicKey().toString(\"base64\"),\r\n };\r\n\r\n const json = JSON.stringify(blob);\r\n const gzipped = zlib.gzipSync(Buffer.from(json, \"utf8\"));\r\n\r\n return gzipped.toString(\"hex\");\r\n },\r\n\r\n decryptSecureBlob: (blobHex: string) => {\r\n const gzippedBuffer = Buffer.from(blobHex, \"hex\");\r\n const jsonBuffer = zlib.gunzipSync(gzippedBuffer);\r\n const blob = JSON.parse(jsonBuffer.toString(\"utf8\"));\r\n\r\n const ecdh = crypto.createECDH(\"secp256k1\");\r\n ecdh.setPrivateKey(Buffer.from(MY_PRIV_KEY!, \"base64\"));\r\n\r\n const sharedSecret = ecdh.computeSecret(\r\n Buffer.from(THEIR_PUB_KEY || blob.senderPublicKey, \"base64\")\r\n );\r\n const key = sharedSecret.slice(0, 32);\r\n\r\n const decipher = crypto.createDecipheriv(\r\n \"aes-256-gcm\",\r\n key,\r\n Buffer.from(blob.iv, \"base64\")\r\n );\r\n decipher.setAuthTag(Buffer.from(blob.tag, \"base64\"));\r\n\r\n const decrypted = Buffer.concat([\r\n decipher.update(Buffer.from(blob.encrypted, \"base64\")),\r\n decipher.final(),\r\n ]);\r\n\r\n return decrypted.toString(\"utf8\");\r\n },\r\n };\r\n};\r\n\r\nexport default Encrypt;\r\n"],"mappings":"AAGA,IAAIA,EAAoC,KAEjC,SAASC,EAAiBC,EAAoB,CACnDF,EAAiBE,CACnB,CAEO,SAASC,GAAsC,CACpD,OAAOH,CACT,CCVA,OAAOI,MAAY,SACnB,OAAOC,MAAU,OAEjB,IAAMC,EAAWC,GAAwB,CACvC,IAAMC,EAAc,QAAQ,IAAI,aAAeD,GAAK,YAC9CE,EAAgB,QAAQ,IAAI,YAAcF,GAAK,WAErD,GAAI,CAACC,GAAe,CAACC,EACnB,MAAM,IAAI,MACR,cACGD,EAA8B,aAAhB,aACjB,0CACF,EAEF,MAAO,CACL,kBAAoBE,GAAoB,CACtC,IAAMC,EAAOP,EAAO,WAAW,WAAW,EAC1CO,EAAK,cAAc,OAAO,KAAKH,EAAc,QAAQ,CAAC,EAKtD,IAAMI,EAHeD,EAAK,cACxB,OAAO,KAAKF,EAAgB,QAAQ,CACtC,EACyB,MAAM,EAAG,EAAE,EAE9BI,EAAKT,EAAO,YAAY,EAAE,EAC1BU,EAASV,EAAO,eAAe,cAAeQ,EAAKC,CAAE,EAErDE,EAAY,OAAO,OAAO,CAC9BD,EAAO,OAAOJ,EAAS,MAAM,EAC7BI,EAAO,MAAM,CACf,CAAC,EACKE,EAAMF,EAAO,WAAW,EAExBG,EAAO,CACX,QAAS,IACT,GAAIJ,EAAG,SAAS,QAAQ,EACxB,IAAKG,EAAI,SAAS,QAAQ,EAC1B,UAAWD,EAAU,SAAS,QAAQ,EACtC,gBAAiBJ,EAAK,aAAa,EAAE,SAAS,QAAQ,CACxD,EAEMO,EAAO,KAAK,UAAUD,CAAI,EAGhC,OAFgBZ,EAAK,SAAS,OAAO,KAAKa,EAAM,MAAM,CAAC,EAExC,SAAS,KAAK,CAC/B,EAEA,kBAAoBC,GAAoB,CACtC,IAAMC,EAAgB,OAAO,KAAKD,EAAS,KAAK,EAC1CE,EAAahB,EAAK,WAAWe,CAAa,EAC1CH,EAAO,KAAK,MAAMI,EAAW,SAAS,MAAM,CAAC,EAE7CV,EAAOP,EAAO,WAAW,WAAW,EAC1CO,EAAK,cAAc,OAAO,KAAKH,EAAc,QAAQ,CAAC,EAKtD,IAAMI,EAHeD,EAAK,cACxB,OAAO,KAAKF,GAAiBQ,EAAK,gBAAiB,QAAQ,CAC7D,EACyB,MAAM,EAAG,EAAE,EAE9BK,EAAWlB,EAAO,iBACtB,cACAQ,EACA,OAAO,KAAKK,EAAK,GAAI,QAAQ,CAC/B,EACA,OAAAK,EAAS,WAAW,OAAO,KAAKL,EAAK,IAAK,QAAQ,CAAC,EAEjC,OAAO,OAAO,CAC9BK,EAAS,OAAO,OAAO,KAAKL,EAAK,UAAW,QAAQ,CAAC,EACrDK,EAAS,MAAM,CACjB,CAAC,EAEgB,SAAS,MAAM,CAClC,CACF,CACF,EAEOC,EAAQjB","names":["_configStorage","setConfigStorage","config","getConfigStorage","crypto","zlib","Encrypt","env","MY_PRIV_KEY","THEIR_PUB_KEY","message","ecdh","key","iv","cipher","encrypted","tag","blob","json","blobHex","gzippedBuffer","jsonBuffer","decipher","enc_default"]}
@@ -0,0 +1,2 @@
1
+ import{a as p}from"./chunk-EY444KLS.js";import{b as y,c as l}from"./chunk-OO3Q5EY3.js";import h from"jsonwebtoken";import{gunzipSync as T,gzipSync as v}from"zlib";var{verify:b}=h,E=async(e,o)=>{let t=process.env.TELEGRAM_TOKEN,r=process.env.TELEGRAM_CHAT_ID;if(!t||!r)throw new Error("Token or Chat ID is missing in TelegramNetwork");return await new p(t,r,{...e},o).sendMessage()},c=async(e,o,t)=>{let r=t.middleware?.powered_by??"alyvro/api-service";t.setting?.telegram&&await E({message:t.middleware?.errors?.forbidden??"no access to this api",method:e.method,originalUrl:e.originalUrl,status_code:"403"},t.logger),o.status(403).json({message:t.middleware?.errors?.forbidden??"no access to this api",status:403,powered_by:r})};async function _(e,o,t){let r=y();if(r?.middleware?.skip_routers?.length&&r.middleware.skip_routers.includes(e.path))return t();if(!r)throw new Error("Config no install");let n=process.env.PRIVATE_KET??r.env?.PRIVATE_KEY;if(!n||typeof n!="string")throw new Error("Please set Private Key in env file or apiService config");try{if(!e.headers[r.middleware?.headers?.status??"x-alyvro-status"]){c(e,o,r);return}let d=e.headers[r.middleware?.headers?.apiKey??"x-alyvro-api-key"],m=e.headers[r.middleware?.headers?.bodyType??"x-alyvro-body-type"];if(!d||typeof d!="string"){c(e,o,r);return}let{decryptSecureBlob:f}=l(r.env);b(d,n);let i=e.body;if(e.headers["content-encoding"]==="gzip"&&Buffer.isBuffer(i))try{i=T(i).toString("utf-8")}catch(s){console.error("Failed to decompress gzip body:",s)}if(m==="sec"){let s=f(e.body);try{s=JSON.parse(s)}catch{}e.body=s}else e.body=i;let g=o.json.bind(o);return o.json=s=>{if(e.headers["accept-encoding"]?.includes("gzip")){try{let a=v(Buffer.from(JSON.stringify(s),"utf-8"));return o.setHeader("Content-Encoding","gzip"),o.setHeader("Content-Type","application/json"),o.send(a),o}catch(a){console.error("Failed to compress response:",a)}return g()}},t()}catch{c(e,o,r);return}}export{_ as middleware};
2
+ //# sourceMappingURL=express.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/middleware.ts"],"sourcesContent":["import type { TelegramNetworkObjectType } from \"@/types/telegram\";\r\nimport type { NextFunction, Request, Response } from \"express\";\r\n\r\nimport { TelegramNetwork } from \"@/network/telegram\";\r\nimport { getConfigStorage } from \"@/storage\";\r\nimport Encrypt from \"@/utils/enc\";\r\nimport jwt from \"jsonwebtoken\";\r\nimport { gunzipSync, gzipSync } from \"zlib\";\r\nimport { ConfigType } from \"main/types\";\r\n\r\nconst { verify } = jwt;\r\n\r\nconst sendTelegramMessage = async (\r\n request_info: TelegramNetworkObjectType,\r\n logger?: boolean,\r\n) => {\r\n const token = process.env.TELEGRAM_TOKEN;\r\n const chat_id = process.env.TELEGRAM_CHAT_ID;\r\n\r\n if (!token || !chat_id) {\r\n throw new Error(\"Token or Chat ID is missing in TelegramNetwork\");\r\n }\r\n\r\n const response = new TelegramNetwork(\r\n token,\r\n chat_id,\r\n {\r\n ...request_info,\r\n },\r\n logger,\r\n );\r\n\r\n return await response.sendMessage();\r\n};\r\n\r\nconst sendErrorMessage = async (\r\n req: Request,\r\n res: Response,\r\n config: ConfigType,\r\n) => {\r\n const powered_by = config.middleware?.powered_by ?? \"alyvro/api-service\";\r\n\r\n if (config.setting?.telegram) {\r\n await sendTelegramMessage(\r\n {\r\n message:\r\n config.middleware?.errors?.forbidden ?? \"no access to this api\",\r\n method: req.method,\r\n originalUrl: req.originalUrl,\r\n status_code: \"403\",\r\n },\r\n config.logger,\r\n );\r\n }\r\n\r\n res.status(403).json({\r\n message: config.middleware?.errors?.forbidden ?? \"no access to this api\",\r\n status: 403,\r\n powered_by,\r\n });\r\n};\r\n\r\nexport async function middleware(\r\n req: Request,\r\n res: Response,\r\n next: NextFunction,\r\n) {\r\n const config = getConfigStorage();\r\n\r\n if (\r\n config?.middleware?.skip_routers?.length &&\r\n config.middleware.skip_routers.includes(req.path)\r\n ) {\r\n return next();\r\n }\r\n\r\n if (!config) throw new Error(\"Config no install\");\r\n\r\n const privateKey = process.env.PRIVATE_KET ?? config.env?.PRIVATE_KEY;\r\n\r\n if (!privateKey || typeof privateKey !== \"string\")\r\n throw new Error(\"Please set Private Key in env file or apiService config\");\r\n\r\n try {\r\n const alyvroStatus =\r\n req.headers[config.middleware?.headers?.status ?? \"x-alyvro-status\"];\r\n\r\n if (!alyvroStatus) {\r\n sendErrorMessage(req, res, config);\r\n\r\n return;\r\n }\r\n\r\n const alyvroKey =\r\n req.headers[config.middleware?.headers?.apiKey ?? \"x-alyvro-api-key\"];\r\n const alyvroBodyType =\r\n req.headers[config.middleware?.headers?.bodyType ?? \"x-alyvro-body-type\"];\r\n\r\n if (!alyvroKey || typeof alyvroKey !== \"string\") {\r\n sendErrorMessage(req, res, config);\r\n return;\r\n }\r\n\r\n const { decryptSecureBlob } = Encrypt(config.env);\r\n\r\n verify(alyvroKey, privateKey);\r\n\r\n let bodyData = req.body;\r\n\r\n if (\r\n req.headers[\"content-encoding\"] === \"gzip\" &&\r\n Buffer.isBuffer(bodyData)\r\n ) {\r\n try {\r\n bodyData = gunzipSync(bodyData).toString(\"utf-8\");\r\n } catch (err) {\r\n console.error(\"Failed to decompress gzip body:\", err);\r\n }\r\n }\r\n\r\n if (alyvroBodyType === \"sec\") {\r\n let decode = decryptSecureBlob(req.body);\r\n\r\n try {\r\n decode = JSON.parse(decode);\r\n } catch (error) {}\r\n\r\n req.body = decode;\r\n } else {\r\n req.body = bodyData;\r\n }\r\n\r\n const originalJson = res.json.bind(res);\r\n res.json = (data) => {\r\n if (req.headers[\"accept-encoding\"]?.includes(\"gzip\")) {\r\n try {\r\n const compressed = gzipSync(\r\n Buffer.from(JSON.stringify(data), \"utf-8\"),\r\n );\r\n res.setHeader(\"Content-Encoding\", \"gzip\");\r\n res.setHeader(\"Content-Type\", \"application/json\");\r\n res.send(compressed);\r\n return res;\r\n } catch (error) {\r\n console.error(\"Failed to compress response:\", error);\r\n }\r\n\r\n return originalJson();\r\n }\r\n };\r\n\r\n return next();\r\n } catch {\r\n sendErrorMessage(req, res, config);\r\n return;\r\n }\r\n}\r\n"],"mappings":"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","names":["jwt","gunzipSync","gzipSync","verify","sendTelegramMessage","request_info","logger","token","chat_id","TelegramNetwork","sendErrorMessage","req","res","config","powered_by","middleware","next","getConfigStorage","privateKey","alyvroKey","alyvroBodyType","decryptSecureBlob","enc_default","bodyData","err","decode","originalJson","data","compressed","error"]}
@@ -0,0 +1,2 @@
1
+ import{a as f}from"./chunk-EY444KLS.js";import{b as y,c as m}from"./chunk-OO3Q5EY3.js";import v from"jsonwebtoken";import{gunzipSync as T,gzipSync as b}from"zlib";var{verify:E}=v,S=async(r,t)=>{let e=process.env.TELEGRAM_TOKEN,s=process.env.TELEGRAM_CHAT_ID;if(!e||!s)throw new Error("Token or Chat ID is missing in TelegramNetwork");return await new f(e,s,{...r},t).sendMessage()},d=async(r,t,e)=>{let s=e.middleware?.powered_by??"alyvro/api-service";e.setting?.telegram&&await S({message:e.middleware?.errors?.forbidden??"no access to this api",method:r.method,originalUrl:r.url,status_code:"403"},e.logger),t.status(403).send({message:e.middleware?.errors?.forbidden??"no access to this api",status:403,powered_by:s})};async function _(r,t){let e=y();if(e?.middleware?.skip_routers?.length&&e.middleware.skip_routers.includes(r.routerPath))return;if(!e)throw new Error("Config no install");let s=process.env.PRIVATE_KET??e.env?.PRIVATE_KEY;if(!s||typeof s!="string")throw new Error("Please set Private Key in env file or apiService config");try{if(!r.headers[e.middleware?.headers?.status??"x-alyvro-status"]){await d(r,t,e);return}let a=r.headers[e.middleware?.headers?.apiKey??"x-alyvro-api-key"],l=r.headers[e.middleware?.headers?.bodyType??"x-alyvro-body-type"];if(!a||typeof a!="string"){await d(r,t,e);return}let{decryptSecureBlob:u}=m(e.env);E(a,s);let i=r.body;if(r.headers["content-encoding"]==="gzip"&&Buffer.isBuffer(i))try{i=T(i).toString("utf-8")}catch(o){console.error("Failed to decompress gzip body:",o)}if(l==="sec"){let o=u(r.body);try{o=JSON.parse(o)}catch{}r.body=o}else r.body=i;let c=t.send.bind(t);t.send=function(o){if(r.headers["accept-encoding"]?.includes("gzip"))try{let n;Buffer.isBuffer(o)?n=o:typeof o=="string"?n=Buffer.from(o,"utf-8"):(n=Buffer.from(JSON.stringify(o),"utf-8"),t.header("Content-Type","application/json"));let g=b(n);return t.header("Content-Encoding","gzip"),t.removeHeader("Content-Length"),c(g)}catch(n){console.error("Failed to compress response:",n)}return c(o)}}catch{await d(r,t,e);return}}export{_ as middleware};
2
+ //# sourceMappingURL=fastify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/fastify/middleware.ts"],"sourcesContent":["import { FastifyReply, FastifyRequest } from \"fastify\";\r\nimport { TelegramNetwork } from \"@/network/telegram\";\r\nimport { getConfigStorage } from \"@/storage\";\r\nimport Encrypt from \"@/utils/enc\";\r\nimport jwt from \"jsonwebtoken\";\r\nimport { gunzipSync, gzipSync } from \"zlib\";\r\nimport { ConfigType } from \"main/types\";\r\nimport { TelegramNetworkObjectType } from \"@/types/telegram\";\r\n\r\nconst { verify } = jwt;\r\n\r\nconst sendTelegramMessage = async (\r\n request_info: TelegramNetworkObjectType,\r\n logger?: boolean,\r\n) => {\r\n const token = process.env.TELEGRAM_TOKEN;\r\n const chat_id = process.env.TELEGRAM_CHAT_ID;\r\n\r\n if (!token || !chat_id) {\r\n throw new Error(\"Token or Chat ID is missing in TelegramNetwork\");\r\n }\r\n\r\n const response = new TelegramNetwork(\r\n token,\r\n chat_id,\r\n {\r\n ...request_info,\r\n },\r\n logger,\r\n );\r\n\r\n return await response.sendMessage();\r\n};\r\n\r\nconst sendErrorMessage = async (\r\n req: FastifyRequest,\r\n reply: FastifyReply,\r\n config: ConfigType,\r\n) => {\r\n const powered_by = config.middleware?.powered_by ?? \"alyvro/api-service\";\r\n\r\n if (config.setting?.telegram) {\r\n await sendTelegramMessage(\r\n {\r\n message:\r\n config.middleware?.errors?.forbidden ?? \"no access to this api\",\r\n method: req.method,\r\n originalUrl: req.url,\r\n status_code: \"403\",\r\n },\r\n config.logger,\r\n );\r\n }\r\n\r\n reply.status(403).send({\r\n message: config.middleware?.errors?.forbidden ?? \"no access to this api\",\r\n status: 403,\r\n powered_by,\r\n });\r\n};\r\n\r\nexport async function middleware(req: FastifyRequest, reply: FastifyReply) {\r\n const config = getConfigStorage();\r\n\r\n if (\r\n config?.middleware?.skip_routers?.length &&\r\n config.middleware.skip_routers.includes(req.routerPath)\r\n ) {\r\n return;\r\n }\r\n\r\n if (!config) throw new Error(\"Config no install\");\r\n\r\n const privateKey = process.env.PRIVATE_KET ?? config.env?.PRIVATE_KEY;\r\n\r\n if (!privateKey || typeof privateKey !== \"string\")\r\n throw new Error(\"Please set Private Key in env file or apiService config\");\r\n\r\n try {\r\n const alyvroStatus =\r\n req.headers[config.middleware?.headers?.status ?? \"x-alyvro-status\"];\r\n\r\n if (!alyvroStatus) {\r\n await sendErrorMessage(req, reply, config);\r\n return;\r\n }\r\n\r\n const alyvroKey =\r\n req.headers[config.middleware?.headers?.apiKey ?? \"x-alyvro-api-key\"];\r\n const alyvroBodyType =\r\n req.headers[config.middleware?.headers?.bodyType ?? \"x-alyvro-body-type\"];\r\n\r\n if (!alyvroKey || typeof alyvroKey !== \"string\") {\r\n await sendErrorMessage(req, reply, config);\r\n return;\r\n }\r\n\r\n const { decryptSecureBlob } = Encrypt(config.env);\r\n\r\n verify(alyvroKey, privateKey);\r\n\r\n let bodyData = req.body;\r\n\r\n if (\r\n req.headers[\"content-encoding\"] === \"gzip\" &&\r\n Buffer.isBuffer(bodyData)\r\n ) {\r\n try {\r\n bodyData = gunzipSync(bodyData).toString(\"utf-8\");\r\n } catch (err) {\r\n console.error(\"Failed to decompress gzip body:\", err);\r\n }\r\n }\r\n\r\n if (alyvroBodyType === \"sec\") {\r\n let decode = decryptSecureBlob(req.body as any);\r\n\r\n try {\r\n decode = JSON.parse(decode);\r\n } catch (error) {}\r\n\r\n req.body = decode;\r\n } else {\r\n req.body = bodyData;\r\n }\r\n\r\n const originalSend = reply.send.bind(reply);\r\n\r\n reply.send = function (payload: unknown) {\r\n if (req.headers[\"accept-encoding\"]?.includes(\"gzip\")) {\r\n try {\r\n let bufferData: Buffer;\r\n\r\n if (Buffer.isBuffer(payload)) {\r\n bufferData = payload;\r\n } else if (typeof payload === \"string\") {\r\n bufferData = Buffer.from(payload, \"utf-8\");\r\n } else {\r\n bufferData = Buffer.from(JSON.stringify(payload), \"utf-8\");\r\n reply.header(\"Content-Type\", \"application/json\");\r\n }\r\n\r\n const compressed = gzipSync(bufferData);\r\n reply.header(\"Content-Encoding\", \"gzip\");\r\n reply.removeHeader(\"Content-Length\");\r\n\r\n return originalSend(compressed);\r\n } catch (error) {\r\n console.error(\"Failed to compress response:\", error);\r\n }\r\n }\r\n return originalSend(payload);\r\n } as any;\r\n } catch {\r\n await sendErrorMessage(req, reply, config);\r\n return;\r\n }\r\n}\r\n"],"mappings":"uFAIA,OAAOA,MAAS,eAChB,OAAS,cAAAC,EAAY,YAAAC,MAAgB,OAIrC,GAAM,CAAE,OAAAC,CAAO,EAAIH,EAEbI,EAAsB,MAC1BC,EACAC,IACG,CACH,IAAMC,EAAQ,QAAQ,IAAI,eACpBC,EAAU,QAAQ,IAAI,iBAE5B,GAAI,CAACD,GAAS,CAACC,EACb,MAAM,IAAI,MAAM,gDAAgD,EAYlE,OAAO,MATU,IAAIC,EACnBF,EACAC,EACA,CACE,GAAGH,CACL,EACAC,CACF,EAEsB,YAAY,CACpC,EAEMI,EAAmB,MACvBC,EACAC,EACAC,IACG,CACH,IAAMC,EAAaD,EAAO,YAAY,YAAc,qBAEhDA,EAAO,SAAS,UAClB,MAAMT,EACJ,CACE,QACES,EAAO,YAAY,QAAQ,WAAa,wBAC1C,OAAQF,EAAI,OACZ,YAAaA,EAAI,IACjB,YAAa,KACf,EACAE,EAAO,MACT,EAGFD,EAAM,OAAO,GAAG,EAAE,KAAK,CACrB,QAASC,EAAO,YAAY,QAAQ,WAAa,wBACjD,OAAQ,IACR,WAAAC,CACF,CAAC,CACH,EAEA,eAAsBC,EAAWJ,EAAqBC,EAAqB,CACzE,IAAMC,EAASG,EAAiB,EAEhC,GACEH,GAAQ,YAAY,cAAc,QAClCA,EAAO,WAAW,aAAa,SAASF,EAAI,UAAU,EAEtD,OAGF,GAAI,CAACE,EAAQ,MAAM,IAAI,MAAM,mBAAmB,EAEhD,IAAMI,EAAa,QAAQ,IAAI,aAAeJ,EAAO,KAAK,YAE1D,GAAI,CAACI,GAAc,OAAOA,GAAe,SACvC,MAAM,IAAI,MAAM,yDAAyD,EAE3E,GAAI,CAIF,GAAI,CAFFN,EAAI,QAAQE,EAAO,YAAY,SAAS,QAAU,iBAAiB,EAElD,CACjB,MAAMH,EAAiBC,EAAKC,EAAOC,CAAM,EACzC,MACF,CAEA,IAAMK,EACJP,EAAI,QAAQE,EAAO,YAAY,SAAS,QAAU,kBAAkB,EAChEM,EACJR,EAAI,QAAQE,EAAO,YAAY,SAAS,UAAY,oBAAoB,EAE1E,GAAI,CAACK,GAAa,OAAOA,GAAc,SAAU,CAC/C,MAAMR,EAAiBC,EAAKC,EAAOC,CAAM,EACzC,MACF,CAEA,GAAM,CAAE,kBAAAO,CAAkB,EAAIC,EAAQR,EAAO,GAAG,EAEhDV,EAAOe,EAAWD,CAAU,EAE5B,IAAIK,EAAWX,EAAI,KAEnB,GACEA,EAAI,QAAQ,kBAAkB,IAAM,QACpC,OAAO,SAASW,CAAQ,EAExB,GAAI,CACFA,EAAWrB,EAAWqB,CAAQ,EAAE,SAAS,OAAO,CAClD,OAASC,EAAK,CACZ,QAAQ,MAAM,kCAAmCA,CAAG,CACtD,CAGF,GAAIJ,IAAmB,MAAO,CAC5B,IAAIK,EAASJ,EAAkBT,EAAI,IAAW,EAE9C,GAAI,CACFa,EAAS,KAAK,MAAMA,CAAM,CAC5B,MAAgB,CAAC,CAEjBb,EAAI,KAAOa,CACb,MACEb,EAAI,KAAOW,EAGb,IAAMG,EAAeb,EAAM,KAAK,KAAKA,CAAK,EAE1CA,EAAM,KAAO,SAAUc,EAAkB,CACvC,GAAIf,EAAI,QAAQ,iBAAiB,GAAG,SAAS,MAAM,EACjD,GAAI,CACF,IAAIgB,EAEA,OAAO,SAASD,CAAO,EACzBC,EAAaD,EACJ,OAAOA,GAAY,SAC5BC,EAAa,OAAO,KAAKD,EAAS,OAAO,GAEzCC,EAAa,OAAO,KAAK,KAAK,UAAUD,CAAO,EAAG,OAAO,EACzDd,EAAM,OAAO,eAAgB,kBAAkB,GAGjD,IAAMgB,EAAa1B,EAASyB,CAAU,EACtC,OAAAf,EAAM,OAAO,mBAAoB,MAAM,EACvCA,EAAM,aAAa,gBAAgB,EAE5Ba,EAAaG,CAAU,CAChC,OAASC,EAAO,CACd,QAAQ,MAAM,+BAAgCA,CAAK,CACrD,CAEF,OAAOJ,EAAaC,CAAO,CAC7B,CACF,MAAQ,CACN,MAAMhB,EAAiBC,EAAKC,EAAOC,CAAM,EACzC,MACF,CACF","names":["jwt","gunzipSync","gzipSync","verify","sendTelegramMessage","request_info","logger","token","chat_id","TelegramNetwork","sendErrorMessage","req","reply","config","powered_by","middleware","getConfigStorage","privateKey","alyvroKey","alyvroBodyType","decryptSecureBlob","enc_default","bodyData","err","decode","originalSend","payload","bufferData","compressed","error"]}
package/dist/esm/index.js CHANGED
@@ -1,15 +1,3 @@
1
- import{a as _,b as C,c as A}from"./chunk-TSDIGLLM.js";import"axios";import g from"crypto";import I from"zlib";var k=t=>{let e=process.env.PRIVATE_KEY??t?.PRIVATE_KEY,r=process.env.PUBLIC_KEY??t?.PUBLIC_KEY;if(!e||!r)throw new Error(`Please set ${e?"PUBLIC_KEY":"PRIVATE_KEY"} in env file or set in ApiService Config`);return{encryptSecureBlob:o=>{let a=g.createECDH("secp256k1");a.setPrivateKey(Buffer.from(e,"base64"));let i=a.computeSecret(Buffer.from(r,"base64")).slice(0,32),p=g.randomBytes(12),c=g.createCipheriv("aes-256-gcm",i,p),n=Buffer.concat([c.update(o,"utf8"),c.final()]),f=c.getAuthTag(),y={version:"1",iv:p.toString("base64"),tag:f.toString("base64"),encrypted:n.toString("base64"),senderPublicKey:a.getPublicKey().toString("base64")},l=JSON.stringify(y);return I.gzipSync(Buffer.from(l,"utf8")).toString("hex")},decryptSecureBlob:o=>{let a=Buffer.from(o,"hex"),s=I.gunzipSync(a),i=JSON.parse(s.toString("utf8")),p=g.createECDH("secp256k1");p.setPrivateKey(Buffer.from(e,"base64"));let n=p.computeSecret(Buffer.from(r||i.senderPublicKey,"base64")).slice(0,32),f=g.createDecipheriv("aes-256-gcm",n,Buffer.from(i.iv,"base64"));return f.setAuthTag(Buffer.from(i.tag,"base64")),Buffer.concat([f.update(Buffer.from(i.encrypted,"base64")),f.final()]).toString("utf8")}}},b=k;import M from"axios";import j from"jsonwebtoken";import{gunzipSync as Y,gzipSync as N}from"zlib";var{sign:O}=j;function B(t,e,r,o){let a=M.create({baseURL:t,auth:e});return a.interceptors.request.use(s=>{let{encryptSecureBlob:i}=b(r),p=s.secret;if(s.headers[o?.headers?.apiKey??"x-alyvro-api-key"]=O({data:"alyvro-secret-api-service"},r?.PRIVATE_KEY,{expiresIn:"10min"}),s.headers[o?.headers?.bodyType??"x-alyvro-body-type"]=p?.body?"sec":"none",s.headers[o?.headers?.status??"x-alyvro-status"]=s.status??!0,s.plugins?.compressor&&s?.data){let c=JSON.stringify(s.data);s.data=N(c),s.headers["Content-Encoding"]="gzip"}return p?.body&&s?.data&&(s.data=i(typeof s.data=="string"?s.data:JSON.stringify(s.data))),s}),a.interceptors.response.use(s=>{let i=s.data;if(s.headers["content-encoding"]==="gzip"&&Buffer.isBuffer(s.data))try{i=JSON.parse(Y(s.data).toString("utf-8"))}catch(c){console.error("Failed to decompress response",c)}let p=i;if(s.config?.plugins?.cache){let c=s.config.url;return{...s,data:s.config.plugins.cache.set(c,p)}}return{...s,data:p}}),_(a),a}var m=class extends Error{status;statusText;data;response_return_status_check;config;constructor(e,r,o,a){super(`Request failed with status ${e}`),this.status=e,this.statusText=r,this.data=o,this.config=a}};var P=null;function K(t){P=t}function T(){return P}import z from"jsonwebtoken";var{sign:L}=z;async function w(t,e){let r=T();if(!r)throw new Error("please set config");let{url:o,auth:a,env:s}=r,p={...e,headers:(()=>{let n=new Headers(e?.headers);return n.set(r.middleware?.headers?.apiKey??"x-alyvro-api-key",L({data:"alyvro-secret-api-service"},s?.PRIVATE_KEY,{expiresIn:"10min"})),n.set(r.middleware?.headers?.bodyType??"x-alyvro-body-type","none"),n.set(r.middleware?.headers?.status??"x-alyvro-status",String(e?.status??!0)),a?.username&&a?.password&&n.set("Authorization","Basic "+Buffer.from(`${a.username}:${a.password}`).toString("base64")),e?.method==="POST"&&n.set("Content-Type","application/json"),n})(),...e?.body?{body:typeof e.body=="string"?e.body:JSON.stringify(e.body)}:void 0},c=o.concat(t);if(e?.response_return){let n=await fetch(c,p);if(!e.response_return_status_check&&!n.ok){let f=await n.json();throw new m(n.status,n.statusText,f,e)}if(e.response_return_status_check&&e.response_return_status_check!==n.status){let f=await n.json();throw new m(n.status,n.statusText,f,e)}return await n.json()}return fetch(c,p)}function h(t,e){console[e].call(console,t)}import U from"axios";import{AxiosError as $}from"axios";function D(t){return t.replace(/([_\*\[\]\(\)~`>#+\-=|{}.!\\])/g,"\\$1")}var v=class{token;chat_id;obj;logger;constructor(e,r,o,a){if(!e||!r)throw new Error("Missing token or chat_id");this.token=e,this.chat_id=r,this.obj=o,this.logger=a}get request(){return U.create({baseURL:`https://api.telegram.org/bot${this.token}`})}methods={send_message:"/sendMessage"};sendMessage=async()=>{try{await this.request.post(this.methods.send_message,{chat_id:this.chat_id,text:D(`**[Server Side Error]:**
2
-
3
- code:${this.obj.status_code}
4
- method:${this.obj.method}
5
- message:${this.obj.message}
6
- request url: ${this.obj.originalUrl}
7
-
8
- Time: ${new Date().toISOString()}`),parse_mode:"MarkdownV2"}),this.logger&&h("[Success Log]: Telegram Message Send","log")}catch(e){this.logger&&(e instanceof $?h(`[Error Log]: Error to send Telegram Message
9
-
10
- Status: ${e.response?.status}
11
- Data Error: ${e.response?.data}`,"error"):h(`[Error Log]: Error to send Telegram Message
12
-
13
- Unknown Error: ${e.message}`,"error"))}}};import V from"jsonwebtoken";import{gunzipSync as q,gzipSync as F}from"zlib";var{verify:H}=V,J=async(t,e)=>{let r=process.env.TELEGRAM_TOKEN,o=process.env.TELEGRAM_CHAT_ID;if(!r||!o)throw new Error("Token or Chat ID is missing in TelegramNetwork");return await new v(r,o,{...t},e).sendMessage()},x=async(t,e,r)=>{let o=r.middleware?.powerd_by??"alyvro/api-service";r.setting?.telegram&&await J({message:r.middleware?.errors?.forbidden??"no access to this api",method:t.method,originalUrl:t.originalUrl,status_code:"403"},r.logger),e.status(403).json({message:r.middleware?.errors?.forbidden??"no access to this api",status:403,powerd_by:o})};async function S(t,e,r){let o=T();if(o?.middleware?.skip_routers?.length&&o.middleware.skip_routers.includes(t.path))return r();if(!o)throw new Error("Config no install");let a=process.env.PRIVATE_KET??o.env?.PRIVATE_KEY;if(!a||typeof a!="string")throw new Error("Please set Private Key in env file or apiService config");try{if(!t.headers[o.middleware?.headers?.status??"x-alyvro-status"]){x(t,e,o);return}let i=t.headers[o.middleware?.headers?.apiKey??"x-alyvro-api-key"],p=t.headers[o.middleware?.headers?.bodyType??"x-alyvro-body-type"];if(!i||typeof i!="string"){x(t,e,o);return}let{decryptSecureBlob:c}=b(o.env);H(i,a);let n=t.body;if(t.headers["content-encoding"]==="gzip"&&Buffer.isBuffer(n))try{n=q(n).toString("utf-8")}catch(y){console.error("Failed to decompress gzip body:",y)}if(p==="sec"){let y=c(t.body);try{y=JSON.parse(y)}catch{}t.body=y}else t.body=n;let f=e.json.bind(e);return e.json=y=>{if(t.headers["accept-encoding"]?.includes("gzip")){try{let l=F(Buffer.from(JSON.stringify(y),"utf-8"));return e.setHeader("Content-Encoding","gzip"),e.setHeader("Content-Type","application/json"),e.send(l),e}catch(l){console.error("Failed to compress response:",l)}return f()}},r()}catch{x(t,e,o);return}}var E=class{data;constructor(e){this.data=e}};var R=class extends E{constructor(e){super(e);let r=e.env?.PRIVATE_KEY??process.env.PRIVATE_KEY,o=e.env?.PUBLIC_KEY??process.env.PUBLIC_KEY;if(!r||!o)throw new Error(`Error to get ${r?"PRIVATE_KEY":"PUBLIC_KEY"}
14
- please set on .env config or in ApiService options`);K({...e,env:{PRIVATE_KEY:r,PUBLIC_KEY:o}})}get client(){return{axios:{request:()=>B(this.data.url,this.data.auth,this.data.env,this.data.middleware)},fetch:{request:w}}}get server(){return{middleware:S}}static get plugins(){return{cache:{server:A}}}static get storages(){return{server:{cache:C}}}};export{R as ApiService};
1
+ import{a as g,b as x,c as T}from"./chunk-OO3Q5EY3.js";import{a as v,b as R,c as b}from"./chunk-TSDIGLLM.js";import"axios";import C from"axios";import E from"jsonwebtoken";import{gunzipSync as w,gzipSync as I}from"zlib";var{sign:_}=E;function A(u,t,s,o){let a=C.create({baseURL:u,auth:t});return a.interceptors.request.use(e=>{let{encryptSecureBlob:y}=T(s),n=e.secret;if(e.headers[o?.headers?.apiKey??"x-alyvro-api-key"]=_({data:"alyvro-secret-api-service"},s?.PRIVATE_KEY,{expiresIn:"10min"}),e.headers[o?.headers?.bodyType??"x-alyvro-body-type"]=n?.body?"sec":"none",e.headers[o?.headers?.status??"x-alyvro-status"]=e.status??!0,e.plugins?.compressor&&e?.data){let i=JSON.stringify(e.data);e.data=I(i),e.headers["Content-Encoding"]="gzip"}return n?.body&&e?.data&&(e.data=y(typeof e.data=="string"?e.data:JSON.stringify(e.data))),e}),a.interceptors.response.use(e=>{let y=e.data;if(e.headers["content-encoding"]==="gzip"&&Buffer.isBuffer(e.data))try{y=JSON.parse(w(e.data).toString("utf-8"))}catch(i){console.error("Failed to decompress response",i)}let n=y;if(e.config?.plugins?.cache){let i=e.config.url;return{...e,data:e.config.plugins.cache.set(i,n)}}return{...e,data:n}}),v(a),a}var d=class extends Error{status;statusText;data;response_return_status_check;config;constructor(t,s,o,a){super(`Request failed with status ${t}`),this.status=t,this.statusText=s,this.data=o,this.config=a}};import P from"jsonwebtoken";var{sign:S}=P;async function m(u,t){let s=x();if(!s)throw new Error("please set config");let{url:o,auth:a,env:e}=s,n={...t,headers:(()=>{let r=new Headers(t?.headers);return r.set(s.middleware?.headers?.apiKey??"x-alyvro-api-key",S({data:"alyvro-secret-api-service"},e?.PRIVATE_KEY,{expiresIn:"10min"})),r.set(s.middleware?.headers?.bodyType??"x-alyvro-body-type","none"),r.set(s.middleware?.headers?.status??"x-alyvro-status",String(t?.status??!0)),a?.username&&a?.password&&r.set("Authorization","Basic "+Buffer.from(`${a.username}:${a.password}`).toString("base64")),t?.method==="POST"&&r.set("Content-Type","application/json"),r})(),...t?.body?{body:typeof t.body=="string"?t.body:JSON.stringify(t.body)}:void 0},i=o.concat(u);if(t?.response_return){let r=await fetch(i,n);if(!t.response_return_status_check&&!r.ok){let l=await r.json();throw new d(r.status,r.statusText,l,t)}if(t.response_return_status_check&&t.response_return_status_check!==r.status){let l=await r.json();throw new d(r.status,r.statusText,l,t)}return await r.json()}return fetch(i,n)}var f=class{data;constructor(t){this.data=t}};var h=class extends f{constructor(t){super(t);let s=t.env?.PRIVATE_KEY??process.env.PRIVATE_KEY,o=t.env?.PUBLIC_KEY??process.env.PUBLIC_KEY;if(!s||!o)throw new Error(`Error to get ${s?"PRIVATE_KEY":"PUBLIC_KEY"}
2
+ please set on .env config or in ApiService options`);g({...t,env:{PRIVATE_KEY:s,PUBLIC_KEY:o}})}get client(){return{axios:{request:()=>A(this.data.url,this.data.auth,this.data.env,this.data.middleware)},fetch:{request:m}}}static get plugins(){return{cache:{server:b}}}static get storages(){return{server:{cache:R}}}};export{h as ApiService};
15
3
  //# sourceMappingURL=index.js.map