@blinkk/root-cms 2.4.10 → 2.5.1
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/ai-OZY3JXDH.js +19 -0
- package/dist/app.js +2 -2
- package/dist/{chunk-Y65VGJLE.js → chunk-KTUENARU.js} +2 -2
- package/dist/{chunk-62EVNFXB.js → chunk-NUUABQRN.js} +61 -0
- package/dist/{chunk-SI44FG3H.js → chunk-RIJF2AHU.js} +1 -1
- package/dist/chunk-RNDSZKAW.js +171 -0
- package/dist/{chunk-ZOEPOKGE.js → chunk-T5UK2H24.js} +131 -6
- package/dist/cli.js +1 -1
- package/dist/{client-PhodvL2Q.d.ts → client-ROwBDNeR.d.ts} +8 -1
- package/dist/client.d.ts +2 -2
- package/dist/client.js +1 -1
- package/dist/core.d.ts +3 -3
- package/dist/core.js +10 -1
- package/dist/functions.js +2 -2
- package/dist/plugin.d.ts +2 -2
- package/dist/plugin.js +83 -5
- package/dist/project.d.ts +1 -1
- package/dist/project.js +1 -1
- package/dist/{schema-Bux4PrV2.d.ts → schema-BKfPP_s9.d.ts} +78 -2
- package/dist/ui/ui.css +1 -1
- package/dist/ui/ui.js +150 -150
- package/dist/ui/ui.js.LEGAL.txt +14 -12
- package/package.json +3 -3
- package/dist/ai-DRQJXU4N.js +0 -13
- package/dist/chunk-377TGNX2.js +0 -82
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Chat,
|
|
3
|
+
ChatClient,
|
|
4
|
+
extractJsonFromResponse,
|
|
5
|
+
generateImage,
|
|
6
|
+
generatePublishMessage,
|
|
7
|
+
summarizeDiff,
|
|
8
|
+
translateString
|
|
9
|
+
} from "./chunk-T5UK2H24.js";
|
|
10
|
+
import "./chunk-MLKGABMK.js";
|
|
11
|
+
export {
|
|
12
|
+
Chat,
|
|
13
|
+
ChatClient,
|
|
14
|
+
extractJsonFromResponse,
|
|
15
|
+
generateImage,
|
|
16
|
+
generatePublishMessage,
|
|
17
|
+
summarizeDiff,
|
|
18
|
+
translateString
|
|
19
|
+
};
|
package/dist/app.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getServerVersion
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KTUENARU.js";
|
|
4
4
|
import {
|
|
5
5
|
getCollectionSchema,
|
|
6
6
|
getProjectSchemas
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-RNDSZKAW.js";
|
|
8
8
|
import "./chunk-MLKGABMK.js";
|
|
9
9
|
|
|
10
10
|
// core/app.tsx
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "@blinkk/root-cms",
|
|
4
|
-
version: "2.
|
|
4
|
+
version: "2.5.1",
|
|
5
5
|
author: "s@blinkk.com",
|
|
6
6
|
license: "MIT",
|
|
7
7
|
engines: {
|
|
@@ -166,7 +166,7 @@ var package_default = {
|
|
|
166
166
|
yjs: "13.6.27"
|
|
167
167
|
},
|
|
168
168
|
peerDependencies: {
|
|
169
|
-
"@blinkk/root": "2.
|
|
169
|
+
"@blinkk/root": "2.5.1",
|
|
170
170
|
"firebase-admin": ">=11",
|
|
171
171
|
"firebase-functions": ">=4",
|
|
172
172
|
preact: ">=10",
|
|
@@ -964,6 +964,67 @@ ${errorMessages}`);
|
|
|
964
964
|
console.log(`published ${publishedDocs.length} docs!`);
|
|
965
965
|
return publishedDocs;
|
|
966
966
|
}
|
|
967
|
+
/**
|
|
968
|
+
* Batch unpublishes a set of docs by id.
|
|
969
|
+
*/
|
|
970
|
+
async unpublishDocs(docIds, options) {
|
|
971
|
+
const projectCollectionsPath = `Projects/${this.projectId}/Collections`;
|
|
972
|
+
const unpublishedBy = options?.unpublishedBy || "root-cms-client";
|
|
973
|
+
const docRefs = docIds.map((docId) => {
|
|
974
|
+
const [collection, slug] = docId.split("/");
|
|
975
|
+
if (!collection || !slug) {
|
|
976
|
+
throw new Error(`invalid doc id: ${docId}`);
|
|
977
|
+
}
|
|
978
|
+
const docRef = this.db.doc(
|
|
979
|
+
`${projectCollectionsPath}/${collection}/Drafts/${slug}`
|
|
980
|
+
);
|
|
981
|
+
return docRef;
|
|
982
|
+
});
|
|
983
|
+
const docSnapshots = await this.db.getAll(...docRefs);
|
|
984
|
+
const docs = docSnapshots.map((snapshot) => snapshot.data()).filter((d) => !!d);
|
|
985
|
+
if (docs.length === 0) {
|
|
986
|
+
console.log("no docs to unpublish");
|
|
987
|
+
return [];
|
|
988
|
+
}
|
|
989
|
+
let batchCount = 0;
|
|
990
|
+
const batch = options?.batch || this.db.batch();
|
|
991
|
+
const unpublishedDocs = [];
|
|
992
|
+
for (const doc of docs) {
|
|
993
|
+
const { id, collection, slug } = doc;
|
|
994
|
+
const draftRef = this.db.doc(
|
|
995
|
+
`${projectCollectionsPath}/${collection}/Drafts/${slug}`
|
|
996
|
+
);
|
|
997
|
+
const scheduledRef = this.db.doc(
|
|
998
|
+
`${projectCollectionsPath}/${collection}/Scheduled/${slug}`
|
|
999
|
+
);
|
|
1000
|
+
const publishedRef = this.db.doc(
|
|
1001
|
+
`${projectCollectionsPath}/${collection}/Published/${slug}`
|
|
1002
|
+
);
|
|
1003
|
+
batch.update(draftRef, {
|
|
1004
|
+
"sys.modifiedAt": FieldValue2.serverTimestamp(),
|
|
1005
|
+
"sys.modifiedBy": unpublishedBy,
|
|
1006
|
+
"sys.publishedAt": FieldValue2.delete(),
|
|
1007
|
+
"sys.publishedBy": FieldValue2.delete(),
|
|
1008
|
+
"sys.firstPublishedAt": FieldValue2.delete(),
|
|
1009
|
+
"sys.firstPublishedBy": FieldValue2.delete()
|
|
1010
|
+
});
|
|
1011
|
+
batchCount += 1;
|
|
1012
|
+
batch.delete(scheduledRef);
|
|
1013
|
+
batchCount += 1;
|
|
1014
|
+
batch.delete(publishedRef);
|
|
1015
|
+
batchCount += 1;
|
|
1016
|
+
unpublishedDocs.push(doc);
|
|
1017
|
+
if (batchCount >= 400) {
|
|
1018
|
+
await batch.commit();
|
|
1019
|
+
batchCount = 0;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
if (batchCount > 0) {
|
|
1023
|
+
await batch.commit();
|
|
1024
|
+
}
|
|
1025
|
+
console.log(`unpublished ${unpublishedDocs.length} docs!`);
|
|
1026
|
+
return unpublishedDocs;
|
|
1027
|
+
}
|
|
967
1028
|
/**
|
|
968
1029
|
* Publishes scheduled docs.
|
|
969
1030
|
*/
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// core/project.ts
|
|
2
|
+
var SCHEMA_MODULES = import.meta.glob(
|
|
3
|
+
[
|
|
4
|
+
"/**/*.schema.ts",
|
|
5
|
+
"!/appengine/**/*.schema.ts",
|
|
6
|
+
"!/functions/**/*.schema.ts",
|
|
7
|
+
"!/gae/**/*.schema.ts"
|
|
8
|
+
],
|
|
9
|
+
{ eager: true }
|
|
10
|
+
);
|
|
11
|
+
async function getProjectSchemas() {
|
|
12
|
+
const schemas = {};
|
|
13
|
+
for (const fileId in SCHEMA_MODULES) {
|
|
14
|
+
const schemaModule = SCHEMA_MODULES[fileId];
|
|
15
|
+
if (schemaModule.default) {
|
|
16
|
+
const resolved = resolveOneOfPatterns(schemaModule.default);
|
|
17
|
+
schemas[fileId] = resolved;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return schemas;
|
|
21
|
+
}
|
|
22
|
+
function resolveOneOfPatterns(schemaObj) {
|
|
23
|
+
const clone = structuredClone(schemaObj);
|
|
24
|
+
function handleField(field) {
|
|
25
|
+
if (field.type === "oneof") {
|
|
26
|
+
const oneOfField = field;
|
|
27
|
+
if (isSchemaPattern(oneOfField.types)) {
|
|
28
|
+
const resolved = resolveSchemaPattern(oneOfField.types);
|
|
29
|
+
oneOfField.types = resolved.names.map((name) => resolved.schemas[name]);
|
|
30
|
+
}
|
|
31
|
+
} else if (field.type === "object" && "fields" in field) {
|
|
32
|
+
(field.fields || []).forEach(handleField);
|
|
33
|
+
} else if (field.type === "array" && "of" in field && field.of) {
|
|
34
|
+
handleField(field.of);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
(clone.fields || []).forEach(handleField);
|
|
38
|
+
return clone;
|
|
39
|
+
}
|
|
40
|
+
async function getCollectionSchema(collectionId) {
|
|
41
|
+
if (!testValidCollectionId(collectionId)) {
|
|
42
|
+
throw new Error(`invalid collection id: ${collectionId}`);
|
|
43
|
+
}
|
|
44
|
+
const fileId = `/collections/${collectionId}.schema.ts`;
|
|
45
|
+
const module = SCHEMA_MODULES[fileId];
|
|
46
|
+
if (!module.default) {
|
|
47
|
+
console.warn(`collection schema not exported in: ${fileId}`);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
const collection = module.default;
|
|
51
|
+
collection.id = collectionId;
|
|
52
|
+
return convertOneOfTypes(collection);
|
|
53
|
+
}
|
|
54
|
+
function testValidCollectionId(id) {
|
|
55
|
+
return /^[A-Za-z0-9_-]+$/.test(id);
|
|
56
|
+
}
|
|
57
|
+
function isSchemaPattern(value) {
|
|
58
|
+
return typeof value === "object" && value !== null && "_schemaPattern" in value && value._schemaPattern === true;
|
|
59
|
+
}
|
|
60
|
+
function buildSchemaNameMap() {
|
|
61
|
+
const nameMap = {};
|
|
62
|
+
for (const fileId in SCHEMA_MODULES) {
|
|
63
|
+
const module = SCHEMA_MODULES[fileId];
|
|
64
|
+
if (module.default && module.default.name) {
|
|
65
|
+
nameMap[module.default.name] = module.default;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return nameMap;
|
|
69
|
+
}
|
|
70
|
+
function globToRegex(pattern) {
|
|
71
|
+
const regexStr = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "{{DOUBLE_STAR}}").replace(/\*/g, "[^/]*").replace(/\{\{DOUBLE_STAR\}\}/g, ".*");
|
|
72
|
+
return new RegExp(`^${regexStr}$`);
|
|
73
|
+
}
|
|
74
|
+
function resolveSchemaPattern(pattern) {
|
|
75
|
+
const regex = globToRegex(pattern.pattern);
|
|
76
|
+
const excludeSet = new Set(pattern.exclude || []);
|
|
77
|
+
const names = [];
|
|
78
|
+
const schemas = {};
|
|
79
|
+
for (const fileId in SCHEMA_MODULES) {
|
|
80
|
+
if (!regex.test(fileId)) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const module = SCHEMA_MODULES[fileId];
|
|
84
|
+
if (!module.default || !module.default.name) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const schemaName = module.default.name;
|
|
88
|
+
if (excludeSet.has(schemaName)) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
let schemaObj = module.default;
|
|
92
|
+
if (pattern.omitFields && pattern.omitFields.length > 0) {
|
|
93
|
+
const omitSet = new Set(pattern.omitFields);
|
|
94
|
+
schemaObj = {
|
|
95
|
+
...schemaObj,
|
|
96
|
+
fields: schemaObj.fields.filter(
|
|
97
|
+
(f) => !omitSet.has(f.id || "")
|
|
98
|
+
)
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
names.push(schemaName);
|
|
102
|
+
schemas[schemaName] = schemaObj;
|
|
103
|
+
}
|
|
104
|
+
return { names, schemas };
|
|
105
|
+
}
|
|
106
|
+
function convertOneOfTypes(collection) {
|
|
107
|
+
const clone = structuredClone(collection);
|
|
108
|
+
const types = clone.types || {};
|
|
109
|
+
const schemaNameMap = buildSchemaNameMap();
|
|
110
|
+
function handleOneOfField(field) {
|
|
111
|
+
if (isSchemaPattern(field.types)) {
|
|
112
|
+
const resolved = resolveSchemaPattern(field.types);
|
|
113
|
+
for (const [name, schemaObj] of Object.entries(resolved.schemas)) {
|
|
114
|
+
if (!types[name]) {
|
|
115
|
+
types[name] = schemaObj;
|
|
116
|
+
if (schemaObj.fields) {
|
|
117
|
+
walk(schemaObj);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
field.types = resolved.names;
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const names = [];
|
|
125
|
+
(field.types || []).forEach((sub) => {
|
|
126
|
+
if (typeof sub === "string") {
|
|
127
|
+
names.push(sub);
|
|
128
|
+
if (!types[sub] && schemaNameMap[sub]) {
|
|
129
|
+
const resolvedSchema = schemaNameMap[sub];
|
|
130
|
+
types[sub] = resolvedSchema;
|
|
131
|
+
if (resolvedSchema.fields) {
|
|
132
|
+
walk(resolvedSchema);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (sub.name) {
|
|
138
|
+
names.push(sub.name);
|
|
139
|
+
if (!types[sub.name]) {
|
|
140
|
+
types[sub.name] = sub;
|
|
141
|
+
if (sub.fields) {
|
|
142
|
+
walk(sub);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
field.types = names;
|
|
148
|
+
}
|
|
149
|
+
function handleField(field) {
|
|
150
|
+
if (field.type === "oneof") {
|
|
151
|
+
handleOneOfField(field);
|
|
152
|
+
} else if (field.type === "object") {
|
|
153
|
+
walk(field);
|
|
154
|
+
} else if (field.type === "array" && field.of) {
|
|
155
|
+
handleField(field.of);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function walk(schema) {
|
|
159
|
+
const fields = schema?.fields || [];
|
|
160
|
+
fields.forEach(handleField);
|
|
161
|
+
}
|
|
162
|
+
walk(clone);
|
|
163
|
+
clone.types = types;
|
|
164
|
+
return clone;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export {
|
|
168
|
+
SCHEMA_MODULES,
|
|
169
|
+
getProjectSchemas,
|
|
170
|
+
getCollectionSchema
|
|
171
|
+
};
|
|
@@ -14,6 +14,49 @@ var LEGACY_MODEL_RENAME = {
|
|
|
14
14
|
"vertexai/gemini-2.0-pro": "gemini-2.0-pro"
|
|
15
15
|
};
|
|
16
16
|
async function summarizeDiff(cmsClient, options) {
|
|
17
|
+
const cmsPluginOptions = cmsClient.cmsPlugin.getConfig();
|
|
18
|
+
const firebaseConfig = cmsPluginOptions.firebaseConfig;
|
|
19
|
+
const model = "gemini-2.5-flash";
|
|
20
|
+
const ai = genkit({
|
|
21
|
+
plugins: [
|
|
22
|
+
vertexAI({
|
|
23
|
+
projectId: firebaseConfig.projectId,
|
|
24
|
+
location: firebaseConfig.location || "us-central1"
|
|
25
|
+
})
|
|
26
|
+
]
|
|
27
|
+
});
|
|
28
|
+
const beforeJson = JSON.stringify(options.before ?? null, null, 2);
|
|
29
|
+
const afterJson = JSON.stringify(options.after ?? null, null, 2);
|
|
30
|
+
const systemPrompt = [
|
|
31
|
+
"Summarize CMS document changes in 2-4 bullet points.",
|
|
32
|
+
"Focus on content changes only. Ignore metadata like timestamps.",
|
|
33
|
+
'If no meaningful changes, say "No significant changes."'
|
|
34
|
+
].join("\n");
|
|
35
|
+
const diffPrompt = [
|
|
36
|
+
"Before:",
|
|
37
|
+
beforeJson,
|
|
38
|
+
"",
|
|
39
|
+
"After:",
|
|
40
|
+
afterJson,
|
|
41
|
+
"",
|
|
42
|
+
"What changed?"
|
|
43
|
+
].join("\n");
|
|
44
|
+
const res = await generate(ai, model, {
|
|
45
|
+
messages: [
|
|
46
|
+
{
|
|
47
|
+
role: "system",
|
|
48
|
+
content: [{ text: systemPrompt }]
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
prompt: [{ text: diffPrompt }],
|
|
52
|
+
config: {
|
|
53
|
+
// Respond more quickly with less creativity.
|
|
54
|
+
temperature: 0.3
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return res.text?.trim() || "";
|
|
58
|
+
}
|
|
59
|
+
async function generatePublishMessage(cmsClient, options) {
|
|
17
60
|
const cmsPluginOptions = cmsClient.cmsPlugin.getConfig();
|
|
18
61
|
const firebaseConfig = cmsPluginOptions.firebaseConfig;
|
|
19
62
|
const model = (typeof cmsPluginOptions.experiments?.ai === "object" ? cmsPluginOptions.experiments.ai.model : void 0) || DEFAULT_MODEL;
|
|
@@ -28,10 +71,13 @@ async function summarizeDiff(cmsClient, options) {
|
|
|
28
71
|
const beforeJson = JSON.stringify(options.before ?? null, null, 2);
|
|
29
72
|
const afterJson = JSON.stringify(options.after ?? null, null, 2);
|
|
30
73
|
const systemPrompt = [
|
|
31
|
-
"You are an assistant that
|
|
32
|
-
"
|
|
33
|
-
'
|
|
34
|
-
|
|
74
|
+
"You are an assistant that generates concise commit-style messages for CMS document changes.",
|
|
75
|
+
"Generate a single short sentence (maximum 60 characters) describing the most important change.",
|
|
76
|
+
'Use imperative mood like "Add feature" or "Update content" or "Fix typo".',
|
|
77
|
+
"Focus on the key content change, ignore structural metadata changes.",
|
|
78
|
+
"Do not use punctuation at the end.",
|
|
79
|
+
'Examples: "Add new hero image", "Update pricing details", "Fix typo in headline"',
|
|
80
|
+
"Include "
|
|
35
81
|
].join("\n");
|
|
36
82
|
const diffPrompt = [
|
|
37
83
|
"Previous version JSON:",
|
|
@@ -44,7 +90,7 @@ async function summarizeDiff(cmsClient, options) {
|
|
|
44
90
|
afterJson,
|
|
45
91
|
"```",
|
|
46
92
|
"",
|
|
47
|
-
"
|
|
93
|
+
"Generate a commit message for these changes."
|
|
48
94
|
].join("\n");
|
|
49
95
|
const res = await generate(ai, model, {
|
|
50
96
|
messages: [
|
|
@@ -285,10 +331,89 @@ var ChatClient = class {
|
|
|
285
331
|
function cleanModelName(model) {
|
|
286
332
|
return LEGACY_MODEL_RENAME[model] || model;
|
|
287
333
|
}
|
|
334
|
+
function extractJsonFromResponse(responseText) {
|
|
335
|
+
let jsonText = responseText.trim();
|
|
336
|
+
if (jsonText.startsWith("```")) {
|
|
337
|
+
const lines = jsonText.split("\n");
|
|
338
|
+
jsonText = lines.slice(1, -1).join("\n");
|
|
339
|
+
if (jsonText.startsWith("json")) {
|
|
340
|
+
jsonText = jsonText.substring(4).trim();
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return jsonText;
|
|
344
|
+
}
|
|
345
|
+
async function translateString(cmsClient, options) {
|
|
346
|
+
const cmsPluginOptions = cmsClient.cmsPlugin.getConfig();
|
|
347
|
+
const firebaseConfig = cmsPluginOptions.firebaseConfig;
|
|
348
|
+
const model = (typeof cmsPluginOptions.experiments?.ai === "object" ? cmsPluginOptions.experiments.ai.model : void 0) || DEFAULT_MODEL;
|
|
349
|
+
const ai = genkit({
|
|
350
|
+
plugins: [
|
|
351
|
+
vertexAI({
|
|
352
|
+
projectId: firebaseConfig.projectId,
|
|
353
|
+
location: firebaseConfig.location || "us-central1"
|
|
354
|
+
})
|
|
355
|
+
]
|
|
356
|
+
});
|
|
357
|
+
const systemPrompt = [
|
|
358
|
+
"You are a professional translator assistant.",
|
|
359
|
+
"Translate the given source text into the requested target languages.",
|
|
360
|
+
"Maintain the tone, style, and intent of the original text.",
|
|
361
|
+
"Return ONLY a valid JSON object with locale codes as keys and translations as values.",
|
|
362
|
+
"Do not include any markdown formatting, code blocks, or explanatory text."
|
|
363
|
+
].join("\n");
|
|
364
|
+
const userPromptParts = [
|
|
365
|
+
`Source text: "${options.sourceText}"`,
|
|
366
|
+
""
|
|
367
|
+
];
|
|
368
|
+
if (options.description) {
|
|
369
|
+
userPromptParts.push(`Context/Description: ${options.description}`, "");
|
|
370
|
+
}
|
|
371
|
+
if (options.existingTranslations && Object.keys(options.existingTranslations).length > 0) {
|
|
372
|
+
userPromptParts.push("Existing translations for reference:");
|
|
373
|
+
Object.entries(options.existingTranslations).forEach(
|
|
374
|
+
([locale, translation]) => {
|
|
375
|
+
if (translation) {
|
|
376
|
+
userPromptParts.push(`- ${locale}: "${translation}"`);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
);
|
|
380
|
+
userPromptParts.push("");
|
|
381
|
+
}
|
|
382
|
+
userPromptParts.push(
|
|
383
|
+
`Target locales: ${options.targetLocales.join(", ")}`,
|
|
384
|
+
"",
|
|
385
|
+
"Provide translations as a JSON object with locale codes as keys."
|
|
386
|
+
);
|
|
387
|
+
const userPrompt = userPromptParts.join("\n");
|
|
388
|
+
const res = await generate(ai, model, {
|
|
389
|
+
messages: [
|
|
390
|
+
{
|
|
391
|
+
role: "system",
|
|
392
|
+
content: [{ text: systemPrompt }]
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
role: "user",
|
|
396
|
+
content: [{ text: userPrompt }]
|
|
397
|
+
}
|
|
398
|
+
]
|
|
399
|
+
});
|
|
400
|
+
const responseText = res.text || "{}";
|
|
401
|
+
const jsonText = extractJsonFromResponse(responseText);
|
|
402
|
+
try {
|
|
403
|
+
const translations = JSON.parse(jsonText);
|
|
404
|
+
return translations;
|
|
405
|
+
} catch (err) {
|
|
406
|
+
console.error("Failed to parse AI translation response:", responseText);
|
|
407
|
+
throw new Error("Invalid response format from AI translation");
|
|
408
|
+
}
|
|
409
|
+
}
|
|
288
410
|
|
|
289
411
|
export {
|
|
290
412
|
summarizeDiff,
|
|
413
|
+
generatePublishMessage,
|
|
291
414
|
generateImage,
|
|
292
415
|
Chat,
|
|
293
|
-
ChatClient
|
|
416
|
+
ChatClient,
|
|
417
|
+
extractJsonFromResponse,
|
|
418
|
+
translateString
|
|
294
419
|
};
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Plugin, Request, RootConfig } from '@blinkk/root';
|
|
2
2
|
import { App } from 'firebase-admin/app';
|
|
3
3
|
import { Firestore, WriteBatch, Timestamp, Query } from 'firebase-admin/firestore';
|
|
4
|
-
import { C as Collection } from './schema-
|
|
4
|
+
import { C as Collection } from './schema-BKfPP_s9.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Supported Root AI models. Defaults to 'gemini-3-flash-preview'.
|
|
@@ -613,6 +613,13 @@ declare class RootCMSClient {
|
|
|
613
613
|
batch?: WriteBatch;
|
|
614
614
|
releaseId?: string;
|
|
615
615
|
}): Promise<any[]>;
|
|
616
|
+
/**
|
|
617
|
+
* Batch unpublishes a set of docs by id.
|
|
618
|
+
*/
|
|
619
|
+
unpublishDocs(docIds: string[], options?: {
|
|
620
|
+
unpublishedBy?: string;
|
|
621
|
+
batch?: WriteBatch;
|
|
622
|
+
}): Promise<any[]>;
|
|
616
623
|
/**
|
|
617
624
|
* Publishes scheduled docs.
|
|
618
625
|
*/
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '@blinkk/root';
|
|
2
2
|
import 'firebase-admin/app';
|
|
3
3
|
import 'firebase-admin/firestore';
|
|
4
|
-
export { A as Action, q as ArrayObject, C as BatchRequest, B as BatchRequestOptions, x as BatchRequestQuery, y as BatchRequestQueryOptions, E as BatchResponse, c as DataSource, d as DataSourceData, e as DataSourceMode, b as Doc, D as DocMode, i as GetCountOptions, G as GetDocOptions, H as HttpMethod, l as ListActionsOptions, h as ListDocsOptions, L as LoadTranslationsOptions, a as LocaleTranslations, k as Release, R as RootCMSClient, f as SaveDraftOptions, S as SetDocOptions, j as Translation, z as TranslationsDoc, T as TranslationsMap, g as UpdateDraftOptions, U as UserRole, n as getCmsPlugin, m as isRichTextData, r as marshalArray, o as marshalData, p as normalizeData, w as parseDocId, t as toArrayObject, v as translationsForLocale, s as unmarshalArray, u as unmarshalData } from './client-
|
|
5
|
-
import './schema-
|
|
4
|
+
export { A as Action, q as ArrayObject, C as BatchRequest, B as BatchRequestOptions, x as BatchRequestQuery, y as BatchRequestQueryOptions, E as BatchResponse, c as DataSource, d as DataSourceData, e as DataSourceMode, b as Doc, D as DocMode, i as GetCountOptions, G as GetDocOptions, H as HttpMethod, l as ListActionsOptions, h as ListDocsOptions, L as LoadTranslationsOptions, a as LocaleTranslations, k as Release, R as RootCMSClient, f as SaveDraftOptions, S as SetDocOptions, j as Translation, z as TranslationsDoc, T as TranslationsMap, g as UpdateDraftOptions, U as UserRole, n as getCmsPlugin, m as isRichTextData, r as marshalArray, o as marshalData, p as normalizeData, w as parseDocId, t as toArrayObject, v as translationsForLocale, s as unmarshalArray, u as unmarshalData } from './client-ROwBDNeR.js';
|
|
5
|
+
import './schema-BKfPP_s9.js';
|
package/dist/client.js
CHANGED
package/dist/core.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { R as RootCMSClient, D as DocMode, L as LoadTranslationsOptions, T as TranslationsMap, a as LocaleTranslations } from './client-
|
|
2
|
-
export { A as Action, q as ArrayObject, C as BatchRequest, B as BatchRequestOptions, x as BatchRequestQuery, y as BatchRequestQueryOptions, E as BatchResponse, c as DataSource, d as DataSourceData, e as DataSourceMode, b as Doc, i as GetCountOptions, G as GetDocOptions, H as HttpMethod, l as ListActionsOptions, h as ListDocsOptions, F as Locale, O as MultiLocaleTranslationsMap, k as Release, f as SaveDraftOptions, S as SetDocOptions, P as SingleLocaleTranslationsMap, I as SourceString, J as TranslatedString, j as Translation, z as TranslationsDoc, K as TranslationsDocMode, N as TranslationsLocaleDocEntry, M as TranslationsLocaleDocHashMap, Q as TranslationsManager, g as UpdateDraftOptions, U as UserRole, V as buildTranslationsDbPath, W as buildTranslationsLocaleDocDbPath, n as getCmsPlugin, m as isRichTextData, r as marshalArray, o as marshalData, p as normalizeData, w as parseDocId, t as toArrayObject, v as translationsForLocale, s as unmarshalArray, u as unmarshalData } from './client-
|
|
1
|
+
import { R as RootCMSClient, D as DocMode, L as LoadTranslationsOptions, T as TranslationsMap, a as LocaleTranslations } from './client-ROwBDNeR.js';
|
|
2
|
+
export { A as Action, q as ArrayObject, C as BatchRequest, B as BatchRequestOptions, x as BatchRequestQuery, y as BatchRequestQueryOptions, E as BatchResponse, c as DataSource, d as DataSourceData, e as DataSourceMode, b as Doc, i as GetCountOptions, G as GetDocOptions, H as HttpMethod, l as ListActionsOptions, h as ListDocsOptions, F as Locale, O as MultiLocaleTranslationsMap, k as Release, f as SaveDraftOptions, S as SetDocOptions, P as SingleLocaleTranslationsMap, I as SourceString, J as TranslatedString, j as Translation, z as TranslationsDoc, K as TranslationsDocMode, N as TranslationsLocaleDocEntry, M as TranslationsLocaleDocHashMap, Q as TranslationsManager, g as UpdateDraftOptions, U as UserRole, V as buildTranslationsDbPath, W as buildTranslationsLocaleDocDbPath, n as getCmsPlugin, m as isRichTextData, r as marshalArray, o as marshalData, p as normalizeData, w as parseDocId, t as toArrayObject, v as translationsForLocale, s as unmarshalArray, u as unmarshalData } from './client-ROwBDNeR.js';
|
|
3
3
|
import { Request, RootConfig, Response, RouteParams, GetStaticProps, GetStaticPaths } from '@blinkk/root';
|
|
4
4
|
import { Query } from 'firebase-admin/firestore';
|
|
5
|
-
export { s as schema } from './schema-
|
|
5
|
+
export { s as schema } from './schema-BKfPP_s9.js';
|
|
6
6
|
import 'firebase-admin/app';
|
|
7
7
|
|
|
8
8
|
/**
|
package/dist/core.js
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
translationsForLocale,
|
|
16
16
|
unmarshalArray,
|
|
17
17
|
unmarshalData
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-NUUABQRN.js";
|
|
19
19
|
import {
|
|
20
20
|
__export
|
|
21
21
|
} from "./chunk-MLKGABMK.js";
|
|
@@ -484,6 +484,7 @@ __export(schema_exports, {
|
|
|
484
484
|
defineCollection: () => defineCollection,
|
|
485
485
|
defineSchema: () => defineSchema,
|
|
486
486
|
file: () => file,
|
|
487
|
+
glob: () => glob,
|
|
487
488
|
image: () => image,
|
|
488
489
|
multiselect: () => multiselect,
|
|
489
490
|
number: () => number,
|
|
@@ -565,6 +566,14 @@ function defineCollection(collection2) {
|
|
|
565
566
|
return collection2;
|
|
566
567
|
}
|
|
567
568
|
var collection = defineCollection;
|
|
569
|
+
function glob(pattern, options) {
|
|
570
|
+
return {
|
|
571
|
+
_schemaPattern: true,
|
|
572
|
+
pattern,
|
|
573
|
+
exclude: options?.exclude,
|
|
574
|
+
omitFields: options?.omitFields
|
|
575
|
+
};
|
|
576
|
+
}
|
|
568
577
|
export {
|
|
569
578
|
BatchRequest,
|
|
570
579
|
BatchResponse,
|
package/dist/functions.js
CHANGED
package/dist/plugin.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '@blinkk/root';
|
|
2
2
|
import 'firebase-admin/app';
|
|
3
3
|
import 'firebase-admin/firestore';
|
|
4
|
-
export { Z as CMSAIConfig, X as CMSBuiltInSidebarTool, a0 as CMSPlugin, $ as CMSPluginOptions, _ as CMSSidebarTool, Y as CMSUser, a1 as cmsPlugin } from './client-
|
|
5
|
-
import './schema-
|
|
4
|
+
export { Z as CMSAIConfig, X as CMSBuiltInSidebarTool, a0 as CMSPlugin, $ as CMSPluginOptions, _ as CMSSidebarTool, Y as CMSUser, a1 as cmsPlugin } from './client-ROwBDNeR.js';
|
|
5
|
+
import './schema-BKfPP_s9.js';
|