@bbigbang/core 0.1.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/dist/config.js +380 -0
- package/dist/execution/executionDispatcher.js +3810 -0
- package/dist/main.js +90 -0
- package/dist/nodeEventHistory.js +206 -0
- package/dist/scheduler/dreamLogic.js +50 -0
- package/dist/scheduler/dreamScheduler.js +65 -0
- package/dist/services/agentFileAccessService.js +1913 -0
- package/dist/services/agentRuntimeCleanupBroker.js +62 -0
- package/dist/services/agentSkillsBroker.js +118 -0
- package/dist/services/agentSkillsService.js +83 -0
- package/dist/services/agentWorkspaceBroker.js +937 -0
- package/dist/services/agentWorkspaceService.js +70 -0
- package/dist/services/appVersion.js +14 -0
- package/dist/services/auth.js +586 -0
- package/dist/services/claudeControlBroker.js +154 -0
- package/dist/services/claudeTranscriptBroker.js +100 -0
- package/dist/services/claudeTranscriptService.js +359 -0
- package/dist/services/codexAppServerBroker.js +155 -0
- package/dist/services/codexTranscriptBroker.js +98 -0
- package/dist/services/codexTranscriptService.js +961 -0
- package/dist/services/droidMissionBroker.js +124 -0
- package/dist/services/droidMissionImporter.js +630 -0
- package/dist/services/droidModelOptions.js +165 -0
- package/dist/services/hubServerRegistrationService.js +268 -0
- package/dist/services/libraryManifest.js +43 -0
- package/dist/services/libraryScaffold.js +26 -0
- package/dist/services/libraryService.js +2263 -0
- package/dist/services/memoryService.js +386 -0
- package/dist/services/missionEvidence.js +377 -0
- package/dist/services/missionService.js +2361 -0
- package/dist/services/missionTrace.js +158 -0
- package/dist/services/nativeMissionBriefParser.js +120 -0
- package/dist/services/nativeMissionOrchestrator.js +2045 -0
- package/dist/services/nativeMissionReportGenerator.js +227 -0
- package/dist/services/nativeMissionValidationRunner.js +452 -0
- package/dist/services/nativeMissionWorkerBroker.js +190 -0
- package/dist/services/nodeRegistry.js +34 -0
- package/dist/services/nodeStateReconciler.js +97 -0
- package/dist/services/panelMediaScanner.js +119 -0
- package/dist/services/persistentRuntimeJsonlClient.js +153 -0
- package/dist/services/platformAgentPolicy.js +180 -0
- package/dist/services/platformAgentService.js +2041 -0
- package/dist/services/projectAccessResolver.js +93 -0
- package/dist/services/projectService.js +392 -0
- package/dist/services/resourceSpaceService.js +140 -0
- package/dist/services/scenarioRuntimeService.js +1130 -0
- package/dist/services/suggestedPlannerService.js +868 -0
- package/dist/services/workbenchGitBroker.js +161 -0
- package/dist/services/workbenchGitService.js +69 -0
- package/dist/services/workbenchInspectBroker.js +65 -0
- package/dist/services/workbenchNodePathService.js +79 -0
- package/dist/services/workbenchRegistryService.js +240 -0
- package/dist/services/workbenchRootService.js +181 -0
- package/dist/services/workbenchTerminalBroker.js +378 -0
- package/dist/services/workspaceRunOwnership.js +60 -0
- package/dist/services/workspaceScaffold.js +105 -0
- package/dist/services/workspaceSessionRuntimeService.js +576 -0
- package/dist/services/workspaceSessionService.js +245 -0
- package/dist/services/workspaceToolActionRunner.js +1582 -0
- package/dist/services/workspaceToolErrors.js +10 -0
- package/dist/services/workspaceToolExecutionUtils.js +895 -0
- package/dist/services/workspaceToolLatestStateProjector.js +91 -0
- package/dist/services/workspaceToolManifest.js +572 -0
- package/dist/services/workspaceToolMutationQueue.js +43 -0
- package/dist/services/workspaceToolPanelProjection.js +460 -0
- package/dist/services/workspaceToolPromotion.js +255 -0
- package/dist/services/workspaceToolPromotionState.js +224 -0
- package/dist/services/workspaceToolPublishDiagnostics.js +189 -0
- package/dist/services/workspaceToolPublishIdentityResolver.js +146 -0
- package/dist/services/workspaceToolReadModel.js +378 -0
- package/dist/services/workspaceToolRunLedger.js +239 -0
- package/dist/services/workspaceToolService.js +3067 -0
- package/dist/services/workspaceToolSnapshotPanelSync.js +293 -0
- package/dist/services/workspaceToolTerminalLifecycle.js +283 -0
- package/dist/services/workspaceToolTypes.js +1 -0
- package/dist/services/workspaceToolUploadMaterializer.js +228 -0
- package/dist/web/actionCardRoutes.js +129 -0
- package/dist/web/actionCards.js +469 -0
- package/dist/web/activationContext.js +684 -0
- package/dist/web/agentChannelGuards.js +48 -0
- package/dist/web/agentMentionCooldowns.js +32 -0
- package/dist/web/agentReminders.js +1668 -0
- package/dist/web/agentRuntimePresence.js +197 -0
- package/dist/web/agentSelfState.js +494 -0
- package/dist/web/agentTaskLinks.js +26 -0
- package/dist/web/agentVisibility.js +79 -0
- package/dist/web/assets.js +95 -0
- package/dist/web/channelActivationPrompt.js +395 -0
- package/dist/web/channelMemoryNotes.js +127 -0
- package/dist/web/channelMentions.js +10 -0
- package/dist/web/channelMessageSequences.js +19 -0
- package/dist/web/channelSubscriptions.js +26 -0
- package/dist/web/clearedTaskRoots.js +10 -0
- package/dist/web/collaborationPromptGuidance.js +36 -0
- package/dist/web/collaborationSurfaceState.js +140 -0
- package/dist/web/contextBundleRanking.js +154 -0
- package/dist/web/contextBundleResolver.js +488 -0
- package/dist/web/conversationBuiltinSkillRoots.js +50 -0
- package/dist/web/conversationControls.js +232 -0
- package/dist/web/conversationHandoffs.js +612 -0
- package/dist/web/conversationManager.js +2511 -0
- package/dist/web/conversationSummaries.js +876 -0
- package/dist/web/conversationSurfaceKinds.js +17 -0
- package/dist/web/conversationTargets.js +173 -0
- package/dist/web/directActivationPrompt.js +122 -0
- package/dist/web/directReplyTargets.js +69 -0
- package/dist/web/directThreadResolver.js +129 -0
- package/dist/web/dmTaskHandoffPrompt.js +120 -0
- package/dist/web/dmTaskThreadStatusProjection.js +229 -0
- package/dist/web/ftsQuery.js +33 -0
- package/dist/web/internalAgentRouter.js +11341 -0
- package/dist/web/libraryCuratorScheduler.js +58 -0
- package/dist/web/libraryDocumentPromptGuidance.js +8 -0
- package/dist/web/messageCheckpoints.js +19 -0
- package/dist/web/nodeWsHandler.js +2495 -0
- package/dist/web/notificationRounds.js +1061 -0
- package/dist/web/panelActionMessages.js +108 -0
- package/dist/web/panelActivationPrompt.js +18 -0
- package/dist/web/panelAudit.js +273 -0
- package/dist/web/panelLifecycle.js +222 -0
- package/dist/web/panelMediaPolicy.js +43 -0
- package/dist/web/panelPathPolicy.js +63 -0
- package/dist/web/panelPreviews.js +175 -0
- package/dist/web/panelQueryHandles.js +2749 -0
- package/dist/web/panelRoutes.js +2147 -0
- package/dist/web/panels.js +904 -0
- package/dist/web/peerInboxAggregates.js +1247 -0
- package/dist/web/planApprovalState.js +92 -0
- package/dist/web/platformAgentScheduler.js +66 -0
- package/dist/web/proactiveOpportunities.js +452 -0
- package/dist/web/promptContextSections.js +242 -0
- package/dist/web/promptHistorySanitizer.js +26 -0
- package/dist/web/promptSlashCommands.js +158 -0
- package/dist/web/rollingConversationSummary.js +453 -0
- package/dist/web/routeHelpers.js +11 -0
- package/dist/web/routes/handoff.js +288 -0
- package/dist/web/routes/history.js +345 -0
- package/dist/web/routes/memory.js +258 -0
- package/dist/web/routes/selfState.js +171 -0
- package/dist/web/routes/workspace.js +154 -0
- package/dist/web/runSurfaceWatermarks.js +431 -0
- package/dist/web/runtimeCapabilities.js +48 -0
- package/dist/web/sameAgentHandoffs.js +494 -0
- package/dist/web/server.js +15567 -0
- package/dist/web/sharedCollaborationCapsules.js +163 -0
- package/dist/web/soloSessionRelay.js +42 -0
- package/dist/web/soloWsHandler.js +138 -0
- package/dist/web/suggestedPlannerScheduler.js +56 -0
- package/dist/web/surfaceActivationPolicy.js +108 -0
- package/dist/web/surfaceCollaborators.js +61 -0
- package/dist/web/surfaceSystemStatus.js +263 -0
- package/dist/web/targetParticipants.js +77 -0
- package/dist/web/taskEvents.js +49 -0
- package/dist/web/taskLifecycleMessages.js +165 -0
- package/dist/web/taskLoops.js +732 -0
- package/dist/web/taskMemoryNotes.js +224 -0
- package/dist/web/taskNumbers.js +16 -0
- package/dist/web/taskOwnerGuards.js +49 -0
- package/dist/web/taskParticipantResolver.js +42 -0
- package/dist/web/taskParticipants.js +97 -0
- package/dist/web/taskSourceDetails.js +20 -0
- package/dist/web/taskStateViews.js +210 -0
- package/dist/web/taskStatusTransitions.js +9 -0
- package/dist/web/taskThreadFollowups.js +599 -0
- package/dist/web/taskThreadRuntimeClosure.js +685 -0
- package/dist/web/taskUpdateDelivery.js +104 -0
- package/dist/web/threadReplyContentHeuristics.js +30 -0
- package/dist/web/threadRoots.js +61 -0
- package/dist/web/threadTaskBindings.js +365 -0
- package/dist/web/uiPanelPromptGuidance.js +27 -0
- package/dist/web/workspaceMemoryHints.js +143 -0
- package/dist/web/workspaceToolPromptGuidance.js +30 -0
- package/dist/web/wsHandler.js +397 -0
- package/dist/web/wsSink.js +116 -0
- package/package.json +54 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
function isPathWithinRoot(candidatePath, rootPath) {
|
|
3
|
+
const relativePath = path.relative(rootPath, candidatePath);
|
|
4
|
+
return !(relativePath.startsWith('..') || path.isAbsolute(relativePath));
|
|
5
|
+
}
|
|
6
|
+
function resolveAllowedAbsolutePath(rawPath, allowedRoots) {
|
|
7
|
+
const absolutePath = path.resolve(rawPath);
|
|
8
|
+
let matchedRoot = null;
|
|
9
|
+
for (const rawRoot of allowedRoots) {
|
|
10
|
+
const normalizedRoot = path.resolve(rawRoot);
|
|
11
|
+
if (!isPathWithinRoot(absolutePath, normalizedRoot))
|
|
12
|
+
continue;
|
|
13
|
+
if (!matchedRoot || normalizedRoot.length > matchedRoot.length) {
|
|
14
|
+
matchedRoot = normalizedRoot;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (!matchedRoot) {
|
|
18
|
+
return {
|
|
19
|
+
ok: false,
|
|
20
|
+
reason: 'Absolute panel paths require an allowlisted root.',
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
ok: true,
|
|
25
|
+
absolutePath,
|
|
26
|
+
allowedRoot: matchedRoot,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function resolvePanelDatasetPath(workspaceRoot, datasetPath, config) {
|
|
30
|
+
if (path.isAbsolute(datasetPath)) {
|
|
31
|
+
return resolveAllowedAbsolutePath(datasetPath, config.panelAbsolutePathRoots);
|
|
32
|
+
}
|
|
33
|
+
const allowedRoot = path.resolve(workspaceRoot);
|
|
34
|
+
const absolutePath = path.resolve(allowedRoot, datasetPath);
|
|
35
|
+
if (!isPathWithinRoot(absolutePath, allowedRoot)) {
|
|
36
|
+
return { ok: false, reason: 'Dataset path escapes agent workspace.' };
|
|
37
|
+
}
|
|
38
|
+
return { ok: true, absolutePath, allowedRoot };
|
|
39
|
+
}
|
|
40
|
+
export function resolvePanelMediaPath(agentWorkspacePath, mediaPath, config, options) {
|
|
41
|
+
if (path.isAbsolute(mediaPath)) {
|
|
42
|
+
const resolved = resolveAllowedAbsolutePath(mediaPath, config.panelAbsolutePathRoots);
|
|
43
|
+
if (!resolved.ok) {
|
|
44
|
+
return { ok: false, statusCode: 403, error: resolved.reason };
|
|
45
|
+
}
|
|
46
|
+
return resolved;
|
|
47
|
+
}
|
|
48
|
+
if (!agentWorkspacePath) {
|
|
49
|
+
return { ok: false, statusCode: 503, error: 'Agent workspace unavailable' };
|
|
50
|
+
}
|
|
51
|
+
const workspaceRoot = path.resolve(agentWorkspacePath);
|
|
52
|
+
const allowedRoot = options?.allowedRelativeRoot
|
|
53
|
+
? path.resolve(workspaceRoot, options.allowedRelativeRoot)
|
|
54
|
+
: workspaceRoot;
|
|
55
|
+
if (!isPathWithinRoot(allowedRoot, workspaceRoot)) {
|
|
56
|
+
return { ok: false, statusCode: 403, error: 'Path outside workspace' };
|
|
57
|
+
}
|
|
58
|
+
const absolutePath = path.resolve(workspaceRoot, mediaPath);
|
|
59
|
+
if (!isPathWithinRoot(absolutePath, allowedRoot)) {
|
|
60
|
+
return { ok: false, statusCode: 403, error: 'Path outside workspace' };
|
|
61
|
+
}
|
|
62
|
+
return { ok: true, absolutePath, allowedRoot };
|
|
63
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
export const PANEL_PREVIEW_TTL_MS = 24 * 60 * 60 * 1000;
|
|
3
|
+
export function insertPanelPreview(db, params) {
|
|
4
|
+
const id = params.id ?? randomUUID();
|
|
5
|
+
const now = params.createdAt ?? Date.now();
|
|
6
|
+
const expiresAt = params.expiresAt ?? now + PANEL_PREVIEW_TTL_MS;
|
|
7
|
+
db.prepare(`INSERT INTO panel_previews(
|
|
8
|
+
id, agent_id, conversation_id, owner_user_id, run_id,
|
|
9
|
+
component, props_json, actions_json, dataset_source_json, source_json,
|
|
10
|
+
row_count, created_at, expires_at
|
|
11
|
+
)
|
|
12
|
+
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, params.agentId, params.conversationId, params.ownerUserId ?? null, params.runId ?? null, params.component, JSON.stringify(params.props ?? {}), JSON.stringify(params.actions ?? []), params.datasetSource ? JSON.stringify(params.datasetSource) : null, JSON.stringify(params.source ?? {}), params.rowCount ?? 0, now, expiresAt);
|
|
13
|
+
return id;
|
|
14
|
+
}
|
|
15
|
+
export function insertPanelPreviewRows(db, rows) {
|
|
16
|
+
const insert = db.prepare(`INSERT INTO panel_preview_rows(
|
|
17
|
+
preview_id, row_index, row_id, fields_json, media_json,
|
|
18
|
+
node_id, cached_asset_ids_json
|
|
19
|
+
)
|
|
20
|
+
VALUES(?, ?, ?, ?, ?, ?, ?)`);
|
|
21
|
+
for (const row of rows) {
|
|
22
|
+
const previewId = row.previewId ?? row.panelId;
|
|
23
|
+
insert.run(previewId, row.rowIndex, row.rowId ?? null, JSON.stringify(row.fields), JSON.stringify(row.media), row.nodeId ?? null, JSON.stringify(row.cachedAssetIds ?? {}));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function getPanelPreviewById(db, id) {
|
|
27
|
+
const row = db.prepare(`SELECT
|
|
28
|
+
id, agent_id as agentId, conversation_id as conversationId, owner_user_id as ownerUserId,
|
|
29
|
+
run_id as runId, component, props_json as propsJson, actions_json as actionsJson,
|
|
30
|
+
dataset_source_json as datasetSourceJson, source_json as sourceJson,
|
|
31
|
+
row_count as rowCount, created_at as createdAt, expires_at as expiresAt
|
|
32
|
+
FROM panel_previews
|
|
33
|
+
WHERE id = ?
|
|
34
|
+
LIMIT 1`).get(id);
|
|
35
|
+
if (!row)
|
|
36
|
+
return null;
|
|
37
|
+
const datasetSource = parseNullableJsonObject(row.datasetSourceJson);
|
|
38
|
+
return {
|
|
39
|
+
id: row.id,
|
|
40
|
+
agentId: row.agentId,
|
|
41
|
+
conversationId: row.conversationId,
|
|
42
|
+
ownerUserId: row.ownerUserId ?? undefined,
|
|
43
|
+
scopeType: 'direct',
|
|
44
|
+
scopeId: row.conversationId,
|
|
45
|
+
component: row.component,
|
|
46
|
+
props: parseJsonObject(row.propsJson),
|
|
47
|
+
actions: parseJsonArray(row.actionsJson),
|
|
48
|
+
rowCount: row.rowCount,
|
|
49
|
+
rowCountKnown: row.rowCount >= 0,
|
|
50
|
+
datasetSource: datasetSource ?? undefined,
|
|
51
|
+
status: 'idle',
|
|
52
|
+
progress: null,
|
|
53
|
+
result: null,
|
|
54
|
+
version: 1,
|
|
55
|
+
createdByRunId: row.runId ?? undefined,
|
|
56
|
+
createdAt: new Date(row.createdAt).toISOString(),
|
|
57
|
+
updatedAt: new Date(row.createdAt).toISOString(),
|
|
58
|
+
archivedAt: null,
|
|
59
|
+
source: parseJsonObject(row.sourceJson),
|
|
60
|
+
expiresAt: new Date(row.expiresAt).toISOString(),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export function isPanelPreviewExpired(preview) {
|
|
64
|
+
return Date.parse(preview.expiresAt) <= Date.now();
|
|
65
|
+
}
|
|
66
|
+
export function listPanelPreviewRows(db, previewId, options) {
|
|
67
|
+
const limit = Math.max(1, Math.min(100, Math.floor(options.limit || 50)));
|
|
68
|
+
const cursorRowIndex = parseCursor(options.cursor);
|
|
69
|
+
const conditions = ['preview_id = ?'];
|
|
70
|
+
const params = [previewId];
|
|
71
|
+
if (options.filterField && options.filterValue !== undefined) {
|
|
72
|
+
conditions.push(`${panelPreviewFieldJsonExtractExpression(options.filterField)} = ?`);
|
|
73
|
+
params.push(toSqlJsonValue(options.filterValue));
|
|
74
|
+
}
|
|
75
|
+
if (cursorRowIndex !== null) {
|
|
76
|
+
conditions.push('row_index > ?');
|
|
77
|
+
params.push(cursorRowIndex);
|
|
78
|
+
}
|
|
79
|
+
const orderBy = options.sortField
|
|
80
|
+
? `${panelPreviewFieldJsonExtractExpression(options.sortField)} ${options.sortDirection === 'desc' ? 'DESC' : 'ASC'}, row_index ASC`
|
|
81
|
+
: 'row_index ASC';
|
|
82
|
+
const rows = db.prepare(`SELECT row_index as rowIndex, row_id as rowId, fields_json as fieldsJson, media_json as mediaJson
|
|
83
|
+
FROM panel_preview_rows
|
|
84
|
+
WHERE ${conditions.join(' AND ')}
|
|
85
|
+
ORDER BY ${orderBy}
|
|
86
|
+
LIMIT ?`).all(...params, limit + 1);
|
|
87
|
+
const hasMore = rows.length > limit;
|
|
88
|
+
const resultRows = hasMore ? rows.slice(0, limit) : rows;
|
|
89
|
+
const lastRow = resultRows[resultRows.length - 1];
|
|
90
|
+
return {
|
|
91
|
+
rows: resultRows.map((row) => ({
|
|
92
|
+
rowIndex: row.rowIndex,
|
|
93
|
+
rowId: row.rowId,
|
|
94
|
+
fields: parseJsonObject(row.fieldsJson),
|
|
95
|
+
media: parseJsonObject(row.mediaJson),
|
|
96
|
+
})),
|
|
97
|
+
nextCursor: hasMore && lastRow
|
|
98
|
+
? Buffer.from(JSON.stringify({ ri: lastRow.rowIndex }), 'utf8').toString('base64')
|
|
99
|
+
: null,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export function getPanelPreviewRowByIndex(db, previewId, rowIndex) {
|
|
103
|
+
const row = db.prepare(`SELECT row_index as rowIndex, row_id as rowId, fields_json as fieldsJson, media_json as mediaJson,
|
|
104
|
+
node_id as nodeId
|
|
105
|
+
FROM panel_preview_rows
|
|
106
|
+
WHERE preview_id = ?
|
|
107
|
+
AND row_index = ?
|
|
108
|
+
LIMIT 1`).get(previewId, rowIndex);
|
|
109
|
+
if (!row)
|
|
110
|
+
return null;
|
|
111
|
+
return {
|
|
112
|
+
rowIndex: row.rowIndex,
|
|
113
|
+
rowId: row.rowId,
|
|
114
|
+
fields: parseJsonObject(row.fieldsJson),
|
|
115
|
+
media: parseJsonObject(row.mediaJson),
|
|
116
|
+
nodeId: row.nodeId,
|
|
117
|
+
cachedAssetIds: {},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export function deleteExpiredPanelPreviews(db, now = Date.now()) {
|
|
121
|
+
const result = db.prepare('DELETE FROM panel_previews WHERE expires_at <= ?').run(now);
|
|
122
|
+
return result.changes;
|
|
123
|
+
}
|
|
124
|
+
function parseJsonObject(value) {
|
|
125
|
+
if (!value)
|
|
126
|
+
return {};
|
|
127
|
+
try {
|
|
128
|
+
const parsed = JSON.parse(value);
|
|
129
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
130
|
+
? parsed
|
|
131
|
+
: {};
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function parseNullableJsonObject(value) {
|
|
138
|
+
if (!value)
|
|
139
|
+
return null;
|
|
140
|
+
const parsed = parseJsonObject(value);
|
|
141
|
+
return Object.keys(parsed).length > 0 ? parsed : null;
|
|
142
|
+
}
|
|
143
|
+
function parseJsonArray(value) {
|
|
144
|
+
if (!value)
|
|
145
|
+
return [];
|
|
146
|
+
try {
|
|
147
|
+
const parsed = JSON.parse(value);
|
|
148
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function parseCursor(cursor) {
|
|
155
|
+
if (!cursor)
|
|
156
|
+
return null;
|
|
157
|
+
try {
|
|
158
|
+
const parsed = JSON.parse(Buffer.from(cursor, 'base64').toString('utf8'));
|
|
159
|
+
return Number.isInteger(parsed.ri) ? Number(parsed.ri) : null;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function panelPreviewFieldJsonExtractExpression(field) {
|
|
166
|
+
const safePath = field
|
|
167
|
+
.split('.')
|
|
168
|
+
.map((part) => part.replace(/[^A-Za-z0-9_]/g, ''))
|
|
169
|
+
.filter(Boolean)
|
|
170
|
+
.join('.');
|
|
171
|
+
return `json_extract(fields_json, '$.${safePath}')`;
|
|
172
|
+
}
|
|
173
|
+
function toSqlJsonValue(value) {
|
|
174
|
+
return typeof value === 'boolean' ? (value ? 1 : 0) : value;
|
|
175
|
+
}
|