@bendyline/docblocks 1.1.2 → 2.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.
Files changed (149) hide show
  1. package/README.md +76 -11
  2. package/dist/chunk-6IYMTYMQ.js +1692 -0
  3. package/dist/chunk-6IYMTYMQ.js.map +1 -0
  4. package/dist/chunk-AEHCVWU5.js +25 -0
  5. package/dist/chunk-AEHCVWU5.js.map +1 -0
  6. package/dist/chunk-B56KWCSE.js +802 -0
  7. package/dist/chunk-B56KWCSE.js.map +1 -0
  8. package/dist/{chunk-ME76RUMR.js → chunk-BNKV7MTO.js} +15 -1
  9. package/dist/chunk-BNKV7MTO.js.map +1 -0
  10. package/dist/chunk-BXMF5YQJ.js +149 -0
  11. package/dist/chunk-BXMF5YQJ.js.map +1 -0
  12. package/dist/chunk-COYQXQK3.js +1071 -0
  13. package/dist/chunk-COYQXQK3.js.map +1 -0
  14. package/dist/chunk-DN7A33LL.js +780 -0
  15. package/dist/chunk-DN7A33LL.js.map +1 -0
  16. package/dist/chunk-EZKJZUNJ.js +13 -0
  17. package/dist/chunk-EZKJZUNJ.js.map +1 -0
  18. package/dist/chunk-FA7UNOXK.js +20 -0
  19. package/dist/chunk-FA7UNOXK.js.map +1 -0
  20. package/dist/chunk-FNW556FN.js +75 -0
  21. package/dist/chunk-FNW556FN.js.map +1 -0
  22. package/dist/chunk-GM5YXU4L.js +29 -0
  23. package/dist/chunk-GM5YXU4L.js.map +1 -0
  24. package/dist/chunk-JS6XFWQK.js +225 -0
  25. package/dist/chunk-JS6XFWQK.js.map +1 -0
  26. package/dist/chunk-MNSZ7EZN.js +111 -0
  27. package/dist/chunk-MNSZ7EZN.js.map +1 -0
  28. package/dist/chunk-P3DVZQ6S.js +228 -0
  29. package/dist/chunk-P3DVZQ6S.js.map +1 -0
  30. package/dist/chunk-P4WATND4.js +52 -0
  31. package/dist/chunk-P4WATND4.js.map +1 -0
  32. package/dist/chunk-RVPGQBWR.js +169 -0
  33. package/dist/chunk-RVPGQBWR.js.map +1 -0
  34. package/dist/chunk-U722UUFN.js +9 -0
  35. package/dist/chunk-U722UUFN.js.map +1 -0
  36. package/dist/chunk-VTCSF7VS.js +553 -0
  37. package/dist/chunk-VTCSF7VS.js.map +1 -0
  38. package/dist/chunk-WJKYY5QR.js +1350 -0
  39. package/dist/chunk-WJKYY5QR.js.map +1 -0
  40. package/dist/chunk-XUML3MKV.js +945 -0
  41. package/dist/chunk-XUML3MKV.js.map +1 -0
  42. package/dist/document/index.d.ts +358 -0
  43. package/dist/document/index.js +25 -0
  44. package/dist/document/index.js.map +1 -0
  45. package/dist/filesystem/electron.d.ts +73 -0
  46. package/dist/filesystem/electron.js +17 -0
  47. package/dist/filesystem/electron.js.map +1 -0
  48. package/dist/filesystem/index.d.ts +228 -8
  49. package/dist/filesystem/index.js +133 -6
  50. package/dist/filesystem/index.js.map +1 -1
  51. package/dist/filesystem/indexeddb.d.ts +284 -0
  52. package/dist/filesystem/indexeddb.js +23 -0
  53. package/dist/filesystem/indexeddb.js.map +1 -0
  54. package/dist/filesystem/memory.d.ts +152 -0
  55. package/dist/filesystem/memory.js +13 -0
  56. package/dist/filesystem/memory.js.map +1 -0
  57. package/dist/filesystem/native.d.ts +136 -0
  58. package/dist/filesystem/native.js +28 -0
  59. package/dist/filesystem/native.js.map +1 -0
  60. package/dist/host/index.d.ts +32 -6
  61. package/dist/host/index.js +26 -27
  62. package/dist/host/index.js.map +1 -1
  63. package/dist/index.d.ts +14 -9
  64. package/dist/index.js +204 -8
  65. package/dist/index.js.map +1 -1
  66. package/dist/mcp/index.d.ts +33 -0
  67. package/dist/mcp/index.js +32 -0
  68. package/dist/mcp/index.js.map +1 -0
  69. package/dist/mcp/zod.d.ts +5765 -0
  70. package/dist/mcp/zod.js +724 -0
  71. package/dist/mcp/zod.js.map +1 -0
  72. package/dist/share/index.d.ts +43 -0
  73. package/dist/share/index.js +13 -0
  74. package/dist/share/index.js.map +1 -0
  75. package/dist/types-BEg5SQ1_.d.ts +301 -0
  76. package/dist/types-CX893hgH.d.ts +468 -0
  77. package/dist/types-CueK0tvU.d.ts +501 -0
  78. package/dist/vscode/index.d.ts +220 -0
  79. package/dist/vscode/index.js +383 -0
  80. package/dist/vscode/index.js.map +1 -0
  81. package/dist/workspace/index.d.ts +141 -3
  82. package/dist/workspace/index.js +28 -1
  83. package/dist/workspace/index.js.map +1 -1
  84. package/dist/workspace-path-CWVrcuPL.d.ts +21 -0
  85. package/package.json +50 -5
  86. package/dist/chunk-GUNM43XZ.js +0 -63
  87. package/dist/chunk-GUNM43XZ.js.map +0 -1
  88. package/dist/chunk-IM7LCQJ6.js +0 -850
  89. package/dist/chunk-IM7LCQJ6.js.map +0 -1
  90. package/dist/chunk-ME76RUMR.js.map +0 -1
  91. package/dist/filesystem/electron-provider.d.ts +0 -32
  92. package/dist/filesystem/electron-provider.d.ts.map +0 -1
  93. package/dist/filesystem/electron-provider.js +0 -64
  94. package/dist/filesystem/electron-provider.js.map +0 -1
  95. package/dist/filesystem/file-media-provider.d.ts +0 -23
  96. package/dist/filesystem/file-media-provider.d.ts.map +0 -1
  97. package/dist/filesystem/file-media-provider.js +0 -85
  98. package/dist/filesystem/file-media-provider.js.map +0 -1
  99. package/dist/filesystem/filesystem-content-container.d.ts +0 -24
  100. package/dist/filesystem/filesystem-content-container.d.ts.map +0 -1
  101. package/dist/filesystem/filesystem-content-container.js +0 -116
  102. package/dist/filesystem/filesystem-content-container.js.map +0 -1
  103. package/dist/filesystem/index.d.ts.map +0 -1
  104. package/dist/filesystem/indexeddb-content-container.d.ts +0 -20
  105. package/dist/filesystem/indexeddb-content-container.d.ts.map +0 -1
  106. package/dist/filesystem/indexeddb-content-container.js +0 -93
  107. package/dist/filesystem/indexeddb-content-container.js.map +0 -1
  108. package/dist/filesystem/indexeddb-provider.d.ts +0 -32
  109. package/dist/filesystem/indexeddb-provider.d.ts.map +0 -1
  110. package/dist/filesystem/indexeddb-provider.js +0 -295
  111. package/dist/filesystem/indexeddb-provider.js.map +0 -1
  112. package/dist/filesystem/native-provider.d.ts +0 -45
  113. package/dist/filesystem/native-provider.d.ts.map +0 -1
  114. package/dist/filesystem/native-provider.js +0 -336
  115. package/dist/filesystem/native-provider.js.map +0 -1
  116. package/dist/filesystem/types.d.ts +0 -50
  117. package/dist/filesystem/types.d.ts.map +0 -1
  118. package/dist/filesystem/types.js +0 -8
  119. package/dist/filesystem/types.js.map +0 -1
  120. package/dist/host/index.d.ts.map +0 -1
  121. package/dist/host/types.d.ts +0 -149
  122. package/dist/host/types.d.ts.map +0 -1
  123. package/dist/host/types.js +0 -10
  124. package/dist/host/types.js.map +0 -1
  125. package/dist/index-pgBHBQ9G.d.ts +0 -213
  126. package/dist/index.d.ts.map +0 -1
  127. package/dist/workspace/index.d.ts.map +0 -1
  128. package/dist/workspace/types.d.ts +0 -29
  129. package/dist/workspace/types.d.ts.map +0 -1
  130. package/dist/workspace/types.js +0 -6
  131. package/dist/workspace/types.js.map +0 -1
  132. package/dist/workspace/workspace-manager.d.ts +0 -35
  133. package/dist/workspace/workspace-manager.d.ts.map +0 -1
  134. package/dist/workspace/workspace-manager.js +0 -82
  135. package/dist/workspace/workspace-manager.js.map +0 -1
  136. package/src/filesystem/electron-provider.ts +0 -88
  137. package/src/filesystem/file-media-provider.ts +0 -103
  138. package/src/filesystem/filesystem-content-container.ts +0 -126
  139. package/src/filesystem/index.ts +0 -24
  140. package/src/filesystem/indexeddb-content-container.ts +0 -104
  141. package/src/filesystem/indexeddb-provider.ts +0 -345
  142. package/src/filesystem/native-provider.ts +0 -384
  143. package/src/filesystem/types.ts +0 -69
  144. package/src/host/index.ts +0 -47
  145. package/src/host/types.ts +0 -153
  146. package/src/index.ts +0 -9
  147. package/src/workspace/index.ts +0 -10
  148. package/src/workspace/types.ts +0 -29
  149. package/src/workspace/workspace-manager.ts +0 -90
@@ -0,0 +1,220 @@
1
+ /**
2
+ * Typed message protocol between the extension host and webview.
3
+ */
4
+ type DocumentSessionMessageStatus = 'idle' | 'saved' | 'dirty' | 'saving' | 'error' | 'conflict' | 'closed';
5
+ type DocumentConflictChoice = 'use-local' | 'use-external';
6
+ /** Host-observed details that help a user distinguish two text branches. */
7
+ interface DocumentConflictDetailsMessage {
8
+ /** VS Code document version on which the DocBlocks draft was based. */
9
+ localBaseDocumentVersion: number;
10
+ /** Current VS Code document version observed outside the DocBlocks edit pipeline. */
11
+ externalDocumentVersion: number;
12
+ /** UTF-8 encoded sizes of the complete text snapshots. */
13
+ localBytes: number;
14
+ externalBytes: number | null;
15
+ /** Times are extension-host observations, not filesystem-authoritative mtimes. */
16
+ localEditedAt: number | null;
17
+ externalObservedAt: number | null;
18
+ /** Whether VS Code reported the external document snapshot as not yet saved. */
19
+ externalIsDirty: boolean | null;
20
+ }
21
+ declare const DOCBLOCKS_ACCENT_COLORS: readonly ["brown", "green", "blue", "purple", "maroon", "orange", "gray"];
22
+ type DocBlocksAccentColor = (typeof DOCBLOCKS_ACCENT_COLORS)[number];
23
+ declare const DOCBLOCKS_WRITE_CANVAS_TEXT_SIZE_MIN = 12;
24
+ declare const DOCBLOCKS_WRITE_CANVAS_TEXT_SIZE_MAX = 32;
25
+ declare const DOCBLOCKS_WRITE_CANVAS_LINE_SPACING_MIN = 1.2;
26
+ declare const DOCBLOCKS_WRITE_CANVAS_LINE_SPACING_MAX = 2.4;
27
+ interface VscodeWriteCanvasSettings {
28
+ textSize: number;
29
+ lineSpacing: number;
30
+ }
31
+ declare const DEFAULT_VSCODE_WRITE_CANVAS_SETTINGS: Readonly<VscodeWriteCanvasSettings>;
32
+ interface VscodeEditorSettings {
33
+ autoSave: boolean;
34
+ accentColor: DocBlocksAccentColor;
35
+ writeCanvasSettings: VscodeWriteCanvasSettings;
36
+ }
37
+ /**
38
+ * An opaque, one-shot authority to write one host-owned export target.
39
+ * The label is presentation-only and must never be interpreted as a path.
40
+ */
41
+ interface ExportTargetGrantMessage {
42
+ grantId: string;
43
+ displayLabel: string;
44
+ }
45
+ /** Messages sent from the extension host to the webview. */
46
+ type ExtensionToWebviewMessage = {
47
+ type: 'setContent';
48
+ content: string;
49
+ documentVersion: number;
50
+ fileName: string;
51
+ sessionId: string;
52
+ sessionRevision: number;
53
+ acknowledgedClientRevision: number;
54
+ } | {
55
+ type: 'editAcknowledged';
56
+ sessionId: string;
57
+ clientRevision: number;
58
+ sessionRevision: number;
59
+ accepted: boolean;
60
+ message: string | null;
61
+ } | {
62
+ type: 'sessionState';
63
+ sessionId: string;
64
+ status: DocumentSessionMessageStatus;
65
+ revision: number;
66
+ persistedRevision: number;
67
+ acknowledgedClientRevision: number;
68
+ documentVersion: number;
69
+ error: string | null;
70
+ conflict: DocumentConflictDetailsMessage | null;
71
+ } | {
72
+ type: 'saveResult';
73
+ sessionId: string;
74
+ requestId: number;
75
+ ok: boolean;
76
+ revision: number;
77
+ persistedRevision: number;
78
+ documentVersion: number;
79
+ message: string | null;
80
+ } | {
81
+ type: 'themeChange';
82
+ theme: 'light' | 'dark';
83
+ } | {
84
+ type: 'editorSettings';
85
+ settings: VscodeEditorSettings;
86
+ } | {
87
+ type: 'mediaResolved';
88
+ requestId: number;
89
+ url: string;
90
+ } | {
91
+ type: 'mediaListed';
92
+ requestId: number;
93
+ entries: MediaEntryMessage[];
94
+ } | {
95
+ type: 'mediaAdded';
96
+ requestId: number;
97
+ path: string;
98
+ } | {
99
+ type: 'mediaRemoved';
100
+ requestId: number;
101
+ } | {
102
+ type: 'mediaError';
103
+ requestId: number;
104
+ message: string;
105
+ } | {
106
+ type: 'exportSaved';
107
+ requestId: number;
108
+ target: ExportTargetGrantMessage | null;
109
+ } | {
110
+ type: 'exportError';
111
+ requestId: number;
112
+ message: string;
113
+ } | {
114
+ type: 'exportTargetResolved';
115
+ requestId: number;
116
+ target: ExportTargetGrantMessage | null;
117
+ } | {
118
+ type: 'exportTargetPicked';
119
+ requestId: number;
120
+ target: ExportTargetGrantMessage | null;
121
+ } | {
122
+ type: 'workspaceFileRead';
123
+ requestId: number;
124
+ dataBase64: string | null;
125
+ } | {
126
+ type: 'workspaceFileError';
127
+ requestId: number;
128
+ message: string;
129
+ };
130
+ /** Messages sent from the webview to the extension host. */
131
+ type WebviewToExtensionMessage = {
132
+ type: 'ready';
133
+ } | {
134
+ type: 'setAutoSave';
135
+ enabled: boolean;
136
+ } | {
137
+ type: 'setAccentColor';
138
+ accentColor: DocBlocksAccentColor;
139
+ } | {
140
+ type: 'setWriteCanvasSettings';
141
+ settings: VscodeWriteCanvasSettings;
142
+ } | {
143
+ type: 'edit';
144
+ content: string;
145
+ sessionId: string;
146
+ clientRevision: number;
147
+ baseDocumentVersion: number;
148
+ } | {
149
+ type: 'save';
150
+ sessionId: string;
151
+ requestId: number;
152
+ clientRevision: number;
153
+ baseDocumentVersion: number;
154
+ } | {
155
+ type: 'resolveConflict';
156
+ sessionId: string;
157
+ choice: DocumentConflictChoice;
158
+ } | {
159
+ type: 'resolveMedia';
160
+ requestId: number;
161
+ ref: string;
162
+ } | {
163
+ type: 'listMedia';
164
+ requestId: number;
165
+ } | {
166
+ type: 'addMedia';
167
+ requestId: number;
168
+ name: string;
169
+ dataBase64: string;
170
+ mimeType: string;
171
+ } | {
172
+ type: 'removeMedia';
173
+ requestId: number;
174
+ ref: string;
175
+ } | {
176
+ type: 'saveExport';
177
+ requestId: number;
178
+ filename: string;
179
+ dataBase64: string;
180
+ mimeType: string;
181
+ grantId: string | null;
182
+ } | {
183
+ type: 'resolveExportTarget';
184
+ requestId: number;
185
+ filename: string;
186
+ } | {
187
+ type: 'pickExportTarget';
188
+ requestId: number;
189
+ filename: string;
190
+ currentGrantId: string | null;
191
+ } | {
192
+ type: 'readWorkspaceFile';
193
+ requestId: number;
194
+ path: string;
195
+ };
196
+ interface MediaEntryMessage {
197
+ name: string;
198
+ mimeType: string;
199
+ size: number;
200
+ }
201
+ /**
202
+ * The webview boundary is untrusted at runtime. Keep malformed or stale
203
+ * messages out of the document session instead of relying on a TypeScript
204
+ * assertion in the extension host.
205
+ */
206
+ declare function parseWebviewToExtensionMessage(value: unknown): WebviewToExtensionMessage | null;
207
+ /**
208
+ * Validate host responses before they influence webview state. This protects
209
+ * the browser side from protocol drift and from messages injected by another
210
+ * script in the webview document; a TypeScript MessageEvent annotation is not
211
+ * runtime validation.
212
+ */
213
+ declare function parseExtensionToWebviewMessage(value: unknown): ExtensionToWebviewMessage | null;
214
+ declare function isDocBlocksAccentColor(value: unknown): value is DocBlocksAccentColor;
215
+ declare function isDocBlocksWriteCanvasTextSize(value: unknown): value is number;
216
+ declare function isDocBlocksWriteCanvasLineSpacing(value: unknown): value is number;
217
+ declare function isSafeExportFilename(value: unknown): value is string;
218
+ declare function isSafeMimeType(value: unknown): value is string;
219
+
220
+ export { DEFAULT_VSCODE_WRITE_CANVAS_SETTINGS, DOCBLOCKS_ACCENT_COLORS, DOCBLOCKS_WRITE_CANVAS_LINE_SPACING_MAX, DOCBLOCKS_WRITE_CANVAS_LINE_SPACING_MIN, DOCBLOCKS_WRITE_CANVAS_TEXT_SIZE_MAX, DOCBLOCKS_WRITE_CANVAS_TEXT_SIZE_MIN, type DocBlocksAccentColor, type DocumentConflictChoice, type DocumentConflictDetailsMessage, type DocumentSessionMessageStatus, type ExportTargetGrantMessage, type ExtensionToWebviewMessage, type MediaEntryMessage, type VscodeEditorSettings, type VscodeWriteCanvasSettings, type WebviewToExtensionMessage, isDocBlocksAccentColor, isDocBlocksWriteCanvasLineSpacing, isDocBlocksWriteCanvasTextSize, isSafeExportFilename, isSafeMimeType, parseExtensionToWebviewMessage, parseWebviewToExtensionMessage };
@@ -0,0 +1,383 @@
1
+ import {
2
+ HOST_WIRE_LIMITS,
3
+ isBoundedString
4
+ } from "../chunk-FNW556FN.js";
5
+
6
+ // src/vscode/messages.ts
7
+ var MAX_REQUEST_ID = 2147483647;
8
+ var DOCBLOCKS_ACCENT_COLORS = [
9
+ "brown",
10
+ "green",
11
+ "blue",
12
+ "purple",
13
+ "maroon",
14
+ "orange",
15
+ "gray"
16
+ ];
17
+ var DOCBLOCKS_WRITE_CANVAS_TEXT_SIZE_MIN = 12;
18
+ var DOCBLOCKS_WRITE_CANVAS_TEXT_SIZE_MAX = 32;
19
+ var DOCBLOCKS_WRITE_CANVAS_LINE_SPACING_MIN = 1.2;
20
+ var DOCBLOCKS_WRITE_CANVAS_LINE_SPACING_MAX = 2.4;
21
+ var DEFAULT_VSCODE_WRITE_CANVAS_SETTINGS = {
22
+ textSize: 16,
23
+ lineSpacing: 1.7
24
+ };
25
+ function parseWebviewToExtensionMessage(value) {
26
+ if (!isRecord(value) || typeof value.type !== "string") return null;
27
+ switch (value.type) {
28
+ case "ready":
29
+ return hasOnlyKeys(value, ["type"]) ? { type: "ready" } : null;
30
+ case "setAutoSave":
31
+ return hasOnlyKeys(value, ["type", "enabled"]) && typeof value.enabled === "boolean" ? { type: "setAutoSave", enabled: value.enabled } : null;
32
+ case "setAccentColor":
33
+ return hasOnlyKeys(value, ["type", "accentColor"]) && isDocBlocksAccentColor(value.accentColor) ? { type: "setAccentColor", accentColor: value.accentColor } : null;
34
+ case "setWriteCanvasSettings": {
35
+ if (!hasOnlyKeys(value, ["type", "settings"])) return null;
36
+ const settings = parseVscodeWriteCanvasSettings(value.settings);
37
+ return settings ? { type: "setWriteCanvasSettings", settings } : null;
38
+ }
39
+ case "edit":
40
+ return hasOnlyKeys(value, [
41
+ "type",
42
+ "content",
43
+ "sessionId",
44
+ "clientRevision",
45
+ "baseDocumentVersion"
46
+ ]) && hasBoundedString(value, "content", HOST_WIRE_LIMITS.documentCharacters) && isSessionEnvelope(value) ? {
47
+ type: "edit",
48
+ content: value.content,
49
+ sessionId: value.sessionId,
50
+ clientRevision: value.clientRevision,
51
+ baseDocumentVersion: value.baseDocumentVersion
52
+ } : null;
53
+ case "save":
54
+ return hasOnlyKeys(value, [
55
+ "type",
56
+ "sessionId",
57
+ "requestId",
58
+ "clientRevision",
59
+ "baseDocumentVersion"
60
+ ]) && isSessionEnvelope(value) && hasRequestId(value) ? {
61
+ type: "save",
62
+ sessionId: value.sessionId,
63
+ requestId: value.requestId,
64
+ clientRevision: value.clientRevision,
65
+ baseDocumentVersion: value.baseDocumentVersion
66
+ } : null;
67
+ case "resolveConflict":
68
+ return hasOnlyKeys(value, ["type", "sessionId", "choice"]) && hasBoundedString(value, "sessionId", HOST_WIRE_LIMITS.identifierCharacters, 1) && (value.choice === "use-local" || value.choice === "use-external") ? { type: "resolveConflict", sessionId: value.sessionId, choice: value.choice } : null;
69
+ case "resolveMedia":
70
+ return hasOnlyKeys(value, ["type", "requestId", "ref"]) && hasRequestId(value) && hasBoundedString(value, "ref", HOST_WIRE_LIMITS.pathCharacters, 1) ? { type: "resolveMedia", requestId: value.requestId, ref: value.ref } : null;
71
+ case "listMedia":
72
+ return hasOnlyKeys(value, ["type", "requestId"]) && hasRequestId(value) ? { type: "listMedia", requestId: value.requestId } : null;
73
+ case "addMedia":
74
+ return hasOnlyKeys(value, ["type", "requestId", "name", "dataBase64", "mimeType"]) && hasRequestId(value) && hasBoundedString(value, "name", HOST_WIRE_LIMITS.pathCharacters, 1) && hasBoundedString(value, "dataBase64", HOST_WIRE_LIMITS.base64Characters) && hasMimeType(value, "mimeType") ? {
75
+ type: "addMedia",
76
+ requestId: value.requestId,
77
+ name: value.name,
78
+ dataBase64: value.dataBase64,
79
+ mimeType: value.mimeType
80
+ } : null;
81
+ case "removeMedia":
82
+ return hasOnlyKeys(value, ["type", "requestId", "ref"]) && hasRequestId(value) && hasBoundedString(value, "ref", HOST_WIRE_LIMITS.pathCharacters, 1) ? { type: "removeMedia", requestId: value.requestId, ref: value.ref } : null;
83
+ case "saveExport":
84
+ return hasOnlyKeys(value, [
85
+ "type",
86
+ "requestId",
87
+ "filename",
88
+ "dataBase64",
89
+ "mimeType",
90
+ "grantId"
91
+ ]) && hasRequestId(value) && hasSafeFilename(value, "filename") && hasBoundedString(value, "dataBase64", HOST_WIRE_LIMITS.base64Characters) && hasMimeType(value, "mimeType") && hasNullableBoundedString(value, "grantId", HOST_WIRE_LIMITS.identifierCharacters, 1) ? {
92
+ type: "saveExport",
93
+ requestId: value.requestId,
94
+ filename: value.filename,
95
+ dataBase64: value.dataBase64,
96
+ mimeType: value.mimeType,
97
+ grantId: value.grantId
98
+ } : null;
99
+ case "resolveExportTarget":
100
+ return hasOnlyKeys(value, ["type", "requestId", "filename"]) && hasRequestId(value) && hasSafeFilename(value, "filename") ? { type: "resolveExportTarget", requestId: value.requestId, filename: value.filename } : null;
101
+ case "pickExportTarget":
102
+ return hasOnlyKeys(value, ["type", "requestId", "filename", "currentGrantId"]) && hasRequestId(value) && hasSafeFilename(value, "filename") && hasNullableBoundedString(value, "currentGrantId", HOST_WIRE_LIMITS.identifierCharacters, 1) ? {
103
+ type: "pickExportTarget",
104
+ requestId: value.requestId,
105
+ filename: value.filename,
106
+ currentGrantId: value.currentGrantId
107
+ } : null;
108
+ case "readWorkspaceFile":
109
+ return hasOnlyKeys(value, ["type", "requestId", "path"]) && hasRequestId(value) && hasBoundedString(value, "path", HOST_WIRE_LIMITS.pathCharacters, 1) ? { type: "readWorkspaceFile", requestId: value.requestId, path: value.path } : null;
110
+ default:
111
+ return null;
112
+ }
113
+ }
114
+ function parseExtensionToWebviewMessage(value) {
115
+ if (!isRecord(value) || typeof value.type !== "string") return null;
116
+ switch (value.type) {
117
+ case "setContent":
118
+ return hasOnlyKeys(value, [
119
+ "type",
120
+ "content",
121
+ "documentVersion",
122
+ "fileName",
123
+ "sessionId",
124
+ "sessionRevision",
125
+ "acknowledgedClientRevision"
126
+ ]) && hasBoundedString(value, "content", HOST_WIRE_LIMITS.documentCharacters) && hasNonNegativeInteger(value, "documentVersion") && hasBoundedString(value, "fileName", HOST_WIRE_LIMITS.pathCharacters, 1) && hasBoundedString(value, "sessionId", HOST_WIRE_LIMITS.identifierCharacters, 1) && hasNonNegativeInteger(value, "sessionRevision") && hasNonNegativeInteger(value, "acknowledgedClientRevision") ? {
127
+ type: "setContent",
128
+ content: value.content,
129
+ documentVersion: value.documentVersion,
130
+ fileName: value.fileName,
131
+ sessionId: value.sessionId,
132
+ sessionRevision: value.sessionRevision,
133
+ acknowledgedClientRevision: value.acknowledgedClientRevision
134
+ } : null;
135
+ case "editAcknowledged":
136
+ return hasOnlyKeys(value, [
137
+ "type",
138
+ "sessionId",
139
+ "clientRevision",
140
+ "sessionRevision",
141
+ "accepted",
142
+ "message"
143
+ ]) && hasBoundedString(value, "sessionId", HOST_WIRE_LIMITS.identifierCharacters, 1) && hasNonNegativeInteger(value, "clientRevision") && hasNonNegativeInteger(value, "sessionRevision") && typeof value.accepted === "boolean" && hasNullableBoundedString(value, "message", HOST_WIRE_LIMITS.messageCharacters) ? {
144
+ type: "editAcknowledged",
145
+ sessionId: value.sessionId,
146
+ clientRevision: value.clientRevision,
147
+ sessionRevision: value.sessionRevision,
148
+ accepted: value.accepted,
149
+ message: value.message
150
+ } : null;
151
+ case "sessionState": {
152
+ if (!hasOnlyKeys(value, [
153
+ "type",
154
+ "sessionId",
155
+ "status",
156
+ "revision",
157
+ "persistedRevision",
158
+ "acknowledgedClientRevision",
159
+ "documentVersion",
160
+ "error",
161
+ "conflict"
162
+ ]) || !hasBoundedString(value, "sessionId", HOST_WIRE_LIMITS.identifierCharacters, 1) || !isDocumentSessionMessageStatus(value.status) || !hasNonNegativeInteger(value, "revision") || !hasNonNegativeInteger(value, "persistedRevision") || value.persistedRevision > value.revision || !hasNonNegativeInteger(value, "acknowledgedClientRevision") || !hasNonNegativeInteger(value, "documentVersion") || !hasNullableBoundedString(value, "error", HOST_WIRE_LIMITS.messageCharacters)) {
163
+ return null;
164
+ }
165
+ const conflict = parseDocumentConflictDetails(value.conflict);
166
+ if (conflict === void 0 || value.status === "conflict" && conflict === null || value.status !== "conflict" && conflict !== null) {
167
+ return null;
168
+ }
169
+ return {
170
+ type: "sessionState",
171
+ sessionId: value.sessionId,
172
+ status: value.status,
173
+ revision: value.revision,
174
+ persistedRevision: value.persistedRevision,
175
+ acknowledgedClientRevision: value.acknowledgedClientRevision,
176
+ documentVersion: value.documentVersion,
177
+ error: value.error,
178
+ conflict
179
+ };
180
+ }
181
+ case "saveResult":
182
+ return hasOnlyKeys(value, [
183
+ "type",
184
+ "sessionId",
185
+ "requestId",
186
+ "ok",
187
+ "revision",
188
+ "persistedRevision",
189
+ "documentVersion",
190
+ "message"
191
+ ]) && hasBoundedString(value, "sessionId", HOST_WIRE_LIMITS.identifierCharacters, 1) && hasRequestId(value) && typeof value.ok === "boolean" && hasNonNegativeInteger(value, "revision") && hasNonNegativeInteger(value, "persistedRevision") && value.persistedRevision <= value.revision && hasNonNegativeInteger(value, "documentVersion") && hasNullableBoundedString(value, "message", HOST_WIRE_LIMITS.messageCharacters) ? {
192
+ type: "saveResult",
193
+ sessionId: value.sessionId,
194
+ requestId: value.requestId,
195
+ ok: value.ok,
196
+ revision: value.revision,
197
+ persistedRevision: value.persistedRevision,
198
+ documentVersion: value.documentVersion,
199
+ message: value.message
200
+ } : null;
201
+ case "themeChange":
202
+ return hasOnlyKeys(value, ["type", "theme"]) && (value.theme === "light" || value.theme === "dark") ? { type: "themeChange", theme: value.theme } : null;
203
+ case "editorSettings": {
204
+ if (!hasOnlyKeys(value, ["type", "settings"])) return null;
205
+ const settings = parseVscodeEditorSettings(value.settings);
206
+ return settings ? { type: "editorSettings", settings } : null;
207
+ }
208
+ case "mediaResolved":
209
+ return hasOnlyKeys(value, ["type", "requestId", "url"]) && hasRequestId(value) && isBoundedMediaDataUrl(value.url) ? { type: "mediaResolved", requestId: value.requestId, url: value.url } : null;
210
+ case "mediaListed": {
211
+ if (!hasOnlyKeys(value, ["type", "requestId", "entries"]) || !hasRequestId(value)) {
212
+ return null;
213
+ }
214
+ const entries = parseMediaEntries(value.entries);
215
+ return entries ? { type: "mediaListed", requestId: value.requestId, entries } : null;
216
+ }
217
+ case "mediaAdded":
218
+ return hasOnlyKeys(value, ["type", "requestId", "path"]) && hasRequestId(value) && hasBoundedString(value, "path", HOST_WIRE_LIMITS.pathCharacters, 1) ? { type: "mediaAdded", requestId: value.requestId, path: value.path } : null;
219
+ case "mediaRemoved":
220
+ return hasOnlyKeys(value, ["type", "requestId"]) && hasRequestId(value) ? { type: "mediaRemoved", requestId: value.requestId } : null;
221
+ case "mediaError":
222
+ case "exportError":
223
+ case "workspaceFileError":
224
+ return hasOnlyKeys(value, ["type", "requestId", "message"]) && hasRequestId(value) && hasBoundedString(value, "message", HOST_WIRE_LIMITS.messageCharacters, 1) ? { type: value.type, requestId: value.requestId, message: value.message } : null;
225
+ case "exportSaved":
226
+ case "exportTargetResolved":
227
+ case "exportTargetPicked": {
228
+ if (!hasOnlyKeys(value, ["type", "requestId", "target"]) || !hasRequestId(value)) {
229
+ return null;
230
+ }
231
+ const target = parseExportTargetGrant(value.target);
232
+ return target !== void 0 ? { type: value.type, requestId: value.requestId, target } : null;
233
+ }
234
+ case "workspaceFileRead":
235
+ return hasOnlyKeys(value, ["type", "requestId", "dataBase64"]) && hasRequestId(value) && hasNullableBoundedString(value, "dataBase64", HOST_WIRE_LIMITS.base64Characters) ? { type: "workspaceFileRead", requestId: value.requestId, dataBase64: value.dataBase64 } : null;
236
+ default:
237
+ return null;
238
+ }
239
+ }
240
+ function parseExportTargetGrant(value) {
241
+ if (value === null) return null;
242
+ if (!isRecord(value) || !hasOnlyKeys(value, ["grantId", "displayLabel"]) || !hasBoundedString(value, "grantId", HOST_WIRE_LIMITS.identifierCharacters, 1) || !hasBoundedString(value, "displayLabel", HOST_WIRE_LIMITS.pathCharacters, 1)) {
243
+ return void 0;
244
+ }
245
+ return { grantId: value.grantId, displayLabel: value.displayLabel };
246
+ }
247
+ function parseDocumentConflictDetails(value) {
248
+ if (value === null) return null;
249
+ if (!isRecord(value) || !hasOnlyKeys(value, [
250
+ "localBaseDocumentVersion",
251
+ "externalDocumentVersion",
252
+ "localBytes",
253
+ "externalBytes",
254
+ "localEditedAt",
255
+ "externalObservedAt",
256
+ "externalIsDirty"
257
+ ]) || !hasNonNegativeInteger(value, "localBaseDocumentVersion") || !hasNonNegativeInteger(value, "externalDocumentVersion") || !hasNonNegativeInteger(value, "localBytes") || !isNullableNonNegativeInteger(value.externalBytes) || !isNullableNonNegativeInteger(value.localEditedAt) || !isNullableNonNegativeInteger(value.externalObservedAt) || value.externalIsDirty !== null && typeof value.externalIsDirty !== "boolean") {
258
+ return void 0;
259
+ }
260
+ return {
261
+ localBaseDocumentVersion: value.localBaseDocumentVersion,
262
+ externalDocumentVersion: value.externalDocumentVersion,
263
+ localBytes: value.localBytes,
264
+ externalBytes: value.externalBytes,
265
+ localEditedAt: value.localEditedAt,
266
+ externalObservedAt: value.externalObservedAt,
267
+ externalIsDirty: value.externalIsDirty
268
+ };
269
+ }
270
+ function parseVscodeEditorSettings(value) {
271
+ if (!isRecord(value) || !hasOnlyKeys(value, ["autoSave", "accentColor", "writeCanvasSettings"]) || typeof value.autoSave !== "boolean" || !isDocBlocksAccentColor(value.accentColor)) {
272
+ return null;
273
+ }
274
+ const writeCanvasSettings = parseVscodeWriteCanvasSettings(value.writeCanvasSettings);
275
+ return writeCanvasSettings ? { autoSave: value.autoSave, accentColor: value.accentColor, writeCanvasSettings } : null;
276
+ }
277
+ function isDocBlocksAccentColor(value) {
278
+ return DOCBLOCKS_ACCENT_COLORS.some((color) => color === value);
279
+ }
280
+ function isDocBlocksWriteCanvasTextSize(value) {
281
+ return numberInRange(
282
+ value,
283
+ DOCBLOCKS_WRITE_CANVAS_TEXT_SIZE_MIN,
284
+ DOCBLOCKS_WRITE_CANVAS_TEXT_SIZE_MAX
285
+ );
286
+ }
287
+ function isDocBlocksWriteCanvasLineSpacing(value) {
288
+ return numberInRange(
289
+ value,
290
+ DOCBLOCKS_WRITE_CANVAS_LINE_SPACING_MIN,
291
+ DOCBLOCKS_WRITE_CANVAS_LINE_SPACING_MAX
292
+ );
293
+ }
294
+ function parseVscodeWriteCanvasSettings(value) {
295
+ return isRecord(value) && hasOnlyKeys(value, ["textSize", "lineSpacing"]) && isDocBlocksWriteCanvasTextSize(value.textSize) && isDocBlocksWriteCanvasLineSpacing(value.lineSpacing) ? { textSize: value.textSize, lineSpacing: value.lineSpacing } : null;
296
+ }
297
+ function numberInRange(value, min, max) {
298
+ return typeof value === "number" && Number.isFinite(value) && value >= min && value <= max;
299
+ }
300
+ function parseMediaEntries(value) {
301
+ if (!Array.isArray(value) || value.length > HOST_WIRE_LIMITS.arrayEntries) return null;
302
+ const entries = [];
303
+ for (const entry of value) {
304
+ if (!isRecord(entry) || !hasOnlyKeys(entry, ["name", "mimeType", "size"]) || !hasBoundedString(entry, "name", HOST_WIRE_LIMITS.pathCharacters, 1) || !hasMimeType(entry, "mimeType") || !hasNonNegativeInteger(entry, "size") || entry.size > HOST_WIRE_LIMITS.binaryBytes) {
305
+ return null;
306
+ }
307
+ entries.push({ name: entry.name, mimeType: entry.mimeType, size: entry.size });
308
+ }
309
+ return entries;
310
+ }
311
+ function isBoundedMediaDataUrl(value) {
312
+ if (!isBoundedString(value, HOST_WIRE_LIMITS.base64Characters + 512, 1)) return false;
313
+ if (!value.startsWith("data:")) return false;
314
+ const separator = value.indexOf(";base64,");
315
+ return separator > 5 && separator <= HOST_WIRE_LIMITS.identifierCharacters;
316
+ }
317
+ function isDocumentSessionMessageStatus(value) {
318
+ return value === "idle" || value === "saved" || value === "dirty" || value === "saving" || value === "error" || value === "conflict" || value === "closed";
319
+ }
320
+ function isSessionEnvelope(value) {
321
+ return hasBoundedString(value, "sessionId", HOST_WIRE_LIMITS.identifierCharacters, 1) && hasNonNegativeInteger(value, "clientRevision") && hasNonNegativeInteger(value, "baseDocumentVersion");
322
+ }
323
+ function hasRequestId(value) {
324
+ return hasNonNegativeInteger(value, "requestId") && value.requestId <= MAX_REQUEST_ID;
325
+ }
326
+ function hasBoundedString(value, key, maximumCharacters, minimumCharacters = 0) {
327
+ return isBoundedString(value[key], maximumCharacters, minimumCharacters);
328
+ }
329
+ function hasNullableBoundedString(value, key, maximumCharacters, minimumCharacters = 0) {
330
+ return value[key] === null || isBoundedString(value[key], maximumCharacters, minimumCharacters);
331
+ }
332
+ function hasNonNegativeInteger(value, key) {
333
+ const entry = value[key];
334
+ return typeof entry === "number" && Number.isSafeInteger(entry) && entry >= 0;
335
+ }
336
+ function isNullableNonNegativeInteger(value) {
337
+ return value === null || typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
338
+ }
339
+ function isRecord(value) {
340
+ return typeof value === "object" && value !== null && !Array.isArray(value);
341
+ }
342
+ function hasOnlyKeys(value, keys) {
343
+ const expected = new Set(keys);
344
+ const actual = Object.keys(value);
345
+ return actual.length === expected.size && actual.every((key) => expected.has(key));
346
+ }
347
+ function hasSafeFilename(value, key) {
348
+ return isSafeExportFilename(value[key]);
349
+ }
350
+ function isSafeExportFilename(value) {
351
+ return isBoundedString(value, 255, 1) && value.trim() === value && !/[\\/:*?"<>|]/.test(value) && !hasControlCharacter(value) && value !== "." && value !== ".." && !value.endsWith(".") && !value.endsWith(" ");
352
+ }
353
+ function hasControlCharacter(value) {
354
+ for (let index = 0; index < value.length; index += 1) {
355
+ const code = value.charCodeAt(index);
356
+ if (code <= 31 || code === 127) return true;
357
+ }
358
+ return false;
359
+ }
360
+ function hasMimeType(value, key) {
361
+ return isSafeMimeType(value[key]);
362
+ }
363
+ function isSafeMimeType(value) {
364
+ return isBoundedString(value, HOST_WIRE_LIMITS.identifierCharacters, 1) && /^[A-Za-z0-9!#$&^_.+-]+\/[A-Za-z0-9!#$&^_.+-]+(?:\s*;\s*[A-Za-z0-9!#$&^_.+-]+=[^;\r\n]+)*$/.test(
365
+ value
366
+ );
367
+ }
368
+ export {
369
+ DEFAULT_VSCODE_WRITE_CANVAS_SETTINGS,
370
+ DOCBLOCKS_ACCENT_COLORS,
371
+ DOCBLOCKS_WRITE_CANVAS_LINE_SPACING_MAX,
372
+ DOCBLOCKS_WRITE_CANVAS_LINE_SPACING_MIN,
373
+ DOCBLOCKS_WRITE_CANVAS_TEXT_SIZE_MAX,
374
+ DOCBLOCKS_WRITE_CANVAS_TEXT_SIZE_MIN,
375
+ isDocBlocksAccentColor,
376
+ isDocBlocksWriteCanvasLineSpacing,
377
+ isDocBlocksWriteCanvasTextSize,
378
+ isSafeExportFilename,
379
+ isSafeMimeType,
380
+ parseExtensionToWebviewMessage,
381
+ parseWebviewToExtensionMessage
382
+ };
383
+ //# sourceMappingURL=index.js.map