@teamso/teamso-mcp 0.0.0-stage → 1.2.1
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 +136 -0
- package/LICENSE +21 -0
- package/README.md +506 -2
- package/dist/client.d.ts +215 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +797 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/index.d.ts +12 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +58 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/server.d.ts +28 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +58 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/account.d.ts +4 -0
- package/dist/tools/account.d.ts.map +1 -0
- package/dist/tools/account.js +34 -0
- package/dist/tools/account.js.map +1 -0
- package/dist/tools/api.d.ts +13 -0
- package/dist/tools/api.d.ts.map +1 -0
- package/dist/tools/api.js +982 -0
- package/dist/tools/api.js.map +1 -0
- package/dist/tools/approvals.d.ts +5 -0
- package/dist/tools/approvals.d.ts.map +1 -0
- package/dist/tools/approvals.js +120 -0
- package/dist/tools/approvals.js.map +1 -0
- package/dist/tools/communication.d.ts +4 -0
- package/dist/tools/communication.d.ts.map +1 -0
- package/dist/tools/communication.js +39 -0
- package/dist/tools/communication.js.map +1 -0
- package/dist/tools/employees.d.ts +5 -0
- package/dist/tools/employees.d.ts.map +1 -0
- package/dist/tools/employees.js +113 -0
- package/dist/tools/employees.js.map +1 -0
- package/dist/tools/help.d.ts +6 -0
- package/dist/tools/help.d.ts.map +1 -0
- package/dist/tools/help.js +171 -0
- package/dist/tools/help.js.map +1 -0
- package/dist/tools/index.d.ts +86 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +118 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/leave-support.d.ts +60 -0
- package/dist/tools/leave-support.d.ts.map +1 -0
- package/dist/tools/leave-support.js +185 -0
- package/dist/tools/leave-support.js.map +1 -0
- package/dist/tools/leave.d.ts +14 -0
- package/dist/tools/leave.d.ts.map +1 -0
- package/dist/tools/leave.js +388 -0
- package/dist/tools/leave.js.map +1 -0
- package/dist/tools/payroll.d.ts +5 -0
- package/dist/tools/payroll.d.ts.map +1 -0
- package/dist/tools/payroll.js +101 -0
- package/dist/tools/payroll.js.map +1 -0
- package/dist/tools/performance.d.ts +13 -0
- package/dist/tools/performance.d.ts.map +1 -0
- package/dist/tools/performance.js +592 -0
- package/dist/tools/performance.js.map +1 -0
- package/dist/tools/schemas.d.ts +2079 -0
- package/dist/tools/schemas.d.ts.map +1 -0
- package/dist/tools/schemas.js +460 -0
- package/dist/tools/schemas.js.map +1 -0
- package/dist/tools/shared.d.ts +20 -0
- package/dist/tools/shared.d.ts.map +1 -0
- package/dist/tools/shared.js +64 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/types.d.ts +545 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/api-endpoints.d.ts +130 -0
- package/dist/utils/api-endpoints.d.ts.map +1 -0
- package/dist/utils/api-endpoints.js +459 -0
- package/dist/utils/api-endpoints.js.map +1 -0
- package/dist/utils/dates.d.ts +27 -0
- package/dist/utils/dates.d.ts.map +1 -0
- package/dist/utils/dates.js +102 -0
- package/dist/utils/dates.js.map +1 -0
- package/dist/utils/format.d.ts +8 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +26 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/help-search.d.ts +25 -0
- package/dist/utils/help-search.d.ts.map +1 -0
- package/dist/utils/help-search.js +93 -0
- package/dist/utils/help-search.js.map +1 -0
- package/dist/utils/json-schema-dialect.d.ts +12 -0
- package/dist/utils/json-schema-dialect.d.ts.map +1 -0
- package/dist/utils/json-schema-dialect.js +146 -0
- package/dist/utils/json-schema-dialect.js.map +1 -0
- package/dist/utils/results.d.ts +27 -0
- package/dist/utils/results.d.ts.map +1 -0
- package/dist/utils/results.js +88 -0
- package/dist/utils/results.js.map +1 -0
- package/dist/utils/structured.d.ts +89 -0
- package/dist/utils/structured.d.ts.map +1 -0
- package/dist/utils/structured.js +307 -0
- package/dist/utils/structured.js.map +1 -0
- package/dist/utils/text.d.ts +12 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +46 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +86 -4
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { ToolInputError } from './results.js';
|
|
2
|
+
/**
|
|
3
|
+
* Teamso leave dates are Turkey wall-clock strings (`yyyy-MM-dd HH:mm`) that
|
|
4
|
+
* the API stores and returns unchanged. They are never converted to or from
|
|
5
|
+
* UTC here.
|
|
6
|
+
*/
|
|
7
|
+
const DATE_INPUT = /^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2})(?::\d{2}(?:\.\d+)?)?)?$/;
|
|
8
|
+
const TIME = /^(\d{2}):(\d{2})/;
|
|
9
|
+
export const DEFAULT_WORKDAY_START = '09:00';
|
|
10
|
+
export const DEFAULT_WORKDAY_END = '18:00';
|
|
11
|
+
/** Parses `yyyy-MM-dd`, `yyyy-MM-dd HH:mm` or `yyyy-MM-ddTHH:mm[:ss]`; throws a readable error otherwise. */
|
|
12
|
+
export function parseWallClock(value, field) {
|
|
13
|
+
const match = DATE_INPUT.exec(value.trim());
|
|
14
|
+
if (!match) {
|
|
15
|
+
throw new ToolInputError(`\`${field}\` must be \`yyyy-MM-dd\` or \`yyyy-MM-dd HH:mm\` (Turkey local time), got "${value}".`);
|
|
16
|
+
}
|
|
17
|
+
const [, year, month, day, hour, minute] = match;
|
|
18
|
+
const calendar = new Date(Date.UTC(Number(year), Number(month) - 1, Number(day)));
|
|
19
|
+
if (calendar.getUTCFullYear() !== Number(year)
|
|
20
|
+
|| calendar.getUTCMonth() !== Number(month) - 1
|
|
21
|
+
|| calendar.getUTCDate() !== Number(day)) {
|
|
22
|
+
throw new ToolInputError(`\`${field}\` is not a real calendar date: "${value}".`);
|
|
23
|
+
}
|
|
24
|
+
if (hour !== undefined && (Number(hour) > 23 || Number(minute) > 59)) {
|
|
25
|
+
throw new ToolInputError(`\`${field}\` has an invalid time: "${value}".`);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
date: `${year}-${month}-${day}`,
|
|
29
|
+
time: hour !== undefined ? `${hour}:${minute}` : undefined,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function formatWallClock(date, time) {
|
|
33
|
+
return `${date} ${time}`;
|
|
34
|
+
}
|
|
35
|
+
/** `HH:mm` from `HH:mm[:ss]`, or undefined. */
|
|
36
|
+
export function toClockTime(value) {
|
|
37
|
+
if (!value)
|
|
38
|
+
return undefined;
|
|
39
|
+
const match = TIME.exec(value.trim());
|
|
40
|
+
if (!match)
|
|
41
|
+
return undefined;
|
|
42
|
+
return Number(match[1]) <= 23 && Number(match[2]) <= 59 ? `${match[1]}:${match[2]}` : undefined;
|
|
43
|
+
}
|
|
44
|
+
export const TEAMSO_TIME_ZONE = 'Europe/Istanbul';
|
|
45
|
+
/** An ISO 8601 instant: a date-time with `Z` or a numeric UTC offset. */
|
|
46
|
+
const ISO_INSTANT = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:?\d{2})$/i;
|
|
47
|
+
const istanbulParts = new Intl.DateTimeFormat('en-CA', {
|
|
48
|
+
timeZone: TEAMSO_TIME_ZONE,
|
|
49
|
+
year: 'numeric',
|
|
50
|
+
month: '2-digit',
|
|
51
|
+
day: '2-digit',
|
|
52
|
+
hour: '2-digit',
|
|
53
|
+
minute: '2-digit',
|
|
54
|
+
hourCycle: 'h23',
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* An instant (epoch millis or ISO string with an offset) as Turkey wall-clock
|
|
58
|
+
* parts. Wall-clock strings without an offset are not instants and return
|
|
59
|
+
* undefined, so they are never shifted.
|
|
60
|
+
*/
|
|
61
|
+
function istanbulWallClock(value) {
|
|
62
|
+
if (typeof value === 'string' && !ISO_INSTANT.test(value.trim()))
|
|
63
|
+
return undefined;
|
|
64
|
+
const instant = new Date(typeof value === 'number' ? value : value.trim());
|
|
65
|
+
if (Number.isNaN(instant.getTime()))
|
|
66
|
+
return undefined;
|
|
67
|
+
const parts = Object.fromEntries(istanbulParts.formatToParts(instant).map(part => [part.type, part.value]));
|
|
68
|
+
return {
|
|
69
|
+
date: `${parts.year}-${parts.month}-${parts.day}`,
|
|
70
|
+
time: `${parts.hour}:${parts.minute}`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* `yyyy-MM-dd` from an API date. Instants (epoch millis, ISO strings with an
|
|
75
|
+
* offset) are read on the Turkey calendar, so a midnight stored in either UTC
|
|
76
|
+
* or Turkey time lands on the intended day; wall-clock strings
|
|
77
|
+
* (`yyyy-MM-dd[ HH:mm]`) are taken as they are.
|
|
78
|
+
*/
|
|
79
|
+
export function toIsoDay(value) {
|
|
80
|
+
if (value === null || value === undefined || value === '')
|
|
81
|
+
return undefined;
|
|
82
|
+
const instant = istanbulWallClock(value);
|
|
83
|
+
if (instant)
|
|
84
|
+
return instant.date;
|
|
85
|
+
if (typeof value === 'number')
|
|
86
|
+
return undefined;
|
|
87
|
+
const match = /^(\d{4}-\d{2}-\d{2})/.exec(value.trim());
|
|
88
|
+
return match?.[1];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* API date-time for display. Instants become Turkey wall clock
|
|
92
|
+
* (`yyyy-MM-dd HH:mm`), matching the leave dates; other strings are kept.
|
|
93
|
+
*/
|
|
94
|
+
export function toDisplayDateTime(value) {
|
|
95
|
+
if (value === null || value === undefined || value === '')
|
|
96
|
+
return undefined;
|
|
97
|
+
const instant = istanbulWallClock(value);
|
|
98
|
+
if (instant)
|
|
99
|
+
return formatWallClock(instant.date, instant.time);
|
|
100
|
+
return typeof value === 'string' ? value : undefined;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=dates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dates.js","sourceRoot":"","sources":["../../src/utils/dates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Small Markdown helpers for the human-readable half of tool results. */
|
|
2
|
+
export declare function markdownTable(headers: string[], rows: Array<Array<string | number | boolean | undefined | null>>): string;
|
|
3
|
+
export declare function escapeCell(value: string | number | boolean | undefined | null): string;
|
|
4
|
+
/** "1 day", "2.5 days". */
|
|
5
|
+
export declare function formatDays(value: number): string;
|
|
6
|
+
export declare function formatDateRange(start: string | undefined, end: string | undefined): string;
|
|
7
|
+
export declare function codeList(values: string[]): string;
|
|
8
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAE1E,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM,CAKzH;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAGtF;AAED,2BAA2B;AAC3B,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG1F;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Small Markdown helpers for the human-readable half of tool results. */
|
|
2
|
+
export function markdownTable(headers, rows) {
|
|
3
|
+
const head = `| ${headers.map(escapeCell).join(' | ')} |`;
|
|
4
|
+
const divider = `| ${headers.map(() => '---').join(' | ')} |`;
|
|
5
|
+
const body = rows.map(row => `| ${row.map(cell => escapeCell(cell)).join(' | ')} |`);
|
|
6
|
+
return [head, divider, ...body].join('\n');
|
|
7
|
+
}
|
|
8
|
+
export function escapeCell(value) {
|
|
9
|
+
if (value === undefined || value === null || value === '')
|
|
10
|
+
return '—';
|
|
11
|
+
return String(value).replace(/\|/g, '\\|').replace(/\r?\n/g, ' ');
|
|
12
|
+
}
|
|
13
|
+
/** "1 day", "2.5 days". */
|
|
14
|
+
export function formatDays(value) {
|
|
15
|
+
const rounded = Math.round(value * 100) / 100;
|
|
16
|
+
return `${rounded} ${rounded === 1 ? 'day' : 'days'}`;
|
|
17
|
+
}
|
|
18
|
+
export function formatDateRange(start, end) {
|
|
19
|
+
if (start && end)
|
|
20
|
+
return `${start} → ${end}`;
|
|
21
|
+
return start ?? end ?? '—';
|
|
22
|
+
}
|
|
23
|
+
export function codeList(values) {
|
|
24
|
+
return values.length ? values.map(value => `\`${value}\``).join(', ') : '—';
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAE1E,MAAM,UAAU,aAAa,CAAC,OAAiB,EAAE,IAAgE;IAC/G,MAAM,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IAC1D,MAAM,OAAO,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrF,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAmD;IAC5E,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,GAAG,CAAC;IACtE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AACpE,CAAC;AAED,2BAA2B;AAC3B,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IAC9C,OAAO,GAAG,OAAO,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAyB,EAAE,GAAuB;IAChF,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,GAAG,KAAK,MAAM,GAAG,EAAE,CAAC;IAC7C,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAgB;IACvC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { HelpArticle } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Query words folded to Turkish-insensitive form, stop words dropped and
|
|
4
|
+
* inflection suffixes stripped ("girilir" → "gir", "hedefi" → "hedef").
|
|
5
|
+
* Consonant softening is tolerated ("talebi" → "taleb" → "tale" also finds "talep").
|
|
6
|
+
*/
|
|
7
|
+
export declare function helpQueryStems(query: string): string[];
|
|
8
|
+
/**
|
|
9
|
+
* Title match 10, summary 4, each body occurrence 1 (at most 3 per word), plus
|
|
10
|
+
* 4 per matched word so articles covering more of the query rank first.
|
|
11
|
+
* Overview articles carry the module name in their title, so they get a 15%
|
|
12
|
+
* penalty to let the task article win "how do I…" questions.
|
|
13
|
+
*/
|
|
14
|
+
export declare function scoreHelpArticle(article: HelpArticle, stems: string[]): number;
|
|
15
|
+
export interface HelpSearchOptions {
|
|
16
|
+
module?: string;
|
|
17
|
+
role?: string;
|
|
18
|
+
limit: number;
|
|
19
|
+
}
|
|
20
|
+
export interface HelpSearchHit {
|
|
21
|
+
article: HelpArticle;
|
|
22
|
+
score: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function searchHelpArticles(articles: HelpArticle[], query: string, options: HelpSearchOptions): HelpSearchHit[];
|
|
25
|
+
//# sourceMappingURL=help-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help-search.d.ts","sourceRoot":"","sources":["../../src/utils/help-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA0B/C;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAmBtD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAiB9E;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,iBAAiB,GACzB,aAAa,EAAE,CASjB"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { normalizeSearchText } from './text.js';
|
|
2
|
+
/**
|
|
3
|
+
* Help-center search, ported from the API's `HowToMcpCatalog` so the hosted
|
|
4
|
+
* and local servers rank articles the same way.
|
|
5
|
+
*/
|
|
6
|
+
/** Question words that only blur the search. Already in normalized form. */
|
|
7
|
+
const STOP_WORDS = new Set([
|
|
8
|
+
'nasil', 'ne', 'neden', 'nerede', 'hangi', 'bir', 've', 'ile', 'mi', 'mu', 'icin', 'bu', 'su', 'da', 'de',
|
|
9
|
+
'ben', 'benim', 'yapilir', 'yaparim', 'how', 'do', 'i', 'to', 'the', 'a', 'an', 'can', 'my', 'what',
|
|
10
|
+
'where', 'is', 'of', 'in',
|
|
11
|
+
]);
|
|
12
|
+
/** Normalized Turkish suffixes, longest first; at least three letters of stem remain. */
|
|
13
|
+
const SUFFIXES = [
|
|
14
|
+
'lerinin', 'larinin', 'lerini', 'larini', 'leri', 'lari', 'ilir', 'ulur', 'ilen', 'ulan', 'mesi', 'masi',
|
|
15
|
+
'ler', 'lar', 'mek', 'mak', 'nin', 'nun', 'den', 'dan', 'ten', 'tan', 'dir', 'dur', 'in', 'un', 'si', 'su',
|
|
16
|
+
'de', 'da', 'te', 'ta', 'ye', 'ya', 'ir', 'ur', 'ar', 'er', 'me', 'ma', 'im', 'um', 'iz', 'uz', 'e', 'a',
|
|
17
|
+
'i', 'u',
|
|
18
|
+
];
|
|
19
|
+
const MAX_SUFFIX_PASSES = 3;
|
|
20
|
+
const OVERVIEW_PENALTY = 0.85;
|
|
21
|
+
/**
|
|
22
|
+
* Query words folded to Turkish-insensitive form, stop words dropped and
|
|
23
|
+
* inflection suffixes stripped ("girilir" → "gir", "hedefi" → "hedef").
|
|
24
|
+
* Consonant softening is tolerated ("talebi" → "taleb" → "tale" also finds "talep").
|
|
25
|
+
*/
|
|
26
|
+
export function helpQueryStems(query) {
|
|
27
|
+
const stems = [];
|
|
28
|
+
for (const word of normalizeSearchText(query).split(/[^\p{L}\p{N}]+/u)) {
|
|
29
|
+
if (word.length < 2 || STOP_WORDS.has(word))
|
|
30
|
+
continue;
|
|
31
|
+
let stem = word;
|
|
32
|
+
// Suffixes stack ("dönemini" = dönem+in+i), so strip up to three times.
|
|
33
|
+
for (let pass = 0; pass < MAX_SUFFIX_PASSES; pass++) {
|
|
34
|
+
const before = stem;
|
|
35
|
+
const suffix = SUFFIXES.find(candidate => stem.endsWith(candidate)
|
|
36
|
+
&& stem.length - candidate.length >= 3);
|
|
37
|
+
if (suffix)
|
|
38
|
+
stem = stem.slice(0, stem.length - suffix.length);
|
|
39
|
+
if (stem === before)
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
if (stem.length >= 4 && 'bcdg'.includes(stem[stem.length - 1]) && stem !== word) {
|
|
43
|
+
stem = stem.slice(0, -1);
|
|
44
|
+
}
|
|
45
|
+
stems.push(stem);
|
|
46
|
+
}
|
|
47
|
+
return stems;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Title match 10, summary 4, each body occurrence 1 (at most 3 per word), plus
|
|
51
|
+
* 4 per matched word so articles covering more of the query rank first.
|
|
52
|
+
* Overview articles carry the module name in their title, so they get a 15%
|
|
53
|
+
* penalty to let the task article win "how do I…" questions.
|
|
54
|
+
*/
|
|
55
|
+
export function scoreHelpArticle(article, stems) {
|
|
56
|
+
if (stems.length === 0)
|
|
57
|
+
return 0;
|
|
58
|
+
const title = normalizeSearchText(article.title);
|
|
59
|
+
const summary = normalizeSearchText(article.summary);
|
|
60
|
+
const body = normalizeSearchText(article.body);
|
|
61
|
+
let total = 0;
|
|
62
|
+
let matchedWords = 0;
|
|
63
|
+
for (const stem of stems) {
|
|
64
|
+
const score = (title.includes(stem) ? 10 : 0)
|
|
65
|
+
+ (summary.includes(stem) ? 4 : 0)
|
|
66
|
+
+ Math.min(3, occurrences(body, stem));
|
|
67
|
+
if (score > 0)
|
|
68
|
+
matchedWords++;
|
|
69
|
+
total += score;
|
|
70
|
+
}
|
|
71
|
+
if (total === 0)
|
|
72
|
+
return 0;
|
|
73
|
+
const score = total + matchedWords * 4;
|
|
74
|
+
return article.id.endsWith('.overview') ? Math.floor(score * OVERVIEW_PENALTY) : score;
|
|
75
|
+
}
|
|
76
|
+
export function searchHelpArticles(articles, query, options) {
|
|
77
|
+
const stems = helpQueryStems(query);
|
|
78
|
+
return articles
|
|
79
|
+
.filter(article => !options.module || article.dir === options.module)
|
|
80
|
+
.filter(article => !options.role || (article.roles ?? []).includes(options.role))
|
|
81
|
+
.map(article => ({ article, score: scoreHelpArticle(article, stems) }))
|
|
82
|
+
.filter(hit => hit.score > 0)
|
|
83
|
+
.sort((a, b) => b.score - a.score || (a.article.order ?? 0) - (b.article.order ?? 0))
|
|
84
|
+
.slice(0, options.limit);
|
|
85
|
+
}
|
|
86
|
+
function occurrences(haystack, needle) {
|
|
87
|
+
let count = 0;
|
|
88
|
+
for (let index = haystack.indexOf(needle); index >= 0; index = haystack.indexOf(needle, index + needle.length)) {
|
|
89
|
+
count++;
|
|
90
|
+
}
|
|
91
|
+
return count;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=help-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help-search.js","sourceRoot":"","sources":["../../src/utils/help-search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
2
|
+
/**
|
|
3
|
+
* MCP SDK 1.30 still advertises Zod tool schemas as JSON Schema draft-07.
|
|
4
|
+
* Claude and other 2020-12-only clients reject those tools before dispatch.
|
|
5
|
+
* Rewrite the tools/list payload at the transport boundary instead of
|
|
6
|
+
* depending on an SDK target option that is not currently passed through.
|
|
7
|
+
*/
|
|
8
|
+
export declare const JSON_SCHEMA_2020_12 = "https://json-schema.org/draft/2020-12/schema";
|
|
9
|
+
export declare function toJsonSchema2020_12<T>(schema: T): T;
|
|
10
|
+
export declare function normalizeOutgoingMessage(message: unknown): unknown;
|
|
11
|
+
export declare function withJsonSchema2020_12<T extends Transport>(transport: T): T;
|
|
12
|
+
//# sourceMappingURL=json-schema-dialect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-dialect.d.ts","sourceRoot":"","sources":["../../src/utils/json-schema-dialect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAE/E;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,iDAAiD,CAAC;AAgHlF,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAMnD;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAmBlE;AAED,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,SAAS,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,CAK1E"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP SDK 1.30 still advertises Zod tool schemas as JSON Schema draft-07.
|
|
3
|
+
* Claude and other 2020-12-only clients reject those tools before dispatch.
|
|
4
|
+
* Rewrite the tools/list payload at the transport boundary instead of
|
|
5
|
+
* depending on an SDK target option that is not currently passed through.
|
|
6
|
+
*/
|
|
7
|
+
export const JSON_SCHEMA_2020_12 = 'https://json-schema.org/draft/2020-12/schema';
|
|
8
|
+
const DEFINITIONS_REF_PREFIX = '#/definitions/';
|
|
9
|
+
const SCHEMA_MAP_KEYWORDS = new Set([
|
|
10
|
+
'properties',
|
|
11
|
+
'patternProperties',
|
|
12
|
+
'$defs',
|
|
13
|
+
'dependentSchemas',
|
|
14
|
+
]);
|
|
15
|
+
const DATA_KEYWORDS = new Set([
|
|
16
|
+
'enum',
|
|
17
|
+
'const',
|
|
18
|
+
'default',
|
|
19
|
+
'examples',
|
|
20
|
+
'required',
|
|
21
|
+
'dependentRequired',
|
|
22
|
+
]);
|
|
23
|
+
function isPlainObject(value) {
|
|
24
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
25
|
+
}
|
|
26
|
+
function convertSchemaMap(node) {
|
|
27
|
+
if (!isPlainObject(node))
|
|
28
|
+
return node;
|
|
29
|
+
const out = {};
|
|
30
|
+
for (const [name, subschema] of Object.entries(node)) {
|
|
31
|
+
out[name] = convertNode(subschema);
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
function convertNode(node) {
|
|
36
|
+
if (Array.isArray(node))
|
|
37
|
+
return node.map(convertNode);
|
|
38
|
+
if (!isPlainObject(node))
|
|
39
|
+
return node;
|
|
40
|
+
const hasTupleItems = Array.isArray(node.items);
|
|
41
|
+
const out = {};
|
|
42
|
+
for (const [key, value] of Object.entries(node)) {
|
|
43
|
+
switch (key) {
|
|
44
|
+
case '$schema':
|
|
45
|
+
break;
|
|
46
|
+
case 'definitions':
|
|
47
|
+
out.$defs = convertSchemaMap(value);
|
|
48
|
+
break;
|
|
49
|
+
case '$ref':
|
|
50
|
+
out.$ref = typeof value === 'string' && value.startsWith(DEFINITIONS_REF_PREFIX)
|
|
51
|
+
? `#/$defs/${value.slice(DEFINITIONS_REF_PREFIX.length)}`
|
|
52
|
+
: value;
|
|
53
|
+
break;
|
|
54
|
+
case 'items':
|
|
55
|
+
if (hasTupleItems)
|
|
56
|
+
out.prefixItems = value.map(convertNode);
|
|
57
|
+
else
|
|
58
|
+
out.items = convertNode(value);
|
|
59
|
+
break;
|
|
60
|
+
case 'additionalItems':
|
|
61
|
+
if (hasTupleItems)
|
|
62
|
+
out.items = convertNode(value);
|
|
63
|
+
break;
|
|
64
|
+
case 'dependencies': {
|
|
65
|
+
const dependentRequired = {};
|
|
66
|
+
const dependentSchemas = {};
|
|
67
|
+
if (isPlainObject(value)) {
|
|
68
|
+
for (const [property, dependency] of Object.entries(value)) {
|
|
69
|
+
if (Array.isArray(dependency))
|
|
70
|
+
dependentRequired[property] = dependency;
|
|
71
|
+
else
|
|
72
|
+
dependentSchemas[property] = convertNode(dependency);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (Object.keys(dependentRequired).length > 0) {
|
|
76
|
+
out.dependentRequired = dependentRequired;
|
|
77
|
+
}
|
|
78
|
+
if (Object.keys(dependentSchemas).length > 0) {
|
|
79
|
+
out.dependentSchemas = dependentSchemas;
|
|
80
|
+
}
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
case 'exclusiveMinimum':
|
|
84
|
+
case 'exclusiveMaximum': {
|
|
85
|
+
const bound = key === 'exclusiveMinimum' ? node.minimum : node.maximum;
|
|
86
|
+
if (value === true && typeof bound === 'number')
|
|
87
|
+
out[key] = bound;
|
|
88
|
+
else if (value !== false)
|
|
89
|
+
out[key] = convertNode(value);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case 'minimum':
|
|
93
|
+
if (node.exclusiveMinimum === true)
|
|
94
|
+
break;
|
|
95
|
+
out.minimum = convertNode(value);
|
|
96
|
+
break;
|
|
97
|
+
case 'maximum':
|
|
98
|
+
if (node.exclusiveMaximum === true)
|
|
99
|
+
break;
|
|
100
|
+
out.maximum = convertNode(value);
|
|
101
|
+
break;
|
|
102
|
+
default:
|
|
103
|
+
if (DATA_KEYWORDS.has(key))
|
|
104
|
+
out[key] = value;
|
|
105
|
+
else if (SCHEMA_MAP_KEYWORDS.has(key))
|
|
106
|
+
out[key] = convertSchemaMap(value);
|
|
107
|
+
else
|
|
108
|
+
out[key] = convertNode(value);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return out;
|
|
112
|
+
}
|
|
113
|
+
export function toJsonSchema2020_12(schema) {
|
|
114
|
+
if (!isPlainObject(schema))
|
|
115
|
+
return schema;
|
|
116
|
+
return {
|
|
117
|
+
$schema: JSON_SCHEMA_2020_12,
|
|
118
|
+
...convertNode(schema),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
export function normalizeOutgoingMessage(message) {
|
|
122
|
+
if (!isPlainObject(message))
|
|
123
|
+
return message;
|
|
124
|
+
const result = message.result;
|
|
125
|
+
if (!isPlainObject(result) || !Array.isArray(result.tools))
|
|
126
|
+
return message;
|
|
127
|
+
const tools = result.tools.map(tool => {
|
|
128
|
+
if (!isPlainObject(tool))
|
|
129
|
+
return tool;
|
|
130
|
+
const next = { ...tool };
|
|
131
|
+
if (isPlainObject(tool.inputSchema)) {
|
|
132
|
+
next.inputSchema = toJsonSchema2020_12(tool.inputSchema);
|
|
133
|
+
}
|
|
134
|
+
if (isPlainObject(tool.outputSchema)) {
|
|
135
|
+
next.outputSchema = toJsonSchema2020_12(tool.outputSchema);
|
|
136
|
+
}
|
|
137
|
+
return next;
|
|
138
|
+
});
|
|
139
|
+
return { ...message, result: { ...result, tools } };
|
|
140
|
+
}
|
|
141
|
+
export function withJsonSchema2020_12(transport) {
|
|
142
|
+
const originalSend = transport.send.bind(transport);
|
|
143
|
+
transport.send = (message, options) => originalSend(normalizeOutgoingMessage(message), options);
|
|
144
|
+
return transport;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=json-schema-dialect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-dialect.js","sourceRoot":"","sources":["../../src/utils/json-schema-dialect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
export declare const ACCESS_TOKEN_URL = "https://teamso.com/dashboard/mcp-access";
|
|
3
|
+
/** Invalid tool input or a business rule the user has to fix; its message is shown as-is. */
|
|
4
|
+
export declare class ToolInputError extends Error {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
export interface NextAction {
|
|
8
|
+
tool: string;
|
|
9
|
+
arguments: Record<string, unknown>;
|
|
10
|
+
reason: string;
|
|
11
|
+
}
|
|
12
|
+
/** Successful tool result: concise Markdown for the reader, typed data for chaining. */
|
|
13
|
+
export declare function toolResult(text: string, structuredContent: Record<string, unknown>): CallToolResult;
|
|
14
|
+
/** Failed tool result (`isError: true`) with an actionable explanation. */
|
|
15
|
+
export declare function errorResult(message: string): CallToolResult;
|
|
16
|
+
export interface ApiErrorHints {
|
|
17
|
+
/** Text per `message_code` or API `message` (e.g. `OTP_NOT_DONE`, `NOT_AUTHORIZED_TO_APPROVE`). */
|
|
18
|
+
byCode?: Record<string, string>;
|
|
19
|
+
/** What the caller needs when the API answers 403 `ACCESS_DENIED`. */
|
|
20
|
+
forbidden?: string;
|
|
21
|
+
/** Text for a missing record (`ITEM_NOT_FOUND`, `USER_NOT_FOUND`, HTTP 404). */
|
|
22
|
+
notFound?: string;
|
|
23
|
+
}
|
|
24
|
+
/** Turns any failure into an `isError` result that tells the assistant what to do next. */
|
|
25
|
+
export declare function apiErrorResult(error: unknown, hints?: ApiErrorHints): CallToolResult;
|
|
26
|
+
export declare function describeError(error: unknown, hints?: ApiErrorHints): string;
|
|
27
|
+
//# sourceMappingURL=results.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"results.d.ts","sourceRoot":"","sources":["../../src/utils/results.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGzE,eAAO,MAAM,gBAAgB,4CAA4C,CAAC;AAE1E,6FAA6F;AAC7F,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wFAAwF;AACxF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,cAAc,CAKnG;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAK3D;AAED,MAAM,WAAW,aAAa;IAC5B,mGAAmG;IACnG,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,GAAE,aAAkB,GAAG,cAAc,CAExF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,GAAE,aAAkB,GAAG,MAAM,CAoD/E"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { TeamsoApiError } from '../client.js';
|
|
2
|
+
export const ACCESS_TOKEN_URL = 'https://teamso.com/dashboard/mcp-access';
|
|
3
|
+
/** Invalid tool input or a business rule the user has to fix; its message is shown as-is. */
|
|
4
|
+
export class ToolInputError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'ToolInputError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** Successful tool result: concise Markdown for the reader, typed data for chaining. */
|
|
11
|
+
export function toolResult(text, structuredContent) {
|
|
12
|
+
return {
|
|
13
|
+
content: [{ type: 'text', text }],
|
|
14
|
+
structuredContent,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** Failed tool result (`isError: true`) with an actionable explanation. */
|
|
18
|
+
export function errorResult(message) {
|
|
19
|
+
return {
|
|
20
|
+
content: [{ type: 'text', text: `## Error\n\n${message}` }],
|
|
21
|
+
isError: true,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Turns any failure into an `isError` result that tells the assistant what to do next. */
|
|
25
|
+
export function apiErrorResult(error, hints = {}) {
|
|
26
|
+
return errorResult(describeError(error, hints));
|
|
27
|
+
}
|
|
28
|
+
export function describeError(error, hints = {}) {
|
|
29
|
+
if (error instanceof ToolInputError)
|
|
30
|
+
return error.message;
|
|
31
|
+
if (!(error instanceof TeamsoApiError)) {
|
|
32
|
+
if (error instanceof Error && (error.name === 'TimeoutError' || error.name === 'AbortError')) {
|
|
33
|
+
return 'The request to Teamso timed out or was cancelled. Try again in a moment.';
|
|
34
|
+
}
|
|
35
|
+
return error instanceof Error ? error.message : String(error);
|
|
36
|
+
}
|
|
37
|
+
const codes = [error.apiMessage, error.messageCode].filter((code) => Boolean(code));
|
|
38
|
+
for (const code of codes) {
|
|
39
|
+
const hint = hints.byCode?.[code];
|
|
40
|
+
if (hint)
|
|
41
|
+
return `${hint}\n\n${errorReference(error)}`;
|
|
42
|
+
}
|
|
43
|
+
if (error.status === 401) {
|
|
44
|
+
return 'Teamso rejected the access token (it is invalid, expired, revoked, or its owner is inactive). '
|
|
45
|
+
+ `Create a new personal access token at ${ACCESS_TOKEN_URL} and update \`TEAMSO_ACCESS_TOKEN\`.\n\n`
|
|
46
|
+
+ errorReference(error);
|
|
47
|
+
}
|
|
48
|
+
if (error.status === 403 && error.messageCode === 'IP_NOT_ALLOWED') {
|
|
49
|
+
return 'Your company only allows Teamso access from approved IP addresses, and this request came from '
|
|
50
|
+
+ 'an address outside that list. Ask your Teamso administrator to allow it.\n\n'
|
|
51
|
+
+ errorReference(error);
|
|
52
|
+
}
|
|
53
|
+
if (error.status === 403 || error.messageCode === 'PERMISSION_DENIED') {
|
|
54
|
+
const need = hints.forbidden ? ` ${hints.forbidden}` : '';
|
|
55
|
+
return `Your Teamso account is not allowed to do this.${need} `
|
|
56
|
+
+ 'Ask your Teamso administrator if you need access.\n\n'
|
|
57
|
+
+ errorReference(error);
|
|
58
|
+
}
|
|
59
|
+
if (error.status === 404 || error.messageCode === 'ITEM_NOT_FOUND' || error.messageCode === 'USER_NOT_FOUND') {
|
|
60
|
+
const text = hints.notFound ?? 'Teamso could not find that record, or it is not visible to you.';
|
|
61
|
+
return `${text}\n\n${errorReference(error)}`;
|
|
62
|
+
}
|
|
63
|
+
if (error.status === 429) {
|
|
64
|
+
return 'Too many requests to Teamso. Wait a minute and try again.\n\n' + errorReference(error);
|
|
65
|
+
}
|
|
66
|
+
if (error.status >= 500) {
|
|
67
|
+
return 'Teamso could not complete the request because of a server error. Try again later.\n\n'
|
|
68
|
+
+ errorReference(error);
|
|
69
|
+
}
|
|
70
|
+
if (error.messageCode === 'CREDIT_INSUFFICIENT') {
|
|
71
|
+
return 'Your company does not have enough digital (SMS) credit for this step. '
|
|
72
|
+
+ 'Ask your Teamso administrator to top up credits.\n\n'
|
|
73
|
+
+ errorReference(error);
|
|
74
|
+
}
|
|
75
|
+
const detail = typeof error.result === 'string' && error.result !== error.apiMessage
|
|
76
|
+
? ` (${error.result})`
|
|
77
|
+
: '';
|
|
78
|
+
return `${error.apiMessage ?? 'The request failed.'}${detail}\n\n${errorReference(error)}`;
|
|
79
|
+
}
|
|
80
|
+
function errorReference(error) {
|
|
81
|
+
const parts = [`HTTP ${error.status}`];
|
|
82
|
+
if (error.messageCode)
|
|
83
|
+
parts.push(`\`${error.messageCode}\``);
|
|
84
|
+
if (error.apiMessage && error.apiMessage !== error.messageCode)
|
|
85
|
+
parts.push(error.apiMessage);
|
|
86
|
+
return `_Teamso API: ${parts.join(' · ')}_`;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=results.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"results.js","sourceRoot":"","sources":["../../src/utils/results.ts"],"names":[],"mappings":"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"}
|