collabmd 0.1.31 → 0.1.32

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 (93) hide show
  1. package/dist/client/assets/{drawio-editor-B4sHHwWJ.js → drawio-editor-Br4qyh3r.js} +1 -1
  2. package/dist/client/assets/drawioEditor-ClmnTx5J.js +2 -0
  3. package/dist/client/assets/{editor-session-BKHEYkbY.js → editor-session-Cf-iV5-3.js} +2 -2
  4. package/dist/client/assets/embedded-editor-base-CgEkjNYn.css +1 -0
  5. package/dist/client/assets/{excalidraw-editor-CHbeNZu6.js → excalidraw-editor-CXAxVhlw.js} +2 -2
  6. package/dist/client/assets/{excalidrawEditor-BhaTX2Ko.js → excalidrawEditor-DoH_kMdu.js} +2 -2
  7. package/dist/client/assets/exportDocument-9wTrBZNS.css +1 -0
  8. package/dist/client/assets/{index-kPgEYvEX.js → index-C8QZYHvV.js} +2 -2
  9. package/dist/client/assets/index-CxSbUTs2.css +1 -0
  10. package/dist/client/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  11. package/dist/client/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  12. package/dist/client/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  13. package/dist/client/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  14. package/dist/client/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  15. package/dist/client/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  16. package/dist/client/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  17. package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  18. package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  19. package/dist/client/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  20. package/dist/client/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  21. package/dist/client/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  22. package/dist/client/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  23. package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  24. package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  25. package/dist/client/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  26. package/dist/client/assets/main-BjHHMlv0.js +1249 -0
  27. package/dist/client/assets/vault-api-client-Bf9tB_GW.js +1 -0
  28. package/dist/client/assets/vault-api-client-D7Ck0CvR.css +1 -0
  29. package/dist/client/drawio-editor.html +1 -1
  30. package/dist/client/excalidraw-editor.html +1 -1
  31. package/dist/client/export-document.html +2 -2
  32. package/dist/client/index.html +2 -2
  33. package/package.json +4 -1
  34. package/src/client/app/main-entry.js +2 -0
  35. package/src/client/application/app-shell/git-feature.js +28 -36
  36. package/src/client/application/app-shell/presence-feature.js +3 -1
  37. package/src/client/application/diagram-preview-hydrator.js +24 -15
  38. package/src/client/application/mermaid-preview-hydrator.js +121 -4
  39. package/src/client/application/plantuml-preview-hydrator.js +6 -16
  40. package/src/client/application/preview-renderer.js +11 -2
  41. package/src/client/bootstrap/collabmd-app-shell.js +176 -50
  42. package/src/client/domain/excalidraw-document-switch.js +3 -0
  43. package/src/client/excalidraw-editor.js +187 -84
  44. package/src/client/infrastructure/auth-client.js +4 -4
  45. package/src/client/infrastructure/backlinks-api-client.js +18 -0
  46. package/src/client/infrastructure/comment-thread-store.js +4 -0
  47. package/src/client/infrastructure/editor-session.js +2 -0
  48. package/src/client/infrastructure/git-api-client.js +134 -0
  49. package/src/client/infrastructure/plantuml-api-client.js +21 -0
  50. package/src/client/infrastructure/vault-api-client.js +67 -0
  51. package/src/client/presentation/backlinks-panel.js +6 -9
  52. package/src/client/presentation/bases-preview-controller.js +26 -7
  53. package/src/client/presentation/excalidraw-embed-controller.js +251 -15
  54. package/src/client/presentation/excalidraw-embed-reconciler.js +0 -1
  55. package/src/client/presentation/file-action-controller.js +97 -0
  56. package/src/client/presentation/file-explorer-controller.js +2 -0
  57. package/src/client/presentation/file-explorer-view.js +368 -0
  58. package/src/client/presentation/file-history-view-controller.js +41 -40
  59. package/src/client/presentation/git-diff-view-controller.js +70 -53
  60. package/src/client/presentation/git-panel-controller.js +12 -30
  61. package/src/client/styles/export-document.css +45 -2
  62. package/src/client/styles/features/auth-gate.css +13 -24
  63. package/src/client/styles/features/comment-card.css +6 -0
  64. package/src/client/styles/features/comments-drawer.css +38 -18
  65. package/src/client/styles/features/diagram-preview.css +33 -0
  66. package/src/client/styles/features/embedded-preview.css +37 -11
  67. package/src/client/styles/features/preview-markdown.css +103 -28
  68. package/src/client/styles/foundation/themes.css +4 -0
  69. package/src/client/styles/foundation/tokens.css +4 -3
  70. package/src/client/styles/layout/sidebar.css +72 -0
  71. package/src/server/auth/auth-common.js +224 -0
  72. package/src/server/auth/auth-constants.js +30 -0
  73. package/src/server/auth/auth-strategies.js +320 -0
  74. package/src/server/auth/create-auth-service.js +24 -545
  75. package/src/server/domain/bases/base-definition.js +255 -0
  76. package/src/server/domain/bases/base-expression-runtime.js +1159 -0
  77. package/src/server/domain/bases/base-index-snapshot-store.js +418 -0
  78. package/src/server/domain/bases/base-query-results.js +205 -0
  79. package/src/server/domain/bases/base-query-service.js +68 -1965
  80. package/src/server/domain/collaboration/collaboration-room.js +36 -1
  81. package/src/server/domain/collaboration/room-client-state-store.js +1 -0
  82. package/src/server/domain/collaboration/room-persistence-controller.js +1 -1
  83. package/src/server/infrastructure/http/create-vault-api-query-handler.js +109 -1
  84. package/src/server/infrastructure/http/http-response.js +56 -0
  85. package/src/server/infrastructure/persistence/vault-file-store.js +110 -0
  86. package/dist/client/assets/drawioEditor-DGpo2hcx.js +0 -2
  87. package/dist/client/assets/embedded-editor-base-DgmRcsR8.css +0 -1
  88. package/dist/client/assets/exportDocument-DmV7Gngb.css +0 -1
  89. package/dist/client/assets/index-D69HOZHr.css +0 -1
  90. package/dist/client/assets/main-DSxNTtD-.js +0 -1243
  91. package/dist/client/assets/vault-api-client-BzHQseMN.js +0 -1
  92. package/dist/client/assets/vault-api-client-De7kMvrE.css +0 -1
  93. /package/dist/client/assets/{exportDocument-CtZKWE2c.js → exportDocument-Bia2hI25.js} +0 -0
@@ -0,0 +1,255 @@
1
+ import yaml from 'js-yaml';
2
+
3
+ const SUPPORTED_VIEW_TYPES = new Set(['cards', 'list', 'table']);
4
+
5
+ function isPlainObject(value) {
6
+ return Object.prototype.toString.call(value) === '[object Object]';
7
+ }
8
+
9
+ function capitalize(value = '') {
10
+ const normalized = String(value ?? '').trim();
11
+ if (!normalized) {
12
+ return '';
13
+ }
14
+
15
+ return `${normalized.charAt(0).toUpperCase()}${normalized.slice(1)}`;
16
+ }
17
+
18
+ function normalizeBaseView(rawView, index) {
19
+ const view = isPlainObject(rawView) ? rawView : {};
20
+ const type = typeof view.type === 'string' ? view.type : 'table';
21
+ const name = typeof view.name === 'string' && view.name.trim()
22
+ ? view.name.trim()
23
+ : `${capitalize(type)} ${index + 1}`;
24
+ return {
25
+ extra: Object.entries(view).reduce((acc, [key, value]) => {
26
+ if ([
27
+ 'filters',
28
+ 'groupBy',
29
+ 'group_by',
30
+ 'image',
31
+ 'limit',
32
+ 'name',
33
+ 'order',
34
+ 'properties',
35
+ 'sort',
36
+ 'sorts',
37
+ 'summaries',
38
+ 'type',
39
+ ].includes(key)) {
40
+ return acc;
41
+ }
42
+ acc[key] = value;
43
+ return acc;
44
+ }, {}),
45
+ filters: view.filters ?? null,
46
+ groupBy: typeof view.groupBy === 'string'
47
+ ? view.groupBy
48
+ : (typeof view.group_by === 'string' ? view.group_by : null),
49
+ id: `view-${index}`,
50
+ image: typeof view.image === 'string' ? view.image : null,
51
+ limit: Number.isFinite(Number(view.limit)) ? Math.max(0, Number(view.limit)) : null,
52
+ name,
53
+ order: normalizeViewOrder(view.order ?? view.properties),
54
+ sort: normalizeViewSort(view.sort ?? view.sorts),
55
+ summaries: normalizeSummaries(view.summaries),
56
+ supported: SUPPORTED_VIEW_TYPES.has(type),
57
+ type,
58
+ };
59
+ }
60
+
61
+ function normalizeViewOrder(value) {
62
+ if (Array.isArray(value)) {
63
+ return value
64
+ .map((entry) => {
65
+ if (typeof entry === 'string') {
66
+ return entry;
67
+ }
68
+ if (isPlainObject(entry)) {
69
+ return entry.id ?? entry.property ?? entry.name ?? null;
70
+ }
71
+ return null;
72
+ })
73
+ .filter(Boolean);
74
+ }
75
+
76
+ if (typeof value === 'string' && value.trim()) {
77
+ return [value.trim()];
78
+ }
79
+
80
+ return [];
81
+ }
82
+
83
+ function normalizeViewSort(value) {
84
+ if (typeof value === 'string' && value.trim()) {
85
+ return [{ direction: 'asc', property: value.trim() }];
86
+ }
87
+
88
+ if (!Array.isArray(value)) {
89
+ return [];
90
+ }
91
+
92
+ return value
93
+ .map((entry) => {
94
+ if (typeof entry === 'string') {
95
+ return { direction: 'asc', property: entry };
96
+ }
97
+ if (!isPlainObject(entry)) {
98
+ return null;
99
+ }
100
+
101
+ const property = entry.property ?? entry.id ?? entry.name ?? null;
102
+ if (typeof property !== 'string' || !property.trim()) {
103
+ return null;
104
+ }
105
+
106
+ const direction = String(entry.direction ?? entry.order ?? 'asc').toLowerCase() === 'desc'
107
+ ? 'desc'
108
+ : 'asc';
109
+ return { direction, property: property.trim() };
110
+ })
111
+ .filter(Boolean);
112
+ }
113
+
114
+ function normalizeSummaries(value) {
115
+ if (!value) {
116
+ return [];
117
+ }
118
+
119
+ if (Array.isArray(value)) {
120
+ return value
121
+ .map((entry, index) => normalizeSummary(entry, index))
122
+ .filter(Boolean);
123
+ }
124
+
125
+ if (isPlainObject(value)) {
126
+ const entries = [];
127
+ Object.entries(value).forEach(([property, propertySummaries]) => {
128
+ if (Array.isArray(propertySummaries)) {
129
+ propertySummaries.forEach((entry, index) => {
130
+ const normalized = normalizeSummary(entry, index, property);
131
+ if (normalized) {
132
+ entries.push(normalized);
133
+ }
134
+ });
135
+ return;
136
+ }
137
+
138
+ const normalized = normalizeSummary(propertySummaries, entries.length, property);
139
+ if (normalized) {
140
+ entries.push(normalized);
141
+ }
142
+ });
143
+ return entries;
144
+ }
145
+
146
+ return [];
147
+ }
148
+
149
+ function normalizeSummary(entry, index, property = null) {
150
+ if (typeof entry === 'string') {
151
+ return {
152
+ id: `summary-${index}`,
153
+ label: capitalize(entry),
154
+ property,
155
+ type: entry.toLowerCase(),
156
+ };
157
+ }
158
+
159
+ if (!isPlainObject(entry)) {
160
+ return null;
161
+ }
162
+
163
+ const summaryProperty = typeof (entry.property ?? property) === 'string'
164
+ ? String(entry.property ?? property).trim()
165
+ : null;
166
+ const formula = typeof entry.formula === 'string' ? entry.formula : null;
167
+ const type = typeof entry.type === 'string' ? entry.type.toLowerCase() : (formula ? 'custom' : null);
168
+ if (!summaryProperty) {
169
+ return null;
170
+ }
171
+
172
+ return {
173
+ formula,
174
+ id: `summary-${index}`,
175
+ label: typeof entry.name === 'string' ? entry.name : capitalize(type || 'Summary'),
176
+ property: summaryProperty,
177
+ type,
178
+ };
179
+ }
180
+
181
+ function resolvePropertyLabel(propertyId, definition) {
182
+ const config = definition.properties[propertyId];
183
+ if (config?.displayName) {
184
+ return config.displayName;
185
+ }
186
+ return propertyId.startsWith('file.')
187
+ ? propertyId.slice(5)
188
+ : propertyId.replace(/^note\./u, '');
189
+ }
190
+
191
+ export function normalizeBaseDefinition(source = '') {
192
+ const raw = yaml.load(String(source ?? '')) ?? {};
193
+ const rawObject = isPlainObject(raw) ? raw : {};
194
+ const rawProperties = isPlainObject(rawObject.properties) ? rawObject.properties : {};
195
+ const properties = Object.entries(rawProperties).reduce((acc, [id, config]) => {
196
+ const normalizedConfig = isPlainObject(config) ? { ...config } : {};
197
+ acc[id] = {
198
+ displayName: typeof normalizedConfig.displayName === 'string' ? normalizedConfig.displayName : null,
199
+ formula: typeof normalizedConfig.formula === 'string' ? normalizedConfig.formula : null,
200
+ id,
201
+ raw: normalizedConfig,
202
+ };
203
+ return acc;
204
+ }, {});
205
+
206
+ const rawViews = Array.isArray(rawObject.views) ? rawObject.views : [];
207
+ const views = rawViews.map((rawView, index) => normalizeBaseView(rawView, index));
208
+ if (views.length === 0) {
209
+ views.push(normalizeBaseView({ name: 'Table', type: 'table' }, 0));
210
+ }
211
+
212
+ return {
213
+ filters: rawObject.filters ?? null,
214
+ properties,
215
+ raw: rawObject,
216
+ views,
217
+ };
218
+ }
219
+
220
+ export function buildColumns(definition, view) {
221
+ const order = view.order.length > 0
222
+ ? view.order
223
+ : ['file.name', ...Object.keys(definition.properties)];
224
+ return order.map((propertyId) => ({
225
+ id: propertyId,
226
+ label: resolvePropertyLabel(propertyId, definition),
227
+ }));
228
+ }
229
+
230
+ export function collectEvaluatedPropertyIds(columns, view) {
231
+ const propertyIds = new Set(columns.map((column) => column.id));
232
+
233
+ if (view.groupBy) {
234
+ propertyIds.add(view.groupBy);
235
+ }
236
+
237
+ view.sort.forEach((sortConfig) => {
238
+ if (sortConfig?.property) {
239
+ propertyIds.add(sortConfig.property);
240
+ }
241
+ });
242
+
243
+ view.summaries.forEach((summary) => {
244
+ if (summary?.property) {
245
+ propertyIds.add(summary.property);
246
+ }
247
+ });
248
+
249
+ return [...propertyIds];
250
+ }
251
+
252
+ export function serializeBaseDefinition(definition) {
253
+ const raw = definition?.raw ?? definition ?? {};
254
+ return `${yaml.dump(raw, { lineWidth: -1, noRefs: true }).trim()}\n`;
255
+ }