aziosxjs 1.0.1 → 1.0.2

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.
@@ -0,0 +1,18 @@
1
+ import type { AziosRequestConfig } from '../types/config';
2
+ import type { AziosResponse } from '../types/response';
3
+ import { BaseAdapter } from '../runtimes/HttpAdapter';
4
+ /**
5
+ * Node.js HTTP adapter using built-in http/https modules
6
+ * Compatible with Node.js 16+ (before global fetch was available)
7
+ */
8
+ export declare class NodeHttpAdapter extends BaseAdapter {
9
+ /**
10
+ * Check if this adapter is supported (Node.js environment)
11
+ */
12
+ isSupported(): boolean;
13
+ /**
14
+ * Execute HTTP request using Node.js http/https modules
15
+ */
16
+ request(config: AziosRequestConfig): Promise<AziosResponse>;
17
+ }
18
+ export default NodeHttpAdapter;
@@ -1,2 +1,158 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.NodeHttpAdapter = void 0;
40
+ const http = __importStar(require("http"));
41
+ const https = __importStar(require("https"));
42
+ const url_1 = require("url");
43
+ const HttpAdapter_1 = require("../runtimes/HttpAdapter");
44
+ const AziosError_1 = __importDefault(require("../errors/AziosError"));
45
+ /**
46
+ * Node.js HTTP adapter using built-in http/https modules
47
+ * Compatible with Node.js 16+ (before global fetch was available)
48
+ */
49
+ class NodeHttpAdapter extends HttpAdapter_1.BaseAdapter {
50
+ /**
51
+ * Check if this adapter is supported (Node.js environment)
52
+ */
53
+ isSupported() {
54
+ // In Node.js, this adapter is always supported
55
+ return true;
56
+ }
57
+ /**
58
+ * Execute HTTP request using Node.js http/https modules
59
+ */
60
+ async request(config) {
61
+ if (!this.isSupported()) {
62
+ throw new AziosError_1.default('Node HTTP adapter is not supported in this runtime', 'UNSUPPORTED_RUNTIME', config);
63
+ }
64
+ // Check if request is already cancelled
65
+ if (config.signal && config.signal.aborted) {
66
+ throw new AziosError_1.default('Request aborted', 'ABORTED', config);
67
+ }
68
+ return new Promise((resolve, reject) => {
69
+ const { url, method = 'GET', headers = {}, data, timeout, signal } = config;
70
+ const baseURL = config.baseURL || '';
71
+ const fullURL = new url_1.URL(baseURL + url);
72
+ // Add query parameters
73
+ if (config.params) {
74
+ Object.entries(config.params).forEach(([key, value]) => {
75
+ if (value !== null && value !== undefined) {
76
+ if (Array.isArray(value)) {
77
+ value.forEach(v => fullURL.searchParams.append(key, String(v)));
78
+ }
79
+ else {
80
+ fullURL.searchParams.set(key, String(value));
81
+ }
82
+ }
83
+ });
84
+ }
85
+ const isHttps = fullURL.protocol === 'https:';
86
+ const client = isHttps ? https : http;
87
+ const options = {
88
+ hostname: fullURL.hostname,
89
+ port: fullURL.port || (isHttps ? 443 : 80),
90
+ path: fullURL.pathname + fullURL.search,
91
+ method: method.toUpperCase(),
92
+ headers: {
93
+ 'Content-Type': 'application/json',
94
+ ...headers
95
+ }
96
+ };
97
+ // Handle timeout
98
+ let timeoutId;
99
+ if (timeout) {
100
+ timeoutId = setTimeout(() => {
101
+ req.destroy(new Error('Request timeout'));
102
+ }, timeout);
103
+ }
104
+ // Handle abort signal
105
+ if (signal) {
106
+ signal.addEventListener('abort', () => {
107
+ req.destroy(new Error('Request aborted'));
108
+ });
109
+ }
110
+ const req = client.request(options, (res) => {
111
+ let body = '';
112
+ res.on('data', (chunk) => {
113
+ body += chunk;
114
+ });
115
+ res.on('end', () => {
116
+ if (timeoutId) {
117
+ clearTimeout(timeoutId);
118
+ }
119
+ let responseData = body;
120
+ // Parse JSON if content-type is application/json
121
+ const contentType = res.headers['content-type'];
122
+ if ((contentType === null || contentType === void 0 ? void 0 : contentType.includes('application/json')) && body) {
123
+ try {
124
+ responseData = JSON.parse(body);
125
+ }
126
+ catch (e) {
127
+ // Keep as string if parsing fails
128
+ }
129
+ }
130
+ const response = {
131
+ data: responseData,
132
+ status: res.statusCode || 200,
133
+ statusText: res.statusMessage || '',
134
+ headers: res.headers,
135
+ config
136
+ };
137
+ resolve(response);
138
+ });
139
+ });
140
+ req.on('error', (error) => {
141
+ if (timeoutId) {
142
+ clearTimeout(timeoutId);
143
+ }
144
+ const errorCode = error.message.includes('aborted') ? 'ABORTED' : 'NETWORK_ERROR';
145
+ reject(new AziosError_1.default(`Request failed: ${error.message}`, errorCode, config, undefined, error));
146
+ });
147
+ // Send request body
148
+ if (data) {
149
+ const body = typeof data === 'string' ? data : JSON.stringify(data);
150
+ req.write(body);
151
+ }
152
+ req.end();
153
+ });
154
+ }
155
+ }
156
+ exports.NodeHttpAdapter = NodeHttpAdapter;
157
+ exports.default = NodeHttpAdapter;
2
158
  //# sourceMappingURL=httpAdapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"httpAdapter.js","sourceRoot":"","sources":["../../src/adapters/httpAdapter.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"httpAdapter.js","sourceRoot":"","sources":["../../src/adapters/httpAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { default as NodeHttpAdapter } from './httpAdapter';
@@ -1,2 +1,9 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NodeHttpAdapter = void 0;
7
+ var httpAdapter_1 = require("./httpAdapter");
8
+ Object.defineProperty(exports, "NodeHttpAdapter", { enumerable: true, get: function () { return __importDefault(httpAdapter_1).default; } });
2
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":";;;;;;AAAA,6CAA0D;AAAjD,+HAAA,OAAO,OAAmB"}
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.AdapterFactory = void 0;
7
7
  const detectRuntime_1 = require("./detectRuntime");
8
8
  const UniversalHttpAdapter_1 = __importDefault(require("./UniversalHttpAdapter"));
9
+ const adapters_1 = require("../adapters");
9
10
  /**
10
11
  * Adapter factory for selecting the appropriate HTTP adapter
11
12
  * Uses universal Fetch API when available with fallbacks for specific runtimes
@@ -16,7 +17,20 @@ class AdapterFactory {
16
17
  */
17
18
  static getAdapter() {
18
19
  if (!this.adapters.has(detectRuntime_1.currentRuntime)) {
19
- this.adapters.set(detectRuntime_1.currentRuntime, new UniversalHttpAdapter_1.default());
20
+ let adapter;
21
+ // Try UniversalHttpAdapter first (works in Node 18+, browsers, etc.)
22
+ const universalAdapter = new UniversalHttpAdapter_1.default();
23
+ if (universalAdapter.isSupported()) {
24
+ adapter = universalAdapter;
25
+ }
26
+ else if (detectRuntime_1.currentRuntime === detectRuntime_1.RuntimeType.Node) {
27
+ // Fallback to NodeHttpAdapter for Node.js < 18
28
+ adapter = new adapters_1.NodeHttpAdapter();
29
+ }
30
+ else {
31
+ throw new Error(`No supported HTTP adapter found for runtime: ${detectRuntime_1.currentRuntime}`);
32
+ }
33
+ this.adapters.set(detectRuntime_1.currentRuntime, adapter);
20
34
  }
21
35
  const adapter = this.adapters.get(detectRuntime_1.currentRuntime);
22
36
  if (!adapter.isSupported()) {
@@ -1 +1 @@
1
- {"version":3,"file":"AdapterFactory.js","sourceRoot":"","sources":["../../src/runtimes/AdapterFactory.ts"],"names":[],"mappings":";;;;;;AACA,mDAA6D;AAC7D,kFAAyD;AAEzD;;;GAGG;AACH,MAAa,cAAc;IAGzB;;OAEG;IACH,MAAM,CAAC,UAAU;QACf,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,8BAAc,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,8BAAc,EAAE,IAAI,8BAAoB,EAAE,CAAC,CAAA;QAC/D,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,8BAAc,CAAE,CAAA;QAElD,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,gDAAgD,8BAAc,EAAE,CACjE,CAAA;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,OAAoB,EAAE,OAAoB;QAC/D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACrC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,UAAU;QACf,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;IACvB,CAAC;;AAlCH,wCAmCC;AAlCgB,uBAAQ,GAAkC,IAAI,GAAG,EAAE,CAAA;AAoCpE,kBAAe,cAAc,CAAA"}
1
+ {"version":3,"file":"AdapterFactory.js","sourceRoot":"","sources":["../../src/runtimes/AdapterFactory.ts"],"names":[],"mappings":";;;;;;AACA,mDAA6D;AAC7D,kFAAyD;AACzD,0CAA6C;AAE7C;;;GAGG;AACH,MAAa,cAAc;IAGzB;;OAEG;IACH,MAAM,CAAC,UAAU;QACf,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,8BAAc,CAAC,EAAE,CAAC;YACvC,IAAI,OAAoB,CAAA;YAExB,qEAAqE;YACrE,MAAM,gBAAgB,GAAG,IAAI,8BAAoB,EAAE,CAAA;YACnD,IAAI,gBAAgB,CAAC,WAAW,EAAE,EAAE,CAAC;gBACnC,OAAO,GAAG,gBAAgB,CAAA;YAC5B,CAAC;iBAAM,IAAI,8BAAc,KAAK,2BAAW,CAAC,IAAI,EAAE,CAAC;gBAC/C,+CAA+C;gBAC/C,OAAO,GAAG,IAAI,0BAAe,EAAE,CAAA;YACjC,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CACb,gDAAgD,8BAAc,EAAE,CACjE,CAAA;YACH,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,8BAAc,EAAE,OAAO,CAAC,CAAA;QAC5C,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,8BAAc,CAAE,CAAA;QAElD,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,gDAAgD,8BAAc,EAAE,CACjE,CAAA;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,OAAoB,EAAE,OAAoB;QAC/D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACrC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,UAAU;QACf,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;IACvB,CAAC;;AAjDH,wCAkDC;AAjDgB,uBAAQ,GAAkC,IAAI,GAAG,EAAE,CAAA;AAmDpE,kBAAe,cAAc,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aziosxjs",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "🚀 Advanced HTTP client featuring request monitoring, auth management, plugins, middleware, and universal runtime support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -55,6 +55,8 @@
55
55
  "url": "https://github.com/azeemali2001/azios/issues"
56
56
  },
57
57
  "devDependencies": {
58
+ "@types/node": "^25.6.0",
59
+ "ts-node": "^10.9.2",
58
60
  "typescript": "^5.0.0"
59
61
  }
60
62
  }
@@ -0,0 +1,152 @@
1
+ import * as http from 'http'
2
+ import * as https from 'https'
3
+ import { URL } from 'url'
4
+ import type { AziosRequestConfig } from '../types/config'
5
+ import type { AziosResponse } from '../types/response'
6
+ import { BaseAdapter } from '../runtimes/HttpAdapter'
7
+ import AziosError from '../errors/AziosError'
8
+
9
+ /**
10
+ * Node.js HTTP adapter using built-in http/https modules
11
+ * Compatible with Node.js 16+ (before global fetch was available)
12
+ */
13
+ export class NodeHttpAdapter extends BaseAdapter {
14
+ /**
15
+ * Check if this adapter is supported (Node.js environment)
16
+ */
17
+ isSupported(): boolean {
18
+ // In Node.js, this adapter is always supported
19
+ return true
20
+ }
21
+
22
+ /**
23
+ * Execute HTTP request using Node.js http/https modules
24
+ */
25
+ async request(config: AziosRequestConfig): Promise<AziosResponse> {
26
+ if (!this.isSupported()) {
27
+ throw new AziosError(
28
+ 'Node HTTP adapter is not supported in this runtime',
29
+ 'UNSUPPORTED_RUNTIME',
30
+ config
31
+ )
32
+ }
33
+
34
+ // Check if request is already cancelled
35
+ if (config.signal && config.signal.aborted) {
36
+ throw new AziosError(
37
+ 'Request aborted',
38
+ 'ABORTED',
39
+ config
40
+ )
41
+ }
42
+
43
+ return new Promise((resolve, reject) => {
44
+ const { url, method = 'GET', headers = {}, data, timeout, signal } = config
45
+
46
+ const baseURL = config.baseURL || ''
47
+ const fullURL = new URL(baseURL + url)
48
+
49
+ // Add query parameters
50
+ if (config.params) {
51
+ Object.entries(config.params).forEach(([key, value]) => {
52
+ if (value !== null && value !== undefined) {
53
+ if (Array.isArray(value)) {
54
+ value.forEach(v => fullURL.searchParams.append(key, String(v)))
55
+ } else {
56
+ fullURL.searchParams.set(key, String(value))
57
+ }
58
+ }
59
+ })
60
+ }
61
+
62
+ const isHttps = fullURL.protocol === 'https:'
63
+ const client = isHttps ? https : http
64
+
65
+ const options: http.RequestOptions = {
66
+ hostname: fullURL.hostname,
67
+ port: fullURL.port || (isHttps ? 443 : 80),
68
+ path: fullURL.pathname + fullURL.search,
69
+ method: method.toUpperCase(),
70
+ headers: {
71
+ 'Content-Type': 'application/json',
72
+ ...headers
73
+ }
74
+ }
75
+
76
+ // Handle timeout
77
+ let timeoutId: NodeJS.Timeout | undefined
78
+ if (timeout) {
79
+ timeoutId = setTimeout(() => {
80
+ req.destroy(new Error('Request timeout'))
81
+ }, timeout)
82
+ }
83
+
84
+ // Handle abort signal
85
+ if (signal) {
86
+ signal.addEventListener('abort', () => {
87
+ req.destroy(new Error('Request aborted'))
88
+ })
89
+ }
90
+
91
+ const req = client.request(options, (res) => {
92
+ let body = ''
93
+
94
+ res.on('data', (chunk) => {
95
+ body += chunk
96
+ })
97
+
98
+ res.on('end', () => {
99
+ if (timeoutId) {
100
+ clearTimeout(timeoutId)
101
+ }
102
+
103
+ let responseData: any = body
104
+
105
+ // Parse JSON if content-type is application/json
106
+ const contentType = res.headers['content-type']
107
+ if (contentType?.includes('application/json') && body) {
108
+ try {
109
+ responseData = JSON.parse(body)
110
+ } catch (e) {
111
+ // Keep as string if parsing fails
112
+ }
113
+ }
114
+
115
+ const response: AziosResponse = {
116
+ data: responseData,
117
+ status: res.statusCode || 200,
118
+ statusText: res.statusMessage || '',
119
+ headers: res.headers as Record<string, string>,
120
+ config
121
+ }
122
+
123
+ resolve(response)
124
+ })
125
+ })
126
+
127
+ req.on('error', (error) => {
128
+ if (timeoutId) {
129
+ clearTimeout(timeoutId)
130
+ }
131
+ const errorCode = error.message.includes('aborted') ? 'ABORTED' : 'NETWORK_ERROR'
132
+ reject(new AziosError(
133
+ `Request failed: ${error.message}`,
134
+ errorCode,
135
+ config,
136
+ undefined,
137
+ error
138
+ ))
139
+ })
140
+
141
+ // Send request body
142
+ if (data) {
143
+ const body = typeof data === 'string' ? data : JSON.stringify(data)
144
+ req.write(body)
145
+ }
146
+
147
+ req.end()
148
+ })
149
+ }
150
+ }
151
+
152
+ export default NodeHttpAdapter
@@ -0,0 +1 @@
1
+ export { default as NodeHttpAdapter } from './httpAdapter'
@@ -1,6 +1,7 @@
1
1
  import type { HttpAdapter } from './HttpAdapter'
2
2
  import { currentRuntime, RuntimeType } from './detectRuntime'
3
3
  import UniversalHttpAdapter from './UniversalHttpAdapter'
4
+ import { NodeHttpAdapter } from '../adapters'
4
5
 
5
6
  /**
6
7
  * Adapter factory for selecting the appropriate HTTP adapter
@@ -14,7 +15,22 @@ export class AdapterFactory {
14
15
  */
15
16
  static getAdapter(): HttpAdapter {
16
17
  if (!this.adapters.has(currentRuntime)) {
17
- this.adapters.set(currentRuntime, new UniversalHttpAdapter())
18
+ let adapter: HttpAdapter
19
+
20
+ // Try UniversalHttpAdapter first (works in Node 18+, browsers, etc.)
21
+ const universalAdapter = new UniversalHttpAdapter()
22
+ if (universalAdapter.isSupported()) {
23
+ adapter = universalAdapter
24
+ } else if (currentRuntime === RuntimeType.Node) {
25
+ // Fallback to NodeHttpAdapter for Node.js < 18
26
+ adapter = new NodeHttpAdapter()
27
+ } else {
28
+ throw new Error(
29
+ `No supported HTTP adapter found for runtime: ${currentRuntime}`
30
+ )
31
+ }
32
+
33
+ this.adapters.set(currentRuntime, adapter)
18
34
  }
19
35
 
20
36
  const adapter = this.adapters.get(currentRuntime)!