@get-technology-inc/jamf-docs-mcp-server 3.0.5 → 3.0.7
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/dist/core/constants/doc-types.d.ts +48 -0
- package/dist/core/constants/doc-types.d.ts.map +1 -0
- package/dist/core/constants/doc-types.js +58 -0
- package/dist/core/constants/doc-types.js.map +1 -0
- package/dist/core/constants/index.d.ts +16 -0
- package/dist/core/constants/index.d.ts.map +1 -0
- package/dist/core/constants/index.js +12 -0
- package/dist/core/constants/index.js.map +1 -0
- package/dist/core/constants/limits.d.ts +39 -0
- package/dist/core/constants/limits.d.ts.map +1 -0
- package/dist/core/constants/limits.js +51 -0
- package/dist/core/constants/limits.js.map +1 -0
- package/dist/core/constants/locales.d.ts +34 -0
- package/dist/core/constants/locales.d.ts.map +1 -0
- package/dist/core/constants/locales.js +20 -0
- package/dist/core/constants/locales.js.map +1 -0
- package/dist/core/constants/products.d.ts +127 -0
- package/dist/core/constants/products.d.ts.map +1 -0
- package/dist/core/constants/products.js +135 -0
- package/dist/core/constants/products.js.map +1 -0
- package/dist/core/constants/topics.d.ts +168 -0
- package/dist/core/constants/topics.d.ts.map +1 -0
- package/dist/core/constants/topics.js +186 -0
- package/dist/core/constants/topics.js.map +1 -0
- package/dist/core/constants.d.ts +7 -404
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +16 -427
- package/dist/core/constants.js.map +1 -1
- package/dist/core/http-client.d.ts +14 -2
- package/dist/core/http-client.d.ts.map +1 -1
- package/dist/core/http-client.js +148 -17
- package/dist/core/http-client.js.map +1 -1
- package/dist/core/index.d.ts +12 -12
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +12 -13
- package/dist/core/index.js.map +1 -1
- package/dist/core/resources/index.js +1 -1
- package/dist/core/resources/index.js.map +1 -1
- package/dist/core/schemas/index.d.ts +3 -1
- package/dist/core/schemas/index.d.ts.map +1 -1
- package/dist/core/schemas/index.js +12 -1
- package/dist/core/schemas/index.js.map +1 -1
- package/dist/core/schemas/output.d.ts +7 -0
- package/dist/core/schemas/output.d.ts.map +1 -1
- package/dist/core/schemas/output.js +7 -0
- package/dist/core/schemas/output.js.map +1 -1
- package/dist/core/services/article-service.d.ts +24 -0
- package/dist/core/services/article-service.d.ts.map +1 -0
- package/dist/core/services/article-service.js +118 -0
- package/dist/core/services/article-service.js.map +1 -0
- package/dist/core/services/content-parser.d.ts +38 -0
- package/dist/core/services/content-parser.d.ts.map +1 -0
- package/dist/core/services/content-parser.js +146 -0
- package/dist/core/services/content-parser.js.map +1 -0
- package/dist/core/services/ft-client.d.ts +52 -0
- package/dist/core/services/ft-client.d.ts.map +1 -0
- package/dist/core/services/ft-client.js +87 -0
- package/dist/core/services/ft-client.js.map +1 -0
- package/dist/core/services/glossary.d.ts +9 -5
- package/dist/core/services/glossary.d.ts.map +1 -1
- package/dist/core/services/glossary.js +174 -107
- package/dist/core/services/glossary.js.map +1 -1
- package/dist/core/services/interfaces/cache.d.ts +6 -6
- package/dist/core/services/interfaces/cache.d.ts.map +1 -1
- package/dist/core/services/interfaces/index.d.ts +3 -3
- package/dist/core/services/interfaces/index.d.ts.map +1 -1
- package/dist/core/services/interfaces/logger.d.ts +17 -10
- package/dist/core/services/interfaces/logger.d.ts.map +1 -1
- package/dist/core/services/interfaces/metadata.d.ts +0 -10
- package/dist/core/services/interfaces/metadata.d.ts.map +1 -1
- package/dist/core/services/interfaces/providers.d.ts +26 -10
- package/dist/core/services/interfaces/providers.d.ts.map +1 -1
- package/dist/core/services/logging.d.ts +38 -18
- package/dist/core/services/logging.d.ts.map +1 -1
- package/dist/core/services/logging.js +78 -29
- package/dist/core/services/logging.js.map +1 -1
- package/dist/core/services/maps-registry.d.ts +82 -0
- package/dist/core/services/maps-registry.d.ts.map +1 -0
- package/dist/core/services/maps-registry.js +232 -0
- package/dist/core/services/maps-registry.js.map +1 -0
- package/dist/core/services/metadata.d.ts +18 -9
- package/dist/core/services/metadata.d.ts.map +1 -1
- package/dist/core/services/metadata.js +113 -254
- package/dist/core/services/metadata.js.map +1 -1
- package/dist/core/services/search-service.d.ts +31 -0
- package/dist/core/services/search-service.d.ts.map +1 -0
- package/dist/core/services/search-service.js +471 -0
- package/dist/core/services/search-service.js.map +1 -0
- package/dist/core/services/toc-service.d.ts +30 -0
- package/dist/core/services/toc-service.d.ts.map +1 -0
- package/dist/core/services/toc-service.js +101 -0
- package/dist/core/services/toc-service.js.map +1 -0
- package/dist/core/services/tokenizer.d.ts +1 -1
- package/dist/core/services/tokenizer.d.ts.map +1 -1
- package/dist/core/services/tokenizer.js +3 -3
- package/dist/core/services/tokenizer.js.map +1 -1
- package/dist/core/services/topic-resolver.d.ts +57 -0
- package/dist/core/services/topic-resolver.d.ts.map +1 -0
- package/dist/core/services/topic-resolver.js +185 -0
- package/dist/core/services/topic-resolver.js.map +1 -0
- package/dist/core/tools/batch-get-articles.d.ts +0 -2
- package/dist/core/tools/batch-get-articles.d.ts.map +1 -1
- package/dist/core/tools/batch-get-articles.js +12 -46
- package/dist/core/tools/batch-get-articles.js.map +1 -1
- package/dist/core/tools/get-article.d.ts.map +1 -1
- package/dist/core/tools/get-article.js +29 -112
- package/dist/core/tools/get-article.js.map +1 -1
- package/dist/core/tools/get-toc.js +1 -1
- package/dist/core/tools/get-toc.js.map +1 -1
- package/dist/core/tools/search.js +5 -5
- package/dist/core/tools/search.js.map +1 -1
- package/dist/core/types/context.d.ts +5 -2
- package/dist/core/types/context.d.ts.map +1 -1
- package/dist/core/types.d.ts +141 -31
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils/bundle.d.ts +14 -1
- package/dist/core/utils/bundle.d.ts.map +1 -1
- package/dist/core/utils/bundle.js +19 -2
- package/dist/core/utils/bundle.js.map +1 -1
- package/dist/core/utils/format-article.d.ts +45 -0
- package/dist/core/utils/format-article.d.ts.map +1 -0
- package/dist/core/utils/format-article.js +138 -0
- package/dist/core/utils/format-article.js.map +1 -0
- package/dist/core/utils/ft-metadata.d.ts +22 -0
- package/dist/core/utils/ft-metadata.d.ts.map +1 -0
- package/dist/core/utils/ft-metadata.js +30 -0
- package/dist/core/utils/ft-metadata.js.map +1 -0
- package/dist/core/utils/sanitize.d.ts.map +1 -1
- package/dist/core/utils/sanitize.js +0 -2
- package/dist/core/utils/sanitize.js.map +1 -1
- package/dist/core/utils/url.d.ts.map +1 -1
- package/dist/core/utils/url.js +0 -1
- package/dist/core/utils/url.js.map +1 -1
- package/dist/index.js +10 -6
- package/dist/index.js.map +1 -1
- package/dist/platforms/node/http-server.d.ts +13 -0
- package/dist/platforms/node/http-server.d.ts.map +1 -0
- package/dist/platforms/node/http-server.js +231 -0
- package/dist/platforms/node/http-server.js.map +1 -0
- package/dist/platforms/node/index.d.ts +1 -1
- package/dist/platforms/node/index.d.ts.map +1 -1
- package/dist/platforms/node/index.js +1 -1
- package/dist/platforms/node/index.js.map +1 -1
- package/dist/platforms/node/logger.d.ts +13 -2
- package/dist/platforms/node/logger.d.ts.map +1 -1
- package/dist/platforms/node/logger.js +17 -4
- package/dist/platforms/node/logger.js.map +1 -1
- package/dist/transport/http-handler.d.ts +25 -0
- package/dist/transport/http-handler.d.ts.map +1 -0
- package/dist/transport/http-handler.js +193 -0
- package/dist/transport/http-handler.js.map +1 -0
- package/dist/transport/http-types.d.ts +22 -0
- package/dist/transport/http-types.d.ts.map +1 -0
- package/dist/transport/http-types.js +65 -0
- package/dist/transport/http-types.js.map +1 -0
- package/dist/transport/http.d.ts +4 -8
- package/dist/transport/http.d.ts.map +1 -1
- package/dist/transport/http.js +4 -376
- package/dist/transport/http.js.map +1 -1
- package/dist/transport/index.js +2 -2
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/rate-limiter.d.ts +16 -0
- package/dist/transport/rate-limiter.d.ts.map +1 -0
- package/dist/transport/rate-limiter.js +55 -0
- package/dist/transport/rate-limiter.js.map +1 -0
- package/package.json +3 -3
- package/dist/core/services/interfaces.d.ts +0 -94
- package/dist/core/services/interfaces.d.ts.map +0 -1
- package/dist/core/services/interfaces.js +0 -8
- package/dist/core/services/interfaces.js.map +0 -1
- package/dist/core/services/scraper.d.ts +0 -90
- package/dist/core/services/scraper.d.ts.map +0 -1
- package/dist/core/services/scraper.js +0 -966
- package/dist/core/services/scraper.js.map +0 -1
- package/dist/core/utils/doc-type.d.ts +0 -12
- package/dist/core/utils/doc-type.d.ts.map +0 -1
- package/dist/core/utils/doc-type.js +0 -24
- package/dist/core/utils/doc-type.js.map +0 -1
- package/dist/platforms/node/metadata.d.ts +0 -18
- package/dist/platforms/node/metadata.d.ts.map +0 -1
- package/dist/platforms/node/metadata.js +0 -35
- package/dist/platforms/node/metadata.js.map +0 -1
|
@@ -8,10 +8,23 @@ import { type ProductId } from '../constants.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export declare function compareVersions(a: string, b: string): number;
|
|
10
10
|
/**
|
|
11
|
-
* Extract version number from a bundle_id
|
|
11
|
+
* Extract version number from a bundle_id (2-part or 3-part).
|
|
12
12
|
* e.g., "jamf-pro-documentation-11.25.0" -> "11.25.0"
|
|
13
|
+
* "jamf-school-documentation-2.45" -> "2.45"
|
|
13
14
|
*/
|
|
14
15
|
export declare function extractVersionFromBundleId(bundleId: string): string | null;
|
|
16
|
+
/**
|
|
17
|
+
* Return the bundleId with its version suffix removed.
|
|
18
|
+
* e.g., "jamf-pro-documentation-11.25.0" -> "jamf-pro-documentation"
|
|
19
|
+
* "jamf-pro-documentation" -> "jamf-pro-documentation"
|
|
20
|
+
*/
|
|
21
|
+
export declare function stripVersionSuffix(bundleId: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Strip the "-current" suffix from a bundle identifier.
|
|
24
|
+
* e.g., "jamf-pro-documentation-current" -> "jamf-pro-documentation"
|
|
25
|
+
* "jamf-pro-documentation" -> "jamf-pro-documentation"
|
|
26
|
+
*/
|
|
27
|
+
export declare function stripCurrentSuffix(s: string): string;
|
|
15
28
|
/**
|
|
16
29
|
* Extract product slug from any bundle_id format.
|
|
17
30
|
* Matches against known product IDs so it works for documentation, release-notes, etc.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../../src/core/utils/bundle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIhE;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAkB5D;AAED
|
|
1
|
+
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../../src/core/utils/bundle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIhE;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAkB5D;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG1E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpD;AAOD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAOrE"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Bundle ID utilities
|
|
3
3
|
*/
|
|
4
4
|
import { JAMF_PRODUCTS } from '../constants.js';
|
|
5
|
-
const BUNDLE_VERSION_REGEX = /-(\d+\.\d
|
|
5
|
+
const BUNDLE_VERSION_REGEX = /-(\d+\.\d+(?:\.\d+)?)$/;
|
|
6
6
|
/**
|
|
7
7
|
* Compare two version strings. Returns positive if a > b, negative if a < b, 0 if equal.
|
|
8
8
|
* "current" is always treated as the maximum value.
|
|
@@ -33,13 +33,30 @@ export function compareVersions(a, b) {
|
|
|
33
33
|
return 0;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
* Extract version number from a bundle_id
|
|
36
|
+
* Extract version number from a bundle_id (2-part or 3-part).
|
|
37
37
|
* e.g., "jamf-pro-documentation-11.25.0" -> "11.25.0"
|
|
38
|
+
* "jamf-school-documentation-2.45" -> "2.45"
|
|
38
39
|
*/
|
|
39
40
|
export function extractVersionFromBundleId(bundleId) {
|
|
40
41
|
const match = BUNDLE_VERSION_REGEX.exec(bundleId);
|
|
41
42
|
return match?.[1] ?? null;
|
|
42
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Return the bundleId with its version suffix removed.
|
|
46
|
+
* e.g., "jamf-pro-documentation-11.25.0" -> "jamf-pro-documentation"
|
|
47
|
+
* "jamf-pro-documentation" -> "jamf-pro-documentation"
|
|
48
|
+
*/
|
|
49
|
+
export function stripVersionSuffix(bundleId) {
|
|
50
|
+
return bundleId.replace(BUNDLE_VERSION_REGEX, '');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Strip the "-current" suffix from a bundle identifier.
|
|
54
|
+
* e.g., "jamf-pro-documentation-current" -> "jamf-pro-documentation"
|
|
55
|
+
* "jamf-pro-documentation" -> "jamf-pro-documentation"
|
|
56
|
+
*/
|
|
57
|
+
export function stripCurrentSuffix(s) {
|
|
58
|
+
return s.replace(/-current$/, '');
|
|
59
|
+
}
|
|
43
60
|
// Product IDs sorted by length descending to match longest prefix first
|
|
44
61
|
// (e.g., "jamf-protect" before "jamf-pro")
|
|
45
62
|
const SORTED_PRODUCT_IDS = Object.keys(JAMF_PRODUCTS)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../../src/core/utils/bundle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAkB,MAAM,iBAAiB,CAAC;AAEhE,MAAM,oBAAoB,GAAG,
|
|
1
|
+
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../../src/core/utils/bundle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAkB,MAAM,iBAAiB,CAAC;AAEhE,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;AAEtD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,CAAS,EAAE,CAAS;IAClD,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAAC,OAAO,CAAC,CAAC;IAAC,CAAC;IAC1B,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;QAAC,OAAO,CAAC,CAAC;IAAC,CAAC;IAClC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;QAAC,OAAO,CAAC,CAAC,CAAC;IAAC,CAAC;IAEnC,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAEnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;QACD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAAC,OAAO,IAAI,GAAG,IAAI,CAAC;QAAC,CAAC;IAC5C,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,QAAgB;IACzD,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClD,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,QAAQ,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,CAAS;IAC1C,OAAO,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,wEAAwE;AACxE,2CAA2C;AAC3C,MAAM,kBAAkB,GAAiB,MAAM,CAAC,IAAI,CAAC,aAAa,CAAiB;KAChF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvC;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACrC,IAAI,QAAQ,KAAK,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;YACvD,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared article formatting utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent Markdown formatting for article output
|
|
5
|
+
* used by both get-article and batch-get-articles tools.
|
|
6
|
+
*/
|
|
7
|
+
import type { ArticleSection, FetchArticleResult } from '../types.js';
|
|
8
|
+
interface RelatedArticle {
|
|
9
|
+
title: string;
|
|
10
|
+
url: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Options for full (non-compact) article formatting.
|
|
14
|
+
* All fields are optional so that batch-get-articles can omit them.
|
|
15
|
+
*/
|
|
16
|
+
export interface FormatArticleFullOptions {
|
|
17
|
+
/** Show breadcrumb trail above the title */
|
|
18
|
+
breadcrumb?: string[] | undefined;
|
|
19
|
+
/** Show "Last Updated" in metadata line */
|
|
20
|
+
lastUpdated?: string | undefined;
|
|
21
|
+
/** Show "Showing section: ..." note */
|
|
22
|
+
section?: string | undefined;
|
|
23
|
+
/** Show the sections list when content is truncated */
|
|
24
|
+
sections?: ArticleSection[] | undefined;
|
|
25
|
+
/** Include related article links at the bottom */
|
|
26
|
+
relatedArticles?: RelatedArticle[] | undefined;
|
|
27
|
+
/** Use brief footer (source link only, no token count line). Default: false */
|
|
28
|
+
briefFooter?: boolean | undefined;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Format an article in compact mode.
|
|
32
|
+
*
|
|
33
|
+
* Output: title, compact metadata (product | version), content, compact footer.
|
|
34
|
+
*/
|
|
35
|
+
export declare function formatArticleCompact(article: FetchArticleResult): string;
|
|
36
|
+
/**
|
|
37
|
+
* Format an article in full mode.
|
|
38
|
+
*
|
|
39
|
+
* Output: breadcrumb (optional), title, full metadata, section note (optional),
|
|
40
|
+
* separator, content, sections list (optional), related articles (optional),
|
|
41
|
+
* full footer.
|
|
42
|
+
*/
|
|
43
|
+
export declare function formatArticleFull(article: FetchArticleResult, options?: FormatArticleFullOptions): string;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=format-article.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-article.d.ts","sourceRoot":"","sources":["../../../src/core/utils/format-article.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAa,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAOjF,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAClC,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,cAAc,EAAE,GAAG,SAAS,CAAC;IACxC,kDAAkD;IAClD,eAAe,CAAC,EAAE,cAAc,EAAE,GAAG,SAAS,CAAC;IAC/C,+EAA+E;IAC/E,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACnC;AAkHD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,kBAAkB,GAC1B,MAAM,CAMR;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,kBAAkB,EAC3B,OAAO,GAAE,wBAA6B,GACrC,MAAM,CAoCR"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared article formatting utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent Markdown formatting for article output
|
|
5
|
+
* used by both get-article and batch-get-articles tools.
|
|
6
|
+
*/
|
|
7
|
+
import { sanitizeMarkdownText, sanitizeMarkdownUrl } from './sanitize.js';
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Internal helpers
|
|
10
|
+
// ============================================================================
|
|
11
|
+
function formatBreadcrumb(breadcrumb) {
|
|
12
|
+
if (breadcrumb === undefined || breadcrumb.length === 0) {
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
return `*${breadcrumb.join(' > ')}*\n\n`;
|
|
16
|
+
}
|
|
17
|
+
function formatFullMetadata(product, version, lastUpdated, tokenInfo) {
|
|
18
|
+
const meta = [];
|
|
19
|
+
if (product !== undefined && product !== '') {
|
|
20
|
+
meta.push(`**Product**: ${product}`);
|
|
21
|
+
}
|
|
22
|
+
if (version !== undefined && version !== '') {
|
|
23
|
+
meta.push(`**Version**: ${version}`);
|
|
24
|
+
}
|
|
25
|
+
if (lastUpdated !== undefined && lastUpdated !== '') {
|
|
26
|
+
meta.push(`**Last Updated**: ${lastUpdated}`);
|
|
27
|
+
}
|
|
28
|
+
meta.push(`**Tokens**: ${tokenInfo.tokenCount.toLocaleString()}/${tokenInfo.maxTokens.toLocaleString()}`);
|
|
29
|
+
if (tokenInfo.truncated) {
|
|
30
|
+
meta.push('*(truncated)*');
|
|
31
|
+
}
|
|
32
|
+
return meta.length > 0 ? `${meta.join(' | ')}\n\n` : '';
|
|
33
|
+
}
|
|
34
|
+
function formatCompactMetadata(product, version) {
|
|
35
|
+
const meta = [];
|
|
36
|
+
if (product !== undefined && product !== '') {
|
|
37
|
+
meta.push(product);
|
|
38
|
+
}
|
|
39
|
+
if (version !== undefined && version !== '') {
|
|
40
|
+
meta.push(`v${version}`);
|
|
41
|
+
}
|
|
42
|
+
return meta.length > 0 ? `*${meta.join(' | ')}*\n\n` : '';
|
|
43
|
+
}
|
|
44
|
+
function formatSectionsList(sections, tokenInfo) {
|
|
45
|
+
if (sections.length === 0 || !tokenInfo.truncated) {
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
48
|
+
let result = '\n\n---\n\n## Available Sections\n\n';
|
|
49
|
+
for (const section of sections.slice(0, 15)) {
|
|
50
|
+
const indent = ' '.repeat(Math.max(0, section.level - 1));
|
|
51
|
+
result += `${indent}- **${section.title}** (~${String(section.tokenCount)} tokens)\n`;
|
|
52
|
+
}
|
|
53
|
+
if (sections.length > 15) {
|
|
54
|
+
result += `\n*...and ${String(sections.length - 15)} more sections*\n`;
|
|
55
|
+
}
|
|
56
|
+
result += '\n*Use `section` parameter to retrieve a specific section.*\n';
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
function formatRelatedArticles(articles) {
|
|
60
|
+
if (articles === undefined || articles.length === 0) {
|
|
61
|
+
return '';
|
|
62
|
+
}
|
|
63
|
+
let result = '\n\n---\n\n## Related Articles\n\n';
|
|
64
|
+
for (const related of articles) {
|
|
65
|
+
result += `- [${sanitizeMarkdownText(related.title)}](${sanitizeMarkdownUrl(related.url)})\n`;
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
function formatFullFooter(url, tokenInfo) {
|
|
70
|
+
const safeUrl = sanitizeMarkdownUrl(url);
|
|
71
|
+
let result = '\n\n---\n\n';
|
|
72
|
+
result += `*Source: [${sanitizeMarkdownText(url)}](${safeUrl})*\n`;
|
|
73
|
+
result += `*${tokenInfo.tokenCount.toLocaleString()} tokens`;
|
|
74
|
+
if (tokenInfo.truncated) {
|
|
75
|
+
result += ` (truncated from original, max: ${tokenInfo.maxTokens.toLocaleString()})`;
|
|
76
|
+
}
|
|
77
|
+
result += '*\n';
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Brief footer: source link only, no token count line.
|
|
82
|
+
* Used by batch-get-articles in full mode.
|
|
83
|
+
*/
|
|
84
|
+
function formatBriefFooter(url) {
|
|
85
|
+
const safeUrl = sanitizeMarkdownUrl(url);
|
|
86
|
+
return `\n\n---\n*Source: [${sanitizeMarkdownText(url)}](${safeUrl})*\n`;
|
|
87
|
+
}
|
|
88
|
+
function formatCompactFooter(url, tokenInfo) {
|
|
89
|
+
const safeUrl = sanitizeMarkdownUrl(url);
|
|
90
|
+
return `\n---\n*[Source](${safeUrl}) | ${tokenInfo.tokenCount} tokens${tokenInfo.truncated ? ' (truncated)' : ''}*\n`;
|
|
91
|
+
}
|
|
92
|
+
// ============================================================================
|
|
93
|
+
// Public API
|
|
94
|
+
// ============================================================================
|
|
95
|
+
/**
|
|
96
|
+
* Format an article in compact mode.
|
|
97
|
+
*
|
|
98
|
+
* Output: title, compact metadata (product | version), content, compact footer.
|
|
99
|
+
*/
|
|
100
|
+
export function formatArticleCompact(article) {
|
|
101
|
+
let markdown = `# ${article.title}\n\n`;
|
|
102
|
+
markdown += formatCompactMetadata(article.product, article.version);
|
|
103
|
+
markdown += article.content;
|
|
104
|
+
markdown += formatCompactFooter(article.url, article.tokenInfo);
|
|
105
|
+
return markdown;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Format an article in full mode.
|
|
109
|
+
*
|
|
110
|
+
* Output: breadcrumb (optional), title, full metadata, section note (optional),
|
|
111
|
+
* separator, content, sections list (optional), related articles (optional),
|
|
112
|
+
* full footer.
|
|
113
|
+
*/
|
|
114
|
+
export function formatArticleFull(article, options = {}) {
|
|
115
|
+
const { tokenInfo } = article;
|
|
116
|
+
let markdown = '';
|
|
117
|
+
markdown += formatBreadcrumb(options.breadcrumb);
|
|
118
|
+
markdown += `# ${article.title}\n\n`;
|
|
119
|
+
markdown += formatFullMetadata(article.product, article.version, options.lastUpdated, tokenInfo);
|
|
120
|
+
if (options.section !== undefined && options.section !== '') {
|
|
121
|
+
markdown += `*Showing section: "${options.section}"*\n\n`;
|
|
122
|
+
}
|
|
123
|
+
markdown += '---\n\n';
|
|
124
|
+
markdown += article.content;
|
|
125
|
+
if (options.sections !== undefined &&
|
|
126
|
+
(options.section === undefined || options.section === '')) {
|
|
127
|
+
markdown += formatSectionsList(options.sections, tokenInfo);
|
|
128
|
+
}
|
|
129
|
+
markdown += formatRelatedArticles(options.relatedArticles);
|
|
130
|
+
if (options.briefFooter === true) {
|
|
131
|
+
markdown += formatBriefFooter(article.url);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
markdown += formatFullFooter(article.url, tokenInfo);
|
|
135
|
+
}
|
|
136
|
+
return markdown;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=format-article.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-article.js","sourceRoot":"","sources":["../../../src/core/utils/format-article.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for working with Fluid Topics metadata entries.
|
|
3
|
+
*/
|
|
4
|
+
import type { FtMetadataEntry } from '../types.js';
|
|
5
|
+
export declare const FT_META: {
|
|
6
|
+
readonly VERSION_BUNDLE_STEM: "version_bundle_stem";
|
|
7
|
+
readonly VERSION: "version";
|
|
8
|
+
readonly LATEST_VERSION: "latestVersion";
|
|
9
|
+
readonly LOCALE: "ft:locale";
|
|
10
|
+
readonly PRETTY_URL: "ft:prettyUrl";
|
|
11
|
+
readonly BUNDLE: "bundle";
|
|
12
|
+
readonly LEGACY_TOPICNAME: "legacy_topicname";
|
|
13
|
+
readonly LEGACY_URL: "legacy_url";
|
|
14
|
+
readonly ZOOMIN_METADATA: "zoominmetadata";
|
|
15
|
+
readonly CONTENT_TYPE: "jamf:contentType";
|
|
16
|
+
readonly CLUSTER_ID: "ft:clusterId";
|
|
17
|
+
readonly PUBLICATION_ID: "ft:publicationId";
|
|
18
|
+
};
|
|
19
|
+
export declare function getMetaValue(metadata: FtMetadataEntry[], key: string): string;
|
|
20
|
+
export declare function getMetaValues(metadata: FtMetadataEntry[], key: string): string[];
|
|
21
|
+
export declare function bundleStemToDisplayName(stem: string): string;
|
|
22
|
+
//# sourceMappingURL=ft-metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ft-metadata.d.ts","sourceRoot":"","sources":["../../../src/core/utils/ft-metadata.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,eAAO,MAAM,OAAO;;;;;;;;;;;;;CAaV,CAAC;AAEX,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAG7E;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAGhF;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK5D"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Well-known FT metadata keys used across the codebase
|
|
2
|
+
export const FT_META = {
|
|
3
|
+
VERSION_BUNDLE_STEM: 'version_bundle_stem',
|
|
4
|
+
VERSION: 'version',
|
|
5
|
+
LATEST_VERSION: 'latestVersion',
|
|
6
|
+
LOCALE: 'ft:locale',
|
|
7
|
+
PRETTY_URL: 'ft:prettyUrl',
|
|
8
|
+
BUNDLE: 'bundle',
|
|
9
|
+
LEGACY_TOPICNAME: 'legacy_topicname',
|
|
10
|
+
LEGACY_URL: 'legacy_url',
|
|
11
|
+
ZOOMIN_METADATA: 'zoominmetadata',
|
|
12
|
+
CONTENT_TYPE: 'jamf:contentType',
|
|
13
|
+
CLUSTER_ID: 'ft:clusterId',
|
|
14
|
+
PUBLICATION_ID: 'ft:publicationId',
|
|
15
|
+
};
|
|
16
|
+
export function getMetaValue(metadata, key) {
|
|
17
|
+
const entry = metadata.find(m => m.key === key);
|
|
18
|
+
return entry?.values[0] ?? '';
|
|
19
|
+
}
|
|
20
|
+
export function getMetaValues(metadata, key) {
|
|
21
|
+
const entry = metadata.find(m => m.key === key);
|
|
22
|
+
return entry?.values ?? [];
|
|
23
|
+
}
|
|
24
|
+
export function bundleStemToDisplayName(stem) {
|
|
25
|
+
return stem
|
|
26
|
+
.replace(/-documentation$/, '')
|
|
27
|
+
.replace(/-/g, ' ')
|
|
28
|
+
.replace(/\b\w/g, c => c.toUpperCase());
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=ft-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ft-metadata.js","sourceRoot":"","sources":["../../../src/core/utils/ft-metadata.ts"],"names":[],"mappings":"AAKA,uDAAuD;AACvD,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,mBAAmB,EAAE,qBAAqB;IAC1C,OAAO,EAAE,SAAS;IAClB,cAAc,EAAE,eAAe;IAC/B,MAAM,EAAE,WAAW;IACnB,UAAU,EAAE,cAAc;IAC1B,MAAM,EAAE,QAAQ;IAChB,gBAAgB,EAAE,kBAAkB;IACpC,UAAU,EAAE,YAAY;IACxB,eAAe,EAAE,gBAAgB;IACjC,YAAY,EAAE,kBAAkB;IAChC,UAAU,EAAE,cAAc;IAC1B,cAAc,EAAE,kBAAkB;CAC1B,CAAC;AAEX,MAAM,UAAU,YAAY,CAAC,QAA2B,EAAE,GAAW;IACnE,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IAChD,OAAO,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAA2B,EAAE,GAAW;IACpE,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IAChD,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,OAAO,IAAI;SACR,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;SAC9B,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;SAClB,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAC5C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../../src/core/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWvD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAG1D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../../src/core/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWvD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAG1D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAW5D"}
|
|
@@ -45,8 +45,6 @@ export function getSafeErrorMessage(error) {
|
|
|
45
45
|
*/
|
|
46
46
|
export function sanitizeErrorMessage(message) {
|
|
47
47
|
let sanitized = message;
|
|
48
|
-
// Replace backend hostname with frontend (hostnames extracted from DOCS_API_URL / DOCS_BASE_URL)
|
|
49
|
-
sanitized = sanitized.replaceAll('learn-be.jamf.com', 'learn.jamf.com');
|
|
50
48
|
// Remove absolute file paths (Unix and Windows)
|
|
51
49
|
sanitized = sanitized.replace(/(?<![:/\w.])\/[\w./-]+\.\w{1,4}/g, '<path>');
|
|
52
50
|
sanitized = sanitized.replace(/[A-Z]:\\[\w.\\-]+\.\w{1,4}/g, '<path>');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../../src/core/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO,GAAG,CAAC;QACb,CAAC;QACD,iFAAiF;QACjF,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;IAC9E,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,IAAI,SAAS,GAAG,OAAO,CAAC;IAExB,
|
|
1
|
+
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../../src/core/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO,GAAG,CAAC;QACb,CAAC;QACD,iFAAiF;QACjF,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;IAC9E,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,IAAI,SAAS,GAAG,OAAO,CAAC;IAExB,gDAAgD;IAChD,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,kCAAkC,EAAE,QAAQ,CAAC,CAAC;IAC5E,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAC;IAEvE,kDAAkD;IAClD,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAEnD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../../src/core/utils/url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAqC,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEnF,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../../src/core/utils/url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAqC,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEnF,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,aAG5B,CAAC;AAEH,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAOzD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAa7D"}
|
package/dist/core/utils/url.js
CHANGED
|
@@ -8,7 +8,6 @@ import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from '../constants.js';
|
|
|
8
8
|
/** Allowed hostnames for URL validation. */
|
|
9
9
|
export const ALLOWED_HOSTNAMES = new Set([
|
|
10
10
|
'learn.jamf.com',
|
|
11
|
-
'learn-be.jamf.com',
|
|
12
11
|
'docs.jamf.com',
|
|
13
12
|
]);
|
|
14
13
|
/** Check whether a URL string points to an allowed Jamf documentation hostname with HTTPS. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.js","sourceRoot":"","sources":["../../../src/core/utils/url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AAEnF,4CAA4C;AAC5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IACvC,gBAAgB;IAChB,
|
|
1
|
+
{"version":3,"file":"url.js","sourceRoot":"","sources":["../../../src/core/utils/url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AAEnF,4CAA4C;AAC5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IACvC,gBAAgB;IAChB,eAAe;CAChB,CAAC,CAAC;AAEH,8FAA8F;AAC9F,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5B,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,YAAY,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7D,+DAA+D;QAC/D,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,IAAI,iBAAiB,EAAE,CAAC;YAC9D,OAAO,SAAqB,CAAC;QAC/B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4BAA4B;IAC9B,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -10,10 +10,11 @@ import { createMcpServer } from './core/create-server.js';
|
|
|
10
10
|
import { createNodeConfig } from './platforms/node/config.js';
|
|
11
11
|
import { FileCache } from './platforms/node/cache.js';
|
|
12
12
|
import { NodeLoggerFactory } from './platforms/node/logger.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { MapsRegistry } from './core/services/maps-registry.js';
|
|
14
|
+
import { TopicResolver } from './core/services/topic-resolver.js';
|
|
15
|
+
import { createStderrLogger } from './core/services/logging.js';
|
|
15
16
|
import { parseCliArgs } from './transport/index.js';
|
|
16
|
-
const log =
|
|
17
|
+
const log = createStderrLogger('server');
|
|
17
18
|
// Build Node.js platform context
|
|
18
19
|
const config = createNodeConfig();
|
|
19
20
|
const logger = new NodeLoggerFactory();
|
|
@@ -22,14 +23,17 @@ const cache = new FileCache({
|
|
|
22
23
|
maxEntries: config.cache.maxEntries,
|
|
23
24
|
log: logger.createLogger('cache'),
|
|
24
25
|
});
|
|
25
|
-
// Build
|
|
26
|
+
// Build singleton services
|
|
27
|
+
const mapsRegistry = new MapsRegistry(cache, undefined, undefined, config.cacheTtl.products);
|
|
28
|
+
const topicResolver = new TopicResolver(mapsRegistry, cache, undefined, config.cacheTtl.article);
|
|
29
|
+
// Build the complete ServerContext
|
|
26
30
|
const ctx = {
|
|
27
31
|
config,
|
|
28
32
|
logger,
|
|
29
33
|
cache,
|
|
30
|
-
|
|
34
|
+
mapsRegistry,
|
|
35
|
+
topicResolver,
|
|
31
36
|
};
|
|
32
|
-
ctx.metadata = new NodeMetadataStore(ctx);
|
|
33
37
|
// Create the MCP server with all tools, resources, and prompts registered
|
|
34
38
|
const server = createMcpServer(ctx);
|
|
35
39
|
// Start server
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js HTTP server adapter
|
|
3
|
+
*
|
|
4
|
+
* Bridges the platform-agnostic HTTP handler with Node.js `node:http`.
|
|
5
|
+
* All Node.js-specific code (IncomingMessage, ServerResponse, process,
|
|
6
|
+
* Buffer, env vars) is isolated here.
|
|
7
|
+
*/
|
|
8
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
9
|
+
/**
|
|
10
|
+
* Create and start an HTTP server for the MCP server (Node.js platform).
|
|
11
|
+
*/
|
|
12
|
+
export declare function startHttpServer(mcpServer: McpServer, port: number, host: string): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=http-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../../../src/platforms/node/http-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAwJzE;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAkEf"}
|