@hamak/ui-remote-fs-impl 0.4.3

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.
Files changed (64) hide show
  1. package/dist/actions/index.d.ts +5 -0
  2. package/dist/actions/index.d.ts.map +1 -0
  3. package/dist/actions/index.js +4 -0
  4. package/dist/actions/remote-fs-actions.d.ts +189 -0
  5. package/dist/actions/remote-fs-actions.d.ts.map +1 -0
  6. package/dist/actions/remote-fs-actions.js +146 -0
  7. package/dist/es2015/actions/index.js +20 -0
  8. package/dist/es2015/actions/remote-fs-actions.js +147 -0
  9. package/dist/es2015/index.js +25 -0
  10. package/dist/es2015/middleware/index.js +21 -0
  11. package/dist/es2015/middleware/remote-fs-middleware.js +205 -0
  12. package/dist/es2015/middleware/store-sync-middleware.js +138 -0
  13. package/dist/es2015/plugin/index.js +20 -0
  14. package/dist/es2015/plugin/remote-fs-plugin-factory.js +169 -0
  15. package/dist/es2015/providers/http-workspace-client.js +199 -0
  16. package/dist/es2015/providers/index.js +20 -0
  17. package/dist/es2015/services/index.js +20 -0
  18. package/dist/es2015/services/remote-fs-service.js +16 -0
  19. package/dist/index.d.ts +10 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +9 -0
  22. package/dist/middleware/index.d.ts +6 -0
  23. package/dist/middleware/index.d.ts.map +1 -0
  24. package/dist/middleware/index.js +5 -0
  25. package/dist/middleware/remote-fs-middleware.d.ts +50 -0
  26. package/dist/middleware/remote-fs-middleware.d.ts.map +1 -0
  27. package/dist/middleware/remote-fs-middleware.js +192 -0
  28. package/dist/middleware/store-sync-middleware.d.ts +35 -0
  29. package/dist/middleware/store-sync-middleware.d.ts.map +1 -0
  30. package/dist/middleware/store-sync-middleware.js +134 -0
  31. package/dist/plugin/index.d.ts +5 -0
  32. package/dist/plugin/index.d.ts.map +1 -0
  33. package/dist/plugin/index.js +4 -0
  34. package/dist/plugin/remote-fs-plugin-factory.d.ts +84 -0
  35. package/dist/plugin/remote-fs-plugin-factory.d.ts.map +1 -0
  36. package/dist/plugin/remote-fs-plugin-factory.js +150 -0
  37. package/dist/providers/http-workspace-client.d.ts +99 -0
  38. package/dist/providers/http-workspace-client.d.ts.map +1 -0
  39. package/dist/providers/http-workspace-client.js +171 -0
  40. package/dist/providers/index.d.ts +5 -0
  41. package/dist/providers/index.d.ts.map +1 -0
  42. package/dist/providers/index.js +4 -0
  43. package/dist/services/index.d.ts +5 -0
  44. package/dist/services/index.d.ts.map +1 -0
  45. package/dist/services/index.js +4 -0
  46. package/dist/services/remote-fs-service.d.ts +10 -0
  47. package/dist/services/remote-fs-service.d.ts.map +1 -0
  48. package/dist/services/remote-fs-service.js +12 -0
  49. package/package.json +56 -0
  50. package/project.json +24 -0
  51. package/src/actions/index.ts +5 -0
  52. package/src/actions/remote-fs-actions.ts +302 -0
  53. package/src/index.ts +10 -0
  54. package/src/middleware/index.ts +6 -0
  55. package/src/middleware/remote-fs-middleware.ts +244 -0
  56. package/src/middleware/store-sync-middleware.ts +175 -0
  57. package/src/plugin/index.ts +5 -0
  58. package/src/plugin/remote-fs-plugin-factory.ts +238 -0
  59. package/src/providers/http-workspace-client.ts +232 -0
  60. package/src/providers/index.ts +5 -0
  61. package/src/services/index.ts +5 -0
  62. package/src/services/remote-fs-service.ts +13 -0
  63. package/tsconfig.es2015.json +21 -0
  64. package/tsconfig.json +19 -0
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Store Sync Middleware
3
+ *
4
+ * Redux middleware for synchronizing remote filesystem operations to Redux Store FS.
5
+ * This middleware listens to remote FS completion actions and updates the Store FS accordingly.
6
+ * Migrated from amk/libs/ui/core/remote-fs/src/lib/store-fs-adapter-middleware.ts
7
+ */
8
+ import { Pathway } from '@hamak/shared-utils';
9
+ import { RemoteFsActionTypes } from '@hamak/ui-remote-fs-api';
10
+ import { rfsActions, } from '../actions/remote-fs-actions';
11
+ /**
12
+ * Create store sync middleware
13
+ *
14
+ * This middleware intercepts remote FS completion actions and synchronizes them
15
+ * to the Redux Store FileSystem. It handles:
16
+ * - LS_COMPLETED: Creates directories and file entries in Store FS
17
+ * - MKDIR_COMPLETED: Creates directory in Store FS
18
+ * - GET_COMPLETED: Creates/updates file content in Store FS
19
+ * - POST/PUT_COMPLETED: Reloads file content from remote
20
+ * - DELETE_COMPLETED: Removes node from Store FS
21
+ *
22
+ * @param config Middleware configuration
23
+ * @returns Redux middleware
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const middleware = createStoreSyncMiddleware({
28
+ * fileSystemAdapter: storeFs,
29
+ * pathTranslator: new PathTranslator(Pathway.ofRoot().resolve('remote')),
30
+ * autoReload: true
31
+ * });
32
+ * ```
33
+ */
34
+ export function createStoreSyncMiddleware(config) {
35
+ const { fileSystemAdapter, pathTranslator, autoReload = true, transformContent } = config;
36
+ const storeFsActions = fileSystemAdapter.getActions();
37
+ const storeSyncMiddleware = (store) => (next) => (action) => {
38
+ const result = next(action);
39
+ const anyAction = action;
40
+ // Only process remote FS actions
41
+ if (!rfsActions.isRemoteFsAction(anyAction)) {
42
+ return result;
43
+ }
44
+ const dispatch = store.dispatch;
45
+ switch (anyAction.type) {
46
+ case RemoteFsActionTypes.LS_COMPLETED: {
47
+ const completedAction = anyAction;
48
+ const { request, data } = completedAction.payload;
49
+ // Iterate through file list and create entries in Store FS
50
+ data?.forEach((fileInfo) => {
51
+ // Build local path: request path + file name
52
+ const localPath = Pathway.of(request.payload.path)
53
+ .resolve(fileInfo.name)
54
+ .getSegments();
55
+ if (fileInfo.isDirectory) {
56
+ // Create directory with parents flag
57
+ dispatch(storeFsActions.mkdir(localPath, true));
58
+ }
59
+ else {
60
+ // Create file entry without content (contentIsPresent: false)
61
+ dispatch(storeFsActions.setFile(localPath, undefined, 'xs:any', {
62
+ override: true,
63
+ contentIsPresent: false,
64
+ }));
65
+ }
66
+ });
67
+ break;
68
+ }
69
+ case RemoteFsActionTypes.MKDIR_COMPLETED: {
70
+ const completedAction = anyAction;
71
+ const { request } = completedAction.payload;
72
+ const localPath = Pathway.of(request.payload.path).getSegments();
73
+ // Create directory in Store FS
74
+ dispatch(storeFsActions.mkdir(localPath, true));
75
+ break;
76
+ }
77
+ case RemoteFsActionTypes.GET_COMPLETED: {
78
+ const completedAction = anyAction;
79
+ const { request, data } = completedAction.payload;
80
+ const localPath = Pathway.of(request.payload.path).getSegments();
81
+ // Parse content
82
+ let content = data.content === undefined || data.content === null
83
+ ? undefined
84
+ : data.content === ''
85
+ ? undefined
86
+ : JSON.parse(data.content);
87
+ // Apply content transform if provided
88
+ if (content !== undefined && transformContent) {
89
+ content = transformContent(content);
90
+ }
91
+ // Check if file exists in Store FS
92
+ const fileSystemNode = fileSystemAdapter.createSelector((state) => state.fileSystem, localPath)(store.getState());
93
+ if (fileSystemNode === undefined) {
94
+ // File doesn't exist, create it with content
95
+ dispatch(storeFsActions.setFile(localPath, content, 'xs:any', {
96
+ override: true,
97
+ contentIsPresent: true,
98
+ }));
99
+ }
100
+ else {
101
+ // File exists, update content only if it's a file
102
+ if (fileSystemNode?.type === 'file') {
103
+ dispatch(storeFsActions.setFileContent(localPath, content, true));
104
+ }
105
+ }
106
+ break;
107
+ }
108
+ case RemoteFsActionTypes.POST_COMPLETED:
109
+ case RemoteFsActionTypes.PUT_COMPLETED: {
110
+ const completedAction = anyAction;
111
+ const { request } = completedAction.payload;
112
+ const localPath = Pathway.of(request.payload.path).getSegments();
113
+ // Reload file content from remote if autoReload is enabled
114
+ if (autoReload) {
115
+ dispatch(rfsActions.ofGetRequest(localPath));
116
+ }
117
+ break;
118
+ }
119
+ case RemoteFsActionTypes.DELETE_COMPLETED: {
120
+ const completedAction = anyAction;
121
+ const { request } = completedAction.payload;
122
+ const localPath = Pathway.of(request.payload.path).getSegments();
123
+ // Remove node from Store FS
124
+ dispatch(storeFsActions.removeNode(localPath));
125
+ break;
126
+ }
127
+ default:
128
+ break;
129
+ }
130
+ return result;
131
+ };
132
+ return storeSyncMiddleware;
133
+ }
134
+ export default createStoreSyncMiddleware;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Remote FS Plugin Factory
3
+ */
4
+ export * from './remote-fs-plugin-factory';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,4BAA4B,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Remote FS Plugin Factory
3
+ */
4
+ export * from './remote-fs-plugin-factory';
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Remote FS Plugin Factory
3
+ *
4
+ * Creates a microkernel plugin for remote filesystem operations.
5
+ * Integrates HTTP-based remote filesystem with Redux Store FS.
6
+ */
7
+ import type { PluginModule } from '@hamak/microkernel-spi';
8
+ import type { Pathway } from '@hamak/shared-utils';
9
+ import { IWorkspaceClient, IPathTranslator } from '@hamak/ui-remote-fs-spi';
10
+ /**
11
+ * Configuration for Remote FS plugin
12
+ */
13
+ export interface RemoteFsPluginConfig {
14
+ /**
15
+ * Workspace identifier
16
+ */
17
+ workspaceId: string;
18
+ /**
19
+ * Mount point for remote filesystem
20
+ * This is the local path where remote files will be mounted
21
+ * @example Pathway.ofRoot().resolve('remote')
22
+ */
23
+ mountPoint: Pathway;
24
+ /**
25
+ * Base URL for the workspace API
26
+ * If not provided, defaults to current origin + '/api'
27
+ * @example 'http://localhost:3000/api'
28
+ */
29
+ baseUrl?: string;
30
+ /**
31
+ * Request timeout in milliseconds
32
+ * Default: 30000 (30 seconds)
33
+ */
34
+ timeout?: number;
35
+ /**
36
+ * Whether to automatically reload file content after PUT/POST
37
+ * Default: true
38
+ */
39
+ autoReload?: boolean;
40
+ /**
41
+ * Optional transform function for file content before storing
42
+ */
43
+ transformContent?: (content: any) => any;
44
+ /**
45
+ * Enable development logging
46
+ * Default: false
47
+ */
48
+ debug?: boolean;
49
+ /**
50
+ * Custom workspace client (for testing or advanced scenarios)
51
+ */
52
+ customClient?: IWorkspaceClient;
53
+ /**
54
+ * Custom path translator (for advanced scenarios)
55
+ */
56
+ customPathTranslator?: IPathTranslator;
57
+ }
58
+ /**
59
+ * Create Remote FS plugin
60
+ *
61
+ * This plugin provides remote filesystem capabilities through HTTP API.
62
+ * It registers two middleware:
63
+ * - Remote FS Middleware: Handles remote operations via HTTP client
64
+ * - Store Sync Middleware: Synchronizes remote data to Redux Store FS
65
+ *
66
+ * @param config Plugin configuration
67
+ * @returns PluginModule for microkernel integration
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * import { Pathway } from '@hamak/shared-utils';
72
+ * import { createRemoteFsPlugin } from '@hamak/ui-remote-fs-impl';
73
+ *
74
+ * const plugin = createRemoteFsPlugin({
75
+ * workspaceId: '0',
76
+ * mountPoint: Pathway.ofRoot().resolve('remote'),
77
+ * baseUrl: 'http://localhost:3000/api',
78
+ * autoReload: true
79
+ * });
80
+ * ```
81
+ */
82
+ export declare function createRemoteFsPlugin(config: RemoteFsPluginConfig): PluginModule;
83
+ export default createRemoteFsPlugin;
84
+ //# sourceMappingURL=remote-fs-plugin-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-fs-plugin-factory.d.ts","sourceRoot":"","sources":["../../src/plugin/remote-fs-plugin-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAMnD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAkB,MAAM,yBAAyB,CAAC;AAU5F;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,GAAG,CAAC;IAEzC;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAEhC;;OAEG;IACH,oBAAoB,CAAC,EAAE,eAAe,CAAC;CACxC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,YAAY,CAkI/E;AAED,eAAe,oBAAoB,CAAC"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Remote FS Plugin Factory
3
+ *
4
+ * Creates a microkernel plugin for remote filesystem operations.
5
+ * Integrates HTTP-based remote filesystem with Redux Store FS.
6
+ */
7
+ import { WORKSPACE_CLIENT_TOKEN, PATH_TRANSLATOR_TOKEN, } from '@hamak/ui-remote-fs-api';
8
+ import { PathTranslator } from '@hamak/ui-remote-fs-spi';
9
+ import { HttpWorkspaceClient } from '../providers/http-workspace-client';
10
+ import { createRemoteFsMiddleware } from '../middleware/remote-fs-middleware';
11
+ import { createStoreSyncMiddleware } from '../middleware/store-sync-middleware';
12
+ import { STORE_MANAGER_TOKEN, STORE_EXTENSIONS_TOKEN, } from '@hamak/ui-store-api';
13
+ /**
14
+ * Create Remote FS plugin
15
+ *
16
+ * This plugin provides remote filesystem capabilities through HTTP API.
17
+ * It registers two middleware:
18
+ * - Remote FS Middleware: Handles remote operations via HTTP client
19
+ * - Store Sync Middleware: Synchronizes remote data to Redux Store FS
20
+ *
21
+ * @param config Plugin configuration
22
+ * @returns PluginModule for microkernel integration
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * import { Pathway } from '@hamak/shared-utils';
27
+ * import { createRemoteFsPlugin } from '@hamak/ui-remote-fs-impl';
28
+ *
29
+ * const plugin = createRemoteFsPlugin({
30
+ * workspaceId: '0',
31
+ * mountPoint: Pathway.ofRoot().resolve('remote'),
32
+ * baseUrl: 'http://localhost:3000/api',
33
+ * autoReload: true
34
+ * });
35
+ * ```
36
+ */
37
+ export function createRemoteFsPlugin(config) {
38
+ let workspaceClient;
39
+ let pathTranslator;
40
+ let storeManager;
41
+ const log = (message, ...args) => {
42
+ if (config.debug) {
43
+ console.log(`[ui-remote-fs] ${message}`, ...args);
44
+ }
45
+ };
46
+ return {
47
+ async initialize(ctx) {
48
+ log('Initializing plugin...');
49
+ // Create or use custom workspace client
50
+ if (config.customClient) {
51
+ workspaceClient = config.customClient;
52
+ log('Using custom workspace client');
53
+ }
54
+ else {
55
+ const clientConfig = {
56
+ workspaceId: config.workspaceId,
57
+ baseUrl: config.baseUrl,
58
+ timeout: config.timeout,
59
+ };
60
+ workspaceClient = new HttpWorkspaceClient(clientConfig);
61
+ log('Created HTTP workspace client', { baseUrl: config.baseUrl, workspaceId: config.workspaceId });
62
+ }
63
+ // Create or use custom path translator
64
+ if (config.customPathTranslator) {
65
+ pathTranslator = config.customPathTranslator;
66
+ log('Using custom path translator');
67
+ }
68
+ else {
69
+ pathTranslator = new PathTranslator(config.mountPoint);
70
+ log('Created path translator', { mountPoint: config.mountPoint.getSegments() });
71
+ }
72
+ // Register services via DI
73
+ ctx.provide({ provide: WORKSPACE_CLIENT_TOKEN, useValue: workspaceClient });
74
+ ctx.provide({ provide: PATH_TRANSLATOR_TOKEN, useValue: pathTranslator });
75
+ // Note: IRemoteFsService implementation will be added in future phases
76
+ // ctx.provide({ provide: REMOTE_FS_SERVICE_TOKEN, useValue: remoteFsService });
77
+ log('Plugin initialized');
78
+ },
79
+ async activate(ctx) {
80
+ log('Activating plugin...');
81
+ // Resolve store manager from DI
82
+ try {
83
+ storeManager = ctx.resolve(STORE_MANAGER_TOKEN);
84
+ }
85
+ catch (error) {
86
+ throw new Error('[ui-remote-fs] Store manager not found. Ensure @hamak/ui-store plugin is loaded before ui-remote-fs.');
87
+ }
88
+ // Get file system adapter from store
89
+ const fileSystemAdapter = storeManager.getFileSystemAdapter();
90
+ if (!fileSystemAdapter) {
91
+ throw new Error('[ui-remote-fs] File system adapter not found in store manager.');
92
+ }
93
+ // Get store extensions collector
94
+ const extensionsCollector = ctx.resolve(STORE_EXTENSIONS_TOKEN);
95
+ // Create and register remote FS middleware
96
+ const remoteFsMiddleware = createRemoteFsMiddleware({
97
+ client: workspaceClient,
98
+ pathTranslator,
99
+ onError: (error, action) => {
100
+ log('Remote FS error:', error, action);
101
+ ctx.hooks.emit('ui-remote-fs:error', { error, action });
102
+ },
103
+ onSuccess: (result, action) => {
104
+ log('Remote FS success:', action.type);
105
+ ctx.hooks.emit('ui-remote-fs:success', { result, action });
106
+ },
107
+ });
108
+ // Create and register store sync middleware
109
+ const storeSyncMiddleware = createStoreSyncMiddleware({
110
+ fileSystemAdapter,
111
+ pathTranslator,
112
+ autoReload: config.autoReload,
113
+ transformContent: config.transformContent,
114
+ });
115
+ // Register middleware with store extensions
116
+ const middlewareExtensions = [
117
+ {
118
+ id: 'remote-fs',
119
+ middleware: remoteFsMiddleware,
120
+ priority: 100,
121
+ plugin: 'ui-remote-fs',
122
+ description: 'Handles remote filesystem operations via HTTP',
123
+ },
124
+ {
125
+ id: 'store-sync',
126
+ middleware: storeSyncMiddleware,
127
+ priority: 50,
128
+ plugin: 'ui-remote-fs',
129
+ description: 'Synchronizes remote FS to Redux Store FS',
130
+ },
131
+ ];
132
+ extensionsCollector.register('ui-remote-fs:middleware', {
133
+ middleware: middlewareExtensions,
134
+ });
135
+ log('Middleware registered');
136
+ // Emit ready event
137
+ ctx.hooks.emit('ui-remote-fs:ready', {
138
+ workspaceClient,
139
+ pathTranslator,
140
+ mountPoint: config.mountPoint,
141
+ });
142
+ log('Plugin activated');
143
+ },
144
+ async deactivate() {
145
+ log('Plugin deactivated');
146
+ // Cleanup if needed
147
+ },
148
+ };
149
+ }
150
+ export default createRemoteFsPlugin;
@@ -0,0 +1,99 @@
1
+ /**
2
+ * HTTP Workspace Client
3
+ *
4
+ * HTTP-based implementation of IWorkspaceClient using Axios.
5
+ * Migrated from amk/libs/server/ws/ws-client/src/lib/server-ws-ws-client.ts
6
+ */
7
+ import { AxiosInstance } from 'axios';
8
+ import { IWorkspaceClient } from '@hamak/ui-remote-fs-spi';
9
+ import { FileInfo } from '@hamak/shared-utils';
10
+ /**
11
+ * Configuration for HTTP workspace client
12
+ */
13
+ export interface HttpWorkspaceClientConfig {
14
+ /**
15
+ * Base URL for the API (e.g., 'http://localhost:3000/api')
16
+ * If not provided, defaults to current origin + '/api'
17
+ */
18
+ baseUrl?: string;
19
+ /**
20
+ * Workspace identifier
21
+ */
22
+ workspaceId: string;
23
+ /**
24
+ * Request timeout in milliseconds
25
+ * Default: 30000 (30 seconds)
26
+ */
27
+ timeout?: number;
28
+ /**
29
+ * Custom axios instance (for advanced configuration)
30
+ */
31
+ axiosInstance?: AxiosInstance;
32
+ }
33
+ /**
34
+ * HTTP-based implementation of IWorkspaceClient
35
+ *
36
+ * This implementation uses Axios to communicate with a REST API backend.
37
+ * Supports configurable base URL, timeout, and custom axios instances.
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const client = new HttpWorkspaceClient({
42
+ * workspaceId: '0',
43
+ * baseUrl: 'http://localhost:3000/api'
44
+ * });
45
+ *
46
+ * const files = await client.listFiles(['folder', 'subfolder']);
47
+ * ```
48
+ */
49
+ export declare class HttpWorkspaceClient implements IWorkspaceClient {
50
+ private readonly workspaceId;
51
+ private readonly baseUrl;
52
+ private readonly axios;
53
+ constructor(config: HttpWorkspaceClientConfig);
54
+ /**
55
+ * Format path segments to URL path string
56
+ */
57
+ private formatPath;
58
+ /**
59
+ * Handle axios errors and convert to ErrorObject
60
+ */
61
+ private handleError;
62
+ /**
63
+ * Serialize content to string for transmission
64
+ */
65
+ private serializeContent;
66
+ /**
67
+ * List files and directories at the specified path
68
+ */
69
+ listFiles(path: string[]): Promise<FileInfo[]>;
70
+ /**
71
+ * Create a directory at the specified path
72
+ */
73
+ createDirectory(path: string[]): Promise<FileInfo>;
74
+ /**
75
+ * Read a file's metadata and content
76
+ */
77
+ readFile(path: string[]): Promise<FileInfo>;
78
+ /**
79
+ * Write or update a file's content (uses PUT method)
80
+ */
81
+ putFile(path: string[], content: any): Promise<FileInfo>;
82
+ /**
83
+ * Delete a file or directory
84
+ */
85
+ deleteFile(path: string[]): Promise<FileInfo>;
86
+ /**
87
+ * Get the workspace ID
88
+ */
89
+ getWorkspaceId(): string;
90
+ /**
91
+ * Get the base URL
92
+ */
93
+ getBaseUrl(): string;
94
+ }
95
+ /**
96
+ * Factory function to create HTTP workspace client with default configuration
97
+ */
98
+ export declare function createHttpWorkspaceClient(workspaceId: string, baseUrl?: string): HttpWorkspaceClient;
99
+ //# sourceMappingURL=http-workspace-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-workspace-client.d.ts","sourceRoot":"","sources":["../../src/providers/http-workspace-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAc,EAAE,aAAa,EAAc,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,mBAAoB,YAAW,gBAAgB;IAC1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;gBAE1B,MAAM,EAAE,yBAAyB;IAmB7C;;OAEG;IACH,OAAO,CAAC,UAAU;IAIlB;;OAEG;IACH,OAAO,CAAC,WAAW;IA6BnB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAYpD;;OAEG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;IAYxD;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;IAYjD;;OAEG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;IAc9D;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;IAYnD;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,UAAU,IAAI,MAAM;CAGrB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,GACf,mBAAmB,CAKrB"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * HTTP Workspace Client
3
+ *
4
+ * HTTP-based implementation of IWorkspaceClient using Axios.
5
+ * Migrated from amk/libs/server/ws/ws-client/src/lib/server-ws-ws-client.ts
6
+ */
7
+ import axios from 'axios';
8
+ /**
9
+ * HTTP-based implementation of IWorkspaceClient
10
+ *
11
+ * This implementation uses Axios to communicate with a REST API backend.
12
+ * Supports configurable base URL, timeout, and custom axios instances.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const client = new HttpWorkspaceClient({
17
+ * workspaceId: '0',
18
+ * baseUrl: 'http://localhost:3000/api'
19
+ * });
20
+ *
21
+ * const files = await client.listFiles(['folder', 'subfolder']);
22
+ * ```
23
+ */
24
+ export class HttpWorkspaceClient {
25
+ constructor(config) {
26
+ this.workspaceId = config.workspaceId;
27
+ // Default base URL to current origin if not provided
28
+ this.baseUrl = config.baseUrl ||
29
+ (typeof globalThis !== 'undefined' && 'location' in globalThis
30
+ ? `${globalThis.location.protocol}//${globalThis.location.host}/api`
31
+ : '/api');
32
+ // Use provided axios instance or create new one
33
+ this.axios = config.axiosInstance || axios.create({
34
+ baseURL: this.baseUrl,
35
+ timeout: config.timeout || 30000,
36
+ headers: {
37
+ 'Content-Type': 'application/json',
38
+ },
39
+ });
40
+ }
41
+ /**
42
+ * Format path segments to URL path string
43
+ */
44
+ formatPath(path) {
45
+ return path.join('/');
46
+ }
47
+ /**
48
+ * Handle axios errors and convert to ErrorObject
49
+ */
50
+ handleError(error) {
51
+ if (axios.isAxiosError(error)) {
52
+ const axiosError = error;
53
+ // Try to extract error from response
54
+ if (axiosError.response?.data?.error) {
55
+ throw axiosError.response.data.error;
56
+ }
57
+ // Create error from axios error
58
+ const errorObj = {
59
+ code: axiosError.code || 'UNKNOWN',
60
+ message: axiosError.message || 'Unknown error occurred',
61
+ params: {
62
+ status: axiosError.response?.status,
63
+ statusText: axiosError.response?.statusText,
64
+ },
65
+ };
66
+ throw errorObj;
67
+ }
68
+ // Handle non-axios errors
69
+ const errorObj = {
70
+ code: 'UNKNOWN',
71
+ message: error instanceof Error ? error.message : 'Unknown error occurred',
72
+ };
73
+ throw errorObj;
74
+ }
75
+ /**
76
+ * Serialize content to string for transmission
77
+ */
78
+ serializeContent(content) {
79
+ if (typeof content === 'string') {
80
+ return content;
81
+ }
82
+ return JSON.stringify(content);
83
+ }
84
+ /**
85
+ * List files and directories at the specified path
86
+ */
87
+ async listFiles(path) {
88
+ try {
89
+ const formattedPath = this.formatPath(path);
90
+ const response = await this.axios.get(`/workspaces/${this.workspaceId}/files/${formattedPath}`);
91
+ return response.data;
92
+ }
93
+ catch (error) {
94
+ this.handleError(error);
95
+ }
96
+ }
97
+ /**
98
+ * Create a directory at the specified path
99
+ */
100
+ async createDirectory(path) {
101
+ try {
102
+ const formattedPath = this.formatPath(path);
103
+ const response = await this.axios.post(`/workspaces/${this.workspaceId}/mkdir/${formattedPath}`);
104
+ return response.data;
105
+ }
106
+ catch (error) {
107
+ this.handleError(error);
108
+ }
109
+ }
110
+ /**
111
+ * Read a file's metadata and content
112
+ */
113
+ async readFile(path) {
114
+ try {
115
+ const formattedPath = this.formatPath(path);
116
+ const response = await this.axios.get(`/workspaces/${this.workspaceId}/read/${formattedPath}`);
117
+ return response.data;
118
+ }
119
+ catch (error) {
120
+ this.handleError(error);
121
+ }
122
+ }
123
+ /**
124
+ * Write or update a file's content (uses PUT method)
125
+ */
126
+ async putFile(path, content) {
127
+ try {
128
+ const formattedPath = this.formatPath(path);
129
+ const serializedContent = this.serializeContent(content);
130
+ const response = await this.axios.put(`/workspaces/${this.workspaceId}/put/${formattedPath}`, { content: serializedContent });
131
+ return response.data;
132
+ }
133
+ catch (error) {
134
+ this.handleError(error);
135
+ }
136
+ }
137
+ /**
138
+ * Delete a file or directory
139
+ */
140
+ async deleteFile(path) {
141
+ try {
142
+ const formattedPath = this.formatPath(path);
143
+ const response = await this.axios.delete(`/workspaces/${this.workspaceId}/delete/${formattedPath}`);
144
+ return response.data;
145
+ }
146
+ catch (error) {
147
+ this.handleError(error);
148
+ }
149
+ }
150
+ /**
151
+ * Get the workspace ID
152
+ */
153
+ getWorkspaceId() {
154
+ return this.workspaceId;
155
+ }
156
+ /**
157
+ * Get the base URL
158
+ */
159
+ getBaseUrl() {
160
+ return this.baseUrl;
161
+ }
162
+ }
163
+ /**
164
+ * Factory function to create HTTP workspace client with default configuration
165
+ */
166
+ export function createHttpWorkspaceClient(workspaceId, baseUrl) {
167
+ return new HttpWorkspaceClient({
168
+ workspaceId,
169
+ baseUrl,
170
+ });
171
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Remote FS Providers
3
+ */
4
+ export * from './http-workspace-client';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Remote FS Providers
3
+ */
4
+ export * from './http-workspace-client';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Remote FS Services
3
+ */
4
+ export * from './remote-fs-service';
5
+ //# sourceMappingURL=index.d.ts.map