• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

popstas / planfix-mcp-server / 19765592028

28 Nov 2025 01:44PM UTC coverage: 81.082%. Remained the same
19765592028

push

github

popstas
Merge branch 'master' of github.com:popstas/planfix-mcp-server

495 of 683 branches covered (72.47%)

Branch coverage included in aggregate %.

18 of 18 new or added lines in 2 files covered. (100.0%)

43 existing lines in 2 files now uncovered.

3371 of 4085 relevant lines covered (82.52%)

3.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.02
/src/customFieldsConfig.ts
1
import fs from "fs";
1✔
2
import yaml from "js-yaml";
1✔
3
import { CustomField } from "./lib/extendSchemaWithCustomFields.js";
4

5
export interface ChatApiConfig {
6
  chatApiToken: string;
7
  providerId: string;
8
  useChatApi: boolean;
9
  baseUrl: string;
10
}
11

12
export interface AppConfig {
13
  leadTaskFields: CustomField[];
14
  contactFields: CustomField[];
15
  userFields: CustomField[];
16
  chatApi: ChatApiConfig;
17
  proxyUrl?: string;
18
}
19

20
const DEFAULT_PATH = "./data/config.yml";
1✔
21

22
export function getConfigPath(): string {
1✔
23
  const cli = process.argv.find((a) => a.startsWith("--config="));
39✔
24
  if (cli) return cli.slice("--config=".length);
39!
25
  if (process.env.PLANFIX_CONFIG) return process.env.PLANFIX_CONFIG;
39✔
26
  return DEFAULT_PATH;
30✔
27
}
30✔
28

29
function parseEnv(name: string): CustomField[] {
114✔
30
  const raw = process.env[name];
114✔
31
  if (!raw) return [];
114✔
32
  try {
2✔
33
    const data = yaml.load(raw);
2✔
34
    return Array.isArray(data) ? (data as CustomField[]) : [];
114!
35
  } catch {
114!
UNCOV
36
    return [];
×
37
  }
×
38
}
114✔
39

40
function mergeFields(
114✔
41
  envFields: CustomField[],
114✔
42
  fileFields: CustomField[],
114✔
43
): CustomField[] {
114✔
44
  const map = new Map<number, CustomField>();
114✔
45
  for (const f of envFields) {
114✔
46
    if (f && f.id !== undefined)
2✔
47
      map.set(Number(f.id), { ...f, id: Number(f.id) });
2✔
48
  }
2✔
49
  for (const f of fileFields) {
114✔
50
    if (f && f.id !== undefined) {
4✔
51
      const id = Number(f.id);
4✔
52
      map.set(id, { ...map.get(id), ...f, id });
4✔
53
    }
4✔
54
  }
4✔
55
  return Array.from(map.values());
114✔
56
}
114✔
57

58
export function loadCustomFieldsConfig(): AppConfig {
1✔
59
  const envLead = parseEnv("PLANFIX_LEAD_TASK_FIELDS");
38✔
60
  const envContact = parseEnv("PLANFIX_CONTACT_FIELDS");
38✔
61
  const envUser = parseEnv("PLANFIX_USER_FIELDS");
38✔
62
  let fileLead: CustomField[] = [];
38✔
63
  let fileContact: CustomField[] = [];
38✔
64
  let fileUser: CustomField[] = [];
38✔
65
  let fileChatApi: Partial<ChatApiConfig> = {};
38✔
66
  let proxyUrl = "";
38✔
67

68
  const path = getConfigPath();
38✔
69
  if (fs.existsSync(path)) {
38✔
70
    try {
8✔
71
      const content = fs.readFileSync(path, "utf8");
8✔
72
      const parsed = yaml.load(content) as Partial<AppConfig> | undefined;
8✔
73
      fileLead = Array.isArray(parsed?.leadTaskFields)
8✔
74
        ? (parsed!.leadTaskFields as CustomField[])
3✔
75
        : [];
5✔
76
      fileContact = Array.isArray(parsed?.contactFields)
8✔
77
        ? (parsed!.contactFields as CustomField[])
3✔
78
        : [];
5✔
79
      fileUser = Array.isArray(parsed?.userFields)
8✔
80
        ? (parsed!.userFields as CustomField[])
1✔
81
        : [];
7✔
82
      if (parsed?.chatApi && typeof parsed.chatApi === "object") {
8✔
83
        fileChatApi = parsed.chatApi as ChatApiConfig;
1✔
84
      }
1✔
85
      if (typeof parsed?.proxyUrl === "string") {
8✔
86
        proxyUrl = parsed.proxyUrl;
2✔
87
      }
2✔
88
    } catch {
8!
89
      // ignore
UNCOV
90
    }
×
91
  }
8✔
92

93
  const chatApi: ChatApiConfig = {
38✔
94
    chatApiToken: "",
38✔
95
    providerId: "",
38✔
96
    useChatApi: false,
38✔
97
    baseUrl: "",
38✔
98
    ...fileChatApi,
38✔
99
  };
38✔
100

101
  return {
38✔
102
    leadTaskFields: mergeFields(envLead, fileLead),
38✔
103
    contactFields: mergeFields(envContact, fileContact),
38✔
104
    userFields: mergeFields(envUser, fileUser),
38✔
105
    chatApi,
38✔
106
    proxyUrl,
38✔
107
  };
38✔
108
}
38✔
109

110
const cfg = loadCustomFieldsConfig();
1✔
111
export const customFieldsConfig = {
1✔
112
  leadTaskFields: cfg.leadTaskFields,
1✔
113
  contactFields: cfg.contactFields,
1✔
114
  userFields: cfg.userFields,
1✔
115
};
1✔
116
export const chatApiConfig = cfg.chatApi;
1✔
117
export const proxyUrl = cfg.proxyUrl || "";
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc