@obinexusmk2/hypernum 0.1.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.
Files changed (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +256 -0
  3. package/dist/index.cjs +3425 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.ts +1449 -0
  6. package/dist/index.js +3284 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/index.umd.js +8 -0
  9. package/dist/index.umd.js.map +1 -0
  10. package/dist/types/config/config-loader.d.ts +56 -0
  11. package/dist/types/config/config-loader.d.ts.map +1 -0
  12. package/dist/types/config/config-parser.d.ts +28 -0
  13. package/dist/types/config/config-parser.d.ts.map +1 -0
  14. package/dist/types/config/config-resolver.d.ts +21 -0
  15. package/dist/types/config/config-resolver.d.ts.map +1 -0
  16. package/dist/types/config/config-source.d.ts +27 -0
  17. package/dist/types/config/config-source.d.ts.map +1 -0
  18. package/dist/types/config/index.d.ts +68 -0
  19. package/dist/types/config/index.d.ts.map +1 -0
  20. package/dist/types/core/common.d.ts +169 -0
  21. package/dist/types/core/common.d.ts.map +1 -0
  22. package/dist/types/core/config.d.ts +197 -0
  23. package/dist/types/core/config.d.ts.map +1 -0
  24. package/dist/types/core/constants.d.ts +88 -0
  25. package/dist/types/core/constants.d.ts.map +1 -0
  26. package/dist/types/core/errors.d.ts +97 -0
  27. package/dist/types/core/errors.d.ts.map +1 -0
  28. package/dist/types/core/hypernum.d.ts +60 -0
  29. package/dist/types/core/hypernum.d.ts.map +1 -0
  30. package/dist/types/core/index.d.ts +6 -0
  31. package/dist/types/core/index.d.ts.map +1 -0
  32. package/dist/types/index.d.ts +33 -0
  33. package/dist/types/index.d.ts.map +1 -0
  34. package/dist/types/operations/arithmetic.d.ts +72 -0
  35. package/dist/types/operations/arithmetic.d.ts.map +1 -0
  36. package/dist/types/operations/bitwise.d.ts +98 -0
  37. package/dist/types/operations/bitwise.d.ts.map +1 -0
  38. package/dist/types/operations/comparison.d.ts +94 -0
  39. package/dist/types/operations/comparison.d.ts.map +1 -0
  40. package/dist/types/operations/conversion.d.ts +79 -0
  41. package/dist/types/operations/conversion.d.ts.map +1 -0
  42. package/dist/types/operations/factorial.d.ts +58 -0
  43. package/dist/types/operations/factorial.d.ts.map +1 -0
  44. package/dist/types/operations/index.d.ts +6 -0
  45. package/dist/types/operations/index.d.ts.map +1 -0
  46. package/dist/types/operations/power.d.ts +49 -0
  47. package/dist/types/operations/power.d.ts.map +1 -0
  48. package/dist/types/storage/Heap.d.ts +95 -0
  49. package/dist/types/storage/Heap.d.ts.map +1 -0
  50. package/dist/types/storage/index.d.ts +2 -0
  51. package/dist/types/storage/index.d.ts.map +1 -0
  52. package/dist/types/structures/ackermann.d.ts +74 -0
  53. package/dist/types/structures/ackermann.d.ts.map +1 -0
  54. package/dist/types/structures/big-array.d.ts +102 -0
  55. package/dist/types/structures/big-array.d.ts.map +1 -0
  56. package/dist/types/structures/index.d.ts +5 -0
  57. package/dist/types/structures/index.d.ts.map +1 -0
  58. package/dist/types/structures/number-tree.d.ts +114 -0
  59. package/dist/types/structures/number-tree.d.ts.map +1 -0
  60. package/dist/types/structures/power-tower.d.ts +74 -0
  61. package/dist/types/structures/power-tower.d.ts.map +1 -0
  62. package/dist/types/utils/formatting.d.ts +45 -0
  63. package/dist/types/utils/formatting.d.ts.map +1 -0
  64. package/dist/types/utils/index.d.ts +5 -0
  65. package/dist/types/utils/index.d.ts.map +1 -0
  66. package/dist/types/utils/parser.d.ts +39 -0
  67. package/dist/types/utils/parser.d.ts.map +1 -0
  68. package/dist/types/utils/precision.d.ts +57 -0
  69. package/dist/types/utils/precision.d.ts.map +1 -0
  70. package/dist/types/utils/validation.d.ts +28 -0
  71. package/dist/types/utils/validation.d.ts.map +1 -0
  72. package/package.json +164 -0
  73. package/rollup.config.js +162 -0
  74. package/src/config/config-loader.ts +226 -0
  75. package/src/config/config-parser.ts +161 -0
  76. package/src/config/config-resolver.ts +52 -0
  77. package/src/config/config-source.ts +32 -0
  78. package/src/config/index.ts +159 -0
  79. package/src/core/common.ts +185 -0
  80. package/src/core/config.ts +393 -0
  81. package/src/core/constants.ts +102 -0
  82. package/src/core/errors.ts +203 -0
  83. package/src/core/hypernum.ts +241 -0
  84. package/src/core/index.ts +5 -0
  85. package/src/index.ts +183 -0
  86. package/src/operations/arithmetic.ts +333 -0
  87. package/src/operations/bitwise.ts +367 -0
  88. package/src/operations/comparison.ts +272 -0
  89. package/src/operations/conversion.ts +400 -0
  90. package/src/operations/factorial.ts +279 -0
  91. package/src/operations/index.ts +5 -0
  92. package/src/operations/power.ts +316 -0
  93. package/src/storage/Heap.ts +238 -0
  94. package/src/storage/index.ts +1 -0
  95. package/src/structures/ackermann.ts +233 -0
  96. package/src/structures/big-array.ts +306 -0
  97. package/src/structures/index.ts +4 -0
  98. package/src/structures/number-tree.ts +404 -0
  99. package/src/structures/power-tower.ts +278 -0
  100. package/src/types/common.d.ts +357 -0
  101. package/src/types/core.d.ts +161 -0
  102. package/src/types/index.d.ts +2 -0
  103. package/src/utils/formatting.ts +246 -0
  104. package/src/utils/index.ts +4 -0
  105. package/src/utils/parser.ts +245 -0
  106. package/src/utils/precision.ts +217 -0
  107. package/src/utils/validation.ts +183 -0
  108. package/tsconfig.json +84 -0
@@ -0,0 +1,226 @@
1
+
2
+ /**
3
+ * src/config/config-loader.ts
4
+ * Responsible for finding and loading configuration files
5
+ */
6
+
7
+ import { HypernumConfig, mergeConfig } from "@/core";
8
+ import path from "path";
9
+ import { ConfigParser } from "./config-parser";
10
+ import { ConfigSource } from "./config-source";
11
+ import fs from 'fs';
12
+
13
+
14
+ export interface ConfigSearchOptions {
15
+ /**
16
+ * Whether to search in parent directories
17
+ */
18
+ searchParentDirs?: boolean;
19
+
20
+ /**
21
+ * Additional paths to search
22
+ */
23
+ additionalPaths?: string[];
24
+
25
+ /**
26
+ * Base directory to start searching from
27
+ */
28
+ baseDir?: string;
29
+ }
30
+
31
+ export class ConfigLoader {
32
+ private readonly DEFAULT_CONFIG_FILES = [
33
+ '.hypernumrc',
34
+ '.hypernumrc.json',
35
+ '.hypernumrc.js',
36
+ 'hypernum.config.js',
37
+ 'hypernum.config.json',
38
+ ];
39
+
40
+ private readonly DEFAULT_CONFIG_PATHS = [
41
+ process.cwd(),
42
+ path.join(process.cwd(), 'config'),
43
+ path.resolve(process.env['HOME'] || process.env['USERPROFILE'] || '', '.hypernum')
44
+ ];
45
+
46
+ private configParser: ConfigParser;
47
+ private cachedConfig: HypernumConfig | null = null;
48
+
49
+ constructor() {
50
+ this.configParser = new ConfigParser();
51
+ }
52
+
53
+ /**
54
+ * Finds configuration files in standard locations
55
+ */
56
+ public findConfigFiles(options: ConfigSearchOptions = {}): Map<ConfigSource, string> {
57
+ const {
58
+ searchParentDirs = true,
59
+ additionalPaths = [],
60
+ baseDir = process.cwd()
61
+ } = options;
62
+
63
+ const searchPaths = [
64
+ ...this.DEFAULT_CONFIG_PATHS,
65
+ ...additionalPaths
66
+ ];
67
+
68
+ const configFiles = new Map<ConfigSource, string>();
69
+
70
+ // Search for configuration files
71
+ for (const searchPath of searchPaths) {
72
+ for (const filename of this.DEFAULT_CONFIG_FILES) {
73
+ const filePath = path.join(searchPath, filename);
74
+
75
+ if (fs.existsSync(filePath)) {
76
+ const source = this.getConfigSourceFromFilename(filename);
77
+ configFiles.set(source, filePath);
78
+ }
79
+ }
80
+ }
81
+
82
+ // Search parent directories if enabled
83
+ if (searchParentDirs && baseDir !== path.parse(baseDir).root) {
84
+ let currentDir = baseDir;
85
+ let parentDir = path.dirname(currentDir);
86
+
87
+ while (currentDir !== parentDir) {
88
+ for (const filename of this.DEFAULT_CONFIG_FILES) {
89
+ const filePath = path.join(currentDir, filename);
90
+
91
+ if (fs.existsSync(filePath)) {
92
+ const source = this.getConfigSourceFromFilename(filename);
93
+ configFiles.set(source, filePath);
94
+ }
95
+ }
96
+
97
+ currentDir = parentDir;
98
+ parentDir = path.dirname(currentDir);
99
+ }
100
+ }
101
+
102
+ return configFiles;
103
+ }
104
+
105
+ /**
106
+ * Determines the config source type from filename
107
+ */
108
+ public getConfigSourceFromFilename(filename: string): ConfigSource {
109
+ if (filename.endsWith('.js')) {
110
+ return ConfigSource.JS_FILE;
111
+ } else if (filename.endsWith('.json')) {
112
+ return ConfigSource.JSON_FILE;
113
+ } else if (filename.startsWith('.hypernumrc')) {
114
+ return ConfigSource.RC_FILE;
115
+ }
116
+
117
+ return ConfigSource.JSON_FILE; // Default fallback
118
+ }
119
+
120
+ /**
121
+ * Loads configuration from a file
122
+ */
123
+ public loadConfigFromFile(filePath: string): Partial<HypernumConfig> {
124
+ try {
125
+ const extension = path.extname(filePath);
126
+
127
+ switch (extension) {
128
+ case '.js':
129
+ return this.configParser.parseJsConfig(filePath);
130
+ case '.json':
131
+ return this.configParser.parseJsonConfig(filePath);
132
+ default:
133
+ if (filePath.includes('.hypernumrc')) {
134
+ return this.configParser.parseRcConfig(filePath);
135
+ }
136
+ throw new Error(`Unsupported config file extension: ${extension}`);
137
+ }
138
+ } catch (error) {
139
+ console.error(`Error loading config from ${filePath}:`, error);
140
+ return {};
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Loads configuration from all available sources
146
+ */
147
+ public loadConfig(options: ConfigSearchOptions = {}): HypernumConfig {
148
+ // Return cached config if available
149
+ if (this.cachedConfig) {
150
+ return this.cachedConfig;
151
+ }
152
+
153
+ const configFiles = this.findConfigFiles(options);
154
+ const configs: Partial<HypernumConfig>[] = [];
155
+
156
+ // Load environment variables first (highest priority)
157
+ const envConfig = this.loadEnvConfig();
158
+ if (Object.keys(envConfig).length > 0) {
159
+ configs.push(envConfig);
160
+ }
161
+
162
+ // Load from config files in order of priority
163
+ for (const source of [ConfigSource.RC_FILE, ConfigSource.JSON_FILE, ConfigSource.JS_FILE]) {
164
+ const filePath = configFiles.get(source);
165
+ if (filePath) {
166
+ const fileConfig = this.loadConfigFromFile(filePath);
167
+ configs.push(fileConfig);
168
+ }
169
+ }
170
+
171
+ // Merge configurations with default config as base
172
+ let finalConfig = {} as HypernumConfig;
173
+ for (const config of configs.reverse()) {
174
+ finalConfig = mergeConfig({ ...finalConfig, ...config });
175
+ }
176
+
177
+ // Cache the configuration
178
+ this.cachedConfig = finalConfig;
179
+ return finalConfig;
180
+ }
181
+
182
+ /**
183
+ * Loads environment variables as configuration
184
+ */
185
+ public loadEnvConfig(): Partial<HypernumConfig> {
186
+ const envConfig: Partial<HypernumConfig> = {};
187
+ // Load environment variables here and populate envConfig
188
+ // Example: envConfig.someKey = process.env.SOME_ENV_VAR;
189
+ return envConfig;
190
+ }
191
+
192
+
193
+ /**
194
+ * Saves configuration to a file
195
+ */
196
+ public saveConfig(config: HypernumConfig, filePath: string): void {
197
+ try {
198
+ const extension = path.extname(filePath);
199
+
200
+ switch (extension) {
201
+ case '.js':
202
+ const jsContent = `module.exports = ${this.configParser.stringifyConfig(config)};`;
203
+ fs.writeFileSync(filePath, jsContent, 'utf-8');
204
+ break;
205
+ case '.json':
206
+ fs.writeFileSync(filePath, this.configParser.stringifyConfig(config), 'utf-8');
207
+ break;
208
+ default:
209
+ if (filePath.includes('.hypernumrc')) {
210
+ fs.writeFileSync(filePath, this.configParser.stringifyConfig(config), 'utf-8');
211
+ } else {
212
+ throw new Error(`Unsupported config file extension: ${extension}`);
213
+ }
214
+ }
215
+ } catch (error) {
216
+ console.error(`Error saving config to ${filePath}:`, error);
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Clears the configuration cache
222
+ */
223
+ public clearCache(): void {
224
+ this.cachedConfig = null;
225
+ }
226
+ }
@@ -0,0 +1,161 @@
1
+
2
+
3
+ /**
4
+ * src/config/config-parser.ts
5
+ * Parses configuration files in different formats
6
+ */
7
+
8
+ import { HypernumConfig } from "@/core";
9
+ import path from "path";
10
+ import fs from 'fs';
11
+
12
+
13
+ export class ConfigParser {
14
+ /**
15
+ * Parses a JSON configuration file
16
+ */
17
+ public parseJsonConfig(filePath: string): Partial<HypernumConfig> {
18
+ try {
19
+ const content = fs.readFileSync(filePath, 'utf-8');
20
+ return JSON.parse(content) as Partial<HypernumConfig>;
21
+ } catch (error) {
22
+ console.error(`Error parsing JSON config file ${filePath}:`, error);
23
+ return {};
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Parses a JavaScript configuration file
29
+ */
30
+ public parseJsConfig(filePath: string): Partial<HypernumConfig> {
31
+ try {
32
+ // Use dynamic import for ESM compatibility
33
+ if (path.isAbsolute(filePath)) {
34
+ // For Node.js environments
35
+ const config = require(filePath);
36
+ return config.default || config;
37
+ } else {
38
+ // For browser environments or when relative path is used
39
+ const absolutePath = path.resolve(process.cwd(), filePath);
40
+ const config = require(absolutePath);
41
+ return config.default || config;
42
+ }
43
+ } catch (error) {
44
+ console.error(`Error parsing JS config file ${filePath}:`, error);
45
+ return {};
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Parses an RC configuration file
51
+ */
52
+ public parseRcConfig(filePath: string): Partial<HypernumConfig> {
53
+ try {
54
+ const content = fs.readFileSync(filePath, 'utf-8');
55
+
56
+ // Try to parse as JSON first
57
+ try {
58
+ return JSON.parse(content) as Partial<HypernumConfig>;
59
+ } catch {
60
+ // Not valid JSON, try to parse as JS if it has JS-like syntax
61
+ if (content.includes('module.exports') || content.includes('export default')) {
62
+ // Create a temporary JS file to require
63
+ const tempFilePath = `${filePath}.temp.js`;
64
+ fs.writeFileSync(tempFilePath, content);
65
+
66
+ try {
67
+ const config = require(tempFilePath);
68
+ fs.unlinkSync(tempFilePath); // Clean up temp file
69
+ return config.default || config;
70
+ } catch (jsError) {
71
+ fs.unlinkSync(tempFilePath); // Clean up temp file even on error
72
+ throw jsError;
73
+ }
74
+ }
75
+
76
+ // Handle INI-style RC files
77
+ return this.parseIniStyleConfig(content);
78
+ }
79
+ } catch (error) {
80
+ console.error(`Error parsing RC config file ${filePath}:`, error);
81
+ return {};
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Parses an INI-style configuration
87
+ */
88
+ private parseIniStyleConfig(content: string): Partial<HypernumConfig> {
89
+ const config: Record<string, any> = {};
90
+ let currentSection = '';
91
+
92
+ const lines = content.split('\n');
93
+
94
+ for (const line of lines) {
95
+ const trimmedLine = line.trim();
96
+
97
+ // Skip comments and empty lines
98
+ if (trimmedLine.startsWith('#') || trimmedLine.startsWith(';') || !trimmedLine) {
99
+ continue;
100
+ }
101
+
102
+ // Section header
103
+ const sectionMatch = trimmedLine.match(/^\[([^\]]+)\]$/);
104
+ if (sectionMatch) {
105
+ if (sectionMatch[1]) {
106
+ currentSection = sectionMatch[1];
107
+ if (!config[currentSection]) {
108
+ config[currentSection] = {};
109
+ }
110
+ continue;
111
+ }
112
+ }
113
+
114
+ // Key-value pair
115
+ const keyValueMatch = trimmedLine.match(/^([^=]+)=(.*)$/);
116
+ if (keyValueMatch) {
117
+ const key = keyValueMatch[1]?.trim() || '';
118
+ let value: any = keyValueMatch[2] ? keyValueMatch[2].trim() : '';
119
+
120
+ // Try to parse the value
121
+ if (value === 'true' || value === 'false') {
122
+ value = value === 'true';
123
+ } else if (!isNaN(Number(value))) {
124
+ value = Number(value);
125
+ } else if (value.startsWith('"') && value.endsWith('"')) {
126
+ value = value.slice(1, -1);
127
+ } else if (value.startsWith("'") && value.endsWith("'")) {
128
+ value = value.slice(1, -1);
129
+ }
130
+
131
+ if (currentSection) {
132
+ config[currentSection][key] = value;
133
+ } else {
134
+ config[key] = value;
135
+ }
136
+ }
137
+ }
138
+
139
+ return config as Partial<HypernumConfig>;
140
+ }
141
+
142
+ /**
143
+ * Stringifies a configuration object for saving
144
+ */
145
+ public stringifyConfig(config: HypernumConfig): string {
146
+ // Use a custom replacer function to handle BigInt and circular references
147
+ const seen = new WeakSet();
148
+ return JSON.stringify(config, (_, value) => {
149
+ if (typeof value === 'bigint') {
150
+ return value.toString() + 'n';
151
+ }
152
+ if (typeof value === 'object' && value !== null) {
153
+ if (seen.has(value)) {
154
+ return '[Circular]';
155
+ }
156
+ seen.add(value);
157
+ }
158
+ return value;
159
+ }, 2);
160
+ }
161
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * src/config/config-resolver.ts
3
+ * Resolves configuration from multiple sources
4
+ */
5
+ import { HypernumConfig, mergeConfig } from '../core/config';
6
+ import { ConfigSource } from './config-source';
7
+
8
+ export class ConfigResolver {
9
+ /**
10
+ * Default precedence order for configuration sources
11
+ */
12
+ private readonly DEFAULT_PRECEDENCE: ConfigSource[] = [
13
+ ConfigSource.INLINE_CONFIG, // Highest priority
14
+ ConfigSource.ENV_VARIABLES,
15
+ ConfigSource.RC_FILE,
16
+ ConfigSource.JSON_FILE,
17
+ ConfigSource.JS_FILE // Lowest priority
18
+ ];
19
+
20
+ /**
21
+ * Resolves configuration from multiple sources
22
+ */
23
+ public resolveConfig(configs: Map<ConfigSource, Partial<HypernumConfig>>): HypernumConfig {
24
+ // Sort configurations by precedence
25
+ const sortedEntries = Array.from(configs.entries())
26
+ .sort((a, b) => {
27
+ const indexA = this.DEFAULT_PRECEDENCE.indexOf(a[0]);
28
+ const indexB = this.DEFAULT_PRECEDENCE.indexOf(b[0]);
29
+ return indexA - indexB;
30
+ });
31
+
32
+ // Merge configurations in order (low to high priority)
33
+ let finalConfig = {} as HypernumConfig;
34
+ for (const [_, config] of sortedEntries) {
35
+ finalConfig = mergeConfig({ ...finalConfig, ...config });
36
+ }
37
+
38
+ return finalConfig;
39
+ }
40
+
41
+ /**
42
+ * Validates a configuration source
43
+ */
44
+ public validateConfigSource(config: Partial<HypernumConfig>): boolean {
45
+ // Basic validation for now - can be extended with schema validation
46
+ if (!config || typeof config !== 'object') {
47
+ return false;
48
+ }
49
+
50
+ return true;
51
+ }
52
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * src/config/config-source.ts
3
+ * Enum defining possible configuration sources
4
+ */
5
+ export enum ConfigSource {
6
+ /**
7
+ * Environment variables with HYPERNUM_ prefix
8
+ */
9
+ ENV_VARIABLES = 'ENV_VARIABLES',
10
+
11
+ /**
12
+ * RC file (.hypernumrc, .hypernumrc.json, etc.)
13
+ */
14
+ RC_FILE = 'RC_FILE',
15
+
16
+ /**
17
+ * JSON configuration file (hypernum.config.json)
18
+ */
19
+ JSON_FILE = 'JSON_FILE',
20
+
21
+ /**
22
+ * JavaScript configuration file (hypernum.config.js)
23
+ */
24
+ JS_FILE = 'JS_FILE',
25
+
26
+ /**
27
+ * Inline configuration passed to createHypernum()
28
+ */
29
+ INLINE_CONFIG = 'INLINE_CONFIG'
30
+ }
31
+
32
+
@@ -0,0 +1,159 @@
1
+ /**
2
+ * src/config/index.ts
3
+ * Main configuration module
4
+ */
5
+ import { HypernumConfig,DEFAULT_BASIC_CONFIG, DEFAULT_FULL_CONFIG } from '../core/config';
6
+ import { ConfigLoader } from './config-loader';
7
+ import { ConfigParser } from './config-parser';
8
+ import { ConfigResolver } from './config-resolver';
9
+ import { ConfigSource } from './config-source';
10
+
11
+ interface ConfigurationOptions {
12
+ /**
13
+ * Path to a configuration file to use
14
+ */
15
+ configFile?: string;
16
+
17
+ /**
18
+ * Whether to search for configuration files in parent directories
19
+ */
20
+ searchParentDirs?: boolean;
21
+
22
+ /**
23
+ * Additional paths to search for configuration files
24
+ */
25
+ additionalSearchPaths?: string[];
26
+
27
+ /**
28
+ * Whether to use environment variables
29
+ */
30
+ useEnvVars?: boolean;
31
+
32
+ /**
33
+ * Whether to cache the configuration
34
+ */
35
+ cacheConfig?: boolean;
36
+
37
+ /**
38
+ * Inline configuration to use as a base
39
+ */
40
+ baseConfig?: Partial<HypernumConfig>;
41
+ }
42
+
43
+ /**
44
+ * Main configuration module for Hypernum
45
+ */
46
+ export class ConfigurationModule {
47
+ public configLoader: ConfigLoader;
48
+ public configParser: ConfigParser;
49
+ public configResolver: ConfigResolver;
50
+ public cachedConfig: HypernumConfig | null = null;
51
+
52
+ constructor() {
53
+ this.configLoader = new ConfigLoader();
54
+ this.configParser = new ConfigParser();
55
+ this.configResolver = new ConfigResolver();
56
+ }
57
+
58
+ /**
59
+ * Gets the configuration, loading from all available sources
60
+ */
61
+ public getConfig(options: ConfigurationOptions = {}): HypernumConfig {
62
+ const {
63
+ configFile,
64
+ searchParentDirs = true,
65
+ additionalSearchPaths = [],
66
+ useEnvVars = true,
67
+ cacheConfig = true,
68
+ baseConfig = {}
69
+ } = options;
70
+
71
+ // Return cached config if available and caching is enabled
72
+ if (this.cachedConfig && cacheConfig) {
73
+ return this.cachedConfig;
74
+ }
75
+
76
+ const configs = new Map<ConfigSource, Partial<HypernumConfig>>();
77
+
78
+ // Add base config (lowest priority)
79
+ if (Object.keys(baseConfig).length > 0) {
80
+ configs.set(ConfigSource.INLINE_CONFIG, baseConfig);
81
+ }
82
+
83
+ // Load from specific file if provided
84
+ if (configFile) {
85
+ const fileConfig = this.configLoader.loadConfigFromFile(configFile);
86
+ const source = this.configLoader.getConfigSourceFromFilename(configFile);
87
+ if (this.configResolver.validateConfigSource(fileConfig)) {
88
+ configs.set(source, fileConfig);
89
+ }
90
+ } else {
91
+ // Search for configuration files
92
+ const configFiles = this.configLoader.findConfigFiles({
93
+ searchParentDirs,
94
+ additionalPaths: additionalSearchPaths
95
+ });
96
+
97
+ for (const [source, filePath] of configFiles.entries()) {
98
+ const fileConfig = this.configLoader.loadConfigFromFile(filePath);
99
+ if (this.configResolver.validateConfigSource(fileConfig)) {
100
+ configs.set(source, fileConfig);
101
+ }
102
+ }
103
+ }
104
+
105
+ // Load environment variables if enabled
106
+ if (useEnvVars) {
107
+ const envConfig = this.configLoader.loadEnvConfig();
108
+ if (Object.keys(envConfig).length > 0) {
109
+ configs.set(ConfigSource.ENV_VARIABLES, envConfig);
110
+ }
111
+ }
112
+
113
+ // Resolve the final configuration
114
+ const finalConfig = this.configResolver.resolveConfig(configs);
115
+
116
+ // Cache the configuration if caching is enabled
117
+ if (cacheConfig) {
118
+ this.cachedConfig = finalConfig;
119
+ }
120
+
121
+ return finalConfig;
122
+ }
123
+
124
+ /**
125
+ * Initializes configuration from a file
126
+ */
127
+ public initializeFromFile(filePath: string, options: ConfigurationOptions = {}): HypernumConfig {
128
+ return this.getConfig({
129
+ ...options,
130
+ configFile: filePath
131
+ });
132
+ }
133
+
134
+ /**
135
+ * Creates a default configuration
136
+ */
137
+ public createDefaultConfig(type: 'basic' | 'full'): HypernumConfig {
138
+ return type === 'basic' ? DEFAULT_BASIC_CONFIG : DEFAULT_FULL_CONFIG;
139
+ }
140
+
141
+ /**
142
+ * Saves configuration to a file
143
+ */
144
+ public saveConfigToFile(config: HypernumConfig, filePath: string): void {
145
+ this.configLoader.saveConfig(config, filePath);
146
+ }
147
+
148
+ public getConfigSourceFromFilename(filename: string): ConfigSource {
149
+ return this.configLoader.getConfigSourceFromFilename(filename);
150
+ }
151
+
152
+ /**
153
+ * Clears the configuration cache
154
+ */
155
+ public clearCache(): void {
156
+ this.cachedConfig = null;
157
+ this.configLoader.clearCache();
158
+ }
159
+ }