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/cli/index.cjs
CHANGED
|
@@ -1223,6 +1223,9 @@ function createProject(config) {
|
|
|
1223
1223
|
getType: getRuntime,
|
|
1224
1224
|
listTypes() {
|
|
1225
1225
|
return Array.from(runtimes.values());
|
|
1226
|
+
},
|
|
1227
|
+
listRoutableTypes() {
|
|
1228
|
+
return Array.from(runtimes.values()).filter((runtime) => isRoutableType(runtime.config));
|
|
1226
1229
|
}
|
|
1227
1230
|
};
|
|
1228
1231
|
}
|
|
@@ -2168,11 +2171,12 @@ init_cjs_shims();
|
|
|
2168
2171
|
function slugStrategyRules(slugStrategy, preserveTerms) {
|
|
2169
2172
|
if (slugStrategy === "localized") {
|
|
2170
2173
|
const rules = [
|
|
2171
|
-
"Provide a URL slug in JSON field `slug` that is
|
|
2174
|
+
"Provide a URL slug in JSON field `slug` that is Localized into the target language.",
|
|
2172
2175
|
"Base the slug on the meaning of the translated title \u2014 do NOT reuse the English slug words.",
|
|
2173
2176
|
"Slug MUST be ASCII only: a-z, 0-9, hyphens. No uppercase, accents, underscores, or spaces.",
|
|
2174
2177
|
"For non-Latin languages, write the words in the target language and transliterate them into Latin script (e.g. Russian -> romanized Russian, not English).",
|
|
2175
|
-
"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."
|
|
2178
|
+
"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.",
|
|
2179
|
+
'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 \\".'
|
|
2176
2180
|
];
|
|
2177
2181
|
if (preserveTerms?.length) {
|
|
2178
2182
|
rules.push(
|
|
@@ -2205,6 +2209,96 @@ function resolveTranslateConfig(config, type) {
|
|
|
2205
2209
|
return mergeTranslateConfig(config.translate, type.translate, type.slugStrategy);
|
|
2206
2210
|
}
|
|
2207
2211
|
|
|
2212
|
+
// src/translate/sanitize-mdx-jsx.ts
|
|
2213
|
+
init_cjs_shims();
|
|
2214
|
+
function sanitizeMdxJsxAttributeQuotes(body) {
|
|
2215
|
+
let adjusted = false;
|
|
2216
|
+
let out = "";
|
|
2217
|
+
let i = 0;
|
|
2218
|
+
while (i < body.length) {
|
|
2219
|
+
if (body[i] !== "<" || !/[\w.]/.test(body[i + 1] ?? "")) {
|
|
2220
|
+
out += body[i];
|
|
2221
|
+
i += 1;
|
|
2222
|
+
continue;
|
|
2223
|
+
}
|
|
2224
|
+
const tagStart = i;
|
|
2225
|
+
i += 1;
|
|
2226
|
+
while (i < body.length && /[\w.-]/.test(body[i] ?? "")) i += 1;
|
|
2227
|
+
const tagName = body.slice(tagStart + 1, i);
|
|
2228
|
+
let tagOut = `<${tagName}`;
|
|
2229
|
+
let tagAdjusted = false;
|
|
2230
|
+
while (i < body.length && body[i] !== ">" && body[i] !== "/") {
|
|
2231
|
+
while (i < body.length && /\s/.test(body[i] ?? "")) {
|
|
2232
|
+
tagOut += body[i];
|
|
2233
|
+
i += 1;
|
|
2234
|
+
}
|
|
2235
|
+
if (i >= body.length || body[i] === ">" || body[i] === "/") break;
|
|
2236
|
+
const attrStart = i;
|
|
2237
|
+
while (i < body.length && /[\w:.-]/.test(body[i] ?? "")) i += 1;
|
|
2238
|
+
body.slice(attrStart, i);
|
|
2239
|
+
while (i < body.length && /\s/.test(body[i] ?? "")) i += 1;
|
|
2240
|
+
if (body[i] !== "=") {
|
|
2241
|
+
tagOut += body.slice(attrStart, i);
|
|
2242
|
+
continue;
|
|
2243
|
+
}
|
|
2244
|
+
tagOut += body.slice(attrStart, i);
|
|
2245
|
+
tagOut += "=";
|
|
2246
|
+
i += 1;
|
|
2247
|
+
while (i < body.length && /\s/.test(body[i] ?? "")) i += 1;
|
|
2248
|
+
const quote = body[i];
|
|
2249
|
+
if (quote !== '"' && quote !== "'") {
|
|
2250
|
+
continue;
|
|
2251
|
+
}
|
|
2252
|
+
if (quote === "'") {
|
|
2253
|
+
const valStart2 = i + 1;
|
|
2254
|
+
i += 1;
|
|
2255
|
+
while (i < body.length) {
|
|
2256
|
+
if (body[i] === "\\") {
|
|
2257
|
+
i += 2;
|
|
2258
|
+
continue;
|
|
2259
|
+
}
|
|
2260
|
+
if (body[i] === "'") break;
|
|
2261
|
+
i += 1;
|
|
2262
|
+
}
|
|
2263
|
+
tagOut += body.slice(valStart2 - 1, i + 1);
|
|
2264
|
+
i += 1;
|
|
2265
|
+
continue;
|
|
2266
|
+
}
|
|
2267
|
+
const valStart = i + 1;
|
|
2268
|
+
i += 1;
|
|
2269
|
+
let closeIdx = -1;
|
|
2270
|
+
for (let scan = valStart; scan < body.length; scan += 1) {
|
|
2271
|
+
if (body[scan] !== '"') continue;
|
|
2272
|
+
let j = scan + 1;
|
|
2273
|
+
while (j < body.length && /\s/.test(body[j] ?? "")) j += 1;
|
|
2274
|
+
if (j < body.length && (body[j] === ">" || body[j] === "/" || /[a-zA-Z]/.test(body[j] ?? ""))) {
|
|
2275
|
+
closeIdx = scan;
|
|
2276
|
+
break;
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
if (closeIdx === -1) {
|
|
2280
|
+
tagOut += body.slice(valStart - 1, i);
|
|
2281
|
+
break;
|
|
2282
|
+
}
|
|
2283
|
+
const value = body.slice(valStart, closeIdx);
|
|
2284
|
+
const hasInternalQuote = value.includes('"');
|
|
2285
|
+
if (hasInternalQuote) {
|
|
2286
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
2287
|
+
tagOut += `'${escaped}'`;
|
|
2288
|
+
tagAdjusted = true;
|
|
2289
|
+
} else {
|
|
2290
|
+
tagOut += `"${value}"`;
|
|
2291
|
+
}
|
|
2292
|
+
i = closeIdx + 1;
|
|
2293
|
+
}
|
|
2294
|
+
if (tagAdjusted) adjusted = true;
|
|
2295
|
+
tagOut += body[i] ?? "";
|
|
2296
|
+
out += tagOut;
|
|
2297
|
+
i += 1;
|
|
2298
|
+
}
|
|
2299
|
+
return { body: out, adjusted };
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2208
2302
|
// src/translate/validate-translation.ts
|
|
2209
2303
|
init_cjs_shims();
|
|
2210
2304
|
function formatZodIssues(error) {
|
|
@@ -2339,6 +2433,9 @@ async function translatePage(config, item, options = {}) {
|
|
|
2339
2433
|
if (!validated.ok) {
|
|
2340
2434
|
throw new Error(`Translation validation failed: ${validated.error}`);
|
|
2341
2435
|
}
|
|
2436
|
+
const { body: translatedBody, adjusted: mdxAdjusted } = sanitizeMdxJsxAttributeQuotes(
|
|
2437
|
+
result.parsed.body
|
|
2438
|
+
);
|
|
2342
2439
|
const writeDb = openStore(config, "readwrite");
|
|
2343
2440
|
const snapshotId = recordEnSnapshot(
|
|
2344
2441
|
config,
|
|
@@ -2357,7 +2454,7 @@ async function translatePage(config, item, options = {}) {
|
|
|
2357
2454
|
locale: item.locale,
|
|
2358
2455
|
slug,
|
|
2359
2456
|
frontmatter: validated.frontmatter,
|
|
2360
|
-
body:
|
|
2457
|
+
body: translatedBody,
|
|
2361
2458
|
enHash: currentEnHash,
|
|
2362
2459
|
translatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2363
2460
|
model: result.model,
|
|
@@ -2376,7 +2473,8 @@ async function translatePage(config, item, options = {}) {
|
|
|
2376
2473
|
usage: result.usage,
|
|
2377
2474
|
estimatedCostUsd,
|
|
2378
2475
|
durationMs: Date.now() - startedAt,
|
|
2379
|
-
slugAdjusted
|
|
2476
|
+
slugAdjusted,
|
|
2477
|
+
mdxAdjusted: mdxAdjusted || void 0
|
|
2380
2478
|
};
|
|
2381
2479
|
} catch (error) {
|
|
2382
2480
|
return {
|