This commit is contained in:
Andras Schmelczer 2026-01-12 22:42:29 +00:00 • committed by GitHub
commit afc96005ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
91 changed files with 6230 additions and 9161 deletions

View file

@ -23,14 +23,19 @@ jobs:
- name: Setup Node.js environment
uses: actions/setup-node@v4.2.0
with:
node-version: "22.x"
node-version: "25.x"
check-latest: true
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: "1.89.0"
toolchain: "1.92.0"
components: clippy, rustfmt
- name: Install Task
uses: arduino/setup-task@v2
with:
version: 3.x
- name: Lint & test
run: scripts/check.sh
run: task check

View file

@ -5,8 +5,8 @@ on:
branches:
- main
paths:
- 'docs/**'
- '.github/workflows/deploy-docs.yml'
- "docs/**"
- ".github/workflows/deploy-docs.yml"
workflow_dispatch:
permissions:
@ -28,18 +28,22 @@ jobs:
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v4
- name: Setup Node.js environment
uses: actions/setup-node@v4.2.0
with:
node-version: 22
cache: npm
cache-dependency-path: docs/package-lock.json
node-version: "25.x"
check-latest: true
- name: Install Task
uses: arduino/setup-task@v2
with:
version: 3.x
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Build docs
run: scripts/build-docs.sh
run: task docs:check
- name: Upload artifact
uses: actions/upload-pages-artifact@v3

View file

@ -6,7 +6,7 @@ on:
pull_request:
branches: ["main"]
schedule:
- cron: '0 * * * *'
- cron: "0 * * * *"
workflow_dispatch:
concurrency:
@ -28,21 +28,22 @@ jobs:
- name: Setup Node.js environment
uses: actions/setup-node@v4.2.0
with:
node-version: "22.x"
node-version: "25.x"
check-latest: true
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: "1.89.0"
toolchain: "1.92.0"
components: clippy, rustfmt
- name: Setup rust
run: |
which sqlx || cargo install sqlx-cli
cd sync-server
sqlx database create --database-url sqlite://db.sqlite3
sqlx migrate run --source src/app_state/database/migrations --database-url sqlite://db.sqlite3
- name: Install Task
uses: arduino/setup-task@v2
with:
version: 3.x
- name: Setup database
run: task db:setup
- name: E2E tests
run: |
@ -51,7 +52,7 @@ jobs:
SERVER_PID=$!
cd ..
scripts/e2e.sh 8
task e2e -- 8
EXIT_CODE=$?
kill $SERVER_PID 2>/dev/null || true
@ -69,4 +70,4 @@ jobs:
- name: Cleanup
if: always()
run: scripts/clean-up.sh
run: task clean

View file

@ -19,28 +19,30 @@ jobs:
- name: Setup Node.js environment
uses: actions/setup-node@v4.2.0
with:
node-version: "22.x"
node-version: "25.x"
check-latest: true
- name: Build plugin
run: |
cd frontend
npm ci
npm run build
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: "1.89.0"
toolchain: "1.92.0"
components: clippy, rustfmt
- name: Install Task
uses: arduino/setup-task@v2
with:
version: 3.x
- name: Install cross-compilation tools
run: |
apt update
apt install -y gcc-aarch64-linux-gnu musl-tools gcc-mingw-w64-x86-64
- name: Build Linux and Windows binaries
run: ./scripts/build-sync-server-binaries.sh
- name: Build frontend
run: task frontend:build
- name: Build binaries
run: task release:build-binaries
- name: Create release
env:

View file

@ -5,6 +5,6 @@
"**/dist": true,
"**/node_modules": true,
"**/.sqlx": true,
"**/target": true,
},
"**/target": true
}
}

240
CLAUDE.md
View file

@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Project Overview
VaultLink is a self-hosted Obsidian plugin for real-time collaborative file syncing. The project consists of a Rust-based sync server and a TypeScript frontend with three main components: an Obsidian plugin, a sync client library, and a test client.
VaultLink is a self-hosted Obsidian plugin for real-time collaborative file syncing. The project consists of a Rust-based sync server and a TypeScript frontend with four main components: an Obsidian plugin, a sync client library, a test client, and a standalone CLI client.
## Architecture
@ -13,98 +13,234 @@ VaultLink is a self-hosted Obsidian plugin for real-time collaborative file sync
- **sync-server/**: Rust-based WebSocket server with SQLite database for document versioning and real-time synchronization
- **frontend/sync-client/**: TypeScript library providing core sync functionality, WebSocket management, and file operations
- **frontend/obsidian-plugin/**: Obsidian plugin that integrates the sync client with Obsidian's API
- **frontend/test-client/**: CLI testing tool for the sync functionality
- **frontend/test-client/**: CLI testing tool for simulating multiple concurrent users
- **frontend/local-client-cli/**: Standalone CLI for VaultLink sync client
### Key Technologies
- **Backend**: Rust with Axum framework, SQLite with SQLx, WebSockets for real-time sync
- **Frontend**: TypeScript, Webpack for bundling, Jest for testing
- **Frontend**: TypeScript, Webpack for bundling, Node.js native test runner
- **Sync Algorithm**: Uses reconcile-text library for operational transformation
### Architectural Patterns
**Server Architecture:**
- `AppState`: Central state container holding `Database`, `Cursors`, and `Broadcasts`
- `Database`: SQLite-backed document versioning with SQLx for compile-time query verification
- `Broadcasts`: WebSocket broadcast system for real-time updates to connected clients
- `Cursors`: Tracks user cursor positions across documents with background cleanup task
**Client Architecture:**
- `SyncClient`: Main entry point, orchestrates all sync operations
- `SyncService`: HTTP API client for CRUD operations on documents
- `WebSocketManager`: Manages WebSocket connection and real-time updates
- `Syncer`: Coordinates file synchronization between local filesystem and server
- `CursorTracker`: Manages local and remote cursor positions
- `Database`: Client-side document metadata cache
- `FileOperations`: Abstraction layer for filesystem operations
**Dual-Bundle Strategy:**
The sync-client builds two separate bundles:
- `sync-client.web.js`: Browser-compatible UMD bundle (excludes `ws` package)
- `sync-client.node.js`: Node.js CommonJS bundle with WebSocket support
## Development Commands
### Server Development
This project uses [Taskfile](https://taskfile.dev/) for task automation. Run `task --list` to see all available tasks.
### Initial Setup
**Taskfile:**
```bash
# Install Task (https://taskfile.dev/installation/)
# macOS
brew install go-task
# Linux
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin
# Or via npm
npm install -g @go-task/cli
```
**Node.js (requires version 25):**
```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
nvm install 25
nvm use 25
nvm alias default 25 # Optional: set as system default
```
**Rust:**
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
cargo install sqlx-cli cargo-machete cargo-edit cargo-insta
```
**Frontend:**
```bash
task frontend:install
```
### Common Tasks (Taskfile)
```bash
task check # Full CI check (lint, test, format). Run before pushing.
task check:fix # Same as above but auto-fixes issues
task e2e -- 8 # E2E tests with 8 concurrent clients
task clean # Clean logs and database files
task update-api-types # Update TypeScript bindings from Rust types
task release:bump -- patch # Bump version (patch|minor|major)
```
### Server Tasks
```bash
task rust:run # Start development server
task rust:test # Run all Rust tests
task rust:clippy # Lint Rust code
task rust:clippy-fix # Auto-fix clippy warnings
task rust:fmt # Format Rust code
task rust:fmt-check # Check Rust formatting
task rust:machete # Detect unused dependencies
```
### Frontend Tasks
```bash
task frontend:dev # Start development mode
task frontend:build # Build all workspaces
task frontend:test # Run all frontend tests
task frontend:lint # Lint and format TypeScript
```
### Database Tasks
```bash
task db:setup # Create and migrate database
task db:reset # Reset database (delete and recreate)
task db:prepare # Prepare SQLx offline data
task db:add-migration NAME=<migration_name> # Add new migration
```
### Documentation Tasks
```bash
task docs:check # Build and check documentation
task docs:dev # Start documentation dev server
```
### Direct Commands (Alternative)
If you prefer not to use Taskfile, these commands work directly:
**Server:**
```bash
cd sync-server
cargo run config-e2e.yml # Start development server
cargo test --verbose # Run Rust tests
cargo clippy --all-targets --all-features # Lint Rust code
cargo clippy --all-targets --all-features --fix --allow-dirty --allow-staged # Auto-fix clippy warnings
cargo fmt --all -- --check # Check Rust formatting
cargo fmt --all # Auto-format Rust code
cargo machete --with-metadata # Detect unused dependencies
cargo test --verbose # Run all Rust tests
cargo clippy --all-targets --all-features # Lint
cargo fmt --all # Format
```
### Frontend Development
**Frontend:**
```bash
cd frontend
npm run dev # Start development mode (watches sync-client and obsidian-plugin)
npm run dev # Development mode
npm run build # Build all workspaces
npm run test # Run all tests
npm run lint # Lint and format TypeScript code
npm run test # Run tests
npm run lint # Lint and format
```
### Database Setup (Development)
**Database:**
```bash
cd sync-server
sqlx database create --database-url sqlite://db.sqlite3
sqlx migrate run --source src/app_state/database/migrations --database-url sqlite://db.sqlite3
cargo sqlx prepare --workspace
```
### Initial Setup
```bash
# Install required cargo tools
cargo install sqlx-cli cargo-machete cargo-edit
```
### Scripts
- `scripts/check.sh`: Full CI check (builds, lints, tests both server and frontend)
- `scripts/check.sh --fix`: Same as above but auto-fixes linting and formatting issues
- `scripts/e2e.sh`: End-to-end testing
- `scripts/clean-up.sh`: Clean logs and database files
- `scripts/bump-version.sh patch`: Publish new version
- `scripts/update-api-types.sh`: Update TypeScript bindings from Rust types
## Code Structure
### Workspace Configuration
The frontend uses npm workspaces with four packages:
- `sync-client`: Core synchronization logic
- `sync-client`: Core synchronization logic (builds dual bundles for web and Node.js)
- `obsidian-plugin`: Obsidian-specific integration
- `test-client`: Testing utilities
- `test-client`: Testing utilities for E2E tests
- `local-client-cli`: Standalone CLI for VaultLink sync client
### Type Generation
Rust structs generate TypeScript types via ts-rs crate, stored in `sync-server/bindings/` and used by frontend packages.
### Type Generation and API Updates
### Key Files
- `sync-server/src/`: Rust server implementation with WebSocket handlers
- `frontend/sync-client/src/sync-client.ts`: Main sync client entry point
- `frontend/obsidian-plugin/src/vault-link-plugin.ts`: Main Obsidian plugin class
- `frontend/sync-client/src/services/sync-service.ts`: Core synchronization logic
Rust structs generate TypeScript types via ts-rs crate:
1. Rust structs annotated with `#[derive(TS)]` export to `sync-server/bindings/`
2. Run `task update-api-types` to copy bindings to `frontend/sync-client/src/services/types/`
3. Frontend imports these types for type-safe API communication
### Important Implementation Details
**SQLx Compile-Time Verification:**
- SQLx verifies SQL queries at compile time against the database schema
- Run `cargo sqlx prepare --workspace` after schema changes to update `.sqlx/` directory
- CI builds require prepared query metadata to avoid needing a live database
## Testing
### Running Tests
- Server: `cargo test --verbose`
- Frontend: `npm run test` (runs Jest across all workspaces)
- E2E: `scripts/e2e.sh`
```bash
task rust:test # All Rust tests
task frontend:test # All frontend tests
task e2e -- 8 # E2E with 8 concurrent clients
task clean # Clean up after tests
```
Or use direct commands:
```bash
cd sync-server && cargo test --verbose # Rust tests
cd frontend && npm run test # Frontend tests
```
### Test Structure
- Rust: Unit tests alongside source files
- TypeScript: `.test.ts` files using Jest
- E2E: Uses test-client to simulate multiple concurrent users
## Code Style
- **Rust**: Unit tests alongside source files, uses `cargo-insta` for snapshot testing
- **TypeScript**: `.test.ts` files using Node.js native test runner (not Jest)
- **E2E**: Uses `test-client` to simulate multiple concurrent users with random operations
## Code Style and Formatting
### Rust
- Uses extensive Clippy lints (see Cargo.toml)
- Follows pedantic linting rules
- Extensive Clippy lints (see `Cargo.toml`)
- Pedantic linting rules enabled
- Forbids unsafe code
- Uses cargo fmt with default settings
- Uses `rustfmt.toml` for formatting configuration (4 spaces, Unix line endings)
- Run `cargo fmt --all` to format
### TypeScript
- Prettier configuration: 4-space tabs, trailing commas removed, LF line endings
- ESLint with unused imports plugin
- Consistent across all three frontend packages
- **Prettier**: 4-space indentation, no trailing commas, LF line endings
- **YAML/Markdown override**: 2-space indentation (via prettier config)
- **ESLint**: Strict rules with unused imports detection
- Configuration in `frontend/package.json`
- Run `npm run lint` to format and fix issues
### EditorConfig
- `.editorconfig` at project root defines baseline formatting rules
- `rustfmt.toml` and Prettier config explicitly mirror these settings
- Both formatters enforce: 4-space indent (2 for YAML/MD), LF endings, final newline, trim trailing whitespace

View file

@ -8,12 +8,12 @@
## Develop
### Install [nvm](https://github.com/nvm-sh/nvm)
### Set up Node.JS 25 with [nvm](https://github.com/nvm-sh/nvm)
- `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash`
- `nvm install 22`
- `nvm use 22`
- Optionally set the system-wide default: `nvm alias default 22`
- `nvm install 25`
- `nvm use 25`
- Optionally, set the system-wide default: `nvm alias default 25`
### Set up Rust
@ -77,3 +77,10 @@ And to clean up the logs & database files, run `scripts/clean-up.sh`
## Projects
- [Sync server](./sync-server/README.md)
a create that has been processed by the server but got lost on the way back will create a 2nd doc if it gets edited

96
Taskfile.yml Normal file
View file

@ -0,0 +1,96 @@
version: "3"
vars:
NODE_VERSION: "25"
includes:
rust:
taskfile: ./taskfiles/rust.yml
dir: ./sync-server
frontend:
taskfile: ./taskfiles/frontend.yml
dir: ./frontend
db:
taskfile: ./taskfiles/database.yml
dir: ./sync-server
e2e:
taskfile: ./taskfiles/e2e.yml
docs:
taskfile: ./taskfiles/docs.yml
dir: ./docs
release:
taskfile: ./taskfiles/release.yml
tasks:
check:
desc: Run all checks (lint, test, format)
cmds:
- task: check-node
- task: db:setup
- task: rust:test
- task: rust:lint
- task: update-api-types
- task: frontend:install
- task: frontend:build
- task: frontend:test
- task: frontend:lint
- task: format
- task: check-clean
check:fix:
desc: Run all checks with auto-fix enabled
cmds:
- task: check-node
- task: db:setup
- task: rust:test
- task: rust:lint-fix
- task: update-api-types
- task: frontend:install
- task: frontend:build
- task: frontend:test
- task: frontend:lint
- task: format
check-node:
internal: true
silent: true
preconditions:
- sh: node -v | grep -q "^v{{.NODE_VERSION}}"
msg: "Node.js {{.NODE_VERSION}} required (found: $(node -v))"
cmds:
- echo "Node.js {{.NODE_VERSION}} confirmed"
check-clean:
internal: true
preconditions:
- sh: test -z "$(git status --porcelain)"
msg: |
Working directory not clean after linting:
$(git status --porcelain)
format:
desc: Format all files with Prettier
dir: "{{.ROOT_DIR}}"
cmds:
- npx -C frontend prettier --write "**/*.{ts,js,json,md,yml,yaml}"
update-api-types:
desc: Update TypeScript bindings from Rust types
cmds:
- rm -rf sync-server/bindings
- task: rust:export-bindings
- cp -r sync-server/bindings/* frontend/sync-client/src/services/types/
- cd frontend && npm run lint
- task: format
clean:
desc: Clean up logs and databases
cmds:
- rm -rf sync-server/databases logs
e2e:
desc: Run E2E tests (usage - task e2e -- 8)
cmds:
- task: e2e:run
vars:
PROCESS_COUNT: "{{.CLI_ARGS}}"

View file

@ -2,12 +2,7 @@
"version": "0.2",
"language": "en-GB",
"dictionaries": ["en-gb"],
"ignorePaths": [
"node_modules",
".vitepress/dist",
".vitepress/cache",
"package-lock.json"
],
"ignorePaths": ["node_modules", ".vitepress/dist", ".vitepress/cache", "package-lock.json"],
"words": [
"VaultLink",
"Obsidian",

View file

@ -361,11 +361,11 @@ VALUES (?, ?, ?);
```json
{
"type": "upload_file",
"path": "notes/example.md",
"content": "File content here...",
"base_version": 10,
"timestamp": "2024-01-01T12:00:00Z"
"type": "upload_file",
"path": "notes/example.md",
"content": "File content here...",
"base_version": 10,
"timestamp": "2024-01-01T12:00:00Z"
}
```
@ -373,8 +373,8 @@ VALUES (?, ?, ?);
```json
{
"type": "download_file",
"path": "notes/example.md"
"type": "download_file",
"path": "notes/example.md"
}
```
@ -382,8 +382,8 @@ VALUES (?, ?, ?);
```json
{
"type": "delete_file",
"path": "notes/old.md"
"type": "delete_file",
"path": "notes/old.md"
}
```
@ -391,8 +391,8 @@ VALUES (?, ?, ?);
```json
{
"type": "list_files",
"since_version": 0
"type": "list_files",
"since_version": 0
}
```
@ -402,11 +402,11 @@ VALUES (?, ?, ?);
```json
{
"type": "file_updated",
"path": "notes/example.md",
"version": 11,
"size": 1024,
"hash": "abc123..."
"type": "file_updated",
"path": "notes/example.md",
"version": 11,
"size": 1024,
"hash": "abc123..."
}
```
@ -414,10 +414,10 @@ VALUES (?, ?, ?);
```json
{
"type": "file_content",
"path": "notes/example.md",
"content": "Updated content...",
"version": 11
"type": "file_content",
"path": "notes/example.md",
"content": "Updated content...",
"version": 11
}
```
@ -425,9 +425,9 @@ VALUES (?, ?, ?);
```json
{
"type": "file_deleted",
"path": "notes/old.md",
"version": 12
"type": "file_deleted",
"path": "notes/old.md",
"version": 12
}
```
@ -435,9 +435,9 @@ VALUES (?, ?, ?);
```json
{
"type": "sync_complete",
"total_files": 150,
"current_version": 200
"type": "sync_complete",
"total_files": 150,
"current_version": 200
}
```
@ -445,9 +445,9 @@ VALUES (?, ?, ?);
```json
{
"type": "error",
"message": "File too large",
"code": "FILE_TOO_LARGE"
"type": "error",
"message": "File too large",
"code": "FILE_TOO_LARGE"
}
```

View file

@ -53,7 +53,7 @@ Central authority for synchronisation. Rust + Axum framework.
**Technology**:
- **Language**: Rust 1.89+
- **Language**: Rust 1.92+
- **Framework**: Axum (async web framework)
- **Database**: SQLite with SQLx
- **Protocol**: WebSockets for real-time communication

View file

@ -243,9 +243,9 @@ users:
2. Client sends authentication message:
```json
{
"type": "auth",
"token": "user-token",
"vault": "vault-name"
"type": "auth",
"token": "user-token",
"vault": "vault-name"
}
```
3. Server validates:

View file

@ -75,7 +75,7 @@ chmod +x sync_server-linux-x86_64
### Build from Source
Requirements: Rust 1.89.0+, SQLite development headers, SQLx CLI
Requirements: Rust 1.92.0+, SQLite development headers, SQLx CLI
```bash
# Clone the repository

5960
docs/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
FROM node:22-slim AS builder
FROM node:25-slim AS builder
WORKDIR /build
@ -7,7 +7,7 @@ COPY . .
RUN npm ci
RUN npm run build
FROM node:22-alpine
FROM node:25-alpine
LABEL org.opencontainers.image.title="VaultLink Local CLI"
LABEL org.opencontainers.image.description="Standalone CLI for VaultLink sync client"

View file

@ -47,24 +47,24 @@ vaultlink \
### Required
| Option | Description |
|--------|-------------|
| `-l, --local-path <path>` | Local directory to sync |
| `-r, --remote-uri <uri>` | Remote server WebSocket URI (ws:// or wss://) |
| `-t, --token <token>` | Authentication token |
| `-v, --vault-name <name>` | Vault name on server |
| Option | Description |
| ------------------------- | --------------------------------------------- |
| `-l, --local-path <path>` | Local directory to sync |
| `-r, --remote-uri <uri>` | Remote server WebSocket URI (ws:// or wss://) |
| `-t, --token <token>` | Authentication token |
| `-v, --vault-name <name>` | Vault name on server |
### Optional
| Option | Default | Description |
|--------|---------|-------------|
| `--sync-concurrency <number>` | `1` | Concurrent sync operations |
| `--max-file-size-mb <number>` | `10` | Maximum file size in MB |
| `--ignore-pattern <pattern>` | - | Glob pattern to ignore (repeatable) |
| `--websocket-retry-interval-ms <ms>` | `3500` | WebSocket reconnection interval |
| `--log-level <level>` | `INFO` | Log level: DEBUG, INFO, WARNING, ERROR |
| `-h, --help` | - | Show help |
| `-V, --version` | - | Show version |
| Option | Default | Description |
| ------------------------------------ | ------- | -------------------------------------- |
| `--sync-concurrency <number>` | `1` | Concurrent sync operations |
| `--max-file-size-mb <number>` | `10` | Maximum file size in MB |
| `--ignore-pattern <pattern>` | - | Glob pattern to ignore (repeatable) |
| `--websocket-retry-interval-ms <ms>` | `3500` | WebSocket reconnection interval |
| `--log-level <level>` | `INFO` | Log level: DEBUG, INFO, WARNING, ERROR |
| `-h, --help` | - | Show help |
| `-V, --version` | - | Show version |
### Auto-Ignored Patterns
@ -74,11 +74,13 @@ vaultlink \
### Examples
Basic usage:
```bash
vaultlink -l ./vault -r wss://sync.example.com -t token123 -v default
```
With ignore patterns:
```bash
vaultlink -l ./vault -r wss://sync.example.com -t token123 -v default \
--ignore-pattern "*.tmp" \
@ -87,6 +89,7 @@ vaultlink -l ./vault -r wss://sync.example.com -t token123 -v default \
```
With debug logging:
```bash
vaultlink -l ./vault -r wss://sync.example.com -t token123 -v default \
--log-level DEBUG
@ -176,6 +179,7 @@ services:
## Development
Build:
```bash
npm run build
# or from the parent folder, run
@ -183,11 +187,13 @@ docker build -f local-client-cli/Dockerfile .
```
Test:
```bash
npm test
```
Docker build:
```bash
cd frontend
docker build -f local-client-cli/Dockerfile -t vault-link-cli:test .

View file

@ -11,18 +11,16 @@
"build": "webpack --mode production",
"test": "tsx --test 'src/**/*.test.ts'"
},
"dependencies": {
"commander": "^14.0.2",
"watcher": "^2.3.1"
},
"devDependencies": {
"@types/node": "^24.8.1",
"commander": "^14.0.2",
"watcher": "^2.3.1",
"@types/node": "^25.0.2",
"sync-client": "file:../sync-client",
"ts-loader": "^9.5.2",
"ts-loader": "^9.5.4",
"tslib": "2.8.1",
"tsx": "^4.20.6",
"typescript": "5.8.3",
"webpack": "^5.99.9",
"tsx": "^4.21.0",
"typescript": "5.9.3",
"webpack": "^5.103.0",
"webpack-cli": "^6.0.1"
}
}

View file

@ -106,8 +106,8 @@ export class FileWatcher {
}
/**
* Convert a native platform path to forward slashes
*/
* Convert a native platform path to forward slashes
*/
private toUnixPath(nativePath: string): string {
if (path.sep === "\\") {
return nativePath.replace(/\\/g, "/");

View file

@ -185,8 +185,8 @@ export class NodeFileSystemOperations implements FileSystemOperations {
}
/**
* Convert a forward-slash path to native platform path separators
*/
* Convert a forward-slash path to native platform path separators
*/
private toNativePath(relativePath: string): string {
if (path.sep === "\\") {
return relativePath.replace(/\//g, "\\");
@ -195,8 +195,8 @@ export class NodeFileSystemOperations implements FileSystemOperations {
}
/**
* Convert a native platform path to forward slashes
*/
* Convert a native platform path to forward slashes
*/
private toUnixPath(nativePath: string): string {
if (path.sep === "\\") {
return nativePath.replace(/\\/g, "/");

View file

@ -18,7 +18,5 @@
"declarationMap": true,
"sourceMap": true
},
"exclude": [
"dist"
]
"exclude": ["dist"]
}

Some files were not shown because too many files have changed in this diff Show more