collabmd 0.1.44 → 0.1.45

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 (170) hide show
  1. package/dist/client/assets/{chunk-AXR3VHVW-0GTk_evH.js → chunk-ERSWUTIN-ME9RVNel.js} +3 -3
  2. package/dist/client/assets/{chunk-CZQZEIFA-DT3N9fo7.js → chunk-YGJVY4SA-CjSe7Bx7.js} +2 -2
  3. package/dist/client/assets/{comment-threads-D-iKphIp.js → comment-threads-DDegmaFO.js} +1 -1
  4. package/dist/client/assets/drawio-editor-ClE8jpoG.js +9 -0
  5. package/dist/client/assets/drawioEditor-CXaTM9Ds.js +2 -0
  6. package/dist/client/assets/editor-session-GTwZS6Df.js +16 -0
  7. package/dist/client/assets/embedded-editor-base-CiNEc8vy.css +1 -0
  8. package/dist/client/assets/{en-GADW4C6J-DQ6zyCEM.js → en-7NFCYGKX-BrgYZAEe.js} +1 -1
  9. package/dist/client/assets/{excalidraw-editor-BHu6k8d4.js → excalidraw-editor-BZVM81BO.js} +2 -2
  10. package/dist/client/assets/excalidraw-editor-CyGwOhLz.css +1 -0
  11. package/dist/client/assets/excalidraw-scene-C8n9CHsK.js +176 -0
  12. package/dist/client/assets/excalidrawEditor-DxJanCze.js +2 -0
  13. package/dist/client/assets/export-page-CUfws2T-.js +39 -0
  14. package/dist/client/assets/exportDocument-BCuxqXDY.js +2 -0
  15. package/dist/client/assets/exportDocument-DV-OX74E.css +1 -0
  16. package/dist/client/assets/image-QXRYHUNP-lfTHE3bb.js +1 -0
  17. package/dist/client/assets/index-C3YnUgMD.css +1 -0
  18. package/dist/client/assets/index-D2wXraJ1.js +2 -0
  19. package/dist/client/assets/main-DtiGz7uI.js +795 -0
  20. package/dist/client/assets/modulepreload-polyfill-P2Xu9kJm.js +1 -0
  21. package/dist/client/assets/preview-diagram-utils-txBCoW8d.js +1 -0
  22. package/dist/client/assets/quick-switcher-controller-shW_6vPY.js +12 -0
  23. package/dist/client/assets/room-CQLoqtMo.js +1 -0
  24. package/dist/client/assets/runtime-config-DSGmGE9V.js +1 -0
  25. package/dist/client/assets/vault-api-client-C6bcGwy-.js +5 -0
  26. package/dist/client/assets/{yjs-provider-reset-guard-Cox4nxwu.js → yjs-provider-reset-guard-DE0vINDP.js} +1 -1
  27. package/dist/client/drawio-editor.html +3 -2
  28. package/dist/client/excalidraw-editor.html +3 -2
  29. package/dist/client/export-document.html +4 -3
  30. package/dist/client/index.html +97 -27
  31. package/package.json +10 -12
  32. package/src/client/app/drawio-editor-entry.js +0 -3
  33. package/src/client/app/drawio-editor.html +1 -0
  34. package/src/client/app/excalidraw-editor-entry.js +0 -3
  35. package/src/client/app/excalidraw-editor.html +1 -0
  36. package/src/client/app/export-document-entry.js +0 -3
  37. package/src/client/app/export-document.html +1 -0
  38. package/src/client/app/index.html +94 -24
  39. package/src/client/app/main-entry.js +0 -5
  40. package/src/client/application/app-shell/chat-feature.js +180 -124
  41. package/src/client/application/app-shell/comments-feature.js +1 -1
  42. package/src/client/application/app-shell/git-feature.js +4 -9
  43. package/src/client/application/app-shell/presence-feature.js +16 -10
  44. package/src/client/application/app-shell/ui-feature-shell.js +33 -15
  45. package/src/client/application/app-shell/ui-feature-sidebar.js +74 -1
  46. package/src/client/application/app-shell/ui-feature-tab-activity.js +2 -2
  47. package/src/client/application/app-shell/workspace-feature.js +22 -83
  48. package/src/client/application/app-shell-elements.js +7 -1
  49. package/src/client/application/diagram-chrome.js +161 -166
  50. package/src/client/application/diagram-preview-export.js +7 -34
  51. package/src/client/application/diagram-preview-hydrator.js +1 -19
  52. package/src/client/application/markdown-frontmatter.js +0 -2
  53. package/src/client/application/mermaid-preview-hydrator.js +1 -14
  54. package/src/client/application/plantuml-preview-hydrator.js +0 -10
  55. package/src/client/application/preview-diagram-utils.js +31 -2
  56. package/src/client/application/preview-render-compiler.js +2 -1
  57. package/src/client/application/preview-renderer.js +2 -2
  58. package/src/client/application/quick-switcher-loader.js +3 -1
  59. package/src/client/application/workspace-preview-controller.js +0 -3
  60. package/src/client/bootstrap/collabmd-app-shell.js +125 -39
  61. package/src/client/domain/excalidraw-collaboration.js +0 -2
  62. package/src/client/domain/room.js +38 -0
  63. package/src/client/export/export-pipeline.js +6 -34
  64. package/src/client/infrastructure/auth-client.js +4 -10
  65. package/src/client/infrastructure/browser-notification-port.js +33 -20
  66. package/src/client/infrastructure/browser-preferences-port.js +36 -9
  67. package/src/client/infrastructure/editor-view-adapter.js +87 -3
  68. package/src/client/infrastructure/lobby-presence.js +1 -0
  69. package/src/client/infrastructure/vault-api-client.js +25 -0
  70. package/src/client/infrastructure/workspace-sync-client.js +13 -1
  71. package/src/client/presentation/comment-overview-controller.js +18 -53
  72. package/src/client/presentation/comment-ui/comment-ui-card.js +1 -12
  73. package/src/client/presentation/comment-ui/comment-ui-layout.js +242 -219
  74. package/src/client/presentation/comment-ui/comment-ui-render.js +32 -45
  75. package/src/client/presentation/comment-ui/comment-ui-shared.js +65 -14
  76. package/src/client/presentation/comment-ui-controller.js +5 -1
  77. package/src/client/presentation/file-action-controller.js +32 -0
  78. package/src/client/presentation/file-explorer-controller.js +33 -3
  79. package/src/client/presentation/file-explorer-view.js +49 -5
  80. package/src/client/presentation/file-tree-state.js +10 -4
  81. package/src/client/presentation/quick-switcher-controller.js +243 -72
  82. package/src/client/presentation/quick-switcher-text-search.js +2 -2
  83. package/src/client/presentation/toast-controller.js +3 -0
  84. package/src/client/styles/components/feedback.css +6 -0
  85. package/src/client/styles/features/collaboration-chat.css +49 -53
  86. package/src/client/styles/features/collaboration-presence.css +9 -7
  87. package/src/client/styles/features/comment-card.css +25 -11
  88. package/src/client/styles/features/comment-overlays.css +0 -4
  89. package/src/client/styles/features/comment-overview.css +44 -21
  90. package/src/client/styles/features/comments-drawer.css +2 -100
  91. package/src/client/styles/features/diagram-preview.css +5 -18
  92. package/src/client/styles/features/embedded-preview.css +8 -33
  93. package/src/client/styles/features/quick-switcher.css +8 -0
  94. package/src/client/styles/foundation/tokens.css +1 -0
  95. package/src/client/styles/layout/editor-page.css +40 -0
  96. package/src/client/styles/layout/responsive.css +31 -1
  97. package/src/client/styles/layout/shell.css +25 -6
  98. package/src/client/styles/layout/sidebar.css +47 -15
  99. package/src/client/styles/overrides/codemirror.css +217 -15
  100. package/src/server/application/workspace-reconciliation.js +1 -1
  101. package/src/server/create-app-server.js +2 -3
  102. package/src/server/domain/bases/base-query-service.js +1 -77
  103. package/src/server/domain/comment-overview.js +10 -3
  104. package/src/server/domain/docx-exporter.js +24 -33
  105. package/src/server/domain/ripgrep-search-service.js +3 -1
  106. package/src/server/domain/workspace-state.js +32 -11
  107. package/src/server/infrastructure/git/diff-service.js +24 -13
  108. package/src/server/infrastructure/git/git-service.js +40 -10
  109. package/src/server/infrastructure/git/history-service.js +42 -29
  110. package/src/server/infrastructure/git/path-utils.js +1 -1
  111. package/src/server/infrastructure/git/responses.js +0 -95
  112. package/src/server/infrastructure/github/github-app-client.js +22 -15
  113. package/src/server/infrastructure/http/create-request-handler.js +2 -8
  114. package/src/server/infrastructure/http/create-vault-api-command-handler.js +5 -5
  115. package/src/server/infrastructure/http/http-errors.js +7 -1
  116. package/dist/client/assets/bases-preview-controller-2pLHk0uk.js +0 -143
  117. package/dist/client/assets/button-BCEiw4Rw.js +0 -1
  118. package/dist/client/assets/diagram-action-icons-aa_KOv9h.js +0 -36
  119. package/dist/client/assets/drawio-editor-DDvFoarP.js +0 -9
  120. package/dist/client/assets/drawio-embed-controller-BD1GTRwn.js +0 -1
  121. package/dist/client/assets/drawioEditor-Bu5grlH5.js +0 -2
  122. package/dist/client/assets/editor-session-DGlpiAsK.js +0 -16
  123. package/dist/client/assets/embedded-editor-base-C9roKYpW.css +0 -1
  124. package/dist/client/assets/excalidraw-editor-Cr_184EF.css +0 -1
  125. package/dist/client/assets/excalidraw-embed-controller-y2fenN_g.js +0 -1
  126. package/dist/client/assets/excalidraw-embed-reconciler-DGiagExg.js +0 -1
  127. package/dist/client/assets/excalidraw-scene-BvsQ6mLP.js +0 -176
  128. package/dist/client/assets/excalidrawEditor-4vFE--Uw.js +0 -2
  129. package/dist/client/assets/export-page-Cby8JzPO.js +0 -39
  130. package/dist/client/assets/exportDocument-C9v-bc7I.css +0 -1
  131. package/dist/client/assets/exportDocument-CRHCfsdo.js +0 -2
  132. package/dist/client/assets/file-history-view-controller-BDjEV9xJ.js +0 -112
  133. package/dist/client/assets/git-diff-view-controller-DgdM1aqb.js +0 -150
  134. package/dist/client/assets/git-panel-controller-BDTR2HVp.js +0 -207
  135. package/dist/client/assets/image-XGD7JQR6-XDUWHRpO.js +0 -1
  136. package/dist/client/assets/index-7xOyXDhP.css +0 -1
  137. package/dist/client/assets/index-Bz1KuQ6y.js +0 -2
  138. package/dist/client/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  139. package/dist/client/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  140. package/dist/client/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  141. package/dist/client/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  142. package/dist/client/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  143. package/dist/client/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  144. package/dist/client/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  145. package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  146. package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  147. package/dist/client/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  148. package/dist/client/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  149. package/dist/client/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  150. package/dist/client/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  151. package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  152. package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  153. package/dist/client/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  154. package/dist/client/assets/main-Ci07m9oP.js +0 -152
  155. package/dist/client/assets/preview-diagram-utils-n_bbJA9V.js +0 -1
  156. package/dist/client/assets/quick-switcher-controller-CoiYvllm.js +0 -12
  157. package/dist/client/assets/room-CDrmIdDt.js +0 -1
  158. package/dist/client/assets/runtime-config-CDgeuPWN.js +0 -1
  159. package/dist/client/assets/runtime-config-loader-BHGniHP5.js +0 -1
  160. package/dist/client/assets/runtime-paths-DvpihCEq.js +0 -1
  161. package/dist/client/assets/segmented-control-DJrHSz8M.js +0 -1
  162. package/dist/client/assets/vault-api-client-sLB2bo56.js +0 -1
  163. package/dist/client/assets/vault-paths-CVkuh0j-.js +0 -5
  164. package/src/client/bootstrap/lazy-controller-feature.js +0 -433
  165. package/src/client/infrastructure/backlinks-api-client.js +0 -16
  166. package/src/client/infrastructure/plantuml-api-client.js +0 -19
  167. package/src/client/infrastructure/runtime-config-loader.js +0 -56
  168. package/src/server/infrastructure/git/command-runner.js +0 -49
  169. package/src/server/infrastructure/git/errors.js +0 -8
  170. package/src/server/infrastructure/http/create-esm-proxy-handler.js +0 -130
@@ -1,4 +1,4 @@
1
- import { createGitRequestError } from './errors.js';
1
+ import { createRequestError as createGitRequestError } from '../http/http-errors.js';
2
2
  import { getVaultFileKind, isImageAttachmentFilePath } from '../../../domain/file-kind.js';
3
3
  import { normalizeRelativeGitPath } from './path-utils.js';
4
4
  import {
@@ -9,11 +9,7 @@ import {
9
9
  parseUnifiedDiff,
10
10
  } from './parsers.js';
11
11
  import {
12
- createCommitDiffResponse,
13
12
  createEmptyStats,
14
- createFileHistoryResponse,
15
- createFileSnapshotResponse,
16
- createHistoryResponse,
17
13
  } from './responses.js';
18
14
 
19
15
  const EMPTY_TREE_HASH = '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
@@ -127,13 +123,13 @@ export class GitHistoryService {
127
123
  const normalizedOffset = normalizeHistoryOffset(offset);
128
124
 
129
125
  if (!isGitRepo) {
130
- return createHistoryResponse({
126
+ return {
131
127
  commits: [],
132
128
  hasMore: false,
133
129
  isGitRepo: false,
134
130
  limit: normalizedLimit,
135
131
  offset: normalizedOffset,
136
- });
132
+ };
137
133
  }
138
134
 
139
135
  const cacheKey = JSON.stringify({
@@ -149,12 +145,13 @@ export class GitHistoryService {
149
145
  return this.runRequest(cacheKey, async () => {
150
146
  const hasHeadCommit = await this.hasHeadCommit();
151
147
  if (!hasHeadCommit) {
152
- return setCachedValue(this.historyCache, cacheKey, createHistoryResponse({
148
+ return setCachedValue(this.historyCache, cacheKey, {
153
149
  commits: [],
154
150
  hasMore: false,
151
+ isGitRepo: true,
155
152
  limit: normalizedLimit,
156
153
  offset: normalizedOffset,
157
- }), this.responseCacheTtlMs);
154
+ }, this.responseCacheTtlMs);
158
155
  }
159
156
 
160
157
  const output = await this.commandRunner.execGit([
@@ -175,12 +172,13 @@ export class GitHistoryService {
175
172
  .map((chunk) => this.parseHistoryChunk(chunk));
176
173
 
177
174
  const hasMore = commits.length > normalizedLimit;
178
- const response = createHistoryResponse({
175
+ const response = {
179
176
  commits: commits.slice(0, normalizedLimit),
180
177
  hasMore,
178
+ isGitRepo: true,
181
179
  limit: normalizedLimit,
182
180
  offset: normalizedOffset,
183
- });
181
+ };
184
182
 
185
183
  return setCachedValue(this.historyCache, cacheKey, response, this.responseCacheTtlMs);
186
184
  });
@@ -193,14 +191,14 @@ export class GitHistoryService {
193
191
  const normalizedPath = normalizeRelativeGitPath(path);
194
192
 
195
193
  if (!isGitRepo) {
196
- return createFileHistoryResponse({
194
+ return {
197
195
  commits: [],
198
196
  hasMore: false,
199
197
  isGitRepo: false,
200
198
  limit: normalizedLimit,
201
199
  offset: normalizedOffset,
202
200
  path: normalizedPath,
203
- });
201
+ };
204
202
  }
205
203
 
206
204
  const cacheKey = JSON.stringify({
@@ -217,13 +215,14 @@ export class GitHistoryService {
217
215
  return this.runRequest(cacheKey, async () => {
218
216
  const hasHeadCommit = await this.hasHeadCommit();
219
217
  if (!hasHeadCommit) {
220
- return setCachedValue(this.historyCache, cacheKey, createFileHistoryResponse({
218
+ return setCachedValue(this.historyCache, cacheKey, {
221
219
  commits: [],
222
220
  hasMore: false,
221
+ isGitRepo: true,
223
222
  limit: normalizedLimit,
224
223
  offset: normalizedOffset,
225
224
  path: normalizedPath,
226
- }), this.responseCacheTtlMs);
225
+ }, this.responseCacheTtlMs);
227
226
  }
228
227
 
229
228
  const logArgs = [
@@ -254,13 +253,14 @@ export class GitHistoryService {
254
253
 
255
254
  const commits = this.mergeFileHistoryChunks(nameStatusOutput, numstatOutput);
256
255
  const hasMore = commits.length > normalizedLimit;
257
- const response = createFileHistoryResponse({
256
+ const response = {
258
257
  commits: commits.slice(0, normalizedLimit),
259
258
  hasMore,
259
+ isGitRepo: true,
260
260
  limit: normalizedLimit,
261
261
  offset: normalizedOffset,
262
262
  path: normalizedPath,
263
- });
263
+ };
264
264
 
265
265
  return setCachedValue(this.historyCache, cacheKey, response, this.responseCacheTtlMs);
266
266
  });
@@ -269,13 +269,19 @@ export class GitHistoryService {
269
269
  async getCommit({ allowLargePatch = false, hash, metaOnly = false, path = null } = {}) {
270
270
  const isGitRepo = await this.commandRunner.isGitRepo();
271
271
  if (!isGitRepo) {
272
- return createCommitDiffResponse({
272
+ return {
273
273
  commit: null,
274
274
  files: [],
275
275
  isGitRepo: false,
276
276
  metaOnly,
277
277
  path: null,
278
- });
278
+ source: 'commit',
279
+ summary: {
280
+ additions: 0,
281
+ deletions: 0,
282
+ filesChanged: 0,
283
+ },
284
+ };
279
285
  }
280
286
 
281
287
  const normalizedHash = this.normalizeCommitHash(hash);
@@ -301,13 +307,15 @@ export class GitHistoryService {
301
307
  const summary = createSummaryFromFiles(meta.files);
302
308
 
303
309
  if (metaOnly) {
304
- const metaResponse = createCommitDiffResponse({
310
+ const metaResponse = {
305
311
  commit: meta.commit,
306
312
  files: meta.files,
313
+ isGitRepo: true,
307
314
  metaOnly: true,
308
315
  path: normalizedPath,
316
+ source: 'commit',
309
317
  summary,
310
- });
318
+ };
311
319
  return setCachedValue(this.commitCache, cacheKey, metaResponse, this.responseCacheTtlMs);
312
320
  }
313
321
 
@@ -326,7 +334,7 @@ export class GitHistoryService {
326
334
  !allowLargePatch
327
335
  && (fileSummary.additions + fileSummary.deletions) > this.maxInitialPatchLines
328
336
  ) {
329
- const guardedResponse = createCommitDiffResponse({
337
+ const guardedResponse = {
330
338
  commit: meta.commit,
331
339
  files: [{
332
340
  ...baseFile,
@@ -335,10 +343,12 @@ export class GitHistoryService {
335
343
  patchLineCount: fileSummary.additions + fileSummary.deletions,
336
344
  tooLarge: true,
337
345
  }],
346
+ isGitRepo: true,
338
347
  metaOnly: false,
339
348
  path: normalizedPath,
349
+ source: 'commit',
340
350
  summary,
341
- });
351
+ };
342
352
  return setCachedValue(this.commitCache, cacheKey, guardedResponse, this.responseCacheTtlMs);
343
353
  }
344
354
 
@@ -385,13 +395,15 @@ export class GitHistoryService {
385
395
  tooLarge: false,
386
396
  };
387
397
 
388
- const response = createCommitDiffResponse({
398
+ const response = {
389
399
  commit: meta.commit,
390
400
  files: [detailedFile],
401
+ isGitRepo: true,
391
402
  metaOnly: false,
392
403
  path: normalizedPath,
404
+ source: 'commit',
393
405
  summary,
394
- });
406
+ };
395
407
  return setCachedValue(this.commitCache, cacheKey, response, this.responseCacheTtlMs);
396
408
  });
397
409
  }
@@ -402,13 +414,13 @@ export class GitHistoryService {
402
414
  const normalizedPath = normalizeRelativeGitPath(path);
403
415
 
404
416
  if (!isGitRepo) {
405
- return createFileSnapshotResponse({
417
+ return {
406
418
  content: '',
407
419
  fileKind: getVaultFileKind(normalizedPath),
408
420
  hash: normalizedHash,
409
421
  isGitRepo: false,
410
422
  path: normalizedPath,
411
- });
423
+ };
412
424
  }
413
425
 
414
426
  if (isImageAttachmentFilePath(normalizedPath)) {
@@ -438,12 +450,13 @@ export class GitHistoryService {
438
450
  throw createGitRequestError(404, 'Commit file not found');
439
451
  }
440
452
 
441
- return setCachedValue(this.commitCache, cacheKey, createFileSnapshotResponse({
453
+ return setCachedValue(this.commitCache, cacheKey, {
442
454
  content,
443
455
  fileKind,
444
456
  hash: normalizedHash,
457
+ isGitRepo: true,
445
458
  path: normalizedPath,
446
- }), this.responseCacheTtlMs);
459
+ }, this.responseCacheTtlMs);
447
460
  });
448
461
  }
449
462
 
@@ -1,4 +1,4 @@
1
- import { createGitRequestError } from './errors.js';
1
+ import { createRequestError as createGitRequestError } from '../http/http-errors.js';
2
2
 
3
3
  export function decodeQuotedPath(pathValue) {
4
4
  const rawValue = String(pathValue ?? '').trim();
@@ -54,98 +54,3 @@ export function createEmptyStatusResponse() {
54
54
  summary: createEmptySummary(),
55
55
  };
56
56
  }
57
-
58
- export function createDiffResponse({
59
- files = [],
60
- isGitRepo = true,
61
- metaOnly = false,
62
- path = null,
63
- scope = 'working-tree',
64
- summary = {
65
- additions: 0,
66
- deletions: 0,
67
- filesChanged: 0,
68
- },
69
- } = {}) {
70
- return {
71
- files,
72
- isGitRepo,
73
- metaOnly,
74
- path,
75
- scope,
76
- summary,
77
- };
78
- }
79
-
80
- export function createHistoryResponse({
81
- commits = [],
82
- hasMore = false,
83
- isGitRepo = true,
84
- limit = 30,
85
- offset = 0,
86
- } = {}) {
87
- return {
88
- commits,
89
- hasMore,
90
- isGitRepo,
91
- limit,
92
- offset,
93
- };
94
- }
95
-
96
- export function createFileHistoryResponse({
97
- commits = [],
98
- hasMore = false,
99
- isGitRepo = true,
100
- limit = 30,
101
- offset = 0,
102
- path = null,
103
- } = {}) {
104
- return {
105
- commits,
106
- hasMore,
107
- isGitRepo,
108
- limit,
109
- offset,
110
- path,
111
- };
112
- }
113
-
114
- export function createCommitDiffResponse({
115
- commit = null,
116
- files = [],
117
- isGitRepo = true,
118
- metaOnly = false,
119
- path = null,
120
- summary = {
121
- additions: 0,
122
- deletions: 0,
123
- filesChanged: 0,
124
- },
125
- } = {}) {
126
- return {
127
- commit,
128
- files,
129
- isGitRepo,
130
- metaOnly,
131
- path,
132
- source: 'commit',
133
- summary,
134
- };
135
- }
136
-
137
- export function createFileSnapshotResponse({
138
- content = '',
139
- fileKind = null,
140
- hash = null,
141
- isGitRepo = true,
142
- path = null,
143
- } = {}) {
144
- return {
145
- content,
146
- fileKind,
147
- hash,
148
- isGitRepo,
149
- path,
150
- };
151
- }
@@ -1,16 +1,11 @@
1
1
  import { createSign } from 'node:crypto';
2
2
 
3
+ import { createRequestError } from '../http/http-errors.js';
4
+
3
5
  function base64UrlJson(value) {
4
6
  return Buffer.from(JSON.stringify(value)).toString('base64url');
5
7
  }
6
8
 
7
- function createRequestError(statusCode, message, code) {
8
- const error = new Error(message);
9
- error.statusCode = statusCode;
10
- error.code = code;
11
- return error;
12
- }
13
-
14
9
  function normalizeBaseUrl(value) {
15
10
  return String(value ?? 'https://api.github.com').trim().replace(/\/+$/u, '') || 'https://api.github.com';
16
11
  }
@@ -80,7 +75,9 @@ export class GitHubAppClient {
80
75
 
81
76
  createAppJwt() {
82
77
  if (!this.isConfigured()) {
83
- throw createRequestError(503, 'GitHub App setup is not configured.', 'HOSTED_GITHUB_APP_NOT_CONFIGURED');
78
+ throw createRequestError(503, 'GitHub App setup is not configured.', {
79
+ code: 'HOSTED_GITHUB_APP_NOT_CONFIGURED',
80
+ });
84
81
  }
85
82
 
86
83
  return createGitHubAppJwt({
@@ -91,7 +88,9 @@ export class GitHubAppClient {
91
88
 
92
89
  createInstallationSetupUrl({ state } = {}) {
93
90
  if (!this.appSlug) {
94
- throw createRequestError(503, 'GitHub App slug is not configured.', 'HOSTED_GITHUB_APP_NOT_CONFIGURED');
91
+ throw createRequestError(503, 'GitHub App slug is not configured.', {
92
+ code: 'HOSTED_GITHUB_APP_NOT_CONFIGURED',
93
+ });
95
94
  }
96
95
 
97
96
  const setupUrl = new URL(`/apps/${encodeURIComponent(this.appSlug)}/installations/new`, this.htmlBaseUrl);
@@ -131,7 +130,7 @@ export class GitHubAppClient {
131
130
  throw createRequestError(
132
131
  response.status,
133
132
  payload?.message || 'GitHub API request failed.',
134
- 'HOSTED_GITHUB_API_FAILED',
133
+ { code: 'HOSTED_GITHUB_API_FAILED' },
135
134
  );
136
135
  }
137
136
 
@@ -141,7 +140,9 @@ export class GitHubAppClient {
141
140
  async createInstallationAccessToken(installationId, { appJwt = null } = {}) {
142
141
  const normalizedInstallationId = String(installationId ?? '').trim();
143
142
  if (!normalizedInstallationId) {
144
- throw createRequestError(400, 'GitHub installation id is required.', 'HOSTED_GITHUB_INSTALLATION_REQUIRED');
143
+ throw createRequestError(400, 'GitHub installation id is required.', {
144
+ code: 'HOSTED_GITHUB_INSTALLATION_REQUIRED',
145
+ });
145
146
  }
146
147
 
147
148
  const payload = await this.request(`/app/installations/${encodeURIComponent(normalizedInstallationId)}/access_tokens`, {
@@ -150,7 +151,9 @@ export class GitHubAppClient {
150
151
  });
151
152
  const token = String(payload?.token ?? '').trim();
152
153
  if (!token) {
153
- throw createRequestError(502, 'GitHub did not return an installation access token.', 'HOSTED_GITHUB_TOKEN_MISSING');
154
+ throw createRequestError(502, 'GitHub did not return an installation access token.', {
155
+ code: 'HOSTED_GITHUB_TOKEN_MISSING',
156
+ });
154
157
  }
155
158
  return token;
156
159
  }
@@ -158,7 +161,9 @@ export class GitHubAppClient {
158
161
  async getInstallation(installationId, { appJwt = null } = {}) {
159
162
  const normalizedInstallationId = String(installationId ?? '').trim();
160
163
  if (!normalizedInstallationId) {
161
- throw createRequestError(400, 'GitHub installation id is required.', 'HOSTED_GITHUB_INSTALLATION_REQUIRED');
164
+ throw createRequestError(400, 'GitHub installation id is required.', {
165
+ code: 'HOSTED_GITHUB_INSTALLATION_REQUIRED',
166
+ });
162
167
  }
163
168
 
164
169
  return this.request(`/app/installations/${encodeURIComponent(normalizedInstallationId)}`, {
@@ -176,7 +181,9 @@ export class GitHubAppClient {
176
181
  async resolveVaultSourceFromInstallation(installationId) {
177
182
  const normalizedInstallationId = String(installationId ?? '').trim();
178
183
  if (!normalizedInstallationId) {
179
- throw createRequestError(400, 'GitHub installation id is required.', 'HOSTED_GITHUB_INSTALLATION_REQUIRED');
184
+ throw createRequestError(400, 'GitHub installation id is required.', {
185
+ code: 'HOSTED_GITHUB_INSTALLATION_REQUIRED',
186
+ });
180
187
  }
181
188
 
182
189
  const appJwt = this.createAppJwt();
@@ -189,7 +196,7 @@ export class GitHubAppClient {
189
196
  throw createRequestError(
190
197
  409,
191
198
  'GitHub App installation must grant access to exactly one selected repository.',
192
- 'HOSTED_GITHUB_REPOSITORY_SELECTION_REQUIRED',
199
+ { code: 'HOSTED_GITHUB_REPOSITORY_SELECTION_REQUIRED' },
193
200
  );
194
201
  }
195
202
 
@@ -2,7 +2,6 @@ import { createAuthApiHandler } from './create-auth-api-handler.js';
2
2
  import { createGitApiCommandHandler } from './create-git-api-command-handler.js';
3
3
  import { createGitApiQueryHandler } from './create-git-api-query-handler.js';
4
4
  import { createHostedApiHandler } from './create-hosted-api-handler.js';
5
- import { createEsmProxyHandler } from './create-esm-proxy-handler.js';
6
5
  import { createPlantUmlApiHandler } from './create-plantuml-api-handler.js';
7
6
  import { createStaticHandler } from './create-static-handler.js';
8
7
  import { createVaultApiCommandHandler } from './create-vault-api-command-handler.js';
@@ -45,7 +44,7 @@ export function createRequestHandler(
45
44
  vaultFileStore,
46
45
  backlinkIndex,
47
46
  baseQueryService = null,
48
- docxExporter = null,
47
+ renderDocx = null,
49
48
  roomRegistry = null,
50
49
  plantUmlRenderer = null,
51
50
  gitService = null,
@@ -56,7 +55,6 @@ export function createRequestHandler(
56
55
  hostedWorkspaceService = null,
57
56
  githubSetupFlow = null,
58
57
  ) {
59
- const handleEsmProxy = createEsmProxyHandler();
60
58
  const handleStaticRequest = createStaticHandler(config, authService, searchService);
61
59
  const handleAuthApi = createAuthApiHandler({ authService });
62
60
  const handleHostedApi = createHostedApiHandler({
@@ -80,7 +78,7 @@ export function createRequestHandler(
80
78
  });
81
79
  const handleVaultApiCommand = createVaultApiCommandHandler({
82
80
  backlinkIndex,
83
- docxExporter,
81
+ renderDocx,
84
82
  roomRegistry,
85
83
  vaultFileStore,
86
84
  workspaceMutationCoordinator,
@@ -195,10 +193,6 @@ export function createRequestHandler(
195
193
  return;
196
194
  }
197
195
 
198
- if (await handleEsmProxy(req, res, requestUrl)) {
199
- return;
200
- }
201
-
202
196
  if (requestUrl.pathname.startsWith('/api/')) {
203
197
  const authorization = authService.authorizeApiRequest(req);
204
198
  if (!authorization.ok) {
@@ -40,7 +40,7 @@ function getDirectoryDeleteStatusCode(message = '') {
40
40
  return String(message).includes('Directory is not empty') ? 409 : 400;
41
41
  }
42
42
 
43
- async function handleExportDocx({ docxExporter }, req, res) {
43
+ async function handleExportDocx({ renderDocx }, req, res) {
44
44
  try {
45
45
  const body = await parseJsonBody(req, DOCX_EXPORT_REQUEST_LIMIT_BYTES);
46
46
  if (!body?.filePath || typeof body?.html !== 'string') {
@@ -48,12 +48,12 @@ async function handleExportDocx({ docxExporter }, req, res) {
48
48
  return true;
49
49
  }
50
50
 
51
- if (!docxExporter?.render) {
51
+ if (typeof renderDocx !== 'function') {
52
52
  jsonResponse(req, res, 503, { error: 'DOCX export is unavailable' });
53
53
  return true;
54
54
  }
55
55
 
56
- const docxBuffer = await docxExporter.render({
56
+ const docxBuffer = await renderDocx({
57
57
  html: body.html,
58
58
  title: body.title || '',
59
59
  });
@@ -289,11 +289,11 @@ const ROUTE_TABLE = [
289
289
  ];
290
290
 
291
291
  export function createVaultApiCommandHandler({
292
- docxExporter = null,
292
+ renderDocx = null,
293
293
  vaultFileStore,
294
294
  workspaceMutationCoordinator = null,
295
295
  }) {
296
- const context = { docxExporter, vaultFileStore, workspaceMutationCoordinator };
296
+ const context = { renderDocx, vaultFileStore, workspaceMutationCoordinator };
297
297
 
298
298
  return async function handleVaultApiCommand(req, res, requestUrl) {
299
299
  for (const route of ROUTE_TABLE) {
@@ -1,6 +1,12 @@
1
- export function createRequestError(statusCode, message) {
1
+ export function createRequestError(statusCode, message, { code = null, requestCode = null } = {}) {
2
2
  const error = new Error(message);
3
3
  error.statusCode = statusCode;
4
+ if (code) {
5
+ error.code = code;
6
+ }
7
+ if (requestCode) {
8
+ error.requestCode = requestCode;
9
+ }
4
10
  return error;
5
11
  }
6
12