scribe-cms 0.0.7 → 0.0.8
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/cli/index.cjs +102 -4
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +102 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +103 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +103 -5
- package/dist/index.js.map +1 -1
- package/dist/runtime.cjs +5 -0
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +5 -1
- package/dist/runtime.js.map +1 -1
- package/dist/src/core/types.d.ts +3 -0
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/create-project.d.ts.map +1 -1
- package/dist/src/create-scribe.d.ts.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/runtime.d.ts +1 -0
- package/dist/src/runtime.d.ts.map +1 -1
- package/dist/src/translate/page-translator.d.ts +1 -0
- package/dist/src/translate/page-translator.d.ts.map +1 -1
- package/dist/src/translate/resolve-translate-config.d.ts.map +1 -1
- package/dist/src/translate/sanitize-mdx-jsx.d.ts +9 -0
- package/dist/src/translate/sanitize-mdx-jsx.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1187,6 +1187,9 @@ function createProject(config) {
|
|
|
1187
1187
|
getType: getRuntime,
|
|
1188
1188
|
listTypes() {
|
|
1189
1189
|
return Array.from(runtimes.values());
|
|
1190
|
+
},
|
|
1191
|
+
listRoutableTypes() {
|
|
1192
|
+
return Array.from(runtimes.values()).filter((runtime) => isRoutableType(runtime.config));
|
|
1190
1193
|
}
|
|
1191
1194
|
};
|
|
1192
1195
|
}
|
|
@@ -1682,6 +1685,7 @@ function createScribe(input) {
|
|
|
1682
1685
|
project,
|
|
1683
1686
|
getType: project.getType,
|
|
1684
1687
|
listTypes: project.listTypes,
|
|
1688
|
+
listRoutableTypes: project.listRoutableTypes,
|
|
1685
1689
|
sitemap(options) {
|
|
1686
1690
|
return generateSitemap(project, options);
|
|
1687
1691
|
}
|
|
@@ -2369,11 +2373,12 @@ function buildGeminiResponseSchema(schema, slugStrategy) {
|
|
|
2369
2373
|
function slugStrategyRules(slugStrategy, preserveTerms) {
|
|
2370
2374
|
if (slugStrategy === "localized") {
|
|
2371
2375
|
const rules = [
|
|
2372
|
-
"Provide a URL slug in JSON field `slug` that is
|
|
2376
|
+
"Provide a URL slug in JSON field `slug` that is Localized into the target language.",
|
|
2373
2377
|
"Base the slug on the meaning of the translated title \u2014 do NOT reuse the English slug words.",
|
|
2374
2378
|
"Slug MUST be ASCII only: a-z, 0-9, hyphens. No uppercase, accents, underscores, or spaces.",
|
|
2375
2379
|
"For non-Latin languages, write the words in the target language and transliterate them into Latin script (e.g. Russian -> romanized Russian, not English).",
|
|
2376
|
-
"Do NOT append locale codes to the slug (e.g. -fr, -he, -zh-cn). Locale routing is handled by the URL prefix, not the slug."
|
|
2380
|
+
"Do NOT append locale codes to the slug (e.g. -fr, -he, -zh-cn). Locale routing is handled by the URL prefix, not the slug.",
|
|
2381
|
+
'In JSX attributes (e.g. FaqItem question="..."), use single quotes when the value contains double-quote characters (e.g. Hebrew \u05D3\u05D5\u05D0"\u05DC), or escape them as \\".'
|
|
2377
2382
|
];
|
|
2378
2383
|
if (preserveTerms?.length) {
|
|
2379
2384
|
rules.push(
|
|
@@ -2406,6 +2411,95 @@ function resolveTranslateConfig(config, type) {
|
|
|
2406
2411
|
return mergeTranslateConfig(config.translate, type.translate, type.slugStrategy);
|
|
2407
2412
|
}
|
|
2408
2413
|
|
|
2414
|
+
// src/translate/sanitize-mdx-jsx.ts
|
|
2415
|
+
function sanitizeMdxJsxAttributeQuotes(body) {
|
|
2416
|
+
let adjusted = false;
|
|
2417
|
+
let out = "";
|
|
2418
|
+
let i = 0;
|
|
2419
|
+
while (i < body.length) {
|
|
2420
|
+
if (body[i] !== "<" || !/[\w.]/.test(body[i + 1] ?? "")) {
|
|
2421
|
+
out += body[i];
|
|
2422
|
+
i += 1;
|
|
2423
|
+
continue;
|
|
2424
|
+
}
|
|
2425
|
+
const tagStart = i;
|
|
2426
|
+
i += 1;
|
|
2427
|
+
while (i < body.length && /[\w.-]/.test(body[i] ?? "")) i += 1;
|
|
2428
|
+
const tagName = body.slice(tagStart + 1, i);
|
|
2429
|
+
let tagOut = `<${tagName}`;
|
|
2430
|
+
let tagAdjusted = false;
|
|
2431
|
+
while (i < body.length && body[i] !== ">" && body[i] !== "/") {
|
|
2432
|
+
while (i < body.length && /\s/.test(body[i] ?? "")) {
|
|
2433
|
+
tagOut += body[i];
|
|
2434
|
+
i += 1;
|
|
2435
|
+
}
|
|
2436
|
+
if (i >= body.length || body[i] === ">" || body[i] === "/") break;
|
|
2437
|
+
const attrStart = i;
|
|
2438
|
+
while (i < body.length && /[\w:.-]/.test(body[i] ?? "")) i += 1;
|
|
2439
|
+
body.slice(attrStart, i);
|
|
2440
|
+
while (i < body.length && /\s/.test(body[i] ?? "")) i += 1;
|
|
2441
|
+
if (body[i] !== "=") {
|
|
2442
|
+
tagOut += body.slice(attrStart, i);
|
|
2443
|
+
continue;
|
|
2444
|
+
}
|
|
2445
|
+
tagOut += body.slice(attrStart, i);
|
|
2446
|
+
tagOut += "=";
|
|
2447
|
+
i += 1;
|
|
2448
|
+
while (i < body.length && /\s/.test(body[i] ?? "")) i += 1;
|
|
2449
|
+
const quote = body[i];
|
|
2450
|
+
if (quote !== '"' && quote !== "'") {
|
|
2451
|
+
continue;
|
|
2452
|
+
}
|
|
2453
|
+
if (quote === "'") {
|
|
2454
|
+
const valStart2 = i + 1;
|
|
2455
|
+
i += 1;
|
|
2456
|
+
while (i < body.length) {
|
|
2457
|
+
if (body[i] === "\\") {
|
|
2458
|
+
i += 2;
|
|
2459
|
+
continue;
|
|
2460
|
+
}
|
|
2461
|
+
if (body[i] === "'") break;
|
|
2462
|
+
i += 1;
|
|
2463
|
+
}
|
|
2464
|
+
tagOut += body.slice(valStart2 - 1, i + 1);
|
|
2465
|
+
i += 1;
|
|
2466
|
+
continue;
|
|
2467
|
+
}
|
|
2468
|
+
const valStart = i + 1;
|
|
2469
|
+
i += 1;
|
|
2470
|
+
let closeIdx = -1;
|
|
2471
|
+
for (let scan = valStart; scan < body.length; scan += 1) {
|
|
2472
|
+
if (body[scan] !== '"') continue;
|
|
2473
|
+
let j = scan + 1;
|
|
2474
|
+
while (j < body.length && /\s/.test(body[j] ?? "")) j += 1;
|
|
2475
|
+
if (j < body.length && (body[j] === ">" || body[j] === "/" || /[a-zA-Z]/.test(body[j] ?? ""))) {
|
|
2476
|
+
closeIdx = scan;
|
|
2477
|
+
break;
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
if (closeIdx === -1) {
|
|
2481
|
+
tagOut += body.slice(valStart - 1, i);
|
|
2482
|
+
break;
|
|
2483
|
+
}
|
|
2484
|
+
const value = body.slice(valStart, closeIdx);
|
|
2485
|
+
const hasInternalQuote = value.includes('"');
|
|
2486
|
+
if (hasInternalQuote) {
|
|
2487
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
2488
|
+
tagOut += `'${escaped}'`;
|
|
2489
|
+
tagAdjusted = true;
|
|
2490
|
+
} else {
|
|
2491
|
+
tagOut += `"${value}"`;
|
|
2492
|
+
}
|
|
2493
|
+
i = closeIdx + 1;
|
|
2494
|
+
}
|
|
2495
|
+
if (tagAdjusted) adjusted = true;
|
|
2496
|
+
tagOut += body[i] ?? "";
|
|
2497
|
+
out += tagOut;
|
|
2498
|
+
i += 1;
|
|
2499
|
+
}
|
|
2500
|
+
return { body: out, adjusted };
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2409
2503
|
// src/translate/validate-translation.ts
|
|
2410
2504
|
function formatZodIssues(error) {
|
|
2411
2505
|
return error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`).join("; ");
|
|
@@ -2539,6 +2633,9 @@ async function translatePage(config, item, options = {}) {
|
|
|
2539
2633
|
if (!validated.ok) {
|
|
2540
2634
|
throw new Error(`Translation validation failed: ${validated.error}`);
|
|
2541
2635
|
}
|
|
2636
|
+
const { body: translatedBody, adjusted: mdxAdjusted } = sanitizeMdxJsxAttributeQuotes(
|
|
2637
|
+
result.parsed.body
|
|
2638
|
+
);
|
|
2542
2639
|
const writeDb = openStore(config, "readwrite");
|
|
2543
2640
|
const snapshotId = recordEnSnapshot(
|
|
2544
2641
|
config,
|
|
@@ -2557,7 +2654,7 @@ async function translatePage(config, item, options = {}) {
|
|
|
2557
2654
|
locale: item.locale,
|
|
2558
2655
|
slug,
|
|
2559
2656
|
frontmatter: validated.frontmatter,
|
|
2560
|
-
body:
|
|
2657
|
+
body: translatedBody,
|
|
2561
2658
|
enHash: currentEnHash,
|
|
2562
2659
|
translatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2563
2660
|
model: result.model,
|
|
@@ -2576,7 +2673,8 @@ async function translatePage(config, item, options = {}) {
|
|
|
2576
2673
|
usage: result.usage,
|
|
2577
2674
|
estimatedCostUsd,
|
|
2578
2675
|
durationMs: Date.now() - startedAt,
|
|
2579
|
-
slugAdjusted
|
|
2676
|
+
slugAdjusted,
|
|
2677
|
+
mdxAdjusted: mdxAdjusted || void 0
|
|
2580
2678
|
};
|
|
2581
2679
|
} catch (error) {
|
|
2582
2680
|
return {
|
|
@@ -2727,6 +2825,7 @@ exports.getRedirectSourceSlugs = getRedirectSourceSlugs;
|
|
|
2727
2825
|
exports.getRelationTarget = getRelationTarget;
|
|
2728
2826
|
exports.getStaticExportRoots = getStaticExportRoots;
|
|
2729
2827
|
exports.isResolvedConfig = isResolvedConfig;
|
|
2828
|
+
exports.isRoutableType = isRoutableType;
|
|
2730
2829
|
exports.loadConfigSync = loadConfigSync;
|
|
2731
2830
|
exports.resolveConfig = resolveConfig;
|
|
2732
2831
|
exports.resolveLocalesFromPreset = resolveLocalesFromPreset;
|