From c2ea80dd940253345046080edecec8fac57fad26 Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Thu, 13 Jun 2024 18:36:19 -0400 Subject: [PATCH] fix: after parsing the paths, replace the image paths with file ids (#3847) * fix: after parsing the paths, replace the image paths with file ids * fix for link too --- .../parseImagePaths.test.ts.snap | 112 +++++++++++++--- .../src/__test__/fixtures/hume.mdx | 27 +++- .../cli/docs-resolver/src/parseImagePaths.ts | 123 +++++++++++------- 3 files changed, 199 insertions(+), 63 deletions(-) diff --git a/packages/cli/docs-resolver/src/__test__/__snapshots__/parseImagePaths.test.ts.snap b/packages/cli/docs-resolver/src/__test__/__snapshots__/parseImagePaths.test.ts.snap index c13198613da..8e4c25b6a89 100644 --- a/packages/cli/docs-resolver/src/__test__/__snapshots__/parseImagePaths.test.ts.snap +++ b/packages/cli/docs-resolver/src/__test__/__snapshots__/parseImagePaths.test.ts.snap @@ -632,9 +632,9 @@ description: >- exports[`hume should replace all images with full path 1`] = ` [ - "/Volume/git/fern/my/docs/img/evi-tools-view.png", - "/Volume/git/fern/my/docs/img/create-function-interface.png", - "/Volume/git/fern/my/docs/img/add-tool-view.png", + "/Volume/git/fern/my/docs/folder/img/add-tool-view.png", + "/Volume/git/fern/my/docs/folder/img/evi-tools-view.png", + "/Volume/git/fern/my/docs/folder/img/create-function-interface.png", ] `; @@ -644,42 +644,83 @@ exports[`hume should replace all images with full path 2`] = ` "added": undefined, "count": 1, "removed": true, - "value": " EVI Tools page + "value": " ![image](./img/add-tool-view.png) ", }, { "added": true, "count": 1, "removed": undefined, - "value": " EVI Tools page + "value": " ![image](/Volume/git/fern/my/docs/folder/img/add-tool-view.png) ", }, { "added": undefined, "count": 1, "removed": true, - "value": " EVI Create function interface + "value": " ![test](./img/add-tool-view.png) ", }, { "added": true, "count": 1, "removed": undefined, - "value": " EVI Create function interface + "value": " ![test](/Volume/git/fern/my/docs/folder/img/add-tool-view.png) ", }, { "added": undefined, "count": 1, "removed": true, - "value": " Add tool to configuration within the Hume portal + "value": " EVI Tools page ", }, { "added": true, "count": 1, "removed": undefined, - "value": " Add tool to configuration within the Hume portal + "value": " EVI Tools page +", + }, + { + "added": undefined, + "count": 1, + "removed": true, + "value": " EVI Create function interface +", + }, + { + "added": true, + "count": 1, + "removed": undefined, + "value": " EVI Create function interface +", + }, + { + "added": undefined, + "count": 1, + "removed": true, + "value": " Add tool to configuration within the Hume portal +", + }, + { + "added": true, + "count": 1, + "removed": undefined, + "value": " Add tool to configuration within the Hume portal +", + }, + { + "added": undefined, + "count": 1, + "removed": true, + "value": "---", + }, + { + "added": true, + "count": 1, + "removed": undefined, + "value": "--- ", }, ] @@ -691,42 +732,83 @@ exports[`hume should replace all images with full path 3`] = ` "added": undefined, "count": 1, "removed": true, - "value": " EVI Tools page + "value": " ![image](./img/add-tool-view.png) ", }, { "added": true, "count": 1, "removed": undefined, - "value": " EVI Tools page + "value": " ![image](file:123e4567-e89b-12d3-a456-426655440000) ", }, { "added": undefined, "count": 1, "removed": true, - "value": " EVI Create function interface + "value": " ![test](./img/add-tool-view.png) ", }, { "added": true, "count": 1, "removed": undefined, - "value": " EVI Create function interface + "value": " ![test](file:123e4567-e89b-12d3-a456-426655440000) ", }, { "added": undefined, "count": 1, "removed": true, - "value": " Add tool to configuration within the Hume portal + "value": " EVI Tools page ", }, { "added": true, "count": 1, "removed": undefined, - "value": " Add tool to configuration within the Hume portal + "value": " EVI Tools page +", + }, + { + "added": undefined, + "count": 1, + "removed": true, + "value": " EVI Create function interface +", + }, + { + "added": true, + "count": 1, + "removed": undefined, + "value": " EVI Create function interface +", + }, + { + "added": undefined, + "count": 1, + "removed": true, + "value": " Add tool to configuration within the Hume portal +", + }, + { + "added": true, + "count": 1, + "removed": undefined, + "value": " Add tool to configuration within the Hume portal +", + }, + { + "added": undefined, + "count": 1, + "removed": true, + "value": "---", + }, + { + "added": true, + "count": 1, + "removed": undefined, + "value": "--- ", }, ] diff --git a/packages/cli/docs-resolver/src/__test__/fixtures/hume.mdx b/packages/cli/docs-resolver/src/__test__/fixtures/hume.mdx index c952a6f86aa..c89b2565a8c 100644 --- a/packages/cli/docs-resolver/src/__test__/fixtures/hume.mdx +++ b/packages/cli/docs-resolver/src/__test__/fixtures/hume.mdx @@ -34,6 +34,25 @@ step-by-step instructions on how to create and use an EVI Configuration. For EVI to leverage tools or call functions, a configuration must be created with the tool’s definition. Our step-by-step guide below walks you through creating a tool and adding it to a configuration, either via our [Portal](https://beta.hume.ai) or a POST request. + + + + ![image](./img/add-tool-view.png) + + + + + + + + ![test](./img/add-tool-view.png) + + + + text and image + + + @@ -42,7 +61,7 @@ For EVI to leverage tools or call functions, a configuration must be created wit We will first create a Tool with a specified function. In this case, we will create a tool for getting the weather. In the Portal, navigate to the [EVI Tools page](https://beta.hume.ai/evi/tools). Click the **Create function** button to begin. - EVI Tools page + EVI Tools page ### Fill in the Tool details. @@ -53,7 +72,7 @@ For EVI to leverage tools or call functions, a configuration must be created wit - **Parameters**: Define the parameters your function accepts using a JSON schema. This schema specifies the expected structure and data types of the input parameters. - EVI Create function interface + EVI Create function interface The JSON schema defines the structure of the parameters your function will accept. The key components of the schema are: @@ -86,7 +105,7 @@ For EVI to leverage tools or call functions, a configuration must be created wit After creating an EVI Configuration using our [Configuration guide](https://dev.hume.ai/docs/empathic-voice-interface-evi/configuration), navgiate to the specific configuration where you want to add your tool. In the **Tools** section, click the **Add** button to add a tool to your configuration. - Add tool to configuration within the Hume portal + Add tool to configuration within the Hume portal @@ -634,4 +653,4 @@ for this type of failure: ``` ---- +--- \ No newline at end of file diff --git a/packages/cli/docs-resolver/src/parseImagePaths.ts b/packages/cli/docs-resolver/src/parseImagePaths.ts index 7ef4b34e2b9..5d52a72de7c 100644 --- a/packages/cli/docs-resolver/src/parseImagePaths.ts +++ b/packages/cli/docs-resolver/src/parseImagePaths.ts @@ -168,7 +168,10 @@ export function replaceImagePathsAndUrls( const { content, data } = grayMatter(markdown); let replacedContent = content; - const tree = fromMarkdown(content); + const tree = fromMarkdown(content, { + extensions: [mdx()], + mdastExtensions: [mdxFromMarkdown()] + }); let offset = 0; @@ -179,8 +182,8 @@ export function replaceImagePathsAndUrls( const { start, length } = getPosition(content, node.position); const original = replacedContent.slice(start + offset, start + offset + length); let replaced = original; - if (node.type === "image") { - const src = trimAnchor(node.url); + + function replaceSrc(src: string | undefined) { if (src != null && !isExternalUrl(src)) { try { const fileId = fileIdsMap.get(AbsoluteFilePath.of(src)); @@ -193,28 +196,11 @@ export function replaceImagePathsAndUrls( } } - if (node.type === "html" || node.type === "text") { - const srcRegex = /src={?['"]([^'"]+)['"](?! \+)}?/g; - - let match; - while ((match = srcRegex.exec(node.value)) != null) { - const pathToImage = trimAnchor(match[1]); - if (pathToImage != null && !isExternalUrl(pathToImage)) { - try { - const fileId = fileIdsMap.get(AbsoluteFilePath.of(pathToImage)); - if (fileId != null) { - replaced = replaced.replaceAll(pathToImage, `file:${fileId}`); - } - } catch (e) { - // do nothing - } - } + function replaceHref(href: string | undefined) { + if (href == null) { + return; } - } - - if (node.type === "link") { - const href = trimAnchor(node.url); - if (href != null && (href.endsWith(".md") || href.endsWith(".mdx"))) { + if (href.endsWith(".md") || href.endsWith(".mdx")) { const absoluteFilePath = resolvePath(href, metadata); if (absoluteFilePath != null) { const pathName = markdownFilesToPathName.get(absoluteFilePath); @@ -235,34 +221,83 @@ export function replaceImagePathsAndUrls( } } - if (node.type === "html" || node.type === "text") { - const hrefRegex = /href={?['"]([^'"]+)['"](?! \+)}?/g; + if (node.type === "image") { + const src = trimAnchor(node.url); + replaceSrc(src); + } + + if (node.type === "mdxJsxFlowElement" || node.type === "mdxJsxTextElement") { + if (node.name && MEDIA_NODE_NAMES.includes(node.name)) { + const srcAttr = node.attributes.find((attr) => attr.type === "mdxJsxAttribute" && attr.name === "src"); + + if (srcAttr?.value) { + let srcValue = srcAttr.value; + if (typeof srcValue !== "string") { + const match = srcValue.value.match(STR_REGEX); + if (match?.[1]) { + srcValue = match[1]; + } + } + + const pathToImage = trimAnchor(srcValue); + replaceSrc(pathToImage); + } + } else { + node.attributes.forEach((attr) => { + if (attr.type === "mdxJsxAttribute" && attr.value && typeof attr.value !== "string") { + const match = SRC_REGEX.exec(attr.value.value); + if (match?.[1]) { + const pathToImage = trimAnchor(match[1]); + replaceSrc(pathToImage); + } + } + }); + } + } + + if (node.type === "html" || node.type === "text" || node.type === "mdxTextExpression") { + const srcRegex = /src={?['"]([^'"]+)['"](?! \+)}?/g; let match; - while ((match = hrefRegex.exec(node.value)) != null) { - const href = trimAnchor(match[1]); - if (href != null && (href.endsWith(".md") || href.endsWith(".mdx"))) { - const absoluteFilePath = resolvePath(href, metadata); - if (absoluteFilePath != null) { - const pathName = markdownFilesToPathName.get(absoluteFilePath); - if (pathName != null) { - replaced = replaced.replaceAll(href, pathName); - } else { - context.logger.error( - `${relative( - metadata.absolutePathToFernFolder, - absoluteFilePath - )} has no slug defined but is referenced by ${relative( - metadata.absolutePathToFernFolder, - metadata.absolutePathToMdx - )}` - ); + while ((match = srcRegex.exec(node.value)) != null) { + const pathToImage = trimAnchor(match[1]); + replaceSrc(pathToImage); + } + } + + if (node.type === "link") { + replaceHref(trimAnchor(node.url)); + } + + if (node.type === "mdxJsxFlowElement" || node.type === "mdxJsxTextElement") { + if (node.name === "a") { + const hrefAttr = node.attributes.find( + (attr) => attr.type === "mdxJsxAttribute" && attr.name === "href" + ); + + if (hrefAttr?.value) { + let href = hrefAttr.value; + if (typeof href !== "string") { + const match = href.value.match(STR_REGEX); + if (match?.[1]) { + href = match[1]; } } + replaceHref(trimAnchor(href)); } } } + if (node.type === "html" || node.type === "text" || node.type === "mdxTextExpression") { + const hrefRegex = /href={?['"]([^'"]+)['"](?! \+)}?/g; + + let match; + while ((match = hrefRegex.exec(node.value)) != null) { + const href = trimAnchor(match[1]); + replaceHref(href); + } + } + if (replaced === original) { return; }