scribe-cms 0.0.10 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/runtime.js CHANGED
@@ -3,6 +3,9 @@ import { z } from 'zod';
3
3
  import fs2 from 'fs';
4
4
  import matter from 'gray-matter';
5
5
  import Database from 'better-sqlite3';
6
+ import remarkMdx from 'remark-mdx';
7
+ import remarkParse from 'remark-parse';
8
+ import { unified } from 'unified';
6
9
 
7
10
  // src/config/resolve-config.ts
8
11
 
@@ -542,6 +545,118 @@ function listTranslationsForType(db, contentType) {
542
545
  return db.prepare(`SELECT * FROM translations WHERE content_type = ? ORDER BY en_slug, locale`).all(contentType);
543
546
  }
544
547
 
548
+ // src/translate/normalize-mdx-body.ts
549
+ function needsMdxEscapeNormalization(body) {
550
+ return /\\n[ \t/>]|<[\w.-][^>]*\\n/.test(body);
551
+ }
552
+ function normalizeTranslatedMdxBody(body) {
553
+ if (!needsMdxEscapeNormalization(body)) {
554
+ return { body, adjusted: false };
555
+ }
556
+ const normalized = body.replace(/\\r\\n/g, "\n").replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
557
+ return { body: normalized, adjusted: normalized !== body };
558
+ }
559
+
560
+ // src/translate/sanitize-mdx-jsx.ts
561
+ function sanitizeMdxJsxAttributeQuotes(body) {
562
+ let adjusted = false;
563
+ let out = "";
564
+ let i = 0;
565
+ while (i < body.length) {
566
+ if (body[i] !== "<" || !/[\w.]/.test(body[i + 1] ?? "")) {
567
+ out += body[i];
568
+ i += 1;
569
+ continue;
570
+ }
571
+ const tagStart = i;
572
+ i += 1;
573
+ while (i < body.length && /[\w.-]/.test(body[i] ?? "")) i += 1;
574
+ const tagName = body.slice(tagStart + 1, i);
575
+ let tagOut = `<${tagName}`;
576
+ let tagAdjusted = false;
577
+ while (i < body.length && body[i] !== ">" && body[i] !== "/") {
578
+ while (i < body.length && /\s/.test(body[i] ?? "")) {
579
+ tagOut += body[i];
580
+ i += 1;
581
+ }
582
+ if (i >= body.length || body[i] === ">" || body[i] === "/") break;
583
+ const attrStart = i;
584
+ while (i < body.length && /[\w:.-]/.test(body[i] ?? "")) i += 1;
585
+ body.slice(attrStart, i);
586
+ while (i < body.length && /\s/.test(body[i] ?? "")) i += 1;
587
+ if (body[i] !== "=") {
588
+ tagOut += body.slice(attrStart, i);
589
+ continue;
590
+ }
591
+ tagOut += body.slice(attrStart, i);
592
+ tagOut += "=";
593
+ i += 1;
594
+ while (i < body.length && /\s/.test(body[i] ?? "")) i += 1;
595
+ const quote = body[i];
596
+ if (quote !== '"' && quote !== "'") {
597
+ continue;
598
+ }
599
+ if (quote === "'") {
600
+ const valStart2 = i + 1;
601
+ i += 1;
602
+ while (i < body.length) {
603
+ if (body[i] === "\\") {
604
+ i += 2;
605
+ continue;
606
+ }
607
+ if (body[i] === "'") break;
608
+ i += 1;
609
+ }
610
+ tagOut += body.slice(valStart2 - 1, i + 1);
611
+ i += 1;
612
+ continue;
613
+ }
614
+ const valStart = i + 1;
615
+ i += 1;
616
+ let closeIdx = -1;
617
+ for (let scan = valStart; scan < body.length; scan += 1) {
618
+ if (body[scan] !== '"') continue;
619
+ let j = scan + 1;
620
+ while (j < body.length && /\s/.test(body[j] ?? "")) j += 1;
621
+ if (j < body.length && (body[j] === ">" || body[j] === "/" || /[a-zA-Z]/.test(body[j] ?? ""))) {
622
+ closeIdx = scan;
623
+ break;
624
+ }
625
+ }
626
+ if (closeIdx === -1) {
627
+ tagOut += body.slice(valStart - 1, i);
628
+ break;
629
+ }
630
+ const value = body.slice(valStart, closeIdx);
631
+ const hasInternalQuote = value.includes('"');
632
+ if (hasInternalQuote) {
633
+ const escaped = value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
634
+ tagOut += `'${escaped}'`;
635
+ tagAdjusted = true;
636
+ } else {
637
+ tagOut += `"${value}"`;
638
+ }
639
+ i = closeIdx + 1;
640
+ }
641
+ if (tagAdjusted) adjusted = true;
642
+ tagOut += body[i] ?? "";
643
+ out += tagOut;
644
+ i += 1;
645
+ }
646
+ return { body: out, adjusted };
647
+ }
648
+
649
+ // src/translate/validate-mdx-body.ts
650
+ unified().use(remarkParse).use(remarkMdx);
651
+ function prepareTranslatedMdxBody(body) {
652
+ const normalized = normalizeTranslatedMdxBody(body);
653
+ const sanitized = sanitizeMdxJsxAttributeQuotes(normalized.body);
654
+ return {
655
+ body: sanitized.body,
656
+ adjusted: normalized.adjusted || sanitized.adjusted
657
+ };
658
+ }
659
+
545
660
  // src/loader/normalize-en.ts
546
661
  function normalizeEnFrontmatter(data) {
547
662
  const out = { ...data };
@@ -662,7 +777,7 @@ function buildDocumentFromTranslation(row, enDoc, type, config) {
662
777
  noindex: seo.noindex,
663
778
  canonicalPathOverride: seo.canonicalPathOverride,
664
779
  frontmatter,
665
- content: row.body
780
+ content: prepareTranslatedMdxBody(row.body).body
666
781
  };
667
782
  }
668
783
  var DEV_REVALIDATE_MS = 1500;