azurajs 3.0.0 → 3.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.
Files changed (106) hide show
  1. package/dist/config/index.js +128 -6
  2. package/dist/config/index.js.map +1 -1
  3. package/dist/config/index.mjs +130 -1
  4. package/dist/config/index.mjs.map +1 -1
  5. package/dist/core/index.js +1100 -11
  6. package/dist/core/index.js.map +1 -1
  7. package/dist/core/index.mjs +1102 -3
  8. package/dist/core/index.mjs.map +1 -1
  9. package/dist/decorators/index.js +117 -87
  10. package/dist/decorators/index.js.map +1 -1
  11. package/dist/decorators/index.mjs +98 -1
  12. package/dist/decorators/index.mjs.map +1 -1
  13. package/dist/index.js +2592 -236
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.mjs +2537 -9
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/middleware/index.js +16 -7
  18. package/dist/middleware/index.js.map +1 -1
  19. package/dist/middleware/index.mjs +17 -1
  20. package/dist/middleware/index.mjs.map +1 -1
  21. package/dist/plugins/index.js +1056 -73
  22. package/dist/plugins/index.js.map +1 -1
  23. package/dist/plugins/index.mjs +1042 -1
  24. package/dist/plugins/index.mjs.map +1 -1
  25. package/dist/types/index.js +49 -12
  26. package/dist/types/index.js.map +1 -1
  27. package/dist/types/index.mjs +49 -2
  28. package/dist/types/index.mjs.map +1 -1
  29. package/dist/utils/index.js +551 -50
  30. package/dist/utils/index.js.map +1 -1
  31. package/dist/utils/index.mjs +541 -3
  32. package/dist/utils/index.mjs.map +1 -1
  33. package/package.json +52 -18
  34. package/{dist/chunk-DR254CWJ.mjs → src/config/ConfigModule.ts} +169 -132
  35. package/src/config/index.ts +1 -0
  36. package/src/core/index.ts +2 -0
  37. package/src/core/router.ts +284 -0
  38. package/{dist/chunk-EYAHUNC7.mjs → src/core/server.ts} +590 -699
  39. package/src/decorators/Route.ts +110 -0
  40. package/src/decorators/index.ts +23 -0
  41. package/src/index.ts +12 -0
  42. package/src/middleware/LoggingMiddleware.ts +20 -0
  43. package/src/middleware/index.ts +1 -0
  44. package/src/plugins/CORSPlugin.ts +56 -0
  45. package/src/plugins/CircuitBreakerPlugin.ts +84 -0
  46. package/src/plugins/CompressionPlugin.ts +80 -0
  47. package/src/plugins/ETagPlugin.ts +31 -0
  48. package/src/plugins/HealthCheckPlugin.ts +57 -0
  49. package/src/plugins/HelmetPlugin.ts +89 -0
  50. package/src/plugins/JWTPlugin.ts +132 -0
  51. package/src/plugins/MultipartPlugin.ts +168 -0
  52. package/src/plugins/ProxyPlugin.ts +89 -0
  53. package/src/plugins/RateLimitPlugin.ts +96 -0
  54. package/src/plugins/RequestIdPlugin.ts +21 -0
  55. package/src/plugins/SSEPlugin.ts +114 -0
  56. package/src/plugins/SessionPlugin.ts +98 -0
  57. package/src/plugins/StaticPlugin.ts +152 -0
  58. package/src/plugins/TimeoutPlugin.ts +33 -0
  59. package/src/plugins/index.ts +18 -0
  60. package/src/types/common.type.ts +82 -0
  61. package/src/types/config.type.ts +57 -0
  62. package/{dist/chunk-OWUGAI5V.mjs → src/types/http/status.ts} +49 -51
  63. package/src/types/index.ts +55 -0
  64. package/src/types/plugins/plugin.type.ts +170 -0
  65. package/src/types/reflect.d.ts +14 -0
  66. package/src/types/routes.type.ts +70 -0
  67. package/src/utils/HttpError.ts +62 -0
  68. package/src/utils/IpResolver.ts +30 -0
  69. package/src/utils/Logger.ts +144 -0
  70. package/src/utils/Parser.ts +182 -0
  71. package/src/utils/cookies/CookieManager.ts +48 -0
  72. package/src/utils/index.ts +9 -0
  73. package/{dist/chunk-UWIFSGSQ.mjs → src/utils/validators/DTOValidator.ts} +145 -141
  74. package/src/utils/validators/SchemaValidator.ts +45 -0
  75. package/dist/chunk-3UFAWS2V.js +0 -392
  76. package/dist/chunk-3UFAWS2V.js.map +0 -1
  77. package/dist/chunk-4LSFAAZW.js +0 -4
  78. package/dist/chunk-4LSFAAZW.js.map +0 -1
  79. package/dist/chunk-7NSRIVZM.js +0 -54
  80. package/dist/chunk-7NSRIVZM.js.map +0 -1
  81. package/dist/chunk-AOG6NYAM.js +0 -144
  82. package/dist/chunk-AOG6NYAM.js.map +0 -1
  83. package/dist/chunk-DR254CWJ.mjs.map +0 -1
  84. package/dist/chunk-EYAHUNC7.mjs.map +0 -1
  85. package/dist/chunk-HHDQPIJN.mjs +0 -19
  86. package/dist/chunk-HHDQPIJN.mjs.map +0 -1
  87. package/dist/chunk-HHZNAGGI.js +0 -702
  88. package/dist/chunk-HHZNAGGI.js.map +0 -1
  89. package/dist/chunk-KJM5XCAY.js +0 -21
  90. package/dist/chunk-KJM5XCAY.js.map +0 -1
  91. package/dist/chunk-NLSZKAPA.mjs +0 -1044
  92. package/dist/chunk-NLSZKAPA.mjs.map +0 -1
  93. package/dist/chunk-OWUGAI5V.mjs.map +0 -1
  94. package/dist/chunk-POPNQEOK.js +0 -1063
  95. package/dist/chunk-POPNQEOK.js.map +0 -1
  96. package/dist/chunk-QPRW4YU4.js +0 -134
  97. package/dist/chunk-QPRW4YU4.js.map +0 -1
  98. package/dist/chunk-REJDZUZ5.mjs +0 -382
  99. package/dist/chunk-REJDZUZ5.mjs.map +0 -1
  100. package/dist/chunk-TC6N6TJZ.mjs +0 -100
  101. package/dist/chunk-TC6N6TJZ.mjs.map +0 -1
  102. package/dist/chunk-TEUXKMXP.js +0 -122
  103. package/dist/chunk-TEUXKMXP.js.map +0 -1
  104. package/dist/chunk-UWIFSGSQ.mjs.map +0 -1
  105. package/dist/chunk-YPBKY4KY.mjs +0 -3
  106. package/dist/chunk-YPBKY4KY.mjs.map +0 -1
@@ -1,12 +1,134 @@
1
1
  'use strict';
2
2
 
3
- var chunkQPRW4YU4_js = require('../chunk-QPRW4YU4.js');
3
+ var fs = require('fs');
4
+ var path = require('path');
4
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
+ }
5
131
 
6
-
7
- Object.defineProperty(exports, "ConfigModule", {
8
- enumerable: true,
9
- get: function () { return chunkQPRW4YU4_js.ConfigModule; }
10
- });
132
+ exports.ConfigModule = ConfigModule;
11
133
  //# sourceMappingURL=index.js.map
12
134
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
1
+ {"version":3,"sources":["../../src/config/ConfigModule.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"]}
@@ -1,3 +1,132 @@
1
- export { ConfigModule } from '../chunk-DR254CWJ.mjs';
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
+ export { ConfigModule };
2
131
  //# sourceMappingURL=index.mjs.map
3
132
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
1
+ {"version":3,"sources":["../../src/config/ConfigModule.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"]}