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.
- package/README.md +21 -6
- package/dist/cli/index.cjs +1207 -204
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +1208 -205
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/prompt-translate.d.ts +3 -0
- package/dist/cli/prompt-translate.d.ts.map +1 -1
- package/dist/cli/translate-progress.d.ts.map +1 -1
- package/dist/index.cjs +969 -166
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +970 -168
- package/dist/index.js.map +1 -1
- package/dist/runtime.cjs +136 -62
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +136 -62
- package/dist/runtime.js.map +1 -1
- package/dist/src/config/resolve-config.d.ts.map +1 -1
- package/dist/src/core/introspect-schema.d.ts +7 -1
- package/dist/src/core/introspect-schema.d.ts.map +1 -1
- package/dist/src/core/types.d.ts +6 -0
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/create-project.d.ts.map +1 -1
- package/dist/src/i18n/resolve-document.d.ts +1 -1
- package/dist/src/i18n/resolve-document.d.ts.map +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/storage/batch-jobs.d.ts +53 -0
- package/dist/src/storage/batch-jobs.d.ts.map +1 -0
- package/dist/src/storage/sqlite.d.ts.map +1 -1
- package/dist/src/translate/batch-worklist.d.ts +87 -0
- package/dist/src/translate/batch-worklist.d.ts.map +1 -0
- package/dist/src/translate/gemini-batch.d.ts +26 -0
- package/dist/src/translate/gemini-batch.d.ts.map +1 -0
- package/dist/src/translate/gemini-client.d.ts +18 -0
- package/dist/src/translate/gemini-client.d.ts.map +1 -1
- package/dist/src/translate/gemini-models.d.ts +9 -0
- package/dist/src/translate/gemini-models.d.ts.map +1 -1
- package/dist/src/translate/gemini-pricing.d.ts +2 -1
- package/dist/src/translate/gemini-pricing.d.ts.map +1 -1
- package/dist/src/translate/page-translator.d.ts +25 -52
- package/dist/src/translate/page-translator.d.ts.map +1 -1
- package/dist/src/translate/prompts/translation-prompt.d.ts +6 -0
- package/dist/src/translate/prompts/translation-prompt.d.ts.map +1 -1
- package/dist/src/translate/response-schema.d.ts +8 -1
- package/dist/src/translate/response-schema.d.ts.map +1 -1
- package/dist/src/translate/retry.d.ts +16 -0
- package/dist/src/translate/retry.d.ts.map +1 -0
- package/dist/src/translate/sanitize-mdx-jsx.d.ts.map +1 -1
- package/dist/src/translate/translate-core.d.ts +155 -0
- package/dist/src/translate/translate-core.d.ts.map +1 -0
- package/dist/studio/server.cjs +84 -47
- package/dist/studio/server.cjs.map +1 -1
- package/dist/studio/server.js +84 -47
- package/dist/studio/server.js.map +1 -1
- package/package.json +1 -1
package/dist/studio/server.js
CHANGED
|
@@ -40,20 +40,16 @@ function getRelationTarget(schema) {
|
|
|
40
40
|
}
|
|
41
41
|
return null;
|
|
42
42
|
}
|
|
43
|
-
function
|
|
43
|
+
function peelOptionalWrappers(schema) {
|
|
44
44
|
let current = schema;
|
|
45
45
|
for (let i = 0; i < 8; i++) {
|
|
46
|
-
const
|
|
47
|
-
if (
|
|
48
|
-
current =
|
|
46
|
+
const type = current._def?.type;
|
|
47
|
+
if (type === "optional" || type === "nullable") {
|
|
48
|
+
current = current.unwrap();
|
|
49
49
|
continue;
|
|
50
50
|
}
|
|
51
|
-
if (
|
|
52
|
-
current =
|
|
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
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
const elementBase =
|
|
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
|
|
102
|
-
const
|
|
106
|
+
function buildPathTrie(paths) {
|
|
107
|
+
const root = { leaf: false, children: /* @__PURE__ */ new Map() };
|
|
103
108
|
for (const path4 of paths) {
|
|
104
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
}
|