Skip to content

Commit 38139c8

Browse files
authored
fix: regex replacement (#1222)
* fix: regex replacement * chore: add changeset
1 parent 22d51d3 commit 38139c8

File tree

4 files changed

+64
-2
lines changed

4 files changed

+64
-2
lines changed

.changeset/clever-forks-remain.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@lingo.dev/_compiler": patch
3+
"lingo.dev": patch
4+
---
5+
6+
fix regex replacement

packages/cli/src/cli/loaders/mdx2/code-placeholder.spec.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,59 @@ describe("MDX Code Placeholder Loader", () => {
512512
});
513513

514514
describe("placeholder replacement bugs", () => {
515+
it("should handle special $ characters in code content correctly", async () => {
516+
const loader = createMdxCodePlaceholderLoader();
517+
loader.setDefaultLocale("en");
518+
519+
// Code containing special $ characters that have special meaning in replaceAll
520+
const content = dedent`
521+
Text before.
522+
523+
\`\`\`js
524+
const price = "$100";
525+
const template = "$\`text\`";
526+
const special = "$&$'$\`";
527+
\`\`\`
528+
529+
Text after.
530+
`;
531+
532+
// Pull and then push the same content
533+
const pulled = await loader.pull("en", content);
534+
const translated = pulled.replace("Text before", "Texto antes");
535+
const pushed = await loader.push("en", translated);
536+
537+
// Should not contain any placeholders
538+
expect(pushed).not.toMatch(/---CODE-PLACEHOLDER-[0-9a-f]+---/);
539+
540+
// Should preserve all special $ characters exactly as they were
541+
expect(pushed).toContain('const price = "$100";');
542+
expect(pushed).toContain('const template = "$`text`";');
543+
expect(pushed).toContain('const special = "$&$\'$`";');
544+
expect(pushed).toContain("Texto antes");
545+
});
546+
547+
it("should handle inline code with $ characters correctly", async () => {
548+
const loader = createMdxCodePlaceholderLoader();
549+
loader.setDefaultLocale("en");
550+
551+
const content = "Use `$price` and `$&` and `$\`` in your code.";
552+
553+
// Pull and then push the same content
554+
const pulled = await loader.pull("en", content);
555+
const translated = pulled.replace("Use", "Utilize");
556+
const pushed = await loader.push("en", translated);
557+
558+
// Should not contain any placeholders
559+
expect(pushed).not.toMatch(/---INLINE-CODE-PLACEHOLDER-[0-9a-f]+---/);
560+
561+
// Should preserve all special $ characters
562+
expect(pushed).toContain("`$price`");
563+
expect(pushed).toContain("`$&`");
564+
expect(pushed).toContain("`$\``");
565+
expect(pushed).toContain("Utilize");
566+
});
567+
515568
it("should not leave placeholders when content matches", async () => {
516569
const loader = createMdxCodePlaceholderLoader();
517570
loader.setDefaultLocale("en");

packages/cli/src/cli/loaders/mdx2/code-placeholder.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,10 @@ export default function createMdxCodePlaceholderLoader(): ILoader<
162162
const replacement = original.startsWith(">")
163163
? _.trimStart(original, "> ")
164164
: original;
165-
result = result.replaceAll(placeholder, replacement);
165+
166+
// Use function replacer to avoid special $ character handling
167+
// When using a string, $ has special meaning (e.g., $` inserts text before match)
168+
result = result.replaceAll(placeholder, () => replacement);
166169
}
167170

168171
return result;

packages/compiler/src/lib/lcp/api/provider-details.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export const providerDetails: Record<
4747
},
4848
"lingo.dev": {
4949
name: "Lingo.dev",
50-
apiKeyEnvVar: "LINGO_API_KEY",
50+
apiKeyEnvVar: "LINGODOTDEV_API_KEY",
5151
apiKeyConfigKey: "auth.apiKey",
5252
getKeyLink: "https://lingo.dev",
5353
docsLink: "https://lingo.dev/docs",

0 commit comments

Comments
 (0)