scribe-cms 0.0.20 → 0.0.22

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/index.cjs CHANGED
@@ -1161,18 +1161,18 @@ function parseTokenInner(inner) {
1161
1161
  }
1162
1162
  case "relation": {
1163
1163
  const parts = rest.split(":");
1164
- if (parts.length < 2 || parts.length > 3) {
1164
+ if (parts.length !== 3) {
1165
1165
  return {
1166
1166
  ok: false,
1167
- reason: `relation must be relation:<typeId>:<enSlug> or relation:<typeId>:<enSlug>:slug`
1167
+ reason: `relation must be relation:<typeId>:<enSlug>:href or relation:<typeId>:<enSlug>:slug`
1168
1168
  };
1169
1169
  }
1170
1170
  const [targetTypeId, enSlug, mode] = parts;
1171
1171
  if (!targetTypeId || !enSlug) {
1172
1172
  return { ok: false, reason: `relation is missing a typeId or enSlug` };
1173
1173
  }
1174
- if (mode !== void 0 && mode !== "slug") {
1175
- return { ok: false, reason: `relation mode must be "slug" (got "${mode}")` };
1174
+ if (mode !== "href" && mode !== "slug") {
1175
+ return { ok: false, reason: `relation mode must be "href" or "slug" (got "${mode}")` };
1176
1176
  }
1177
1177
  return {
1178
1178
  ok: true,
@@ -1180,7 +1180,7 @@ function parseTokenInner(inner) {
1180
1180
  kind: "relation",
1181
1181
  targetTypeId,
1182
1182
  enSlug,
1183
- mode: mode === "slug" ? "slug" : "url"
1183
+ mode
1184
1184
  }
1185
1185
  };
1186
1186
  }
@@ -1286,7 +1286,9 @@ function isStringRecord(value) {
1286
1286
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
1287
1287
  return Object.values(value).every((v) => typeof v === "string");
1288
1288
  }
1289
- function createInlineResolver(config) {
1289
+ function createInlineResolver(config, options = {}) {
1290
+ const linkStyle = options.linkStyle ?? "app";
1291
+ const exportExtension = options.exportExtension ?? ".md";
1290
1292
  const urlBuilder = createUrlBuilder(config);
1291
1293
  const typeById = new Map(config.types.map((t) => [t.id, t]));
1292
1294
  const storePath = resolveStorePath(config);
@@ -1347,7 +1349,10 @@ function createInlineResolver(config) {
1347
1349
  if (token.mode === "slug") return token.enSlug;
1348
1350
  if (!isRoutableType(type)) return "";
1349
1351
  const slug = localizedSlug2(token.targetTypeId, token.enSlug, locale);
1350
- return urlBuilder.resolvePath(type.path, slug, locale);
1352
+ if (linkStyle === "export") {
1353
+ return urlBuilder.resolvePath(type.path, `${slug}${exportExtension}`, locale);
1354
+ }
1355
+ return type.path.replace("{slug}", slug);
1351
1356
  }
1352
1357
  }
1353
1358
  }
@@ -1886,7 +1891,10 @@ function createProject(config, options = {}) {
1886
1891
  }
1887
1892
  return runtime;
1888
1893
  };
1889
- const inlineResolver = options.resolveInlineTokens ? createInlineResolver(config) : void 0;
1894
+ const inlineResolver = options.resolveInlineTokens ? createInlineResolver(config, {
1895
+ linkStyle: options.inlineLinkStyle,
1896
+ exportExtension: options.exportLinkExtension
1897
+ }) : void 0;
1890
1898
  for (const type of config.types) {
1891
1899
  runtimes.set(
1892
1900
  type.id,
@@ -2409,7 +2417,11 @@ async function generateSitemap(project, options) {
2409
2417
  // src/create-scribe.ts
2410
2418
  function createScribe(input) {
2411
2419
  const config = resolveConfig(input);
2412
- const project = createProject(config, { resolveAssets: true, resolveInlineTokens: true });
2420
+ const project = createProject(config, {
2421
+ resolveAssets: true,
2422
+ resolveInlineTokens: true,
2423
+ inlineLinkStyle: "app"
2424
+ });
2413
2425
  const scribe = {
2414
2426
  config,
2415
2427
  project,
@@ -3000,7 +3012,7 @@ function validateInlineTokens(config) {
3000
3012
  });
3001
3013
  break;
3002
3014
  }
3003
- if (token.mode === "url") {
3015
+ if (token.mode === "href") {
3004
3016
  const targetType = typeById.get(token.targetTypeId);
3005
3017
  if (!isRoutableType(targetType)) {
3006
3018
  issues.push({
@@ -3653,10 +3665,10 @@ var LOCALE_NAMES = {
3653
3665
  };
3654
3666
  function defaultLocalizationPrompt(localeName, locale) {
3655
3667
  return [
3656
- `Localize the content above into natural ${localeName} (${locale}).`,
3657
- "Do not translate word-for-word.",
3658
- "Preserve the source tone and brand voice.",
3659
- "Write as if a native speaker authored it for the target market."
3668
+ `Write the content above in natural ${localeName} (${locale}), as if it had been originally authored by a native ${localeName} copywriter for that market.`,
3669
+ `Preserve the source tone and brand voice, but express every idea the way ${localeName} copy actually reads \u2014 never word-for-word.`,
3670
+ `Use native ${localeName} typographic conventions for quotation marks, apostrophes, and spacing around punctuation \u2014 not the source language's.`,
3671
+ `Before returning, re-read each ${localeName} sentence on its own: if it is ambiguous, unidiomatic, or reads like a translation, rewrite it.`
3660
3672
  ].join(" ");
3661
3673
  }
3662
3674
  function buildLocalizationPrompt(promptOverride, localeName, locale) {
@@ -3666,7 +3678,12 @@ function buildLocalizationPrompt(promptOverride, localeName, locale) {
3666
3678
 
3667
3679
  ${localeDirective}`;
3668
3680
  }
3669
- var TASK_FRAMING = "You are localizing the content below into a target language specified at the end of this prompt.";
3681
+ var TASK_FRAMING = [
3682
+ "You are a native-speaker marketing copywriter producing the localized edition of the content below. The target language is specified at the end of this prompt.",
3683
+ "You are NOT translating a document. Each sentence in the source tells you the INTENT \u2014 what it must make the reader feel or understand. Write copy that accomplishes the same thing, the way a native copywriter would have written it from scratch.",
3684
+ "Never mirror the source sentence structure when the target language would naturally phrase the idea differently. Calqued syntax is the #1 failure mode.",
3685
+ "When the source uses wordplay, an idiom, or a punchy rhetorical device, recreate the effect rather than the words. If no natural equivalent exists, write a plain, confident line that carries the same message \u2014 never a literal rendering that sounds odd or ambiguous in the target language."
3686
+ ].join("\n");
3670
3687
  function buildOutputFormatLine(hasFrontmatter, slugStrategy) {
3671
3688
  if (!hasFrontmatter) {
3672
3689
  return slugStrategy === "localized" ? "`body` (string, full MDX body), `slug` (string)." : "`body` (string, full MDX body).";