@easynet/agent-common 1.0.2 → 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.
@@ -0,0 +1,2 @@
1
+ export { loadYamlFile, loadYamlFileSync, parseYamlContent, clearYamlFileCache, type LoadYamlOptions, type YamlEnvOptions, } from "./yaml.js";
2
+ export { isPathRef, expandHomePath, resolveConfigPath, type ResolveConfigPathOptions, } from "./path.js";
@@ -0,0 +1,9 @@
1
+ export interface ResolveConfigPathOptions {
2
+ expandHome?: boolean;
3
+ homeDir?: string;
4
+ }
5
+ export declare function isPathRef(value: unknown): value is string;
6
+ export declare function expandHomePath(inputPath: string, options?: {
7
+ homeDir?: string;
8
+ }): string;
9
+ export declare function resolveConfigPath(pathRef: string, configDir: string, options?: ResolveConfigPathOptions): string;
@@ -0,0 +1,12 @@
1
+ export interface YamlEnvOptions {
2
+ substituteEnv?: boolean;
3
+ missingEnv?: "keep" | "empty";
4
+ env?: NodeJS.ProcessEnv;
5
+ }
6
+ export interface LoadYamlOptions extends YamlEnvOptions {
7
+ cache?: boolean;
8
+ }
9
+ export declare function clearYamlFileCache(): void;
10
+ export declare function parseYamlContent<T = unknown>(content: string, options?: YamlEnvOptions): T;
11
+ export declare function loadYamlFileSync<T = unknown>(filePath: string, options?: LoadYamlOptions): T | undefined;
12
+ export declare function loadYamlFile<T = unknown>(filePath: string, options?: LoadYamlOptions): Promise<T | undefined>;
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from "./npm/index.js";
2
+ export * from "./config/index.js";
package/dist/index.js CHANGED
@@ -20,17 +20,122 @@ import {
20
20
  resolveNpmPackageVersion,
21
21
  runNpmCommand
22
22
  } from "./chunk-UDSSVJ5F.js";
23
+
24
+ // src/config/yaml.ts
25
+ import { existsSync, readFileSync, statSync } from "fs";
26
+ import { readFile, stat } from "fs/promises";
27
+ import path from "path";
28
+ import { parse as parseYaml } from "yaml";
29
+ var YAML_CACHE = /* @__PURE__ */ new Map();
30
+ function clearYamlFileCache() {
31
+ YAML_CACHE.clear();
32
+ }
33
+ function substituteEnvInString(input, env, missingEnv) {
34
+ return input.replace(/\$\{(\w+)\}/g, (_, name) => {
35
+ const value = env[name];
36
+ if (value !== void 0) return value;
37
+ return missingEnv === "empty" ? "" : `\${${name}}`;
38
+ });
39
+ }
40
+ function substituteEnvInValue(input, options) {
41
+ if (typeof input === "string") {
42
+ return substituteEnvInString(input, options.env, options.missingEnv);
43
+ }
44
+ if (Array.isArray(input)) {
45
+ return input.map((item) => substituteEnvInValue(item, options));
46
+ }
47
+ if (input && typeof input === "object") {
48
+ const out = {};
49
+ for (const [k, v] of Object.entries(input)) {
50
+ out[k] = substituteEnvInValue(v, options);
51
+ }
52
+ return out;
53
+ }
54
+ return input;
55
+ }
56
+ function parseYamlContent(content, options = {}) {
57
+ const parsed = parseYaml(content);
58
+ if (options.substituteEnv === false) return parsed;
59
+ return substituteEnvInValue(parsed, {
60
+ env: options.env ?? process.env,
61
+ missingEnv: options.missingEnv ?? "keep"
62
+ });
63
+ }
64
+ function readFromCache(filePath, mtimeMs) {
65
+ const cached = YAML_CACHE.get(filePath);
66
+ if (!cached) return void 0;
67
+ if (cached.mtimeMs !== mtimeMs) return void 0;
68
+ return cached.value;
69
+ }
70
+ function writeCache(filePath, mtimeMs, value) {
71
+ YAML_CACHE.set(filePath, { mtimeMs, value });
72
+ }
73
+ function loadYamlFileSync(filePath, options = {}) {
74
+ const absPath = path.resolve(filePath);
75
+ if (!existsSync(absPath)) return void 0;
76
+ const useCache = options.cache === true;
77
+ const fileStat = statSync(absPath);
78
+ if (useCache) {
79
+ const cached = readFromCache(absPath, fileStat.mtimeMs);
80
+ if (cached !== void 0) return cached;
81
+ }
82
+ const content = readFileSync(absPath, "utf-8");
83
+ const parsed = parseYamlContent(content, options);
84
+ if (useCache) writeCache(absPath, fileStat.mtimeMs, parsed);
85
+ return parsed;
86
+ }
87
+ async function loadYamlFile(filePath, options = {}) {
88
+ const absPath = path.resolve(filePath);
89
+ let fileStat;
90
+ try {
91
+ fileStat = await stat(absPath);
92
+ } catch (err) {
93
+ if (err?.code === "ENOENT") return void 0;
94
+ throw err;
95
+ }
96
+ const useCache = options.cache === true;
97
+ if (useCache) {
98
+ const cached = readFromCache(absPath, fileStat.mtimeMs);
99
+ if (cached !== void 0) return cached;
100
+ }
101
+ const content = await readFile(absPath, "utf-8");
102
+ const parsed = parseYamlContent(content, options);
103
+ if (useCache) writeCache(absPath, fileStat.mtimeMs, parsed);
104
+ return parsed;
105
+ }
106
+
107
+ // src/config/path.ts
108
+ import path2 from "path";
109
+ import { homedir } from "os";
110
+ function isPathRef(value) {
111
+ return typeof value === "string" && value.length > 0 && (value.endsWith(".yaml") || value.endsWith(".yml"));
112
+ }
113
+ function expandHomePath(inputPath, options = {}) {
114
+ const home = options.homeDir ?? homedir();
115
+ if (inputPath === "~") return home;
116
+ if (inputPath.startsWith("~/")) return path2.join(home, inputPath.slice(2));
117
+ return inputPath;
118
+ }
119
+ function resolveConfigPath(pathRef, configDir, options = {}) {
120
+ const expanded = options.expandHome === false ? pathRef : expandHomePath(pathRef, { homeDir: options.homeDir });
121
+ return path2.resolve(configDir, expanded);
122
+ }
23
123
  export {
24
124
  NPM_PROTOCOL_PREFIX,
25
125
  assertNpmCommandSuccess,
26
126
  clearVersionCache,
127
+ clearYamlFileCache,
27
128
  ensureNpmPackageInstalled,
28
129
  ensurePackageInCache,
130
+ expandHomePath,
29
131
  formatProviderDisplay,
30
132
  getInstalledVersion,
31
133
  getPackageEntryPath,
32
134
  importFromCache,
33
135
  isNpmProviderSpec,
136
+ isPathRef,
137
+ loadYamlFile,
138
+ loadYamlFileSync,
34
139
  npmInstall,
35
140
  npmPublish,
36
141
  npmRoot,
@@ -38,6 +143,8 @@ export {
38
143
  npmSearchJson,
39
144
  parseNpmProvider,
40
145
  parseNpmProviderSpec,
146
+ parseYamlContent,
147
+ resolveConfigPath,
41
148
  resolveLatestVersionFromRegistry,
42
149
  resolveNpmPackageVersion,
43
150
  runNpmCommand
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../src/config/yaml.ts","../src/config/path.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\";\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\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","import path from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface ResolveConfigPathOptions {\n expandHome?: boolean;\n homeDir?: string;\n}\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"],"mappings":"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","names":["path"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easynet/agent-common",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Shared runtime utilities for Easynet agent projects",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -35,6 +35,9 @@
35
35
  "test": "npm run build && npm run typecheck",
36
36
  "release": "semantic-release"
37
37
  },
38
+ "dependencies": {
39
+ "yaml": "^2.8.1"
40
+ },
38
41
  "devDependencies": {
39
42
  "@semantic-release/commit-analyzer": "^13.0.0",
40
43
  "@semantic-release/git": "^10.0.1",