@promptbook/cli 0.113.0-4 → 0.113.0-8
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/apps/agents-server/src/app/admin/update/AdvancedOriginRepositoryPanel.tsx +76 -0
- package/apps/agents-server/src/app/admin/update/CurrentDeploymentCard.tsx +160 -0
- package/apps/agents-server/src/app/admin/update/PendingCommitsCard.tsx +86 -0
- package/apps/agents-server/src/app/admin/update/TargetEnvironmentCard.tsx +331 -0
- package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +20 -873
- package/apps/agents-server/src/app/admin/update/UpdateJobCard.tsx +329 -0
- package/apps/agents-server/src/app/admin/update/UpdateOverview.ts +74 -0
- package/apps/agents-server/src/app/admin/update/buildDeploymentTimeBehindLabel.ts +29 -0
- package/apps/agents-server/src/app/admin/update/formatHumanReadableTimestamp.ts +18 -0
- package/apps/agents-server/src/app/admin/update/getUpdateJobFailureMessage.ts +13 -0
- package/apps/agents-server/src/app/admin/update/getUpdateJobSuccessMessage.ts +13 -0
- package/apps/agents-server/src/app/admin/update/useUpdateClientState.ts +441 -0
- package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +13 -1
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/AgentCodePageClient.tsx +14 -559
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/AgentCodePageHeader.tsx +84 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/AgentCodePageSection.tsx +52 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/GeneratedCodePreview.tsx +138 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/GeneratedHarnessSection.tsx +98 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/SourceBookSection.tsx +66 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/TranspiledCodeErrorBanner.tsx +30 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/TranspiledCodeExportWarningBanner.tsx +62 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/Transpiler.ts +9 -0
- package/apps/agents-server/src/app/agents/[agentName]/export-as-transpiled-code/useAgentCodeExportState.ts +478 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/cloneMockedChatPreset.ts +17 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/confirmDeleteMockedChat.ts +16 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedMessage.ts +81 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedParticipant.ts +146 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/createDraftWithUpdatedSettings.ts +19 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/createDuplicatedDraft.ts +66 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/findMockedChatById.ts +51 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/persistMockedChats.ts +51 -0
- package/apps/agents-server/src/app/system/utilities/mocked-chats/useMockedChatsEditorState.ts +16 -426
- package/apps/agents-server/src/components/Homepage/buildFreeGraphBoxLayout.ts +446 -0
- package/apps/agents-server/src/components/Homepage/buildGraphLayoutNodes.ts +415 -157
- package/apps/agents-server/src/components/Homepage/useAgentsGraphCanvasState.ts +2 -1
- package/apps/agents-server/src/database/sqlite/$provideLocalSqliteSupabase.ts +3 -1541
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/LocalSqliteQueryBuilder.ts +623 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/LocalSqliteSupabaseClient.ts +64 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/ensureTable.ts +93 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteFilters.ts +202 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteMutationPayload.ts +131 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteRowOperations.ts +102 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteSql.ts +59 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteTableSchema.ts +329 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteTypes.ts +84 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/localSqliteValueCodec.ts +63 -0
- package/apps/agents-server/src/database/sqlite/localSqliteSupabase/normalizeSqliteError.ts +22 -0
- package/apps/agents-server/src/search/createDefaultServerSearchProviders/loadLocalOrganizationSearchDataset.ts +12 -1
- package/apps/agents-server/src/tools/send_email.ts +1 -2
- package/apps/agents-server/src/utils/agentOrganization/loadAgentOrganizationState.ts +13 -1
- package/apps/agents-server/src/utils/backup/createServerBackupZipStream.ts +7 -1382
- package/apps/agents-server/src/utils/backup/serverBackup/appendAgentBackupEntriesToZip.ts +27 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendConversationBackupEntriesToZip.ts +140 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendFileBackupEntriesToZip.ts +147 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendMessageBackupEntriesToZip.ts +65 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendMetadataBackupEntriesToZip.ts +39 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendSectionEntriesToZip.ts +92 -0
- package/apps/agents-server/src/utils/backup/serverBackup/appendUserBackupEntriesToZip.ts +80 -0
- package/apps/agents-server/src/utils/backup/serverBackup/createRedactedWalletBackupRecord.ts +34 -0
- package/apps/agents-server/src/utils/backup/serverBackup/createServerBackupManifest.ts +82 -0
- package/apps/agents-server/src/utils/backup/serverBackup/downloadBackupBinaryContent.ts +39 -0
- package/apps/agents-server/src/utils/backup/serverBackup/resolveFeedbackThreadMessages.ts +53 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupAttachments.ts +151 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupContext.ts +167 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupFilenames.ts +161 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupPreviews.ts +97 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupRowUtilities.ts +158 -0
- package/apps/agents-server/src/utils/backup/serverBackup/serverBackupTypes.ts +59 -0
- package/apps/agents-server/src/utils/createLocalAgentSourceImporter.ts +159 -0
- package/apps/agents-server/src/utils/createMissingImportedAgentFallback.ts +60 -0
- package/apps/agents-server/src/utils/customDomainRouting.ts +157 -12
- package/apps/agents-server/src/utils/externalChatRunner/processExternalUserChatJob.ts +1 -1
- package/apps/agents-server/src/utils/importAgentWithFallback.ts +1 -58
- package/apps/agents-server/src/utils/localAgentRouteReferences.ts +167 -0
- package/apps/agents-server/src/utils/localChatRunner/processLocalUserChatJob.ts +1 -1
- package/apps/agents-server/src/utils/managementApi/managementApiAgents.ts +17 -3
- package/apps/agents-server/src/utils/messages/sendMessage.ts +5 -3
- package/apps/agents-server/src/utils/resolveAgentStateFromSource.ts +7 -1
- package/apps/agents-server/src/utils/resolveInheritedAgentSource.ts +54 -5
- package/apps/agents-server/src/utils/resolveServerAgentContext.ts +12 -1
- package/apps/agents-server/src/utils/resolveStoredAgentState.ts +2 -1
- package/apps/agents-server/src/utils/speech-to-text/SpeechToTextFailoverRecognition/SpeechToTextFailoverRecognitionProviderRuntime.ts +0 -1
- package/apps/agents-server/src/utils/speech-to-text/SpeechToTextFailoverRecognition.ts +34 -2
- package/apps/agents-server/src/utils/userChat/userChatMessageLifecycle.ts +39 -9
- package/apps/agents-server/tests/e2e/support/ChatHistoryNavigationSupport.ts +5 -0
- package/esm/index.es.js +875 -60
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/find-refactor-candidates/find-refactor-candidates.d.ts +7 -0
- package/esm/scripts/find-refactor-candidates/selectMostImportantRefactorCandidates.d.ts +12 -0
- package/esm/scripts/run-codex-prompts/common/resolveCoderAgent.d.ts +20 -0
- package/esm/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +5 -0
- package/esm/scripts/run-codex-prompts/ui/buildCoderRunAgentVisual.d.ts +29 -0
- package/esm/scripts/run-codex-prompts/ui/buildCoderRunUiFrame.d.ts +4 -0
- package/esm/src/avatars/renderAvatarVisualAsciiArt.d.ts +75 -0
- package/esm/src/book-components/Chat/Chat/insertDictationChunk.d.ts +1 -1
- package/esm/src/book-components/Chat/Chat/insertDictationChunk.test.d.ts +1 -0
- package/esm/src/book-components/Chat/Chat/learnDictationDictionary.test.d.ts +1 -0
- package/esm/src/book-components/Chat/Chat/refineFinalDictationChunk.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/common/createPositiveIntegerOptionParser.d.ts +10 -0
- package/esm/src/utils/ascii-art/$detectTerminalAnsiColorDepth.d.ts +15 -0
- package/esm/src/utils/ascii-art/convertImageDataToAsciiArt.d.ts +80 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/avatars/avatarAnimationScheduler.ts +2 -1
- package/src/avatars/renderAvatarVisualAsciiArt.ts +138 -0
- package/src/avatars/visuals/octopus3d3AvatarVisual.ts +6 -2
- package/src/avatars/visuals/octopus3d4AvatarVisual.ts +14 -18
- package/src/book-components/Chat/Chat/insertDictationChunk.ts +3 -3
- package/src/book-components/Chat/Chat/learnDictationDictionary.ts +1 -1
- package/src/book-components/Chat/Chat/useChatInputAreaDictation.ts +133 -26
- package/src/cli/cli-commands/agents-server/buildAgentsServer.ts +3 -1
- package/src/cli/cli-commands/coder/boilerplateTemplates.ts +14 -21
- package/src/cli/cli-commands/coder/find-refactor-candidates.ts +9 -2
- package/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.ts +1 -4
- package/src/cli/cli-commands/coder/run.ts +3 -27
- package/src/cli/cli-commands/common/createPositiveIntegerOptionParser.ts +31 -0
- package/src/commitments/TEAM/TEAM.ts +5 -5
- package/src/other/templates/getTemplatesPipelineCollection.ts +770 -1169
- package/src/utils/ascii-art/$detectTerminalAnsiColorDepth.ts +45 -0
- package/src/utils/ascii-art/convertImageDataToAsciiArt.ts +396 -0
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -0
- package/umd/index.umd.js +875 -60
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/find-refactor-candidates/find-refactor-candidates.d.ts +7 -0
- package/umd/scripts/find-refactor-candidates/selectMostImportantRefactorCandidates.d.ts +12 -0
- package/umd/scripts/run-codex-prompts/common/resolveCoderAgent.d.ts +20 -0
- package/umd/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +5 -0
- package/umd/scripts/run-codex-prompts/ui/buildCoderRunAgentVisual.d.ts +29 -0
- package/umd/scripts/run-codex-prompts/ui/buildCoderRunUiFrame.d.ts +4 -0
- package/umd/src/avatars/renderAvatarVisualAsciiArt.d.ts +75 -0
- package/umd/src/book-components/Chat/Chat/insertDictationChunk.d.ts +1 -1
- package/umd/src/book-components/Chat/Chat/insertDictationChunk.test.d.ts +1 -0
- package/umd/src/book-components/Chat/Chat/learnDictationDictionary.test.d.ts +1 -0
- package/umd/src/book-components/Chat/Chat/refineFinalDictationChunk.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/common/createPositiveIntegerOptionParser.d.ts +10 -0
- package/umd/src/utils/ascii-art/$detectTerminalAnsiColorDepth.d.ts +15 -0
- package/umd/src/utils/ascii-art/convertImageDataToAsciiArt.d.ts +80 -0
- package/umd/src/version.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/common/resolveAgentSystemMessage.d.ts +0 -6
- package/umd/scripts/run-codex-prompts/common/resolveAgentSystemMessage.d.ts +0 -6
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import JSZip from 'jszip';
|
|
2
|
+
import type { ServerBackupSectionDefinition } from '../serverBackupSections';
|
|
3
|
+
import { loadBackupTableFilePayload, type ServerBackupContext } from './serverBackupContext';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Writes the legacy table-backed agent export while keeping the books tree unchanged.
|
|
7
|
+
*
|
|
8
|
+
* @param zip - ZIP archive being assembled.
|
|
9
|
+
* @param sectionRootPath - Root path for the agents section.
|
|
10
|
+
* @param sectionDefinition - Agents section definition.
|
|
11
|
+
* @param context - Shared backup context.
|
|
12
|
+
*
|
|
13
|
+
* @private function of `createServerBackupZipStream`
|
|
14
|
+
*/
|
|
15
|
+
export async function appendAgentBackupEntriesToZip(
|
|
16
|
+
zip: JSZip,
|
|
17
|
+
sectionRootPath: string,
|
|
18
|
+
sectionDefinition: ServerBackupSectionDefinition,
|
|
19
|
+
context: ServerBackupContext,
|
|
20
|
+
): Promise<void> {
|
|
21
|
+
const tableKeys = sectionDefinition.tables || [];
|
|
22
|
+
|
|
23
|
+
for (const tableKey of tableKeys) {
|
|
24
|
+
const tablePayload = await loadBackupTableFilePayload(context.supabase, tableKey);
|
|
25
|
+
zip.file(`${sectionRootPath}/${tableKey}.json`, `${JSON.stringify(tablePayload, null, 2)}\n`);
|
|
26
|
+
}
|
|
27
|
+
}
|
package/apps/agents-server/src/utils/backup/serverBackup/appendConversationBackupEntriesToZip.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import JSZip from 'jszip';
|
|
2
|
+
import { resolveFeedbackThreadMessages } from './resolveFeedbackThreadMessages';
|
|
3
|
+
import {
|
|
4
|
+
loadAgentRows,
|
|
5
|
+
loadChatFeedbackRows,
|
|
6
|
+
loadUserChatRows,
|
|
7
|
+
loadUserRows,
|
|
8
|
+
type ServerBackupContext,
|
|
9
|
+
} from './serverBackupContext';
|
|
10
|
+
import {
|
|
11
|
+
createBackupStem,
|
|
12
|
+
createJsonMetadataFilename,
|
|
13
|
+
createUniqueBackupFilename,
|
|
14
|
+
ensureJsonFilename,
|
|
15
|
+
} from './serverBackupFilenames';
|
|
16
|
+
import { createAgentPreviewByName, createAgentPreviewByPermanentId, createUserPreviewById } from './serverBackupPreviews';
|
|
17
|
+
import { normalizeOptionalText, resolveSerializableArray } from './serverBackupRowUtilities';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Writes one JSON chat export per conversation and per feedback thread.
|
|
21
|
+
*
|
|
22
|
+
* @param zip - ZIP archive being assembled.
|
|
23
|
+
* @param sectionRootPath - Root path for the conversations section.
|
|
24
|
+
* @param context - Shared backup context.
|
|
25
|
+
*
|
|
26
|
+
* @private function of `createServerBackupZipStream`
|
|
27
|
+
*/
|
|
28
|
+
export async function appendConversationBackupEntriesToZip(
|
|
29
|
+
zip: JSZip,
|
|
30
|
+
sectionRootPath: string,
|
|
31
|
+
context: ServerBackupContext,
|
|
32
|
+
): Promise<void> {
|
|
33
|
+
const [userChats, users, agents, feedbackRows] = await Promise.all([
|
|
34
|
+
loadUserChatRows(context),
|
|
35
|
+
loadUserRows(context),
|
|
36
|
+
loadAgentRows(context),
|
|
37
|
+
loadChatFeedbackRows(context),
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
const chatsRootPath = `${sectionRootPath}/chats`;
|
|
41
|
+
const feedbackRootPath = `${sectionRootPath}/feedback`;
|
|
42
|
+
const usedChatFilenames = new Set<string>();
|
|
43
|
+
const usedFeedbackFilenames = new Set<string>();
|
|
44
|
+
const userPreviewById = createUserPreviewById(users);
|
|
45
|
+
const agentPreviewByPermanentId = createAgentPreviewByPermanentId(agents);
|
|
46
|
+
const agentPreviewByName = createAgentPreviewByName(agents);
|
|
47
|
+
|
|
48
|
+
zip.folder(chatsRootPath);
|
|
49
|
+
zip.folder(feedbackRootPath);
|
|
50
|
+
|
|
51
|
+
for (const chat of userChats) {
|
|
52
|
+
const userPreview = userPreviewById.get(chat.userId) || null;
|
|
53
|
+
const agentPreview = agentPreviewByPermanentId.get(chat.agentPermanentId) || {
|
|
54
|
+
id: 0,
|
|
55
|
+
agentName: chat.agentPermanentId,
|
|
56
|
+
permanentId: chat.agentPermanentId,
|
|
57
|
+
};
|
|
58
|
+
const chatMessages = resolveSerializableArray(chat.messages);
|
|
59
|
+
const preferredFilename = ensureJsonFilename(
|
|
60
|
+
createBackupStem(
|
|
61
|
+
[userPreview?.username, agentPreview.agentName, normalizeOptionalText(chat.title), 'conversation'],
|
|
62
|
+
`chat-${chat.id}`,
|
|
63
|
+
),
|
|
64
|
+
);
|
|
65
|
+
const filename = createUniqueBackupFilename(
|
|
66
|
+
usedChatFilenames,
|
|
67
|
+
preferredFilename,
|
|
68
|
+
`chat-${chat.id}`,
|
|
69
|
+
);
|
|
70
|
+
const metadataFilename = createJsonMetadataFilename(filename);
|
|
71
|
+
|
|
72
|
+
zip.file(`${chatsRootPath}/${filename}`, `${JSON.stringify(chatMessages, null, 2)}\n`);
|
|
73
|
+
zip.file(
|
|
74
|
+
`${chatsRootPath}/${metadataFilename}`,
|
|
75
|
+
`${JSON.stringify(
|
|
76
|
+
{
|
|
77
|
+
kind: 'user-chat',
|
|
78
|
+
chatId: chat.id,
|
|
79
|
+
title: chat.title,
|
|
80
|
+
createdAt: chat.createdAt,
|
|
81
|
+
updatedAt: chat.updatedAt,
|
|
82
|
+
lastMessageAt: chat.lastMessageAt,
|
|
83
|
+
source: chat.source,
|
|
84
|
+
draftMessage: chat.draftMessage,
|
|
85
|
+
messageCount: chatMessages.length,
|
|
86
|
+
user: userPreview,
|
|
87
|
+
agent: agentPreview,
|
|
88
|
+
},
|
|
89
|
+
null,
|
|
90
|
+
2,
|
|
91
|
+
)}\n`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
for (const feedback of feedbackRows) {
|
|
96
|
+
const { messages, rawChatThreadText } = resolveFeedbackThreadMessages(feedback.chatThread);
|
|
97
|
+
const agentPreview = agentPreviewByName.get(feedback.agentName) || {
|
|
98
|
+
id: 0,
|
|
99
|
+
agentName: feedback.agentName,
|
|
100
|
+
permanentId: null,
|
|
101
|
+
};
|
|
102
|
+
const preferredFilename = ensureJsonFilename(
|
|
103
|
+
createBackupStem(
|
|
104
|
+
[feedback.agentName, normalizeOptionalText(feedback.textRating), `feedback ${feedback.id}`],
|
|
105
|
+
`feedback-${feedback.id}`,
|
|
106
|
+
),
|
|
107
|
+
);
|
|
108
|
+
const filename = createUniqueBackupFilename(
|
|
109
|
+
usedFeedbackFilenames,
|
|
110
|
+
preferredFilename,
|
|
111
|
+
`feedback-${feedback.id}`,
|
|
112
|
+
);
|
|
113
|
+
const metadataFilename = createJsonMetadataFilename(filename);
|
|
114
|
+
|
|
115
|
+
zip.file(`${feedbackRootPath}/${filename}`, `${JSON.stringify(messages, null, 2)}\n`);
|
|
116
|
+
zip.file(
|
|
117
|
+
`${feedbackRootPath}/${metadataFilename}`,
|
|
118
|
+
`${JSON.stringify(
|
|
119
|
+
{
|
|
120
|
+
kind: 'chat-feedback',
|
|
121
|
+
feedbackId: feedback.id,
|
|
122
|
+
createdAt: feedback.createdAt,
|
|
123
|
+
agent: agentPreview,
|
|
124
|
+
rating: feedback.rating,
|
|
125
|
+
textRating: feedback.textRating,
|
|
126
|
+
userNote: feedback.userNote,
|
|
127
|
+
expectedAnswer: feedback.expectedAnswer,
|
|
128
|
+
promptbookEngineVersion: feedback.promptbookEngineVersion,
|
|
129
|
+
url: feedback.url,
|
|
130
|
+
language: feedback.language,
|
|
131
|
+
platform: feedback.platform,
|
|
132
|
+
messageCount: messages.length,
|
|
133
|
+
...(rawChatThreadText ? { rawChatThreadText } : {}),
|
|
134
|
+
},
|
|
135
|
+
null,
|
|
136
|
+
2,
|
|
137
|
+
)}\n`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import JSZip from 'jszip';
|
|
2
|
+
import { downloadBackupBinaryContent } from './downloadBackupBinaryContent';
|
|
3
|
+
import {
|
|
4
|
+
createAttachmentReferencesByUrl,
|
|
5
|
+
resolveAttachmentReferencesForUrls,
|
|
6
|
+
} from './serverBackupAttachments';
|
|
7
|
+
import {
|
|
8
|
+
loadAgentRows,
|
|
9
|
+
loadChatFeedbackRows,
|
|
10
|
+
loadTableRows,
|
|
11
|
+
loadUserChatRows,
|
|
12
|
+
loadUserRows,
|
|
13
|
+
type ServerBackupContext,
|
|
14
|
+
} from './serverBackupContext';
|
|
15
|
+
import {
|
|
16
|
+
createBinaryMetadataFilename,
|
|
17
|
+
createUniqueBackupFilename,
|
|
18
|
+
resolveBinaryBackupFilename,
|
|
19
|
+
resolvePathBasename,
|
|
20
|
+
} from './serverBackupFilenames';
|
|
21
|
+
import {
|
|
22
|
+
createAgentPreviewById,
|
|
23
|
+
createAgentPreviewByName,
|
|
24
|
+
createAgentPreviewByPermanentId,
|
|
25
|
+
createUserPreviewById,
|
|
26
|
+
} from './serverBackupPreviews';
|
|
27
|
+
import { deduplicateSerializableObjects, normalizeOptionalText } from './serverBackupRowUtilities';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Writes uploaded files and generated images together with sidecar restore metadata.
|
|
31
|
+
*
|
|
32
|
+
* @param zip - ZIP archive being assembled.
|
|
33
|
+
* @param sectionRootPath - Root path for the files section.
|
|
34
|
+
* @param context - Shared backup context.
|
|
35
|
+
*
|
|
36
|
+
* @private function of `createServerBackupZipStream`
|
|
37
|
+
*/
|
|
38
|
+
export async function appendFileBackupEntriesToZip(
|
|
39
|
+
zip: JSZip,
|
|
40
|
+
sectionRootPath: string,
|
|
41
|
+
context: ServerBackupContext,
|
|
42
|
+
): Promise<void> {
|
|
43
|
+
const [fileRows, imageRows, users, agents, userChats, feedbackRows] = await Promise.all([
|
|
44
|
+
loadTableRows(context.supabase, 'File'),
|
|
45
|
+
loadTableRows(context.supabase, 'Image'),
|
|
46
|
+
loadUserRows(context),
|
|
47
|
+
loadAgentRows(context),
|
|
48
|
+
loadUserChatRows(context),
|
|
49
|
+
loadChatFeedbackRows(context),
|
|
50
|
+
]);
|
|
51
|
+
const uploadsRootPath = `${sectionRootPath}/uploads`;
|
|
52
|
+
const imagesRootPath = `${sectionRootPath}/images`;
|
|
53
|
+
const usedUploadFilenames = new Set<string>();
|
|
54
|
+
const usedImageFilenames = new Set<string>();
|
|
55
|
+
const userPreviewById = createUserPreviewById(users);
|
|
56
|
+
const agentPreviewById = createAgentPreviewById(agents);
|
|
57
|
+
const agentPreviewByPermanentId = createAgentPreviewByPermanentId(agents);
|
|
58
|
+
const agentPreviewByName = createAgentPreviewByName(agents);
|
|
59
|
+
const attachmentReferencesByUrl = createAttachmentReferencesByUrl({
|
|
60
|
+
userChats,
|
|
61
|
+
feedbackRows,
|
|
62
|
+
userPreviewById,
|
|
63
|
+
agentPreviewByPermanentId,
|
|
64
|
+
agentPreviewByName,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
zip.folder(uploadsRootPath);
|
|
68
|
+
zip.folder(imagesRootPath);
|
|
69
|
+
|
|
70
|
+
for (const fileRow of fileRows) {
|
|
71
|
+
const contentUrl = normalizeOptionalText(fileRow.storageUrl) || normalizeOptionalText(fileRow.shortUrl);
|
|
72
|
+
const filename = createUniqueBackupFilename(
|
|
73
|
+
usedUploadFilenames,
|
|
74
|
+
resolveBinaryBackupFilename(fileRow.fileName, contentUrl, `file-${fileRow.id}`),
|
|
75
|
+
`file-${fileRow.id}`,
|
|
76
|
+
);
|
|
77
|
+
const downloadResult = await downloadBackupBinaryContent(contentUrl);
|
|
78
|
+
const attachedToMessages = deduplicateSerializableObjects(
|
|
79
|
+
resolveAttachmentReferencesForUrls(
|
|
80
|
+
attachmentReferencesByUrl,
|
|
81
|
+
[fileRow.storageUrl, fileRow.shortUrl],
|
|
82
|
+
),
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
if (downloadResult.content) {
|
|
86
|
+
zip.file(`${uploadsRootPath}/${filename}`, downloadResult.content);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
zip.file(
|
|
90
|
+
`${uploadsRootPath}/${createBinaryMetadataFilename(filename)}`,
|
|
91
|
+
`${JSON.stringify(
|
|
92
|
+
{
|
|
93
|
+
kind: 'uploaded-file',
|
|
94
|
+
id: fileRow.id,
|
|
95
|
+
createdAt: fileRow.createdAt,
|
|
96
|
+
originalFileName: resolvePathBasename(fileRow.fileName, `file-${fileRow.id}`),
|
|
97
|
+
fileType: fileRow.fileType,
|
|
98
|
+
fileSize: fileRow.fileSize,
|
|
99
|
+
purpose: fileRow.purpose,
|
|
100
|
+
status: fileRow.status,
|
|
101
|
+
uploadedBy: typeof fileRow.userId === 'number' ? userPreviewById.get(fileRow.userId) || null : null,
|
|
102
|
+
agent: typeof fileRow.agentId === 'number' ? agentPreviewById.get(fileRow.agentId) || null : null,
|
|
103
|
+
attachedToMessages,
|
|
104
|
+
contentUrl,
|
|
105
|
+
contentIncluded: Boolean(downloadResult.content),
|
|
106
|
+
...(downloadResult.error ? { contentDownloadError: downloadResult.error } : {}),
|
|
107
|
+
},
|
|
108
|
+
null,
|
|
109
|
+
2,
|
|
110
|
+
)}\n`,
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
for (const imageRow of imageRows) {
|
|
115
|
+
const filename = createUniqueBackupFilename(
|
|
116
|
+
usedImageFilenames,
|
|
117
|
+
resolveBinaryBackupFilename(imageRow.filename, imageRow.cdnUrl, `image-${imageRow.id}`),
|
|
118
|
+
`image-${imageRow.id}`,
|
|
119
|
+
);
|
|
120
|
+
const downloadResult = await downloadBackupBinaryContent(imageRow.cdnUrl);
|
|
121
|
+
|
|
122
|
+
if (downloadResult.content) {
|
|
123
|
+
zip.file(`${imagesRootPath}/${filename}`, downloadResult.content);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
zip.file(
|
|
127
|
+
`${imagesRootPath}/${createBinaryMetadataFilename(filename)}`,
|
|
128
|
+
`${JSON.stringify(
|
|
129
|
+
{
|
|
130
|
+
kind: 'generated-image',
|
|
131
|
+
id: imageRow.id,
|
|
132
|
+
createdAt: imageRow.createdAt,
|
|
133
|
+
updatedAt: imageRow.updatedAt,
|
|
134
|
+
filename: imageRow.filename,
|
|
135
|
+
prompt: imageRow.prompt,
|
|
136
|
+
purpose: imageRow.purpose,
|
|
137
|
+
agent: typeof imageRow.agentId === 'number' ? agentPreviewById.get(imageRow.agentId) || null : null,
|
|
138
|
+
contentUrl: imageRow.cdnUrl,
|
|
139
|
+
contentIncluded: Boolean(downloadResult.content),
|
|
140
|
+
...(downloadResult.error ? { contentDownloadError: downloadResult.error } : {}),
|
|
141
|
+
},
|
|
142
|
+
null,
|
|
143
|
+
2,
|
|
144
|
+
)}\n`,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import JSZip from 'jszip';
|
|
2
|
+
import { loadTableRows, type ServerBackupContext } from './serverBackupContext';
|
|
3
|
+
import { createBackupStem, createUniqueBackupFilename, ensureJsonFilename } from './serverBackupFilenames';
|
|
4
|
+
import { groupRowsBy } from './serverBackupRowUtilities';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Writes one JSON file per system message with delivery history.
|
|
8
|
+
*
|
|
9
|
+
* @param zip - ZIP archive being assembled.
|
|
10
|
+
* @param sectionRootPath - Root path for the messages section.
|
|
11
|
+
* @param context - Shared backup context.
|
|
12
|
+
*
|
|
13
|
+
* @private function of `createServerBackupZipStream`
|
|
14
|
+
*/
|
|
15
|
+
export async function appendMessageBackupEntriesToZip(
|
|
16
|
+
zip: JSZip,
|
|
17
|
+
sectionRootPath: string,
|
|
18
|
+
context: ServerBackupContext,
|
|
19
|
+
): Promise<void> {
|
|
20
|
+
const [messageRows, sendAttemptRows] = await Promise.all([
|
|
21
|
+
loadTableRows(context.supabase, 'Message'),
|
|
22
|
+
loadTableRows(context.supabase, 'MessageSendAttempt'),
|
|
23
|
+
]);
|
|
24
|
+
const usedMessageFilenames = new Set<string>();
|
|
25
|
+
const sendAttemptsByMessageId = groupRowsBy(sendAttemptRows, (row) => row.messageId);
|
|
26
|
+
|
|
27
|
+
for (const messageRow of messageRows) {
|
|
28
|
+
const filename = createUniqueBackupFilename(
|
|
29
|
+
usedMessageFilenames,
|
|
30
|
+
ensureJsonFilename(
|
|
31
|
+
createBackupStem(
|
|
32
|
+
[messageRow.channel, messageRow.direction, messageRow.createdAt],
|
|
33
|
+
`message-${messageRow.id}`,
|
|
34
|
+
),
|
|
35
|
+
),
|
|
36
|
+
`message-${messageRow.id}`,
|
|
37
|
+
);
|
|
38
|
+
const sendAttempts = sendAttemptsByMessageId.get(messageRow.id) || [];
|
|
39
|
+
|
|
40
|
+
zip.file(
|
|
41
|
+
`${sectionRootPath}/${filename}`,
|
|
42
|
+
`${JSON.stringify(
|
|
43
|
+
{
|
|
44
|
+
id: messageRow.id,
|
|
45
|
+
createdAt: messageRow.createdAt,
|
|
46
|
+
channel: messageRow.channel,
|
|
47
|
+
direction: messageRow.direction,
|
|
48
|
+
sender: messageRow.sender,
|
|
49
|
+
recipients: messageRow.recipients,
|
|
50
|
+
content: messageRow.content,
|
|
51
|
+
threadId: messageRow.threadId,
|
|
52
|
+
metadata: messageRow.metadata,
|
|
53
|
+
sendAttempts: sendAttempts.map((row) => ({
|
|
54
|
+
id: row.id,
|
|
55
|
+
createdAt: row.createdAt,
|
|
56
|
+
providerName: row.providerName,
|
|
57
|
+
isSuccessful: row.isSuccessful,
|
|
58
|
+
})),
|
|
59
|
+
},
|
|
60
|
+
null,
|
|
61
|
+
2,
|
|
62
|
+
)}\n`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import JSZip from 'jszip';
|
|
2
|
+
import { loadTableRows, type ServerBackupContext } from './serverBackupContext';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Filename used for the flattened metadata and limits export.
|
|
6
|
+
*
|
|
7
|
+
* @private constant of `createServerBackupZipStream`
|
|
8
|
+
*/
|
|
9
|
+
const METADATA_AND_LIMITS_FILENAME = 'metadata-and-limits.json';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Writes the flattened metadata and limits file.
|
|
13
|
+
*
|
|
14
|
+
* @param zip - ZIP archive being assembled.
|
|
15
|
+
* @param sectionRootPath - Root path for the metadata section.
|
|
16
|
+
* @param context - Shared backup context.
|
|
17
|
+
*
|
|
18
|
+
* @private function of `createServerBackupZipStream`
|
|
19
|
+
*/
|
|
20
|
+
export async function appendMetadataBackupEntriesToZip(
|
|
21
|
+
zip: JSZip,
|
|
22
|
+
sectionRootPath: string,
|
|
23
|
+
context: ServerBackupContext,
|
|
24
|
+
): Promise<void> {
|
|
25
|
+
const [metadataRows, serverLimitRows] = await Promise.all([
|
|
26
|
+
loadTableRows(context.supabase, 'Metadata'),
|
|
27
|
+
loadTableRows(context.supabase, 'ServerLimit'),
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
const keyValueEntries = [
|
|
31
|
+
...metadataRows.map((row) => [row.key, row.value] as const),
|
|
32
|
+
...serverLimitRows.map((row) => [row.key, row.value] as const),
|
|
33
|
+
].sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey));
|
|
34
|
+
|
|
35
|
+
zip.file(
|
|
36
|
+
`${sectionRootPath}/${METADATA_AND_LIMITS_FILENAME}`,
|
|
37
|
+
`${JSON.stringify(Object.fromEntries(keyValueEntries), null, 2)}\n`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import JSZip from 'jszip';
|
|
2
|
+
import type { ServerBackupSectionDefinition } from '../serverBackupSections';
|
|
3
|
+
import { appendAgentBackupEntriesToZip } from './appendAgentBackupEntriesToZip';
|
|
4
|
+
import { appendConversationBackupEntriesToZip } from './appendConversationBackupEntriesToZip';
|
|
5
|
+
import { appendFileBackupEntriesToZip } from './appendFileBackupEntriesToZip';
|
|
6
|
+
import { appendMessageBackupEntriesToZip } from './appendMessageBackupEntriesToZip';
|
|
7
|
+
import { appendMetadataBackupEntriesToZip } from './appendMetadataBackupEntriesToZip';
|
|
8
|
+
import { appendUserBackupEntriesToZip } from './appendUserBackupEntriesToZip';
|
|
9
|
+
import type { ServerBackupContext } from './serverBackupContext';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Filename used when a requested section intentionally exports no data.
|
|
13
|
+
*
|
|
14
|
+
* @private constant of `createServerBackupZipStream`
|
|
15
|
+
*/
|
|
16
|
+
const EXCLUDED_SECTION_FILENAME = 'excluded.json';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Appends one selected section into the ZIP archive.
|
|
20
|
+
*
|
|
21
|
+
* @param options - Section append options.
|
|
22
|
+
*
|
|
23
|
+
* @private function of `createServerBackupZipStream`
|
|
24
|
+
*/
|
|
25
|
+
export async function appendSectionEntriesToZip(options: {
|
|
26
|
+
zip: JSZip;
|
|
27
|
+
backupRootFolderName: string;
|
|
28
|
+
sectionDefinition: ServerBackupSectionDefinition;
|
|
29
|
+
context: ServerBackupContext;
|
|
30
|
+
}): Promise<void> {
|
|
31
|
+
const { zip, backupRootFolderName, sectionDefinition, context } = options;
|
|
32
|
+
const sectionRootPath = `${backupRootFolderName}/data/${sectionDefinition.directoryName}`;
|
|
33
|
+
zip.folder(sectionRootPath);
|
|
34
|
+
|
|
35
|
+
switch (sectionDefinition.key) {
|
|
36
|
+
case 'metadata':
|
|
37
|
+
await appendMetadataBackupEntriesToZip(zip, sectionRootPath, context);
|
|
38
|
+
return;
|
|
39
|
+
case 'agents':
|
|
40
|
+
await appendAgentBackupEntriesToZip(zip, sectionRootPath, sectionDefinition, context);
|
|
41
|
+
return;
|
|
42
|
+
case 'conversations':
|
|
43
|
+
await appendConversationBackupEntriesToZip(zip, sectionRootPath, context);
|
|
44
|
+
return;
|
|
45
|
+
case 'users':
|
|
46
|
+
await appendUserBackupEntriesToZip(zip, sectionRootPath, context);
|
|
47
|
+
return;
|
|
48
|
+
case 'files':
|
|
49
|
+
await appendFileBackupEntriesToZip(zip, sectionRootPath, context);
|
|
50
|
+
return;
|
|
51
|
+
case 'messages':
|
|
52
|
+
await appendMessageBackupEntriesToZip(zip, sectionRootPath, context);
|
|
53
|
+
return;
|
|
54
|
+
case 'security':
|
|
55
|
+
case 'caches':
|
|
56
|
+
appendExcludedSectionNoteToZip(zip, sectionRootPath, sectionDefinition);
|
|
57
|
+
return;
|
|
58
|
+
default: {
|
|
59
|
+
const exhaustiveSectionKey: never = sectionDefinition.key;
|
|
60
|
+
throw new Error(`Unsupported backup section ${String(exhaustiveSectionKey)}.`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Writes the explanatory note for a section that is intentionally excluded from the archive.
|
|
67
|
+
*
|
|
68
|
+
* @param zip - ZIP archive being assembled.
|
|
69
|
+
* @param sectionRootPath - Root path for the excluded section.
|
|
70
|
+
* @param sectionDefinition - Excluded section definition.
|
|
71
|
+
*
|
|
72
|
+
* @private function of `createServerBackupZipStream`
|
|
73
|
+
*/
|
|
74
|
+
function appendExcludedSectionNoteToZip(
|
|
75
|
+
zip: JSZip,
|
|
76
|
+
sectionRootPath: string,
|
|
77
|
+
sectionDefinition: ServerBackupSectionDefinition,
|
|
78
|
+
): void {
|
|
79
|
+
zip.file(
|
|
80
|
+
`${sectionRootPath}/${EXCLUDED_SECTION_FILENAME}`,
|
|
81
|
+
`${JSON.stringify(
|
|
82
|
+
{
|
|
83
|
+
key: sectionDefinition.key,
|
|
84
|
+
label: sectionDefinition.label,
|
|
85
|
+
included: false,
|
|
86
|
+
reason: sectionDefinition.description,
|
|
87
|
+
},
|
|
88
|
+
null,
|
|
89
|
+
2,
|
|
90
|
+
)}\n`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import JSZip from 'jszip';
|
|
2
|
+
import { createRedactedWalletBackupRecord } from './createRedactedWalletBackupRecord';
|
|
3
|
+
import { loadAgentRows, loadTableRows, loadUserRows, type ServerBackupContext } from './serverBackupContext';
|
|
4
|
+
import { createBackupStem, createUniqueBackupFilename, ensureJsonFilename } from './serverBackupFilenames';
|
|
5
|
+
import { createAgentPreviewByPermanentId } from './serverBackupPreviews';
|
|
6
|
+
import { groupRowsBy } from './serverBackupRowUtilities';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Writes one JSON file per user with related memories, structured data, and redacted wallet entries.
|
|
10
|
+
*
|
|
11
|
+
* @param zip - ZIP archive being assembled.
|
|
12
|
+
* @param sectionRootPath - Root path for the users section.
|
|
13
|
+
* @param context - Shared backup context.
|
|
14
|
+
*
|
|
15
|
+
* @private function of `createServerBackupZipStream`
|
|
16
|
+
*/
|
|
17
|
+
export async function appendUserBackupEntriesToZip(
|
|
18
|
+
zip: JSZip,
|
|
19
|
+
sectionRootPath: string,
|
|
20
|
+
context: ServerBackupContext,
|
|
21
|
+
): Promise<void> {
|
|
22
|
+
const [users, agents, memoryRows, userDataRows, walletRows] = await Promise.all([
|
|
23
|
+
loadUserRows(context),
|
|
24
|
+
loadAgentRows(context),
|
|
25
|
+
loadTableRows(context.supabase, 'UserMemory'),
|
|
26
|
+
loadTableRows(context.supabase, 'UserData'),
|
|
27
|
+
loadTableRows(context.supabase, 'Wallet'),
|
|
28
|
+
]);
|
|
29
|
+
const usedUserFilenames = new Set<string>();
|
|
30
|
+
const agentPreviewByPermanentId = createAgentPreviewByPermanentId(agents);
|
|
31
|
+
const memoryRowsByUserId = groupRowsBy(memoryRows, (row) => row.userId);
|
|
32
|
+
const userDataRowsByUserId = groupRowsBy(userDataRows, (row) => row.userId);
|
|
33
|
+
const walletRowsByUserId = groupRowsBy(walletRows, (row) => row.userId);
|
|
34
|
+
|
|
35
|
+
for (const user of users) {
|
|
36
|
+
const filename = createUniqueBackupFilename(
|
|
37
|
+
usedUserFilenames,
|
|
38
|
+
ensureJsonFilename(createBackupStem([user.username], `user-${user.id}`)),
|
|
39
|
+
`user-${user.id}`,
|
|
40
|
+
);
|
|
41
|
+
const userMemoryRows = memoryRowsByUserId.get(user.id) || [];
|
|
42
|
+
const scopedUserDataRows = userDataRowsByUserId.get(user.id) || [];
|
|
43
|
+
const scopedWalletRows = walletRowsByUserId.get(user.id) || [];
|
|
44
|
+
|
|
45
|
+
zip.file(
|
|
46
|
+
`${sectionRootPath}/${filename}`,
|
|
47
|
+
`${JSON.stringify(
|
|
48
|
+
{
|
|
49
|
+
user: {
|
|
50
|
+
id: user.id,
|
|
51
|
+
createdAt: user.createdAt,
|
|
52
|
+
updatedAt: user.updatedAt,
|
|
53
|
+
username: user.username,
|
|
54
|
+
isAdmin: user.isAdmin,
|
|
55
|
+
profileImageUrl: user.profileImageUrl,
|
|
56
|
+
},
|
|
57
|
+
memories: userMemoryRows.map((row) => ({
|
|
58
|
+
id: row.id,
|
|
59
|
+
createdAt: row.createdAt,
|
|
60
|
+
updatedAt: row.updatedAt,
|
|
61
|
+
content: row.content,
|
|
62
|
+
isGlobal: row.isGlobal,
|
|
63
|
+
deletedAt: row.deletedAt,
|
|
64
|
+
agent: row.agentPermanentId ? agentPreviewByPermanentId.get(row.agentPermanentId) || null : null,
|
|
65
|
+
})),
|
|
66
|
+
data: scopedUserDataRows.map((row) => ({
|
|
67
|
+
id: row.id,
|
|
68
|
+
createdAt: row.createdAt,
|
|
69
|
+
updatedAt: row.updatedAt,
|
|
70
|
+
key: row.key,
|
|
71
|
+
value: row.value,
|
|
72
|
+
})),
|
|
73
|
+
wallet: scopedWalletRows.map((row) => createRedactedWalletBackupRecord(row, agentPreviewByPermanentId)),
|
|
74
|
+
},
|
|
75
|
+
null,
|
|
76
|
+
2,
|
|
77
|
+
)}\n`,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { normalizeOptionalText } from './serverBackupRowUtilities';
|
|
2
|
+
import type { BackupAgentPreview, WalletRow } from './serverBackupTypes';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates the redacted wallet representation written into per-user backups.
|
|
6
|
+
*
|
|
7
|
+
* @param walletRow - Persisted wallet row.
|
|
8
|
+
* @param agentPreviewByPermanentId - Agent preview lookup for scoped records.
|
|
9
|
+
* @returns Redacted wallet record safe for backup export.
|
|
10
|
+
*
|
|
11
|
+
* @private function of `createServerBackupZipStream`
|
|
12
|
+
*/
|
|
13
|
+
export function createRedactedWalletBackupRecord(
|
|
14
|
+
walletRow: WalletRow,
|
|
15
|
+
agentPreviewByPermanentId: ReadonlyMap<string, BackupAgentPreview>,
|
|
16
|
+
): Record<string, unknown> {
|
|
17
|
+
return {
|
|
18
|
+
id: walletRow.id,
|
|
19
|
+
createdAt: walletRow.createdAt,
|
|
20
|
+
updatedAt: walletRow.updatedAt,
|
|
21
|
+
isUserScoped: walletRow.isUserScoped,
|
|
22
|
+
isGlobal: walletRow.isGlobal,
|
|
23
|
+
deletedAt: walletRow.deletedAt,
|
|
24
|
+
recordType: walletRow.recordType,
|
|
25
|
+
service: walletRow.service,
|
|
26
|
+
key: walletRow.key,
|
|
27
|
+
jsonSchema: walletRow.jsonSchema,
|
|
28
|
+
username: walletRow.username,
|
|
29
|
+
agent: walletRow.agentPermanentId ? agentPreviewByPermanentId.get(walletRow.agentPermanentId) || null : null,
|
|
30
|
+
hasPassword: Boolean(normalizeOptionalText(walletRow.password)),
|
|
31
|
+
hasSecret: Boolean(normalizeOptionalText(walletRow.secret)),
|
|
32
|
+
hasCookies: Boolean(normalizeOptionalText(walletRow.cookies)),
|
|
33
|
+
};
|
|
34
|
+
}
|