Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ test-files
.ignore
.obsidian
.trash
.agents
.obsidianignore
Sync Engine Logs
.vscode
Expand Down
2 changes: 1 addition & 1 deletion modules.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
"id": "webdav",
"name": "WebDAV",
"version": "0.1.8",
"version": "0.1.9",
"description": "WebDAV backend support.",
"icon": "server",
"main": "https://sync.consensia.cc/modules/webdav.js",
Expand Down
7 changes: 6 additions & 1 deletion packages/webdav/src/webdav/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,12 @@ function toStat(endpoint: string, { propstat, href }: WebDAVResponseItem): Stat

const mtime = new Date(getDavText(validPropstat.prop.getlastmodified) ?? '').valueOf();
const size = Number.parseInt(getDavText(validPropstat.prop.getcontentlength) ?? '0', 10);
const uid = getDavText(validPropstat.prop.getetag) ?? `${mtime}~${size}`;

// https://www.rfc-editor.org/rfc/rfc9110.html#section-8.8.3
// https://github.com/hesprs/sync-engine/issues/225
let etag = getDavText(validPropstat.prop.getetag);
if (etag?.startsWith('W/')) etag = etag.slice(2);
const uid = etag ?? `${mtime}~${size}`;

return { isDir: false, key, mtime, size, uid };
}
Expand Down
4 changes: 2 additions & 2 deletions packages/webdav/test/fs-webdav.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ test('stat parses dav fields and prefers etag for uid', async () => {
propstat: {
prop: {
getcontentlength: { '#text': '12' },
getetag: 'etag-123',
getetag: 'W/"etag-123"',
getlastmodified: { '#text': 'Mon, 01 Jan 2024 00:00:00 GMT' },
resourcetype: {},
},
Expand All @@ -164,7 +164,7 @@ test('stat parses dav fields and prefers etag for uid', async () => {
key: 'Notes/file.md',
mtime: sharedDate,
size: 12,
uid: 'etag-123',
uid: '"etag-123"',
});
});

Expand Down
21 changes: 21 additions & 0 deletions skills/debug-module/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
name: debug-module
description: Write a temporary Sync Engine module for debugging. Use when encountering unreasonable bugs, don't use when the bug can be identified by inspecting code.
---

Sync Engine serves for various services, many bugs need deeper investigation that Sync Engine's built-in logs are not suffice. Temporary debug modules allow you to gather more info to facilitate the analysis.

When writing a debug module, you need to produce a plain, self-contained JS ESM file at repo root, containing a simple Sync Engine module. Read repo docs on how to develop a module before writing. Useful patterns:

- Register a request middleware to log raw request raw request and response.
- Register a filesystem wrapper to trace the files.
- Subscribe to Sync Engine events and (execute code to) gather information when event fires.

You must:

- Obfuscate any privacy-sensitive info logged in your module, including hashing filenames and contents instead of logging raw content, and strip off auth header and URL in logged requests. File mtime, size, and UID are safe to disclose without obfuscation.
- When logging, dispatch Sync Engine events `logGeneral` or `logSync` directly, do not create a separate logging and export logs path.
- Simplify the module to bare minimum, don't gather information that has no value, focus on the most valuable and distinguishing info, don't do over-abstraction. The module is throwaway.
- Only perform syntax checking, no need linting or formatting.

After writing the module, you need to give clear instruction on what to perform after loading the module.
Loading