@alyvro/api-service 1.2.0 → 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,154 +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
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
17
+
18
+ ---
19
19
 
20
20
  ### 📦 Installation
21
21
 
22
- ```bash
22
+ bash
23
23
  pnpm add @alyvro/api-service
24
+
24
25
  # or
26
+
25
27
  npm install @alyvro/api-service
26
- # or
27
- yarn add @alyvro/api-service
28
- ```
28
+
29
+ If you are using a specific framework, make sure it is installed (e.g., `fastify` or `express`).
29
30
 
30
31
  ---
31
32
 
32
- ## ✨ Usage
33
+ ## ✨ Server-Side Usage
34
+
35
+ Initialize the service once in your application entry point.
36
+
37
+ ### ➤ Fastify
33
38
 
34
- ### Client-side
39
+ Import the middleware directly from the fastify subpath. This ensures no Express dependencies are loaded.
35
40
 
36
41
  ```ts
42
+ import Fastify from "fastify";
37
43
  import { ApiService } from "@alyvro/api-service";
38
- import { cache, createAbortController } from "@alyvro/api-service/plugins";
44
+ import middleware from "@alyvro/api-service/fastify";
39
45
 
40
- const api = new ApiService({ api_url: "https://api.alyvro.com" });
46
+ const fastify = Fastify();
41
47
 
42
- // Example: Request with cache, compressor, and retry
43
- 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
+ });
44
55
 
45
- // Using Axios
46
- const axiosResponse = await api.client.axios.request().post(
47
- "/user",
48
- { index: "foo" },
49
- {
50
- secret: { body: true },
51
- signal: controller.signal,
52
- plugins: {
53
- // cache:cache or ApiService.plugins.cache,
54
- compressor: true,
55
- retry: { retries: 5, retryDelay: 500, backoff: true },
56
- },
57
- }
58
- );
56
+ // Add the hook to handle API security and logging
57
+ fastify.addHook("preHandler", middleware);
59
58
 
60
- // Using fetch
61
- const fetchResponse = await api.client.fetch.request("/user", {
62
- method: "POST",
63
- body: { index: "foo" },
64
- signal: controller.signal,
59
+ fastify.get("/", async (request, reply) => {
60
+ return { hello: "world" };
65
61
  });
66
62
 
67
- // Cancel request if needed
68
- controller.abort();
63
+ fastify.listen({ port: 3000 });
69
64
  ```
70
65
 
71
- - `cache` → stores and reuses previous responses to reduce duplicate requests (client & server safe)
72
- - `compressor` → automatically compresses/decompresses payloads when supported by the server
73
- - `retry` → automatic per-request retry with configurable attempts, delay, and backoff
74
- - `createAbortController` → allows canceling requests on demand
75
- - ⚠️ **Note:** Plugins currently only work with Axios. Fetch does **not** support Axios plugins yet.
76
-
77
- ---
78
-
79
- ### ➤ Server-side (Express)
66
+ ### Express
80
67
 
81
68
  ```ts
82
69
  import express from "express";
83
70
  import { ApiService } from "@alyvro/api-service";
71
+ import middleware from "@alyvro/api-service/express";
84
72
 
85
73
  const app = express();
86
74
 
87
- const api = new ApiService({
88
- url: "https://alyvro.com",
89
- settings: { telegram: true }, // enables Telegram error reporting
90
- middleware: {
91
- skip_routers: ["/health", "/status"],
92
- },
75
+ new ApiService({
76
+ url: "http://localhost:3000",
93
77
  });
94
78
 
95
- // Middleware with skip_routers option
96
- app.use((req, res, next) => api.server.middleware(req, res, next));
79
+ app.use(middleware);
97
80
 
98
81
  app.get("/", (req, res) => {
99
- res.json({ message: "Hello world!" });
82
+ res.json({ message: "Hello from Express" });
100
83
  });
101
84
  ```
102
85
 
103
- Middleware now supports skipping routes via `skip_routers`. Requests matching any path in this array will bypass the middleware.
104
-
105
- All server errors will automatically be sent to your Telegram bot.
106
-
107
86
  ---
108
87
 
109
- ### Typed Axios Example
88
+ ## Client-Side Usage
110
89
 
111
- 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.
112
91
 
113
- #### Example
92
+ ### ➤ Using Axios (Recommended)
114
93
 
115
94
  ```ts
116
- // Define your API schema mapping endpoints to their response types
117
- const apis = new ApiService({
118
- url: "https://api.example.com",
119
- }).client.axios.request<{
120
- "/": { index: number };
121
- "/auth": { success: boolean };
122
- "/profile": { id: string; name: string; email: string };
123
- }>();
124
-
125
- // GET request - TypeScript infers the response type as { index: number }
126
- apis.get("/").then((res) => {
127
- 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",
128
99
  });
129
100
 
130
- // POST request - TypeScript infers the response type as { success: boolean }
131
- apis.post("/auth", { username: "john", password: "secret" }).then((res) => {
132
- if (res.data.success) {
133
- console.log("Login successful ✅");
134
- }
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
+ },
135
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";
132
+
133
+ type ApiSchema = {
134
+ "/users": { id: number; name: string }[];
135
+ "/auth/login": { token: string };
136
+ };
136
137
 
137
- // PATCH request - TypeScript infers the response type as { id: string; name: string; email: string }
138
- apis.patch("/profile", { name: "John Doe" }).then((res) => {
139
- console.log(res.data.email); // ✅ res.data.email is a string
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);
140
145
  });
141
146
 
142
- // DELETE request - also fully typed
143
- apis.delete("/profile").then((res) => {
144
- 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);
145
150
  });
146
151
  ```
147
152
 
148
- #### Benefits
153
+ ---
154
+
155
+ ## 🧩 Plugins (Axios Only)
156
+
157
+ Plugins allow extending the functionality of requests per call.
158
+
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();
149
172
 
150
- - **Type-safe endpoints**: Each endpoint URL is strongly typed, so you can’t accidentally mistype.
151
- - **Automatic inference**: No need to manually annotate response types, they are inferred from the schema.
152
- - **Better DX**: Autocomplete and IntelliSense show the correct response structure per endpoint.
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
+ });
153
180
 
154
- This pattern combines the flexibility of Axios with the type-safety of a predefined API schema.
181
+ // Cancel the request
182
+ controller.abort();
183
+ ```
155
184
 
156
185
  ---
157
186
 
158
- ## ⚙️ Config Options
187
+ ## ⚙️ Configuration
159
188
 
160
189
  | Key | Type | Required | Description |
161
190
  | ------------------------- | -------------------------------------- | ------------------------------------------ | -------------------------------------------------------------- |
@@ -175,65 +204,23 @@ This pattern combines the flexibility of Axios with the type-safety of a predefi
175
204
 
176
205
  ---
177
206
 
178
- ## 🧩 Plugins
179
-
180
- Plugins allow extending the functionality of requests and middleware. They are configured **per-request**.
181
-
182
- ### Built-in Plugins
183
-
184
- - **Cache**
185
- Stores last response and prevents duplicate requests with identical payloads.
186
-
187
- - **Compressor**
188
- Compresses request payloads and automatically decompresses gzip responses.
207
+ ## 📫 Telegram Integration
189
208
 
190
- - **Retry**
191
- Automatically retries failed requests.
209
+ To enable error reporting:
192
210
 
193
- ```ts
194
- plugins: { retry: { retries: 5, retryDelay: 500, backoff: true } }
195
- ```
211
+ 1. Set `TELEGRAM_TOKEN` and `TELEGRAM_CHAT_ID` in your environment variables.
212
+ 2. Enable it in the config:
196
213
 
197
- - **Cancel**
198
- Allows canceling requests using `AbortController`.
199
-
200
- ```ts
201
- import { createAbortController } from "@alyvro/api-service/plugins";
202
- const controller = createAbortController();
203
- api.get("/users", { signal: controller.signal });
204
- controller.abort();
205
- ```
206
-
207
- > ⚠️ **Note:** Plugins currently only work with Axios. Fetch does **not** support Axios plugins yet.
208
-
209
- ---
210
-
211
- ## 📫 Telegram Error Reporting
214
+ ts
215
+ new ApiService({
216
+ url: "...",
217
+ setting: { telegram: true }
218
+ });
212
219
 
213
- 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.
214
221
 
215
222
  ---
216
223
 
217
- ## 📘 License
218
-
219
- MIT License
220
-
221
- Copyright (c) 2025 Alyvro
222
-
223
- Permission is hereby granted, free of charge, to any person obtaining a copy
224
- of this software and associated documentation files (the "Software"), to deal
225
- in the Software without restriction, including without limitation the rights
226
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
227
- copies of the Software, and to permit persons to whom the Software is
228
- furnished to do so, subject to the following conditions:
229
-
230
- The above copyright notice and this permission notice shall be included in all
231
- copies or substantial portions of the Software.
224
+ ## License
232
225
 
233
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
234
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
235
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
236
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
237
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
238
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
239
- 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,11 +19,7 @@ type ConfigMiddlewareType = {
19
19
  headers: Partial<ConfigMiddlewareHeadersType>;
20
20
  errors: Partial<ConfigMiddlewareErrorsType>;
21
21
  skip_routers: string[];
22
- powerd_by: string;
23
- };
24
- type ApiTypes = {
25
- prefix: string;
26
- data_returns: any;
22
+ powered_by: string;
27
23
  };
28
24
  type ConfigType = {
29
25
  url: string;
@@ -32,7 +28,6 @@ type ConfigType = {
32
28
  env?: ConfigEnvType;
33
29
  setting?: Partial<ConfigSettingType>;
34
30
  middleware?: Partial<ConfigMiddlewareType>;
35
- api_types?: ApiTypes[];
36
31
  };
37
32
 
38
- export type { ApiTypes as A, ConfigType as C, ConfigEnvType as a, ConfigSettingType as b, ConfigMiddlewareHeadersType as c, ConfigMiddlewareErrorsType as d, ConfigMiddlewareType as e };
33
+ export type { ConfigType as C, ConfigEnvType as a, ConfigSettingType as b, ConfigMiddlewareHeadersType as c, ConfigMiddlewareErrorsType as d, ConfigMiddlewareType as e };
@@ -19,11 +19,7 @@ type ConfigMiddlewareType = {
19
19
  headers: Partial<ConfigMiddlewareHeadersType>;
20
20
  errors: Partial<ConfigMiddlewareErrorsType>;
21
21
  skip_routers: string[];
22
- powerd_by: string;
23
- };
24
- type ApiTypes = {
25
- prefix: string;
26
- data_returns: any;
22
+ powered_by: string;
27
23
  };
28
24
  type ConfigType = {
29
25
  url: string;
@@ -32,7 +28,6 @@ type ConfigType = {
32
28
  env?: ConfigEnvType;
33
29
  setting?: Partial<ConfigSettingType>;
34
30
  middleware?: Partial<ConfigMiddlewareType>;
35
- api_types?: ApiTypes[];
36
31
  };
37
32
 
38
- export type { ApiTypes as A, ConfigType as C, ConfigEnvType as a, ConfigSettingType as b, ConfigMiddlewareHeadersType as c, ConfigMiddlewareErrorsType as d, ConfigMiddlewareType as e };
33
+ export type { ConfigType as C, ConfigEnvType as a, ConfigSettingType as b, ConfigMiddlewareHeadersType as c, ConfigMiddlewareErrorsType as d, ConfigMiddlewareType as e };
@@ -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":"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","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