@zeroheight/mcp-server 1.2.0 → 2.0.0

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.
@@ -2,21 +2,19 @@
2
2
  * Styleguide Tools
3
3
  */
4
4
 
5
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="df781019-a836-5ef6-a5af-e1d5efd4c9fb")}catch(e){}}();
5
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8e279caa-2a6c-5171-8561-ff4a3a6351e4")}catch(e){}}();
6
6
  import z from "zod";
7
7
  import { getStyleguideTree, listStyleguides } from "../api/styleguide.js";
8
- import { DEFAULT_NAME, formatStyleguideListAsMarkdown, formatTreeAsJson, } from "../common/formatters/styleguide.js";
8
+ import { formatStyleguideListAsMarkdown, formatTreeAsJson, } from "../common/formatters/styleguide.js";
9
+ import { getCredentials } from "../common/credentials.js";
9
10
  export function registerListStyleguidesTool(server) {
10
11
  server.registerTool("list-styleguides", {
11
12
  title: "List styleguides",
12
- description: "List all accessible styleguides as resource links",
13
- inputSchema: {
14
- responseType: z
15
- .enum(["markdown", "resource_links"])
16
- .default("markdown"),
17
- },
18
- }, async ({ responseType }) => {
19
- const styleguides = await listStyleguides();
13
+ description: "List all accessible styleguides as markdown",
14
+ inputSchema: {},
15
+ }, async (_, { authInfo }) => {
16
+ const credentials = await getCredentials(authInfo);
17
+ const styleguides = await listStyleguides(credentials);
20
18
  if (styleguides.length === 0) {
21
19
  return {
22
20
  isError: true,
@@ -28,35 +26,13 @@ export function registerListStyleguidesTool(server) {
28
26
  ],
29
27
  };
30
28
  }
31
- if (responseType === "markdown") {
32
- return {
33
- content: [
34
- {
35
- type: "text",
36
- text: formatStyleguideListAsMarkdown(styleguides),
37
- mimeType: "text/markdown",
38
- },
39
- ],
40
- };
41
- }
42
- const resourceLinks = styleguides.map((styleguide) => ({
43
- type: "resource_link",
44
- uri: `zeroheight://styleguide/${styleguide.id}`,
45
- name: styleguide.name ?? DEFAULT_NAME,
46
- _meta: {
47
- shareId: styleguide.share_id,
48
- id: styleguide.id,
49
- },
50
- mimeType: "application/json",
51
- description: "Navigation structure for the styleguide",
52
- }));
53
29
  return {
54
30
  content: [
55
31
  {
56
32
  type: "text",
57
- text: `There are available ${styleguides.length} styleguides`,
33
+ text: formatStyleguideListAsMarkdown(styleguides),
34
+ mimeType: "text/markdown",
58
35
  },
59
- ...resourceLinks,
60
36
  ],
61
37
  };
62
38
  });
@@ -68,9 +44,10 @@ export function registerGetStyleguideTreeTool(server) {
68
44
  inputSchema: {
69
45
  styleguideId: z.number().int().positive(),
70
46
  },
71
- }, async ({ styleguideId }) => {
47
+ }, async ({ styleguideId }, { authInfo }) => {
72
48
  try {
73
- const tree = await getStyleguideTree(styleguideId);
49
+ const credentials = await getCredentials(authInfo);
50
+ const tree = await getStyleguideTree(credentials, styleguideId);
74
51
  const formattedTree = formatTreeAsJson(tree);
75
52
  return {
76
53
  content: [
@@ -95,4 +72,4 @@ export function registerGetStyleguideTreeTool(server) {
95
72
  });
96
73
  }
97
74
  //# sourceMappingURL=styleguide.js.map
98
- //# debugId=df781019-a836-5ef6-a5af-e1d5efd4c9fb
75
+ //# debugId=8e279caa-2a6c-5171-8561-ff4a3a6351e4
@@ -1 +1 @@
1
- {"version":3,"file":"styleguide.js","sources":["tools/styleguide.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Styleguide Tools\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { ResourceLink } from \"@modelcontextprotocol/sdk/types.js\";\nimport z from \"zod\";\n\nimport { getStyleguideTree, listStyleguides } from \"../api/styleguide.js\";\nimport {\n DEFAULT_NAME,\n formatStyleguideListAsMarkdown,\n formatTreeAsJson,\n} from \"../common/formatters/styleguide.js\";\n\nexport function registerListStyleguidesTool(server: McpServer) {\n server.registerTool(\n \"list-styleguides\",\n {\n title: \"List styleguides\",\n description: \"List all accessible styleguides as resource links\",\n inputSchema: {\n responseType: z\n .enum([\"markdown\", \"resource_links\"])\n .default(\"markdown\"),\n },\n },\n async ({ responseType }) => {\n const styleguides = await listStyleguides();\n\n if (styleguides.length === 0) {\n return {\n isError: true,\n content: [\n {\n type: \"text\",\n text: \"There are no accessible styleguides. Check your auth credentials and make sure you have at least one styleguide in zeroheight.\",\n },\n ],\n };\n }\n\n if (responseType === \"markdown\") {\n return {\n content: [\n {\n type: \"text\",\n text: formatStyleguideListAsMarkdown(styleguides),\n mimeType: \"text/markdown\",\n },\n ],\n };\n }\n\n const resourceLinks: ResourceLink[] = styleguides.map((styleguide) => ({\n type: \"resource_link\",\n uri: `zeroheight://styleguide/${styleguide.id}`,\n name: styleguide.name ?? DEFAULT_NAME,\n _meta: {\n shareId: styleguide.share_id,\n id: styleguide.id,\n },\n mimeType: \"application/json\",\n description: \"Navigation structure for the styleguide\",\n }));\n\n return {\n content: [\n {\n type: \"text\",\n text: `There are available ${styleguides.length} styleguides`,\n },\n ...resourceLinks,\n ],\n };\n },\n );\n}\n\nexport function registerGetStyleguideTreeTool(server: McpServer) {\n server.registerTool(\n \"get-styleguide-tree\",\n {\n title: \"Get styleguide tree\",\n description:\n \"A navigation hierarchy for a styleguide with top-level navigation, categories, pages and tabs\",\n inputSchema: {\n styleguideId: z.number().int().positive(),\n },\n },\n async ({ styleguideId }) => {\n try {\n const tree = await getStyleguideTree(styleguideId);\n const formattedTree = formatTreeAsJson(tree);\n\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(formattedTree, null, 2),\n },\n ],\n };\n } catch {\n return {\n isError: true,\n content: [\n {\n type: \"text\",\n text: \"Could not get the navigation tree for this styleguide.\",\n },\n ],\n };\n }\n },\n );\n}\n"],"names":[],"mappings":"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","debug_id":"df781019-a836-5ef6-a5af-e1d5efd4c9fb"}
1
+ {"version":3,"file":"styleguide.js","sources":["tools/styleguide.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Styleguide Tools\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport z from \"zod\";\n\nimport { getStyleguideTree, listStyleguides } from \"../api/styleguide.js\";\nimport {\n DEFAULT_NAME,\n formatStyleguideListAsMarkdown,\n formatTreeAsJson,\n} from \"../common/formatters/styleguide.js\";\nimport { getCredentials } from \"../common/credentials.js\";\n\nexport function registerListStyleguidesTool(server: McpServer) {\n server.registerTool(\n \"list-styleguides\",\n {\n title: \"List styleguides\",\n description: \"List all accessible styleguides as markdown\",\n inputSchema: {},\n },\n async (_, { authInfo }) => {\n const credentials = await getCredentials(authInfo);\n const styleguides = await listStyleguides(credentials);\n\n if (styleguides.length === 0) {\n return {\n isError: true,\n content: [\n {\n type: \"text\",\n text: \"There are no accessible styleguides. Check your auth credentials and make sure you have at least one styleguide in zeroheight.\",\n },\n ],\n };\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: formatStyleguideListAsMarkdown(styleguides),\n mimeType: \"text/markdown\",\n },\n ],\n };\n },\n );\n}\n\nexport function registerGetStyleguideTreeTool(server: McpServer) {\n server.registerTool(\n \"get-styleguide-tree\",\n {\n title: \"Get styleguide tree\",\n description:\n \"A navigation hierarchy for a styleguide with top-level navigation, categories, pages and tabs\",\n inputSchema: {\n styleguideId: z.number().int().positive(),\n },\n },\n async ({ styleguideId }, { authInfo }) => {\n try {\n const credentials = await getCredentials(authInfo);\n const tree = await getStyleguideTree(credentials, styleguideId);\n const formattedTree = formatTreeAsJson(tree);\n\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(formattedTree, null, 2),\n },\n ],\n };\n } catch {\n return {\n isError: true,\n content: [\n {\n type: \"text\",\n text: \"Could not get the navigation tree for this styleguide.\",\n },\n ],\n };\n }\n },\n );\n}\n"],"names":[],"mappings":"AAAA;;GAEG;;;AAGH,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAEL,8BAA8B,EAC9B,gBAAgB,GACjB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;QACE,KAAK,EAAE,kBAAkB;QACzB,WAAW,EAAE,6CAA6C;QAC1D,WAAW,EAAE,EAAE;KAChB,EACD,KAAK,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACxB,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;QAEvD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,gIAAgI;qBACvI;iBACF;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,8BAA8B,CAAC,WAAW,CAAC;oBACjD,QAAQ,EAAE,eAAe;iBAC1B;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,MAAiB;IAC7D,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,+FAA+F;QACjG,WAAW,EAAE;YACX,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;SAC1C;KACF,EACD,KAAK,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACvC,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YAChE,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAE7C,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;qBAC7C;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,wDAAwD;qBAC/D;iBACF;aACF,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","debug_id":"8e279caa-2a6c-5171-8561-ff4a3a6351e4"}
package/package.json CHANGED
@@ -1,19 +1,25 @@
1
1
  {
2
2
  "name": "@zeroheight/mcp-server",
3
- "version": "1.2.0",
3
+ "version": "2.0.0",
4
4
  "description": "MCP server for zeroheight",
5
5
  "type": "module",
6
6
  "bin": {
7
- "mcp-server": "dist/index.js"
7
+ "mcp-server": "dist/stdio.js"
8
8
  },
9
9
  "scripts": {
10
- "build": "tsc && chmod 755 dist/index.js && npm run sentry:sourcemaps",
11
- "dev": "tsc && chmod 755 dist/index.js",
12
- "start": "node dist/index.js",
10
+ "build:local": "tsc -p tsconfig.stdio.json && chmod 755 dist/stdio.js && npm run sentry:sourcemaps:local",
11
+ "dev:local": "tsc -p tsconfig.stdio.json && chmod 755 dist/stdio.js",
12
+ "start:local": "node --env-file=local.env dist/stdio.js",
13
+ "build:remote": "tsc && chmod 755 dist/http.js",
14
+ "dev:remote:build": "tsc && chmod 755 dist/http.js",
15
+ "dev:remote:start": "node --env-file=remote.env dist/http.js",
16
+ "build": "npm run build:local",
17
+ "start:remote": "node --env-file=remote.env dist/http.js",
13
18
  "cleanup": "rm -rf dist",
14
19
  "lint": "prettier --write .",
15
20
  "test": "rstest",
16
- "sentry:sourcemaps": "sentry-cli sourcemaps inject --org zeroheight --project mcp-server ./dist && sentry-cli sourcemaps upload --org zeroheight --project mcp-server ./dist"
21
+ "sentry:sourcemaps:local": "./upload-sourcemaps.sh local",
22
+ "sentry:sourcemaps:remote": "./upload-sourcemaps.sh remote"
17
23
  },
18
24
  "engines": {
19
25
  "node": ">= 22"
@@ -30,13 +36,17 @@
30
36
  },
31
37
  "homepage": "https://zeroheight.com",
32
38
  "dependencies": {
39
+ "@codegenie/serverless-express": "^4.17.0",
33
40
  "@modelcontextprotocol/sdk": "^1.17.1",
41
+ "@sentry/aws-serverless": "^10.17.0",
34
42
  "@sentry/cli": "^2.52.0",
35
43
  "@sentry/node": "^10.5.0",
44
+ "express": "^5.1.0",
36
45
  "zod": "^3.25.76"
37
46
  },
38
47
  "devDependencies": {
39
48
  "@rstest/core": "^0.1.2",
49
+ "@types/express": "^5.0.3",
40
50
  "@types/node": "^24.2.0",
41
51
  "prettier": "^3.6.2",
42
52
  "typescript": "^5.9.2"
@@ -1,16 +0,0 @@
1
-
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e553bd78-9f77-52cf-bf2e-5515e27caa19")}catch(e){}}();
3
- import { expect, describe, it } from "@rstest/core";
4
- import { getZeroheightURL } from "./api.js";
5
- describe("getZeroheightURL", () => {
6
- it("uses local development domain when NODE_ENV is dev", () => {
7
- process.env.NODE_ENV = "dev";
8
- expect(getZeroheightURL().toString()).toBe("https://zeroheight.dev/");
9
- });
10
- it("uses local development domain when NODE_ENV is dev", () => {
11
- process.env.NODE_ENV = "production";
12
- expect(getZeroheightURL().toString()).toBe("https://zeroheight.com/");
13
- });
14
- });
15
- //# sourceMappingURL=api.test.js.map
16
- //# debugId=e553bd78-9f77-52cf-bf2e-5515e27caa19
@@ -1 +0,0 @@
1
- {"version":3,"file":"api.test.js","sources":["api/api.test.ts"],"sourceRoot":"/","sourcesContent":["import { expect, describe, it } from \"@rstest/core\";\n\nimport { getZeroheightURL } from \"./api.js\";\n\ndescribe(\"getZeroheightURL\", () => {\n it(\"uses local development domain when NODE_ENV is dev\", () => {\n process.env.NODE_ENV = \"dev\";\n expect(getZeroheightURL().toString()).toBe(\"https://zeroheight.dev/\");\n });\n\n it(\"uses local development domain when NODE_ENV is dev\", () => {\n process.env.NODE_ENV = \"production\";\n expect(getZeroheightURL().toString()).toBe(\"https://zeroheight.com/\");\n });\n});\n"],"names":[],"mappings":";;AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC7B,MAAM,CAAC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,YAAY,CAAC;QACpC,MAAM,CAAC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","debug_id":"e553bd78-9f77-52cf-bf2e-5515e27caa19"}
@@ -1,453 +0,0 @@
1
-
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a1566a24-9938-599b-a8a8-1237e4dbc1d7")}catch(e){}}();
3
- import { expect, describe, it } from "@rstest/core";
4
- import { formatStyleguideListAsMarkdown, formatTreeAsJson, } from "./styleguide.js";
5
- describe("formatStyleguideListAsMarkdown", () => {
6
- describe("when list is empty", () => {
7
- it("returns an empty string", () => {
8
- expect(formatStyleguideListAsMarkdown([])).toBe("");
9
- });
10
- });
11
- describe("when there's one styleguide", () => {
12
- it("formats styleguide list as markdown list on one line", () => {
13
- expect(formatStyleguideListAsMarkdown([
14
- { id: 1, name: "Styleguide 1", team_id: 1, share_id: "abc123" },
15
- ])).toBe("- Styleguide 1 (ID: 1)");
16
- });
17
- });
18
- describe("when there's multiple styleguides", () => {
19
- it("formats styleguide list as markdown list", () => {
20
- expect(formatStyleguideListAsMarkdown([
21
- { id: 1, name: "Styleguide 1", team_id: 1, share_id: "abc123" },
22
- { id: 2, name: "Styleguide 2", team_id: 1, share_id: "xyz987" },
23
- ])).toBe("- Styleguide 1 (ID: 1)\n- Styleguide 2 (ID: 2)");
24
- });
25
- });
26
- });
27
- describe("formatTreeAsJson", () => {
28
- describe("when tree is empty", () => {
29
- it("returns an empty object", () => {
30
- expect(formatTreeAsJson([])).toEqual({});
31
- });
32
- });
33
- describe("when tree has a single page node", () => {
34
- it("creates nested structure with page info", () => {
35
- const tree = [
36
- {
37
- id: 1,
38
- type: "category",
39
- name: "Documentation",
40
- hidden: false,
41
- children: [
42
- {
43
- id: 2,
44
- type: "page",
45
- name: "Getting Started",
46
- url: "/docs/getting-started",
47
- hidden: false,
48
- children: [],
49
- category_overview_page: false,
50
- },
51
- ],
52
- },
53
- ];
54
- const result = formatTreeAsJson(tree);
55
- expect(result).toEqual({
56
- Documentation: {
57
- "Getting Started": {
58
- id: 2,
59
- url: "/docs/getting-started",
60
- },
61
- },
62
- });
63
- });
64
- });
65
- describe("when tree has multiple categories", () => {
66
- it("creates nested structure for each category", () => {
67
- const tree = [
68
- {
69
- id: 1,
70
- type: "category",
71
- name: "API",
72
- hidden: false,
73
- children: [
74
- {
75
- id: 2,
76
- type: "page",
77
- name: "REST API",
78
- url: "/api/rest",
79
- hidden: false,
80
- children: [],
81
- category_overview_page: false,
82
- },
83
- ],
84
- },
85
- {
86
- id: 3,
87
- type: "category",
88
- name: "Guides",
89
- hidden: false,
90
- children: [
91
- {
92
- id: 4,
93
- type: "page",
94
- name: "Tutorial",
95
- url: "/guides/tutorial",
96
- hidden: false,
97
- children: [],
98
- category_overview_page: false,
99
- },
100
- ],
101
- },
102
- ];
103
- const result = formatTreeAsJson(tree);
104
- expect(result).toEqual({
105
- API: {
106
- "REST API": {
107
- id: 2,
108
- url: "/api/rest",
109
- },
110
- },
111
- Guides: {
112
- Tutorial: {
113
- id: 4,
114
- url: "/guides/tutorial",
115
- },
116
- },
117
- });
118
- });
119
- });
120
- describe("when tree has nested categories", () => {
121
- it("creates deeply nested structure", () => {
122
- const tree = [
123
- {
124
- id: 1,
125
- type: "category",
126
- name: "Documentation",
127
- hidden: false,
128
- children: [
129
- {
130
- id: 2,
131
- type: "category",
132
- name: "API",
133
- hidden: false,
134
- children: [
135
- {
136
- id: 3,
137
- type: "page",
138
- name: "Reference",
139
- url: "/docs/api/reference",
140
- hidden: false,
141
- children: [],
142
- category_overview_page: false,
143
- },
144
- ],
145
- },
146
- ],
147
- },
148
- ];
149
- const result = formatTreeAsJson(tree);
150
- expect(result).toEqual({
151
- Documentation: {
152
- API: {
153
- Reference: {
154
- id: 3,
155
- url: "/docs/api/reference",
156
- },
157
- },
158
- },
159
- });
160
- });
161
- });
162
- describe("when tree has navigation nodes", () => {
163
- it("processes navigation nodes and their children", () => {
164
- const tree = [
165
- {
166
- id: 1,
167
- type: "navigation",
168
- name: "Main Nav",
169
- hidden: false,
170
- children: [
171
- {
172
- id: 2,
173
- type: "page",
174
- name: "Home",
175
- url: "/home",
176
- hidden: false,
177
- children: [],
178
- category_overview_page: false,
179
- },
180
- {
181
- id: 3,
182
- type: "category",
183
- name: "Products",
184
- hidden: false,
185
- children: [
186
- {
187
- id: 4,
188
- type: "page",
189
- name: "Product A",
190
- url: "/products/a",
191
- hidden: false,
192
- children: [],
193
- category_overview_page: false,
194
- },
195
- ],
196
- },
197
- ],
198
- },
199
- ];
200
- const result = formatTreeAsJson(tree);
201
- expect(result).toEqual({
202
- "Main Nav": {
203
- Home: {
204
- id: 2,
205
- url: "/home",
206
- },
207
- Products: {
208
- "Product A": {
209
- id: 4,
210
- url: "/products/a",
211
- },
212
- },
213
- },
214
- });
215
- });
216
- });
217
- describe("when nodes have duplicate names", () => {
218
- it("appends numbers to make names unique", () => {
219
- const tree = [
220
- {
221
- id: 1,
222
- type: "category",
223
- name: "Docs",
224
- hidden: false,
225
- children: [
226
- {
227
- id: 2,
228
- type: "page",
229
- name: "Overview",
230
- url: "/docs/overview1",
231
- hidden: false,
232
- children: [],
233
- category_overview_page: false,
234
- },
235
- {
236
- id: 3,
237
- type: "page",
238
- name: "Overview",
239
- url: "/docs/overview2",
240
- hidden: false,
241
- children: [],
242
- category_overview_page: false,
243
- },
244
- {
245
- id: 4,
246
- type: "page",
247
- name: "Overview",
248
- url: "/docs/overview3",
249
- hidden: false,
250
- children: [],
251
- category_overview_page: false,
252
- },
253
- ],
254
- },
255
- ];
256
- const result = formatTreeAsJson(tree);
257
- expect(result).toEqual({
258
- Docs: {
259
- Overview: {
260
- id: 2,
261
- url: "/docs/overview1",
262
- },
263
- "Overview 1": {
264
- id: 3,
265
- url: "/docs/overview2",
266
- },
267
- "Overview 2": {
268
- id: 4,
269
- url: "/docs/overview3",
270
- },
271
- },
272
- });
273
- });
274
- });
275
- describe("when nodes have no name", () => {
276
- it("uses node type as fallback name", () => {
277
- const tree = [
278
- {
279
- id: 1,
280
- type: "category",
281
- name: "",
282
- hidden: false,
283
- children: [
284
- {
285
- id: 2,
286
- type: "page",
287
- name: "",
288
- url: "/page1",
289
- hidden: false,
290
- children: [],
291
- category_overview_page: false,
292
- },
293
- ],
294
- },
295
- ];
296
- const result = formatTreeAsJson(tree);
297
- expect(result).toEqual({
298
- category: {
299
- page: {
300
- id: 2,
301
- url: "/page1",
302
- },
303
- },
304
- });
305
- });
306
- });
307
- describe("when tree has tab nodes", () => {
308
- it("ignores tab nodes", () => {
309
- const tree = [
310
- {
311
- id: 1,
312
- type: "category",
313
- name: "Main",
314
- hidden: false,
315
- children: [
316
- {
317
- id: 3,
318
- type: "page",
319
- name: "Page1",
320
- url: "/page1",
321
- hidden: false,
322
- children: [
323
- {
324
- id: 2,
325
- type: "tab",
326
- name: "Tab1",
327
- url: "/tab1",
328
- hidden: false,
329
- children: [],
330
- },
331
- ],
332
- category_overview_page: false,
333
- },
334
- ],
335
- },
336
- ];
337
- const result = formatTreeAsJson(tree);
338
- expect(result).toEqual({
339
- Main: {
340
- Page1: {
341
- id: 3,
342
- url: "/page1",
343
- },
344
- },
345
- });
346
- });
347
- });
348
- describe("when tree has complex nested structure", () => {
349
- it("handles multiple levels of nesting correctly", () => {
350
- const tree = [
351
- {
352
- id: 1,
353
- type: "navigation",
354
- name: "Root",
355
- hidden: false,
356
- children: [
357
- {
358
- id: 2,
359
- type: "category",
360
- name: "Section A",
361
- hidden: false,
362
- children: [
363
- {
364
- id: 3,
365
- type: "category",
366
- name: "Subsection 1",
367
- hidden: false,
368
- children: [
369
- {
370
- id: 4,
371
- type: "page",
372
- name: "Page A",
373
- url: "/a/1/a",
374
- hidden: false,
375
- children: [],
376
- category_overview_page: false,
377
- },
378
- {
379
- id: 5,
380
- type: "page",
381
- name: "Page B",
382
- url: "/a/1/b",
383
- hidden: false,
384
- children: [],
385
- category_overview_page: false,
386
- },
387
- ],
388
- },
389
- {
390
- id: 6,
391
- type: "page",
392
- name: "Direct Page",
393
- url: "/a/direct",
394
- hidden: false,
395
- children: [],
396
- category_overview_page: false,
397
- },
398
- ],
399
- },
400
- ],
401
- },
402
- ];
403
- const result = formatTreeAsJson(tree);
404
- expect(result).toEqual({
405
- Root: {
406
- "Section A": {
407
- "Subsection 1": {
408
- "Page A": {
409
- id: 4,
410
- url: "/a/1/a",
411
- },
412
- "Page B": {
413
- id: 5,
414
- url: "/a/1/b",
415
- },
416
- },
417
- "Direct Page": {
418
- id: 6,
419
- url: "/a/direct",
420
- },
421
- },
422
- },
423
- });
424
- });
425
- });
426
- describe("when multiple root nodes have duplicate names", () => {
427
- it("handles duplicate names at root level", () => {
428
- const tree = [
429
- {
430
- id: 1,
431
- type: "category",
432
- name: "Section",
433
- hidden: false,
434
- children: [],
435
- },
436
- {
437
- id: 2,
438
- type: "category",
439
- name: "Section",
440
- hidden: false,
441
- children: [],
442
- },
443
- ];
444
- const result = formatTreeAsJson(tree);
445
- expect(result).toEqual({
446
- Section: {},
447
- "Section 1": {},
448
- });
449
- });
450
- });
451
- });
452
- //# sourceMappingURL=styleguide.test.js.map
453
- //# debugId=a1566a24-9938-599b-a8a8-1237e4dbc1d7