scribe-cms 0.0.12 → 0.0.14

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.
Files changed (55) hide show
  1. package/README.md +21 -6
  2. package/dist/cli/index.cjs +1207 -204
  3. package/dist/cli/index.cjs.map +1 -1
  4. package/dist/cli/index.js +1208 -205
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/cli/prompt-translate.d.ts +3 -0
  7. package/dist/cli/prompt-translate.d.ts.map +1 -1
  8. package/dist/cli/translate-progress.d.ts.map +1 -1
  9. package/dist/index.cjs +969 -166
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.js +970 -168
  12. package/dist/index.js.map +1 -1
  13. package/dist/runtime.cjs +136 -62
  14. package/dist/runtime.cjs.map +1 -1
  15. package/dist/runtime.js +136 -62
  16. package/dist/runtime.js.map +1 -1
  17. package/dist/src/config/resolve-config.d.ts.map +1 -1
  18. package/dist/src/core/introspect-schema.d.ts +7 -1
  19. package/dist/src/core/introspect-schema.d.ts.map +1 -1
  20. package/dist/src/core/types.d.ts +6 -0
  21. package/dist/src/core/types.d.ts.map +1 -1
  22. package/dist/src/create-project.d.ts.map +1 -1
  23. package/dist/src/i18n/resolve-document.d.ts +1 -1
  24. package/dist/src/i18n/resolve-document.d.ts.map +1 -1
  25. package/dist/src/index.d.ts +3 -3
  26. package/dist/src/index.d.ts.map +1 -1
  27. package/dist/src/storage/batch-jobs.d.ts +53 -0
  28. package/dist/src/storage/batch-jobs.d.ts.map +1 -0
  29. package/dist/src/storage/sqlite.d.ts.map +1 -1
  30. package/dist/src/translate/batch-worklist.d.ts +87 -0
  31. package/dist/src/translate/batch-worklist.d.ts.map +1 -0
  32. package/dist/src/translate/gemini-batch.d.ts +26 -0
  33. package/dist/src/translate/gemini-batch.d.ts.map +1 -0
  34. package/dist/src/translate/gemini-client.d.ts +18 -0
  35. package/dist/src/translate/gemini-client.d.ts.map +1 -1
  36. package/dist/src/translate/gemini-models.d.ts +9 -0
  37. package/dist/src/translate/gemini-models.d.ts.map +1 -1
  38. package/dist/src/translate/gemini-pricing.d.ts +2 -1
  39. package/dist/src/translate/gemini-pricing.d.ts.map +1 -1
  40. package/dist/src/translate/page-translator.d.ts +25 -52
  41. package/dist/src/translate/page-translator.d.ts.map +1 -1
  42. package/dist/src/translate/prompts/translation-prompt.d.ts +6 -0
  43. package/dist/src/translate/prompts/translation-prompt.d.ts.map +1 -1
  44. package/dist/src/translate/response-schema.d.ts +8 -1
  45. package/dist/src/translate/response-schema.d.ts.map +1 -1
  46. package/dist/src/translate/retry.d.ts +16 -0
  47. package/dist/src/translate/retry.d.ts.map +1 -0
  48. package/dist/src/translate/sanitize-mdx-jsx.d.ts.map +1 -1
  49. package/dist/src/translate/translate-core.d.ts +155 -0
  50. package/dist/src/translate/translate-core.d.ts.map +1 -0
  51. package/dist/studio/server.cjs +84 -47
  52. package/dist/studio/server.cjs.map +1 -1
  53. package/dist/studio/server.js +84 -47
  54. package/dist/studio/server.js.map +1 -1
  55. package/package.json +1 -1
@@ -40,20 +40,16 @@ function getRelationTarget(schema) {
40
40
  }
41
41
  return null;
42
42
  }
43
- function unwrapSchema(schema) {
43
+ function peelOptionalWrappers(schema) {
44
44
  let current = schema;
45
45
  for (let i = 0; i < 8; i++) {
46
- const anySchema = current;
47
- if (typeof anySchema.unwrap === "function") {
48
- current = anySchema.unwrap();
46
+ const type = current._def?.type;
47
+ if (type === "optional" || type === "nullable") {
48
+ current = current.unwrap();
49
49
  continue;
50
50
  }
51
- if (typeof anySchema.removeDefault === "function") {
52
- current = anySchema.removeDefault();
53
- continue;
54
- }
55
- if (anySchema._def?.innerType) {
56
- current = anySchema._def.innerType;
51
+ if (type === "default") {
52
+ current = current.removeDefault();
57
53
  continue;
58
54
  }
59
55
  break;
@@ -62,6 +58,12 @@ function unwrapSchema(schema) {
62
58
  }
63
59
 
64
60
  // src/core/introspect-schema.ts
61
+ function getArrayElement(schema) {
62
+ if (schema instanceof Object && "element" in schema && schema._def?.type === "array") {
63
+ return schema.element;
64
+ }
65
+ return null;
66
+ }
65
67
  function introspectSchema(schema, prefix = []) {
66
68
  const relation = getRelationTarget(schema);
67
69
  if (relation && prefix.length > 0) {
@@ -75,7 +77,10 @@ function introspectSchema(schema, prefix = []) {
75
77
  }
76
78
  ];
77
79
  }
78
- const base = unwrapSchema(schema);
80
+ if (prefix.length > 0 && getFieldKind(schema) === "translatable") {
81
+ return [{ path: prefix, kind: "translatable" }];
82
+ }
83
+ const base = peelOptionalWrappers(schema);
79
84
  if (base instanceof Object && "shape" in base) {
80
85
  const shape = base.shape;
81
86
  const fields = [];
@@ -84,9 +89,9 @@ function introspectSchema(schema, prefix = []) {
84
89
  }
85
90
  return fields;
86
91
  }
87
- if (base instanceof Object && "element" in base) {
88
- const element = base.element;
89
- const elementBase = unwrapSchema(element);
92
+ const element = getArrayElement(base);
93
+ if (element) {
94
+ const elementBase = peelOptionalWrappers(element);
90
95
  if (elementBase instanceof Object && "shape" in elementBase) {
91
96
  const shape = elementBase.shape;
92
97
  const fields = [];
@@ -98,15 +103,48 @@ function introspectSchema(schema, prefix = []) {
98
103
  }
99
104
  return [{ path: prefix, kind: getFieldKind(schema) }];
100
105
  }
101
- function extractByPaths(data, paths) {
102
- const out = {};
106
+ function buildPathTrie(paths) {
107
+ const root = { leaf: false, children: /* @__PURE__ */ new Map() };
103
108
  for (const path4 of paths) {
104
- const value = getAtPath(data, path4);
109
+ let node = root;
110
+ for (const segment of path4) {
111
+ let child = node.children.get(segment);
112
+ if (!child) {
113
+ child = { leaf: false, children: /* @__PURE__ */ new Map() };
114
+ node.children.set(segment, child);
115
+ }
116
+ node = child;
117
+ }
118
+ node.leaf = true;
119
+ }
120
+ return root;
121
+ }
122
+ function extractNode(data, trie) {
123
+ if (trie.leaf) return data;
124
+ const star = trie.children.get("*");
125
+ if (star) {
126
+ if (!Array.isArray(data)) return void 0;
127
+ return data.map(
128
+ (item) => typeof item === "object" && item !== null ? extractNode(item, star) ?? {} : {}
129
+ );
130
+ }
131
+ if (typeof data !== "object" || data === null || Array.isArray(data)) return void 0;
132
+ const record = data;
133
+ const out = {};
134
+ let any = false;
135
+ for (const [key, child] of trie.children) {
136
+ const value = extractNode(record[key], child);
105
137
  if (value !== void 0) {
106
- setAtPath(out, path4.filter((p) => p !== "*"), value);
138
+ out[key] = value;
139
+ any = true;
107
140
  }
108
141
  }
109
- return out;
142
+ return any ? out : void 0;
143
+ }
144
+ function extractByPaths(data, paths) {
145
+ if (paths.length === 0) return {};
146
+ const extracted = extractNode(data, buildPathTrie(paths));
147
+ return extracted && typeof extracted === "object" && !Array.isArray(extracted) ? extracted : {};
110
148
  }
111
149
  function pickTranslatable(data, schema) {
112
150
  const translatablePaths = introspectSchema(schema).filter((f) => f.kind === "translatable").map((f) => f.path);
@@ -121,32 +159,6 @@ function mergeStructuralOntoLocale(localeData, enData, schema) {
121
159
  const translatable = pickTranslatable(localeData, schema);
122
160
  return deepMerge(structural, translatable);
123
161
  }
124
- function getAtPath(obj, path4) {
125
- let current = obj;
126
- for (const segment of path4) {
127
- if (segment === "*") {
128
- if (!Array.isArray(current)) return void 0;
129
- return current.map(
130
- (item) => typeof item === "object" && item !== null ? getAtPath(item, path4.slice(path4.indexOf("*") + 1)) : void 0
131
- );
132
- }
133
- if (typeof current !== "object" || current === null || Array.isArray(current)) return void 0;
134
- current = current[segment];
135
- }
136
- return current;
137
- }
138
- function setAtPath(obj, path4, value) {
139
- if (path4.length === 0) return;
140
- if (path4.length === 1) {
141
- obj[path4[0]] = value;
142
- return;
143
- }
144
- const [head, ...rest] = path4;
145
- if (!(head in obj) || typeof obj[head] !== "object" || obj[head] === null) {
146
- obj[head] = {};
147
- }
148
- setAtPath(obj[head], rest, value);
149
- }
150
162
  function deepMerge(base, overlay) {
151
163
  const out = { ...base };
152
164
  for (const [key, value] of Object.entries(overlay)) {
@@ -366,7 +378,7 @@ function mergeBuiltinsIntoFrontmatter(frontmatter, doc, type, defaultLocale, loc
366
378
  out.canonicalPath = resolveCanonicalPathname(type, doc, defaultLocale, localeRouting);
367
379
  return out;
368
380
  }
369
- var SCHEMA_VERSION = 4;
381
+ var SCHEMA_VERSION = 5;
370
382
  var MIGRATIONS = [
371
383
  `CREATE TABLE IF NOT EXISTS meta (
372
384
  key TEXT PRIMARY KEY,
@@ -414,7 +426,30 @@ var MIGRATIONS = [
414
426
  UNIQUE (content_type, en_slug, en_hash)
415
427
  )`,
416
428
  `CREATE INDEX IF NOT EXISTS idx_en_snapshots_lookup
417
- ON en_snapshots(content_type, en_slug, created_at DESC)`
429
+ ON en_snapshots(content_type, en_slug, created_at DESC)`,
430
+ `CREATE TABLE IF NOT EXISTS translation_batch_jobs (
431
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
432
+ job_name TEXT NOT NULL UNIQUE,
433
+ model TEXT NOT NULL,
434
+ display_model TEXT NOT NULL,
435
+ created_at TEXT NOT NULL,
436
+ state TEXT NOT NULL,
437
+ completed_at TEXT
438
+ )`,
439
+ `CREATE TABLE IF NOT EXISTS translation_batch_items (
440
+ job_id INTEGER NOT NULL,
441
+ request_index INTEGER NOT NULL,
442
+ content_type TEXT NOT NULL,
443
+ en_slug TEXT NOT NULL,
444
+ locale TEXT NOT NULL,
445
+ en_hash TEXT NOT NULL,
446
+ snapshot_id INTEGER NOT NULL,
447
+ status TEXT NOT NULL,
448
+ error TEXT,
449
+ PRIMARY KEY (job_id, request_index)
450
+ )`,
451
+ `CREATE INDEX IF NOT EXISTS idx_batch_items_status
452
+ ON translation_batch_items(status)`
418
453
  ];
419
454
  function resolveStorePath(config) {
420
455
  return config.storePath;
@@ -437,6 +472,8 @@ function addColumnIfMissing(db, table, column, ddlType) {
437
472
  }
438
473
  }
439
474
  function readSchemaVersion(db) {
475
+ const metaTable = db.prepare(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'meta'`).get();
476
+ if (!metaTable) return 0;
440
477
  const row = db.prepare(`SELECT value FROM meta WHERE key = 'schema_version'`).get();
441
478
  return row ? Number.parseInt(row.value, 10) || 0 : 0;
442
479
  }