auravia-connect 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +28 -0
- package/dist/client/createClient.d.ts +34 -0
- package/dist/client/createClient.js +263 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +9 -0
- package/package.json +29 -0
package/Readme.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# auravia-connect
|
|
2
|
+
|
|
3
|
+
π Smart frontendβbackend connector with built-in mocking, fallback, and debug timeline.
|
|
4
|
+
|
|
5
|
+
Auravia Connect is a lightweight HTTP client designed to simplify communication between frontend and backend while providing powerful developer tools like smart mocking and automatic fallback.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## β¨ Features
|
|
10
|
+
|
|
11
|
+
- π Simple HTTP client (GET, POST, PUT, PATCH, DELETE)
|
|
12
|
+
- π§ Smart mock generator
|
|
13
|
+
- π§ͺ Wildcard route mocking (`/users/:id`)
|
|
14
|
+
- β± Mock delay simulation
|
|
15
|
+
- π¨ Error simulation
|
|
16
|
+
- π Smart fallback when network fails
|
|
17
|
+
- π§© Request & response interceptors
|
|
18
|
+
- π§ Debug timeline
|
|
19
|
+
- βοΈ Strategy control (prefer mock or network)
|
|
20
|
+
- π¦ Zero dependencies
|
|
21
|
+
- β‘ Lightweight
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## π¦ Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install auravia-connect
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
type ClientConfig = {
|
|
2
|
+
baseURL?: string;
|
|
3
|
+
headers?: Record<string, string>;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
mock?: boolean;
|
|
6
|
+
mockFallback?: boolean;
|
|
7
|
+
debug?: boolean;
|
|
8
|
+
mockStrategy?: "prefer-mock" | "prefer-network";
|
|
9
|
+
};
|
|
10
|
+
type ApiResponse<T = any> = {
|
|
11
|
+
ok: boolean;
|
|
12
|
+
status: number;
|
|
13
|
+
data: T | null;
|
|
14
|
+
error: string | null;
|
|
15
|
+
};
|
|
16
|
+
type MockOptions = {
|
|
17
|
+
method?: string;
|
|
18
|
+
delay?: number;
|
|
19
|
+
count?: number;
|
|
20
|
+
status?: number;
|
|
21
|
+
};
|
|
22
|
+
export declare function createClient(defaultConfig?: ClientConfig): {
|
|
23
|
+
get: (url: string) => Promise<ApiResponse<any>>;
|
|
24
|
+
post: (url: string, body?: any) => Promise<ApiResponse<any>>;
|
|
25
|
+
put: (url: string, body?: any) => Promise<ApiResponse<any>>;
|
|
26
|
+
patch: (url: string, body?: any) => Promise<ApiResponse<any>>;
|
|
27
|
+
delete: (url: string) => Promise<ApiResponse<any>>;
|
|
28
|
+
onRequest(fn: Function): number;
|
|
29
|
+
onResponse(fn: Function): number;
|
|
30
|
+
ejectRequest(id: number): void;
|
|
31
|
+
ejectResponse(id: number): void;
|
|
32
|
+
mock(url: string, response: any, options?: MockOptions): void;
|
|
33
|
+
};
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createClient = createClient;
|
|
4
|
+
function createClient(defaultConfig = {}) {
|
|
5
|
+
// ===============================
|
|
6
|
+
// π₯ INTERCEPTORS
|
|
7
|
+
// ===============================
|
|
8
|
+
let interceptorId = 0;
|
|
9
|
+
const requestInterceptors = [];
|
|
10
|
+
const responseInterceptors = [];
|
|
11
|
+
// ===============================
|
|
12
|
+
// π₯ MOCK STORAGE
|
|
13
|
+
// ===============================
|
|
14
|
+
const mocks = [];
|
|
15
|
+
// ===============================
|
|
16
|
+
// π₯ DEBUG LOGGER
|
|
17
|
+
// ===============================
|
|
18
|
+
function debugLog(...args) {
|
|
19
|
+
if (defaultConfig.debug) {
|
|
20
|
+
console.log("[auravia]", ...args);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// ===============================
|
|
24
|
+
// π₯ STRATEGY
|
|
25
|
+
// ===============================
|
|
26
|
+
function shouldUseMockFirst() {
|
|
27
|
+
var _a;
|
|
28
|
+
return (((_a = defaultConfig.mockStrategy) !== null && _a !== void 0 ? _a : "prefer-mock") === "prefer-mock");
|
|
29
|
+
}
|
|
30
|
+
// ===============================
|
|
31
|
+
// π₯ GENERATORS
|
|
32
|
+
// ===============================
|
|
33
|
+
const generators = {
|
|
34
|
+
text: () => "Sample text",
|
|
35
|
+
number: () => Math.floor(Math.random() * 1000),
|
|
36
|
+
boolean: () => Math.random() > 0.5,
|
|
37
|
+
uuid: () => typeof crypto !== "undefined" && crypto.randomUUID
|
|
38
|
+
? crypto.randomUUID()
|
|
39
|
+
: Math.random().toString(36).slice(2),
|
|
40
|
+
image: () => `https://picsum.photos/200?random=${Math.random()}`,
|
|
41
|
+
video: () => "https://samplelib.com/lib/preview/mp4/sample-5s.mp4",
|
|
42
|
+
mp3: () => "https://samplelib.com/lib/preview/mp3/sample-3s.mp3",
|
|
43
|
+
};
|
|
44
|
+
// ===============================
|
|
45
|
+
// π₯ SCHEMA RESOLVER
|
|
46
|
+
// ===============================
|
|
47
|
+
function resolveSchema(schema) {
|
|
48
|
+
if (typeof schema === "string" && generators[schema]) {
|
|
49
|
+
return generators[schema]();
|
|
50
|
+
}
|
|
51
|
+
if (Array.isArray(schema)) {
|
|
52
|
+
return schema.map(item => resolveSchema(item));
|
|
53
|
+
}
|
|
54
|
+
if (schema && typeof schema === "object") {
|
|
55
|
+
const result = {};
|
|
56
|
+
for (const key in schema) {
|
|
57
|
+
result[key] = resolveSchema(schema[key]);
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
return schema;
|
|
62
|
+
}
|
|
63
|
+
// ===============================
|
|
64
|
+
// π₯ URL MATCHER
|
|
65
|
+
// ===============================
|
|
66
|
+
function matchUrl(mockUrl, requestUrl) {
|
|
67
|
+
if (mockUrl === requestUrl)
|
|
68
|
+
return true;
|
|
69
|
+
const regex = new RegExp("^" + mockUrl.replace(/:[^/]+/g, "[^/]+") + "$");
|
|
70
|
+
return regex.test(requestUrl);
|
|
71
|
+
}
|
|
72
|
+
// ===============================
|
|
73
|
+
// π₯ FIND MOCK
|
|
74
|
+
// ===============================
|
|
75
|
+
function findMock(config) {
|
|
76
|
+
return mocks.find(m => {
|
|
77
|
+
const methodMatch = !m.method || m.method === config.method;
|
|
78
|
+
const urlMatch = matchUrl(m.url, config.url);
|
|
79
|
+
return methodMatch && urlMatch;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// ===============================
|
|
83
|
+
// π₯ DELAY
|
|
84
|
+
// ===============================
|
|
85
|
+
function sleep(ms) {
|
|
86
|
+
return new Promise(res => setTimeout(res, ms));
|
|
87
|
+
}
|
|
88
|
+
// ===============================
|
|
89
|
+
// π₯ BUILD MOCK RESPONSE
|
|
90
|
+
// ===============================
|
|
91
|
+
async function buildMockResponse(mock, config) {
|
|
92
|
+
var _a, _b, _c, _d;
|
|
93
|
+
if ((_a = mock.options) === null || _a === void 0 ? void 0 : _a.delay) {
|
|
94
|
+
await sleep(mock.options.delay);
|
|
95
|
+
}
|
|
96
|
+
let data = typeof mock.response === "function"
|
|
97
|
+
? await mock.response(config)
|
|
98
|
+
: resolveSchema(mock.response);
|
|
99
|
+
if (((_b = mock.options) === null || _b === void 0 ? void 0 : _b.count) && mock.options.count > 1) {
|
|
100
|
+
data = Array.from({ length: mock.options.count }).map(() => resolveSchema(mock.response));
|
|
101
|
+
}
|
|
102
|
+
const statusCode = (_d = (_c = mock.options) === null || _c === void 0 ? void 0 : _c.status) !== null && _d !== void 0 ? _d : 200;
|
|
103
|
+
let mockResponse = {
|
|
104
|
+
ok: statusCode >= 200 && statusCode < 300,
|
|
105
|
+
status: statusCode,
|
|
106
|
+
data,
|
|
107
|
+
error: statusCode >= 200 && statusCode < 300
|
|
108
|
+
? null
|
|
109
|
+
: "Mock error",
|
|
110
|
+
};
|
|
111
|
+
for (const interceptor of responseInterceptors) {
|
|
112
|
+
mockResponse = await interceptor.fn(mockResponse);
|
|
113
|
+
}
|
|
114
|
+
return mockResponse;
|
|
115
|
+
}
|
|
116
|
+
// ===============================
|
|
117
|
+
// π₯ REQUEST ENGINE
|
|
118
|
+
// ===============================
|
|
119
|
+
async function request(method, url, body) {
|
|
120
|
+
const startTime = Date.now();
|
|
121
|
+
debugLog("β", method, url);
|
|
122
|
+
const controller = new AbortController();
|
|
123
|
+
let config = {
|
|
124
|
+
method,
|
|
125
|
+
url,
|
|
126
|
+
data: body,
|
|
127
|
+
headers: { ...defaultConfig.headers },
|
|
128
|
+
baseURL: defaultConfig.baseURL,
|
|
129
|
+
};
|
|
130
|
+
// ---------- request interceptors ----------
|
|
131
|
+
try {
|
|
132
|
+
for (const interceptor of requestInterceptors) {
|
|
133
|
+
config = await interceptor.fn(config);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
status: 0,
|
|
140
|
+
data: null,
|
|
141
|
+
error: (err === null || err === void 0 ? void 0 : err.message) || "Request blocked by interceptor",
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// ===============================
|
|
145
|
+
// π₯ DIRECT MOCK (strategy aware)
|
|
146
|
+
// ===============================
|
|
147
|
+
const directMock = defaultConfig.mock ? findMock(config) : undefined;
|
|
148
|
+
if (directMock && shouldUseMockFirst()) {
|
|
149
|
+
debugLog("β mock hit");
|
|
150
|
+
const res = await buildMockResponse(directMock, config);
|
|
151
|
+
debugLog("β±", Date.now() - startTime + "ms");
|
|
152
|
+
return res;
|
|
153
|
+
}
|
|
154
|
+
// ===============================
|
|
155
|
+
// π₯ REAL FETCH
|
|
156
|
+
// ===============================
|
|
157
|
+
const timer = defaultConfig.timeout
|
|
158
|
+
? setTimeout(() => controller.abort(), defaultConfig.timeout)
|
|
159
|
+
: null;
|
|
160
|
+
try {
|
|
161
|
+
debugLog("β¦ trying network");
|
|
162
|
+
const res = await fetch((config.baseURL || "") + config.url, {
|
|
163
|
+
method: config.method,
|
|
164
|
+
headers: {
|
|
165
|
+
"Content-Type": "application/json",
|
|
166
|
+
...config.headers,
|
|
167
|
+
},
|
|
168
|
+
body: config.data && config.method !== "GET"
|
|
169
|
+
? JSON.stringify(config.data)
|
|
170
|
+
: undefined,
|
|
171
|
+
signal: controller.signal,
|
|
172
|
+
});
|
|
173
|
+
const contentType = res.headers.get("content-type") || "";
|
|
174
|
+
let parsed;
|
|
175
|
+
if (contentType.includes("application/json")) {
|
|
176
|
+
parsed = await res.json();
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
parsed = await res.text();
|
|
180
|
+
}
|
|
181
|
+
let response = {
|
|
182
|
+
ok: res.ok,
|
|
183
|
+
status: res.status,
|
|
184
|
+
data: parsed,
|
|
185
|
+
error: null,
|
|
186
|
+
};
|
|
187
|
+
for (const interceptor of responseInterceptors) {
|
|
188
|
+
response = await interceptor.fn(response);
|
|
189
|
+
}
|
|
190
|
+
debugLog("β network");
|
|
191
|
+
debugLog("β±", Date.now() - startTime + "ms");
|
|
192
|
+
return response;
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
// ===============================
|
|
196
|
+
// π₯ SMART FALLBACK
|
|
197
|
+
// ===============================
|
|
198
|
+
if (defaultConfig.mock && defaultConfig.mockFallback) {
|
|
199
|
+
const fallbackMock = findMock(config);
|
|
200
|
+
if (fallbackMock) {
|
|
201
|
+
debugLog("β network failed");
|
|
202
|
+
debugLog("β fallback mock hit");
|
|
203
|
+
const res = await buildMockResponse(fallbackMock, config);
|
|
204
|
+
debugLog("β±", Date.now() - startTime + "ms");
|
|
205
|
+
return res;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
debugLog("β request failed");
|
|
209
|
+
debugLog("β±", Date.now() - startTime + "ms");
|
|
210
|
+
return {
|
|
211
|
+
ok: false,
|
|
212
|
+
status: 500,
|
|
213
|
+
data: null,
|
|
214
|
+
error: (err === null || err === void 0 ? void 0 : err.message) || "Network error",
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
if (timer)
|
|
219
|
+
clearTimeout(timer);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// ===============================
|
|
223
|
+
// π₯ PUBLIC API
|
|
224
|
+
// ===============================
|
|
225
|
+
return {
|
|
226
|
+
get: (url) => request("GET", url),
|
|
227
|
+
post: (url, body) => request("POST", url, body),
|
|
228
|
+
put: (url, body) => request("PUT", url, body),
|
|
229
|
+
patch: (url, body) => request("PATCH", url, body),
|
|
230
|
+
delete: (url) => request("DELETE", url),
|
|
231
|
+
onRequest(fn) {
|
|
232
|
+
const id = ++interceptorId;
|
|
233
|
+
requestInterceptors.push({ id, fn });
|
|
234
|
+
return id;
|
|
235
|
+
},
|
|
236
|
+
onResponse(fn) {
|
|
237
|
+
const id = ++interceptorId;
|
|
238
|
+
responseInterceptors.push({ id, fn });
|
|
239
|
+
return id;
|
|
240
|
+
},
|
|
241
|
+
ejectRequest(id) {
|
|
242
|
+
const i = requestInterceptors.findIndex(x => x.id === id);
|
|
243
|
+
if (i !== -1)
|
|
244
|
+
requestInterceptors.splice(i, 1);
|
|
245
|
+
},
|
|
246
|
+
ejectResponse(id) {
|
|
247
|
+
const i = responseInterceptors.findIndex(x => x.id === id);
|
|
248
|
+
if (i !== -1)
|
|
249
|
+
responseInterceptors.splice(i, 1);
|
|
250
|
+
},
|
|
251
|
+
mock(url, response, options) {
|
|
252
|
+
if (!defaultConfig.mock) {
|
|
253
|
+
throw new Error("[auravia-connect] Mock disabled. Use createClient({ mock: true })");
|
|
254
|
+
}
|
|
255
|
+
mocks.push({
|
|
256
|
+
url,
|
|
257
|
+
method: options === null || options === void 0 ? void 0 : options.method,
|
|
258
|
+
response,
|
|
259
|
+
options,
|
|
260
|
+
});
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createClient = exports.auraviaReady = void 0;
|
|
4
|
+
const auraviaReady = () => {
|
|
5
|
+
return "auravia-connect ready";
|
|
6
|
+
};
|
|
7
|
+
exports.auraviaReady = auraviaReady;
|
|
8
|
+
var createClient_1 = require("./client/createClient");
|
|
9
|
+
Object.defineProperty(exports, "createClient", { enumerable: true, get: function () { return createClient_1.createClient; } });
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "auravia-connect",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Smart frontend-backend connector with built-in mocking and fallback",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "commonjs",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"require": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"http-client",
|
|
22
|
+
"mock",
|
|
23
|
+
"api-client",
|
|
24
|
+
"fetch-wrapper",
|
|
25
|
+
"testing"
|
|
26
|
+
],
|
|
27
|
+
"author": "Dinesh R",
|
|
28
|
+
"license": "MIT"
|
|
29
|
+
}
|