@botbotgo/common 1.0.1 → 1.0.3

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.
@@ -67,46 +67,50 @@ function parseYamlContent(content, options = {}) {
67
67
  missingEnv: options.missingEnv ?? "keep"
68
68
  });
69
69
  }
70
- function readFromCache(filePath, mtimeMs) {
70
+ function buildCacheVersion(fileStat) {
71
+ const mtime = fileStat.mtimeNs ?? (typeof fileStat.mtimeMs === "bigint" ? fileStat.mtimeMs : BigInt(Math.trunc(fileStat.mtimeMs * 1e6)));
72
+ return `${mtime}:${fileStat.size.toString()}`;
73
+ }
74
+ function readFromCache(filePath, version) {
71
75
  const cached = YAML_CACHE.get(filePath);
72
76
  if (!cached) return void 0;
73
- if (cached.mtimeMs !== mtimeMs) return void 0;
77
+ if (cached.version !== version) return void 0;
74
78
  return cached.value;
75
79
  }
76
- function writeCache(filePath, mtimeMs, value) {
77
- YAML_CACHE.set(filePath, { mtimeMs, value });
80
+ function writeCache(filePath, version, value) {
81
+ YAML_CACHE.set(filePath, { version, value });
78
82
  }
79
83
  function loadYamlFileSync(filePath, options = {}) {
80
84
  const absPath = path2.resolve(filePath);
81
85
  if (!existsSync(absPath)) return void 0;
82
86
  const useCache = options.cache === true;
83
- const fileStat = statSync(absPath);
87
+ const fileStat = statSync(absPath, { bigint: true });
84
88
  if (useCache) {
85
- const cached = readFromCache(absPath, fileStat.mtimeMs);
89
+ const cached = readFromCache(absPath, buildCacheVersion(fileStat));
86
90
  if (cached !== void 0) return cached;
87
91
  }
88
92
  const content = readFileSync(absPath, "utf-8");
89
93
  const parsed = parseYamlContent(content, options);
90
- if (useCache) writeCache(absPath, fileStat.mtimeMs, parsed);
94
+ if (useCache) writeCache(absPath, buildCacheVersion(fileStat), parsed);
91
95
  return parsed;
92
96
  }
93
97
  async function loadYamlFile(filePath, options = {}) {
94
98
  const absPath = path2.resolve(filePath);
95
99
  let fileStat;
96
100
  try {
97
- fileStat = await stat(absPath);
101
+ fileStat = await stat(absPath, { bigint: true });
98
102
  } catch (err) {
99
103
  if (err?.code === "ENOENT") return void 0;
100
104
  throw err;
101
105
  }
102
106
  const useCache = options.cache === true;
103
107
  if (useCache) {
104
- const cached = readFromCache(absPath, fileStat.mtimeMs);
108
+ const cached = readFromCache(absPath, buildCacheVersion(fileStat));
105
109
  if (cached !== void 0) return cached;
106
110
  }
107
111
  const content = await readFile(absPath, "utf-8");
108
112
  const parsed = parseYamlContent(content, options);
109
- if (useCache) writeCache(absPath, fileStat.mtimeMs, parsed);
113
+ if (useCache) writeCache(absPath, buildCacheVersion(fileStat), parsed);
110
114
  return parsed;
111
115
  }
112
116
 
@@ -203,4 +207,4 @@ export {
203
207
  isRefNode,
204
208
  resolveKindResourceFile
205
209
  };
206
- //# sourceMappingURL=chunk-X4TDNR4V.js.map
210
+ //# sourceMappingURL=chunk-2HMNFLD4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/yaml.ts","../src/config/path.ts","../src/config/kind.ts"],"sourcesContent":["import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { resolveConfigPath } from \"./path.js\";\n\nexport interface YamlEnvOptions {\n substituteEnv?: boolean;\n missingEnv?: \"keep\" | \"empty\";\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface LoadYamlOptions extends YamlEnvOptions {\n cache?: boolean;\n}\n\nexport interface LoadModuleConfigOptions<TConfig, TRaw = Record<string, unknown>> {\n path?: string;\n defaultPath?: string;\n appRoot?: string;\n yaml?: LoadYamlOptions;\n unwrapSpec?: boolean;\n fallback: TConfig;\n normalize?: (raw: TRaw, meta: { resolvedPath: string }) => TConfig;\n}\n\ninterface CacheEntry {\n version: string;\n value: unknown;\n}\n\nconst YAML_CACHE = new Map<string, CacheEntry>();\n\nexport function clearYamlFileCache(): void {\n YAML_CACHE.clear();\n}\n\nfunction substituteEnvInString(\n input: string,\n env: NodeJS.ProcessEnv,\n missingEnv: \"keep\" | \"empty\",\n): string {\n return input.replace(/\\$\\{(\\w+)\\}/g, (_, name: string) => {\n const value = env[name];\n if (value !== undefined) return value;\n return missingEnv === \"empty\" ? \"\" : `\\${${name}}`;\n });\n}\n\nfunction substituteEnvInValue(\n input: unknown,\n options: { env: NodeJS.ProcessEnv; missingEnv: \"keep\" | \"empty\" },\n): unknown {\n if (typeof input === \"string\") {\n return substituteEnvInString(input, options.env, options.missingEnv);\n }\n if (Array.isArray(input)) {\n return input.map((item) => substituteEnvInValue(item, options));\n }\n if (input && typeof input === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(input)) {\n out[k] = substituteEnvInValue(v, options);\n }\n return out;\n }\n return input;\n}\n\nexport function parseYamlContent<T = unknown>(\n content: string,\n options: YamlEnvOptions = {},\n): T {\n const parsed = parseYaml(content) as unknown;\n if (options.substituteEnv === false) return parsed as T;\n return substituteEnvInValue(parsed, {\n env: options.env ?? process.env,\n missingEnv: options.missingEnv ?? \"keep\",\n }) as T;\n}\n\nfunction buildCacheVersion(\n fileStat: { mtimeNs?: bigint; mtimeMs: number | bigint; size: number | bigint },\n): string {\n const mtime = fileStat.mtimeNs\n ?? (typeof fileStat.mtimeMs === \"bigint\"\n ? fileStat.mtimeMs\n : BigInt(Math.trunc(fileStat.mtimeMs * 1_000_000)));\n return `${mtime}:${fileStat.size.toString()}`;\n}\n\nfunction readFromCache(filePath: string, version: string): unknown | undefined {\n const cached = YAML_CACHE.get(filePath);\n if (!cached) return undefined;\n if (cached.version !== version) return undefined;\n return cached.value;\n}\n\nfunction writeCache(filePath: string, version: string, value: unknown): void {\n YAML_CACHE.set(filePath, { version, value });\n}\n\nexport function loadYamlFileSync<T = unknown>(\n filePath: string,\n options: LoadYamlOptions = {},\n): T | undefined {\n const absPath = path.resolve(filePath);\n if (!existsSync(absPath)) return undefined;\n const useCache = options.cache === true;\n const fileStat = statSync(absPath, { bigint: true });\n if (useCache) {\n const cached = readFromCache(absPath, buildCacheVersion(fileStat));\n if (cached !== undefined) return cached as T;\n }\n const content = readFileSync(absPath, \"utf-8\");\n const parsed = parseYamlContent<T>(content, options);\n if (useCache) writeCache(absPath, buildCacheVersion(fileStat), parsed);\n return parsed;\n}\n\nexport async function loadYamlFile<T = unknown>(\n filePath: string,\n options: LoadYamlOptions = {},\n): Promise<T | undefined> {\n const absPath = path.resolve(filePath);\n let fileStat;\n try {\n fileStat = await stat(absPath, { bigint: true });\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === \"ENOENT\") return undefined;\n throw err;\n }\n const useCache = options.cache === true;\n if (useCache) {\n const cached = readFromCache(absPath, buildCacheVersion(fileStat));\n if (cached !== undefined) return cached as T;\n }\n const content = await readFile(absPath, \"utf-8\");\n const parsed = parseYamlContent<T>(content, options);\n if (useCache) writeCache(absPath, buildCacheVersion(fileStat), parsed);\n return parsed;\n}\n\nexport async function loadYamlObject(\n filePath: string,\n options: LoadYamlOptions = {},\n): Promise<Record<string, unknown>> {\n const parsed = await loadYamlFile<unknown>(filePath, options);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n return {};\n}\n\n/**\n * Generic module config loader:\n * 1) resolve path (path || defaultPath) relative to appRoot\n * 2) load YAML as object\n * 3) normalize into module-owned config interface\n * 4) fallback when missing/invalid\n */\nexport async function loadModuleConfig<TConfig, TRaw = Record<string, unknown>>(\n options: LoadModuleConfigOptions<TConfig, TRaw>,\n): Promise<TConfig> {\n const selected = options.path ?? options.defaultPath;\n if (!selected) return options.fallback;\n\n const appRoot = options.appRoot ?? process.cwd();\n const resolvedPath = resolveConfigPath(selected, appRoot);\n const loaded = await loadYamlFile<unknown>(resolvedPath, options.yaml);\n if (!loaded || typeof loaded !== \"object\" || Array.isArray(loaded)) return options.fallback;\n const raw = options.unwrapSpec === true\n ? (\n typeof (loaded as { spec?: unknown }).spec === \"object\" &&\n (loaded as { spec?: unknown }).spec !== null &&\n !Array.isArray((loaded as { spec?: unknown }).spec)\n ? (loaded as { spec: unknown }).spec\n : loaded\n )\n : loaded;\n\n if (options.normalize) {\n return options.normalize(raw as TRaw, { resolvedPath });\n }\n return raw as TConfig;\n}\n","import path from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface ResolveConfigPathOptions {\n expandHome?: boolean;\n homeDir?: string;\n}\n\nexport type PathRef = { ref?: string };\n\nexport function isPathRef(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length > 0 &&\n (value.endsWith(\".yaml\") || value.endsWith(\".yml\"))\n );\n}\n\nexport function expandHomePath(inputPath: string, options: { homeDir?: string } = {}): string {\n const home = options.homeDir ?? homedir();\n if (inputPath === \"~\") return home;\n if (inputPath.startsWith(\"~/\")) return path.join(home, inputPath.slice(2));\n return inputPath;\n}\n\nexport function resolveConfigPath(\n pathRef: string,\n configDir: string,\n options: ResolveConfigPathOptions = {},\n): string {\n const expanded = options.expandHome === false ? pathRef : expandHomePath(pathRef, { homeDir: options.homeDir });\n return path.resolve(configDir, expanded);\n}\n\nexport function asObject(input: unknown): Record<string, unknown> | undefined {\n return typeof input === \"object\" && input !== null ? (input as Record<string, unknown>) : undefined;\n}\n\nexport function toPathRef(input: unknown): PathRef | undefined {\n if (typeof input === \"string\" && input.trim().length > 0) return { ref: input.trim() };\n const obj = asObject(input);\n if (!obj) return undefined;\n const value =\n (typeof (obj as { __filePath?: unknown }).__filePath === \"string\" &&\n (obj as { __filePath: string }).__filePath.trim().length > 0\n ? (obj as { __filePath: string }).__filePath.trim()\n : undefined) ??\n (typeof obj.ref === \"string\" && obj.ref.trim().length > 0 ? obj.ref.trim() : undefined);\n return value ? { ref: value } : undefined;\n}\n","import { dirname } from \"node:path\";\nimport { loadYamlFile, type LoadYamlOptions } from \"./yaml.js\";\nimport { asObject, resolveConfigPath } from \"./path.js\";\n\nexport interface ResourceMetadata {\n name?: string;\n labels?: Record<string, string>;\n}\n\nexport interface ResourceHeader {\n apiVersion: string;\n kind: string;\n metadata?: ResourceMetadata;\n spec: unknown;\n}\n\nexport type RefNode = { ref: string };\n\nexport type ResolvedResource<TSpec = unknown> = ResourceHeader & {\n spec: TSpec;\n __filePath: string;\n};\n\nexport interface ResolveKindResourceOptions {\n baseDir?: string;\n maxDepth?: number;\n cache?: boolean;\n yaml?: LoadYamlOptions;\n expectedKind?: string;\n expectedApiVersion?: string;\n}\n\nfunction toResourceHeader(input: unknown): ResourceHeader {\n const obj = asObject(input);\n if (!obj) throw new Error(\"Invalid config document: expected object root\");\n\n const apiVersion = typeof obj.apiVersion === \"string\" ? obj.apiVersion.trim() : \"\";\n const kind = typeof obj.kind === \"string\" ? obj.kind.trim() : \"\";\n const spec = (obj as { spec?: unknown }).spec;\n if (!apiVersion) throw new Error(\"Invalid config document: missing apiVersion\");\n if (!kind) throw new Error(\"Invalid config document: missing kind\");\n if (spec === undefined) throw new Error(\"Invalid config document: missing spec\");\n const metadataRaw = asObject(obj.metadata);\n const metadata: ResourceMetadata | undefined = metadataRaw\n ? {\n name: typeof metadataRaw.name === \"string\" ? metadataRaw.name : undefined,\n labels:\n metadataRaw.labels && typeof metadataRaw.labels === \"object\" && !Array.isArray(metadataRaw.labels)\n ? (metadataRaw.labels as Record<string, string>)\n : undefined,\n }\n : undefined;\n return { apiVersion, kind, metadata, spec };\n}\n\nexport function isRefNode(input: unknown): input is RefNode {\n const obj = asObject(input);\n return !!obj && typeof obj.ref === \"string\" && obj.ref.trim().length > 0;\n}\n\nexport async function resolveKindResourceFile<TSpec = unknown>(\n entryFile: string,\n options: ResolveKindResourceOptions = {},\n): Promise<ResolvedResource<TSpec>> {\n const baseDir = options.baseDir ?? process.cwd();\n const entryAbs = resolveConfigPath(entryFile, baseDir);\n const maxDepth = options.maxDepth ?? 50;\n const cache = new Map<string, ResolvedResource>();\n const visiting = new Set<string>();\n\n const resolveNode = async (node: unknown, currentDir: string, depth: number): Promise<unknown> => {\n if (depth > maxDepth) throw new Error(`Config ref resolution exceeded maxDepth=${maxDepth}`);\n if (isRefNode(node)) {\n const next = resolveConfigPath(node.ref, currentDir);\n return loadResource(next, depth + 1);\n }\n if (Array.isArray(node)) {\n return Promise.all(node.map((item) => resolveNode(item, currentDir, depth + 1)));\n }\n const obj = asObject(node);\n if (!obj) return node;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n out[k] = await resolveNode(v, currentDir, depth + 1);\n }\n return out;\n };\n\n const loadResource = async (absPath: string, depth: number): Promise<ResolvedResource> => {\n if (depth > maxDepth) throw new Error(`Config ref resolution exceeded maxDepth=${maxDepth}`);\n if (options.cache !== false) {\n const cached = cache.get(absPath);\n if (cached) return cached;\n }\n if (visiting.has(absPath)) {\n throw new Error(`Config ref cycle detected at: ${absPath}`);\n }\n visiting.add(absPath);\n try {\n const raw = await loadYamlFile(absPath, options.yaml);\n const header = toResourceHeader(raw);\n if (options.expectedApiVersion && header.apiVersion !== options.expectedApiVersion) {\n throw new Error(`Unexpected apiVersion \"${header.apiVersion}\" at ${absPath}`);\n }\n const resolvedSpec = await resolveNode(header.spec, dirname(absPath), depth + 1);\n const resolved: ResolvedResource = {\n ...header,\n spec: resolvedSpec,\n __filePath: absPath,\n };\n if (options.cache !== false) cache.set(absPath, resolved);\n return resolved;\n } finally {\n visiting.delete(absPath);\n }\n };\n\n const root = await loadResource(entryAbs, 0);\n if (options.expectedKind && root.kind !== options.expectedKind) {\n throw new Error(`Expected kind \"${options.expectedKind}\" but got \"${root.kind}\" at ${root.__filePath}`);\n }\n return root as ResolvedResource<TSpec>;\n}\n"],"mappings":"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","names":["path","path"]}
@@ -3,7 +3,7 @@ import {
3
3
  asTrimmedString,
4
4
  parseJsonObject,
5
5
  shortToolName
6
- } from "./chunk-OTWARMTU.js";
6
+ } from "./chunk-OJWAEVSP.js";
7
7
  import {
8
8
  AgentContextTokens
9
9
  } from "./chunk-H5BG6SXW.js";
@@ -461,4 +461,4 @@ export {
461
461
  createAgentEventBus,
462
462
  createConsoleAgentEventListener
463
463
  };
464
- //# sourceMappingURL=chunk-PZOGGHUH.js.map
464
+ //# sourceMappingURL=chunk-6VW5AW43.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseYamlContent
3
- } from "./chunk-X4TDNR4V.js";
3
+ } from "./chunk-2HMNFLD4.js";
4
4
 
5
5
  // src/utils/deep-merge.ts
6
6
  function deepMerge(target, ...sources) {
@@ -179,4 +179,4 @@ export {
179
179
  parseMarkdownYamlFrontmatter,
180
180
  applyDefaultToolChoice
181
181
  };
182
- //# sourceMappingURL=chunk-OTWARMTU.js.map
182
+ //# sourceMappingURL=chunk-OJWAEVSP.js.map
@@ -10,7 +10,7 @@ import {
10
10
  resolveConfigPath,
11
11
  resolveKindResourceFile,
12
12
  toPathRef
13
- } from "../chunk-X4TDNR4V.js";
13
+ } from "../chunk-2HMNFLD4.js";
14
14
  export {
15
15
  asObject,
16
16
  clearYamlFileCache,
@@ -4,9 +4,9 @@ import {
4
4
  createProgressAgentEventListener,
5
5
  createRuntime2TreeEventListener,
6
6
  resolveRuntime2DebugConfig
7
- } from "../chunk-PZOGGHUH.js";
8
- import "../chunk-OTWARMTU.js";
9
- import "../chunk-X4TDNR4V.js";
7
+ } from "../chunk-6VW5AW43.js";
8
+ import "../chunk-OJWAEVSP.js";
9
+ import "../chunk-2HMNFLD4.js";
10
10
  import "../chunk-H5BG6SXW.js";
11
11
  import "../chunk-DIIWJNRE.js";
12
12
  import "../chunk-QG6CT2GZ.js";
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  createConsoleAgentEventListener,
10
10
  createProgressAgentEventListener,
11
11
  createRuntime2TreeEventListener
12
- } from "./chunk-PZOGGHUH.js";
12
+ } from "./chunk-6VW5AW43.js";
13
13
  import {
14
14
  asRecord,
15
15
  extractTextFromLlmOutput,
@@ -17,8 +17,8 @@ import {
17
17
  shortToolName,
18
18
  stripNullishObjectFields,
19
19
  summarizeForLog
20
- } from "./chunk-OTWARMTU.js";
21
- import "./chunk-X4TDNR4V.js";
20
+ } from "./chunk-OJWAEVSP.js";
21
+ import "./chunk-2HMNFLD4.js";
22
22
  import {
23
23
  AgentContextTokens
24
24
  } from "./chunk-H5BG6SXW.js";
@@ -12,8 +12,8 @@ import {
12
12
  shortToolName,
13
13
  stripNullishObjectFields,
14
14
  summarizeForLog
15
- } from "../chunk-OTWARMTU.js";
16
- import "../chunk-X4TDNR4V.js";
15
+ } from "../chunk-OJWAEVSP.js";
16
+ import "../chunk-2HMNFLD4.js";
17
17
  import {
18
18
  computeChecksum,
19
19
  createChecksumAccumulator
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/common",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Shared runtime utilities for BotBotGo agent projects",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -93,9 +93,11 @@
93
93
  "release": "semantic-release"
94
94
  },
95
95
  "dependencies": {
96
- "keytar": "^7.9.0",
97
96
  "yaml": "^2.8.1"
98
97
  },
98
+ "optionalDependencies": {
99
+ "keytar": "^7.9.0"
100
+ },
99
101
  "peerDependencies": {},
100
102
  "peerDependenciesMeta": {},
101
103
  "devDependencies": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/config/yaml.ts","../src/config/path.ts","../src/config/kind.ts"],"sourcesContent":["import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { resolveConfigPath } from \"./path.js\";\n\nexport interface YamlEnvOptions {\n substituteEnv?: boolean;\n missingEnv?: \"keep\" | \"empty\";\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface LoadYamlOptions extends YamlEnvOptions {\n cache?: boolean;\n}\n\nexport interface LoadModuleConfigOptions<TConfig, TRaw = Record<string, unknown>> {\n path?: string;\n defaultPath?: string;\n appRoot?: string;\n yaml?: LoadYamlOptions;\n unwrapSpec?: boolean;\n fallback: TConfig;\n normalize?: (raw: TRaw, meta: { resolvedPath: string }) => TConfig;\n}\n\ninterface CacheEntry {\n mtimeMs: number;\n value: unknown;\n}\n\nconst YAML_CACHE = new Map<string, CacheEntry>();\n\nexport function clearYamlFileCache(): void {\n YAML_CACHE.clear();\n}\n\nfunction substituteEnvInString(\n input: string,\n env: NodeJS.ProcessEnv,\n missingEnv: \"keep\" | \"empty\",\n): string {\n return input.replace(/\\$\\{(\\w+)\\}/g, (_, name: string) => {\n const value = env[name];\n if (value !== undefined) return value;\n return missingEnv === \"empty\" ? \"\" : `\\${${name}}`;\n });\n}\n\nfunction substituteEnvInValue(\n input: unknown,\n options: { env: NodeJS.ProcessEnv; missingEnv: \"keep\" | \"empty\" },\n): unknown {\n if (typeof input === \"string\") {\n return substituteEnvInString(input, options.env, options.missingEnv);\n }\n if (Array.isArray(input)) {\n return input.map((item) => substituteEnvInValue(item, options));\n }\n if (input && typeof input === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(input)) {\n out[k] = substituteEnvInValue(v, options);\n }\n return out;\n }\n return input;\n}\n\nexport function parseYamlContent<T = unknown>(\n content: string,\n options: YamlEnvOptions = {},\n): T {\n const parsed = parseYaml(content) as unknown;\n if (options.substituteEnv === false) return parsed as T;\n return substituteEnvInValue(parsed, {\n env: options.env ?? process.env,\n missingEnv: options.missingEnv ?? \"keep\",\n }) as T;\n}\n\nfunction readFromCache(filePath: string, mtimeMs: number): unknown | undefined {\n const cached = YAML_CACHE.get(filePath);\n if (!cached) return undefined;\n if (cached.mtimeMs !== mtimeMs) return undefined;\n return cached.value;\n}\n\nfunction writeCache(filePath: string, mtimeMs: number, value: unknown): void {\n YAML_CACHE.set(filePath, { mtimeMs, value });\n}\n\nexport function loadYamlFileSync<T = unknown>(\n filePath: string,\n options: LoadYamlOptions = {},\n): T | undefined {\n const absPath = path.resolve(filePath);\n if (!existsSync(absPath)) return undefined;\n const useCache = options.cache === true;\n const fileStat = statSync(absPath);\n if (useCache) {\n const cached = readFromCache(absPath, fileStat.mtimeMs);\n if (cached !== undefined) return cached as T;\n }\n const content = readFileSync(absPath, \"utf-8\");\n const parsed = parseYamlContent<T>(content, options);\n if (useCache) writeCache(absPath, fileStat.mtimeMs, parsed);\n return parsed;\n}\n\nexport async function loadYamlFile<T = unknown>(\n filePath: string,\n options: LoadYamlOptions = {},\n): Promise<T | undefined> {\n const absPath = path.resolve(filePath);\n let fileStat;\n try {\n fileStat = await stat(absPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === \"ENOENT\") return undefined;\n throw err;\n }\n const useCache = options.cache === true;\n if (useCache) {\n const cached = readFromCache(absPath, fileStat.mtimeMs);\n if (cached !== undefined) return cached as T;\n }\n const content = await readFile(absPath, \"utf-8\");\n const parsed = parseYamlContent<T>(content, options);\n if (useCache) writeCache(absPath, fileStat.mtimeMs, parsed);\n return parsed;\n}\n\nexport async function loadYamlObject(\n filePath: string,\n options: LoadYamlOptions = {},\n): Promise<Record<string, unknown>> {\n const parsed = await loadYamlFile<unknown>(filePath, options);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n return {};\n}\n\n/**\n * Generic module config loader:\n * 1) resolve path (path || defaultPath) relative to appRoot\n * 2) load YAML as object\n * 3) normalize into module-owned config interface\n * 4) fallback when missing/invalid\n */\nexport async function loadModuleConfig<TConfig, TRaw = Record<string, unknown>>(\n options: LoadModuleConfigOptions<TConfig, TRaw>,\n): Promise<TConfig> {\n const selected = options.path ?? options.defaultPath;\n if (!selected) return options.fallback;\n\n const appRoot = options.appRoot ?? process.cwd();\n const resolvedPath = resolveConfigPath(selected, appRoot);\n const loaded = await loadYamlFile<unknown>(resolvedPath, options.yaml);\n if (!loaded || typeof loaded !== \"object\" || Array.isArray(loaded)) return options.fallback;\n const raw = options.unwrapSpec === true\n ? (\n typeof (loaded as { spec?: unknown }).spec === \"object\" &&\n (loaded as { spec?: unknown }).spec !== null &&\n !Array.isArray((loaded as { spec?: unknown }).spec)\n ? (loaded as { spec: unknown }).spec\n : loaded\n )\n : loaded;\n\n if (options.normalize) {\n return options.normalize(raw as TRaw, { resolvedPath });\n }\n return raw as TConfig;\n}\n","import path from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface ResolveConfigPathOptions {\n expandHome?: boolean;\n homeDir?: string;\n}\n\nexport type PathRef = { ref?: string };\n\nexport function isPathRef(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length > 0 &&\n (value.endsWith(\".yaml\") || value.endsWith(\".yml\"))\n );\n}\n\nexport function expandHomePath(inputPath: string, options: { homeDir?: string } = {}): string {\n const home = options.homeDir ?? homedir();\n if (inputPath === \"~\") return home;\n if (inputPath.startsWith(\"~/\")) return path.join(home, inputPath.slice(2));\n return inputPath;\n}\n\nexport function resolveConfigPath(\n pathRef: string,\n configDir: string,\n options: ResolveConfigPathOptions = {},\n): string {\n const expanded = options.expandHome === false ? pathRef : expandHomePath(pathRef, { homeDir: options.homeDir });\n return path.resolve(configDir, expanded);\n}\n\nexport function asObject(input: unknown): Record<string, unknown> | undefined {\n return typeof input === \"object\" && input !== null ? (input as Record<string, unknown>) : undefined;\n}\n\nexport function toPathRef(input: unknown): PathRef | undefined {\n if (typeof input === \"string\" && input.trim().length > 0) return { ref: input.trim() };\n const obj = asObject(input);\n if (!obj) return undefined;\n const value =\n (typeof (obj as { __filePath?: unknown }).__filePath === \"string\" &&\n (obj as { __filePath: string }).__filePath.trim().length > 0\n ? (obj as { __filePath: string }).__filePath.trim()\n : undefined) ??\n (typeof obj.ref === \"string\" && obj.ref.trim().length > 0 ? obj.ref.trim() : undefined);\n return value ? { ref: value } : undefined;\n}\n","import { dirname } from \"node:path\";\nimport { loadYamlFile, type LoadYamlOptions } from \"./yaml.js\";\nimport { asObject, resolveConfigPath } from \"./path.js\";\n\nexport interface ResourceMetadata {\n name?: string;\n labels?: Record<string, string>;\n}\n\nexport interface ResourceHeader {\n apiVersion: string;\n kind: string;\n metadata?: ResourceMetadata;\n spec: unknown;\n}\n\nexport type RefNode = { ref: string };\n\nexport type ResolvedResource<TSpec = unknown> = ResourceHeader & {\n spec: TSpec;\n __filePath: string;\n};\n\nexport interface ResolveKindResourceOptions {\n baseDir?: string;\n maxDepth?: number;\n cache?: boolean;\n yaml?: LoadYamlOptions;\n expectedKind?: string;\n expectedApiVersion?: string;\n}\n\nfunction toResourceHeader(input: unknown): ResourceHeader {\n const obj = asObject(input);\n if (!obj) throw new Error(\"Invalid config document: expected object root\");\n\n const apiVersion = typeof obj.apiVersion === \"string\" ? obj.apiVersion.trim() : \"\";\n const kind = typeof obj.kind === \"string\" ? obj.kind.trim() : \"\";\n const spec = (obj as { spec?: unknown }).spec;\n if (!apiVersion) throw new Error(\"Invalid config document: missing apiVersion\");\n if (!kind) throw new Error(\"Invalid config document: missing kind\");\n if (spec === undefined) throw new Error(\"Invalid config document: missing spec\");\n const metadataRaw = asObject(obj.metadata);\n const metadata: ResourceMetadata | undefined = metadataRaw\n ? {\n name: typeof metadataRaw.name === \"string\" ? metadataRaw.name : undefined,\n labels:\n metadataRaw.labels && typeof metadataRaw.labels === \"object\" && !Array.isArray(metadataRaw.labels)\n ? (metadataRaw.labels as Record<string, string>)\n : undefined,\n }\n : undefined;\n return { apiVersion, kind, metadata, spec };\n}\n\nexport function isRefNode(input: unknown): input is RefNode {\n const obj = asObject(input);\n return !!obj && typeof obj.ref === \"string\" && obj.ref.trim().length > 0;\n}\n\nexport async function resolveKindResourceFile<TSpec = unknown>(\n entryFile: string,\n options: ResolveKindResourceOptions = {},\n): Promise<ResolvedResource<TSpec>> {\n const baseDir = options.baseDir ?? process.cwd();\n const entryAbs = resolveConfigPath(entryFile, baseDir);\n const maxDepth = options.maxDepth ?? 50;\n const cache = new Map<string, ResolvedResource>();\n const visiting = new Set<string>();\n\n const resolveNode = async (node: unknown, currentDir: string, depth: number): Promise<unknown> => {\n if (depth > maxDepth) throw new Error(`Config ref resolution exceeded maxDepth=${maxDepth}`);\n if (isRefNode(node)) {\n const next = resolveConfigPath(node.ref, currentDir);\n return loadResource(next, depth + 1);\n }\n if (Array.isArray(node)) {\n return Promise.all(node.map((item) => resolveNode(item, currentDir, depth + 1)));\n }\n const obj = asObject(node);\n if (!obj) return node;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n out[k] = await resolveNode(v, currentDir, depth + 1);\n }\n return out;\n };\n\n const loadResource = async (absPath: string, depth: number): Promise<ResolvedResource> => {\n if (depth > maxDepth) throw new Error(`Config ref resolution exceeded maxDepth=${maxDepth}`);\n if (options.cache !== false) {\n const cached = cache.get(absPath);\n if (cached) return cached;\n }\n if (visiting.has(absPath)) {\n throw new Error(`Config ref cycle detected at: ${absPath}`);\n }\n visiting.add(absPath);\n try {\n const raw = await loadYamlFile(absPath, options.yaml);\n const header = toResourceHeader(raw);\n if (options.expectedApiVersion && header.apiVersion !== options.expectedApiVersion) {\n throw new Error(`Unexpected apiVersion \"${header.apiVersion}\" at ${absPath}`);\n }\n const resolvedSpec = await resolveNode(header.spec, dirname(absPath), depth + 1);\n const resolved: ResolvedResource = {\n ...header,\n spec: resolvedSpec,\n __filePath: absPath,\n };\n if (options.cache !== false) cache.set(absPath, resolved);\n return resolved;\n } finally {\n visiting.delete(absPath);\n }\n };\n\n const root = await loadResource(entryAbs, 0);\n if (options.expectedKind && root.kind !== options.expectedKind) {\n throw new Error(`Expected kind \"${options.expectedKind}\" but got \"${root.kind}\" at ${root.__filePath}`);\n }\n return root as ResolvedResource<TSpec>;\n}\n"],"mappings":"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","names":["path","path"]}