@dsmrt/axiom-config 1.0.0 → 1.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @dsmrt/axiom-config
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 5edaee0: load config by env
8
+
9
+ ## 1.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - b1a56bc: adding debug logging to the cli and config packages
14
+
3
15
  ## 1.0.0
4
16
 
5
17
  ### Major Changes
package/dist/index.d.mts CHANGED
@@ -39,6 +39,7 @@ interface LoadConfigInput {
39
39
  cwd?: string;
40
40
  }
41
41
  declare const importConfigFromPath: (path: string) => Promise<Config>;
42
+ declare const loadConfigByEnv: <T extends object>(env: string, options?: Omit<LoadConfigInput, "env">) => Promise<ConfigContainer & T>;
42
43
  declare const loadConfig: <T extends object>(input?: LoadConfigInput) => Promise<ConfigContainer & T>;
43
44
  /**
44
45
  * Simple object check.
@@ -50,4 +51,4 @@ declare function isObject(item: unknown): unknown;
50
51
  declare function mergeDeep(target: any, ...sources: any[]): any;
51
52
  declare const configPath: (input?: LoadConfigInput) => string;
52
53
 
53
- export { type AwsConfigs, type BaseConfig, type Config, ConfigContainer, type LoadConfigInput, configPath, importConfigFromPath, isObject, loadConfig, mergeDeep };
54
+ export { type AwsConfigs, type BaseConfig, type Config, ConfigContainer, type LoadConfigInput, configPath, importConfigFromPath, isObject, loadConfig, loadConfigByEnv, mergeDeep };
package/dist/index.d.ts CHANGED
@@ -39,6 +39,7 @@ interface LoadConfigInput {
39
39
  cwd?: string;
40
40
  }
41
41
  declare const importConfigFromPath: (path: string) => Promise<Config>;
42
+ declare const loadConfigByEnv: <T extends object>(env: string, options?: Omit<LoadConfigInput, "env">) => Promise<ConfigContainer & T>;
42
43
  declare const loadConfig: <T extends object>(input?: LoadConfigInput) => Promise<ConfigContainer & T>;
43
44
  /**
44
45
  * Simple object check.
@@ -50,4 +51,4 @@ declare function isObject(item: unknown): unknown;
50
51
  declare function mergeDeep(target: any, ...sources: any[]): any;
51
52
  declare const configPath: (input?: LoadConfigInput) => string;
52
53
 
53
- export { type AwsConfigs, type BaseConfig, type Config, ConfigContainer, type LoadConfigInput, configPath, importConfigFromPath, isObject, loadConfig, mergeDeep };
54
+ export { type AwsConfigs, type BaseConfig, type Config, ConfigContainer, type LoadConfigInput, configPath, importConfigFromPath, isObject, loadConfig, loadConfigByEnv, mergeDeep };
package/dist/index.js CHANGED
@@ -25,11 +25,18 @@ __export(index_exports, {
25
25
  importConfigFromPath: () => importConfigFromPath,
26
26
  isObject: () => isObject,
27
27
  loadConfig: () => loadConfig,
28
+ loadConfigByEnv: () => loadConfigByEnv,
28
29
  mergeDeep: () => mergeDeep
29
30
  });
30
31
  module.exports = __toCommonJS(index_exports);
31
32
  var import_node_fs = require("fs");
32
- var import_find_up = require("find-up");
33
+ var import_glob = require("glob");
34
+ var isDebugEnabled = () => process.env.AXIOM_DEBUG === "true" || process.env.AXIOM_DEBUG === "1";
35
+ var debug = (message, ...args) => {
36
+ if (isDebugEnabled()) {
37
+ console.error(`[axiom:config] ${message}`, ...args);
38
+ }
39
+ };
33
40
  var ConfigContainer = class {
34
41
  name;
35
42
  env;
@@ -52,31 +59,79 @@ var ConfigContainer = class {
52
59
  }
53
60
  };
54
61
  var importConfigFromPath = async (path) => {
62
+ debug(`Attempting to import config from: ${path}`);
55
63
  if (/\.json$/.test(path)) {
56
- return JSON.parse((0, import_node_fs.readFileSync)(path).toString());
64
+ debug(`Loading JSON config file: ${path}`);
65
+ try {
66
+ const config = JSON.parse((0, import_node_fs.readFileSync)(path).toString());
67
+ debug(`Successfully loaded JSON config with name: ${config.name}`);
68
+ return config;
69
+ } catch (error) {
70
+ debug(`Failed to parse JSON config: ${error}`);
71
+ throw error;
72
+ }
57
73
  }
58
74
  if (/\.((m)?ts|mjs)$/.test(path)) {
59
- const loaded = await import(path);
60
- return loaded.default || loaded;
75
+ debug(`Loading TypeScript/ESM config file: ${path}`);
76
+ try {
77
+ const loaded = await import(path);
78
+ const config = loaded.default || loaded;
79
+ debug(`Successfully loaded TS/ESM config with name: ${config.name}`);
80
+ return config;
81
+ } catch (error) {
82
+ debug(`Failed to import TS/ESM config: ${error}`);
83
+ throw error;
84
+ }
61
85
  }
62
86
  if (/\.(m)?js$/.test(path)) {
63
- const loaded = require(path);
64
- return loaded.default || loaded;
87
+ debug(`Loading JavaScript config file: ${path}`);
88
+ try {
89
+ const loaded = require(path);
90
+ const config = loaded.default || loaded;
91
+ debug(`Successfully loaded JS config with name: ${config.name}`);
92
+ return config;
93
+ } catch (error) {
94
+ debug(`Failed to require JS config: ${error}`);
95
+ throw error;
96
+ }
65
97
  }
98
+ debug(`Unsupported file type: ${path}`);
66
99
  throw new Error(`Unsupported file type or path not found: ${path}`);
67
100
  };
101
+ var loadConfigByEnv = async (env, options) => {
102
+ return await loadConfig({ env, ...options });
103
+ };
68
104
  var loadConfig = async (input) => {
105
+ debug(
106
+ `Loading config with options:`,
107
+ JSON.stringify({
108
+ env: input?.env,
109
+ cwd: input?.cwd,
110
+ hasOverrides: !!input?.overrides
111
+ })
112
+ );
113
+ debug(`Looking for base config file...`);
69
114
  const baseConfigFile = configPath({
70
115
  ...input,
71
116
  env: void 0
72
117
  });
118
+ debug(`Loading base config from: ${baseConfigFile}`);
73
119
  const baseConfig = await importConfigFromPath(baseConfigFile);
120
+ debug(`Base config loaded: ${baseConfig.name} (env: ${baseConfig.env})`);
74
121
  let overrides = input?.overrides || {};
75
122
  if (input?.env) {
76
- const devConfig = await importConfigFromPath(configPath(input));
123
+ debug(`Looking for environment-specific config for: ${input.env}`);
124
+ const envConfigPath = configPath(input);
125
+ debug(`Loading env config from: ${envConfigPath}`);
126
+ const devConfig = await importConfigFromPath(envConfigPath);
127
+ debug(`Env config loaded: ${devConfig.name} (env: ${devConfig.env})`);
77
128
  overrides = mergeDeep(devConfig, overrides);
129
+ debug(`Merged env config with overrides`);
78
130
  }
79
131
  const configObject = mergeDeep(baseConfig, overrides);
132
+ debug(
133
+ `Final config: ${configObject.name} (env: ${configObject.env}, isProd: ${configObject.env === (configObject.prodEnvName || "prod")})`
134
+ );
80
135
  return new ConfigContainer(configObject);
81
136
  };
82
137
  function isObject(item) {
@@ -99,21 +154,39 @@ function mergeDeep(target, ...sources) {
99
154
  }
100
155
  var configPath = (input) => {
101
156
  const envIndicator = input?.env ? `.${input.env}` : "";
102
- const p = (0, import_find_up.sync)(
103
- [
104
- `.axiom${envIndicator}.json`,
105
- `.axiom${envIndicator}.js`,
106
- `.axiom${envIndicator}.mjs`,
107
- `.axiom${envIndicator}.ts`,
108
- `.axiom${envIndicator}.mts`
109
- ],
110
- { cwd: input?.cwd }
157
+ const extensions = ["json", "js", "mjs", "ts", "mts"];
158
+ const pattern = `.axiom${envIndicator}.{${extensions.join(",")}}`;
159
+ debug(
160
+ `Searching for config files with pattern: ${pattern}`,
161
+ input?.cwd ? `from ${input.cwd}` : "from current directory"
111
162
  );
112
- if (p === void 0)
163
+ const cwd = input?.cwd || process.cwd();
164
+ let currentDir = cwd;
165
+ let found;
166
+ while (true) {
167
+ const matches = (0, import_glob.globSync)(pattern, {
168
+ cwd: currentDir,
169
+ absolute: true,
170
+ nodir: true
171
+ });
172
+ if (matches.length > 0) {
173
+ found = matches[0];
174
+ break;
175
+ }
176
+ const parent = require("path").dirname(currentDir);
177
+ if (parent === currentDir) {
178
+ break;
179
+ }
180
+ currentDir = parent;
181
+ }
182
+ if (found === void 0) {
183
+ debug(`Config file not found! Searched for pattern: ${pattern}`);
113
184
  throw new Error(
114
185
  `Axiom config files not found: .axiom${envIndicator}.json, .axiom${envIndicator}.js .axiom${envIndicator}.ts`
115
186
  );
116
- return p;
187
+ }
188
+ debug(`Found config file: ${found}`);
189
+ return found;
117
190
  };
118
191
  // Annotate the CommonJS export names for ESM import in node:
119
192
  0 && (module.exports = {
@@ -122,5 +195,6 @@ var configPath = (input) => {
122
195
  importConfigFromPath,
123
196
  isObject,
124
197
  loadConfig,
198
+ loadConfigByEnv,
125
199
  mergeDeep
126
200
  });
package/dist/index.mjs CHANGED
@@ -7,7 +7,13 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
7
7
 
8
8
  // src/index.ts
9
9
  import { readFileSync } from "fs";
10
- import { sync as findUpSync } from "find-up";
10
+ import { globSync } from "glob";
11
+ var isDebugEnabled = () => process.env.AXIOM_DEBUG === "true" || process.env.AXIOM_DEBUG === "1";
12
+ var debug = (message, ...args) => {
13
+ if (isDebugEnabled()) {
14
+ console.error(`[axiom:config] ${message}`, ...args);
15
+ }
16
+ };
11
17
  var ConfigContainer = class {
12
18
  name;
13
19
  env;
@@ -30,31 +36,79 @@ var ConfigContainer = class {
30
36
  }
31
37
  };
32
38
  var importConfigFromPath = async (path) => {
39
+ debug(`Attempting to import config from: ${path}`);
33
40
  if (/\.json$/.test(path)) {
34
- return JSON.parse(readFileSync(path).toString());
41
+ debug(`Loading JSON config file: ${path}`);
42
+ try {
43
+ const config = JSON.parse(readFileSync(path).toString());
44
+ debug(`Successfully loaded JSON config with name: ${config.name}`);
45
+ return config;
46
+ } catch (error) {
47
+ debug(`Failed to parse JSON config: ${error}`);
48
+ throw error;
49
+ }
35
50
  }
36
51
  if (/\.((m)?ts|mjs)$/.test(path)) {
37
- const loaded = await import(path);
38
- return loaded.default || loaded;
52
+ debug(`Loading TypeScript/ESM config file: ${path}`);
53
+ try {
54
+ const loaded = await import(path);
55
+ const config = loaded.default || loaded;
56
+ debug(`Successfully loaded TS/ESM config with name: ${config.name}`);
57
+ return config;
58
+ } catch (error) {
59
+ debug(`Failed to import TS/ESM config: ${error}`);
60
+ throw error;
61
+ }
39
62
  }
40
63
  if (/\.(m)?js$/.test(path)) {
41
- const loaded = __require(path);
42
- return loaded.default || loaded;
64
+ debug(`Loading JavaScript config file: ${path}`);
65
+ try {
66
+ const loaded = __require(path);
67
+ const config = loaded.default || loaded;
68
+ debug(`Successfully loaded JS config with name: ${config.name}`);
69
+ return config;
70
+ } catch (error) {
71
+ debug(`Failed to require JS config: ${error}`);
72
+ throw error;
73
+ }
43
74
  }
75
+ debug(`Unsupported file type: ${path}`);
44
76
  throw new Error(`Unsupported file type or path not found: ${path}`);
45
77
  };
78
+ var loadConfigByEnv = async (env, options) => {
79
+ return await loadConfig({ env, ...options });
80
+ };
46
81
  var loadConfig = async (input) => {
82
+ debug(
83
+ `Loading config with options:`,
84
+ JSON.stringify({
85
+ env: input?.env,
86
+ cwd: input?.cwd,
87
+ hasOverrides: !!input?.overrides
88
+ })
89
+ );
90
+ debug(`Looking for base config file...`);
47
91
  const baseConfigFile = configPath({
48
92
  ...input,
49
93
  env: void 0
50
94
  });
95
+ debug(`Loading base config from: ${baseConfigFile}`);
51
96
  const baseConfig = await importConfigFromPath(baseConfigFile);
97
+ debug(`Base config loaded: ${baseConfig.name} (env: ${baseConfig.env})`);
52
98
  let overrides = input?.overrides || {};
53
99
  if (input?.env) {
54
- const devConfig = await importConfigFromPath(configPath(input));
100
+ debug(`Looking for environment-specific config for: ${input.env}`);
101
+ const envConfigPath = configPath(input);
102
+ debug(`Loading env config from: ${envConfigPath}`);
103
+ const devConfig = await importConfigFromPath(envConfigPath);
104
+ debug(`Env config loaded: ${devConfig.name} (env: ${devConfig.env})`);
55
105
  overrides = mergeDeep(devConfig, overrides);
106
+ debug(`Merged env config with overrides`);
56
107
  }
57
108
  const configObject = mergeDeep(baseConfig, overrides);
109
+ debug(
110
+ `Final config: ${configObject.name} (env: ${configObject.env}, isProd: ${configObject.env === (configObject.prodEnvName || "prod")})`
111
+ );
58
112
  return new ConfigContainer(configObject);
59
113
  };
60
114
  function isObject(item) {
@@ -77,21 +131,39 @@ function mergeDeep(target, ...sources) {
77
131
  }
78
132
  var configPath = (input) => {
79
133
  const envIndicator = input?.env ? `.${input.env}` : "";
80
- const p = findUpSync(
81
- [
82
- `.axiom${envIndicator}.json`,
83
- `.axiom${envIndicator}.js`,
84
- `.axiom${envIndicator}.mjs`,
85
- `.axiom${envIndicator}.ts`,
86
- `.axiom${envIndicator}.mts`
87
- ],
88
- { cwd: input?.cwd }
134
+ const extensions = ["json", "js", "mjs", "ts", "mts"];
135
+ const pattern = `.axiom${envIndicator}.{${extensions.join(",")}}`;
136
+ debug(
137
+ `Searching for config files with pattern: ${pattern}`,
138
+ input?.cwd ? `from ${input.cwd}` : "from current directory"
89
139
  );
90
- if (p === void 0)
140
+ const cwd = input?.cwd || process.cwd();
141
+ let currentDir = cwd;
142
+ let found;
143
+ while (true) {
144
+ const matches = globSync(pattern, {
145
+ cwd: currentDir,
146
+ absolute: true,
147
+ nodir: true
148
+ });
149
+ if (matches.length > 0) {
150
+ found = matches[0];
151
+ break;
152
+ }
153
+ const parent = __require("path").dirname(currentDir);
154
+ if (parent === currentDir) {
155
+ break;
156
+ }
157
+ currentDir = parent;
158
+ }
159
+ if (found === void 0) {
160
+ debug(`Config file not found! Searched for pattern: ${pattern}`);
91
161
  throw new Error(
92
162
  `Axiom config files not found: .axiom${envIndicator}.json, .axiom${envIndicator}.js .axiom${envIndicator}.ts`
93
163
  );
94
- return p;
164
+ }
165
+ debug(`Found config file: ${found}`);
166
+ return found;
95
167
  };
96
168
  export {
97
169
  ConfigContainer,
@@ -99,5 +171,6 @@ export {
99
171
  importConfigFromPath,
100
172
  isObject,
101
173
  loadConfig,
174
+ loadConfigByEnv,
102
175
  mergeDeep
103
176
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsmrt/axiom-config",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Config library for axiom cli",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -35,7 +35,7 @@
35
35
  "vitest": "^4.0.0"
36
36
  },
37
37
  "dependencies": {
38
- "find-up": "^5.0.0",
38
+ "glob": "^10.5.0",
39
39
  "yargs": "^17.7.2"
40
40
  },
41
41
  "scripts": {