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.js
CHANGED
|
@@ -1208,6 +1208,9 @@ function createProject(config) {
|
|
|
1208
1208
|
getType: getRuntime,
|
|
1209
1209
|
listTypes() {
|
|
1210
1210
|
return Array.from(runtimes.values());
|
|
1211
|
+
},
|
|
1212
|
+
listRoutableTypes() {
|
|
1213
|
+
return Array.from(runtimes.values()).filter((runtime) => isRoutableType(runtime.config));
|
|
1211
1214
|
}
|
|
1212
1215
|
};
|
|
1213
1216
|
}
|
|
@@ -2153,11 +2156,12 @@ init_esm_shims();
|
|
|
2153
2156
|
function slugStrategyRules(slugStrategy, preserveTerms) {
|
|
2154
2157
|
if (slugStrategy === "localized") {
|
|
2155
2158
|
const rules = [
|
|
2156
|
-
"Provide a URL slug in JSON field `slug` that is
|
|
2159
|
+
"Provide a URL slug in JSON field `slug` that is Localized into the target language.",
|
|
2157
2160
|
"Base the slug on the meaning of the translated title \u2014 do NOT reuse the English slug words.",
|
|
2158
2161
|
"Slug MUST be ASCII only: a-z, 0-9, hyphens. No uppercase, accents, underscores, or spaces.",
|
|
2159
2162
|
"For non-Latin languages, write the words in the target language and transliterate them into Latin script (e.g. Russian -> romanized Russian, not English).",
|
|
2160
|
-
"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."
|
|
2163
|
+
"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.",
|
|
2164
|
+
'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 \\".'
|
|
2161
2165
|
];
|
|
2162
2166
|
if (preserveTerms?.length) {
|
|
2163
2167
|
rules.push(
|
|
@@ -2190,6 +2194,96 @@ function resolveTranslateConfig(config, type) {
|
|
|
2190
2194
|
return mergeTranslateConfig(config.translate, type.translate, type.slugStrategy);
|
|
2191
2195
|
}
|
|
2192
2196
|
|
|
2197
|
+
// src/translate/sanitize-mdx-jsx.ts
|
|
2198
|
+
init_esm_shims();
|
|
2199
|
+
function sanitizeMdxJsxAttributeQuotes(body) {
|
|
2200
|
+
let adjusted = false;
|
|
2201
|
+
let out = "";
|
|
2202
|
+
let i = 0;
|
|
2203
|
+
while (i < body.length) {
|
|
2204
|
+
if (body[i] !== "<" || !/[\w.]/.test(body[i + 1] ?? "")) {
|
|
2205
|
+
out += body[i];
|
|
2206
|
+
i += 1;
|
|
2207
|
+
continue;
|
|
2208
|
+
}
|
|
2209
|
+
const tagStart = i;
|
|
2210
|
+
i += 1;
|
|
2211
|
+
while (i < body.length && /[\w.-]/.test(body[i] ?? "")) i += 1;
|
|
2212
|
+
const tagName = body.slice(tagStart + 1, i);
|
|
2213
|
+
let tagOut = `<${tagName}`;
|
|
2214
|
+
let tagAdjusted = false;
|
|
2215
|
+
while (i < body.length && body[i] !== ">" && body[i] !== "/") {
|
|
2216
|
+
while (i < body.length && /\s/.test(body[i] ?? "")) {
|
|
2217
|
+
tagOut += body[i];
|
|
2218
|
+
i += 1;
|
|
2219
|
+
}
|
|
2220
|
+
if (i >= body.length || body[i] === ">" || body[i] === "/") break;
|
|
2221
|
+
const attrStart = i;
|
|
2222
|
+
while (i < body.length && /[\w:.-]/.test(body[i] ?? "")) i += 1;
|
|
2223
|
+
body.slice(attrStart, i);
|
|
2224
|
+
while (i < body.length && /\s/.test(body[i] ?? "")) i += 1;
|
|
2225
|
+
if (body[i] !== "=") {
|
|
2226
|
+
tagOut += body.slice(attrStart, i);
|
|
2227
|
+
continue;
|
|
2228
|
+
}
|
|
2229
|
+
tagOut += body.slice(attrStart, i);
|
|
2230
|
+
tagOut += "=";
|
|
2231
|
+
i += 1;
|
|
2232
|
+
while (i < body.length && /\s/.test(body[i] ?? "")) i += 1;
|
|
2233
|
+
const quote = body[i];
|
|
2234
|
+
if (quote !== '"' && quote !== "'") {
|
|
2235
|
+
continue;
|
|
2236
|
+
}
|
|
2237
|
+
if (quote === "'") {
|
|
2238
|
+
const valStart2 = i + 1;
|
|
2239
|
+
i += 1;
|
|
2240
|
+
while (i < body.length) {
|
|
2241
|
+
if (body[i] === "\\") {
|
|
2242
|
+
i += 2;
|
|
2243
|
+
continue;
|
|
2244
|
+
}
|
|
2245
|
+
if (body[i] === "'") break;
|
|
2246
|
+
i += 1;
|
|
2247
|
+
}
|
|
2248
|
+
tagOut += body.slice(valStart2 - 1, i + 1);
|
|
2249
|
+
i += 1;
|
|
2250
|
+
continue;
|
|
2251
|
+
}
|
|
2252
|
+
const valStart = i + 1;
|
|
2253
|
+
i += 1;
|
|
2254
|
+
let closeIdx = -1;
|
|
2255
|
+
for (let scan = valStart; scan < body.length; scan += 1) {
|
|
2256
|
+
if (body[scan] !== '"') continue;
|
|
2257
|
+
let j = scan + 1;
|
|
2258
|
+
while (j < body.length && /\s/.test(body[j] ?? "")) j += 1;
|
|
2259
|
+
if (j < body.length && (body[j] === ">" || body[j] === "/" || /[a-zA-Z]/.test(body[j] ?? ""))) {
|
|
2260
|
+
closeIdx = scan;
|
|
2261
|
+
break;
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
if (closeIdx === -1) {
|
|
2265
|
+
tagOut += body.slice(valStart - 1, i);
|
|
2266
|
+
break;
|
|
2267
|
+
}
|
|
2268
|
+
const value = body.slice(valStart, closeIdx);
|
|
2269
|
+
const hasInternalQuote = value.includes('"');
|
|
2270
|
+
if (hasInternalQuote) {
|
|
2271
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
2272
|
+
tagOut += `'${escaped}'`;
|
|
2273
|
+
tagAdjusted = true;
|
|
2274
|
+
} else {
|
|
2275
|
+
tagOut += `"${value}"`;
|
|
2276
|
+
}
|
|
2277
|
+
i = closeIdx + 1;
|
|
2278
|
+
}
|
|
2279
|
+
if (tagAdjusted) adjusted = true;
|
|
2280
|
+
tagOut += body[i] ?? "";
|
|
2281
|
+
out += tagOut;
|
|
2282
|
+
i += 1;
|
|
2283
|
+
}
|
|
2284
|
+
return { body: out, adjusted };
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2193
2287
|
// src/translate/validate-translation.ts
|
|
2194
2288
|
init_esm_shims();
|
|
2195
2289
|
function formatZodIssues(error) {
|
|
@@ -2324,6 +2418,9 @@ async function translatePage(config, item, options = {}) {
|
|
|
2324
2418
|
if (!validated.ok) {
|
|
2325
2419
|
throw new Error(`Translation validation failed: ${validated.error}`);
|
|
2326
2420
|
}
|
|
2421
|
+
const { body: translatedBody, adjusted: mdxAdjusted } = sanitizeMdxJsxAttributeQuotes(
|
|
2422
|
+
result.parsed.body
|
|
2423
|
+
);
|
|
2327
2424
|
const writeDb = openStore(config, "readwrite");
|
|
2328
2425
|
const snapshotId = recordEnSnapshot(
|
|
2329
2426
|
config,
|
|
@@ -2342,7 +2439,7 @@ async function translatePage(config, item, options = {}) {
|
|
|
2342
2439
|
locale: item.locale,
|
|
2343
2440
|
slug,
|
|
2344
2441
|
frontmatter: validated.frontmatter,
|
|
2345
|
-
body:
|
|
2442
|
+
body: translatedBody,
|
|
2346
2443
|
enHash: currentEnHash,
|
|
2347
2444
|
translatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2348
2445
|
model: result.model,
|
|
@@ -2361,7 +2458,8 @@ async function translatePage(config, item, options = {}) {
|
|
|
2361
2458
|
usage: result.usage,
|
|
2362
2459
|
estimatedCostUsd,
|
|
2363
2460
|
durationMs: Date.now() - startedAt,
|
|
2364
|
-
slugAdjusted
|
|
2461
|
+
slugAdjusted,
|
|
2462
|
+
mdxAdjusted: mdxAdjusted || void 0
|
|
2365
2463
|
};
|
|
2366
2464
|
} catch (error) {
|
|
2367
2465
|
return {
|