@zeroheight/mcp-server 2.1.0 → 2.1.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +12 -4
  3. package/dist/api/api.js +31 -6
  4. package/dist/api/api.js.map +1 -1
  5. package/dist/api/page.js +8 -11
  6. package/dist/api/page.js.map +1 -1
  7. package/dist/api/styleguide.js +6 -6
  8. package/dist/api/styleguide.js.map +1 -1
  9. package/dist/api/token.js +15 -0
  10. package/dist/api/token.js.map +1 -0
  11. package/dist/api/types/token.js +5 -0
  12. package/dist/api/types/token.js.map +1 -0
  13. package/dist/auth/introspection.js +36 -0
  14. package/dist/auth/introspection.js.map +1 -0
  15. package/dist/common/credentials.js +27 -9
  16. package/dist/common/credentials.js.map +1 -1
  17. package/dist/common/formatters/token.js +10 -0
  18. package/dist/common/formatters/token.js.map +1 -0
  19. package/dist/lint/color.js +43 -0
  20. package/dist/lint/color.js.map +1 -0
  21. package/dist/lint/dimension.js +90 -0
  22. package/dist/lint/dimension.js.map +1 -0
  23. package/dist/lint/index.js +122 -0
  24. package/dist/lint/index.js.map +1 -0
  25. package/dist/lint/parser.js +462 -0
  26. package/dist/lint/parser.js.map +1 -0
  27. package/dist/lint/tokens.js +33 -0
  28. package/dist/lint/tokens.js.map +1 -0
  29. package/dist/logging.js +129 -0
  30. package/dist/logging.js.map +1 -0
  31. package/dist/mcp-server.js +9 -4
  32. package/dist/mcp-server.js.map +1 -1
  33. package/dist/tools/lint.js +74 -0
  34. package/dist/tools/lint.js.map +1 -0
  35. package/dist/tools/page.js +56 -25
  36. package/dist/tools/page.js.map +1 -1
  37. package/dist/tools/styleguide.js +22 -11
  38. package/dist/tools/styleguide.js.map +1 -1
  39. package/dist/tools/token.js +73 -0
  40. package/dist/tools/token.js.map +1 -0
  41. package/dist/types/server.js +5 -0
  42. package/dist/types/server.js.map +1 -0
  43. package/package.json +10 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## Release notes
2
2
 
3
+ ## [2.1.1](https://www.npmjs.com/package/@zeroheight/mcp-server/v/2.1.1) - 16th February 2026
4
+
5
+ - Bug fixes
6
+
3
7
  ## [2.1.0](https://www.npmjs.com/package/@zeroheight/mcp-server/v/2.1.0) - 9th December 2025
4
8
 
5
9
  - Beta feature
package/README.md CHANGED
@@ -43,16 +43,24 @@ To help improve the experience this MCP server uses Sentry for error tracking. I
43
43
  The server provides these MCP tools:
44
44
 
45
45
  **list-styleguides**
46
- List all accessible styleguides as resource links or markdown
46
+ Discover available design systems that provide documented guidance for components, patterns, and styles. If multiple systems are available, confirm with the user which should be used.
47
+
48
+ *Helpful to reference before generating UI so decisions can reflect established design approaches.*
47
49
 
48
50
  **get-styleguide-tree**
49
- Get a navigation hierarchy for a styleguide with top-level navigation, categories, pages and tabs
51
+ View the navigation hierarchy of a design system including categories, pages, and tabs — to better understand how guidance is organized.
52
+
53
+ *Helpful when determining where to look for component or pattern documentation before generating UI.*
50
54
 
51
55
  **list-pages**
52
- List all accessible pages in a styleguide with optional search
56
+ Explore the pages within a design system to find guidance relevant to the task.
57
+
58
+ *Useful when generating UI that should align with documented component usage, patterns, or interaction recommendations rather than inferred solutions.*
53
59
 
54
60
  **get-page**
55
- Get a styleguide page in the requested format (markdown or JSON)
61
+ Fetch guidance from a specific design system page, including usage notes, recommendations, and supporting context.
62
+
63
+ *Particularly helpful ahead of UI generation to increase the likelihood that outputs reflect the intent of the design system.*
56
64
 
57
65
  ### Setup Examples
58
66
 
package/dist/api/api.js CHANGED
@@ -1,10 +1,15 @@
1
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]="84ff6650-a8f8-5c0b-9cd9-6a6cd07211cf")}catch(e){}}();
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]="4a8750ba-4616-5bb8-aadc-1a6c400d4bd6")}catch(e){}}();
3
3
  import * as Sentry from "@sentry/node";
4
4
  import { IncorrectScopeError, MaxRetriesError, UnauthorizedError, UnknownError, } from "./errors.js";
5
5
  import packageJson from "../../package.json" with { type: "json" };
6
6
  const API_PATH = "/open_api/v2";
7
7
  const USER_AGENT = `zeroheight-mcp-server/${packageJson.version}`;
8
+ export var ApiType;
9
+ (function (ApiType) {
10
+ ApiType["OpenApi"] = "open_api";
11
+ ApiType["Internal"] = "internal";
12
+ })(ApiType || (ApiType = {}));
8
13
  export var ResponseStatus;
9
14
  (function (ResponseStatus) {
10
15
  ResponseStatus["Success"] = "success";
@@ -15,6 +20,10 @@ export var ResponseStatus;
15
20
  * Get the correct URL for production of development depending on the environment variable
16
21
  */
17
22
  export function getZeroheightURL() {
23
+ const zeroheightURL = process.env["ZEROHEIGHT_URL"];
24
+ if (zeroheightURL) {
25
+ return new URL(zeroheightURL);
26
+ }
18
27
  if (process.env["NODE_ENV"] === "dev") {
19
28
  return new URL("https://zeroheight.dev");
20
29
  }
@@ -25,9 +34,9 @@ export function getZeroheightURL() {
25
34
  async function sleep(ms) {
26
35
  return new Promise((resolve) => setTimeout(resolve, ms));
27
36
  }
28
- export async function request(path, credentials, init, search) {
37
+ export async function request(path, credentials, init, search, apiType = ApiType.OpenApi, metadata = {}) {
29
38
  const url = getZeroheightURL();
30
- url.pathname = API_PATH + path;
39
+ url.pathname = (apiType === ApiType.OpenApi ? API_PATH : "/api") + path;
31
40
  if (search) {
32
41
  url.search = "?" + search.toString();
33
42
  }
@@ -43,9 +52,19 @@ export async function request(path, credentials, init, search) {
43
52
  "Content-Type": "application/json",
44
53
  Accept: "application/json",
45
54
  };
55
+ if (metadata.clientUserAgent) {
56
+ headers["X-MCP-Client-User-Agent"] = metadata.clientUserAgent;
57
+ }
46
58
  if (credentials.type === "jwt") {
47
59
  headers["Authorization"] = `Bearer ${credentials.jwt}`;
48
60
  headers["X-API-CLIENT-NAME"] = "remote-mcp-server";
61
+ if (credentials.mcpAuthId) {
62
+ headers["X-MCP-Auth-ID"] = String(credentials.mcpAuthId);
63
+ }
64
+ }
65
+ else if (credentials.type === "oauth_jwt") {
66
+ headers["Authorization"] = `Bearer ${credentials.jwt}`;
67
+ headers["X-API-CLIENT-NAME"] = `remote-mcp-server:${credentials.clientId}`;
49
68
  }
50
69
  else {
51
70
  headers["X-API-CLIENT"] = credentials.client;
@@ -64,8 +83,14 @@ export async function request(path, credentials, init, search) {
64
83
  }
65
84
  else if (response.status === 429) {
66
85
  retries++;
67
- const responseData = await response.json();
68
- const waitTime = responseData.data.reset_time * 1000 - Date.now();
86
+ let waitTime;
87
+ if (apiType === ApiType.OpenApi) {
88
+ const responseData = await response.json();
89
+ waitTime = responseData.data.reset_time * 1000 - Date.now();
90
+ }
91
+ else {
92
+ waitTime = 2 ** retries * 1000;
93
+ }
69
94
  await sleep(waitTime);
70
95
  continue;
71
96
  }
@@ -118,4 +143,4 @@ export async function internalRequest(path, method, body) {
118
143
  return responseJson;
119
144
  }
120
145
  //# sourceMappingURL=api.js.map
121
- //# debugId=84ff6650-a8f8-5c0b-9cd9-6a6cd07211cf
146
+ //# debugId=4a8750ba-4616-5bb8-aadc-1a6c400d4bd6
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sources":["api/api.ts"],"sourceRoot":"/","sourcesContent":["import * as Sentry from \"@sentry/node\";\nimport {\n IncorrectScopeError,\n MaxRetriesError,\n UnauthorizedError,\n UnknownError,\n} from \"./errors.js\";\n\nimport packageJson from \"../../package.json\" with { type: \"json\" };\n\nimport { Credentials } from \"../common/credentials.js\";\n\nconst API_PATH = \"/open_api/v2\";\nconst USER_AGENT = `zeroheight-mcp-server/${packageJson.version}`;\n\nexport enum ResponseStatus {\n Success = \"success\",\n Error = \"error\",\n Fail = \"fail\",\n}\n\n/**\n * Open API V2 Response format\n */\n\ninterface BaseResponse<T> {\n status: ResponseStatus;\n message: string;\n data: T;\n}\n\ninterface SuccessResponse<T> extends BaseResponse<T> {\n status: ResponseStatus.Success;\n}\n\ninterface FailResponse<T> extends BaseResponse<T> {\n status: ResponseStatus.Fail;\n}\n\ninterface ErrorResponse<T> extends BaseResponse<T> {\n status: ResponseStatus.Error;\n}\n\nexport type APIResponse<S = {}, F = {}, E = {}> =\n | SuccessResponse<S>\n | FailResponse<F>\n | ErrorResponse<E>;\n\n/**\n * Get the correct URL for production of development depending on the environment variable\n */\nexport function getZeroheightURL() {\n if (process.env[\"NODE_ENV\"] === \"dev\") {\n return new URL(\"https://zeroheight.dev\");\n } else {\n return new URL(\"https://zeroheight.com\");\n }\n}\n\nasync function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function request<R>(\n path: string,\n credentials: Credentials,\n init: RequestInit,\n search?: URLSearchParams,\n): Promise<R> {\n const url = getZeroheightURL();\n url.pathname = API_PATH + path;\n if (search) {\n url.search = \"?\" + search.toString();\n }\n\n if (process.env[\"NODE_ENV\"] === \"dev\") {\n process.env[\"NODE_TLS_REJECT_UNAUTHORIZED\"] = \"0\";\n }\n\n const maxRetries = 3;\n let retries = 0;\n\n const headers: Record<string, string> = {\n \"X-API-CLIENT-NAME\": \"mcp-server\",\n \"X-API-CLIENT-VERSION\": packageJson.version,\n \"User-Agent\": USER_AGENT,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n };\n\n if (credentials.type === \"jwt\") {\n headers[\"Authorization\"] = `Bearer ${credentials.jwt}`;\n headers[\"X-API-CLIENT-NAME\"] = \"remote-mcp-server\";\n } else {\n headers[\"X-API-CLIENT\"] = credentials.client;\n headers[\"X-API-KEY\"] = credentials.token;\n }\n\n while (retries < maxRetries) {\n const response = await fetch(url, {\n ...init,\n headers,\n });\n\n if (response.status === 401) {\n console.error(\"Unauthorized response from API\", {\n response: { status: response.status, body: await response.text() },\n });\n throw new UnauthorizedError();\n } else if (response.status === 429) {\n retries++;\n const responseData = await response.json();\n const waitTime = responseData.data.reset_time * 1000 - Date.now();\n await sleep(waitTime);\n continue;\n } else if (response.status < 200 || response.status >= 300) {\n console.error(\"API request failed\", {\n response: { status: response.status, body: await response.text() },\n });\n\n if (response.status === 403) {\n throw new IncorrectScopeError();\n } else {\n Sentry.captureMessage(\n `Unknown error occurred making request to: ${url}`,\n );\n throw new UnknownError();\n }\n }\n\n const responseJson = await response.json();\n return responseJson;\n }\n\n throw new MaxRetriesError();\n}\n\nexport async function internalRequest<R>(\n path: string,\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\",\n body: any,\n): Promise<R> {\n const url = getZeroheightURL();\n url.pathname = \"/api\" + path;\n\n if (process.env[\"NODE_ENV\"] === \"dev\") {\n process.env[\"NODE_TLS_REJECT_UNAUTHORIZED\"] = \"0\";\n }\n\n const response = await fetch(url, {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n \"User-Agent\": USER_AGENT,\n \"X-API-KEY\": process.env[\"INTERNAL_API_KEY\"] || \"\",\n },\n body: JSON.stringify(body),\n });\n\n if (response.status < 200 || response.status >= 300) {\n console.error(\"Internal API request failed\", {\n response: { status: response.status, body: await response.text() },\n });\n\n if (response.status === 401) {\n throw new UnauthorizedError();\n } else {\n Sentry.captureMessage(\n `Unknown error occurred making internal request to: ${url}`,\n );\n throw new UnknownError();\n }\n }\n\n const responseJson = await response.json();\n return responseJson;\n}\n"],"names":[],"mappings":"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","debug_id":"84ff6650-a8f8-5c0b-9cd9-6a6cd07211cf"}
1
+ {"version":3,"file":"api.js","sources":["api/api.ts"],"sourceRoot":"/","sourcesContent":["import * as Sentry from \"@sentry/node\";\nimport {\n IncorrectScopeError,\n MaxRetriesError,\n UnauthorizedError,\n UnknownError,\n} from \"./errors.js\";\n\nimport packageJson from \"../../package.json\" with { type: \"json\" };\n\nimport { Credentials } from \"../common/credentials.js\";\n\nconst API_PATH = \"/open_api/v2\";\nconst USER_AGENT = `zeroheight-mcp-server/${packageJson.version}`;\n\nexport enum ApiType {\n OpenApi = \"open_api\", // /open_api/v2\n Internal = \"internal\", // /api\n}\n\nexport enum ResponseStatus {\n Success = \"success\",\n Error = \"error\",\n Fail = \"fail\",\n}\n\n/**\n * Open API V2 Response format\n */\n\ninterface BaseResponse<T> {\n status: ResponseStatus;\n message: string;\n data: T;\n}\n\ninterface SuccessResponse<T> extends BaseResponse<T> {\n status: ResponseStatus.Success;\n}\n\ninterface FailResponse<T> extends BaseResponse<T> {\n status: ResponseStatus.Fail;\n}\n\ninterface ErrorResponse<T> extends BaseResponse<T> {\n status: ResponseStatus.Error;\n}\n\nexport type APIResponse<S = {}, F = {}, E = {}> =\n | SuccessResponse<S>\n | FailResponse<F>\n | ErrorResponse<E>;\n\n/**\n * Get the correct URL for production of development depending on the environment variable\n */\nexport function getZeroheightURL() {\n const zeroheightURL = process.env[\"ZEROHEIGHT_URL\"];\n if (zeroheightURL) {\n return new URL(zeroheightURL);\n }\n\n if (process.env[\"NODE_ENV\"] === \"dev\") {\n return new URL(\"https://zeroheight.dev\");\n } else {\n return new URL(\"https://zeroheight.com\");\n }\n}\n\nasync function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function request<R>(\n path: string,\n credentials: Credentials,\n init: RequestInit,\n search?: URLSearchParams,\n apiType: ApiType = ApiType.OpenApi,\n metadata: { clientUserAgent?: string } = {},\n): Promise<R> {\n const url = getZeroheightURL();\n url.pathname = (apiType === ApiType.OpenApi ? API_PATH : \"/api\") + path;\n if (search) {\n url.search = \"?\" + search.toString();\n }\n\n if (process.env[\"NODE_ENV\"] === \"dev\") {\n process.env[\"NODE_TLS_REJECT_UNAUTHORIZED\"] = \"0\";\n }\n\n const maxRetries = 3;\n let retries = 0;\n\n const headers: Record<string, string> = {\n \"X-API-CLIENT-NAME\": \"mcp-server\",\n \"X-API-CLIENT-VERSION\": packageJson.version,\n \"User-Agent\": USER_AGENT,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n };\n\n if (metadata.clientUserAgent) {\n headers[\"X-MCP-Client-User-Agent\"] = metadata.clientUserAgent;\n }\n\n if (credentials.type === \"jwt\") {\n headers[\"Authorization\"] = `Bearer ${credentials.jwt}`;\n headers[\"X-API-CLIENT-NAME\"] = \"remote-mcp-server\";\n if (credentials.mcpAuthId) {\n headers[\"X-MCP-Auth-ID\"] = String(credentials.mcpAuthId);\n }\n } else if (credentials.type === \"oauth_jwt\") {\n headers[\"Authorization\"] = `Bearer ${credentials.jwt}`;\n headers[\"X-API-CLIENT-NAME\"] = `remote-mcp-server:${credentials.clientId}`;\n } else {\n headers[\"X-API-CLIENT\"] = credentials.client;\n headers[\"X-API-KEY\"] = credentials.token;\n }\n\n while (retries < maxRetries) {\n const response = await fetch(url, {\n ...init,\n headers,\n });\n\n if (response.status === 401) {\n console.error(\"Unauthorized response from API\", {\n response: { status: response.status, body: await response.text() },\n });\n throw new UnauthorizedError();\n } else if (response.status === 429) {\n retries++;\n let waitTime: number;\n if (apiType === ApiType.OpenApi) {\n const responseData = await response.json();\n waitTime = responseData.data.reset_time * 1000 - Date.now();\n } else {\n waitTime = 2 ** retries * 1000;\n }\n await sleep(waitTime);\n continue;\n } else if (response.status < 200 || response.status >= 300) {\n console.error(\"API request failed\", {\n response: { status: response.status, body: await response.text() },\n });\n\n if (response.status === 403) {\n throw new IncorrectScopeError();\n } else {\n Sentry.captureMessage(\n `Unknown error occurred making request to: ${url}`,\n );\n throw new UnknownError();\n }\n }\n\n const responseJson = await response.json();\n return responseJson;\n }\n\n throw new MaxRetriesError();\n}\n\nexport async function internalRequest<R>(\n path: string,\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\",\n body: any,\n): Promise<R> {\n const url = getZeroheightURL();\n url.pathname = \"/api\" + path;\n\n if (process.env[\"NODE_ENV\"] === \"dev\") {\n process.env[\"NODE_TLS_REJECT_UNAUTHORIZED\"] = \"0\";\n }\n\n const response = await fetch(url, {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n \"User-Agent\": USER_AGENT,\n \"X-API-KEY\": process.env[\"INTERNAL_API_KEY\"] || \"\",\n },\n body: JSON.stringify(body),\n });\n\n if (response.status < 200 || response.status >= 300) {\n console.error(\"Internal API request failed\", {\n response: { status: response.status, body: await response.text() },\n });\n\n if (response.status === 401) {\n throw new UnauthorizedError();\n } else {\n Sentry.captureMessage(\n `Unknown error occurred making internal request to: ${url}`,\n );\n throw new UnknownError();\n }\n }\n\n const responseJson = await response.json();\n return responseJson;\n}\n"],"names":[],"mappings":"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","debug_id":"4a8750ba-4616-5bb8-aadc-1a6c400d4bd6"}
package/dist/api/page.js CHANGED
@@ -1,9 +1,9 @@
1
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]="c0906784-1b58-5e49-b986-94f3d2cb0468")}catch(e){}}();
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]="4cc32259-80f6-5153-bf7c-7e2ca8c7578d")}catch(e){}}();
3
3
  import { request } from "./api.js";
4
4
  import { UnknownError } from "./errors.js";
5
5
  import { captureException } from "../common/errors.js";
6
- export async function listPages(credentials, styleguideId, optionalParams = {}) {
6
+ export async function listPages(credentials, styleguideId, optionalParams = {}, clientUserAgent) {
7
7
  try {
8
8
  const searchParams = new URLSearchParams({
9
9
  show_hidden: "false",
@@ -16,7 +16,7 @@ export async function listPages(credentials, styleguideId, optionalParams = {})
16
16
  }
17
17
  const response = await request(`/styleguides/${styleguideId}/pages`, credentials, {
18
18
  method: "GET",
19
- }, searchParams);
19
+ }, searchParams, undefined, { clientUserAgent });
20
20
  if ("pages" in response.data) {
21
21
  return response.data.pages;
22
22
  }
@@ -27,7 +27,7 @@ export async function listPages(credentials, styleguideId, optionalParams = {})
27
27
  return [];
28
28
  }
29
29
  }
30
- export async function getPage(credentials, pageId, optionalParams = {}) {
30
+ export async function getPage(credentials, pageId, optionalParams = {}, clientUserAgent) {
31
31
  try {
32
32
  const searchParams = new URLSearchParams();
33
33
  if (optionalParams.releaseId) {
@@ -35,7 +35,7 @@ export async function getPage(credentials, pageId, optionalParams = {}) {
35
35
  }
36
36
  const response = await request(`/pages/${pageId}`, credentials, {
37
37
  method: "GET",
38
- }, searchParams);
38
+ }, searchParams, undefined, { clientUserAgent });
39
39
  if ("page" in response.data) {
40
40
  return response.data.page;
41
41
  }
@@ -46,7 +46,7 @@ export async function getPage(credentials, pageId, optionalParams = {}) {
46
46
  return null;
47
47
  }
48
48
  }
49
- export async function searchPages(credentials, styleguideId, query, releaseId) {
49
+ export async function searchPages(credentials, styleguideId, query, releaseId, clientUserAgent) {
50
50
  try {
51
51
  const filters = {
52
52
  type: "page",
@@ -57,14 +57,11 @@ export async function searchPages(credentials, styleguideId, query, releaseId) {
57
57
  }
58
58
  const response = await request(`/search`, credentials, {
59
59
  method: "POST",
60
- headers: {
61
- "Content-Type": "application/json",
62
- },
63
60
  body: JSON.stringify({
64
61
  query,
65
62
  filters,
66
63
  }),
67
- });
64
+ }, undefined, undefined, { clientUserAgent });
68
65
  if ("results" in response.data) {
69
66
  return response.data.results;
70
67
  }
@@ -76,4 +73,4 @@ export async function searchPages(credentials, styleguideId, query, releaseId) {
76
73
  }
77
74
  }
78
75
  //# sourceMappingURL=page.js.map
79
- //# debugId=c0906784-1b58-5e49-b986-94f3d2cb0468
76
+ //# debugId=4cc32259-80f6-5153-bf7c-7e2ca8c7578d
@@ -1 +1 @@
1
- {"version":3,"file":"page.js","sources":["api/page.ts"],"sourceRoot":"/","sourcesContent":["import { Credentials } from \"../common/credentials.js\";\nimport { APIResponse, request } from \"./api.js\";\nimport { UnknownError } from \"./errors.js\";\nimport { Page, PageListItem, PageSearchResultItem } from \"./types/page.js\";\nimport { captureException } from \"../common/errors.js\";\n\ninterface PageListSuccessResponse {\n pages: PageListItem[];\n}\n\ninterface PageListOptionalParams {\n searchTerm: string;\n releaseId: number;\n}\n\nexport async function listPages(\n credentials: Credentials,\n styleguideId: number,\n optionalParams: Partial<PageListOptionalParams> = {}\n) {\n try {\n const searchParams = new URLSearchParams({\n show_hidden: \"false\",\n });\n\n if (optionalParams.releaseId) {\n searchParams.set(\"release_id\", optionalParams.releaseId.toString());\n }\n\n if (optionalParams.searchTerm) {\n searchParams.set(\"search\", optionalParams.searchTerm);\n }\n\n const response = await request<\n APIResponse<PageListSuccessResponse, {}, {}>\n >(\n `/styleguides/${styleguideId}/pages`,\n credentials,\n {\n method: \"GET\",\n },\n searchParams\n );\n\n if (\"pages\" in response.data) {\n return response.data.pages;\n }\n\n throw new UnknownError();\n } catch (e) {\n captureException(e);\n return [];\n }\n}\n\ninterface PageSuccessResponse {\n page: Page;\n}\n\ninterface PageOptionalParams {\n releaseId: number;\n}\n\nexport async function getPage(\n credentials: Credentials,\n pageId: number | string,\n optionalParams: Partial<PageOptionalParams> = {}\n) {\n try {\n const searchParams = new URLSearchParams();\n\n if (optionalParams.releaseId) {\n searchParams.set(\"release_id\", optionalParams.releaseId.toString());\n }\n\n const response = await request<APIResponse<PageSuccessResponse, {}, {}>>(\n `/pages/${pageId}`,\n credentials,\n {\n method: \"GET\",\n },\n searchParams\n );\n\n if (\"page\" in response.data) {\n return response.data.page;\n }\n\n throw new UnknownError();\n } catch (e) {\n captureException(e);\n return null;\n }\n}\n\ninterface SearchSuccessResponse {\n results: PageSearchResultItem[];\n}\n\nexport async function searchPages(\n credentials: Credentials,\n styleguideId: number,\n query: string,\n releaseId?: number\n) {\n try {\n const filters: Record<string, number | string> = {\n type: \"page\",\n styleguide_id: styleguideId,\n };\n\n if (typeof releaseId === \"number\") {\n filters[\"styleguide_version_id\"] = releaseId;\n }\n\n const response = await request<APIResponse<SearchSuccessResponse, {}, {}>>(\n `/search`,\n credentials,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n query,\n filters,\n }),\n }\n );\n\n if (\"results\" in response.data) {\n return response.data.results;\n }\n\n throw new UnknownError();\n } catch (e) {\n captureException(e);\n return [];\n }\n}\n"],"names":[],"mappings":"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","debug_id":"c0906784-1b58-5e49-b986-94f3d2cb0468"}
1
+ {"version":3,"file":"page.js","sources":["api/page.ts"],"sourceRoot":"/","sourcesContent":["import { Credentials } from \"../common/credentials.js\";\nimport { APIResponse, request } from \"./api.js\";\nimport { UnknownError } from \"./errors.js\";\nimport { Page, PageListItem, PageSearchResultItem } from \"./types/page.js\";\nimport { captureException } from \"../common/errors.js\";\n\ninterface PageListSuccessResponse {\n pages: PageListItem[];\n}\n\ninterface PageListOptionalParams {\n searchTerm: string;\n releaseId: number;\n}\n\nexport async function listPages(\n credentials: Credentials,\n styleguideId: number,\n optionalParams: Partial<PageListOptionalParams> = {},\n clientUserAgent?: string,\n) {\n try {\n const searchParams = new URLSearchParams({\n show_hidden: \"false\",\n });\n\n if (optionalParams.releaseId) {\n searchParams.set(\"release_id\", optionalParams.releaseId.toString());\n }\n\n if (optionalParams.searchTerm) {\n searchParams.set(\"search\", optionalParams.searchTerm);\n }\n\n const response = await request<\n APIResponse<PageListSuccessResponse, {}, {}>\n >(\n `/styleguides/${styleguideId}/pages`,\n credentials,\n {\n method: \"GET\",\n },\n searchParams,\n undefined,\n { clientUserAgent },\n );\n\n if (\"pages\" in response.data) {\n return response.data.pages;\n }\n\n throw new UnknownError();\n } catch (e) {\n captureException(e);\n return [];\n }\n}\n\ninterface PageSuccessResponse {\n page: Page;\n}\n\ninterface PageOptionalParams {\n releaseId: number;\n}\n\nexport async function getPage(\n credentials: Credentials,\n pageId: number | string,\n optionalParams: Partial<PageOptionalParams> = {},\n clientUserAgent?: string,\n) {\n try {\n const searchParams = new URLSearchParams();\n\n if (optionalParams.releaseId) {\n searchParams.set(\"release_id\", optionalParams.releaseId.toString());\n }\n\n const response = await request<APIResponse<PageSuccessResponse, {}, {}>>(\n `/pages/${pageId}`,\n credentials,\n {\n method: \"GET\",\n },\n searchParams,\n undefined,\n { clientUserAgent },\n );\n\n if (\"page\" in response.data) {\n return response.data.page;\n }\n\n throw new UnknownError();\n } catch (e) {\n captureException(e);\n return null;\n }\n}\n\ninterface SearchSuccessResponse {\n results: PageSearchResultItem[];\n}\n\nexport async function searchPages(\n credentials: Credentials,\n styleguideId: number,\n query: string,\n releaseId?: number,\n clientUserAgent?: string,\n) {\n try {\n const filters: Record<string, number | string> = {\n type: \"page\",\n styleguide_id: styleguideId,\n };\n\n if (typeof releaseId === \"number\") {\n filters[\"styleguide_version_id\"] = releaseId;\n }\n\n const response = await request<APIResponse<SearchSuccessResponse, {}, {}>>(\n `/search`,\n credentials,\n {\n method: \"POST\",\n body: JSON.stringify({\n query,\n filters,\n }),\n },\n undefined,\n undefined,\n { clientUserAgent },\n );\n\n if (\"results\" in response.data) {\n return response.data.results;\n }\n\n throw new UnknownError();\n } catch (e) {\n captureException(e);\n return [];\n }\n}\n"],"names":[],"mappings":"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","debug_id":"4cc32259-80f6-5153-bf7c-7e2ca8c7578d"}
@@ -1,13 +1,13 @@
1
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]="e5eec58f-0a29-5ede-91ca-d9450e4f4bc2")}catch(e){}}();
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]="3d4cd722-6043-5c3e-a421-a6f2511a55b0")}catch(e){}}();
3
3
  import { request } from "./api.js";
4
4
  import { UnknownError } from "./errors.js";
5
5
  import { captureException } from "../common/errors.js";
6
- export async function listStyleguides(credentials) {
6
+ export async function listStyleguides(credentials, clientUserAgent) {
7
7
  try {
8
8
  const response = await request("/styleguides", credentials, {
9
9
  method: "GET",
10
- });
10
+ }, undefined, undefined, { clientUserAgent });
11
11
  if ("styleguides" in response.data) {
12
12
  if (credentials.type === "jwt") {
13
13
  return response.data.styleguides.filter((sg) => sg.id === credentials.styleguideId);
@@ -21,14 +21,14 @@ export async function listStyleguides(credentials) {
21
21
  return [];
22
22
  }
23
23
  }
24
- export async function getStyleguideTree(credentials, id) {
24
+ export async function getStyleguideTree(credentials, id, clientUserAgent) {
25
25
  try {
26
26
  const searchParams = new URLSearchParams({
27
27
  show_hidden: "false",
28
28
  });
29
29
  const response = await request(`/styleguides/${id}/tree`, credentials, {
30
30
  method: "GET",
31
- }, searchParams);
31
+ }, searchParams, undefined, { clientUserAgent });
32
32
  if ("tree" in response.data) {
33
33
  return response.data.tree;
34
34
  }
@@ -41,4 +41,4 @@ export async function getStyleguideTree(credentials, id) {
41
41
  }
42
42
  }
43
43
  //# sourceMappingURL=styleguide.js.map
44
- //# debugId=e5eec58f-0a29-5ede-91ca-d9450e4f4bc2
44
+ //# debugId=3d4cd722-6043-5c3e-a421-a6f2511a55b0
@@ -1 +1 @@
1
- {"version":3,"file":"styleguide.js","sources":["api/styleguide.ts"],"sourceRoot":"/","sourcesContent":["import { APIResponse, request } from \"./api.js\";\nimport { UnknownError } from \"./errors.js\";\nimport { Credentials } from \"../common/credentials.js\";\nimport {\n CategoryNode,\n NavigationNode,\n PageNode,\n Styleguide,\n} from \"./types/styleguide.js\";\nimport { captureException } from \"../common/errors.js\";\n\ninterface StyleguideListSuccessResponse {\n styleguides: Styleguide[];\n}\n\nexport async function listStyleguides(credentials: Credentials) {\n try {\n const response = await request<\n APIResponse<StyleguideListSuccessResponse, {}, {}>\n >(\"/styleguides\", credentials, {\n method: \"GET\",\n });\n\n if (\"styleguides\" in response.data) {\n if (credentials.type === \"jwt\") {\n return response.data.styleguides.filter(\n (sg) => sg.id === credentials.styleguideId,\n );\n }\n\n return response.data.styleguides;\n }\n\n throw new UnknownError();\n } catch (e) {\n captureException(e);\n return [];\n }\n}\n\ninterface SyleguideTreeSuccessResponse {\n tree: (PageNode | CategoryNode | NavigationNode)[];\n}\n\nexport async function getStyleguideTree(credentials: Credentials, id: number) {\n try {\n const searchParams = new URLSearchParams({\n show_hidden: \"false\",\n });\n\n const response = await request<\n APIResponse<SyleguideTreeSuccessResponse, {}, {}>\n >(\n `/styleguides/${id}/tree`,\n credentials,\n {\n method: \"GET\",\n },\n searchParams,\n );\n\n if (\"tree\" in response.data) {\n return response.data.tree;\n }\n\n console.error(response);\n\n throw new UnknownError();\n } catch (e) {\n captureException(e);\n return [];\n }\n}\n"],"names":[],"mappings":";;AAAA,OAAO,EAAe,OAAO,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAMvD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,WAAwB;IAC5D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAE5B,cAAc,EAAE,WAAW,EAAE;YAC7B,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QAEH,IAAI,aAAa,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,WAAW,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBAC/B,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CACrC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,WAAW,CAAC,YAAY,CAC3C,CAAC;YACJ,CAAC;YAED,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;QACnC,CAAC;QAED,MAAM,IAAI,YAAY,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,WAAwB,EAAE,EAAU;IAC1E,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,IAAI,eAAe,CAAC;YACvC,WAAW,EAAE,OAAO;SACrB,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAG5B,gBAAgB,EAAE,OAAO,EACzB,WAAW,EACX;YACE,MAAM,EAAE,KAAK;SACd,EACD,YAAY,CACb,CAAC;QAEF,IAAI,MAAM,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5B,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAExB,MAAM,IAAI,YAAY,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC","debug_id":"e5eec58f-0a29-5ede-91ca-d9450e4f4bc2"}
1
+ {"version":3,"file":"styleguide.js","sources":["api/styleguide.ts"],"sourceRoot":"/","sourcesContent":["import { APIResponse, request } from \"./api.js\";\nimport { UnknownError } from \"./errors.js\";\nimport { Credentials } from \"../common/credentials.js\";\nimport {\n CategoryNode,\n NavigationNode,\n PageNode,\n Styleguide,\n} from \"./types/styleguide.js\";\nimport { captureException } from \"../common/errors.js\";\n\ninterface StyleguideListSuccessResponse {\n styleguides: Styleguide[];\n}\n\nexport async function listStyleguides(credentials: Credentials, clientUserAgent?: string) {\n try {\n const response = await request<\n APIResponse<StyleguideListSuccessResponse, {}, {}>\n >(\"/styleguides\", credentials, {\n method: \"GET\",\n }, undefined, undefined, { clientUserAgent });\n\n if (\"styleguides\" in response.data) {\n if (credentials.type === \"jwt\") {\n return response.data.styleguides.filter(\n (sg) => sg.id === credentials.styleguideId,\n );\n }\n\n return response.data.styleguides;\n }\n\n throw new UnknownError();\n } catch (e) {\n captureException(e);\n return [];\n }\n}\n\ninterface SyleguideTreeSuccessResponse {\n tree: (PageNode | CategoryNode | NavigationNode)[];\n}\n\nexport async function getStyleguideTree(credentials: Credentials, id: number, clientUserAgent?: string) {\n try {\n const searchParams = new URLSearchParams({\n show_hidden: \"false\",\n });\n\n const response = await request<\n APIResponse<SyleguideTreeSuccessResponse, {}, {}>\n >(\n `/styleguides/${id}/tree`,\n credentials,\n {\n method: \"GET\",\n },\n searchParams,\n undefined,\n { clientUserAgent },\n );\n\n if (\"tree\" in response.data) {\n return response.data.tree;\n }\n\n console.error(response);\n\n throw new UnknownError();\n } catch (e) {\n captureException(e);\n return [];\n }\n}\n"],"names":[],"mappings":";;AAAA,OAAO,EAAe,OAAO,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAMvD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,WAAwB,EAAE,eAAwB;IACtF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAE5B,cAAc,EAAE,WAAW,EAAE;YAC7B,MAAM,EAAE,KAAK;SACd,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;QAE9C,IAAI,aAAa,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,WAAW,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBAC/B,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CACrC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,WAAW,CAAC,YAAY,CAC3C,CAAC;YACJ,CAAC;YAED,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;QACnC,CAAC;QAED,MAAM,IAAI,YAAY,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,WAAwB,EAAE,EAAU,EAAE,eAAwB;IACpG,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,IAAI,eAAe,CAAC;YACvC,WAAW,EAAE,OAAO;SACrB,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAG5B,gBAAgB,EAAE,OAAO,EACzB,WAAW,EACX;YACE,MAAM,EAAE,KAAK;SACd,EACD,YAAY,EACZ,SAAS,EACT,EAAE,eAAe,EAAE,CACpB,CAAC;QAEF,IAAI,MAAM,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5B,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAExB,MAAM,IAAI,YAAY,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC","debug_id":"3d4cd722-6043-5c3e-a421-a6f2511a55b0"}
@@ -0,0 +1,15 @@
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]="6a5a51a2-6a32-54bd-9e0a-63ef812eb566")}catch(e){}}();
3
+ import { ApiType, request } from "./api.js";
4
+ import { captureException } from "../common/errors.js";
5
+ export async function getTokenSetExport(credentials, tokenSetId, clientUserAgent) {
6
+ try {
7
+ return await request(`/token_management/token_set/${tokenSetId}/export`, credentials, { method: "GET" }, new URLSearchParams({ format: "w3c" }), ApiType.Internal, { clientUserAgent });
8
+ }
9
+ catch (e) {
10
+ captureException(e);
11
+ return null;
12
+ }
13
+ }
14
+ //# sourceMappingURL=token.js.map
15
+ //# debugId=6a5a51a2-6a32-54bd-9e0a-63ef812eb566
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sources":["api/token.ts"],"sourceRoot":"/","sourcesContent":["import { Credentials } from \"../common/credentials.js\";\nimport { ApiType, request } from \"./api.js\";\nimport { TokenGroup } from \"./types/token.js\";\nimport { captureException } from \"../common/errors.js\";\n\nexport async function getTokenSetExport(\n credentials: Credentials,\n tokenSetId: number,\n clientUserAgent?: string,\n): Promise<TokenGroup | null> {\n try {\n return await request<TokenGroup>(\n `/token_management/token_set/${tokenSetId}/export`,\n credentials,\n { method: \"GET\" },\n new URLSearchParams({ format: \"w3c\" }),\n ApiType.Internal,\n { clientUserAgent },\n );\n } catch (e) {\n captureException(e);\n return null;\n }\n}\n"],"names":[],"mappings":";;AACA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,WAAwB,EACxB,UAAkB,EAClB,eAAwB;IAExB,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAClB,+BAA+B,UAAU,SAAS,EAClD,WAAW,EACX,EAAE,MAAM,EAAE,KAAK,EAAE,EACjB,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EACtC,OAAO,CAAC,QAAQ,EAChB,EAAE,eAAe,EAAE,CACpB,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC","debug_id":"6a5a51a2-6a32-54bd-9e0a-63ef812eb566"}
@@ -0,0 +1,5 @@
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]="176de3fd-0981-5940-a815-50166cce2f8b")}catch(e){}}();
3
+ export {};
4
+ //# sourceMappingURL=token.js.map
5
+ //# debugId=176de3fd-0981-5940-a815-50166cce2f8b
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sources":["api/types/token.ts"],"sourceRoot":"/","sourcesContent":["export interface TokenSet {\n id: number;\n name: string;\n source: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface TokenValue {\n $value: string | number | Record<string, unknown>;\n $type?: string;\n $description?: string;\n}\n\nexport interface TokenGroup {\n $type?: string;\n $description?: string;\n [key: string]: string | TokenValue | TokenGroup | undefined;\n}\n"],"names":[],"mappings":"","debug_id":"176de3fd-0981-5940-a815-50166cce2f8b"}
@@ -0,0 +1,36 @@
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]="00a53473-e975-58f2-96d3-02166ee7d41a")}catch(e){}}();
3
+ import { InvalidTokenError, } from "@modelcontextprotocol/sdk/server/auth/errors.js";
4
+ import { internalRequest } from "../api/api.js";
5
+ function parseScopes(scope) {
6
+ if (!scope) {
7
+ return [];
8
+ }
9
+ if (Array.isArray(scope)) {
10
+ return scope.filter((item) => typeof item === "string");
11
+ }
12
+ return scope
13
+ .split(" ")
14
+ .map((item) => item.trim())
15
+ .filter(Boolean);
16
+ }
17
+ export async function verifyAccessToken(token, _req) {
18
+ const exchange = await internalRequest("/mcp/exchange_oauth_token", "POST", {
19
+ access_token: token,
20
+ });
21
+ if (!exchange.active) {
22
+ throw new InvalidTokenError("Token is inactive");
23
+ }
24
+ if (typeof exchange.exp !== "number") {
25
+ throw new InvalidTokenError("Token has no expiration time");
26
+ }
27
+ return {
28
+ token: exchange.extra.jwt,
29
+ clientId: exchange.client_id ?? "unknown-client",
30
+ scopes: parseScopes(exchange.scope),
31
+ expiresAt: exchange.exp,
32
+ extra: exchange.extra,
33
+ };
34
+ }
35
+ //# sourceMappingURL=introspection.js.map
36
+ //# debugId=00a53473-e975-58f2-96d3-02166ee7d41a
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspection.js","sources":["auth/introspection.ts"],"sourceRoot":"/","sourcesContent":["import { Request } from \"express\";\nimport { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport {\n InvalidTokenError,\n ServerError,\n} from \"@modelcontextprotocol/sdk/server/auth/errors.js\";\nimport { internalRequest } from \"../api/api.js\";\n\ninterface ExchangeResponse {\n active: boolean;\n scope?: string | string[];\n client_id?: string;\n exp?: number;\n extra: {\n features: Record<string, unknown>;\n jwt: string;\n user_id: number;\n team_id: number;\n };\n}\n\nfunction parseScopes(scope?: string | string[]): string[] {\n if (!scope) {\n return [];\n }\n if (Array.isArray(scope)) {\n return scope.filter((item): item is string => typeof item === \"string\");\n }\n return scope\n .split(\" \")\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nexport async function verifyAccessToken(\n token: string,\n _req: Request,\n): Promise<AuthInfo> {\n const exchange = await internalRequest<ExchangeResponse>(\n \"/mcp/exchange_oauth_token\",\n \"POST\",\n {\n access_token: token,\n },\n );\n\n if (!exchange.active) {\n throw new InvalidTokenError(\"Token is inactive\");\n }\n\n if (typeof exchange.exp !== \"number\") {\n throw new InvalidTokenError(\"Token has no expiration time\");\n }\n\n return {\n token: exchange.extra.jwt,\n clientId: exchange.client_id ?? \"unknown-client\",\n scopes: parseScopes(exchange.scope),\n expiresAt: exchange.exp,\n extra: exchange.extra,\n };\n}\n"],"names":[],"mappings":";;AAEA,OAAO,EACL,iBAAiB,GAElB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAehD,SAAS,WAAW,CAAC,KAAyB;IAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAa,EACb,IAAa;IAEb,MAAM,QAAQ,GAAG,MAAM,eAAe,CACpC,2BAA2B,EAC3B,MAAM,EACN;QACE,YAAY,EAAE,KAAK;KACpB,CACF,CAAC;IAEF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QACrB,MAAM,IAAI,iBAAiB,CAAC,mBAAmB,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,OAAO,QAAQ,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;QACrC,MAAM,IAAI,iBAAiB,CAAC,8BAA8B,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG;QACzB,QAAQ,EAAE,QAAQ,CAAC,SAAS,IAAI,gBAAgB;QAChD,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC;QACnC,SAAS,EAAE,QAAQ,CAAC,GAAG;QACvB,KAAK,EAAE,QAAQ,CAAC,KAAK;KACtB,CAAC;AACJ,CAAC","debug_id":"00a53473-e975-58f2-96d3-02166ee7d41a"}
@@ -1,7 +1,10 @@
1
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]="07c05406-ef6e-5651-b18b-da323e5fc8d1")}catch(e){}}();
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]="11c203a2-35a9-5524-af57-bf3c016a0056")}catch(e){}}();
3
3
  import { MissingCredentialsError } from "./errors.js";
4
4
  import { internalRequest } from "../api/api.js";
5
+ export function isLocalMCP(credentials) {
6
+ return credentials.type === "client_token";
7
+ }
5
8
  export function getCredentialsFromEnvironment() {
6
9
  const token = process.env["ZEROHEIGHT_ACCESS_TOKEN"];
7
10
  const client = process.env["ZEROHEIGHT_CLIENT_ID"];
@@ -18,15 +21,30 @@ export async function getCredentials(authInfo) {
18
21
  if (!authInfo) {
19
22
  return getCredentialsFromEnvironment();
20
23
  }
21
- const res = await internalRequest("/mcp_url/exchange_token", "POST", {
22
- token: authInfo.token,
23
- });
24
+ if (authInfo.clientId === "http-client") {
25
+ const res = await internalRequest("/mcp_url/exchange_token", "POST", {
26
+ token: authInfo.token,
27
+ });
28
+ return {
29
+ type: "jwt",
30
+ jwt: res.jwt,
31
+ styleguideId: res.styleguide_id,
32
+ features: res.features ?? {},
33
+ userId: res.user_id,
34
+ viewerId: res.viewer_id,
35
+ teamId: res.team_id,
36
+ mcpAuthId: res.mcp_auth_id,
37
+ tokenSets: res.token_sets,
38
+ };
39
+ }
24
40
  return {
25
- type: "jwt",
26
- jwt: res.jwt,
27
- styleguideId: res.styleguide_id,
28
- features: res.features ?? {},
41
+ type: "oauth_jwt",
42
+ jwt: authInfo.token,
43
+ features: authInfo.extra.features,
44
+ userId: authInfo.extra.user_id,
45
+ teamId: authInfo.extra.team_id,
46
+ clientId: authInfo.clientId,
29
47
  };
30
48
  }
31
49
  //# sourceMappingURL=credentials.js.map
32
- //# debugId=07c05406-ef6e-5651-b18b-da323e5fc8d1
50
+ //# debugId=11c203a2-35a9-5524-af57-bf3c016a0056
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.js","sources":["common/credentials.ts"],"sourceRoot":"/","sourcesContent":["import { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport { MissingCredentialsError } from \"./errors.js\";\nimport { internalRequest } from \"../api/api.js\";\n\nexport type Credentials =\n | {\n type: \"client_token\";\n token: string;\n client: string;\n }\n | {\n type: \"jwt\";\n jwt: string;\n styleguideId: number;\n features: Record<string, boolean>;\n };\n\nexport function getCredentialsFromEnvironment(): Credentials {\n const token = process.env[\"ZEROHEIGHT_ACCESS_TOKEN\"];\n const client = process.env[\"ZEROHEIGHT_CLIENT_ID\"];\n if (!token || !client) {\n throw new MissingCredentialsError();\n }\n\n return {\n type: \"client_token\",\n token,\n client,\n };\n}\n\ninterface JwtResponse {\n jwt: string;\n styleguide_id: number;\n features: Record<string, boolean>;\n}\n\nexport async function getCredentials(\n authInfo?: AuthInfo\n): Promise<Credentials> {\n if (!authInfo) {\n return getCredentialsFromEnvironment();\n }\n\n const res = await internalRequest<JwtResponse>(\n \"/mcp_url/exchange_token\",\n \"POST\",\n {\n token: authInfo.token,\n }\n );\n\n return {\n type: \"jwt\",\n jwt: res.jwt,\n styleguideId: res.styleguide_id,\n features: res.features ?? {},\n };\n}\n"],"names":[],"mappings":";;AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAehD,MAAM,UAAU,6BAA6B;IAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,uBAAuB,EAAE,CAAC;IACtC,CAAC;IAED,OAAO;QACL,IAAI,EAAE,cAAc;QACpB,KAAK;QACL,MAAM;KACP,CAAC;AACJ,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAmB;IAEnB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,6BAA6B,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,eAAe,CAC/B,yBAAyB,EACzB,MAAM,EACN;QACE,KAAK,EAAE,QAAQ,CAAC,KAAK;KACtB,CACF,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,YAAY,EAAE,GAAG,CAAC,aAAa;QAC/B,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE;KAC7B,CAAC;AACJ,CAAC","debug_id":"07c05406-ef6e-5651-b18b-da323e5fc8d1"}
1
+ {"version":3,"file":"credentials.js","sources":["common/credentials.ts"],"sourceRoot":"/","sourcesContent":["import { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport { MissingCredentialsError } from \"./errors.js\";\nimport { internalRequest } from \"../api/api.js\";\n\nexport type Credentials =\n | {\n type: \"client_token\";\n token: string;\n client: string;\n }\n | {\n type: \"jwt\";\n jwt: string;\n styleguideId: number;\n features: Record<string, boolean>;\n viewerId?: string;\n userId?: number;\n teamId?: number;\n mcpAuthId?: number;\n tokenSets?: Array<{ id: number; name: string }>;\n }\n | {\n type: \"oauth_jwt\";\n jwt: string;\n clientId: string;\n features: Record<string, boolean>;\n userId: number;\n teamId: number;\n };\n\nexport function isLocalMCP(\n credentials: Credentials,\n): credentials is Extract<Credentials, { type: \"client_token\" }> {\n return credentials.type === \"client_token\";\n}\n\nexport function getCredentialsFromEnvironment(): Credentials {\n const token = process.env[\"ZEROHEIGHT_ACCESS_TOKEN\"];\n const client = process.env[\"ZEROHEIGHT_CLIENT_ID\"];\n if (!token || !client) {\n throw new MissingCredentialsError();\n }\n\n return {\n type: \"client_token\",\n token,\n client,\n };\n}\n\ninterface JwtResponse {\n jwt: string;\n styleguide_id: number;\n features: Record<string, boolean>;\n user_id?: number;\n viewer_id?: string;\n team_id?: number;\n mcp_auth_id?: number;\n token_sets?: Array<{ id: number; name: string }>;\n}\n\nexport async function getCredentials(\n authInfo?: AuthInfo,\n): Promise<Credentials> {\n if (!authInfo) {\n return getCredentialsFromEnvironment();\n }\n if (authInfo.clientId === \"http-client\") {\n const res = await internalRequest<JwtResponse>(\n \"/mcp_url/exchange_token\",\n \"POST\",\n {\n token: authInfo.token,\n },\n );\n\n return {\n type: \"jwt\",\n jwt: res.jwt,\n styleguideId: res.styleguide_id,\n features: res.features ?? {},\n userId: res.user_id,\n viewerId: res.viewer_id,\n teamId: res.team_id,\n mcpAuthId: res.mcp_auth_id,\n tokenSets: res.token_sets,\n };\n }\n return {\n type: \"oauth_jwt\",\n jwt: authInfo.token,\n features: authInfo.extra!.features as Record<string, boolean>,\n userId: authInfo.extra!.user_id as number,\n teamId: authInfo.extra!.team_id as number,\n clientId: authInfo.clientId,\n };\n}\n"],"names":[],"mappings":";;AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AA4BhD,MAAM,UAAU,UAAU,CACxB,WAAwB;IAExB,OAAO,WAAW,CAAC,IAAI,KAAK,cAAc,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,6BAA6B;IAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,uBAAuB,EAAE,CAAC;IACtC,CAAC;IAED,OAAO;QACL,IAAI,EAAE,cAAc;QACpB,KAAK;QACL,MAAM;KACP,CAAC;AACJ,CAAC;AAaD,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAmB;IAEnB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,6BAA6B,EAAE,CAAC;IACzC,CAAC;IACD,IAAI,QAAQ,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,eAAe,CAC/B,yBAAyB,EACzB,MAAM,EACN;YACE,KAAK,EAAE,QAAQ,CAAC,KAAK;SACtB,CACF,CAAC;QAEF,OAAO;YACL,IAAI,EAAE,KAAK;YACX,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,YAAY,EAAE,GAAG,CAAC,aAAa;YAC/B,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE;YAC5B,MAAM,EAAE,GAAG,CAAC,OAAO;YACnB,QAAQ,EAAE,GAAG,CAAC,SAAS;YACvB,MAAM,EAAE,GAAG,CAAC,OAAO;YACnB,SAAS,EAAE,GAAG,CAAC,WAAW;YAC1B,SAAS,EAAE,GAAG,CAAC,UAAU;SAC1B,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,QAAQ,CAAC,KAAK;QACnB,QAAQ,EAAE,QAAQ,CAAC,KAAM,CAAC,QAAmC;QAC7D,MAAM,EAAE,QAAQ,CAAC,KAAM,CAAC,OAAiB;QACzC,MAAM,EAAE,QAAQ,CAAC,KAAM,CAAC,OAAiB;QACzC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;KAC5B,CAAC;AACJ,CAAC","debug_id":"11c203a2-35a9-5524-af57-bf3c016a0056"}
@@ -0,0 +1,10 @@
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]="4c5c6e2e-3416-5b29-a1eb-011b1b114173")}catch(e){}}();
3
+ export function formatTokenSetsAsMarkdown(tokenSets) {
4
+ if (tokenSets.length === 0) {
5
+ return "No token sets available. You can link token sets in your styleguide's AI settings.";
6
+ }
7
+ return tokenSets.map((ts) => `- ${ts.name} (ID: ${ts.id})`).join("\n");
8
+ }
9
+ //# sourceMappingURL=token.js.map
10
+ //# debugId=4c5c6e2e-3416-5b29-a1eb-011b1b114173
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sources":["common/formatters/token.ts"],"sourceRoot":"/","sourcesContent":["import { LinkedTokenSet } from \"../../types/server.js\";\n\nexport function formatTokenSetsAsMarkdown(tokenSets: LinkedTokenSet[]): string {\n if (tokenSets.length === 0) {\n return \"No token sets available. You can link token sets in your styleguide's AI settings.\";\n }\n return tokenSets.map((ts) => `- ${ts.name} (ID: ${ts.id})`).join(\"\\n\");\n}\n"],"names":[],"mappings":";;AAEA,MAAM,UAAU,yBAAyB,CAAC,SAA2B;IACnE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,oFAAoF,CAAC;IAC9F,CAAC;IACD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzE,CAAC","debug_id":"4c5c6e2e-3416-5b29-a1eb-011b1b114173"}
@@ -0,0 +1,43 @@
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]="c0a4d1e9-2a97-5cc7-8056-fb540bb525a7")}catch(e){}}();
3
+ import { parse, differenceCiede2000 } from "culori";
4
+ import { flattenTokensByType } from "./tokens.js";
5
+ export function parseColor(value) {
6
+ const parsed = parse(value);
7
+ return parsed ?? null;
8
+ }
9
+ /** CIEDE2000 perceptual distance. 0 = identical, higher = more different. */
10
+ export function colorDistance(color1, color2) {
11
+ const c1 = parse(color1);
12
+ const c2 = parse(color2);
13
+ if (!c1 || !c2)
14
+ return null;
15
+ const diff = differenceCiede2000();
16
+ return diff(c1, c2);
17
+ }
18
+ /**
19
+ * Find the closest color token within a CIEDE2000 threshold.
20
+ * Default threshold is 10 (perceptually similar).
21
+ */
22
+ export function findClosestColorToken(color, tokens, threshold = 10) {
23
+ const parsedColor = parse(color);
24
+ if (!parsedColor)
25
+ return null;
26
+ const colorTokens = flattenTokensByType(tokens, "color");
27
+ const diff = differenceCiede2000();
28
+ let closest = null;
29
+ for (const [name, tokenValue] of colorTokens) {
30
+ const tokenColor = parse(tokenValue);
31
+ if (!tokenColor)
32
+ continue;
33
+ const distance = diff(parsedColor, tokenColor);
34
+ if (distance <= threshold) {
35
+ if (!closest || distance < closest.distance) {
36
+ closest = { name, value: tokenValue, distance };
37
+ }
38
+ }
39
+ }
40
+ return closest;
41
+ }
42
+ //# sourceMappingURL=color.js.map
43
+ //# debugId=c0a4d1e9-2a97-5cc7-8056-fb540bb525a7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.js","sources":["lint/color.ts"],"sourceRoot":"/","sourcesContent":["import { parse, differenceCiede2000, type Color } from \"culori\";\nimport type { TokenGroup } from \"../api/types/token.js\";\nimport { flattenTokensByType } from \"./tokens.js\";\n\nexport function parseColor(value: string): Color | null {\n const parsed = parse(value);\n return parsed ?? null;\n}\n\n/** CIEDE2000 perceptual distance. 0 = identical, higher = more different. */\nexport function colorDistance(color1: string, color2: string): number | null {\n const c1 = parse(color1);\n const c2 = parse(color2);\n if (!c1 || !c2) return null;\n\n const diff = differenceCiede2000();\n return diff(c1, c2);\n}\n\nexport interface ColorTokenMatch {\n name: string;\n value: string;\n distance: number;\n}\n\n/**\n * Find the closest color token within a CIEDE2000 threshold.\n * Default threshold is 10 (perceptually similar).\n */\nexport function findClosestColorToken(\n color: string,\n tokens: TokenGroup,\n threshold: number = 10,\n): ColorTokenMatch | null {\n const parsedColor = parse(color);\n if (!parsedColor) return null;\n\n const colorTokens = flattenTokensByType(tokens, \"color\");\n const diff = differenceCiede2000();\n\n let closest: ColorTokenMatch | null = null;\n\n for (const [name, tokenValue] of colorTokens) {\n const tokenColor = parse(tokenValue);\n if (!tokenColor) continue;\n\n const distance = diff(parsedColor, tokenColor);\n\n if (distance <= threshold) {\n if (!closest || distance < closest.distance) {\n closest = { name, value: tokenValue, distance };\n }\n }\n }\n\n return closest;\n}\n"],"names":[],"mappings":";;AAAA,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAc,MAAM,QAAQ,CAAC;AAEhE,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,MAAM,IAAI,IAAI,CAAC;AACxB,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,MAAc;IAC1D,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACzB,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACzB,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAE5B,MAAM,IAAI,GAAG,mBAAmB,EAAE,CAAC;IACnC,OAAO,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AACtB,CAAC;AAQD;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAa,EACb,MAAkB,EAClB,YAAoB,EAAE;IAEtB,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE9B,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,mBAAmB,EAAE,CAAC;IAEnC,IAAI,OAAO,GAA2B,IAAI,CAAC;IAE3C,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,WAAW,EAAE,CAAC;QAC7C,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;QACrC,IAAI,CAAC,UAAU;YAAE,SAAS;QAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QAE/C,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,OAAO,IAAI,QAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;gBAC5C,OAAO,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC","debug_id":"c0a4d1e9-2a97-5cc7-8056-fb540bb525a7"}