@lemoncat7/dsh-knowledge 2.3.0 → 2.3.1
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/README.md +11 -4
- package/docs/architecture.md +1 -1
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +93 -0
- package/lib/api.js.map +1 -1
- package/lib/client.js +1 -1
- package/lib/client.js.map +1 -1
- package/lib/extraction.js +9 -2
- package/lib/extraction.js.map +1 -1
- package/lib/notes/domain.d.ts +8 -0
- package/lib/notes/domain.d.ts.map +1 -1
- package/lib/notes/domain.js.map +1 -1
- package/lib/notes/share-import.d.ts +36 -0
- package/lib/notes/share-import.d.ts.map +1 -0
- package/lib/notes/share-import.js +325 -0
- package/lib/notes/share-import.js.map +1 -0
- package/lib/notes/share-page.d.ts +12 -0
- package/lib/notes/share-page.d.ts.map +1 -0
- package/lib/notes/share-page.js +81 -0
- package/lib/notes/share-page.js.map +1 -0
- package/lib/notes/store.d.ts +15 -1
- package/lib/notes/store.d.ts.map +1 -1
- package/lib/notes/store.js +177 -6
- package/lib/notes/store.js.map +1 -1
- package/lib/web-note-editor-selection.d.ts.map +1 -1
- package/lib/web-note-editor-selection.js +23 -0
- package/lib/web-note-editor-selection.js.map +1 -1
- package/lib/web.d.ts.map +1 -1
- package/lib/web.js +7 -6
- package/lib/web.js.map +1 -1
- package/package.json +1 -1
- package/web/app.js +303 -29
- package/web/index.html +1 -2
- package/web/note-editor.js +64 -64
- package/web/styles.css +168 -291
- package/lib/web-workspace-effects.d.ts +0 -13
- package/lib/web-workspace-effects.d.ts.map +0 -1
- package/lib/web-workspace-effects.js +0 -366
- package/lib/web-workspace-effects.js.map +0 -1
- package/web/workspace-effects.js +0 -16
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { lookup } from 'node:dns/promises';
|
|
3
|
+
import { request as requestHttp } from 'node:http';
|
|
4
|
+
import { request as requestHttps } from 'node:https';
|
|
5
|
+
import { isIP } from 'node:net';
|
|
6
|
+
const SHARE_TOKEN_PATTERN = /^share_[A-Za-z0-9_-]{32}$/;
|
|
7
|
+
const MAX_MANIFEST_BYTES = 2 * 1024 * 1024;
|
|
8
|
+
const MAX_IMPORT_FILE_BYTES = 64 * 1024 * 1024;
|
|
9
|
+
const MAX_IMPORT_TOTAL_BYTES = 256 * 1024 * 1024;
|
|
10
|
+
const MAX_IMPORT_NODES = 500;
|
|
11
|
+
const REQUEST_TIMEOUT_MS = 20_000;
|
|
12
|
+
export function createNoteShareManifest(share, nodes, truncated) {
|
|
13
|
+
const paths = relativePaths(share.node, nodes);
|
|
14
|
+
const manifestNodes = nodes.map(node => ({
|
|
15
|
+
id: node.id,
|
|
16
|
+
path: paths.get(node.id) ?? node.name,
|
|
17
|
+
kind: node.kind,
|
|
18
|
+
mediaType: node.mediaType,
|
|
19
|
+
size: node.size,
|
|
20
|
+
sha256: node.sha256,
|
|
21
|
+
}));
|
|
22
|
+
const files = manifestNodes.filter(node => node.kind !== 'folder');
|
|
23
|
+
return {
|
|
24
|
+
version: 1,
|
|
25
|
+
share: {
|
|
26
|
+
name: share.node.name,
|
|
27
|
+
kind: share.node.kind,
|
|
28
|
+
updatedAt: share.node.updatedAt,
|
|
29
|
+
nodeCount: manifestNodes.length,
|
|
30
|
+
fileCount: files.length,
|
|
31
|
+
totalSize: files.reduce((total, node) => total + node.size, 0),
|
|
32
|
+
},
|
|
33
|
+
nodes: manifestNodes,
|
|
34
|
+
truncated,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export async function inspectNoteShareUrl(rawUrl, store) {
|
|
38
|
+
const url = canonicalShareUrl(rawUrl);
|
|
39
|
+
const localShare = store?.getShareByToken(shareToken(url));
|
|
40
|
+
if (localShare !== undefined) {
|
|
41
|
+
const localNodes = localShare.node.kind === 'folder' ? store.listSharedSubtree(localShare.noteId, 501) : [localShare.node];
|
|
42
|
+
const truncated = localNodes.length > 500;
|
|
43
|
+
return { url: url.href, manifest: createNoteShareManifest(localShare, localNodes.slice(0, 500), truncated) };
|
|
44
|
+
}
|
|
45
|
+
const payload = await requestPublicUrl(new URL(`${url.href}/manifest`), MAX_MANIFEST_BYTES);
|
|
46
|
+
return { url: url.href, manifest: validateManifest(JSON.parse(payload.toString('utf8'))) };
|
|
47
|
+
}
|
|
48
|
+
export async function importNoteShare(store, rawUrl, parentId) {
|
|
49
|
+
const canonical = canonicalShareUrl(rawUrl);
|
|
50
|
+
const localShare = store.getShareByToken(shareToken(canonical));
|
|
51
|
+
if (localShare !== undefined) {
|
|
52
|
+
const nodes = localShare.node.kind === 'folder' ? store.listSharedSubtree(localShare.noteId, MAX_IMPORT_NODES + 1) : [localShare.node];
|
|
53
|
+
if (nodes.length > MAX_IMPORT_NODES)
|
|
54
|
+
throw inputError('分享目录超过 500 项,暂时不能导入');
|
|
55
|
+
const root = await store.copy(localShare.noteId, parentId);
|
|
56
|
+
const files = nodes.filter(node => node.kind !== 'folder');
|
|
57
|
+
return {
|
|
58
|
+
root,
|
|
59
|
+
importedNodes: nodes.length,
|
|
60
|
+
importedFiles: files.length,
|
|
61
|
+
totalBytes: files.reduce((total, node) => total + node.size, 0),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const { url, manifest } = await inspectNoteShareUrl(canonical.href);
|
|
65
|
+
if (manifest.truncated)
|
|
66
|
+
throw inputError('分享目录超过 500 项,暂时不能导入');
|
|
67
|
+
if (manifest.nodes.length === 0)
|
|
68
|
+
throw inputError('分享中没有可导入的内容');
|
|
69
|
+
const rootManifest = manifest.nodes.find(node => node.path === manifest.share.name);
|
|
70
|
+
if (rootManifest === undefined || rootManifest.kind !== manifest.share.kind)
|
|
71
|
+
throw inputError('分享清单缺少有效的根项目');
|
|
72
|
+
const createdByPath = new Map();
|
|
73
|
+
let root;
|
|
74
|
+
let importedFiles = 0;
|
|
75
|
+
let totalBytes = 0;
|
|
76
|
+
try {
|
|
77
|
+
const ordered = [...manifest.nodes].sort((left, right) => {
|
|
78
|
+
const depth = pathDepth(left.path) - pathDepth(right.path);
|
|
79
|
+
if (depth !== 0)
|
|
80
|
+
return depth;
|
|
81
|
+
if (left.kind === 'folder' && right.kind !== 'folder')
|
|
82
|
+
return -1;
|
|
83
|
+
if (left.kind !== 'folder' && right.kind === 'folder')
|
|
84
|
+
return 1;
|
|
85
|
+
return left.path.localeCompare(right.path, 'zh-CN');
|
|
86
|
+
});
|
|
87
|
+
for (const item of ordered) {
|
|
88
|
+
const name = pathName(item.path);
|
|
89
|
+
const parentPath = pathParent(item.path);
|
|
90
|
+
const destinationParentId = parentPath === null ? parentId : createdByPath.get(parentPath)?.id;
|
|
91
|
+
if (parentPath !== null && destinationParentId === undefined)
|
|
92
|
+
throw inputError(`分享清单中的父目录不存在:${parentPath}`);
|
|
93
|
+
let created;
|
|
94
|
+
if (item.kind === 'folder') {
|
|
95
|
+
created = await store.createFolder(name, destinationParentId ?? null);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
const content = await requestPublicUrl(contentUrl(url, item.id), MAX_IMPORT_FILE_BYTES);
|
|
99
|
+
if (content.byteLength !== item.size)
|
|
100
|
+
throw inputError(`分享文件大小校验失败:${item.path}`);
|
|
101
|
+
if (item.sha256 !== null && createHash('sha256').update(content).digest('hex') !== item.sha256) {
|
|
102
|
+
throw inputError(`分享文件完整性校验失败:${item.path}`);
|
|
103
|
+
}
|
|
104
|
+
totalBytes += content.byteLength;
|
|
105
|
+
if (totalBytes > MAX_IMPORT_TOTAL_BYTES)
|
|
106
|
+
throw inputError('分享内容超过 256 MiB 导入上限');
|
|
107
|
+
created = item.kind === 'document'
|
|
108
|
+
? await store.createDocument(name, destinationParentId ?? null, content.toString('utf8'))
|
|
109
|
+
: await store.upload({ name, parentId: destinationParentId ?? null, mediaType: item.mediaType ?? 'application/octet-stream', content });
|
|
110
|
+
importedFiles += 1;
|
|
111
|
+
}
|
|
112
|
+
createdByPath.set(item.path, created);
|
|
113
|
+
if (item === rootManifest)
|
|
114
|
+
root = created;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
if (root !== undefined)
|
|
119
|
+
await store.delete(root.id).catch(() => { });
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
if (root === undefined)
|
|
123
|
+
throw inputError('分享内容导入失败');
|
|
124
|
+
return { root, importedNodes: createdByPath.size, importedFiles, totalBytes };
|
|
125
|
+
}
|
|
126
|
+
function canonicalShareUrl(raw) {
|
|
127
|
+
let url;
|
|
128
|
+
try {
|
|
129
|
+
url = new URL(raw.trim());
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
throw inputError('请输入完整的 HTTP 或 HTTPS 分享链接');
|
|
133
|
+
}
|
|
134
|
+
if (url.protocol !== 'https:' && url.protocol !== 'http:')
|
|
135
|
+
throw inputError('分享链接只支持 HTTP 或 HTTPS');
|
|
136
|
+
if (url.username || url.password)
|
|
137
|
+
throw inputError('分享链接不能包含用户名或密码');
|
|
138
|
+
const match = url.pathname.match(/^(.*\/shared\/(share_[A-Za-z0-9_-]{32}))(?:\/)?$/);
|
|
139
|
+
if (match?.[1] === undefined || !SHARE_TOKEN_PATTERN.test(match[2] ?? ''))
|
|
140
|
+
throw inputError('这不是有效的 DSH 笔记分享链接');
|
|
141
|
+
url.pathname = match[1];
|
|
142
|
+
url.search = '';
|
|
143
|
+
url.hash = '';
|
|
144
|
+
return url;
|
|
145
|
+
}
|
|
146
|
+
function contentUrl(base, noteId) {
|
|
147
|
+
const url = new URL(`${base}/content`);
|
|
148
|
+
url.searchParams.set('noteId', noteId);
|
|
149
|
+
return url;
|
|
150
|
+
}
|
|
151
|
+
function shareToken(url) { return url.pathname.slice(url.pathname.lastIndexOf('/') + 1); }
|
|
152
|
+
async function requestPublicUrl(url, maximumBytes, redirects = 0) {
|
|
153
|
+
if (redirects > 3)
|
|
154
|
+
throw upstreamError('分享服务重定向次数过多');
|
|
155
|
+
const target = await resolvePublicTarget(url);
|
|
156
|
+
const request = url.protocol === 'https:' ? requestHttps : requestHttp;
|
|
157
|
+
return await new Promise((resolve, reject) => {
|
|
158
|
+
const req = request(url, {
|
|
159
|
+
headers: { accept: 'application/json, application/octet-stream;q=0.9', 'user-agent': 'dsh-knowledge-share-import/1' },
|
|
160
|
+
lookup: (_hostname, _options, callback) => callback(null, target.address, target.family),
|
|
161
|
+
}, response => {
|
|
162
|
+
const status = response.statusCode ?? 502;
|
|
163
|
+
if ([301, 302, 303, 307, 308].includes(status)) {
|
|
164
|
+
response.resume();
|
|
165
|
+
const location = response.headers.location;
|
|
166
|
+
if (!location)
|
|
167
|
+
return reject(upstreamError('分享服务返回了无效重定向'));
|
|
168
|
+
let redirected;
|
|
169
|
+
try {
|
|
170
|
+
redirected = new URL(location, url);
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return reject(upstreamError('分享服务返回了无效重定向'));
|
|
174
|
+
}
|
|
175
|
+
requestPublicUrl(redirected, maximumBytes, redirects + 1).then(resolve, reject);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (status < 200 || status >= 300) {
|
|
179
|
+
response.resume();
|
|
180
|
+
reject(upstreamError(status === 404 ? '分享不存在或已经停止' : `分享服务返回 HTTP ${status}`));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const declared = Number(response.headers['content-length'] ?? 0);
|
|
184
|
+
if (Number.isFinite(declared) && declared > maximumBytes) {
|
|
185
|
+
response.destroy();
|
|
186
|
+
reject(inputError('分享内容超过导入限制'));
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const chunks = [];
|
|
190
|
+
let size = 0;
|
|
191
|
+
response.on('data', chunk => {
|
|
192
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
193
|
+
size += buffer.byteLength;
|
|
194
|
+
if (size > maximumBytes) {
|
|
195
|
+
response.destroy(inputError('分享内容超过导入限制'));
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
chunks.push(buffer);
|
|
199
|
+
});
|
|
200
|
+
response.on('end', () => resolve(Buffer.concat(chunks)));
|
|
201
|
+
response.on('error', reject);
|
|
202
|
+
});
|
|
203
|
+
req.setTimeout(REQUEST_TIMEOUT_MS, () => req.destroy(upstreamError('读取分享超时,请稍后重试')));
|
|
204
|
+
req.on('error', reject);
|
|
205
|
+
req.end();
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
async function resolvePublicTarget(url) {
|
|
209
|
+
if (url.protocol !== 'https:' && url.protocol !== 'http:')
|
|
210
|
+
throw inputError('分享链接只支持 HTTP 或 HTTPS');
|
|
211
|
+
const hostname = url.hostname.toLocaleLowerCase();
|
|
212
|
+
if (hostname === 'localhost' || hostname.endsWith('.localhost'))
|
|
213
|
+
throw inputError('分享链接不能指向本机或私有网络');
|
|
214
|
+
const literalFamily = isIP(hostname);
|
|
215
|
+
if (literalFamily !== 0) {
|
|
216
|
+
if (!isPublicAddress(hostname))
|
|
217
|
+
throw inputError('分享链接不能指向本机或私有网络');
|
|
218
|
+
return { address: hostname, family: literalFamily };
|
|
219
|
+
}
|
|
220
|
+
let addresses;
|
|
221
|
+
try {
|
|
222
|
+
addresses = await lookup(hostname, { all: true, verbatim: true });
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
throw upstreamError('无法解析分享链接的主机名');
|
|
226
|
+
}
|
|
227
|
+
const publicAddress = addresses.find(item => isPublicAddress(item.address));
|
|
228
|
+
if (publicAddress === undefined || addresses.some(item => !isPublicAddress(item.address))) {
|
|
229
|
+
throw inputError('分享链接不能解析到本机或私有网络');
|
|
230
|
+
}
|
|
231
|
+
return { address: publicAddress.address, family: publicAddress.family === 6 ? 6 : 4 };
|
|
232
|
+
}
|
|
233
|
+
function isPublicAddress(address) {
|
|
234
|
+
if (address.includes(':')) {
|
|
235
|
+
const normalized = address.toLocaleLowerCase();
|
|
236
|
+
if (normalized === '::' || normalized === '::1' || normalized.startsWith('fc') || normalized.startsWith('fd') || normalized.startsWith('fe8') || normalized.startsWith('fe9') || normalized.startsWith('fea') || normalized.startsWith('feb') || normalized.startsWith('ff') || normalized.startsWith('2001:db8:'))
|
|
237
|
+
return false;
|
|
238
|
+
const mapped = normalized.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/)?.[1];
|
|
239
|
+
return mapped === undefined || isPublicAddress(mapped);
|
|
240
|
+
}
|
|
241
|
+
const octets = address.split('.').map(Number);
|
|
242
|
+
if (octets.length !== 4 || octets.some(value => !Number.isInteger(value) || value < 0 || value > 255))
|
|
243
|
+
return false;
|
|
244
|
+
const [a = 0, b = 0, c = 0] = octets;
|
|
245
|
+
return !(a === 0 || a === 10 || a === 127 || a >= 224
|
|
246
|
+
|| (a === 100 && b >= 64 && b <= 127)
|
|
247
|
+
|| (a === 169 && b === 254)
|
|
248
|
+
|| (a === 172 && b >= 16 && b <= 31)
|
|
249
|
+
|| (a === 192 && (b === 168 || (b === 0 && (c === 0 || c === 2))))
|
|
250
|
+
|| (a === 198 && (b === 18 || b === 19 || (b === 51 && c === 100)))
|
|
251
|
+
|| (a === 203 && b === 0 && c === 113));
|
|
252
|
+
}
|
|
253
|
+
function validateManifest(value) {
|
|
254
|
+
if (!isRecord(value) || value.version !== 1 || !isRecord(value.share) || !Array.isArray(value.nodes))
|
|
255
|
+
throw inputError('分享服务返回的清单格式无效');
|
|
256
|
+
const share = value.share;
|
|
257
|
+
if (typeof share.name !== 'string' || share.name.length === 0 || share.name.length > 255)
|
|
258
|
+
throw inputError('分享名称无效');
|
|
259
|
+
if (!isNoteKind(share.kind) || typeof share.updatedAt !== 'string')
|
|
260
|
+
throw inputError('分享信息无效');
|
|
261
|
+
if (value.nodes.length > MAX_IMPORT_NODES)
|
|
262
|
+
throw inputError('分享目录超过 500 项,暂时不能导入');
|
|
263
|
+
const paths = new Set();
|
|
264
|
+
let totalSize = 0;
|
|
265
|
+
const nodes = value.nodes.map((item, index) => {
|
|
266
|
+
if (!isRecord(item) || typeof item.id !== 'string' || !/^note_[a-f0-9]{32}$/.test(item.id))
|
|
267
|
+
throw inputError(`分享清单第 ${index + 1} 项编号无效`);
|
|
268
|
+
if (typeof item.path !== 'string' || !validRelativePath(item.path))
|
|
269
|
+
throw inputError(`分享清单第 ${index + 1} 项路径无效`);
|
|
270
|
+
if (paths.has(item.path))
|
|
271
|
+
throw inputError(`分享清单存在重复路径:${item.path}`);
|
|
272
|
+
paths.add(item.path);
|
|
273
|
+
if (!isNoteKind(item.kind) || (item.mediaType !== null && typeof item.mediaType !== 'string'))
|
|
274
|
+
throw inputError(`分享清单第 ${index + 1} 项类型无效`);
|
|
275
|
+
const size = item.size;
|
|
276
|
+
if (typeof size !== 'number' || !Number.isSafeInteger(size) || size < 0 || size > MAX_IMPORT_FILE_BYTES)
|
|
277
|
+
throw inputError(`分享清单第 ${index + 1} 项大小无效`);
|
|
278
|
+
if (item.sha256 !== null && (typeof item.sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(item.sha256)))
|
|
279
|
+
throw inputError(`分享清单第 ${index + 1} 项摘要无效`);
|
|
280
|
+
if (item.kind !== 'folder')
|
|
281
|
+
totalSize += size;
|
|
282
|
+
return { id: item.id, path: item.path, kind: item.kind, mediaType: item.mediaType, size, sha256: item.sha256 };
|
|
283
|
+
});
|
|
284
|
+
if (totalSize > MAX_IMPORT_TOTAL_BYTES)
|
|
285
|
+
throw inputError('分享内容超过 256 MiB 导入上限');
|
|
286
|
+
if (share.nodeCount !== nodes.length || share.fileCount !== nodes.filter(node => node.kind !== 'folder').length || share.totalSize !== totalSize)
|
|
287
|
+
throw inputError('分享清单统计信息不一致');
|
|
288
|
+
return { version: 1, share: { name: share.name, kind: share.kind, updatedAt: share.updatedAt, nodeCount: share.nodeCount, fileCount: share.fileCount, totalSize: share.totalSize }, nodes, truncated: value.truncated === true };
|
|
289
|
+
}
|
|
290
|
+
function relativePaths(root, nodes) {
|
|
291
|
+
const byId = new Map(nodes.map(node => [node.id, node]));
|
|
292
|
+
const paths = new Map([[root.id, root.name]]);
|
|
293
|
+
const resolve = (node, seen = new Set()) => {
|
|
294
|
+
const cached = paths.get(node.id);
|
|
295
|
+
if (cached !== undefined)
|
|
296
|
+
return cached;
|
|
297
|
+
if (seen.has(node.id) || node.parentId === null)
|
|
298
|
+
return node.name;
|
|
299
|
+
seen.add(node.id);
|
|
300
|
+
const parent = byId.get(node.parentId);
|
|
301
|
+
const value = parent === undefined ? node.name : `${resolve(parent, seen)}/${node.name}`;
|
|
302
|
+
paths.set(node.id, value);
|
|
303
|
+
return value;
|
|
304
|
+
};
|
|
305
|
+
for (const node of nodes)
|
|
306
|
+
resolve(node);
|
|
307
|
+
return paths;
|
|
308
|
+
}
|
|
309
|
+
function validRelativePath(value) {
|
|
310
|
+
if (value.length === 0 || value.length > 4096 || value.startsWith('/') || value.includes('\\') || value.includes('\0'))
|
|
311
|
+
return false;
|
|
312
|
+
const parts = value.split('/');
|
|
313
|
+
return parts.every(part => part.length > 0 && part.length <= 255 && part !== '.' && part !== '..');
|
|
314
|
+
}
|
|
315
|
+
function pathDepth(value) { return value.split('/').length; }
|
|
316
|
+
function pathName(value) { return value.slice(value.lastIndexOf('/') + 1); }
|
|
317
|
+
function pathParent(value) {
|
|
318
|
+
const index = value.lastIndexOf('/');
|
|
319
|
+
return index < 0 ? null : value.slice(0, index);
|
|
320
|
+
}
|
|
321
|
+
function isNoteKind(value) { return value === 'folder' || value === 'document' || value === 'file'; }
|
|
322
|
+
function isRecord(value) { return value !== null && typeof value === 'object' && !Array.isArray(value); }
|
|
323
|
+
function inputError(message) { return Object.assign(new Error(message), { status: 400, code: 'BAD_REQUEST' }); }
|
|
324
|
+
function upstreamError(message) { return Object.assign(new Error(message), { status: 502, code: 'UPSTREAM_ERROR' }); }
|
|
325
|
+
//# sourceMappingURL=share-import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"share-import.js","sourceRoot":"","sources":["../../src/notes/share-import.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { NoteNode, NoteShare } from './domain.js';
|
|
2
|
+
export interface NoteSharePageInput {
|
|
3
|
+
apiPrefix: string;
|
|
4
|
+
share: NoteShare;
|
|
5
|
+
nodes: NoteNode[];
|
|
6
|
+
selectedNode?: NoteNode;
|
|
7
|
+
selectedText?: string;
|
|
8
|
+
contentTruncated?: boolean;
|
|
9
|
+
listTruncated?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function renderNoteSharePage(input: NoteSharePageInput): string;
|
|
12
|
+
//# sourceMappingURL=share-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"share-page.d.ts","sourceRoot":"","sources":["../../src/notes/share-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAEtD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,SAAS,CAAA;IAChB,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,YAAY,CAAC,EAAE,QAAQ,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAsBrE"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export function renderNoteSharePage(input) {
|
|
2
|
+
const { share, nodes } = input;
|
|
3
|
+
const baseHref = `${input.apiPrefix.replace(/\/$/, '')}/shared/${encodeURIComponent(share.token)}`;
|
|
4
|
+
const paths = relativePaths(share.node, nodes);
|
|
5
|
+
const items = nodes
|
|
6
|
+
.filter(node => node.id !== share.noteId)
|
|
7
|
+
.sort((left, right) => (paths.get(left.id) ?? left.name).localeCompare(paths.get(right.id) ?? right.name, 'zh-CN'));
|
|
8
|
+
const selected = input.selectedNode;
|
|
9
|
+
const selectedPath = selected === undefined ? '' : paths.get(selected.id) ?? selected.name;
|
|
10
|
+
const title = share.node.name;
|
|
11
|
+
return `<!doctype html>
|
|
12
|
+
<html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
13
|
+
<meta name="color-scheme" content="light dark"><meta name="referrer" content="no-referrer"><title>${escapeHtml(title)} · 分享笔记</title>
|
|
14
|
+
<style>${SHARE_PAGE_CSS}</style></head><body>
|
|
15
|
+
<main class="share-shell">
|
|
16
|
+
<header class="share-header"><div><span class="eyebrow">DSH KNOWLEDGE</span><h1>${escapeHtml(title)}</h1><p>${share.node.kind === 'folder' ? `共享目录 · ${Math.max(0, nodes.length - 1)} 个项目` : '共享笔记文档 · 只读'}</p></div><span class="readonly">只读分享</span></header>
|
|
17
|
+
<div class="share-workspace${share.node.kind === 'folder' ? '' : ' is-single'}">
|
|
18
|
+
${share.node.kind === 'folder' ? `<nav class="share-tree" aria-label="共享目录"><a class="tree-root" href="${escapeAttribute(baseHref)}">${escapeHtml(share.node.name)}</a>${items.map(node => renderTreeItem(node, paths.get(node.id) ?? node.name, baseHref, selected?.id === node.id)).join('')}${input.listTruncated ? '<p class="notice">目录内容较多,仅展示前 500 项。</p>' : ''}</nav>` : ''}
|
|
19
|
+
<section class="share-content">${renderSharedContent(selected ?? share.node, selectedPath || share.node.name, input.selectedText, input.contentTruncated, baseHref)}</section>
|
|
20
|
+
</div>
|
|
21
|
+
<footer class="share-footer"><span>分享于 ${formatDate(share.createdAt)}</span><span>内容会随原笔记更新</span></footer>
|
|
22
|
+
</main></body></html>`;
|
|
23
|
+
}
|
|
24
|
+
function renderTreeItem(node, path, baseHref, active) {
|
|
25
|
+
const depth = Math.max(0, path.split('/').length - 2);
|
|
26
|
+
if (node.kind === 'folder') {
|
|
27
|
+
return `<div class="tree-item is-folder" style="--depth:${depth}"><span class="tree-icon" aria-hidden="true"></span><span>${escapeHtml(node.name)}</span></div>`;
|
|
28
|
+
}
|
|
29
|
+
const href = `${baseHref}?note=${encodeURIComponent(node.id)}`;
|
|
30
|
+
return `<a class="tree-item is-file${active ? ' is-active' : ''}" style="--depth:${depth}" href="${escapeAttribute(href)}"${active ? ' aria-current="page"' : ''}><span class="file-icon" aria-hidden="true"></span><span>${escapeHtml(node.name)}</span></a>`;
|
|
31
|
+
}
|
|
32
|
+
function renderSharedContent(node, path, text, truncated, baseHref) {
|
|
33
|
+
if (node.kind === 'folder') {
|
|
34
|
+
return '<div class="empty"><span class="empty-mark" aria-hidden="true"></span><h2>选择一篇文档</h2><p>从左侧共享目录中选择要阅读的内容。</p></div>';
|
|
35
|
+
}
|
|
36
|
+
const download = `${baseHref}/content?noteId=${encodeURIComponent(node.id)}&download=1`;
|
|
37
|
+
const heading = `<header class="content-header"><div><span>${escapeHtml(path)}</span><h2>${escapeHtml(node.name)}</h2></div><a class="download" href="${escapeAttribute(download)}">下载</a></header>`;
|
|
38
|
+
if (node.mediaType?.startsWith('image/')) {
|
|
39
|
+
const source = `${baseHref}/content?noteId=${encodeURIComponent(node.id)}`;
|
|
40
|
+
return `${heading}<div class="image-stage"><img src="${escapeAttribute(source)}" alt="${escapeAttribute(node.name)}"></div>`;
|
|
41
|
+
}
|
|
42
|
+
if (text !== undefined) {
|
|
43
|
+
return `${heading}${truncated ? '<p class="notice content-notice">文档较长,网页仅显示前 512 KiB;下载可查看完整内容。</p>' : ''}<article class="document"><pre>${escapeHtml(text)}</pre></article>`;
|
|
44
|
+
}
|
|
45
|
+
return `${heading}<div class="empty"><span class="file-large" aria-hidden="true"></span><h2>此格式不支持网页预览</h2><p>可以下载后使用本地应用打开。</p><a class="download primary" href="${escapeAttribute(download)}">下载文件</a></div>`;
|
|
46
|
+
}
|
|
47
|
+
function relativePaths(root, nodes) {
|
|
48
|
+
const byId = new Map(nodes.map(node => [node.id, node]));
|
|
49
|
+
const paths = new Map([[root.id, root.name]]);
|
|
50
|
+
const resolve = (node, seen = new Set()) => {
|
|
51
|
+
const cached = paths.get(node.id);
|
|
52
|
+
if (cached !== undefined)
|
|
53
|
+
return cached;
|
|
54
|
+
if (seen.has(node.id) || node.parentId === null)
|
|
55
|
+
return node.name;
|
|
56
|
+
seen.add(node.id);
|
|
57
|
+
const parent = byId.get(node.parentId);
|
|
58
|
+
const value = parent === undefined ? node.name : `${resolve(parent, seen)}/${node.name}`;
|
|
59
|
+
paths.set(node.id, value);
|
|
60
|
+
return value;
|
|
61
|
+
};
|
|
62
|
+
for (const node of nodes)
|
|
63
|
+
resolve(node);
|
|
64
|
+
return paths;
|
|
65
|
+
}
|
|
66
|
+
function formatDate(value) {
|
|
67
|
+
const date = new Date(value);
|
|
68
|
+
return Number.isNaN(date.getTime()) ? value : new Intl.DateTimeFormat('zh-CN', { dateStyle: 'medium', timeStyle: 'short' }).format(date);
|
|
69
|
+
}
|
|
70
|
+
function escapeHtml(value) {
|
|
71
|
+
return value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", ''');
|
|
72
|
+
}
|
|
73
|
+
function escapeAttribute(value) {
|
|
74
|
+
return escapeHtml(value);
|
|
75
|
+
}
|
|
76
|
+
const SHARE_PAGE_CSS = `
|
|
77
|
+
*{box-sizing:border-box}html{font-family:Inter,"SF Pro Text","PingFang SC","Microsoft YaHei",system-ui,sans-serif;background:#eef0f2;color:#202428}body{min-width:0;min-height:100dvh;margin:0;padding:clamp(12px,3vw,36px);background:radial-gradient(circle at 14% 4%,rgba(255,255,255,.92),transparent 34%),#eef0f2}button,input,select,textarea,a{font:inherit}.share-shell{width:min(1180px,100%);min-height:calc(100dvh - clamp(24px,6vw,72px));margin:0 auto;overflow:hidden;border:1px solid rgba(25,31,36,.13);border-radius:20px;background:rgba(250,251,252,.82);box-shadow:0 18px 58px rgba(24,30,35,.11);backdrop-filter:blur(22px);-webkit-backdrop-filter:blur(22px)}.share-header{min-height:98px;display:flex;align-items:center;justify-content:space-between;gap:24px;border-bottom:1px solid rgba(25,31,36,.1);padding:20px 24px}.eyebrow{display:block;color:#737b82;font:650 10px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.12em}.share-header h1{margin:7px 0 0;font-size:clamp(20px,2.6vw,30px);line-height:1.2;letter-spacing:-.025em}.share-header p{margin:5px 0 0;color:#767e85;font-size:12px}.readonly{flex:none;border:1px solid rgba(25,31,36,.12);border-radius:999px;padding:7px 10px;background:rgba(255,255,255,.62);color:#626a70;font-size:11px}.share-workspace{min-height:calc(100dvh - 220px);display:grid;grid-template-columns:minmax(220px,280px) minmax(0,1fr)}.share-workspace.is-single{grid-template-columns:minmax(0,1fr)}.share-tree{min-width:0;border-right:1px solid rgba(25,31,36,.1);padding:12px 9px;background:rgba(240,242,244,.56)}.tree-root,.tree-item{min-width:0;min-height:38px;display:flex;align-items:center;gap:9px;border:0;border-radius:9px;padding:7px 9px;color:#4d555b;font-size:12px;text-decoration:none}.tree-root{margin-bottom:6px;color:#202428;font-weight:650}.tree-item{padding-left:calc(9px + var(--depth)*14px)}a.tree-item:hover,a.tree-item:focus-visible{background:rgba(255,255,255,.78);color:#202428;outline:none}.tree-item.is-active{background:#fff;color:#202428;box-shadow:inset 2px 0 0 #555e65,0 1px 5px rgba(25,31,36,.08)}.tree-icon,.file-icon{position:relative;width:17px;height:13px;flex:none;border:1px solid #8a9298;border-radius:3px;background:rgba(255,255,255,.58)}.tree-icon:before{position:absolute;top:-4px;left:1px;width:8px;height:4px;border:1px solid #8a9298;border-bottom:0;border-radius:3px 3px 0 0;background:inherit;content:""}.file-icon{width:14px;height:17px}.share-content{min-width:0;display:grid;grid-template-rows:auto minmax(0,1fr);background:rgba(255,255,255,.38)}.content-header{min-height:72px;display:flex;align-items:center;justify-content:space-between;gap:18px;border-bottom:1px solid rgba(25,31,36,.09);padding:14px clamp(16px,3vw,32px)}.content-header span{display:block;max-width:70vw;overflow:hidden;color:#7b8389;font-size:10px;text-overflow:ellipsis;white-space:nowrap}.content-header h2{margin:5px 0 0;font-size:18px;letter-spacing:-.015em}.download{min-height:38px;display:inline-flex;align-items:center;justify-content:center;border:1px solid rgba(25,31,36,.15);border-radius:9px;padding:7px 13px;background:rgba(255,255,255,.72);color:#30363b;font-size:12px;font-weight:620;text-decoration:none}.download:hover,.download:focus-visible{border-color:rgba(25,31,36,.38);background:#fff;outline:2px solid transparent}.download.primary{margin-top:10px;background:#30363b;color:#fff}.document{min-width:0;padding:clamp(24px,5vw,64px)}.document pre{max-width:820px;margin:0 auto;color:#30363b;font:14px/1.78 "SFMono-Regular",Consolas,"Liberation Mono",monospace;white-space:pre-wrap;overflow-wrap:anywhere}.image-stage{min-height:0;display:grid;place-items:center;padding:24px}.image-stage img{max-width:100%;max-height:72dvh;border-radius:12px;box-shadow:0 10px 34px rgba(25,31,36,.12)}.empty{min-height:420px;display:grid;place-content:center;justify-items:center;padding:32px;color:#767e85;text-align:center}.empty h2{margin:14px 0 0;color:#30363b;font-size:17px}.empty p{margin:6px 0 0;font-size:12px}.empty-mark,.file-large{width:54px;height:39px;border:1.5px solid #939ba1;border-radius:7px;background:rgba(255,255,255,.55)}.file-large{width:40px;height:50px}.notice{margin:10px 7px;border-left:2px solid #7e878e;padding:6px 9px;color:#717980;font-size:11px;line-height:1.5}.content-notice{margin:16px clamp(16px,3vw,32px) 0}.share-footer{min-height:48px;display:flex;align-items:center;justify-content:space-between;gap:16px;border-top:1px solid rgba(25,31,36,.1);padding:10px 18px;color:#7a8288;font-size:10px}
|
|
78
|
+
@media(max-width:720px){body{padding:0}.share-shell{min-height:100dvh;border:0;border-radius:0}.share-header{min-height:88px;padding:16px}.readonly{display:none}.share-workspace{min-height:calc(100dvh - 185px);grid-template-columns:1fr;grid-template-rows:auto minmax(0,1fr)}.share-tree{max-height:34dvh;overflow:auto;border-right:0;border-bottom:1px solid rgba(25,31,36,.1)}.content-header{padding-inline:16px}.document{padding:24px 17px 44px}.download{min-height:44px}.share-footer{align-items:flex-start;flex-direction:column;gap:3px;padding:11px 16px}}
|
|
79
|
+
@media(prefers-color-scheme:dark){html{background:#17191b;color:#ebedef}body{background:radial-gradient(circle at 14% 4%,rgba(255,255,255,.055),transparent 34%),#17191b}.share-shell{border-color:rgba(255,255,255,.11);background:rgba(31,34,37,.88);box-shadow:0 18px 58px rgba(0,0,0,.36)}.share-header,.content-header,.share-footer{border-color:rgba(255,255,255,.09)}.eyebrow,.share-header p,.content-header span,.empty,.notice,.share-footer{color:#9ba1a6}.share-header h1,.content-header h2,.empty h2,.tree-root{color:#eef0f2}.readonly,.download{border-color:rgba(255,255,255,.13);background:rgba(255,255,255,.06);color:#d9dcde}.share-tree{border-color:rgba(255,255,255,.09);background:rgba(15,17,18,.25)}.tree-item{color:#b5babd}a.tree-item:hover,a.tree-item:focus-visible,.tree-item.is-active{background:rgba(255,255,255,.08);color:#f1f2f3}.tree-item.is-active{box-shadow:inset 2px 0 0 #b8bec2,0 1px 7px rgba(0,0,0,.2)}.tree-icon,.file-icon,.empty-mark,.file-large{border-color:#777f85;background:rgba(255,255,255,.04)}.share-content{background:rgba(255,255,255,.015)}.document pre{color:#d9dcde}.download:hover,.download:focus-visible{border-color:rgba(255,255,255,.34);background:rgba(255,255,255,.1)}.download.primary{background:#e3e6e8;color:#202326}}
|
|
80
|
+
`;
|
|
81
|
+
//# sourceMappingURL=share-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"share-page.js","sourceRoot":"","sources":["../../src/notes/share-page.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,mBAAmB,CAAC,KAAyB;IAC3D,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAA;IAC9B,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,kBAAkB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAA;IAClG,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,KAAK;SAChB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,MAAM,CAAC;SACxC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAA;IACrH,MAAM,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAA;IACnC,MAAM,YAAY,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAA;IAC1F,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAA;IAC7B,OAAO;;oGAE2F,UAAU,CAAC,KAAK,CAAC;SAC5G,cAAc;;oFAE6D,UAAU,CAAC,KAAK,CAAC,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa;+BAC7K,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY;MACzE,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,wEAAwE,eAAe,CAAC,QAAQ,CAAC,KAAK,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,0CAA0C,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE;qCAClV,mBAAmB,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,YAAY,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,gBAAgB,EAAE,QAAQ,CAAC;;2CAE5H,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC;sBAChD,CAAA;AACtB,CAAC;AAED,SAAS,cAAc,CAAC,IAAc,EAAE,IAAY,EAAE,QAAgB,EAAE,MAAe;IACrF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACrD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO,mDAAmD,KAAK,6DAA6D,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAA;IAClK,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,QAAQ,SAAS,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAA;IAC9D,OAAO,8BAA8B,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,oBAAoB,KAAK,WAAW,eAAe,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,4DAA4D,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAA;AAChQ,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAc,EAAE,IAAY,EAAE,IAAwB,EAAE,SAA8B,EAAE,QAAgB;IACnI,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO,qHAAqH,CAAA;IAC9H,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,QAAQ,mBAAmB,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,CAAA;IACvF,MAAM,OAAO,GAAG,6CAA6C,UAAU,CAAC,IAAI,CAAC,cAAc,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,wCAAwC,eAAe,CAAC,QAAQ,CAAC,mBAAmB,CAAA;IACpM,IAAI,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,GAAG,QAAQ,mBAAmB,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAA;QAC1E,OAAO,GAAG,OAAO,sCAAsC,eAAe,CAAC,MAAM,CAAC,UAAU,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAA;IAC9H,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,qEAAqE,CAAC,CAAC,CAAC,EAAE,kCAAkC,UAAU,CAAC,IAAI,CAAC,kBAAkB,CAAA;IAChL,CAAC;IACD,OAAO,GAAG,OAAO,mJAAmJ,eAAe,CAAC,QAAQ,CAAC,kBAAkB,CAAA;AACjN,CAAC;AAED,SAAS,aAAa,CAAC,IAAc,EAAE,KAAiB;IACtD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;IACxD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAiB,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC7D,MAAM,OAAO,GAAG,CAAC,IAAc,EAAE,OAAO,IAAI,GAAG,EAAU,EAAU,EAAE;QACnE,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACjC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAA;QACvC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,IAAI,CAAA;QACjE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACjB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACtC,MAAM,KAAK,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAA;QACxF,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;QACzB,OAAO,KAAK,CAAA;IACd,CAAC,CAAA;IACD,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAA;IAC5B,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;AAC1I,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;AAC1I,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAA;AAC1B,CAAC;AAED,MAAM,cAAc,GAAG;;;;CAItB,CAAA"}
|
package/lib/notes/store.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type NoteFileUpload, type NoteListRequest, type NoteNode, type NoteVersion } from './domain.js';
|
|
1
|
+
import { type NoteFileUpload, type NoteListRequest, type NoteNode, type NoteShare, type NoteVersion } from './domain.js';
|
|
2
2
|
export declare class NoteStore {
|
|
3
3
|
private readonly rootPath;
|
|
4
4
|
private readonly removeOnClose;
|
|
@@ -11,6 +11,13 @@ export declare class NoteStore {
|
|
|
11
11
|
list(request?: NoteListRequest): NoteNode[];
|
|
12
12
|
get(id: string): NoteNode | undefined;
|
|
13
13
|
subtree(id: string): NoteNode[];
|
|
14
|
+
listSharedSubtree(id: string, limit?: number): NoteNode[];
|
|
15
|
+
isWithin(rootId: string, candidateId: string): boolean;
|
|
16
|
+
listShares(): NoteShare[];
|
|
17
|
+
getShareByNoteId(noteId: string): NoteShare | undefined;
|
|
18
|
+
getShareByToken(token: string): NoteShare | undefined;
|
|
19
|
+
createShare(noteId: string): NoteShare;
|
|
20
|
+
deleteShare(noteId: string): boolean;
|
|
14
21
|
createFolder(name: string, parentId?: string | null): Promise<NoteNode>;
|
|
15
22
|
createDocument(name: string, parentId?: string | null, content?: string): Promise<NoteNode>;
|
|
16
23
|
upload(upload: NoteFileUpload): Promise<NoteNode>;
|
|
@@ -18,6 +25,11 @@ export declare class NoteStore {
|
|
|
18
25
|
node: NoteNode;
|
|
19
26
|
content: Buffer;
|
|
20
27
|
}>;
|
|
28
|
+
readPreview(id: string, maximumBytes: number): Promise<{
|
|
29
|
+
node: NoteNode;
|
|
30
|
+
content: Buffer;
|
|
31
|
+
truncated: boolean;
|
|
32
|
+
}>;
|
|
21
33
|
updateContent(id: string, content: Uint8Array): Promise<NoteNode>;
|
|
22
34
|
listVersions(id: string, limit?: number): NoteVersion[];
|
|
23
35
|
readVersion(id: string, version: number): Promise<{
|
|
@@ -41,8 +53,10 @@ export declare class NoteStore {
|
|
|
41
53
|
private assertNameAvailable;
|
|
42
54
|
private nameExists;
|
|
43
55
|
private isDescendant;
|
|
56
|
+
private mapShare;
|
|
44
57
|
private migrate;
|
|
45
58
|
private migrateVersionOne;
|
|
59
|
+
private migrateVersionTwo;
|
|
46
60
|
private objectPath;
|
|
47
61
|
private versionDirectory;
|
|
48
62
|
private versionPath;
|
package/lib/notes/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/notes/store.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,QAAQ,EAEb,KAAK,WAAW,EACjB,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/notes/store.ts"],"names":[],"mappings":"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"}
|