@omnistreamai/data-adapter-webdav 0.1.0 → 0.1.2

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/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # @omnistreamai/data-adapter-webdav
2
+
3
+ ## 0.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Initial release of data-sync packages
8
+ - Updated dependencies
9
+ - @omnistreamai/data-core@0.1.2
10
+
11
+ ## 0.1.1
12
+
13
+ ### Patch Changes
14
+
15
+ - Publish beta version with ESM and CJS support
16
+ - Updated dependencies
17
+ - @omnistreamai/data-core@0.1.1
@@ -0,0 +1,59 @@
1
+ import { AdapterType, PaginatedResult, QueryOptions, RemoteAdapter, ServiceConfig } from "@omnistreamai/data-core";
2
+
3
+ //#region src/webdav-adapter.d.ts
4
+
5
+ /**
6
+ * WebDAV adapter implementation
7
+ */
8
+ declare class WebDAVAdapter implements RemoteAdapter {
9
+ readonly type = AdapterType.Remote;
10
+ readonly name = "WebDAVAdapter";
11
+ private service;
12
+ /**
13
+ * Set service configuration
14
+ */
15
+ setService(service: ServiceConfig): void;
16
+ /**
17
+ * Get request headers
18
+ */
19
+ private getHeaders;
20
+ /**
21
+ * Build URL
22
+ */
23
+ private buildUrl;
24
+ /**
25
+ * Send request
26
+ */
27
+ private request;
28
+ /**
29
+ * Initialize store
30
+ */
31
+ initStore(storeName: string, _indexes?: string[], _idKey?: string): Promise<void>;
32
+ /**
33
+ * Add data
34
+ */
35
+ add<T extends Record<string, unknown>>(storeName: string, data: T, idKey?: string): Promise<T>;
36
+ /**
37
+ * Update data
38
+ */
39
+ update<T extends Record<string, unknown>>(storeName: string, id: string, data: Partial<T>, idKey?: string): Promise<T>;
40
+ /**
41
+ * Delete data
42
+ */
43
+ delete(storeName: string, id: string, _idKey?: string): Promise<void>;
44
+ /**
45
+ * Get data by ID
46
+ */
47
+ getData<T extends Record<string, unknown>>(storeName: string, id: string, _idKey?: string): Promise<T | null>;
48
+ /**
49
+ * Get list data (with pagination support)
50
+ */
51
+ getList<T extends Record<string, unknown>>(storeName: string, options?: QueryOptions<T>, _idKey?: string): Promise<PaginatedResult<T>>;
52
+ /**
53
+ * Clear store
54
+ */
55
+ clear(storeName: string): Promise<void>;
56
+ }
57
+ //#endregion
58
+ export { WebDAVAdapter };
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/webdav-adapter.ts"],"sourcesContent":[],"mappings":";;;;;;AAYA;AACe,cADF,aAAA,YAAyB,aACvB,CAAA;EAQO,SAAA,IAAA,GARP,WAAA,CAAA,MAAA;EA4GV,SAAA,IAAA,GAAA,eAAA;EAkBiB,QAAA,OAAA;EAEZ;;;EAiBe,UAAA,CAAA,OAAA,EAzIH,aAyIG,CAAA,EAAA,IAAA;EAGP;;;EAEb,QAAA,UAAA;EAsBiE;;;EAejE,QAAA,QAAA;EAWqB;;;EAIG,QAAA,OAAA;EAAhB;;;EA3MyB,SAAA,CAAA,SAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,MAAA,EAAA,EAAA,MAAA,CAAA,EAAA,MAAA,CAAA,EA6GjC,OA7GiC,CAAA,IAAA,CAAA;EAAa;;;gBA+H7B,kDAEZ,oBAEL,QAAQ;;;;mBAeY,8DAGf,QAAQ,qBAEb,QAAQ;;;;0DAsByD;;;;oBAW5C,0EAIrB,QAAQ;;;;oBAWa,sDAEb,aAAa,sBAErB,QAAQ,gBAAgB;;;;4BAoDK"}
package/dist/index.js ADDED
@@ -0,0 +1,162 @@
1
+ let __omnistreamai_data_core = require("@omnistreamai/data-core");
2
+
3
+ //#region src/webdav-adapter.ts
4
+ /**
5
+ * WebDAV adapter implementation
6
+ */
7
+ var WebDAVAdapter = class {
8
+ type = __omnistreamai_data_core.AdapterType.Remote;
9
+ name = "WebDAVAdapter";
10
+ service = null;
11
+ /**
12
+ * Set service configuration
13
+ */
14
+ setService(service) {
15
+ this.service = service;
16
+ }
17
+ /**
18
+ * Get request headers
19
+ */
20
+ getHeaders() {
21
+ const headers = { "Content-Type": "application/json" };
22
+ if (!this.service?.authentication) return headers;
23
+ const { authentication } = this.service;
24
+ switch (authentication.authType) {
25
+ case __omnistreamai_data_core.AuthType.Token:
26
+ if (authentication.token) headers["Authorization"] = `${authentication.token.token_type} ${authentication.token.access_token}`;
27
+ break;
28
+ case __omnistreamai_data_core.AuthType.Bearer:
29
+ if (authentication.bearer) headers["Authorization"] = `Bearer ${authentication.bearer}`;
30
+ break;
31
+ case __omnistreamai_data_core.AuthType.Basic:
32
+ if (authentication.username && authentication.password) headers["Authorization"] = `Basic ${btoa(`${authentication.username}:${authentication.password}`)}`;
33
+ break;
34
+ }
35
+ return headers;
36
+ }
37
+ /**
38
+ * Build URL
39
+ */
40
+ buildUrl(storeName, id) {
41
+ if (!this.service) throw new Error("Service not configured. Call setService() first.");
42
+ const baseUrl = this.service.endpoint.replace(/\/$/, "");
43
+ const storePath = `/${storeName}`;
44
+ if (id) return `${baseUrl}${storePath}/${id}`;
45
+ return `${baseUrl}${storePath}`;
46
+ }
47
+ /**
48
+ * Send request
49
+ */
50
+ async request(url, options = {}) {
51
+ const response = await fetch(url, {
52
+ ...options,
53
+ headers: {
54
+ ...this.getHeaders(),
55
+ ...options.headers
56
+ }
57
+ });
58
+ if (!response.ok) {
59
+ if (response.status === 404) return null;
60
+ throw new Error(`HTTP error! status: ${response.status}`);
61
+ }
62
+ const text = await response.text();
63
+ if (!text) return null;
64
+ try {
65
+ return JSON.parse(text);
66
+ } catch {
67
+ return null;
68
+ }
69
+ }
70
+ /**
71
+ * Initialize store
72
+ */
73
+ async initStore(storeName, _indexes = [], _idKey = "id") {
74
+ const url = this.buildUrl(storeName);
75
+ const response = await fetch(url, {
76
+ method: "MKCOL",
77
+ headers: this.getHeaders()
78
+ });
79
+ if (!response.ok && response.status !== 409) throw new Error(`Failed to create store: ${response.statusText}`);
80
+ }
81
+ /**
82
+ * Add data
83
+ */
84
+ async add(storeName, data, idKey = "id") {
85
+ const id = String(data[idKey]);
86
+ const url = this.buildUrl(storeName, id);
87
+ return await this.request(url, {
88
+ method: "PUT",
89
+ body: JSON.stringify(data)
90
+ }) ?? data;
91
+ }
92
+ /**
93
+ * Update data
94
+ */
95
+ async update(storeName, id, data, idKey = "id") {
96
+ const existing = await this.getData(storeName, id, idKey);
97
+ if (!existing) throw new Error(`Data with id ${id} not found`);
98
+ const updated = {
99
+ ...existing,
100
+ ...data
101
+ };
102
+ const url = this.buildUrl(storeName, id);
103
+ return await this.request(url, {
104
+ method: "PUT",
105
+ body: JSON.stringify(updated)
106
+ }) ?? updated;
107
+ }
108
+ /**
109
+ * Delete data
110
+ */
111
+ async delete(storeName, id, _idKey = "id") {
112
+ const url = this.buildUrl(storeName, id);
113
+ await this.request(url, { method: "DELETE" });
114
+ }
115
+ /**
116
+ * Get data by ID
117
+ */
118
+ async getData(storeName, id, _idKey = "id") {
119
+ const url = this.buildUrl(storeName, id);
120
+ return await this.request(url, { method: "GET" });
121
+ }
122
+ /**
123
+ * Get list data (with pagination support)
124
+ */
125
+ async getList(storeName, options = {}, _idKey = "id") {
126
+ const url = this.buildUrl(storeName);
127
+ const params = new URLSearchParams();
128
+ if (options.page !== void 0) params.append("page", String(options.page));
129
+ if (options.limit !== void 0) params.append("limit", String(options.limit));
130
+ if (options.where) params.append("where", JSON.stringify(options.where));
131
+ const queryString = params.toString();
132
+ const fullUrl = queryString ? `${url}?${queryString}` : url;
133
+ const result = await this.request(fullUrl, { method: "GET" });
134
+ if (result && "data" in result) return result;
135
+ if (Array.isArray(result)) {
136
+ const dataArray = result;
137
+ return {
138
+ data: dataArray,
139
+ totalCount: dataArray.length,
140
+ page: options.page ?? 1,
141
+ limit: options.limit ?? dataArray.length
142
+ };
143
+ }
144
+ return {
145
+ data: [],
146
+ totalCount: 0,
147
+ page: options.page ?? 1,
148
+ limit: options.limit ?? 10
149
+ };
150
+ }
151
+ /**
152
+ * Clear store
153
+ */
154
+ async clear(storeName) {
155
+ const url = this.buildUrl(storeName);
156
+ await this.request(url, { method: "DELETE" });
157
+ }
158
+ };
159
+
160
+ //#endregion
161
+ exports.WebDAVAdapter = WebDAVAdapter;
162
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["AdapterType","headers: Record<string, string>","AuthType"],"sources":["../src/webdav-adapter.ts"],"sourcesContent":["import {\n AdapterType,\n type RemoteAdapter,\n type QueryOptions,\n type PaginatedResult,\n type ServiceConfig,\n AuthType,\n} from '@omnistreamai/data-core';\n\n/**\n * WebDAV adapter implementation\n */\nexport class WebDAVAdapter implements RemoteAdapter {\n readonly type = AdapterType.Remote;\n readonly name = 'WebDAVAdapter';\n\n private service: ServiceConfig | null = null;\n\n /**\n * Set service configuration\n */\n setService(service: ServiceConfig): void {\n this.service = service;\n }\n\n /**\n * Get request headers\n */\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (!this.service?.authentication) {\n return headers;\n }\n\n const { authentication } = this.service;\n\n switch (authentication.authType) {\n case AuthType.Token:\n if (authentication.token) {\n headers['Authorization'] = `${authentication.token.token_type} ${authentication.token.access_token}`;\n }\n break;\n case AuthType.Bearer:\n if (authentication.bearer) {\n headers['Authorization'] = `Bearer ${authentication.bearer}`;\n }\n break;\n case AuthType.Basic:\n if (authentication.username && authentication.password) {\n const credentials = btoa(`${authentication.username}:${authentication.password}`);\n headers['Authorization'] = `Basic ${credentials}`;\n }\n break;\n }\n\n return headers;\n }\n\n /**\n * Build URL\n */\n private buildUrl(storeName: string, id?: string): string {\n if (!this.service) {\n throw new Error('Service not configured. Call setService() first.');\n }\n\n const baseUrl = this.service.endpoint.replace(/\\/$/, '');\n const storePath = `/${storeName}`;\n \n if (id) {\n return `${baseUrl}${storePath}/${id}`;\n }\n \n return `${baseUrl}${storePath}`;\n }\n\n /**\n * Send request\n */\n private async request<T>(\n url: string,\n options: RequestInit = {}\n ): Promise<T> {\n const response = await fetch(url, {\n ...options,\n headers: {\n ...this.getHeaders(),\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n return null as T;\n }\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n // If response is empty, return null\n const text = await response.text();\n if (!text) {\n return null as T;\n }\n\n try {\n return JSON.parse(text) as T;\n } catch {\n return null as T;\n }\n }\n\n /**\n * Initialize store\n */\n async initStore(\n storeName: string,\n _indexes: string[] = [],\n _idKey: string = 'id'\n ): Promise<void> {\n const url = this.buildUrl(storeName);\n \n // Try to create directory (using MKCOL method)\n const response = await fetch(url, {\n method: 'MKCOL',\n headers: this.getHeaders(),\n });\n\n // If directory already exists (409 Conflict), ignore error\n if (!response.ok && response.status !== 409) {\n throw new Error(`Failed to create store: ${response.statusText}`);\n }\n }\n\n /**\n * Add data\n */\n async add<T extends Record<string, unknown>>(\n storeName: string,\n data: T,\n idKey: string = 'id'\n ): Promise<T> {\n const id = String(data[idKey]);\n const url = this.buildUrl(storeName, id);\n\n const result = await this.request<T>(url, {\n method: 'PUT',\n body: JSON.stringify(data),\n });\n\n return result ?? data;\n }\n\n /**\n * Update data\n */\n async update<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n data: Partial<T>,\n idKey: string = 'id'\n ): Promise<T> {\n // First get existing data\n const existing = await this.getData<T>(storeName, id, idKey);\n if (!existing) {\n throw new Error(`Data with id ${id} not found`);\n }\n\n // Merge data\n const updated = { ...existing, ...data };\n const url = this.buildUrl(storeName, id);\n\n const result = await this.request<T>(url, {\n method: 'PUT',\n body: JSON.stringify(updated),\n });\n\n return result ?? updated;\n }\n\n /**\n * Delete data\n */\n async delete(storeName: string, id: string, _idKey: string = 'id'): Promise<void> {\n const url = this.buildUrl(storeName, id);\n\n await this.request(url, {\n method: 'DELETE',\n });\n }\n\n /**\n * Get data by ID\n */\n async getData<T extends Record<string, unknown>>(\n storeName: string,\n id: string,\n _idKey: string = 'id'\n ): Promise<T | null> {\n const url = this.buildUrl(storeName, id);\n\n return await this.request<T | null>(url, {\n method: 'GET',\n });\n }\n\n /**\n * Get list data (with pagination support)\n */\n async getList<T extends Record<string, unknown>>(\n storeName: string,\n options: QueryOptions<T> = {},\n _idKey: string = 'id'\n ): Promise<PaginatedResult<T>> {\n const url = this.buildUrl(storeName);\n \n // Build query parameters\n const params = new URLSearchParams();\n if (options.page !== undefined) {\n params.append('page', String(options.page));\n }\n if (options.limit !== undefined) {\n params.append('limit', String(options.limit));\n }\n if (options.where) {\n params.append('where', JSON.stringify(options.where));\n }\n\n const queryString = params.toString();\n const fullUrl = queryString ? `${url}?${queryString}` : url;\n\n const result = await this.request<PaginatedResult<T>>(fullUrl, {\n method: 'GET',\n });\n\n // If server returns non-paginated format, convert to paginated format\n if (result && 'data' in result) {\n return result;\n }\n\n // If return is an array, convert to paginated format\n if (Array.isArray(result)) {\n const dataArray = result as T[];\n return {\n data: dataArray,\n totalCount: dataArray.length,\n page: options.page ?? 1,\n limit: options.limit ?? dataArray.length,\n };\n }\n\n // Default return empty result\n return {\n data: [],\n totalCount: 0,\n page: options.page ?? 1,\n limit: options.limit ?? 10,\n };\n }\n\n\n\n /**\n * Clear store\n */\n async clear(storeName: string): Promise<void> {\n const url = this.buildUrl(storeName);\n\n await this.request(url, {\n method: 'DELETE',\n });\n }\n}\n\n\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,17 +1,18 @@
1
1
  {
2
2
  "name": "@omnistreamai/data-adapter-webdav",
3
- "version": "0.1.0",
4
- "type": "module",
3
+ "version": "0.1.2",
5
4
  "main": "./dist/index.js",
5
+ "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
7
7
  "exports": {
8
8
  ".": {
9
9
  "types": "./dist/index.d.ts",
10
- "import": "./dist/index.js"
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js"
11
12
  }
12
13
  },
13
14
  "dependencies": {
14
- "@omnistreamai/data-core": "0.1.0"
15
+ "@omnistreamai/data-core": "0.1.2"
15
16
  },
16
17
  "scripts": {
17
18
  "build": "tsdown",
package/tsdown.config.ts CHANGED
@@ -2,10 +2,11 @@ import { defineConfig } from 'tsdown';
2
2
 
3
3
  export default defineConfig({
4
4
  entry: ['src/index.ts'],
5
- format: ['esm'],
5
+ format: ['esm', 'cjs'],
6
6
  dts: true,
7
7
  clean: true,
8
8
  sourcemap: true,
9
+ platform: 'neutral',
9
10
  });
10
11
 
11
12