azurajs 3.0.2 → 3.0.4

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.
Files changed (120) hide show
  1. package/README.md +32 -0
  2. package/dist/IpResolver-BVgnGnpf.d.mts +5 -0
  3. package/dist/IpResolver-BVgnGnpf.d.ts +5 -0
  4. package/dist/SwaggerPlugin-C0UZTjaZ.d.ts +6 -0
  5. package/dist/SwaggerPlugin-wr9S4SRG.d.mts +6 -0
  6. package/dist/cookies/index.d.mts +7 -0
  7. package/dist/cookies/index.d.ts +7 -0
  8. package/dist/cookies/index.js +38 -0
  9. package/dist/cookies/index.js.map +1 -0
  10. package/dist/cookies/index.mjs +35 -0
  11. package/dist/cookies/index.mjs.map +1 -0
  12. package/dist/core/index.d.mts +18 -27
  13. package/dist/core/index.d.ts +18 -27
  14. package/dist/core/index.js +214 -14
  15. package/dist/core/index.js.map +1 -1
  16. package/dist/core/index.mjs +214 -14
  17. package/dist/core/index.mjs.map +1 -1
  18. package/dist/cors/index.d.mts +7 -0
  19. package/dist/cors/index.d.ts +7 -0
  20. package/dist/cors/index.js +52 -0
  21. package/dist/cors/index.js.map +1 -0
  22. package/dist/cors/index.mjs +50 -0
  23. package/dist/cors/index.mjs.map +1 -0
  24. package/dist/decorators/index.d.mts +2 -0
  25. package/dist/decorators/index.d.ts +2 -0
  26. package/dist/decorators/index.js +25 -0
  27. package/dist/decorators/index.js.map +1 -1
  28. package/dist/decorators/index.mjs +24 -1
  29. package/dist/decorators/index.mjs.map +1 -1
  30. package/dist/decorators-B6l3CbxC.d.ts +13 -0
  31. package/dist/decorators-D5nY109r.d.mts +13 -0
  32. package/dist/http-error/index.d.mts +18 -0
  33. package/dist/http-error/index.d.ts +18 -0
  34. package/dist/http-error/index.js +81 -0
  35. package/dist/http-error/index.js.map +1 -0
  36. package/dist/http-error/index.mjs +79 -0
  37. package/dist/http-error/index.mjs.map +1 -0
  38. package/dist/index-j6QGMhZU.d.mts +30 -0
  39. package/dist/index-tpPZS_UK.d.ts +30 -0
  40. package/dist/index.d.mts +16 -5
  41. package/dist/index.d.ts +16 -5
  42. package/dist/index.js +1178 -14
  43. package/dist/index.js.map +1 -1
  44. package/dist/index.mjs +1176 -15
  45. package/dist/index.mjs.map +1 -1
  46. package/dist/infra/index.d.mts +6 -0
  47. package/dist/infra/index.d.ts +6 -0
  48. package/dist/infra/index.js +162 -0
  49. package/dist/infra/index.js.map +1 -0
  50. package/dist/infra/index.mjs +159 -0
  51. package/dist/infra/index.mjs.map +1 -0
  52. package/dist/{Logger-iEQNVVSc.d.mts → logger/index.d.mts} +2 -1
  53. package/dist/{Logger-iEQNVVSc.d.ts → logger/index.d.ts} +2 -1
  54. package/dist/logger/index.js +123 -0
  55. package/dist/logger/index.js.map +1 -0
  56. package/dist/logger/index.mjs +120 -0
  57. package/dist/logger/index.mjs.map +1 -0
  58. package/dist/plugins/index.d.mts +8 -6
  59. package/dist/plugins/index.d.ts +8 -6
  60. package/dist/plugins/index.js +1101 -0
  61. package/dist/plugins/index.js.map +1 -1
  62. package/dist/plugins/index.mjs +1101 -1
  63. package/dist/plugins/index.mjs.map +1 -1
  64. package/dist/rate-limit/index.d.mts +7 -0
  65. package/dist/rate-limit/index.d.ts +7 -0
  66. package/dist/rate-limit/index.js +81 -0
  67. package/dist/rate-limit/index.js.map +1 -0
  68. package/dist/rate-limit/index.mjs +79 -0
  69. package/dist/rate-limit/index.mjs.map +1 -0
  70. package/dist/router/index.d.mts +4 -0
  71. package/dist/router/index.d.ts +4 -0
  72. package/dist/router/index.js +218 -0
  73. package/dist/router/index.js.map +1 -0
  74. package/dist/router/index.mjs +216 -0
  75. package/dist/router/index.mjs.map +1 -0
  76. package/dist/routes.type-DZO5VBW2.d.mts +58 -0
  77. package/dist/routes.type-DzHNkCag.d.ts +58 -0
  78. package/dist/swagger/index.d.mts +30 -0
  79. package/dist/swagger/index.d.ts +30 -0
  80. package/dist/swagger/index.js +1136 -0
  81. package/dist/swagger/index.js.map +1 -0
  82. package/dist/swagger/index.mjs +1126 -0
  83. package/dist/swagger/index.mjs.map +1 -0
  84. package/dist/swagger/swagger-ui-modern.html +894 -0
  85. package/dist/swagger.type-Bfn5nGR8.d.mts +42 -0
  86. package/dist/swagger.type-CfDbFCZC.d.ts +42 -0
  87. package/dist/types/index.d.mts +5 -58
  88. package/dist/types/index.d.ts +5 -58
  89. package/dist/utils/index.d.mts +7 -72
  90. package/dist/utils/index.d.ts +7 -72
  91. package/dist/validators/index.d.mts +48 -0
  92. package/dist/validators/index.d.ts +48 -0
  93. package/dist/validators/index.js +144 -0
  94. package/dist/validators/index.js.map +1 -0
  95. package/dist/validators/index.mjs +141 -0
  96. package/dist/validators/index.mjs.map +1 -0
  97. package/package.json +86 -2
  98. package/src/cookies/index.ts +1 -0
  99. package/src/core/index.ts +1 -0
  100. package/src/core/router.ts +26 -15
  101. package/src/core/server.ts +64 -14
  102. package/src/cors/index.ts +2 -0
  103. package/src/decorators/index.ts +2 -0
  104. package/src/http-error/index.ts +1 -0
  105. package/src/infra/index.ts +3 -0
  106. package/src/logger/index.ts +1 -0
  107. package/src/plugins/SwaggerPlugin.ts +45 -0
  108. package/src/plugins/index.ts +1 -0
  109. package/src/rate-limit/index.ts +2 -0
  110. package/src/router/index.ts +1 -0
  111. package/src/swagger/constants.ts +8 -0
  112. package/src/swagger/decorators.ts +35 -0
  113. package/src/swagger/index.ts +10 -0
  114. package/src/swagger/openapi-builder.ts +199 -0
  115. package/src/swagger/swagger-ui-html.ts +24 -0
  116. package/src/swagger/swagger-ui-modern.html +894 -0
  117. package/src/swagger/swagger-ui-template.ts +5 -0
  118. package/src/types/index.ts +7 -0
  119. package/src/types/swagger.type.ts +36 -0
  120. package/src/validators/index.ts +4 -0
@@ -0,0 +1,6 @@
1
+ export { ConfigModule } from '../config/index.mjs';
2
+ export { r as resolveIp } from '../IpResolver-BVgnGnpf.mjs';
3
+ import '../config.type-4K-xcMSy.mjs';
4
+ import '../plugin.type-BNooWhKa.mjs';
5
+ import '../common.type-BhGCNyEm.mjs';
6
+ import 'node:http';
@@ -0,0 +1,6 @@
1
+ export { ConfigModule } from '../config/index.js';
2
+ export { r as resolveIp } from '../IpResolver-BVgnGnpf.js';
3
+ import '../config.type-s3ImgfM_.js';
4
+ import '../plugin.type-D4HHceYz.js';
5
+ import '../common.type-BhGCNyEm.js';
6
+ import 'node:http';
@@ -0,0 +1,162 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+ var path = require('path');
5
+
6
+ // src/config/ConfigModule.ts
7
+ var CONFIG_FILES = [
8
+ "azura.config.ts",
9
+ "azura.config.js",
10
+ "azura.config.mjs",
11
+ "azura.config.json",
12
+ "azura.config.yaml",
13
+ "azura.config.yml"
14
+ ];
15
+ var ConfigModule = class _ConfigModule {
16
+ static instance = null;
17
+ config = {};
18
+ constructor() {
19
+ }
20
+ static getInstance() {
21
+ if (!_ConfigModule.instance) {
22
+ _ConfigModule.instance = new _ConfigModule();
23
+ }
24
+ return _ConfigModule.instance;
25
+ }
26
+ static async load(cwd) {
27
+ const instance = _ConfigModule.getInstance();
28
+ const baseDir = cwd ?? process.cwd();
29
+ for (const file of CONFIG_FILES) {
30
+ const fullPath = path.resolve(baseDir, file);
31
+ if (!fs.existsSync(fullPath)) continue;
32
+ if (file.endsWith(".json")) {
33
+ instance.config = JSON.parse(fs.readFileSync(fullPath, "utf-8"));
34
+ return instance.config;
35
+ }
36
+ if (file.endsWith(".yaml") || file.endsWith(".yml")) {
37
+ instance.config = parseSimpleYaml(fs.readFileSync(fullPath, "utf-8"));
38
+ return instance.config;
39
+ }
40
+ if (file.endsWith(".ts") || file.endsWith(".js") || file.endsWith(".mjs")) {
41
+ try {
42
+ const mod = await import(`file://${fullPath}`);
43
+ instance.config = mod.default ?? mod;
44
+ return instance.config;
45
+ } catch {
46
+ }
47
+ }
48
+ }
49
+ return instance.config;
50
+ }
51
+ static loadSync(cwd) {
52
+ const instance = _ConfigModule.getInstance();
53
+ const baseDir = cwd ?? process.cwd();
54
+ for (const file of CONFIG_FILES) {
55
+ const fullPath = path.resolve(baseDir, file);
56
+ if (!fs.existsSync(fullPath)) continue;
57
+ if (file.endsWith(".json")) {
58
+ instance.config = JSON.parse(fs.readFileSync(fullPath, "utf-8"));
59
+ return instance.config;
60
+ }
61
+ if (file.endsWith(".yaml") || file.endsWith(".yml")) {
62
+ instance.config = parseSimpleYaml(fs.readFileSync(fullPath, "utf-8"));
63
+ return instance.config;
64
+ }
65
+ }
66
+ return instance.config;
67
+ }
68
+ static get() {
69
+ return _ConfigModule.getInstance().config;
70
+ }
71
+ static set(config) {
72
+ _ConfigModule.getInstance().config = config;
73
+ }
74
+ static merge(partial) {
75
+ const instance = _ConfigModule.getInstance();
76
+ instance.config = deepMerge(instance.config, partial);
77
+ return instance.config;
78
+ }
79
+ };
80
+ function deepMerge(target, source) {
81
+ const output = { ...target };
82
+ for (const key of Object.keys(source)) {
83
+ if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key]) && target[key] && typeof target[key] === "object") {
84
+ output[key] = deepMerge(target[key], source[key]);
85
+ } else {
86
+ output[key] = source[key];
87
+ }
88
+ }
89
+ return output;
90
+ }
91
+ function parseSimpleYaml(content) {
92
+ const result = {};
93
+ const lines = content.split("\n");
94
+ const stack = [{ indent: -1, obj: result }];
95
+ for (const line of lines) {
96
+ const trimmed = line.trim();
97
+ if (!trimmed || trimmed.startsWith("#")) continue;
98
+ const indent = line.search(/\S/);
99
+ const colonIdx = trimmed.indexOf(":");
100
+ if (colonIdx === -1) continue;
101
+ const key = trimmed.slice(0, colonIdx).trim();
102
+ const rawValue = trimmed.slice(colonIdx + 1).trim();
103
+ while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {
104
+ stack.pop();
105
+ }
106
+ const parent = stack[stack.length - 1].obj;
107
+ if (!rawValue) {
108
+ const newObj = {};
109
+ parent[key] = newObj;
110
+ stack.push({ indent, obj: newObj });
111
+ } else {
112
+ parent[key] = parseYamlValue(rawValue);
113
+ }
114
+ }
115
+ return result;
116
+ }
117
+ function parseYamlValue(val) {
118
+ if (val === "true") return true;
119
+ if (val === "false") return false;
120
+ if (val === "null") return null;
121
+ if (/^-?\d+$/.test(val)) return parseInt(val, 10);
122
+ if (/^-?\d+\.\d+$/.test(val)) return parseFloat(val);
123
+ if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
124
+ return val.slice(1, -1);
125
+ }
126
+ if (val.startsWith("[") && val.endsWith("]")) {
127
+ return val.slice(1, -1).split(",").map((v) => parseYamlValue(v.trim()));
128
+ }
129
+ return val;
130
+ }
131
+
132
+ // src/utils/IpResolver.ts
133
+ var PROXY_HEADERS = [
134
+ "x-forwarded-for",
135
+ "x-real-ip",
136
+ "cf-connecting-ip",
137
+ "x-client-ip",
138
+ "x-cluster-client-ip",
139
+ "fastly-client-ip",
140
+ "true-client-ip"
141
+ ];
142
+ function resolveIp(req) {
143
+ for (const header of PROXY_HEADERS) {
144
+ const val = req.headers[header];
145
+ if (val) {
146
+ const ip = typeof val === "string" ? val.split(",")[0].trim() : val[0];
147
+ if (ip && ip.length > 0) return normalizeIp(ip);
148
+ }
149
+ }
150
+ const remoteAddr = req.socket?.remoteAddress ?? "127.0.0.1";
151
+ return normalizeIp(remoteAddr);
152
+ }
153
+ function normalizeIp(ip) {
154
+ if (ip === "::1" || ip === "::ffff:127.0.0.1") return "127.0.0.1";
155
+ if (ip.startsWith("::ffff:")) return ip.slice(7);
156
+ return ip;
157
+ }
158
+
159
+ exports.ConfigModule = ConfigModule;
160
+ exports.resolveIp = resolveIp;
161
+ //# sourceMappingURL=index.js.map
162
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/config/ConfigModule.ts","../../src/utils/IpResolver.ts"],"names":["resolve","existsSync","readFileSync"],"mappings":"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","file":"index.js","sourcesContent":["import { readFileSync, existsSync } from \"node:fs\";\r\nimport { resolve, join } from \"node:path\";\r\nimport type { AzuraConfig } from \"../types/config.type.js\";\r\n\r\nconst CONFIG_FILES = [\r\n \"azura.config.ts\",\r\n \"azura.config.js\",\r\n \"azura.config.mjs\",\r\n \"azura.config.json\",\r\n \"azura.config.yaml\",\r\n \"azura.config.yml\",\r\n];\r\n\r\nexport class ConfigModule {\r\n private static instance: ConfigModule | null = null;\r\n private config: AzuraConfig = {};\r\n\r\n private constructor() {}\r\n\r\n static getInstance(): ConfigModule {\r\n if (!ConfigModule.instance) {\r\n ConfigModule.instance = new ConfigModule();\r\n }\r\n return ConfigModule.instance;\r\n }\r\n\r\n static async load(cwd?: string): Promise<AzuraConfig> {\r\n const instance = ConfigModule.getInstance();\r\n const baseDir = cwd ?? process.cwd();\r\n\r\n for (const file of CONFIG_FILES) {\r\n const fullPath = resolve(baseDir, file);\r\n if (!existsSync(fullPath)) continue;\r\n\r\n if (file.endsWith(\".json\")) {\r\n instance.config = JSON.parse(readFileSync(fullPath, \"utf-8\"));\r\n return instance.config;\r\n }\r\n\r\n if (file.endsWith(\".yaml\") || file.endsWith(\".yml\")) {\r\n instance.config = parseSimpleYaml(readFileSync(fullPath, \"utf-8\"));\r\n return instance.config;\r\n }\r\n\r\n if (file.endsWith(\".ts\") || file.endsWith(\".js\") || file.endsWith(\".mjs\")) {\r\n try {\r\n const mod = await import(`file://${fullPath}`);\r\n instance.config = mod.default ?? mod;\r\n return instance.config;\r\n } catch {\r\n // TS files may need transpilation — skip if import fails\r\n }\r\n }\r\n }\r\n\r\n return instance.config;\r\n }\r\n\r\n static loadSync(cwd?: string): AzuraConfig {\r\n const instance = ConfigModule.getInstance();\r\n const baseDir = cwd ?? process.cwd();\r\n\r\n for (const file of CONFIG_FILES) {\r\n const fullPath = resolve(baseDir, file);\r\n if (!existsSync(fullPath)) continue;\r\n\r\n if (file.endsWith(\".json\")) {\r\n instance.config = JSON.parse(readFileSync(fullPath, \"utf-8\"));\r\n return instance.config;\r\n }\r\n\r\n if (file.endsWith(\".yaml\") || file.endsWith(\".yml\")) {\r\n instance.config = parseSimpleYaml(readFileSync(fullPath, \"utf-8\"));\r\n return instance.config;\r\n }\r\n }\r\n\r\n return instance.config;\r\n }\r\n\r\n static get(): AzuraConfig {\r\n return ConfigModule.getInstance().config;\r\n }\r\n\r\n static set(config: AzuraConfig): void {\r\n ConfigModule.getInstance().config = config;\r\n }\r\n\r\n static merge(partial: Partial<AzuraConfig>): AzuraConfig {\r\n const instance = ConfigModule.getInstance();\r\n instance.config = deepMerge(instance.config, partial) as AzuraConfig;\r\n return instance.config;\r\n }\r\n}\r\n\r\nfunction deepMerge(target: any, source: any): any {\r\n const output = { ...target };\r\n for (const key of Object.keys(source)) {\r\n if (\r\n source[key] &&\r\n typeof source[key] === \"object\" &&\r\n !Array.isArray(source[key]) &&\r\n target[key] &&\r\n typeof target[key] === \"object\"\r\n ) {\r\n output[key] = deepMerge(target[key], source[key]);\r\n } else {\r\n output[key] = source[key];\r\n }\r\n }\r\n return output;\r\n}\r\n\r\n/**\r\n * Minimal YAML parser for flat/shallow config files.\r\n * Does not handle complex YAML features — use JSON for complex configs.\r\n */\r\nfunction parseSimpleYaml(content: string): Record<string, any> {\r\n const result: Record<string, any> = {};\r\n const lines = content.split(\"\\n\");\r\n const stack: { indent: number; obj: Record<string, any> }[] = [{ indent: -1, obj: result }];\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\r\n\r\n const indent = line.search(/\\S/);\r\n const colonIdx = trimmed.indexOf(\":\");\r\n\r\n if (colonIdx === -1) continue;\r\n\r\n const key = trimmed.slice(0, colonIdx).trim();\r\n const rawValue = trimmed.slice(colonIdx + 1).trim();\r\n\r\n while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {\r\n stack.pop();\r\n }\r\n\r\n const parent = stack[stack.length - 1].obj;\r\n\r\n if (!rawValue) {\r\n const newObj: Record<string, any> = {};\r\n parent[key] = newObj;\r\n stack.push({ indent, obj: newObj });\r\n } else {\r\n parent[key] = parseYamlValue(rawValue);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction parseYamlValue(val: string): any {\r\n if (val === \"true\") return true;\r\n if (val === \"false\") return false;\r\n if (val === \"null\") return null;\r\n if (/^-?\\d+$/.test(val)) return parseInt(val, 10);\r\n if (/^-?\\d+\\.\\d+$/.test(val)) return parseFloat(val);\r\n if ((val.startsWith('\"') && val.endsWith('\"')) || (val.startsWith(\"'\") && val.endsWith(\"'\"))) {\r\n return val.slice(1, -1);\r\n }\r\n if (val.startsWith(\"[\") && val.endsWith(\"]\")) {\r\n return val\r\n .slice(1, -1)\r\n .split(\",\")\r\n .map((v) => parseYamlValue(v.trim()));\r\n }\r\n return val;\r\n}\r\n","import type { IncomingMessage } from \"node:http\";\r\n\r\nconst PROXY_HEADERS = [\r\n \"x-forwarded-for\",\r\n \"x-real-ip\",\r\n \"cf-connecting-ip\",\r\n \"x-client-ip\",\r\n \"x-cluster-client-ip\",\r\n \"fastly-client-ip\",\r\n \"true-client-ip\",\r\n] as const;\r\n\r\nexport function resolveIp(req: IncomingMessage): string {\r\n for (const header of PROXY_HEADERS) {\r\n const val = req.headers[header];\r\n if (val) {\r\n const ip = typeof val === \"string\" ? val.split(\",\")[0].trim() : val[0];\r\n if (ip && ip.length > 0) return normalizeIp(ip);\r\n }\r\n }\r\n\r\n const remoteAddr = req.socket?.remoteAddress ?? \"127.0.0.1\";\r\n return normalizeIp(remoteAddr);\r\n}\r\n\r\nfunction normalizeIp(ip: string): string {\r\n if (ip === \"::1\" || ip === \"::ffff:127.0.0.1\") return \"127.0.0.1\";\r\n if (ip.startsWith(\"::ffff:\")) return ip.slice(7);\r\n return ip;\r\n}\r\n"]}
@@ -0,0 +1,159 @@
1
+ import { existsSync, readFileSync } from 'fs';
2
+ import { resolve } from 'path';
3
+
4
+ // src/config/ConfigModule.ts
5
+ var CONFIG_FILES = [
6
+ "azura.config.ts",
7
+ "azura.config.js",
8
+ "azura.config.mjs",
9
+ "azura.config.json",
10
+ "azura.config.yaml",
11
+ "azura.config.yml"
12
+ ];
13
+ var ConfigModule = class _ConfigModule {
14
+ static instance = null;
15
+ config = {};
16
+ constructor() {
17
+ }
18
+ static getInstance() {
19
+ if (!_ConfigModule.instance) {
20
+ _ConfigModule.instance = new _ConfigModule();
21
+ }
22
+ return _ConfigModule.instance;
23
+ }
24
+ static async load(cwd) {
25
+ const instance = _ConfigModule.getInstance();
26
+ const baseDir = cwd ?? process.cwd();
27
+ for (const file of CONFIG_FILES) {
28
+ const fullPath = resolve(baseDir, file);
29
+ if (!existsSync(fullPath)) continue;
30
+ if (file.endsWith(".json")) {
31
+ instance.config = JSON.parse(readFileSync(fullPath, "utf-8"));
32
+ return instance.config;
33
+ }
34
+ if (file.endsWith(".yaml") || file.endsWith(".yml")) {
35
+ instance.config = parseSimpleYaml(readFileSync(fullPath, "utf-8"));
36
+ return instance.config;
37
+ }
38
+ if (file.endsWith(".ts") || file.endsWith(".js") || file.endsWith(".mjs")) {
39
+ try {
40
+ const mod = await import(`file://${fullPath}`);
41
+ instance.config = mod.default ?? mod;
42
+ return instance.config;
43
+ } catch {
44
+ }
45
+ }
46
+ }
47
+ return instance.config;
48
+ }
49
+ static loadSync(cwd) {
50
+ const instance = _ConfigModule.getInstance();
51
+ const baseDir = cwd ?? process.cwd();
52
+ for (const file of CONFIG_FILES) {
53
+ const fullPath = resolve(baseDir, file);
54
+ if (!existsSync(fullPath)) continue;
55
+ if (file.endsWith(".json")) {
56
+ instance.config = JSON.parse(readFileSync(fullPath, "utf-8"));
57
+ return instance.config;
58
+ }
59
+ if (file.endsWith(".yaml") || file.endsWith(".yml")) {
60
+ instance.config = parseSimpleYaml(readFileSync(fullPath, "utf-8"));
61
+ return instance.config;
62
+ }
63
+ }
64
+ return instance.config;
65
+ }
66
+ static get() {
67
+ return _ConfigModule.getInstance().config;
68
+ }
69
+ static set(config) {
70
+ _ConfigModule.getInstance().config = config;
71
+ }
72
+ static merge(partial) {
73
+ const instance = _ConfigModule.getInstance();
74
+ instance.config = deepMerge(instance.config, partial);
75
+ return instance.config;
76
+ }
77
+ };
78
+ function deepMerge(target, source) {
79
+ const output = { ...target };
80
+ for (const key of Object.keys(source)) {
81
+ if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key]) && target[key] && typeof target[key] === "object") {
82
+ output[key] = deepMerge(target[key], source[key]);
83
+ } else {
84
+ output[key] = source[key];
85
+ }
86
+ }
87
+ return output;
88
+ }
89
+ function parseSimpleYaml(content) {
90
+ const result = {};
91
+ const lines = content.split("\n");
92
+ const stack = [{ indent: -1, obj: result }];
93
+ for (const line of lines) {
94
+ const trimmed = line.trim();
95
+ if (!trimmed || trimmed.startsWith("#")) continue;
96
+ const indent = line.search(/\S/);
97
+ const colonIdx = trimmed.indexOf(":");
98
+ if (colonIdx === -1) continue;
99
+ const key = trimmed.slice(0, colonIdx).trim();
100
+ const rawValue = trimmed.slice(colonIdx + 1).trim();
101
+ while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {
102
+ stack.pop();
103
+ }
104
+ const parent = stack[stack.length - 1].obj;
105
+ if (!rawValue) {
106
+ const newObj = {};
107
+ parent[key] = newObj;
108
+ stack.push({ indent, obj: newObj });
109
+ } else {
110
+ parent[key] = parseYamlValue(rawValue);
111
+ }
112
+ }
113
+ return result;
114
+ }
115
+ function parseYamlValue(val) {
116
+ if (val === "true") return true;
117
+ if (val === "false") return false;
118
+ if (val === "null") return null;
119
+ if (/^-?\d+$/.test(val)) return parseInt(val, 10);
120
+ if (/^-?\d+\.\d+$/.test(val)) return parseFloat(val);
121
+ if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
122
+ return val.slice(1, -1);
123
+ }
124
+ if (val.startsWith("[") && val.endsWith("]")) {
125
+ return val.slice(1, -1).split(",").map((v) => parseYamlValue(v.trim()));
126
+ }
127
+ return val;
128
+ }
129
+
130
+ // src/utils/IpResolver.ts
131
+ var PROXY_HEADERS = [
132
+ "x-forwarded-for",
133
+ "x-real-ip",
134
+ "cf-connecting-ip",
135
+ "x-client-ip",
136
+ "x-cluster-client-ip",
137
+ "fastly-client-ip",
138
+ "true-client-ip"
139
+ ];
140
+ function resolveIp(req) {
141
+ for (const header of PROXY_HEADERS) {
142
+ const val = req.headers[header];
143
+ if (val) {
144
+ const ip = typeof val === "string" ? val.split(",")[0].trim() : val[0];
145
+ if (ip && ip.length > 0) return normalizeIp(ip);
146
+ }
147
+ }
148
+ const remoteAddr = req.socket?.remoteAddress ?? "127.0.0.1";
149
+ return normalizeIp(remoteAddr);
150
+ }
151
+ function normalizeIp(ip) {
152
+ if (ip === "::1" || ip === "::ffff:127.0.0.1") return "127.0.0.1";
153
+ if (ip.startsWith("::ffff:")) return ip.slice(7);
154
+ return ip;
155
+ }
156
+
157
+ export { ConfigModule, resolveIp };
158
+ //# sourceMappingURL=index.mjs.map
159
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/config/ConfigModule.ts","../../src/utils/IpResolver.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { readFileSync, existsSync } from \"node:fs\";\r\nimport { resolve, join } from \"node:path\";\r\nimport type { AzuraConfig } from \"../types/config.type.js\";\r\n\r\nconst CONFIG_FILES = [\r\n \"azura.config.ts\",\r\n \"azura.config.js\",\r\n \"azura.config.mjs\",\r\n \"azura.config.json\",\r\n \"azura.config.yaml\",\r\n \"azura.config.yml\",\r\n];\r\n\r\nexport class ConfigModule {\r\n private static instance: ConfigModule | null = null;\r\n private config: AzuraConfig = {};\r\n\r\n private constructor() {}\r\n\r\n static getInstance(): ConfigModule {\r\n if (!ConfigModule.instance) {\r\n ConfigModule.instance = new ConfigModule();\r\n }\r\n return ConfigModule.instance;\r\n }\r\n\r\n static async load(cwd?: string): Promise<AzuraConfig> {\r\n const instance = ConfigModule.getInstance();\r\n const baseDir = cwd ?? process.cwd();\r\n\r\n for (const file of CONFIG_FILES) {\r\n const fullPath = resolve(baseDir, file);\r\n if (!existsSync(fullPath)) continue;\r\n\r\n if (file.endsWith(\".json\")) {\r\n instance.config = JSON.parse(readFileSync(fullPath, \"utf-8\"));\r\n return instance.config;\r\n }\r\n\r\n if (file.endsWith(\".yaml\") || file.endsWith(\".yml\")) {\r\n instance.config = parseSimpleYaml(readFileSync(fullPath, \"utf-8\"));\r\n return instance.config;\r\n }\r\n\r\n if (file.endsWith(\".ts\") || file.endsWith(\".js\") || file.endsWith(\".mjs\")) {\r\n try {\r\n const mod = await import(`file://${fullPath}`);\r\n instance.config = mod.default ?? mod;\r\n return instance.config;\r\n } catch {\r\n // TS files may need transpilation — skip if import fails\r\n }\r\n }\r\n }\r\n\r\n return instance.config;\r\n }\r\n\r\n static loadSync(cwd?: string): AzuraConfig {\r\n const instance = ConfigModule.getInstance();\r\n const baseDir = cwd ?? process.cwd();\r\n\r\n for (const file of CONFIG_FILES) {\r\n const fullPath = resolve(baseDir, file);\r\n if (!existsSync(fullPath)) continue;\r\n\r\n if (file.endsWith(\".json\")) {\r\n instance.config = JSON.parse(readFileSync(fullPath, \"utf-8\"));\r\n return instance.config;\r\n }\r\n\r\n if (file.endsWith(\".yaml\") || file.endsWith(\".yml\")) {\r\n instance.config = parseSimpleYaml(readFileSync(fullPath, \"utf-8\"));\r\n return instance.config;\r\n }\r\n }\r\n\r\n return instance.config;\r\n }\r\n\r\n static get(): AzuraConfig {\r\n return ConfigModule.getInstance().config;\r\n }\r\n\r\n static set(config: AzuraConfig): void {\r\n ConfigModule.getInstance().config = config;\r\n }\r\n\r\n static merge(partial: Partial<AzuraConfig>): AzuraConfig {\r\n const instance = ConfigModule.getInstance();\r\n instance.config = deepMerge(instance.config, partial) as AzuraConfig;\r\n return instance.config;\r\n }\r\n}\r\n\r\nfunction deepMerge(target: any, source: any): any {\r\n const output = { ...target };\r\n for (const key of Object.keys(source)) {\r\n if (\r\n source[key] &&\r\n typeof source[key] === \"object\" &&\r\n !Array.isArray(source[key]) &&\r\n target[key] &&\r\n typeof target[key] === \"object\"\r\n ) {\r\n output[key] = deepMerge(target[key], source[key]);\r\n } else {\r\n output[key] = source[key];\r\n }\r\n }\r\n return output;\r\n}\r\n\r\n/**\r\n * Minimal YAML parser for flat/shallow config files.\r\n * Does not handle complex YAML features — use JSON for complex configs.\r\n */\r\nfunction parseSimpleYaml(content: string): Record<string, any> {\r\n const result: Record<string, any> = {};\r\n const lines = content.split(\"\\n\");\r\n const stack: { indent: number; obj: Record<string, any> }[] = [{ indent: -1, obj: result }];\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\r\n\r\n const indent = line.search(/\\S/);\r\n const colonIdx = trimmed.indexOf(\":\");\r\n\r\n if (colonIdx === -1) continue;\r\n\r\n const key = trimmed.slice(0, colonIdx).trim();\r\n const rawValue = trimmed.slice(colonIdx + 1).trim();\r\n\r\n while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {\r\n stack.pop();\r\n }\r\n\r\n const parent = stack[stack.length - 1].obj;\r\n\r\n if (!rawValue) {\r\n const newObj: Record<string, any> = {};\r\n parent[key] = newObj;\r\n stack.push({ indent, obj: newObj });\r\n } else {\r\n parent[key] = parseYamlValue(rawValue);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction parseYamlValue(val: string): any {\r\n if (val === \"true\") return true;\r\n if (val === \"false\") return false;\r\n if (val === \"null\") return null;\r\n if (/^-?\\d+$/.test(val)) return parseInt(val, 10);\r\n if (/^-?\\d+\\.\\d+$/.test(val)) return parseFloat(val);\r\n if ((val.startsWith('\"') && val.endsWith('\"')) || (val.startsWith(\"'\") && val.endsWith(\"'\"))) {\r\n return val.slice(1, -1);\r\n }\r\n if (val.startsWith(\"[\") && val.endsWith(\"]\")) {\r\n return val\r\n .slice(1, -1)\r\n .split(\",\")\r\n .map((v) => parseYamlValue(v.trim()));\r\n }\r\n return val;\r\n}\r\n","import type { IncomingMessage } from \"node:http\";\r\n\r\nconst PROXY_HEADERS = [\r\n \"x-forwarded-for\",\r\n \"x-real-ip\",\r\n \"cf-connecting-ip\",\r\n \"x-client-ip\",\r\n \"x-cluster-client-ip\",\r\n \"fastly-client-ip\",\r\n \"true-client-ip\",\r\n] as const;\r\n\r\nexport function resolveIp(req: IncomingMessage): string {\r\n for (const header of PROXY_HEADERS) {\r\n const val = req.headers[header];\r\n if (val) {\r\n const ip = typeof val === \"string\" ? val.split(\",\")[0].trim() : val[0];\r\n if (ip && ip.length > 0) return normalizeIp(ip);\r\n }\r\n }\r\n\r\n const remoteAddr = req.socket?.remoteAddress ?? \"127.0.0.1\";\r\n return normalizeIp(remoteAddr);\r\n}\r\n\r\nfunction normalizeIp(ip: string): string {\r\n if (ip === \"::1\" || ip === \"::ffff:127.0.0.1\") return \"127.0.0.1\";\r\n if (ip.startsWith(\"::ffff:\")) return ip.slice(7);\r\n return ip;\r\n}\r\n"]}
@@ -21,5 +21,6 @@ declare class Logger {
21
21
  banner(port: number, host: string): void;
22
22
  setLevel(level: LogLevel): void;
23
23
  }
24
+ declare const logger: Logger;
24
25
 
25
- export { Logger as L };
26
+ export { Logger, logger };
@@ -21,5 +21,6 @@ declare class Logger {
21
21
  banner(port: number, host: string): void;
22
22
  setLevel(level: LogLevel): void;
23
23
  }
24
+ declare const logger: Logger;
24
25
 
25
- export { Logger as L };
26
+ export { Logger, logger };
@@ -0,0 +1,123 @@
1
+ 'use strict';
2
+
3
+ // src/utils/Logger.ts
4
+ var LEVEL_PRIORITY = {
5
+ debug: 0,
6
+ info: 1,
7
+ warn: 2,
8
+ error: 3,
9
+ silent: 4
10
+ };
11
+ var COLORS = {
12
+ reset: "\x1B[0m",
13
+ bold: "\x1B[1m",
14
+ dim: "\x1B[2m",
15
+ red: "\x1B[31m",
16
+ green: "\x1B[32m",
17
+ yellow: "\x1B[33m",
18
+ blue: "\x1B[34m",
19
+ magenta: "\x1B[35m",
20
+ cyan: "\x1B[36m",
21
+ white: "\x1B[37m",
22
+ gray: "\x1B[90m"};
23
+ var METHOD_COLORS = {
24
+ GET: COLORS.green,
25
+ POST: COLORS.blue,
26
+ PUT: COLORS.yellow,
27
+ DELETE: COLORS.red,
28
+ PATCH: COLORS.magenta,
29
+ HEAD: COLORS.cyan,
30
+ OPTIONS: COLORS.gray
31
+ };
32
+ function statusColor(code) {
33
+ if (code < 200) return COLORS.gray;
34
+ if (code < 300) return COLORS.green;
35
+ if (code < 400) return COLORS.cyan;
36
+ if (code < 500) return COLORS.yellow;
37
+ return COLORS.red;
38
+ }
39
+ function formatDuration(ns) {
40
+ const us = Number(ns) / 1e3;
41
+ if (us < 1e3) return `${us.toFixed(0)}\xB5s`;
42
+ const ms = us / 1e3;
43
+ if (ms < 1e3) return `${ms.toFixed(1)}ms`;
44
+ return `${(ms / 1e3).toFixed(2)}s`;
45
+ }
46
+ var Logger = class {
47
+ level;
48
+ useColors;
49
+ showTimestamp;
50
+ prefix;
51
+ constructor(options = {}) {
52
+ this.level = options.level ?? "info";
53
+ this.useColors = options.colors ?? process.stdout.isTTY !== false;
54
+ this.showTimestamp = options.timestamp ?? true;
55
+ this.prefix = options.prefix ?? "azura";
56
+ }
57
+ shouldLog(level) {
58
+ return LEVEL_PRIORITY[level] >= LEVEL_PRIORITY[this.level];
59
+ }
60
+ timestamp() {
61
+ if (!this.showTimestamp) return "";
62
+ const now = /* @__PURE__ */ new Date();
63
+ return `${COLORS.gray}${now.toISOString().slice(11, 23)}${COLORS.reset} `;
64
+ }
65
+ tag(level) {
66
+ if (!this.useColors) return `[${level.toUpperCase()}]`;
67
+ const colorMap = {
68
+ debug: COLORS.gray,
69
+ info: COLORS.blue,
70
+ warn: COLORS.yellow,
71
+ error: COLORS.red
72
+ };
73
+ return `${colorMap[level] ?? ""}[${level.toUpperCase()}]${COLORS.reset}`;
74
+ }
75
+ debug(message, ...args) {
76
+ if (!this.shouldLog("debug")) return;
77
+ console.debug(`${this.timestamp()}${this.tag("debug")} ${message}`, ...args);
78
+ }
79
+ info(message, ...args) {
80
+ if (!this.shouldLog("info")) return;
81
+ console.info(`${this.timestamp()}${this.tag("info")} ${message}`, ...args);
82
+ }
83
+ warn(message, ...args) {
84
+ if (!this.shouldLog("warn")) return;
85
+ console.warn(`${this.timestamp()}${this.tag("warn")} ${message}`, ...args);
86
+ }
87
+ error(message, ...args) {
88
+ if (!this.shouldLog("error")) return;
89
+ console.error(`${this.timestamp()}${this.tag("error")} ${message}`, ...args);
90
+ }
91
+ request(method, path, statusCode, duration) {
92
+ if (!this.shouldLog("info")) return;
93
+ const mc = this.useColors ? METHOD_COLORS[method] ?? COLORS.white : "";
94
+ const sc = this.useColors ? statusColor(statusCode) : "";
95
+ const r = this.useColors ? COLORS.reset : "";
96
+ const dur = formatDuration(duration);
97
+ console.info(
98
+ `${this.timestamp()}${mc}${method.padEnd(7)}${r} ${path} ${sc}${statusCode}${r} ${COLORS.dim}${dur}${r}`
99
+ );
100
+ }
101
+ banner(port, host) {
102
+ if (!this.shouldLog("info")) return;
103
+ const c = this.useColors;
104
+ const lines = [
105
+ "",
106
+ `${c ? COLORS.bold + COLORS.cyan : ""} \u26A1 AzuraJS v3.0.0${c ? COLORS.reset : ""}`,
107
+ "",
108
+ `${c ? COLORS.green : ""} \u279C Local: ${c ? COLORS.bold : ""}http://${host}:${port}/${c ? COLORS.reset : ""}`,
109
+ `${c ? COLORS.dim : ""} \u279C Press Ctrl+C to stop${c ? COLORS.reset : ""}`,
110
+ ""
111
+ ];
112
+ console.info(lines.join("\n"));
113
+ }
114
+ setLevel(level) {
115
+ this.level = level;
116
+ }
117
+ };
118
+ var logger = new Logger();
119
+
120
+ exports.Logger = Logger;
121
+ exports.logger = logger;
122
+ //# sourceMappingURL=index.js.map
123
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/Logger.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\" | \"silent\";\r\n\r\nconst LEVEL_PRIORITY: Record<LogLevel, number> = {\r\n debug: 0,\r\n info: 1,\r\n warn: 2,\r\n error: 3,\r\n silent: 4,\r\n};\r\n\r\nconst COLORS = {\r\n reset: \"\\x1b[0m\",\r\n bold: \"\\x1b[1m\",\r\n dim: \"\\x1b[2m\",\r\n red: \"\\x1b[31m\",\r\n green: \"\\x1b[32m\",\r\n yellow: \"\\x1b[33m\",\r\n blue: \"\\x1b[34m\",\r\n magenta: \"\\x1b[35m\",\r\n cyan: \"\\x1b[36m\",\r\n white: \"\\x1b[37m\",\r\n gray: \"\\x1b[90m\",\r\n bgRed: \"\\x1b[41m\",\r\n bgGreen: \"\\x1b[42m\",\r\n bgYellow: \"\\x1b[43m\",\r\n bgBlue: \"\\x1b[44m\",\r\n} as const;\r\n\r\nconst METHOD_COLORS: Record<string, string> = {\r\n GET: COLORS.green,\r\n POST: COLORS.blue,\r\n PUT: COLORS.yellow,\r\n DELETE: COLORS.red,\r\n PATCH: COLORS.magenta,\r\n HEAD: COLORS.cyan,\r\n OPTIONS: COLORS.gray,\r\n};\r\n\r\nfunction statusColor(code: number): string {\r\n if (code < 200) return COLORS.gray;\r\n if (code < 300) return COLORS.green;\r\n if (code < 400) return COLORS.cyan;\r\n if (code < 500) return COLORS.yellow;\r\n return COLORS.red;\r\n}\r\n\r\nfunction formatDuration(ns: bigint): string {\r\n const us = Number(ns) / 1_000;\r\n if (us < 1_000) return `${us.toFixed(0)}µs`;\r\n const ms = us / 1_000;\r\n if (ms < 1_000) return `${ms.toFixed(1)}ms`;\r\n return `${(ms / 1_000).toFixed(2)}s`;\r\n}\r\n\r\nexport class Logger {\r\n private level: LogLevel;\r\n private useColors: boolean;\r\n private showTimestamp: boolean;\r\n private prefix: string;\r\n\r\n constructor(options: {\r\n level?: LogLevel;\r\n colors?: boolean;\r\n timestamp?: boolean;\r\n prefix?: string;\r\n } = {}) {\r\n this.level = options.level ?? \"info\";\r\n this.useColors = options.colors ?? process.stdout.isTTY !== false;\r\n this.showTimestamp = options.timestamp ?? true;\r\n this.prefix = options.prefix ?? \"azura\";\r\n }\r\n\r\n private shouldLog(level: LogLevel): boolean {\r\n return LEVEL_PRIORITY[level] >= LEVEL_PRIORITY[this.level];\r\n }\r\n\r\n private timestamp(): string {\r\n if (!this.showTimestamp) return \"\";\r\n const now = new Date();\r\n return `${COLORS.gray}${now.toISOString().slice(11, 23)}${COLORS.reset} `;\r\n }\r\n\r\n private tag(level: LogLevel): string {\r\n if (!this.useColors) return `[${level.toUpperCase()}]`;\r\n const colorMap: Record<string, string> = {\r\n debug: COLORS.gray,\r\n info: COLORS.blue,\r\n warn: COLORS.yellow,\r\n error: COLORS.red,\r\n };\r\n return `${colorMap[level] ?? \"\"}[${level.toUpperCase()}]${COLORS.reset}`;\r\n }\r\n\r\n debug(message: string, ...args: any[]): void {\r\n if (!this.shouldLog(\"debug\")) return;\r\n console.debug(`${this.timestamp()}${this.tag(\"debug\")} ${message}`, ...args);\r\n }\r\n\r\n info(message: string, ...args: any[]): void {\r\n if (!this.shouldLog(\"info\")) return;\r\n console.info(`${this.timestamp()}${this.tag(\"info\")} ${message}`, ...args);\r\n }\r\n\r\n warn(message: string, ...args: any[]): void {\r\n if (!this.shouldLog(\"warn\")) return;\r\n console.warn(`${this.timestamp()}${this.tag(\"warn\")} ${message}`, ...args);\r\n }\r\n\r\n error(message: string, ...args: any[]): void {\r\n if (!this.shouldLog(\"error\")) return;\r\n console.error(`${this.timestamp()}${this.tag(\"error\")} ${message}`, ...args);\r\n }\r\n\r\n request(method: string, path: string, statusCode: number, duration: bigint): void {\r\n if (!this.shouldLog(\"info\")) return;\r\n const mc = this.useColors ? METHOD_COLORS[method] ?? COLORS.white : \"\";\r\n const sc = this.useColors ? statusColor(statusCode) : \"\";\r\n const r = this.useColors ? COLORS.reset : \"\";\r\n const dur = formatDuration(duration);\r\n console.info(\r\n `${this.timestamp()}${mc}${method.padEnd(7)}${r} ${path} ${sc}${statusCode}${r} ${COLORS.dim}${dur}${r}`,\r\n );\r\n }\r\n\r\n banner(port: number, host: string): void {\r\n if (!this.shouldLog(\"info\")) return;\r\n const c = this.useColors;\r\n const lines = [\r\n \"\",\r\n `${c ? COLORS.bold + COLORS.cyan : \"\"} ⚡ AzuraJS v3.0.0${c ? COLORS.reset : \"\"}`,\r\n \"\",\r\n `${c ? COLORS.green : \"\"} ➜ Local: ${c ? COLORS.bold : \"\"}http://${host}:${port}/${c ? COLORS.reset : \"\"}`,\r\n `${c ? COLORS.dim : \"\"} ➜ Press Ctrl+C to stop${c ? COLORS.reset : \"\"}`,\r\n \"\",\r\n ];\r\n console.info(lines.join(\"\\n\"));\r\n }\r\n\r\n setLevel(level: LogLevel): void {\r\n this.level = level;\r\n }\r\n}\r\n\r\nexport const logger = new Logger();\r\n"]}