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
48 changes: 22 additions & 26 deletions .github/workflows/quality-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,19 @@ jobs:
with:
fetch-depth: 0 # Need full history for version comparison

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: '10'

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
node-version-file: '.nvmrc'
cache: 'pnpm'

- name: Install dependencies
run: npm ci --legacy-peer-deps
run: pnpm i --frozen-lockfile

- name: Check for Claude signatures
run: |
Expand Down Expand Up @@ -83,31 +88,22 @@ jobs:
run: |
echo "🔨 Verifying dist is up-to-date..."

# Check if src files were changed
if git diff --name-only HEAD~1 HEAD | grep -qE "^src/.*\.(ts|js)$"; then
echo "📦 Source files changed, verifying dist..."

# Build dist
npm run clean || npx rimraf dist*
npx rollup -c rollup.config.mjs
npx copyfiles package.json LICENSE README.md ./dist
npx rimraf ./dist/ts

# Check if there are differences
if ! git diff --quiet dist/; then
echo "❌ ERROR: dist is out of date!"
echo "The following files in dist/ are not up-to-date:"
git diff --name-only dist/
echo ""
echo "Please run 'npm run build' and commit the changes"
exit 1
fi

echo "✅ dist is up-to-date"
else
echo "ℹ️ No source changes, skipping dist check"
# Always rebuild. A conditional check keyed on "did HEAD~1..HEAD touch
# src/" cannot see drift introduced by a merge commit, which is exactly
# how the committed dist lost the VTODO API in f8d5561.
pnpm build

if ! git diff --quiet dist/; then
echo "❌ ERROR: dist does not match a fresh build from src!"
echo "The following files in dist/ are out of date:"
git diff --name-only dist/
echo ""
echo "Please run 'pnpm build' and commit the changes"
exit 1
fi

echo "✅ dist matches a fresh build from src"

- name: Summary
if: success()
run: |
Expand Down
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ echo "✅ No Claude signatures found"
echo "📦 Checking package.json version..."

# Check if package.json is being modified
if echo "$STAGED_FILES" | grep -q "package.json"; then
if echo "$STAGED_FILES" | grep -qx "package.json"; then
# Get current version from HEAD
OLD_VERSION=$(git show HEAD:package.json 2>/dev/null | grep '"version"' | head -1 | sed 's/.*"version": "\(.*\)".*/\1/')

Expand Down
133 changes: 132 additions & 1 deletion dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export { createAccount } from './account';
export { davRequest, propfind, createObject, updateObject, deleteObject } from './request';
export { collectionQuery, supportedReportSet, isCollectionDirty, syncCollection, smartCollectionSync, } from './collection';
export { calendarQuery, calendarMultiGet, makeCalendar, fetchCalendars, fetchCalendarUserAddresses, fetchCalendarObjects, createCalendarObject, updateCalendarObject, deleteCalendarObject, syncCalendars, freeBusyQuery, } from './calendar';
export { addressBookQuery, addressBookMultiGet, fetchAddressBooks, fetchVCards, createVCard, updateVCard, deleteVCard, } from './addressBook';
export { addressBookQuery, addressBookMultiGet, fetchAddressBooks, fetchVCards, createVCard, updateVCard, deleteVCard, makeAddressBook, } from './addressBook';
export { todoQuery, todoMultiGet, fetchTodos, createTodo, updateTodo, deleteTodo, } from './todo';
export { getBasicAuthHeaders, getBearerAuthHeaders, getOauthHeaders, fetchOauthTokens, refreshAccessToken, } from './util/authHelpers';
export { urlContains, urlEquals, getDAVAttribute, cleanupFalsy } from './util/requestHelpers';
export { DAVNamespace, DAVAttributeMap, DAVNamespaceShort } from './consts';
Expand All @@ -23,6 +24,8 @@ declare const _default: {
[key: string]: T;
};
excludeHeaders: (headers: Record<string, string> | undefined, headersToExclude: string[] | undefined) => Record<string, string>;
defaultIcsFilter: (url: string) => boolean;
validateISO8601TimeRange: (start: string, end: string) => void;
defaultParam: <F extends (...args: any[]) => any>(fn: F, params: Partial<Parameters<F>[0]>) => (...args: Parameters<F>) => ReturnType<F>;
getBasicAuthHeaders: (credentials: import("./types/models").DAVCredentials) => {
authorization?: string;
Expand All @@ -41,6 +44,62 @@ declare const _default: {
authorization?: string;
};
}>;
todoQuery: (params: {
url: string;
props: import("xml-js/types").ElementCompact;
filters?: import("xml-js/types").ElementCompact;
timezone?: string;
depth?: import("./types/DAVTypes").DAVDepth;
headers?: Record<string, string>;
headersToExclude?: string[];
fetchOptions?: RequestInit;
}) => Promise<import("./types/DAVTypes").DAVResponse[]>;
todoMultiGet: (params: {
url: string;
props: import("xml-js/types").ElementCompact;
objectUrls?: string[];
timezone?: string;
depth: import("./types/DAVTypes").DAVDepth;
filters?: import("xml-js/types").ElementCompact;
headers?: Record<string, string>;
headersToExclude?: string[];
fetchOptions?: RequestInit;
}) => Promise<import("./types/DAVTypes").DAVResponse[]>;
fetchTodos: (params: {
calendar: import("./types/models").DAVCalendar;
objectUrls?: string[];
filters?: import("xml-js/types").ElementCompact;
timeRange?: {
start: string;
end: string;
};
expand?: boolean;
urlFilter?: (url: string) => boolean;
headers?: Record<string, string>;
headersToExclude?: string[];
useMultiGet?: boolean;
fetchOptions?: RequestInit;
}) => Promise<import("./types/models").DAVCalendarObject[]>;
createTodo: (params: {
calendar: import("./types/models").DAVCalendar;
iCalString: string;
filename: string;
headers?: Record<string, string>;
headersToExclude?: string[];
fetchOptions?: RequestInit;
}) => Promise<Response>;
updateTodo: (params: {
calendarObject: import("./types/models").DAVCalendarObject;
headers?: Record<string, string>;
headersToExclude?: string[];
fetchOptions?: RequestInit;
}) => Promise<Response>;
deleteTodo: (params: {
calendarObject: import("./types/models").DAVCalendarObject;
headers?: Record<string, string>;
headersToExclude?: string[];
fetchOptions?: RequestInit;
}) => Promise<Response>;
fetchCalendarUserAddresses: (params: {
account: import("./types/models").DAVAccount;
headers?: Record<string, string>;
Expand Down Expand Up @@ -202,6 +261,14 @@ declare const _default: {
fetchOptions?: RequestInit;
fetch?: typeof fetch;
}) => Promise<Response>;
makeAddressBook: (params: {
url: string;
props: import("xml-js/types").ElementCompact;
depth?: import("./types/DAVTypes").DAVDepth;
headers?: Record<string, string>;
headersToExclude?: string[];
fetchOptions?: RequestInit;
}) => Promise<import("./types/DAVTypes").DAVResponse[]>;
serviceDiscovery: (params: {
account: import("./types/models").DAVAccount;
headers?: Record<string, string>;
Expand Down Expand Up @@ -540,6 +607,14 @@ declare const _default: {
fetchOptions?: RequestInit;
fetch?: typeof fetch;
}) => Promise<import("./types/DAVTypes").DAVResponse[]>;
makeAddressBook: (params: {
url: string;
props: import("xml-js/types").ElementCompact;
depth?: import("./types/DAVTypes").DAVDepth;
headers?: Record<string, string>;
headersToExclude?: string[];
fetchOptions?: RequestInit;
}) => Promise<import("./types/DAVTypes").DAVResponse[]>;
fetchVCards: (params: {
addressBook: import("./types/models").DAVAddressBook;
headers?: Record<string, string>;
Expand Down Expand Up @@ -573,6 +648,62 @@ declare const _default: {
fetchOptions?: RequestInit;
fetch?: typeof fetch;
}) => Promise<Response>;
todoQuery: (params: {
url: string;
props: import("xml-js/types").ElementCompact;
filters?: import("xml-js/types").ElementCompact;
timezone?: string;
depth?: import("./types/DAVTypes").DAVDepth;
headers?: Record<string, string>;
headersToExclude?: string[];
fetchOptions?: RequestInit;
}) => Promise<import("./types/DAVTypes").DAVResponse[]>;
todoMultiGet: (params: {
url: string;
props: import("xml-js/types").ElementCompact;
objectUrls?: string[];
timezone?: string;
depth: import("./types/DAVTypes").DAVDepth;
filters?: import("xml-js/types").ElementCompact;
headers?: Record<string, string>;
headersToExclude?: string[];
fetchOptions?: RequestInit;
}) => Promise<import("./types/DAVTypes").DAVResponse[]>;
fetchTodos: (params: {
calendar: import("./types/models").DAVCalendar;
objectUrls?: string[];
filters?: import("xml-js/types").ElementCompact;
timeRange?: {
start: string;
end: string;
};
expand?: boolean;
urlFilter?: (url: string) => boolean;
headers?: Record<string, string>;
headersToExclude?: string[];
useMultiGet?: boolean;
fetchOptions?: RequestInit;
}) => Promise<import("./types/models").DAVObject[]>;
createTodo: (params: {
calendar: import("./types/models").DAVCalendar;
iCalString: string;
filename: string;
headers?: Record<string, string>;
headersToExclude?: string[];
fetchOptions?: RequestInit;
}) => Promise<Response>;
updateTodo: (params: {
calendarObject: import("./types/models").DAVCalendarObject;
headers?: Record<string, string>;
headersToExclude?: string[];
fetchOptions?: RequestInit;
}) => Promise<Response>;
deleteTodo: (params: {
calendarObject: import("./types/models").DAVCalendarObject;
headers?: Record<string, string>;
headersToExclude?: string[];
fetchOptions?: RequestInit;
}) => Promise<Response>;
}>;
DAVClient: typeof client.DAVClient;
DAVNamespace: typeof DAVNamespace;
Expand Down
10 changes: 6 additions & 4 deletions dist/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tsdav",
"version": "2.1.8",
"version": "2.3.1",
"description": "WebDAV, CALDAV, and CARDDAV client for Nodejs and the Browser",
"keywords": [
"dav",
Expand Down Expand Up @@ -31,7 +31,7 @@
"package.json"
],
"scripts": {
"build": "pnpm -s clean && rollup -c rollup.config.mjs && copyfiles package.json LICENSE README.md ./dist && rimraf ./dist/ts",
"build": "rimraf dist* && rollup -c rollup.config.mjs && copyfiles package.json LICENSE README.md ./dist && rimraf ./dist/ts",
"lint": "eslint --ext .ts,.tsx src --ignore-pattern src/__tests__ --ignore-pattern src/util/__tests__",
"clean": "rimraf dist*",
"prepublishOnly": "pnpm build",
Expand All @@ -44,7 +44,8 @@
"test:unit": "jest --testPathPatterns=src/__tests__/unit",
"test:zoho": "jest --testPathPatterns=src/__tests__/integration/zoho --runInBand",
"typecheck": "tsc --noEmit",
"watch": "tsc --watch --outDir ./dist"
"watch": "tsc --watch --outDir ./dist",
"prepare": "husky && npm run build"
},
"dependencies": {
"base-64": "1.0.0",
Expand Down Expand Up @@ -73,6 +74,7 @@
"eslint-module-utils": "2.12.1",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-prettier": "5.5.5",
"husky": "^9.1.7",
"jest": "30.2.0",
"prettier": "3.8.0",
"rimraf": "6.1.2",
Expand All @@ -86,6 +88,6 @@
"typescript": "5.9.3"
},
"engines": {
"node": ">=10"
"node": ">=18"
}
}
Loading
Loading