@blinkk/root-cms 3.0.1-beta.3 → 3.0.1-beta.5
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/app.js +3 -2
- package/dist/{chunk-F4SODS5S.js → chunk-2BSW7SIH.js} +295 -4
- package/dist/{chunk-NXEXOHBD.js → chunk-5CZBPART.js} +243 -16
- package/dist/chunk-BGTUWIV6.js +187 -0
- package/dist/{chunk-TRM4MQHU.js → chunk-C245C557.js} +14 -192
- package/dist/cli.js +1 -2
- package/dist/client.js +1 -2
- package/dist/core.js +1 -2
- package/dist/functions.js +3 -3
- package/dist/plugin.js +29 -12
- package/dist/ui/ui.css +1 -1
- package/dist/ui/ui.js +166 -166
- package/package.json +3 -3
- package/dist/chunk-CRK7N6RR.js +0 -298
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SearchIndexService
|
|
3
|
+
} from "./chunk-C245C557.js";
|
|
4
|
+
import {
|
|
5
|
+
RootCMSClient,
|
|
6
|
+
getCmsPlugin
|
|
7
|
+
} from "./chunk-2BSW7SIH.js";
|
|
8
|
+
|
|
9
|
+
// core/cron.ts
|
|
10
|
+
import { Timestamp as Timestamp2 } from "firebase-admin/firestore";
|
|
11
|
+
|
|
12
|
+
// core/versions.ts
|
|
13
|
+
import fs from "fs";
|
|
14
|
+
import path from "path";
|
|
15
|
+
import { Timestamp } from "firebase-admin/firestore";
|
|
16
|
+
import glob from "tiny-glob";
|
|
17
|
+
var DOCUMENT_SAVE_OFFSET = 5 * 60 * 1e3;
|
|
18
|
+
var VersionsService = class {
|
|
19
|
+
constructor(rootConfig) {
|
|
20
|
+
this.rootConfig = rootConfig;
|
|
21
|
+
const cmsPlugin = getCmsPlugin(rootConfig);
|
|
22
|
+
const cmsPluginOptions = cmsPlugin.getConfig();
|
|
23
|
+
const projectId = cmsPluginOptions.id || "default";
|
|
24
|
+
this.projectId = projectId;
|
|
25
|
+
this.db = cmsPlugin.getFirestore();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Saves a version of all documents that have been edited since the last run.
|
|
29
|
+
*/
|
|
30
|
+
async saveVersions() {
|
|
31
|
+
const lastRun = await this.getLastRun();
|
|
32
|
+
const lastRunWithOffset = lastRun === 0 ? lastRun : lastRun - DOCUMENT_SAVE_OFFSET;
|
|
33
|
+
const changedDocs = await this.getDocsModifiedAfter(lastRunWithOffset);
|
|
34
|
+
const now = Timestamp.now().toMillis();
|
|
35
|
+
const versions = changedDocs.filter((doc) => {
|
|
36
|
+
const modifiedAt = doc.sys.modifiedAt.toMillis();
|
|
37
|
+
if (modifiedAt > now - DOCUMENT_SAVE_OFFSET) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const publishedAt = doc.sys.publishedAt?.toMillis?.();
|
|
41
|
+
if (publishedAt && Math.abs(publishedAt - modifiedAt) < 5e3) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
});
|
|
46
|
+
if (versions.length > 0) {
|
|
47
|
+
this.saveVersionsToFirestore(versions);
|
|
48
|
+
}
|
|
49
|
+
this.saveLastRun(now);
|
|
50
|
+
}
|
|
51
|
+
async saveVersionsToFirestore(versions) {
|
|
52
|
+
const batch = this.db.batch();
|
|
53
|
+
versions.forEach((version) => {
|
|
54
|
+
if (!version.collection || !version.slug || !version.sys?.modifiedAt) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const modifiedAtMillis = version.sys.modifiedAt.toMillis();
|
|
58
|
+
const versionPath = `Projects/${this.projectId}/Collections/${version.collection}/Drafts/${version.slug}/Versions/${modifiedAtMillis}`;
|
|
59
|
+
console.log(versionPath);
|
|
60
|
+
const versionRef = this.db.doc(versionPath);
|
|
61
|
+
batch.set(versionRef, version);
|
|
62
|
+
});
|
|
63
|
+
await batch.commit();
|
|
64
|
+
console.log(`versions: saved ${versions.length} versions`);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Returns the last time (in millis) saveVersions() was run, or 0 if has
|
|
68
|
+
* never been run.
|
|
69
|
+
*/
|
|
70
|
+
async getLastRun() {
|
|
71
|
+
const projectDocRef = this.db.collection("Projects").doc(this.projectId);
|
|
72
|
+
const projectDoc = await projectDocRef.get();
|
|
73
|
+
if (projectDoc.exists) {
|
|
74
|
+
const data = projectDoc.data() || {};
|
|
75
|
+
const ts = data.versionsLastRun;
|
|
76
|
+
if (ts) {
|
|
77
|
+
return ts.toMillis();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Saves {versionLastRun: <timestamp>} to the Projects/<projectId> doc.
|
|
84
|
+
*/
|
|
85
|
+
async saveLastRun(millis) {
|
|
86
|
+
const ts = Timestamp.fromMillis(millis);
|
|
87
|
+
const projectDocRef = this.db.collection("Projects").doc(this.projectId);
|
|
88
|
+
await projectDocRef.set({ versionsLastRun: ts }, { merge: true });
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Returns a list of all docs that were edited after a certain time.
|
|
92
|
+
*/
|
|
93
|
+
async getDocsModifiedAfter(millis) {
|
|
94
|
+
const ts = Timestamp.fromMillis(millis);
|
|
95
|
+
const results = [];
|
|
96
|
+
const collectionIds = await this.listCollections();
|
|
97
|
+
for (const collectionId of collectionIds) {
|
|
98
|
+
const collectionPath = `Projects/${this.projectId}/Collections/${collectionId}/Drafts`;
|
|
99
|
+
const query = this.db.collection(collectionPath).where("sys.modifiedAt", ">=", ts);
|
|
100
|
+
const querySnapshot = await query.get();
|
|
101
|
+
querySnapshot.forEach((doc) => {
|
|
102
|
+
results.push(doc.data());
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return results;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Returns a list of collection ids for the Root project.
|
|
109
|
+
*/
|
|
110
|
+
async listCollections() {
|
|
111
|
+
const collectionsDir = path.join(this.rootConfig.rootDir, "collections");
|
|
112
|
+
if (!fs.existsSync(collectionsDir)) {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
const collectionIds = [];
|
|
116
|
+
const collectionFileNames = await glob("*.schema.ts", {
|
|
117
|
+
cwd: collectionsDir
|
|
118
|
+
});
|
|
119
|
+
collectionFileNames.forEach((filename) => {
|
|
120
|
+
collectionIds.push(filename.slice(0, -10));
|
|
121
|
+
});
|
|
122
|
+
return collectionIds;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// core/cron.ts
|
|
127
|
+
var SEARCH_INDEX_MIN_INTERVAL_MS = 5 * 60 * 1e3;
|
|
128
|
+
async function runCronJobs(rootConfig, options = {}) {
|
|
129
|
+
await Promise.all([
|
|
130
|
+
runCronJob("publishScheduledDocs", runPublishScheduledDocs, rootConfig),
|
|
131
|
+
runCronJob(
|
|
132
|
+
"syncScheduledDataSources",
|
|
133
|
+
runSyncScheduledDataSources,
|
|
134
|
+
rootConfig
|
|
135
|
+
),
|
|
136
|
+
runCronJob("saveVersions", runSaveVersions, rootConfig),
|
|
137
|
+
runCronJob(
|
|
138
|
+
"incrementalSearchIndex",
|
|
139
|
+
runIncrementalSearchIndex,
|
|
140
|
+
rootConfig,
|
|
141
|
+
options.loadSchema
|
|
142
|
+
)
|
|
143
|
+
]);
|
|
144
|
+
}
|
|
145
|
+
async function runCronJob(name, fn, ...args) {
|
|
146
|
+
try {
|
|
147
|
+
await fn(...args);
|
|
148
|
+
} catch (err) {
|
|
149
|
+
console.log(`cron failed: ${name}`);
|
|
150
|
+
console.error(String(err.stack || err));
|
|
151
|
+
throw err;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
async function runPublishScheduledDocs(rootConfig) {
|
|
155
|
+
const cmsClient = new RootCMSClient(rootConfig);
|
|
156
|
+
await cmsClient.publishScheduledDocs();
|
|
157
|
+
await cmsClient.publishScheduledReleases();
|
|
158
|
+
}
|
|
159
|
+
async function runSyncScheduledDataSources(rootConfig) {
|
|
160
|
+
const cmsClient = new RootCMSClient(rootConfig);
|
|
161
|
+
await cmsClient.syncScheduledDataSources();
|
|
162
|
+
}
|
|
163
|
+
async function runSaveVersions(rootConfig) {
|
|
164
|
+
const service = new VersionsService(rootConfig);
|
|
165
|
+
await service.saveVersions();
|
|
166
|
+
}
|
|
167
|
+
async function runIncrementalSearchIndex(rootConfig, loadSchema) {
|
|
168
|
+
const service = new SearchIndexService(rootConfig, loadSchema);
|
|
169
|
+
const status = await service.getStatus();
|
|
170
|
+
if (status.lastRun !== null) {
|
|
171
|
+
const elapsed = Date.now() - status.lastRun;
|
|
172
|
+
if (elapsed < SEARCH_INDEX_MIN_INTERVAL_MS) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const hasChanges = await service.hasChangesSince(
|
|
176
|
+
Timestamp2.fromMillis(status.lastRun)
|
|
177
|
+
);
|
|
178
|
+
if (!hasChanges) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
await service.rebuildIndex({ force: false });
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export {
|
|
186
|
+
runCronJobs
|
|
187
|
+
};
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
RootCMSClient,
|
|
3
2
|
getCmsPlugin
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
|
|
6
|
-
// core/cron.ts
|
|
7
|
-
import { Timestamp as Timestamp3 } from "firebase-admin/firestore";
|
|
3
|
+
} from "./chunk-2BSW7SIH.js";
|
|
8
4
|
|
|
9
5
|
// core/search-index.ts
|
|
10
6
|
import fs from "fs";
|
|
@@ -677,8 +673,8 @@ var SearchIndexService = class {
|
|
|
677
673
|
async listAllDocs(collectionIds) {
|
|
678
674
|
const all = [];
|
|
679
675
|
for (const collectionId of collectionIds) {
|
|
680
|
-
const
|
|
681
|
-
const snap = await this.db.collection(
|
|
676
|
+
const path2 = `Projects/${this.projectId}/Collections/${collectionId}/Drafts`;
|
|
677
|
+
const snap = await this.db.collection(path2).get();
|
|
682
678
|
snap.forEach((d) => {
|
|
683
679
|
const docId = `${collectionId}/${d.id}`;
|
|
684
680
|
if (!this.isDocIndexable(docId)) {
|
|
@@ -700,8 +696,8 @@ var SearchIndexService = class {
|
|
|
700
696
|
async listChangedDocs(collectionIds, lastRun) {
|
|
701
697
|
const all = [];
|
|
702
698
|
for (const collectionId of collectionIds) {
|
|
703
|
-
const
|
|
704
|
-
const q = this.db.collection(
|
|
699
|
+
const path2 = `Projects/${this.projectId}/Collections/${collectionId}/Drafts`;
|
|
700
|
+
const q = this.db.collection(path2).where("sys.modifiedAt", ">=", lastRun);
|
|
705
701
|
const snap = await q.get();
|
|
706
702
|
snap.forEach((d) => {
|
|
707
703
|
const docId = `${collectionId}/${d.id}`;
|
|
@@ -725,8 +721,8 @@ var SearchIndexService = class {
|
|
|
725
721
|
async hasChangesSince(lastRun, docMap = null) {
|
|
726
722
|
const collectionIds = await this.listCollectionIds();
|
|
727
723
|
for (const collectionId of collectionIds) {
|
|
728
|
-
const
|
|
729
|
-
const q = this.db.collection(
|
|
724
|
+
const path2 = `Projects/${this.projectId}/Collections/${collectionId}/Drafts`;
|
|
725
|
+
const q = this.db.collection(path2).where("sys.modifiedAt", ">=", lastRun).limit(1);
|
|
730
726
|
const snap = await q.get();
|
|
731
727
|
if (!snap.empty) {
|
|
732
728
|
return true;
|
|
@@ -739,8 +735,8 @@ var SearchIndexService = class {
|
|
|
739
735
|
}
|
|
740
736
|
const liveIds = /* @__PURE__ */ new Set();
|
|
741
737
|
for (const collectionId of collectionIds) {
|
|
742
|
-
const
|
|
743
|
-
const snap = await this.db.collection(
|
|
738
|
+
const path2 = `Projects/${this.projectId}/Collections/${collectionId}/Drafts`;
|
|
739
|
+
const snap = await this.db.collection(path2).select().get();
|
|
744
740
|
snap.forEach((d) => {
|
|
745
741
|
const docId = `${collectionId}/${d.id}`;
|
|
746
742
|
if (this.isDocIndexable(docId)) {
|
|
@@ -807,8 +803,8 @@ var SearchIndexService = class {
|
|
|
807
803
|
);
|
|
808
804
|
continue;
|
|
809
805
|
}
|
|
810
|
-
const
|
|
811
|
-
const snap = await this.db.collection(
|
|
806
|
+
const path2 = `Projects/${this.projectId}/Collections/${collectionId}/Drafts`;
|
|
807
|
+
const snap = await this.db.collection(path2).get();
|
|
812
808
|
snap.forEach((d) => {
|
|
813
809
|
const data = d.data() || {};
|
|
814
810
|
const slug = data.slug || d.id;
|
|
@@ -884,8 +880,8 @@ var SearchIndexService = class {
|
|
|
884
880
|
}
|
|
885
881
|
const liveIds = /* @__PURE__ */ new Set();
|
|
886
882
|
for (const collectionId of collectionIds) {
|
|
887
|
-
const
|
|
888
|
-
const snap = await this.db.collection(
|
|
883
|
+
const path2 = `Projects/${this.projectId}/Collections/${collectionId}/Drafts`;
|
|
884
|
+
const snap = await this.db.collection(path2).select().get();
|
|
889
885
|
snap.forEach((d) => {
|
|
890
886
|
const docId = `${collectionId}/${d.id}`;
|
|
891
887
|
if (this.isDocIndexable(docId)) {
|
|
@@ -1001,180 +997,6 @@ var SearchIndexService = class {
|
|
|
1001
997
|
}
|
|
1002
998
|
};
|
|
1003
999
|
|
|
1004
|
-
// core/versions.ts
|
|
1005
|
-
import fs2 from "fs";
|
|
1006
|
-
import path2 from "path";
|
|
1007
|
-
import { Timestamp as Timestamp2 } from "firebase-admin/firestore";
|
|
1008
|
-
import glob2 from "tiny-glob";
|
|
1009
|
-
var DOCUMENT_SAVE_OFFSET = 5 * 60 * 1e3;
|
|
1010
|
-
var VersionsService = class {
|
|
1011
|
-
constructor(rootConfig) {
|
|
1012
|
-
this.rootConfig = rootConfig;
|
|
1013
|
-
const cmsPlugin = getCmsPlugin(rootConfig);
|
|
1014
|
-
const cmsPluginOptions = cmsPlugin.getConfig();
|
|
1015
|
-
const projectId = cmsPluginOptions.id || "default";
|
|
1016
|
-
this.projectId = projectId;
|
|
1017
|
-
this.db = cmsPlugin.getFirestore();
|
|
1018
|
-
}
|
|
1019
|
-
/**
|
|
1020
|
-
* Saves a version of all documents that have been edited since the last run.
|
|
1021
|
-
*/
|
|
1022
|
-
async saveVersions() {
|
|
1023
|
-
const lastRun = await this.getLastRun();
|
|
1024
|
-
const lastRunWithOffset = lastRun === 0 ? lastRun : lastRun - DOCUMENT_SAVE_OFFSET;
|
|
1025
|
-
const changedDocs = await this.getDocsModifiedAfter(lastRunWithOffset);
|
|
1026
|
-
const now = Timestamp2.now().toMillis();
|
|
1027
|
-
const versions = changedDocs.filter((doc) => {
|
|
1028
|
-
const modifiedAt = doc.sys.modifiedAt.toMillis();
|
|
1029
|
-
if (modifiedAt > now - DOCUMENT_SAVE_OFFSET) {
|
|
1030
|
-
return false;
|
|
1031
|
-
}
|
|
1032
|
-
const publishedAt = doc.sys.publishedAt?.toMillis?.();
|
|
1033
|
-
if (publishedAt && Math.abs(publishedAt - modifiedAt) < 5e3) {
|
|
1034
|
-
return false;
|
|
1035
|
-
}
|
|
1036
|
-
return true;
|
|
1037
|
-
});
|
|
1038
|
-
if (versions.length > 0) {
|
|
1039
|
-
this.saveVersionsToFirestore(versions);
|
|
1040
|
-
}
|
|
1041
|
-
this.saveLastRun(now);
|
|
1042
|
-
}
|
|
1043
|
-
async saveVersionsToFirestore(versions) {
|
|
1044
|
-
const batch = this.db.batch();
|
|
1045
|
-
versions.forEach((version) => {
|
|
1046
|
-
if (!version.collection || !version.slug || !version.sys?.modifiedAt) {
|
|
1047
|
-
return;
|
|
1048
|
-
}
|
|
1049
|
-
const modifiedAtMillis = version.sys.modifiedAt.toMillis();
|
|
1050
|
-
const versionPath = `Projects/${this.projectId}/Collections/${version.collection}/Drafts/${version.slug}/Versions/${modifiedAtMillis}`;
|
|
1051
|
-
console.log(versionPath);
|
|
1052
|
-
const versionRef = this.db.doc(versionPath);
|
|
1053
|
-
batch.set(versionRef, version);
|
|
1054
|
-
});
|
|
1055
|
-
await batch.commit();
|
|
1056
|
-
console.log(`versions: saved ${versions.length} versions`);
|
|
1057
|
-
}
|
|
1058
|
-
/**
|
|
1059
|
-
* Returns the last time (in millis) saveVersions() was run, or 0 if has
|
|
1060
|
-
* never been run.
|
|
1061
|
-
*/
|
|
1062
|
-
async getLastRun() {
|
|
1063
|
-
const projectDocRef = this.db.collection("Projects").doc(this.projectId);
|
|
1064
|
-
const projectDoc = await projectDocRef.get();
|
|
1065
|
-
if (projectDoc.exists) {
|
|
1066
|
-
const data = projectDoc.data() || {};
|
|
1067
|
-
const ts = data.versionsLastRun;
|
|
1068
|
-
if (ts) {
|
|
1069
|
-
return ts.toMillis();
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
return 0;
|
|
1073
|
-
}
|
|
1074
|
-
/**
|
|
1075
|
-
* Saves {versionLastRun: <timestamp>} to the Projects/<projectId> doc.
|
|
1076
|
-
*/
|
|
1077
|
-
async saveLastRun(millis) {
|
|
1078
|
-
const ts = Timestamp2.fromMillis(millis);
|
|
1079
|
-
const projectDocRef = this.db.collection("Projects").doc(this.projectId);
|
|
1080
|
-
await projectDocRef.set({ versionsLastRun: ts }, { merge: true });
|
|
1081
|
-
}
|
|
1082
|
-
/**
|
|
1083
|
-
* Returns a list of all docs that were edited after a certain time.
|
|
1084
|
-
*/
|
|
1085
|
-
async getDocsModifiedAfter(millis) {
|
|
1086
|
-
const ts = Timestamp2.fromMillis(millis);
|
|
1087
|
-
const results = [];
|
|
1088
|
-
const collectionIds = await this.listCollections();
|
|
1089
|
-
for (const collectionId of collectionIds) {
|
|
1090
|
-
const collectionPath = `Projects/${this.projectId}/Collections/${collectionId}/Drafts`;
|
|
1091
|
-
const query = this.db.collection(collectionPath).where("sys.modifiedAt", ">=", ts);
|
|
1092
|
-
const querySnapshot = await query.get();
|
|
1093
|
-
querySnapshot.forEach((doc) => {
|
|
1094
|
-
results.push(doc.data());
|
|
1095
|
-
});
|
|
1096
|
-
}
|
|
1097
|
-
return results;
|
|
1098
|
-
}
|
|
1099
|
-
/**
|
|
1100
|
-
* Returns a list of collection ids for the Root project.
|
|
1101
|
-
*/
|
|
1102
|
-
async listCollections() {
|
|
1103
|
-
const collectionsDir = path2.join(this.rootConfig.rootDir, "collections");
|
|
1104
|
-
if (!fs2.existsSync(collectionsDir)) {
|
|
1105
|
-
return [];
|
|
1106
|
-
}
|
|
1107
|
-
const collectionIds = [];
|
|
1108
|
-
const collectionFileNames = await glob2("*.schema.ts", {
|
|
1109
|
-
cwd: collectionsDir
|
|
1110
|
-
});
|
|
1111
|
-
collectionFileNames.forEach((filename) => {
|
|
1112
|
-
collectionIds.push(filename.slice(0, -10));
|
|
1113
|
-
});
|
|
1114
|
-
return collectionIds;
|
|
1115
|
-
}
|
|
1116
|
-
};
|
|
1117
|
-
|
|
1118
|
-
// core/cron.ts
|
|
1119
|
-
var SEARCH_INDEX_MIN_INTERVAL_MS = 5 * 60 * 1e3;
|
|
1120
|
-
async function runCronJobs(rootConfig, options = {}) {
|
|
1121
|
-
await Promise.all([
|
|
1122
|
-
runCronJob("publishScheduledDocs", runPublishScheduledDocs, rootConfig),
|
|
1123
|
-
runCronJob(
|
|
1124
|
-
"syncScheduledDataSources",
|
|
1125
|
-
runSyncScheduledDataSources,
|
|
1126
|
-
rootConfig
|
|
1127
|
-
),
|
|
1128
|
-
runCronJob("saveVersions", runSaveVersions, rootConfig),
|
|
1129
|
-
runCronJob(
|
|
1130
|
-
"incrementalSearchIndex",
|
|
1131
|
-
runIncrementalSearchIndex,
|
|
1132
|
-
rootConfig,
|
|
1133
|
-
options.loadSchema
|
|
1134
|
-
)
|
|
1135
|
-
]);
|
|
1136
|
-
}
|
|
1137
|
-
async function runCronJob(name, fn, ...args) {
|
|
1138
|
-
try {
|
|
1139
|
-
await fn(...args);
|
|
1140
|
-
} catch (err) {
|
|
1141
|
-
console.log(`cron failed: ${name}`);
|
|
1142
|
-
console.error(String(err.stack || err));
|
|
1143
|
-
throw err;
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
async function runPublishScheduledDocs(rootConfig) {
|
|
1147
|
-
const cmsClient = new RootCMSClient(rootConfig);
|
|
1148
|
-
await cmsClient.publishScheduledDocs();
|
|
1149
|
-
await cmsClient.publishScheduledReleases();
|
|
1150
|
-
}
|
|
1151
|
-
async function runSyncScheduledDataSources(rootConfig) {
|
|
1152
|
-
const cmsClient = new RootCMSClient(rootConfig);
|
|
1153
|
-
await cmsClient.syncScheduledDataSources();
|
|
1154
|
-
}
|
|
1155
|
-
async function runSaveVersions(rootConfig) {
|
|
1156
|
-
const service = new VersionsService(rootConfig);
|
|
1157
|
-
await service.saveVersions();
|
|
1158
|
-
}
|
|
1159
|
-
async function runIncrementalSearchIndex(rootConfig, loadSchema) {
|
|
1160
|
-
const service = new SearchIndexService(rootConfig, loadSchema);
|
|
1161
|
-
const status = await service.getStatus();
|
|
1162
|
-
if (status.lastRun !== null) {
|
|
1163
|
-
const elapsed = Date.now() - status.lastRun;
|
|
1164
|
-
if (elapsed < SEARCH_INDEX_MIN_INTERVAL_MS) {
|
|
1165
|
-
return;
|
|
1166
|
-
}
|
|
1167
|
-
const hasChanges = await service.hasChangesSince(
|
|
1168
|
-
Timestamp3.fromMillis(status.lastRun)
|
|
1169
|
-
);
|
|
1170
|
-
if (!hasChanges) {
|
|
1171
|
-
return;
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
await service.rebuildIndex({ force: false });
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
1000
|
export {
|
|
1178
|
-
SearchIndexService
|
|
1179
|
-
runCronJobs
|
|
1001
|
+
SearchIndexService
|
|
1180
1002
|
};
|
package/dist/cli.js
CHANGED
package/dist/client.js
CHANGED
package/dist/core.js
CHANGED
package/dist/functions.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runCronJobs
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-BGTUWIV6.js";
|
|
4
|
+
import "./chunk-C245C557.js";
|
|
5
|
+
import "./chunk-2BSW7SIH.js";
|
|
6
6
|
import "./chunk-MLKGABMK.js";
|
|
7
7
|
|
|
8
8
|
// core/functions.ts
|
package/dist/plugin.js
CHANGED
|
@@ -12,17 +12,18 @@ import {
|
|
|
12
12
|
serializeAiConfig,
|
|
13
13
|
summarizeDiff,
|
|
14
14
|
translateString
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-5CZBPART.js";
|
|
16
16
|
import {
|
|
17
|
-
SearchIndexService,
|
|
18
17
|
runCronJobs
|
|
19
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-BGTUWIV6.js";
|
|
19
|
+
import {
|
|
20
|
+
SearchIndexService
|
|
21
|
+
} from "./chunk-C245C557.js";
|
|
20
22
|
import {
|
|
21
23
|
RootCMSClient,
|
|
22
24
|
parseDocId,
|
|
23
25
|
unmarshalData
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import "./chunk-CRK7N6RR.js";
|
|
26
|
+
} from "./chunk-2BSW7SIH.js";
|
|
26
27
|
import "./chunk-MLKGABMK.js";
|
|
27
28
|
|
|
28
29
|
// core/plugin.ts
|
|
@@ -546,11 +547,6 @@ function api(server, options) {
|
|
|
546
547
|
return;
|
|
547
548
|
}
|
|
548
549
|
const body = req.body || {};
|
|
549
|
-
const messages = body.messages || [];
|
|
550
|
-
if (!Array.isArray(messages) || messages.length === 0) {
|
|
551
|
-
res.status(400).json({ success: false, error: "MISSING_MESSAGES" });
|
|
552
|
-
return;
|
|
553
|
-
}
|
|
554
550
|
const model = findModel(aiConfig, body.modelId);
|
|
555
551
|
if (!model) {
|
|
556
552
|
res.status(400).json({ success: false, error: "UNKNOWN_MODEL" });
|
|
@@ -561,10 +557,12 @@ function api(server, options) {
|
|
|
561
557
|
const store = new ChatStore(cmsClient, req.user.email);
|
|
562
558
|
const requestedChatId = typeof body.chatId === "string" ? body.chatId.trim() : "";
|
|
563
559
|
let chatId = "";
|
|
560
|
+
let storedMessages = [];
|
|
564
561
|
if (requestedChatId) {
|
|
565
562
|
const existing = await store.getChat(requestedChatId);
|
|
566
563
|
if (existing) {
|
|
567
564
|
chatId = existing.id;
|
|
565
|
+
storedMessages = existing.messages || [];
|
|
568
566
|
} else {
|
|
569
567
|
const created = await store.createChat({
|
|
570
568
|
id: requestedChatId,
|
|
@@ -576,6 +574,15 @@ function api(server, options) {
|
|
|
576
574
|
const created = await store.createChat({ modelId: model.id });
|
|
577
575
|
chatId = created.id;
|
|
578
576
|
}
|
|
577
|
+
let messages;
|
|
578
|
+
if (body.message && typeof body.message === "object") {
|
|
579
|
+
messages = [...storedMessages, body.message];
|
|
580
|
+
} else if (Array.isArray(body.messages) && body.messages.length > 0) {
|
|
581
|
+
messages = body.messages;
|
|
582
|
+
} else {
|
|
583
|
+
res.status(400).json({ success: false, error: "MISSING_MESSAGES" });
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
579
586
|
try {
|
|
580
587
|
const streamResponse = await runChatStream({
|
|
581
588
|
rootConfig: req.rootConfig,
|
|
@@ -585,7 +592,9 @@ function api(server, options) {
|
|
|
585
592
|
messages,
|
|
586
593
|
chatId,
|
|
587
594
|
user: req.user.email,
|
|
588
|
-
executionMode
|
|
595
|
+
executionMode,
|
|
596
|
+
loadCollection: (collectionId) => getCollectionSchema(req, collectionId),
|
|
597
|
+
loadAllCollections: async () => (await options.getRenderer(req)).getCollections()
|
|
589
598
|
});
|
|
590
599
|
streamResponse.headers.set("x-root-cms-chat-id", chatId);
|
|
591
600
|
await pipeWebResponse(streamResponse, res);
|
|
@@ -628,10 +637,14 @@ function api(server, options) {
|
|
|
628
637
|
try {
|
|
629
638
|
const streamResponse = await runEditObjectStream({
|
|
630
639
|
rootConfig: req.rootConfig,
|
|
640
|
+
cmsClient: new RootCMSClient(req.rootConfig),
|
|
641
|
+
user: req.user.email,
|
|
631
642
|
config: aiConfig,
|
|
632
643
|
model,
|
|
633
644
|
messages,
|
|
634
|
-
editData: body.editData
|
|
645
|
+
editData: body.editData,
|
|
646
|
+
loadCollection: (collectionId) => getCollectionSchema(req, collectionId),
|
|
647
|
+
loadAllCollections: async () => (await options.getRenderer(req)).getCollections()
|
|
635
648
|
});
|
|
636
649
|
await pipeWebResponse(streamResponse, res);
|
|
637
650
|
} catch (err) {
|
|
@@ -1442,6 +1455,10 @@ function cmsPlugin(options) {
|
|
|
1442
1455
|
* Attaches CMS-specific middleware to the Root.js server.
|
|
1443
1456
|
*/
|
|
1444
1457
|
configureServer: async (server, serverOptions) => {
|
|
1458
|
+
server.use(
|
|
1459
|
+
["/cms/api/ai.chat", "/cms/api/ai.edit_object"],
|
|
1460
|
+
bodyParser.json({ limit: "4mb" })
|
|
1461
|
+
);
|
|
1445
1462
|
server.use(bodyParser.json());
|
|
1446
1463
|
server.use(
|
|
1447
1464
|
(err, req, res, next) => {
|