@templatical/core 0.49.0 → 0.50.0
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 +1 -1
- package/dist/cloud/index.d.ts +3 -100
- package/dist/cloud/index.js +1 -627
- package/dist/cloud/index.js.map +1 -1
- package/dist/index.d.ts +32 -21
- package/dist/index.js +125 -189
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/cloud/index.js
CHANGED
|
@@ -178,7 +178,6 @@ function buildUrl(template, params) {
|
|
|
178
178
|
}
|
|
179
179
|
const BASE = "/api/v1/projects/{project}/tenants/{tenant}";
|
|
180
180
|
const TEMPLATE = `${BASE}/templates/{template}`;
|
|
181
|
-
const AI = `${TEMPLATE}/ai`;
|
|
182
181
|
const MEDIA = `${BASE}/media`;
|
|
183
182
|
const FOLDERS = `${MEDIA}/folders`;
|
|
184
183
|
const MODULES = `${BASE}/saved-modules`;
|
|
@@ -202,13 +201,6 @@ const API_ROUTES = {
|
|
|
202
201
|
"comments.update": `${TEMPLATE}/comments/{comment}`,
|
|
203
202
|
"comments.destroy": `${TEMPLATE}/comments/{comment}`,
|
|
204
203
|
"comments.resolve": `${TEMPLATE}/comments/{comment}/resolve`,
|
|
205
|
-
"ai.generate": `${AI}/generate`,
|
|
206
|
-
"ai.conversationMessages": `${AI}/conversation-messages`,
|
|
207
|
-
"ai.suggestions": `${AI}/suggestions`,
|
|
208
|
-
"ai.rewriteText": `${AI}/rewrite-text`,
|
|
209
|
-
"ai.score": `${AI}/score`,
|
|
210
|
-
"ai.fixFinding": `${AI}/fix-finding`,
|
|
211
|
-
"ai.generateFromDesign": `${AI}/generate-from-design`,
|
|
212
204
|
"media.upload": `${MEDIA}/upload`,
|
|
213
205
|
"media.browse": `${MEDIA}/browse`,
|
|
214
206
|
"media.delete": `${MEDIA}/delete`,
|
|
@@ -693,624 +685,6 @@ var WebSocketClient = class {
|
|
|
693
685
|
}
|
|
694
686
|
};
|
|
695
687
|
//#endregion
|
|
696
|
-
//#region src/cloud/ai-chat.ts
|
|
697
|
-
let messageIdCounter = 0;
|
|
698
|
-
function generateMessageId() {
|
|
699
|
-
return `msg_${Date.now()}_${++messageIdCounter}`;
|
|
700
|
-
}
|
|
701
|
-
function useAiChat(options) {
|
|
702
|
-
const { authManager, getTemplateId, onApply, onError } = options;
|
|
703
|
-
const messages = ref([]);
|
|
704
|
-
const isGenerating = ref(false);
|
|
705
|
-
const isLoadingHistory = ref(false);
|
|
706
|
-
const error = ref(null);
|
|
707
|
-
const failedPrompt = ref(null);
|
|
708
|
-
const conversationId = ref(null);
|
|
709
|
-
const lastApplyMessageId = ref(null);
|
|
710
|
-
const lastPreviousContent = ref(null);
|
|
711
|
-
const lastAppliedContent = ref(null);
|
|
712
|
-
const isLastChangeReverted = ref(false);
|
|
713
|
-
const suggestions = ref([]);
|
|
714
|
-
const isLoadingSuggestions = ref(false);
|
|
715
|
-
function updateMessage(msgId, updates) {
|
|
716
|
-
const idx = messages.value.findIndex((m) => m.id === msgId);
|
|
717
|
-
if (idx === -1) return;
|
|
718
|
-
const updated = {
|
|
719
|
-
...messages.value[idx],
|
|
720
|
-
...updates
|
|
721
|
-
};
|
|
722
|
-
messages.value = [
|
|
723
|
-
...messages.value.slice(0, idx),
|
|
724
|
-
updated,
|
|
725
|
-
...messages.value.slice(idx + 1)
|
|
726
|
-
];
|
|
727
|
-
}
|
|
728
|
-
async function loadConversation() {
|
|
729
|
-
const templateId = getTemplateId();
|
|
730
|
-
if (!templateId) return;
|
|
731
|
-
isLoadingHistory.value = true;
|
|
732
|
-
try {
|
|
733
|
-
const url = buildUrl(API_ROUTES["ai.conversationMessages"], {
|
|
734
|
-
project: authManager.projectId,
|
|
735
|
-
tenant: authManager.tenantSlug,
|
|
736
|
-
template: templateId
|
|
737
|
-
});
|
|
738
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
739
|
-
method: "GET",
|
|
740
|
-
headers: { Accept: "application/json" }
|
|
741
|
-
});
|
|
742
|
-
if (!response.ok) return;
|
|
743
|
-
const data = await response.json();
|
|
744
|
-
if (data.conversationId) conversationId.value = data.conversationId;
|
|
745
|
-
if (Array.isArray(data.data) && data.data.length > 0) messages.value = data.data.map((msg) => ({
|
|
746
|
-
id: msg.id,
|
|
747
|
-
role: msg.role,
|
|
748
|
-
content: msg.content,
|
|
749
|
-
timestamp: new Date(msg.createdAt).getTime()
|
|
750
|
-
}));
|
|
751
|
-
} catch {} finally {
|
|
752
|
-
isLoadingHistory.value = false;
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
async function loadSuggestions(currentContent, mergeTags) {
|
|
756
|
-
const templateId = getTemplateId();
|
|
757
|
-
if (!templateId) return;
|
|
758
|
-
isLoadingSuggestions.value = true;
|
|
759
|
-
try {
|
|
760
|
-
const url = buildUrl(API_ROUTES["ai.suggestions"], {
|
|
761
|
-
project: authManager.projectId,
|
|
762
|
-
tenant: authManager.tenantSlug,
|
|
763
|
-
template: templateId
|
|
764
|
-
});
|
|
765
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
766
|
-
method: "POST",
|
|
767
|
-
headers: {
|
|
768
|
-
"Content-Type": "application/json",
|
|
769
|
-
Accept: "text/event-stream"
|
|
770
|
-
},
|
|
771
|
-
body: JSON.stringify({
|
|
772
|
-
currentContent,
|
|
773
|
-
mergeTags: mergeTags.map((p) => ({
|
|
774
|
-
label: p.label,
|
|
775
|
-
value: p.value
|
|
776
|
-
}))
|
|
777
|
-
})
|
|
778
|
-
});
|
|
779
|
-
if (!response.ok) return;
|
|
780
|
-
const reader = response.body?.getReader();
|
|
781
|
-
if (!reader) return;
|
|
782
|
-
const decoder = new TextDecoder();
|
|
783
|
-
let buffer = "";
|
|
784
|
-
while (true) {
|
|
785
|
-
const { done, value } = await reader.read();
|
|
786
|
-
if (done) break;
|
|
787
|
-
buffer += decoder.decode(value, { stream: true });
|
|
788
|
-
const lines = buffer.split("\n");
|
|
789
|
-
buffer = lines.pop() ?? "";
|
|
790
|
-
for (const line of lines) {
|
|
791
|
-
if (!line.startsWith("data: ")) continue;
|
|
792
|
-
let event;
|
|
793
|
-
try {
|
|
794
|
-
event = JSON.parse(line.slice(6));
|
|
795
|
-
} catch {
|
|
796
|
-
continue;
|
|
797
|
-
}
|
|
798
|
-
if (event.type === "done" && Array.isArray(event.suggestions)) suggestions.value = event.suggestions.slice(0, 3);
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
} catch {} finally {
|
|
802
|
-
isLoadingSuggestions.value = false;
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
async function sendPrompt(prompt, currentContent, mergeTags) {
|
|
806
|
-
const templateId = getTemplateId();
|
|
807
|
-
if (!templateId) throw new Error("Template must be saved before using AI generation");
|
|
808
|
-
isGenerating.value = true;
|
|
809
|
-
error.value = null;
|
|
810
|
-
failedPrompt.value = null;
|
|
811
|
-
suggestions.value = [];
|
|
812
|
-
const userMsgId = generateMessageId();
|
|
813
|
-
messages.value = [...messages.value, {
|
|
814
|
-
id: userMsgId,
|
|
815
|
-
role: "user",
|
|
816
|
-
content: prompt,
|
|
817
|
-
timestamp: Date.now()
|
|
818
|
-
}];
|
|
819
|
-
const assistantMsgId = generateMessageId();
|
|
820
|
-
messages.value = [...messages.value, {
|
|
821
|
-
id: assistantMsgId,
|
|
822
|
-
role: "assistant",
|
|
823
|
-
content: "",
|
|
824
|
-
timestamp: Date.now()
|
|
825
|
-
}];
|
|
826
|
-
try {
|
|
827
|
-
const url = buildUrl(API_ROUTES["ai.generate"], {
|
|
828
|
-
project: authManager.projectId,
|
|
829
|
-
tenant: authManager.tenantSlug,
|
|
830
|
-
template: templateId
|
|
831
|
-
});
|
|
832
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
833
|
-
method: "POST",
|
|
834
|
-
headers: {
|
|
835
|
-
"Content-Type": "application/json",
|
|
836
|
-
Accept: "text/event-stream"
|
|
837
|
-
},
|
|
838
|
-
body: JSON.stringify({
|
|
839
|
-
prompt,
|
|
840
|
-
currentContent,
|
|
841
|
-
mergeTags: mergeTags.map((p) => ({
|
|
842
|
-
label: p.label,
|
|
843
|
-
value: p.value
|
|
844
|
-
})),
|
|
845
|
-
conversationId: conversationId.value
|
|
846
|
-
})
|
|
847
|
-
});
|
|
848
|
-
if (!response.ok) {
|
|
849
|
-
const errorData = await response.json().catch(() => null);
|
|
850
|
-
if (response.status === 403) throw new Error("aiGenerationNotAvailable");
|
|
851
|
-
throw new Error(errorData?.message || "Failed to generate template");
|
|
852
|
-
}
|
|
853
|
-
const reader = response.body?.getReader();
|
|
854
|
-
if (!reader) throw new Error("Failed to read stream");
|
|
855
|
-
const decoder = new TextDecoder();
|
|
856
|
-
let buffer = "";
|
|
857
|
-
let result = null;
|
|
858
|
-
try {
|
|
859
|
-
while (true) {
|
|
860
|
-
const { done, value } = await reader.read();
|
|
861
|
-
if (done) break;
|
|
862
|
-
buffer += decoder.decode(value, { stream: true });
|
|
863
|
-
const lines = buffer.split("\n");
|
|
864
|
-
buffer = lines.pop() ?? "";
|
|
865
|
-
for (const line of lines) {
|
|
866
|
-
if (!line.startsWith("data: ")) continue;
|
|
867
|
-
const jsonStr = line.slice(6);
|
|
868
|
-
let event;
|
|
869
|
-
try {
|
|
870
|
-
event = JSON.parse(jsonStr);
|
|
871
|
-
} catch {
|
|
872
|
-
continue;
|
|
873
|
-
}
|
|
874
|
-
if (event.type === "text") updateMessage(assistantMsgId, { content: (messages.value.find((m) => m.id === assistantMsgId)?.content ?? "") + event.text });
|
|
875
|
-
else if (event.type === "error") throw new Error(event.message || "Failed to generate template");
|
|
876
|
-
else if (event.type === "done") {
|
|
877
|
-
if (event.conversationId) conversationId.value = event.conversationId;
|
|
878
|
-
updateMessage(assistantMsgId, { content: event.text });
|
|
879
|
-
result = event.content ?? null;
|
|
880
|
-
if (result) {
|
|
881
|
-
lastPreviousContent.value = currentContent;
|
|
882
|
-
lastAppliedContent.value = result;
|
|
883
|
-
lastApplyMessageId.value = assistantMsgId;
|
|
884
|
-
isLastChangeReverted.value = false;
|
|
885
|
-
onApply?.(result);
|
|
886
|
-
} else error.value = "ai_apply_failed";
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
} finally {
|
|
891
|
-
reader.cancel().catch(() => {});
|
|
892
|
-
}
|
|
893
|
-
return result;
|
|
894
|
-
} catch (err) {
|
|
895
|
-
const wrappedError = err instanceof Error ? err : new Error("Failed to generate template", { cause: err });
|
|
896
|
-
error.value = wrappedError.message;
|
|
897
|
-
failedPrompt.value = prompt;
|
|
898
|
-
onError?.(wrappedError);
|
|
899
|
-
messages.value = messages.value.filter((m) => m.id !== userMsgId && m.id !== assistantMsgId);
|
|
900
|
-
return null;
|
|
901
|
-
} finally {
|
|
902
|
-
isGenerating.value = false;
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
function toggleLastRevert() {
|
|
906
|
-
if (isLastChangeReverted.value) {
|
|
907
|
-
if (lastAppliedContent.value) onApply?.(lastAppliedContent.value);
|
|
908
|
-
isLastChangeReverted.value = false;
|
|
909
|
-
} else {
|
|
910
|
-
if (lastPreviousContent.value) onApply?.(lastPreviousContent.value);
|
|
911
|
-
isLastChangeReverted.value = true;
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
function clearChat() {
|
|
915
|
-
messages.value = [];
|
|
916
|
-
conversationId.value = null;
|
|
917
|
-
error.value = null;
|
|
918
|
-
lastApplyMessageId.value = null;
|
|
919
|
-
lastPreviousContent.value = null;
|
|
920
|
-
lastAppliedContent.value = null;
|
|
921
|
-
isLastChangeReverted.value = false;
|
|
922
|
-
}
|
|
923
|
-
return {
|
|
924
|
-
messages,
|
|
925
|
-
isGenerating,
|
|
926
|
-
isLoadingHistory,
|
|
927
|
-
isLastChangeReverted,
|
|
928
|
-
lastApplyMessageId,
|
|
929
|
-
error,
|
|
930
|
-
failedPrompt,
|
|
931
|
-
suggestions,
|
|
932
|
-
isLoadingSuggestions,
|
|
933
|
-
sendPrompt,
|
|
934
|
-
toggleLastRevert,
|
|
935
|
-
loadConversation,
|
|
936
|
-
loadSuggestions,
|
|
937
|
-
clearChat
|
|
938
|
-
};
|
|
939
|
-
}
|
|
940
|
-
//#endregion
|
|
941
|
-
//#region src/cloud/ai-rewrite.ts
|
|
942
|
-
function useAiRewrite(options) {
|
|
943
|
-
const { authManager, getTemplateId } = options;
|
|
944
|
-
const isRewriting = ref(false);
|
|
945
|
-
const streamingText = ref("");
|
|
946
|
-
const previousContent = ref(null);
|
|
947
|
-
const rewrittenContent = ref(null);
|
|
948
|
-
const isReverted = ref(false);
|
|
949
|
-
const error = ref(null);
|
|
950
|
-
async function rewrite(content, instruction, mergeTags) {
|
|
951
|
-
const templateId = getTemplateId();
|
|
952
|
-
if (!templateId) return null;
|
|
953
|
-
isRewriting.value = true;
|
|
954
|
-
streamingText.value = "";
|
|
955
|
-
error.value = null;
|
|
956
|
-
try {
|
|
957
|
-
const url = buildUrl(API_ROUTES["ai.rewriteText"], {
|
|
958
|
-
project: authManager.projectId,
|
|
959
|
-
tenant: authManager.tenantSlug,
|
|
960
|
-
template: templateId
|
|
961
|
-
});
|
|
962
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
963
|
-
method: "POST",
|
|
964
|
-
headers: {
|
|
965
|
-
"Content-Type": "application/json",
|
|
966
|
-
Accept: "text/event-stream"
|
|
967
|
-
},
|
|
968
|
-
body: JSON.stringify({
|
|
969
|
-
content,
|
|
970
|
-
instruction,
|
|
971
|
-
mergeTags: mergeTags.map((p) => ({
|
|
972
|
-
label: p.label,
|
|
973
|
-
value: p.value
|
|
974
|
-
}))
|
|
975
|
-
})
|
|
976
|
-
});
|
|
977
|
-
if (!response.ok) {
|
|
978
|
-
if (response.status === 403) throw new Error("aiGenerationNotAvailable");
|
|
979
|
-
const errorData = await response.json().catch(() => null);
|
|
980
|
-
throw new Error(errorData?.message || "Failed to rewrite text");
|
|
981
|
-
}
|
|
982
|
-
const reader = response.body?.getReader();
|
|
983
|
-
if (!reader) throw new Error("Failed to read stream");
|
|
984
|
-
const decoder = new TextDecoder();
|
|
985
|
-
let buffer = "";
|
|
986
|
-
let result = null;
|
|
987
|
-
while (true) {
|
|
988
|
-
const { done, value } = await reader.read();
|
|
989
|
-
if (done) break;
|
|
990
|
-
buffer += decoder.decode(value, { stream: true });
|
|
991
|
-
const lines = buffer.split("\n");
|
|
992
|
-
buffer = lines.pop() ?? "";
|
|
993
|
-
for (const line of lines) {
|
|
994
|
-
if (!line.startsWith("data: ")) continue;
|
|
995
|
-
let event;
|
|
996
|
-
try {
|
|
997
|
-
event = JSON.parse(line.slice(6));
|
|
998
|
-
} catch {
|
|
999
|
-
continue;
|
|
1000
|
-
}
|
|
1001
|
-
if (event.type === "text") streamingText.value += event.text;
|
|
1002
|
-
else if (event.type === "error") throw new Error(event.message || "Failed to rewrite text");
|
|
1003
|
-
else if (event.type === "done") {
|
|
1004
|
-
result = event.content ?? null;
|
|
1005
|
-
if (result) {
|
|
1006
|
-
previousContent.value = content;
|
|
1007
|
-
rewrittenContent.value = result;
|
|
1008
|
-
isReverted.value = false;
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
return result;
|
|
1014
|
-
} catch (err) {
|
|
1015
|
-
error.value = err instanceof Error ? err.message : "Failed to rewrite text";
|
|
1016
|
-
return null;
|
|
1017
|
-
} finally {
|
|
1018
|
-
isRewriting.value = false;
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
function undo() {
|
|
1022
|
-
if (!previousContent.value) return null;
|
|
1023
|
-
isReverted.value = true;
|
|
1024
|
-
return previousContent.value;
|
|
1025
|
-
}
|
|
1026
|
-
function redo() {
|
|
1027
|
-
if (!rewrittenContent.value) return null;
|
|
1028
|
-
isReverted.value = false;
|
|
1029
|
-
return rewrittenContent.value;
|
|
1030
|
-
}
|
|
1031
|
-
function reset() {
|
|
1032
|
-
isRewriting.value = false;
|
|
1033
|
-
streamingText.value = "";
|
|
1034
|
-
previousContent.value = null;
|
|
1035
|
-
rewrittenContent.value = null;
|
|
1036
|
-
isReverted.value = false;
|
|
1037
|
-
error.value = null;
|
|
1038
|
-
}
|
|
1039
|
-
return {
|
|
1040
|
-
isRewriting,
|
|
1041
|
-
streamingText,
|
|
1042
|
-
previousContent,
|
|
1043
|
-
rewrittenContent,
|
|
1044
|
-
isReverted,
|
|
1045
|
-
error,
|
|
1046
|
-
rewrite,
|
|
1047
|
-
undo,
|
|
1048
|
-
redo,
|
|
1049
|
-
reset
|
|
1050
|
-
};
|
|
1051
|
-
}
|
|
1052
|
-
//#endregion
|
|
1053
|
-
//#region src/cloud/ai-config.ts
|
|
1054
|
-
function useAiConfig(config) {
|
|
1055
|
-
function isFeatureEnabled(feature) {
|
|
1056
|
-
if (config === false) return false;
|
|
1057
|
-
return config?.[feature] !== false;
|
|
1058
|
-
}
|
|
1059
|
-
return {
|
|
1060
|
-
isFeatureEnabled,
|
|
1061
|
-
hasAnyMenuFeature: computed(() => isFeatureEnabled("chat") || isFeatureEnabled("scoring") || isFeatureEnabled("designToTemplate"))
|
|
1062
|
-
};
|
|
1063
|
-
}
|
|
1064
|
-
//#endregion
|
|
1065
|
-
//#region src/cloud/template-scoring.ts
|
|
1066
|
-
function useTemplateScoring(options) {
|
|
1067
|
-
const { authManager, getTemplateId } = options;
|
|
1068
|
-
const isScoring = ref(false);
|
|
1069
|
-
const scoringResult = ref(null);
|
|
1070
|
-
const error = ref(null);
|
|
1071
|
-
const fixingFindingId = ref(null);
|
|
1072
|
-
const fixStreamingText = ref("");
|
|
1073
|
-
const fixError = ref(null);
|
|
1074
|
-
async function score(content, mergeTags) {
|
|
1075
|
-
const templateId = getTemplateId();
|
|
1076
|
-
if (!templateId) return null;
|
|
1077
|
-
isScoring.value = true;
|
|
1078
|
-
error.value = null;
|
|
1079
|
-
scoringResult.value = null;
|
|
1080
|
-
try {
|
|
1081
|
-
const url = buildUrl(API_ROUTES["ai.score"], {
|
|
1082
|
-
project: authManager.projectId,
|
|
1083
|
-
tenant: authManager.tenantSlug,
|
|
1084
|
-
template: templateId
|
|
1085
|
-
});
|
|
1086
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
1087
|
-
method: "POST",
|
|
1088
|
-
headers: {
|
|
1089
|
-
"Content-Type": "application/json",
|
|
1090
|
-
Accept: "text/event-stream"
|
|
1091
|
-
},
|
|
1092
|
-
body: JSON.stringify({
|
|
1093
|
-
currentContent: content,
|
|
1094
|
-
mergeTags: mergeTags.map((p) => ({
|
|
1095
|
-
label: p.label,
|
|
1096
|
-
value: p.value
|
|
1097
|
-
}))
|
|
1098
|
-
})
|
|
1099
|
-
});
|
|
1100
|
-
if (!response.ok) {
|
|
1101
|
-
if (response.status === 403) throw new Error("aiGenerationNotAvailable");
|
|
1102
|
-
const errorData = await response.json().catch(() => null);
|
|
1103
|
-
throw new Error(errorData?.message || "Failed to score template");
|
|
1104
|
-
}
|
|
1105
|
-
const reader = response.body?.getReader();
|
|
1106
|
-
if (!reader) throw new Error("Failed to read stream");
|
|
1107
|
-
const decoder = new TextDecoder();
|
|
1108
|
-
let buffer = "";
|
|
1109
|
-
let result = null;
|
|
1110
|
-
while (true) {
|
|
1111
|
-
const { done, value } = await reader.read();
|
|
1112
|
-
if (done) break;
|
|
1113
|
-
buffer += decoder.decode(value, { stream: true });
|
|
1114
|
-
const lines = buffer.split("\n");
|
|
1115
|
-
buffer = lines.pop() ?? "";
|
|
1116
|
-
for (const line of lines) {
|
|
1117
|
-
if (!line.startsWith("data: ")) continue;
|
|
1118
|
-
let event;
|
|
1119
|
-
try {
|
|
1120
|
-
event = JSON.parse(line.slice(6));
|
|
1121
|
-
} catch {
|
|
1122
|
-
continue;
|
|
1123
|
-
}
|
|
1124
|
-
if (event.type === "error") throw new Error(event.message || "Failed to score template");
|
|
1125
|
-
if (event.type === "done") result = event.result ?? null;
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
if (result) for (const [category, categoryData] of Object.entries(result.categories)) for (const finding of categoryData.findings) finding.category = category;
|
|
1129
|
-
scoringResult.value = result;
|
|
1130
|
-
return result;
|
|
1131
|
-
} catch (err) {
|
|
1132
|
-
error.value = err instanceof Error ? err.message : "Failed to score template";
|
|
1133
|
-
return null;
|
|
1134
|
-
} finally {
|
|
1135
|
-
isScoring.value = false;
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
async function fixFinding(blockContent, finding, mergeTags) {
|
|
1139
|
-
const templateId = getTemplateId();
|
|
1140
|
-
if (!templateId) return null;
|
|
1141
|
-
fixingFindingId.value = finding.id;
|
|
1142
|
-
fixStreamingText.value = "";
|
|
1143
|
-
fixError.value = null;
|
|
1144
|
-
try {
|
|
1145
|
-
const url = buildUrl(API_ROUTES["ai.fixFinding"], {
|
|
1146
|
-
project: authManager.projectId,
|
|
1147
|
-
tenant: authManager.tenantSlug,
|
|
1148
|
-
template: templateId
|
|
1149
|
-
});
|
|
1150
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
1151
|
-
method: "POST",
|
|
1152
|
-
headers: {
|
|
1153
|
-
"Content-Type": "application/json",
|
|
1154
|
-
Accept: "text/event-stream"
|
|
1155
|
-
},
|
|
1156
|
-
body: JSON.stringify({
|
|
1157
|
-
content: blockContent,
|
|
1158
|
-
finding: {
|
|
1159
|
-
id: finding.id,
|
|
1160
|
-
message: finding.message,
|
|
1161
|
-
suggestion: finding.suggestion,
|
|
1162
|
-
category: finding.category
|
|
1163
|
-
},
|
|
1164
|
-
mergeTags: mergeTags.map((p) => ({
|
|
1165
|
-
label: p.label,
|
|
1166
|
-
value: p.value
|
|
1167
|
-
}))
|
|
1168
|
-
})
|
|
1169
|
-
});
|
|
1170
|
-
if (!response.ok) {
|
|
1171
|
-
if (response.status === 403) throw new Error("aiGenerationNotAvailable");
|
|
1172
|
-
const errorData = await response.json().catch(() => null);
|
|
1173
|
-
throw new Error(errorData?.message || "Failed to fix finding");
|
|
1174
|
-
}
|
|
1175
|
-
const reader = response.body?.getReader();
|
|
1176
|
-
if (!reader) throw new Error("Failed to read stream");
|
|
1177
|
-
const decoder = new TextDecoder();
|
|
1178
|
-
let buffer = "";
|
|
1179
|
-
let result = null;
|
|
1180
|
-
while (true) {
|
|
1181
|
-
const { done, value } = await reader.read();
|
|
1182
|
-
if (done) break;
|
|
1183
|
-
buffer += decoder.decode(value, { stream: true });
|
|
1184
|
-
const lines = buffer.split("\n");
|
|
1185
|
-
buffer = lines.pop() ?? "";
|
|
1186
|
-
for (const line of lines) {
|
|
1187
|
-
if (!line.startsWith("data: ")) continue;
|
|
1188
|
-
let event;
|
|
1189
|
-
try {
|
|
1190
|
-
event = JSON.parse(line.slice(6));
|
|
1191
|
-
} catch {
|
|
1192
|
-
continue;
|
|
1193
|
-
}
|
|
1194
|
-
if (event.type === "text") fixStreamingText.value += event.text;
|
|
1195
|
-
else if (event.type === "error") throw new Error(event.message || "Failed to fix finding");
|
|
1196
|
-
else if (event.type === "done") result = event.content ?? null;
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
return result;
|
|
1200
|
-
} catch (err) {
|
|
1201
|
-
fixError.value = err instanceof Error ? err.message : "Failed to fix finding";
|
|
1202
|
-
return null;
|
|
1203
|
-
} finally {
|
|
1204
|
-
fixingFindingId.value = null;
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
function removeFinding(category, findingId) {
|
|
1208
|
-
if (!scoringResult.value) return;
|
|
1209
|
-
const cat = scoringResult.value.categories[category];
|
|
1210
|
-
if (!cat) return;
|
|
1211
|
-
cat.findings = cat.findings.filter((f) => f.id !== findingId);
|
|
1212
|
-
}
|
|
1213
|
-
function reset() {
|
|
1214
|
-
isScoring.value = false;
|
|
1215
|
-
scoringResult.value = null;
|
|
1216
|
-
error.value = null;
|
|
1217
|
-
fixingFindingId.value = null;
|
|
1218
|
-
fixStreamingText.value = "";
|
|
1219
|
-
fixError.value = null;
|
|
1220
|
-
}
|
|
1221
|
-
return {
|
|
1222
|
-
isScoring,
|
|
1223
|
-
scoringResult,
|
|
1224
|
-
error,
|
|
1225
|
-
fixingFindingId,
|
|
1226
|
-
fixStreamingText,
|
|
1227
|
-
fixError,
|
|
1228
|
-
score,
|
|
1229
|
-
fixFinding,
|
|
1230
|
-
removeFinding,
|
|
1231
|
-
reset
|
|
1232
|
-
};
|
|
1233
|
-
}
|
|
1234
|
-
//#endregion
|
|
1235
|
-
//#region src/cloud/design-reference.ts
|
|
1236
|
-
function useDesignReference(options) {
|
|
1237
|
-
const { authManager, getTemplateId, onApply, onError } = options;
|
|
1238
|
-
const isGenerating = ref(false);
|
|
1239
|
-
const error = ref(null);
|
|
1240
|
-
async function generate(input) {
|
|
1241
|
-
const templateId = getTemplateId();
|
|
1242
|
-
if (!templateId) throw new Error("Template must be saved before using design reference");
|
|
1243
|
-
isGenerating.value = true;
|
|
1244
|
-
error.value = null;
|
|
1245
|
-
try {
|
|
1246
|
-
const formData = new FormData();
|
|
1247
|
-
if (input.prompt) formData.append("prompt", input.prompt);
|
|
1248
|
-
if (input.imageUpload) formData.append("image_upload", input.imageUpload);
|
|
1249
|
-
if (input.pdfUpload) formData.append("pdf_upload", input.pdfUpload);
|
|
1250
|
-
const url = buildUrl(API_ROUTES["ai.generateFromDesign"], {
|
|
1251
|
-
project: authManager.projectId,
|
|
1252
|
-
tenant: authManager.tenantSlug,
|
|
1253
|
-
template: templateId
|
|
1254
|
-
});
|
|
1255
|
-
const response = await authManager.authenticatedFetch(url, {
|
|
1256
|
-
method: "POST",
|
|
1257
|
-
headers: { Accept: "text/event-stream" },
|
|
1258
|
-
body: formData
|
|
1259
|
-
});
|
|
1260
|
-
if (!response.ok) {
|
|
1261
|
-
const errorData = await response.json().catch(() => null);
|
|
1262
|
-
if (response.status === 403) throw new Error("aiGenerationNotAvailable");
|
|
1263
|
-
throw new Error(errorData?.message || "Failed to generate template from design");
|
|
1264
|
-
}
|
|
1265
|
-
const reader = response.body?.getReader();
|
|
1266
|
-
if (!reader) throw new Error("Failed to read stream");
|
|
1267
|
-
const decoder = new TextDecoder();
|
|
1268
|
-
let buffer = "";
|
|
1269
|
-
let result = null;
|
|
1270
|
-
while (true) {
|
|
1271
|
-
const { done, value } = await reader.read();
|
|
1272
|
-
if (done) break;
|
|
1273
|
-
buffer += decoder.decode(value, { stream: true });
|
|
1274
|
-
const lines = buffer.split("\n");
|
|
1275
|
-
buffer = lines.pop() ?? "";
|
|
1276
|
-
for (const line of lines) {
|
|
1277
|
-
if (!line.startsWith("data: ")) continue;
|
|
1278
|
-
const jsonStr = line.slice(6);
|
|
1279
|
-
let event;
|
|
1280
|
-
try {
|
|
1281
|
-
event = JSON.parse(jsonStr);
|
|
1282
|
-
} catch {
|
|
1283
|
-
continue;
|
|
1284
|
-
}
|
|
1285
|
-
if (event.type === "error") throw new Error(event.message || "Failed to generate template from design");
|
|
1286
|
-
if (event.type === "done") {
|
|
1287
|
-
result = event.content ?? null;
|
|
1288
|
-
if (result) onApply?.(result);
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
return result;
|
|
1293
|
-
} catch (err) {
|
|
1294
|
-
const wrappedError = err instanceof Error ? err : new Error("Failed to generate template from design", { cause: err });
|
|
1295
|
-
error.value = wrappedError.message;
|
|
1296
|
-
onError?.(wrappedError);
|
|
1297
|
-
return null;
|
|
1298
|
-
} finally {
|
|
1299
|
-
isGenerating.value = false;
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
|
-
function reset() {
|
|
1303
|
-
isGenerating.value = false;
|
|
1304
|
-
error.value = null;
|
|
1305
|
-
}
|
|
1306
|
-
return {
|
|
1307
|
-
isGenerating,
|
|
1308
|
-
error,
|
|
1309
|
-
generate,
|
|
1310
|
-
reset
|
|
1311
|
-
};
|
|
1312
|
-
}
|
|
1313
|
-
//#endregion
|
|
1314
688
|
//#region src/cloud/comments-provider.ts
|
|
1315
689
|
/** The Pusher event Cloud's backend fans comment writes out on. */
|
|
1316
690
|
const BROADCAST_EVENT = "comment-broadcast";
|
|
@@ -2090,6 +1464,6 @@ async function performHealthCheck(options = {}) {
|
|
|
2090
1464
|
};
|
|
2091
1465
|
}
|
|
2092
1466
|
//#endregion
|
|
2093
|
-
export { API_ROUTES, ApiClient, AuthManager, MediaApiClient, WebSocketClient, buildUrl, createCloudCommentsProvider, createCloudMediaProvider, createCloudRenderProvider, createCloudSavedBlocksProvider, createCloudTemplatesProvider, createCloudTestEmailProvider, createCloudVersionHistoryProvider, createSdkAuthManager, isFatalAuthError, performHealthCheck, resolveExportFonts, resolveWebSocketConfig,
|
|
1467
|
+
export { API_ROUTES, ApiClient, AuthManager, MediaApiClient, WebSocketClient, buildUrl, createCloudCommentsProvider, createCloudMediaProvider, createCloudRenderProvider, createCloudSavedBlocksProvider, createCloudTemplatesProvider, createCloudTestEmailProvider, createCloudVersionHistoryProvider, createSdkAuthManager, isFatalAuthError, performHealthCheck, resolveExportFonts, resolveWebSocketConfig, useExport, usePlanConfig, useTestEmail, useWebSocket };
|
|
2094
1468
|
|
|
2095
1469
|
//# sourceMappingURL=index.js.map
|