documentation-hub 5.7.2
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/.eslintrc.json +43 -0
- package/.github/workflows/build.yml +64 -0
- package/.github/workflows/ci.yml +39 -0
- package/.vscode/extensions.json +3 -0
- package/Current.md +97 -0
- package/DocHub_Image.png +0 -0
- package/README.md +666 -0
- package/USER_GUIDE.md +1173 -0
- package/Updater.md +311 -0
- package/build/256x256.png +0 -0
- package/build/512x512.png +0 -0
- package/build/app-update.yml +4 -0
- package/build/create-icon.js +208 -0
- package/build/icon.ico +0 -0
- package/build/icon.png +0 -0
- package/build/icon_1024x1024.png +0 -0
- package/dist/assets/Analytics-BpsG9895.js +1 -0
- package/dist/assets/Card-IAZin8kp.js +1 -0
- package/dist/assets/CurrentSession-B-rFkHvf.js +12 -0
- package/dist/assets/Dashboard-C_5gMb0q.js +1 -0
- package/dist/assets/Documents-CqZ25axS.js +1 -0
- package/dist/assets/Input-l89xwXBi.js +1 -0
- package/dist/assets/Reporting-DqdHJY_a.js +1 -0
- package/dist/assets/Search-XNbu5z_3.js +1 -0
- package/dist/assets/SessionManager-lH9hZfzH.js +1 -0
- package/dist/assets/Sessions-ClZOPYNc.js +1 -0
- package/dist/assets/Settings-DUEHGURa.js +11 -0
- package/dist/assets/index-8xUe8ptc.js +24 -0
- package/dist/assets/index-RYyJqF7O.css +1 -0
- package/dist/assets/path-BkOl0AGO.js +1 -0
- package/dist/assets/promises-ID_B9S-h.js +1 -0
- package/dist/assets/urlHelpers-TvgahX0r.js +1 -0
- package/dist/assets/useToast-yRSO1dkm.js +1 -0
- package/dist/assets/vendor-charts-RkGK5ROP.js +36 -0
- package/dist/assets/vendor-db-l0sNRNKZ.js +1 -0
- package/dist/assets/vendor-react-BVZ_anCF.js +4 -0
- package/dist/assets/vendor-search-Dw8P0qyA.js +1 -0
- package/dist/assets/vendor-ui-BU7NfluV.js +53 -0
- package/dist/electron/PowerAutomateApiService-LfW09ZGr.js +147 -0
- package/dist/electron/main-CXkNtyv-.js +19789 -0
- package/dist/electron/main.js +5 -0
- package/dist/electron/preload.js +1 -0
- package/dist/icon.png +0 -0
- package/dist/index.html +27 -0
- package/docs/CODEBASE_ANALYSIS_REPORT.md +309 -0
- package/docs/DEBUG_LOGGING_GUIDE.md +244 -0
- package/docs/README.md +115 -0
- package/docs/TOC_WIRING_GUIDE.md +344 -0
- package/docs/analysis/Bullet_Symbol_Bug_Analysis.md +136 -0
- package/docs/analysis/DOCXMLATER_ANALYSIS_SUMMARY.txt +169 -0
- package/docs/analysis/Document_Processing_Issues_Analysis.md +704 -0
- package/docs/analysis/FIELD_PRESERVATION_ANALYSIS.md +1200 -0
- package/docs/analysis/INDENTATION_PRESERVE_ANALYSIS.md +181 -0
- package/docs/analysis/INDENTATION_PRESERVE_IMPLEMENTATION.md +207 -0
- package/docs/analysis/List_Implementation.md +206 -0
- package/docs/analysis/List_Implementation_Accuracy_Report.md +366 -0
- package/docs/analysis/PROCESSING_OPTIONS_UI_UPDATES.md +220 -0
- package/docs/analysis/RefactorStyles.md +852 -0
- package/docs/analysis/STYLE_PARAMETER_ENHANCEMENT.md +143 -0
- package/docs/analysis/docxmlater-comparison-todo-2025-11-13.md +636 -0
- package/docs/analysis/docxmlater-implementation-analysis-2025-11-13.md +340 -0
- package/docs/analysis/docxmlater-template_ui-integration-analysis.md +263 -0
- package/docs/analysis/github-issues-to-create.md +237 -0
- package/docs/api/API_README.md +538 -0
- package/docs/api/API_REFERENCE.md +751 -0
- package/docs/api/TYPE_DEFINITIONS.md +869 -0
- package/docs/architecture/FONT_EMBEDDING_GUIDE.md +318 -0
- package/docs/architecture/docxmlater-functions-and-structure.md +726 -0
- package/docs/docxmlater-readme.md +1341 -0
- package/docs/fixes/EXECUTION_LOG_TEST_BASE.md +573 -0
- package/docs/fixes/HYPERLINK_TEXT_SANITIZATION.md +253 -0
- package/docs/fixes/README.md +37 -0
- package/docs/github-issues/issue-1-body.md +125 -0
- package/docs/github-issues/issue-10-body.md +850 -0
- package/docs/github-issues/issue-2-body.md +200 -0
- package/docs/github-issues/issue-3-body.md +270 -0
- package/docs/github-issues/issue-4-body.md +169 -0
- package/docs/github-issues/issue-5-body.md +173 -0
- package/docs/github-issues/issue-6-body.md +158 -0
- package/docs/github-issues/issue-7-body.md +171 -0
- package/docs/github-issues/issue-8-body.md +407 -0
- package/docs/github-issues/issue-9-body.md +515 -0
- package/docs/github-issues/issue-tracker.md +274 -0
- package/docs/github-issues/predictive-analysis-2025-10-18.md +2131 -0
- package/docs/implementation/List_Framework_Refactor_Plan.md +336 -0
- package/docs/implementation/PRIMARY_TEXT_COLOR_FEATURE.md +217 -0
- package/docs/implementation/RELEASE_PLAN_v2.1.0.md +362 -0
- package/docs/implementation/RefactorStyles.md +588 -0
- package/docs/implementation/implement-plan.md +489 -0
- package/docs/implementation/missing-helpers-implementation.md +391 -0
- package/docs/implementation/refactor-plan.md +520 -0
- package/docs/implementation/session-implementation-complete.md +233 -0
- package/docs/implementation/session-management-plan.md +250 -0
- package/docs/setup-checklist.md +77 -0
- package/docs/versions/changelog.md +345 -0
- package/electron/customUpdater.ts +656 -0
- package/electron/main.ts +2441 -0
- package/electron/memoryConfig.ts +187 -0
- package/electron/preload.ts +394 -0
- package/electron/proxyConfig.ts +340 -0
- package/electron/services/BackupService.ts +452 -0
- package/electron/services/DictionaryService.ts +402 -0
- package/electron/services/LocalDictionaryLookupService.ts +147 -0
- package/electron/services/PowerAutomateApiService.ts +231 -0
- package/electron/services/SharePointSyncService.ts +474 -0
- package/electron/windowsCertStore.ts +427 -0
- package/electron/zscalerConfig.ts +381 -0
- package/eslint.config.js +92 -0
- package/jest.config.js +52 -0
- package/package.json +214 -0
- package/postcss.config.mjs +6 -0
- package/public/icon.png +0 -0
- package/publish-release.ps1 +5 -0
- package/renovate.json +30 -0
- package/src/App.tsx +216 -0
- package/src/__mocks__/p-limit.js +12 -0
- package/src/__mocks__/styleMock.js +1 -0
- package/src/components/common/BugReportButton.tsx +44 -0
- package/src/components/common/BugReportDialog.tsx +193 -0
- package/src/components/common/Button.tsx +153 -0
- package/src/components/common/Card.tsx +86 -0
- package/src/components/common/ColorPickerDialog.tsx +177 -0
- package/src/components/common/ConfirmDialog.tsx +96 -0
- package/src/components/common/DebugConsole.tsx +275 -0
- package/src/components/common/EmptyState.tsx +183 -0
- package/src/components/common/ErrorBoundary.tsx +98 -0
- package/src/components/common/ErrorDetailsDialog.tsx +153 -0
- package/src/components/common/ErrorFallback.tsx +218 -0
- package/src/components/common/Input.tsx +109 -0
- package/src/components/common/Skeleton.tsx +184 -0
- package/src/components/common/SplashScreen.tsx +81 -0
- package/src/components/common/Toast.tsx +155 -0
- package/src/components/common/Tooltip.tsx +79 -0
- package/src/components/common/UpdateNotification.tsx +320 -0
- package/src/components/comparison/ComparisonWindow.tsx +374 -0
- package/src/components/comparison/SideBySideDiff.tsx +486 -0
- package/src/components/comparison/index.ts +8 -0
- package/src/components/document/DocumentUploader.tsx +288 -0
- package/src/components/document/HyperlinkPreview.tsx +430 -0
- package/src/components/document/HyperlinkService.md +1484 -0
- package/src/components/document/Hyperlink_Technical_Documentation.md +496 -0
- package/src/components/document/InlineChangesView.tsx +707 -0
- package/src/components/document/ProcessingProgress.tsx +303 -0
- package/src/components/document/ProcessingResults.tsx +256 -0
- package/src/components/document/TrackedChangesDetail.tsx +530 -0
- package/src/components/document/TrackedChangesPanel.tsx +546 -0
- package/src/components/document/VirtualDocumentList.tsx +240 -0
- package/src/components/editor/DocumentEditor.tsx +723 -0
- package/src/components/editor/DocumentEditorModal.tsx +640 -0
- package/src/components/editor/EditorQuickActions.tsx +502 -0
- package/src/components/editor/EditorToolbar.tsx +312 -0
- package/src/components/editor/TableEditor.tsx +926 -0
- package/src/components/editor/index.ts +18 -0
- package/src/components/layout/Header.tsx +190 -0
- package/src/components/layout/Sidebar.tsx +313 -0
- package/src/components/layout/TitleBar.tsx +190 -0
- package/src/components/navigation/CommandPalette.tsx +233 -0
- package/src/components/navigation/KeyboardShortcutsModal.tsx +173 -0
- package/src/components/sessions/ChangeItem.tsx +408 -0
- package/src/components/sessions/ChangeViewer.tsx +1155 -0
- package/src/components/sessions/DocumentComparisonModal.tsx +314 -0
- package/src/components/sessions/ProcessingOptions.tsx +297 -0
- package/src/components/sessions/ReplacementsTab.tsx +438 -0
- package/src/components/sessions/RevisionHandlingOptions.tsx +87 -0
- package/src/components/sessions/SessionManager.tsx +188 -0
- package/src/components/sessions/StylesEditor.tsx +1335 -0
- package/src/components/sessions/TabContainer.tsx +151 -0
- package/src/components/sessions/VirtualSessionList.tsx +157 -0
- package/src/components/sessions/sessionToProcessorManager.tsx +420 -0
- package/src/components/settings/CertificateManager.tsx +410 -0
- package/src/components/settings/SegmentedControl.tsx +88 -0
- package/src/components/settings/SettingRow.tsx +52 -0
- package/src/contexts/GlobalStatsContext.tsx +396 -0
- package/src/contexts/SessionContext.tsx +2129 -0
- package/src/contexts/ThemeContext.tsx +428 -0
- package/src/contexts/UserSettingsContext.tsx +290 -0
- package/src/contexts/__tests__/GlobalStatsContext.test.tsx +390 -0
- package/src/global.d.ts +273 -0
- package/src/hooks/useDocumentQueue.tsx +210 -0
- package/src/hooks/useToast.tsx +55 -0
- package/src/main.tsx +10 -0
- package/src/pages/Analytics.tsx +386 -0
- package/src/pages/CurrentSession.tsx +1174 -0
- package/src/pages/Dashboard.tsx +319 -0
- package/src/pages/Documents.tsx +317 -0
- package/src/pages/Projects.tsx +250 -0
- package/src/pages/Reporting.tsx +386 -0
- package/src/pages/Search.tsx +349 -0
- package/src/pages/Sessions.tsx +285 -0
- package/src/pages/Settings.tsx +2662 -0
- package/src/services/HyperlinkService.ts +1085 -0
- package/src/services/document/DocXMLaterProcessor.ts +617 -0
- package/src/services/document/DocumentProcessingComparison.ts +856 -0
- package/src/services/document/DocumentSnapshotService.ts +575 -0
- package/src/services/document/WordDocumentProcessor.ts +10509 -0
- package/src/services/document/__tests__/DocXMLaterProcessor.hyperlinks.test.md +311 -0
- package/src/services/document/__tests__/WordDocumentProcessor.integration.test.ts +515 -0
- package/src/services/document/__tests__/WordDocumentProcessor.test.ts +812 -0
- package/src/services/document/blanklines/BlankLineManager.ts +658 -0
- package/src/services/document/blanklines/__tests__/paragraphChecks.test.ts +281 -0
- package/src/services/document/blanklines/helpers/blankLineInsertion.ts +87 -0
- package/src/services/document/blanklines/helpers/blankLineSnapshot.ts +251 -0
- package/src/services/document/blanklines/helpers/clearCustom.ts +121 -0
- package/src/services/document/blanklines/helpers/contextChecks.ts +117 -0
- package/src/services/document/blanklines/helpers/imageChecks.ts +51 -0
- package/src/services/document/blanklines/helpers/paragraphChecks.ts +236 -0
- package/src/services/document/blanklines/helpers/removeBlanksBetweenListItems.ts +91 -0
- package/src/services/document/blanklines/helpers/removeTrailingBlanks.ts +35 -0
- package/src/services/document/blanklines/helpers/tableGuards.ts +21 -0
- package/src/services/document/blanklines/index.ts +67 -0
- package/src/services/document/blanklines/rules/additionRules.ts +337 -0
- package/src/services/document/blanklines/rules/indentationRules.ts +317 -0
- package/src/services/document/blanklines/rules/removalRules.ts +362 -0
- package/src/services/document/blanklines/rules/ruleTypes.ts +92 -0
- package/src/services/document/blanklines/types.ts +29 -0
- package/src/services/document/helpers/ImageBorderCropper.ts +377 -0
- package/src/services/document/helpers/__tests__/whitespace.test.ts +272 -0
- package/src/services/document/helpers/whitespace.ts +117 -0
- package/src/services/document/list/ListNormalizer.ts +947 -0
- package/src/services/document/list/index.ts +45 -0
- package/src/services/document/list/list-detection.ts +275 -0
- package/src/services/document/list/list-types.ts +162 -0
- package/src/services/document/processors/HyperlinkProcessor.ts +370 -0
- package/src/services/document/processors/ListProcessor.ts +257 -0
- package/src/services/document/processors/StructureProcessor.ts +176 -0
- package/src/services/document/processors/StyleProcessor.ts +389 -0
- package/src/services/document/processors/TableProcessor.ts +2238 -0
- package/src/services/document/processors/__tests__/HyperlinkProcessor.test.ts +314 -0
- package/src/services/document/processors/__tests__/ListProcessor.test.ts +291 -0
- package/src/services/document/processors/__tests__/StructureProcessor.test.ts +257 -0
- package/src/services/document/processors/__tests__/TableProcessor.hlp-tips-bullets.test.ts +459 -0
- package/src/services/document/processors/__tests__/TableProcessor.test.ts +1604 -0
- package/src/services/document/processors/index.ts +28 -0
- package/src/services/document/types/docx-processing.ts +310 -0
- package/src/services/editor/EditorActionHandlers.ts +901 -0
- package/src/services/editor/index.ts +13 -0
- package/src/setupTests.ts +47 -0
- package/src/styles/global.css +782 -0
- package/src/types/backup.ts +132 -0
- package/src/types/dictionary.ts +125 -0
- package/src/types/document-processing.ts +331 -0
- package/src/types/docxmlater-augments.d.ts +142 -0
- package/src/types/editor.ts +280 -0
- package/src/types/electron.ts +340 -0
- package/src/types/globalStats.ts +155 -0
- package/src/types/hyperlink.ts +471 -0
- package/src/types/operations.ts +354 -0
- package/src/types/session.ts +427 -0
- package/src/types/settings.ts +112 -0
- package/src/utils/MemoryMonitor.ts +248 -0
- package/src/utils/cn.ts +6 -0
- package/src/utils/colorConvert.ts +306 -0
- package/src/utils/diffUtils.ts +347 -0
- package/src/utils/documentUtils.ts +202 -0
- package/src/utils/electronGuard.ts +62 -0
- package/src/utils/indexedDB.ts +915 -0
- package/src/utils/logger.ts +717 -0
- package/src/utils/pathSecurity.ts +232 -0
- package/src/utils/pathValidator.ts +236 -0
- package/src/utils/processingTimeEstimator.ts +153 -0
- package/src/utils/safeJsonParse.ts +62 -0
- package/src/utils/textSanitizer.ts +162 -0
- package/src/utils/urlHelpers.ts +304 -0
- package/src/utils/urlPatterns.ts +198 -0
- package/src/utils/urlSanitizer.ts +152 -0
- package/src/vite-env.d.ts +11 -0
- package/tsconfig.electron.json +19 -0
- package/tsconfig.json +36 -0
- package/tsconfig.node.json +12 -0
- package/typedoc.json +45 -0
- package/vite.config.ts +152 -0
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session to Processor Mapper
|
|
3
|
+
*
|
|
4
|
+
* Provides type-safe conversion between Session (UI format) and WordProcessingOptions (Processor format)
|
|
5
|
+
* Prevents style transposition by ensuring all properties are correctly mapped and validated
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { WordProcessingOptions } from '../../services/document/WordDocumentProcessor';
|
|
9
|
+
import type { Session, SessionStyle, TableShadingSettings } from '../../types/session';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Normalize color from UI format (#RRGGBB) to OOXML format (RRGGBB)
|
|
13
|
+
*
|
|
14
|
+
* @param color - Color in hex format (with or without # prefix)
|
|
15
|
+
* @returns Color in OOXML format (6 hex digits, uppercase, no # prefix)
|
|
16
|
+
*/
|
|
17
|
+
function normalizeColor(color: string): string {
|
|
18
|
+
return color.replace('#', '').toUpperCase();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Validates that a color is in correct format (6 hex digits without # prefix)
|
|
23
|
+
*
|
|
24
|
+
* @param color - Color to validate
|
|
25
|
+
* @returns True if valid OOXML color format
|
|
26
|
+
*/
|
|
27
|
+
function isValidOOXMLColor(color: string): boolean {
|
|
28
|
+
return /^[0-9A-Fa-f]{6}$/.test(color);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Maps SessionStyle[] (UI format) to WordProcessingOptions.styles (Processor format)
|
|
33
|
+
*
|
|
34
|
+
* CRITICAL: Preserves ALL properties to prevent transposition
|
|
35
|
+
* - Includes preserve* flags for conditional formatting
|
|
36
|
+
* - Includes noSpaceBetweenSame for contextual spacing
|
|
37
|
+
* - Includes indentation for list paragraph positioning
|
|
38
|
+
* - Auto-normalizes colors from #RRGGBB to RRGGBB
|
|
39
|
+
*
|
|
40
|
+
* @param sessionStyles - Array of SessionStyle objects from UI
|
|
41
|
+
* @returns Array of style objects compatible with WordProcessingOptions
|
|
42
|
+
*/
|
|
43
|
+
export function mapSessionStylesToProcessor(
|
|
44
|
+
sessionStyles: SessionStyle[]
|
|
45
|
+
): NonNullable<WordProcessingOptions['styles']> {
|
|
46
|
+
return sessionStyles.map((style) => ({
|
|
47
|
+
// Identity
|
|
48
|
+
id: style.id,
|
|
49
|
+
name: style.name,
|
|
50
|
+
|
|
51
|
+
// Font properties
|
|
52
|
+
fontFamily: style.fontFamily,
|
|
53
|
+
fontSize: style.fontSize,
|
|
54
|
+
|
|
55
|
+
// Format properties
|
|
56
|
+
bold: style.bold,
|
|
57
|
+
italic: style.italic,
|
|
58
|
+
underline: style.underline,
|
|
59
|
+
|
|
60
|
+
// Preserve flags - CRITICAL for preventing transposition
|
|
61
|
+
preserveBold: style.preserveBold,
|
|
62
|
+
preserveItalic: style.preserveItalic,
|
|
63
|
+
preserveUnderline: style.preserveUnderline,
|
|
64
|
+
|
|
65
|
+
// Paragraph properties
|
|
66
|
+
alignment: style.alignment,
|
|
67
|
+
spaceBefore: style.spaceBefore,
|
|
68
|
+
spaceAfter: style.spaceAfter,
|
|
69
|
+
lineSpacing: style.lineSpacing,
|
|
70
|
+
|
|
71
|
+
// Advanced properties
|
|
72
|
+
color: normalizeColor(style.color), // Auto-normalize: #000000 → 000000
|
|
73
|
+
noSpaceBetweenSame: style.noSpaceBetweenSame,
|
|
74
|
+
indentation: style.indentation,
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Maps TableShadingSettings (UI format) to WordProcessingOptions.tableShadingSettings
|
|
80
|
+
*
|
|
81
|
+
* @param settings - Table shading settings from session
|
|
82
|
+
* @returns Normalized table shading settings for processor
|
|
83
|
+
*/
|
|
84
|
+
function mapTableShadingSettings(
|
|
85
|
+
settings: TableShadingSettings | undefined
|
|
86
|
+
): WordProcessingOptions['tableShadingSettings'] {
|
|
87
|
+
if (!settings) return undefined;
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
header2Shading: normalizeColor(settings.header2Shading),
|
|
91
|
+
otherShading: normalizeColor(settings.otherShading),
|
|
92
|
+
imageBorderWidth: settings.imageBorderWidth ?? 1.0,
|
|
93
|
+
cellBorderThickness: settings.cellBorderThickness ?? 0.5,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Maps Session.processingOptions.enabledOperations to WordProcessingOptions boolean flags
|
|
99
|
+
*
|
|
100
|
+
* This function provides the bridge between UI checkbox state and processor method execution:
|
|
101
|
+
* - UI stores array of enabled option IDs (e.g., ['remove-italics', 'smart-tables'])
|
|
102
|
+
* - Processor expects individual boolean flags and nested operations object
|
|
103
|
+
*
|
|
104
|
+
* @param enabledOperations - Array of enabled option IDs
|
|
105
|
+
* @returns Partial WordProcessingOptions with appropriate flags set
|
|
106
|
+
*/
|
|
107
|
+
function mapEnabledOperationsToFlags(enabledOperations: string[]): Partial<WordProcessingOptions> {
|
|
108
|
+
const enabled = new Set(enabledOperations);
|
|
109
|
+
const flags: Partial<WordProcessingOptions> = {};
|
|
110
|
+
|
|
111
|
+
// ═══════════════════════════════════════════════════════════
|
|
112
|
+
// Text Formatting Group
|
|
113
|
+
// ═══════════════════════════════════════════════════════════
|
|
114
|
+
if (enabled.has('remove-italics')) flags.removeItalics = true;
|
|
115
|
+
if (enabled.has('normalize-dashes')) flags.normalizeDashes = true;
|
|
116
|
+
if (enabled.has('remove-whitespace')) flags.removeWhitespace = true;
|
|
117
|
+
|
|
118
|
+
// ═══════════════════════════════════════════════════════════
|
|
119
|
+
// Content Structure Group
|
|
120
|
+
// ═══════════════════════════════════════════════════════════
|
|
121
|
+
if (enabled.has('remove-paragraph-lines')) flags.removeParagraphLines = true;
|
|
122
|
+
if (enabled.has('remove-headers-footers')) flags.removeHeadersFooters = true;
|
|
123
|
+
if (enabled.has('add-document-warning')) flags.addDocumentWarning = true;
|
|
124
|
+
if (enabled.has('center-border-images')) flags.centerAndBorderImages = true;
|
|
125
|
+
|
|
126
|
+
// ═══════════════════════════════════════════════════════════
|
|
127
|
+
// Lists & Tables Group
|
|
128
|
+
// ═══════════════════════════════════════════════════════════
|
|
129
|
+
if (enabled.has('list-indentation')) {
|
|
130
|
+
// Special case: list-indentation sets listBulletSettings.enabled
|
|
131
|
+
// CRITICAL FIX: Do NOT create the object here - just set the enabled flag
|
|
132
|
+
// The actual indentationLevels will be populated from session.listBulletSettings
|
|
133
|
+
// to preserve UI-configured indentation values
|
|
134
|
+
if (!flags.listBulletSettings) {
|
|
135
|
+
flags.listBulletSettings = { enabled: true } as any;
|
|
136
|
+
} else {
|
|
137
|
+
flags.listBulletSettings.enabled = true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (enabled.has('bullet-uniformity')) flags.bulletUniformity = true;
|
|
141
|
+
if (enabled.has('smart-tables')) {
|
|
142
|
+
flags.smartTables = true;
|
|
143
|
+
flags.tableUniformity = true; // Auto-enable table uniformity with smart tables
|
|
144
|
+
}
|
|
145
|
+
if (enabled.has('standardize-table-borders')) {
|
|
146
|
+
flags.standardizeTableBorders = true;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ═══════════════════════════════════════════════════════════
|
|
150
|
+
// Hyperlink Operations (nested under operations object)
|
|
151
|
+
// NOTE: operations property comes from HyperlinkProcessingOptions parent interface
|
|
152
|
+
// Using type assertion to work with inherited property
|
|
153
|
+
// ═══════════════════════════════════════════════════════════
|
|
154
|
+
const operations: any = {};
|
|
155
|
+
if (enabled.has('update-top-hyperlinks')) operations.updateTopHyperlinks = true;
|
|
156
|
+
if (enabled.has('update-toc-hyperlinks')) operations.updateTocHyperlinks = true;
|
|
157
|
+
if (enabled.has('force-remove-heading1-toc')) operations.forceRemoveHeading1FromTOC = true;
|
|
158
|
+
if (enabled.has('fix-internal-hyperlinks')) operations.fixInternalHyperlinks = true;
|
|
159
|
+
if (enabled.has('fix-content-ids')) operations.fixContentIds = true;
|
|
160
|
+
if (enabled.has('replace-outdated-titles')) operations.replaceOutdatedTitles = true;
|
|
161
|
+
if (enabled.has('validate-document-styles')) operations.validateDocumentStyles = true;
|
|
162
|
+
if (enabled.has('validate-header2-tables')) operations.validateHeader2Tables = true;
|
|
163
|
+
|
|
164
|
+
// Assign operations object using type assertion
|
|
165
|
+
(flags as any).operations = operations;
|
|
166
|
+
|
|
167
|
+
return flags;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* MAIN CONVERTER: Session → WordProcessingOptions
|
|
172
|
+
*
|
|
173
|
+
* Converts complete Session object to WordProcessingOptions for document processing
|
|
174
|
+
* - Type-safe conversion with zero data loss
|
|
175
|
+
* - Auto-normalizes colors (#RRGGBB → RRGGBB)
|
|
176
|
+
* - Maps UI option IDs to processor boolean flags
|
|
177
|
+
* - Preserves all style properties including preserve* flags
|
|
178
|
+
*
|
|
179
|
+
* @param session - Complete Session object from SessionContext
|
|
180
|
+
* @returns WordProcessingOptions ready for WordDocumentProcessor.processDocument()
|
|
181
|
+
*/
|
|
182
|
+
export function sessionToProcessorOptions(session: Session): WordProcessingOptions {
|
|
183
|
+
// Base options
|
|
184
|
+
const options: WordProcessingOptions = {
|
|
185
|
+
createBackup: session.processingOptions?.createBackup ?? true,
|
|
186
|
+
validateBeforeProcessing: session.processingOptions?.validateUrls ?? true,
|
|
187
|
+
// Enable change tracking for Document Changes UI - tracks hyperlink and other modifications
|
|
188
|
+
trackChanges: true,
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// Map enabled operations to boolean flags
|
|
192
|
+
const enabledOps = session.processingOptions?.enabledOperations || [];
|
|
193
|
+
Object.assign(options, mapEnabledOperationsToFlags(enabledOps));
|
|
194
|
+
|
|
195
|
+
// Map styles with ALL properties (prevents transposition)
|
|
196
|
+
if (session.styles && session.styles.length > 0) {
|
|
197
|
+
options.styles = mapSessionStylesToProcessor(session.styles);
|
|
198
|
+
// Only apply styles if the 'validate-document-styles' option is checked
|
|
199
|
+
options.assignStyles = enabledOps.includes('validate-document-styles');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Map list settings (direct copy - interfaces are compatible)
|
|
203
|
+
if (session.listBulletSettings?.enabled) {
|
|
204
|
+
options.listBulletSettings = {
|
|
205
|
+
enabled: true,
|
|
206
|
+
indentationLevels: session.listBulletSettings.indentationLevels,
|
|
207
|
+
spacingBetweenItems: 0, // Use List Paragraph style's spaceAfter instead
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Map table shading with color normalization
|
|
212
|
+
options.tableShadingSettings = mapTableShadingSettings(session.tableShadingSettings);
|
|
213
|
+
|
|
214
|
+
// Enable auto-operations based on configuration
|
|
215
|
+
if (options.smartTables) {
|
|
216
|
+
options.tableUniformity = true;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return options;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Validates WordProcessingOptions before processing
|
|
224
|
+
*
|
|
225
|
+
* Catches configuration errors that would cause document corruption:
|
|
226
|
+
* - Invalid color formats (must be 6 hex digits without #)
|
|
227
|
+
* - Invalid font sizes (range: 1-1638 pt)
|
|
228
|
+
* - Invalid spacing values (must be non-negative)
|
|
229
|
+
* - Missing required properties
|
|
230
|
+
*
|
|
231
|
+
* @param options - WordProcessingOptions to validate
|
|
232
|
+
* @returns Validation result with specific error messages
|
|
233
|
+
*/
|
|
234
|
+
export function validateProcessingOptions(options: WordProcessingOptions): {
|
|
235
|
+
valid: boolean;
|
|
236
|
+
errors: string[];
|
|
237
|
+
} {
|
|
238
|
+
const errors: string[] = [];
|
|
239
|
+
|
|
240
|
+
// Validate styles if present
|
|
241
|
+
if (options.styles) {
|
|
242
|
+
for (const style of options.styles) {
|
|
243
|
+
// Required fields
|
|
244
|
+
if (!style.id || !style.name) {
|
|
245
|
+
errors.push(`Style missing required fields: id="${style.id}", name="${style.name}"`);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Color format: must be 6 hex digits WITHOUT # prefix at this point
|
|
249
|
+
if (style.color && !isValidOOXMLColor(style.color)) {
|
|
250
|
+
errors.push(
|
|
251
|
+
`Invalid color for style "${style.id}": "${style.color}" ` +
|
|
252
|
+
`(expected 6 hex digits without # prefix, e.g., "000000")`
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Font size range (Word maximum is 1638 pt)
|
|
257
|
+
if (style.fontSize <= 0 || style.fontSize > 1638) {
|
|
258
|
+
errors.push(
|
|
259
|
+
`Invalid fontSize for style "${style.id}": ${style.fontSize} ` + `(valid range: 1-1638)`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Spacing must be non-negative
|
|
264
|
+
if (style.spaceBefore < 0) {
|
|
265
|
+
errors.push(
|
|
266
|
+
`Invalid spaceBefore for style "${style.id}": ${style.spaceBefore} (must be >= 0)`
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
if (style.spaceAfter < 0) {
|
|
270
|
+
errors.push(
|
|
271
|
+
`Invalid spaceAfter for style "${style.id}": ${style.spaceAfter} (must be >= 0)`
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Line spacing multiplier (typical: 1.0, 1.15, 1.5, 2.0)
|
|
276
|
+
if (style.lineSpacing <= 0 || style.lineSpacing > 10) {
|
|
277
|
+
errors.push(
|
|
278
|
+
`Invalid lineSpacing for style "${style.id}": ${style.lineSpacing} ` +
|
|
279
|
+
`(valid range: 0.1-10)`
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Indentation validation (if present)
|
|
284
|
+
if (style.indentation) {
|
|
285
|
+
if (
|
|
286
|
+
style.indentation.left !== undefined &&
|
|
287
|
+
(style.indentation.left < 0 || style.indentation.left > 10)
|
|
288
|
+
) {
|
|
289
|
+
errors.push(
|
|
290
|
+
`Invalid indentation.left for style "${style.id}": ${style.indentation.left} ` +
|
|
291
|
+
`(valid range: 0-10 inches)`
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
if (
|
|
295
|
+
style.indentation.firstLine !== undefined &&
|
|
296
|
+
(style.indentation.firstLine < 0 || style.indentation.firstLine > 10)
|
|
297
|
+
) {
|
|
298
|
+
errors.push(
|
|
299
|
+
`Invalid indentation.firstLine for style "${style.id}": ${style.indentation.firstLine} ` +
|
|
300
|
+
`(valid range: 0-10 inches)`
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Validate table shading colors
|
|
308
|
+
if (options.tableShadingSettings) {
|
|
309
|
+
const { header2Shading, otherShading } = options.tableShadingSettings;
|
|
310
|
+
|
|
311
|
+
if (header2Shading && !isValidOOXMLColor(header2Shading)) {
|
|
312
|
+
errors.push(
|
|
313
|
+
`Invalid header2Shading color: "${header2Shading}" ` +
|
|
314
|
+
`(expected 6 hex digits without # prefix, e.g., "BFBFBF")`
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (otherShading && !isValidOOXMLColor(otherShading)) {
|
|
319
|
+
errors.push(
|
|
320
|
+
`Invalid otherShading color: "${otherShading}" ` +
|
|
321
|
+
`(expected 6 hex digits without # prefix, e.g., "DFDFDF")`
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Validate list settings if enabled
|
|
327
|
+
if (options.listBulletSettings?.enabled) {
|
|
328
|
+
if (
|
|
329
|
+
!options.listBulletSettings.indentationLevels ||
|
|
330
|
+
options.listBulletSettings.indentationLevels.length === 0
|
|
331
|
+
) {
|
|
332
|
+
errors.push('List settings enabled but indentationLevels array is empty or undefined');
|
|
333
|
+
} else {
|
|
334
|
+
// Validate each indentation level
|
|
335
|
+
for (const level of options.listBulletSettings.indentationLevels) {
|
|
336
|
+
if (level.symbolIndent < 0 || level.symbolIndent > 10) {
|
|
337
|
+
errors.push(
|
|
338
|
+
`Invalid symbolIndent at level ${level.level}: ${level.symbolIndent} inches ` +
|
|
339
|
+
`(valid range: 0-10)`
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
if (level.textIndent < 0 || level.textIndent > 10) {
|
|
343
|
+
errors.push(
|
|
344
|
+
`Invalid textIndent at level ${level.level}: ${level.textIndent} inches ` +
|
|
345
|
+
`(valid range: 0-10)`
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
if (level.textIndent <= level.symbolIndent) {
|
|
349
|
+
errors.push(
|
|
350
|
+
`Invalid indentation at level ${level.level}: textIndent (${level.textIndent}) ` +
|
|
351
|
+
`must be greater than symbolIndent (${level.symbolIndent})`
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return {
|
|
359
|
+
valid: errors.length === 0,
|
|
360
|
+
errors,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Quick validation check - returns true if options are valid
|
|
366
|
+
*
|
|
367
|
+
* @param options - WordProcessingOptions to check
|
|
368
|
+
* @returns True if valid, false otherwise
|
|
369
|
+
*/
|
|
370
|
+
export function isValid(options: WordProcessingOptions): boolean {
|
|
371
|
+
return validateProcessingOptions(options).valid;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Development helper: Logs validation errors to console
|
|
376
|
+
*
|
|
377
|
+
* @param options - WordProcessingOptions to validate
|
|
378
|
+
* @returns True if valid, false with console errors if invalid
|
|
379
|
+
*/
|
|
380
|
+
export function validateAndLog(options: WordProcessingOptions): boolean {
|
|
381
|
+
const result = validateProcessingOptions(options);
|
|
382
|
+
|
|
383
|
+
if (!result.valid) {
|
|
384
|
+
console.error('❌ WordProcessingOptions validation failed:');
|
|
385
|
+
result.errors.forEach((error, index) => {
|
|
386
|
+
console.error(` ${index + 1}. ${error}`);
|
|
387
|
+
});
|
|
388
|
+
} else {
|
|
389
|
+
console.log('✅ WordProcessingOptions validation passed');
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return result.valid;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Helper: Get user-friendly description of which operations are enabled
|
|
397
|
+
* Useful for logging and debugging
|
|
398
|
+
*
|
|
399
|
+
* @param session - Session to describe
|
|
400
|
+
* @returns Human-readable string of enabled operations
|
|
401
|
+
*/
|
|
402
|
+
export function describeEnabledOperations(session: Session): string {
|
|
403
|
+
const enabledOps = session.processingOptions?.enabledOperations || [];
|
|
404
|
+
|
|
405
|
+
if (enabledOps.length === 0) {
|
|
406
|
+
return 'No operations enabled';
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const opNames = enabledOps.map((op) => {
|
|
410
|
+
// Convert kebab-case to Title Case
|
|
411
|
+
return op
|
|
412
|
+
.split('-')
|
|
413
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
414
|
+
.join(' ');
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
return `${enabledOps.length} operations: ${opNames.slice(0, 5).join(', ')}${
|
|
418
|
+
enabledOps.length > 5 ? '...' : ''
|
|
419
|
+
}`;
|
|
420
|
+
}
|