@fnndsc/salsa 3.21.1 → 3.21.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/dist/vfs/dispatcher.d.ts +14 -140
- package/dist/vfs/dispatcher.js +21 -297
- package/dist/vfs/dispatcher.js.map +1 -1
- package/dist/vfs/provider.d.ts +5 -117
- package/dist/vfs/provider.js +0 -8
- package/dist/vfs/provider.js.map +1 -1
- package/dist/vfs/sort.d.ts +2 -14
- package/dist/vfs/sort.js +5 -27
- package/dist/vfs/sort.js.map +1 -1
- package/package.json +3 -2
package/dist/vfs/dispatcher.d.ts
CHANGED
|
@@ -1,149 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file
|
|
2
|
+
* @file The ChRIS session's filesystem: fond's dispatcher with CUBE's mounts.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* fond's `VFSDispatcher` routes a path to the mount that owns it and knows no
|
|
5
|
+
* backend. `CubeVfsDispatcher` registers the ChRIS backend's mounts on it, in
|
|
6
|
+
* an order that matters only for equal-length prefixes (the sort is stable):
|
|
7
|
+
* PACS, `/etc`, the three `/proc` relations, and `/usr/share`. Everything no
|
|
8
|
+
* mount claims is a CUBE file, through the native provider. The engine adds
|
|
9
|
+
* its own static mounts (`/bin`, `/usr`, …) to the shared instance.
|
|
6
10
|
*
|
|
7
11
|
* @module
|
|
8
12
|
*/
|
|
9
|
-
import {
|
|
10
|
-
|
|
13
|
+
import { VFSDispatcher } from "@fnndsc/fond";
|
|
14
|
+
export { VFSDispatcher } from "@fnndsc/fond";
|
|
11
15
|
/**
|
|
12
|
-
*
|
|
16
|
+
* fond's dispatcher with the ChRIS backend's mounts registered, and CUBE's
|
|
17
|
+
* files as the fallback.
|
|
13
18
|
*/
|
|
14
|
-
export declare class VFSDispatcher {
|
|
15
|
-
private providers;
|
|
16
|
-
private defaultProvider;
|
|
17
|
-
private pathResolver?;
|
|
18
|
-
/**
|
|
19
|
-
* Initializes dispatcher and registers standard providers.
|
|
20
|
-
*/
|
|
19
|
+
export declare class CubeVfsDispatcher extends VFSDispatcher {
|
|
21
20
|
constructor();
|
|
22
|
-
/**
|
|
23
|
-
* Registers a path resolution hook that maps logical paths to physical paths.
|
|
24
|
-
*
|
|
25
|
-
* @param resolver - The resolver function mapping a logical path to a physical path.
|
|
26
|
-
*/
|
|
27
|
-
pathResolver_register(resolver: (path: string) => Promise<string>): void;
|
|
28
|
-
/**
|
|
29
|
-
* Registers a new VFS Provider.
|
|
30
|
-
*
|
|
31
|
-
* @param provider - The provider instance to register.
|
|
32
|
-
*/
|
|
33
|
-
provider_register(provider: VFSProvider): void;
|
|
34
|
-
/**
|
|
35
|
-
* Returns all registered providers (excluding the default native provider).
|
|
36
|
-
* Used by callers that need to detect parent-of-prefix paths.
|
|
37
|
-
*/
|
|
38
|
-
providers_get(): VFSProvider[];
|
|
39
|
-
/**
|
|
40
|
-
* Resolves the matching provider for a given virtual path.
|
|
41
|
-
*
|
|
42
|
-
* @param pathStr - The absolute virtual path.
|
|
43
|
-
* @returns The matching VFSProvider or the default native provider.
|
|
44
|
-
*/
|
|
45
|
-
provider_get(pathStr: string): VFSProvider;
|
|
46
|
-
/**
|
|
47
|
-
* Whether a path belongs to a projection rather than a real CUBE folder.
|
|
48
|
-
*
|
|
49
|
-
* A projection root (`/proc`, `/net/pacs`, `/etc`, `/usr/share`) is served
|
|
50
|
-
* by its own provider and has no folder of files behind it. Three shapes
|
|
51
|
-
* count as virtual: a path a non-native provider owns (at or under its
|
|
52
|
-
* prefix), and a path that is a strict ancestor of such a prefix (`/proc`
|
|
53
|
-
* above `/proc/jobs`, `/net` above `/net/pacs`) — its only children are
|
|
54
|
-
* the projections beneath it. The real root `/` is never virtual: it is
|
|
55
|
-
* the CUBE store's own root, which the native provider lists.
|
|
56
|
-
*
|
|
57
|
-
* The point of the question is to keep the raw CUBE-files layer from
|
|
58
|
-
* being asked to build a folder context for a path that has none — the
|
|
59
|
-
* request cannot succeed and only litters the error log, once per
|
|
60
|
-
* ancestor a path walk visits.
|
|
61
|
-
*
|
|
62
|
-
* @param pathStr - The absolute (or root-relative) path to classify.
|
|
63
|
-
* @returns True when a projection owns or is owned by the path.
|
|
64
|
-
*/
|
|
65
|
-
path_isVirtual(pathStr: string): boolean;
|
|
66
|
-
/**
|
|
67
|
-
* Dispatches directory listing to matched provider.
|
|
68
|
-
* Supports dynamic intermediate parent path synthesis for virtual prefixes.
|
|
69
|
-
*
|
|
70
|
-
* @param pathStr - The absolute virtual path to list.
|
|
71
|
-
* @param options - Sort controls.
|
|
72
|
-
* @returns Promise resolving to Result<VFSItem[]>.
|
|
73
|
-
*/
|
|
74
|
-
list(pathStr: string, options?: {
|
|
75
|
-
sort?: "name" | "size" | "date" | "owner";
|
|
76
|
-
reverse?: boolean;
|
|
77
|
-
}): Promise<Result<VFSItem[]>>;
|
|
78
|
-
/**
|
|
79
|
-
* Dispatches copy operation to matched provider.
|
|
80
|
-
*
|
|
81
|
-
* @param src - Source path.
|
|
82
|
-
* @param dest - Destination path.
|
|
83
|
-
* @param options - Copy options.
|
|
84
|
-
* @returns Promise resolving to success boolean.
|
|
85
|
-
*/
|
|
86
|
-
cp(src: string, dest: string, options: CpOptions): Promise<boolean>;
|
|
87
|
-
/**
|
|
88
|
-
* Dispatches file read operation to the matched provider.
|
|
89
|
-
*
|
|
90
|
-
* @param pathStr - The absolute virtual path of the file to read.
|
|
91
|
-
* @returns A Promise resolving to a Result containing the file contents as a string.
|
|
92
|
-
*/
|
|
93
|
-
read(pathStr: string): Promise<Result<string>>;
|
|
94
|
-
/**
|
|
95
|
-
* Dispatches a whole-file write to the matched provider: a projection
|
|
96
|
-
* that holds writable files (a feed's note) takes the content; any other
|
|
97
|
-
* path is refused by name rather than written somewhere it does not live.
|
|
98
|
-
*
|
|
99
|
-
* @param pathStr - The absolute virtual path of the file.
|
|
100
|
-
* @param content - The file's new content, whole.
|
|
101
|
-
* @returns True when the provider took it.
|
|
102
|
-
*/
|
|
103
|
-
/**
|
|
104
|
-
* Dispatches a folder's making to the matched provider; a projection that
|
|
105
|
-
* makes no folders refuses by name.
|
|
106
|
-
*
|
|
107
|
-
* @param pathStr - The absolute virtual path of the new folder.
|
|
108
|
-
* @returns True when the provider made it.
|
|
109
|
-
*/
|
|
110
|
-
mkdir(pathStr: string): Promise<boolean>;
|
|
111
|
-
/**
|
|
112
|
-
* Dispatches an empty folder's removal to the matched provider; a
|
|
113
|
-
* projection that removes no folders refuses by name.
|
|
114
|
-
*
|
|
115
|
-
* @param pathStr - The absolute virtual path of the folder.
|
|
116
|
-
* @returns True when the provider removed it.
|
|
117
|
-
*/
|
|
118
|
-
rmdir(pathStr: string): Promise<boolean>;
|
|
119
|
-
/**
|
|
120
|
-
* Dispatches a rename within one projection; a rename across providers, or
|
|
121
|
-
* in a projection that renames nothing, is refused by name.
|
|
122
|
-
*
|
|
123
|
-
* @param src - The absolute virtual path now.
|
|
124
|
-
* @param dest - The absolute virtual path it takes.
|
|
125
|
-
* @returns True when the provider renamed it.
|
|
126
|
-
*/
|
|
127
|
-
rename(src: string, dest: string): Promise<boolean>;
|
|
128
|
-
write(pathStr: string, content: string): Promise<boolean>;
|
|
129
|
-
/**
|
|
130
|
-
* Dispatches binary file read operation to the matched provider.
|
|
131
|
-
*
|
|
132
|
-
* @param pathStr - The absolute virtual path of the file to read.
|
|
133
|
-
* @returns A Promise resolving to a Result containing the file contents as a Buffer.
|
|
134
|
-
*/
|
|
135
|
-
readBinary(pathStr: string): Promise<Result<Buffer>>;
|
|
136
|
-
/**
|
|
137
|
-
* Resolves a lazy link through the provider that owns it.
|
|
138
|
-
*
|
|
139
|
-
* This is deliberately distinct from {@link list}: a structural traversal
|
|
140
|
-
* can display an unresolved link without causing its provider to fetch the
|
|
141
|
-
* target from a remote service.
|
|
142
|
-
*
|
|
143
|
-
* @param pathStr - Absolute path of the provider-defined link.
|
|
144
|
-
* @returns The resolved target path, or an error if unsupported or absent.
|
|
145
|
-
*/
|
|
146
|
-
linkTarget_resolve(pathStr: string): Promise<Result<string>>;
|
|
147
21
|
}
|
|
148
|
-
/**
|
|
149
|
-
export declare const vfsDispatcher:
|
|
22
|
+
/** The session's one filesystem dispatcher. */
|
|
23
|
+
export declare const vfsDispatcher: CubeVfsDispatcher;
|
package/dist/vfs/dispatcher.js
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* @file
|
|
3
|
+
* @file The ChRIS session's filesystem: fond's dispatcher with CUBE's mounts.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* fond's `VFSDispatcher` routes a path to the mount that owns it and knows no
|
|
6
|
+
* backend. `CubeVfsDispatcher` registers the ChRIS backend's mounts on it, in
|
|
7
|
+
* an order that matters only for equal-length prefixes (the sort is stable):
|
|
8
|
+
* PACS, `/etc`, the three `/proc` relations, and `/usr/share`. Everything no
|
|
9
|
+
* mount claims is a CUBE file, through the native provider. The engine adds
|
|
10
|
+
* its own static mounts (`/bin`, `/usr`, …) to the shared instance.
|
|
7
11
|
*
|
|
8
12
|
* @module
|
|
9
13
|
*/
|
|
10
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.vfsDispatcher = exports.VFSDispatcher = void 0;
|
|
12
|
-
const
|
|
15
|
+
exports.vfsDispatcher = exports.CubeVfsDispatcher = exports.VFSDispatcher = void 0;
|
|
16
|
+
const fond_1 = require("@fnndsc/fond");
|
|
13
17
|
const native_js_1 = require("./providers/native.js");
|
|
14
18
|
const pacs_js_1 = require("./providers/pacs.js");
|
|
15
19
|
const etc_js_1 = require("./providers/etc.js");
|
|
@@ -17,307 +21,27 @@ const proc_js_1 = require("./providers/proc.js");
|
|
|
17
21
|
const workflows_js_1 = require("./providers/workflows.js");
|
|
18
22
|
const procTags_js_1 = require("./providers/procTags.js");
|
|
19
23
|
const share_js_1 = require("./providers/share.js");
|
|
24
|
+
var fond_2 = require("@fnndsc/fond");
|
|
25
|
+
Object.defineProperty(exports, "VFSDispatcher", { enumerable: true, get: function () { return fond_2.VFSDispatcher; } });
|
|
20
26
|
/**
|
|
21
|
-
*
|
|
27
|
+
* fond's dispatcher with the ChRIS backend's mounts registered, and CUBE's
|
|
28
|
+
* files as the fallback.
|
|
22
29
|
*/
|
|
23
|
-
class VFSDispatcher {
|
|
24
|
-
providers = [];
|
|
25
|
-
defaultProvider;
|
|
26
|
-
pathResolver;
|
|
27
|
-
/**
|
|
28
|
-
* Initializes dispatcher and registers standard providers.
|
|
29
|
-
*/
|
|
30
|
+
class CubeVfsDispatcher extends fond_1.VFSDispatcher {
|
|
30
31
|
constructor() {
|
|
31
|
-
|
|
32
|
+
super(new native_js_1.NativeVfsProvider());
|
|
32
33
|
this.provider_register(new pacs_js_1.PacsVfsProvider());
|
|
33
34
|
this.provider_register(new etc_js_1.EtcVfsProvider());
|
|
34
35
|
this.provider_register(new proc_js_1.ProcVfsProvider());
|
|
35
|
-
// Three relations CUBE owns
|
|
36
|
-
//
|
|
37
|
-
//
|
|
36
|
+
// Three relations CUBE owns: the tags a feed can carry, the runs a
|
|
37
|
+
// pipeline produced, and what is known about a plugin as opposed to how
|
|
38
|
+
// to invoke it.
|
|
38
39
|
this.provider_register(new workflows_js_1.WorkflowsVfsProvider());
|
|
39
40
|
this.provider_register(new procTags_js_1.ProcTagsVfsProvider());
|
|
40
41
|
this.provider_register(new share_js_1.ShareVfsProvider());
|
|
41
42
|
}
|
|
42
|
-
/**
|
|
43
|
-
* Registers a path resolution hook that maps logical paths to physical paths.
|
|
44
|
-
*
|
|
45
|
-
* @param resolver - The resolver function mapping a logical path to a physical path.
|
|
46
|
-
*/
|
|
47
|
-
pathResolver_register(resolver) {
|
|
48
|
-
this.pathResolver = resolver;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Registers a new VFS Provider.
|
|
52
|
-
*
|
|
53
|
-
* @param provider - The provider instance to register.
|
|
54
|
-
*/
|
|
55
|
-
provider_register(provider) {
|
|
56
|
-
this.providers.push(provider);
|
|
57
|
-
// Sort by prefix length descending to match most specific prefix first
|
|
58
|
-
this.providers.sort((a, b) => b.prefix.length - a.prefix.length);
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Returns all registered providers (excluding the default native provider).
|
|
62
|
-
* Used by callers that need to detect parent-of-prefix paths.
|
|
63
|
-
*/
|
|
64
|
-
providers_get() {
|
|
65
|
-
return [...this.providers];
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Resolves the matching provider for a given virtual path.
|
|
69
|
-
*
|
|
70
|
-
* @param pathStr - The absolute virtual path.
|
|
71
|
-
* @returns The matching VFSProvider or the default native provider.
|
|
72
|
-
*/
|
|
73
|
-
provider_get(pathStr) {
|
|
74
|
-
const absolutePath = pathStr.startsWith("/") ? pathStr : "/" + pathStr;
|
|
75
|
-
const match = this.providers.find((p) => absolutePath === p.prefix || absolutePath.startsWith(p.prefix + "/"));
|
|
76
|
-
return match || this.defaultProvider;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Whether a path belongs to a projection rather than a real CUBE folder.
|
|
80
|
-
*
|
|
81
|
-
* A projection root (`/proc`, `/net/pacs`, `/etc`, `/usr/share`) is served
|
|
82
|
-
* by its own provider and has no folder of files behind it. Three shapes
|
|
83
|
-
* count as virtual: a path a non-native provider owns (at or under its
|
|
84
|
-
* prefix), and a path that is a strict ancestor of such a prefix (`/proc`
|
|
85
|
-
* above `/proc/jobs`, `/net` above `/net/pacs`) — its only children are
|
|
86
|
-
* the projections beneath it. The real root `/` is never virtual: it is
|
|
87
|
-
* the CUBE store's own root, which the native provider lists.
|
|
88
|
-
*
|
|
89
|
-
* The point of the question is to keep the raw CUBE-files layer from
|
|
90
|
-
* being asked to build a folder context for a path that has none — the
|
|
91
|
-
* request cannot succeed and only litters the error log, once per
|
|
92
|
-
* ancestor a path walk visits.
|
|
93
|
-
*
|
|
94
|
-
* @param pathStr - The absolute (or root-relative) path to classify.
|
|
95
|
-
* @returns True when a projection owns or is owned by the path.
|
|
96
|
-
*/
|
|
97
|
-
path_isVirtual(pathStr) {
|
|
98
|
-
const absolutePath = pathStr.startsWith("/") ? pathStr : "/" + pathStr;
|
|
99
|
-
const clean = absolutePath.length > 1 && absolutePath.endsWith("/") ? absolutePath.slice(0, -1) : absolutePath;
|
|
100
|
-
if (clean === "/")
|
|
101
|
-
return false;
|
|
102
|
-
return this.providers.some((p) => p.prefix.length > 0 &&
|
|
103
|
-
(clean === p.prefix || clean.startsWith(p.prefix + "/") || p.prefix.startsWith(clean + "/")));
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Dispatches directory listing to matched provider.
|
|
107
|
-
* Supports dynamic intermediate parent path synthesis for virtual prefixes.
|
|
108
|
-
*
|
|
109
|
-
* @param pathStr - The absolute virtual path to list.
|
|
110
|
-
* @param options - Sort controls.
|
|
111
|
-
* @returns Promise resolving to Result<VFSItem[]>.
|
|
112
|
-
*/
|
|
113
|
-
async list(pathStr, options) {
|
|
114
|
-
const absolutePath = pathStr.startsWith("/") ? pathStr : "/" + pathStr;
|
|
115
|
-
const cleanPath = absolutePath.endsWith("/") && absolutePath.length > 1 ? absolutePath.slice(0, -1) : absolutePath;
|
|
116
|
-
// Check if cleanPath is a parent of any registered provider's prefix
|
|
117
|
-
const prefixParent = cleanPath === "/" ? "/" : cleanPath + "/";
|
|
118
|
-
const children = this.providers.filter((p) => p.prefix.startsWith(prefixParent));
|
|
119
|
-
if (children.length > 0) {
|
|
120
|
-
const segmentIndex = cleanPath === "/" ? 1 : cleanPath.split("/").length;
|
|
121
|
-
const virtualSubdirs = new Set();
|
|
122
|
-
for (const p of children) {
|
|
123
|
-
const segments = p.prefix.split("/");
|
|
124
|
-
const nextSegment = segments[segmentIndex];
|
|
125
|
-
if (nextSegment) {
|
|
126
|
-
virtualSubdirs.add(nextSegment);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (virtualSubdirs.size > 0) {
|
|
130
|
-
const vfsItems = Array.from(virtualSubdirs).map((name) => ({
|
|
131
|
-
name,
|
|
132
|
-
type: "vfs",
|
|
133
|
-
size: 0,
|
|
134
|
-
owner: "root",
|
|
135
|
-
date: new Date().toISOString(),
|
|
136
|
-
}));
|
|
137
|
-
// Query the default provider to see if there are any native items in this folder
|
|
138
|
-
let resolvedPathStr = pathStr;
|
|
139
|
-
if (this.pathResolver) {
|
|
140
|
-
try {
|
|
141
|
-
resolvedPathStr = await this.pathResolver(pathStr);
|
|
142
|
-
}
|
|
143
|
-
catch (e) {
|
|
144
|
-
// Deliberate absorption: for a read-only listing, the logical
|
|
145
|
-
// path is a valid fallback (the provider lists what it can);
|
|
146
|
-
// contrast cp(), where a guessed path could write wrongly.
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
const nativeResult = await this.defaultProvider.list(resolvedPathStr, options);
|
|
150
|
-
if (nativeResult.ok && nativeResult.value) {
|
|
151
|
-
const nativeItems = nativeResult.value;
|
|
152
|
-
for (const item of nativeItems) {
|
|
153
|
-
if (!virtualSubdirs.has(item.name)) {
|
|
154
|
-
vfsItems.push(item);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
return (0, cumin_1.Ok)(vfsItems);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
const provider = this.provider_get(pathStr);
|
|
162
|
-
if (provider === this.defaultProvider && this.pathResolver) {
|
|
163
|
-
try {
|
|
164
|
-
const resolvedPath = await this.pathResolver(pathStr);
|
|
165
|
-
return provider.list(resolvedPath, options);
|
|
166
|
-
}
|
|
167
|
-
catch (e) {
|
|
168
|
-
// Deliberate absorption: same read-only-listing rationale as above.
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return provider.list(pathStr, options);
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Dispatches copy operation to matched provider.
|
|
175
|
-
*
|
|
176
|
-
* @param src - Source path.
|
|
177
|
-
* @param dest - Destination path.
|
|
178
|
-
* @param options - Copy options.
|
|
179
|
-
* @returns Promise resolving to success boolean.
|
|
180
|
-
*/
|
|
181
|
-
async cp(src, dest, options) {
|
|
182
|
-
const provider = this.provider_get(src);
|
|
183
|
-
if (provider === this.defaultProvider && this.pathResolver) {
|
|
184
|
-
// A copy must never proceed on a guessed path: an unresolved source
|
|
185
|
-
// copies the wrong thing, an unresolved destination writes to the wrong
|
|
186
|
-
// place. Resolution failure fails the copy.
|
|
187
|
-
let resolvedSrc;
|
|
188
|
-
let resolvedDest;
|
|
189
|
-
try {
|
|
190
|
-
resolvedSrc = await this.pathResolver(src);
|
|
191
|
-
}
|
|
192
|
-
catch (e) {
|
|
193
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
194
|
-
cumin_1.errorStack.stack_push("error", `cp: cannot resolve source path ${src}: ${msg}`);
|
|
195
|
-
return false;
|
|
196
|
-
}
|
|
197
|
-
try {
|
|
198
|
-
resolvedDest = await this.pathResolver(dest);
|
|
199
|
-
}
|
|
200
|
-
catch (e) {
|
|
201
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
202
|
-
cumin_1.errorStack.stack_push("error", `cp: cannot resolve destination path ${dest}: ${msg}`);
|
|
203
|
-
return false;
|
|
204
|
-
}
|
|
205
|
-
return provider.cp(resolvedSrc, resolvedDest, options);
|
|
206
|
-
}
|
|
207
|
-
return provider.cp(src, dest, options);
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Dispatches file read operation to the matched provider.
|
|
211
|
-
*
|
|
212
|
-
* @param pathStr - The absolute virtual path of the file to read.
|
|
213
|
-
* @returns A Promise resolving to a Result containing the file contents as a string.
|
|
214
|
-
*/
|
|
215
|
-
async read(pathStr) {
|
|
216
|
-
const provider = this.provider_get(pathStr);
|
|
217
|
-
if (provider !== this.defaultProvider && provider.read) {
|
|
218
|
-
return provider.read(pathStr);
|
|
219
|
-
}
|
|
220
|
-
cumin_1.errorStack.stack_push("error", `File read not supported for path: ${pathStr}`);
|
|
221
|
-
return (0, cumin_1.Err)();
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Dispatches a whole-file write to the matched provider: a projection
|
|
225
|
-
* that holds writable files (a feed's note) takes the content; any other
|
|
226
|
-
* path is refused by name rather than written somewhere it does not live.
|
|
227
|
-
*
|
|
228
|
-
* @param pathStr - The absolute virtual path of the file.
|
|
229
|
-
* @param content - The file's new content, whole.
|
|
230
|
-
* @returns True when the provider took it.
|
|
231
|
-
*/
|
|
232
|
-
/**
|
|
233
|
-
* Dispatches a folder's making to the matched provider; a projection that
|
|
234
|
-
* makes no folders refuses by name.
|
|
235
|
-
*
|
|
236
|
-
* @param pathStr - The absolute virtual path of the new folder.
|
|
237
|
-
* @returns True when the provider made it.
|
|
238
|
-
*/
|
|
239
|
-
async mkdir(pathStr) {
|
|
240
|
-
const provider = this.provider_get(pathStr);
|
|
241
|
-
if (provider !== this.defaultProvider && provider.mkdir)
|
|
242
|
-
return provider.mkdir(pathStr);
|
|
243
|
-
cumin_1.errorStack.stack_push("error", `mkdir: cannot create directory '${pathStr}': Read-only file system`);
|
|
244
|
-
return false;
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Dispatches an empty folder's removal to the matched provider; a
|
|
248
|
-
* projection that removes no folders refuses by name.
|
|
249
|
-
*
|
|
250
|
-
* @param pathStr - The absolute virtual path of the folder.
|
|
251
|
-
* @returns True when the provider removed it.
|
|
252
|
-
*/
|
|
253
|
-
async rmdir(pathStr) {
|
|
254
|
-
const provider = this.provider_get(pathStr);
|
|
255
|
-
if (provider !== this.defaultProvider && provider.rmdir)
|
|
256
|
-
return provider.rmdir(pathStr);
|
|
257
|
-
cumin_1.errorStack.stack_push("error", `rmdir: failed to remove '${pathStr}': Read-only file system`);
|
|
258
|
-
return false;
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Dispatches a rename within one projection; a rename across providers, or
|
|
262
|
-
* in a projection that renames nothing, is refused by name.
|
|
263
|
-
*
|
|
264
|
-
* @param src - The absolute virtual path now.
|
|
265
|
-
* @param dest - The absolute virtual path it takes.
|
|
266
|
-
* @returns True when the provider renamed it.
|
|
267
|
-
*/
|
|
268
|
-
async rename(src, dest) {
|
|
269
|
-
const provider = this.provider_get(src);
|
|
270
|
-
if (provider !== this.provider_get(dest)) {
|
|
271
|
-
cumin_1.errorStack.stack_push("error", `mv: cannot move '${src}' to '${dest}': Invalid cross-device link`);
|
|
272
|
-
return false;
|
|
273
|
-
}
|
|
274
|
-
if (provider !== this.defaultProvider && provider.rename)
|
|
275
|
-
return provider.rename(src, dest);
|
|
276
|
-
cumin_1.errorStack.stack_push("error", `mv: cannot move '${src}': Read-only file system`);
|
|
277
|
-
return false;
|
|
278
|
-
}
|
|
279
|
-
async write(pathStr, content) {
|
|
280
|
-
const provider = this.provider_get(pathStr);
|
|
281
|
-
if (provider !== this.defaultProvider && provider.write) {
|
|
282
|
-
return provider.write(pathStr, content);
|
|
283
|
-
}
|
|
284
|
-
cumin_1.errorStack.stack_push("error", `File write not supported for path: ${pathStr}`);
|
|
285
|
-
return false;
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Dispatches binary file read operation to the matched provider.
|
|
289
|
-
*
|
|
290
|
-
* @param pathStr - The absolute virtual path of the file to read.
|
|
291
|
-
* @returns A Promise resolving to a Result containing the file contents as a Buffer.
|
|
292
|
-
*/
|
|
293
|
-
async readBinary(pathStr) {
|
|
294
|
-
const provider = this.provider_get(pathStr);
|
|
295
|
-
if (provider !== this.defaultProvider && provider.readBinary) {
|
|
296
|
-
return provider.readBinary(pathStr);
|
|
297
|
-
}
|
|
298
|
-
cumin_1.errorStack.stack_push("error", `Binary file read not supported for path: ${pathStr}`);
|
|
299
|
-
return (0, cumin_1.Err)();
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Resolves a lazy link through the provider that owns it.
|
|
303
|
-
*
|
|
304
|
-
* This is deliberately distinct from {@link list}: a structural traversal
|
|
305
|
-
* can display an unresolved link without causing its provider to fetch the
|
|
306
|
-
* target from a remote service.
|
|
307
|
-
*
|
|
308
|
-
* @param pathStr - Absolute path of the provider-defined link.
|
|
309
|
-
* @returns The resolved target path, or an error if unsupported or absent.
|
|
310
|
-
*/
|
|
311
|
-
async linkTarget_resolve(pathStr) {
|
|
312
|
-
const provider = this.provider_get(pathStr);
|
|
313
|
-
if (provider.linkTarget_resolve) {
|
|
314
|
-
return provider.linkTarget_resolve(pathStr);
|
|
315
|
-
}
|
|
316
|
-
cumin_1.errorStack.stack_push('error', `Link resolution not supported for path: ${pathStr}`);
|
|
317
|
-
return (0, cumin_1.Err)();
|
|
318
|
-
}
|
|
319
43
|
}
|
|
320
|
-
exports.
|
|
321
|
-
/**
|
|
322
|
-
exports.vfsDispatcher = new
|
|
44
|
+
exports.CubeVfsDispatcher = CubeVfsDispatcher;
|
|
45
|
+
/** The session's one filesystem dispatcher. */
|
|
46
|
+
exports.vfsDispatcher = new CubeVfsDispatcher();
|
|
323
47
|
//# sourceMappingURL=dispatcher.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/vfs/dispatcher.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/vfs/dispatcher.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAEH,uCAA6C;AAC7C,qDAA0D;AAC1D,iDAAsD;AACtD,+CAAoD;AACpD,iDAAsD;AACtD,2DAAgE;AAChE,yDAA8D;AAC9D,mDAAwD;AAExD,qCAA6C;AAApC,qGAAA,aAAa,OAAA;AAEtB;;;GAGG;AACH,MAAa,iBAAkB,SAAQ,oBAAa;IAClD;QACE,KAAK,CAAC,IAAI,6BAAiB,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,iBAAiB,CAAC,IAAI,yBAAe,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,iBAAiB,CAAC,IAAI,uBAAc,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,iBAAiB,CAAC,IAAI,yBAAe,EAAE,CAAC,CAAC;QAC9C,mEAAmE;QACnE,wEAAwE;QACxE,gBAAgB;QAChB,IAAI,CAAC,iBAAiB,CAAC,IAAI,mCAAoB,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,iBAAiB,CAAC,IAAI,iCAAmB,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,iBAAiB,CAAC,IAAI,2BAAgB,EAAE,CAAC,CAAC;IACjD,CAAC;CACF;AAbD,8CAaC;AAED,+CAA+C;AAClC,QAAA,aAAa,GAAsB,IAAI,iBAAiB,EAAE,CAAC"}
|
package/dist/vfs/provider.d.ts
CHANGED
|
@@ -1,122 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file
|
|
2
|
+
* @file The virtual filesystem's contracts, re-exported from `@fnndsc/fond`.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* The provider interface, the item and the copy options belong to fond, which
|
|
5
|
+
* holds the pieces every layer needs whatever the backend. salsa's mounts
|
|
6
|
+
* implement them.
|
|
6
7
|
*
|
|
7
8
|
* @module
|
|
8
9
|
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Standard interface representing a virtual file system item.
|
|
12
|
-
*/
|
|
13
|
-
export interface VFSItem {
|
|
14
|
-
/** The display name of the item. */
|
|
15
|
-
name: string;
|
|
16
|
-
/** The type of the item. */
|
|
17
|
-
type: "dir" | "file" | "link" | "plugin" | "pipeline" | "vfs" | "job";
|
|
18
|
-
/** Size in bytes. */
|
|
19
|
-
size: number;
|
|
20
|
-
/** Username of the owner. */
|
|
21
|
-
owner: string;
|
|
22
|
-
/** Creation date (ISO string). */
|
|
23
|
-
date: string;
|
|
24
|
-
/** Target path (for links). */
|
|
25
|
-
target?: string;
|
|
26
|
-
/** Version string (for plugins). */
|
|
27
|
-
version?: string;
|
|
28
|
-
/** Title or description (for feeds, queries). */
|
|
29
|
-
title?: string;
|
|
30
|
-
/** Backing resource ID, when the virtual entry represents one. */
|
|
31
|
-
id?: number;
|
|
32
|
-
/** Execution status (for job type items). */
|
|
33
|
-
status?: string;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Options for VFS copy operations.
|
|
37
|
-
*/
|
|
38
|
-
export interface CpOptions {
|
|
39
|
-
/** Recursively copy subdirectories. */
|
|
40
|
-
recursive?: boolean;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Base contract that every Virtual File System Provider must implement.
|
|
44
|
-
*/
|
|
45
|
-
export interface VFSProvider {
|
|
46
|
-
/** The path prefix this provider matches (e.g. '/pacs', '/bin', '/'). */
|
|
47
|
-
prefix: string;
|
|
48
|
-
/**
|
|
49
|
-
* Lists the contents of a directory matching this provider.
|
|
50
|
-
*
|
|
51
|
-
* @param path - The absolute virtual directory path.
|
|
52
|
-
* @param options - Optional sorting controls.
|
|
53
|
-
* @returns A Promise resolving to a Result containing VFSItems.
|
|
54
|
-
*/
|
|
55
|
-
list(path: string, options?: {
|
|
56
|
-
sort?: "name" | "size" | "date" | "owner";
|
|
57
|
-
reverse?: boolean;
|
|
58
|
-
}): Promise<Result<VFSItem[]>>;
|
|
59
|
-
/**
|
|
60
|
-
* Copies files or folders from/to paths under this provider.
|
|
61
|
-
*
|
|
62
|
-
* @param src - The absolute source path.
|
|
63
|
-
* @param dest - The absolute destination path.
|
|
64
|
-
* @param options - Copy flags like recursive.
|
|
65
|
-
* @returns A Promise resolving to true on successful copy execution.
|
|
66
|
-
*/
|
|
67
|
-
cp(src: string, dest: string, options: CpOptions): Promise<boolean>;
|
|
68
|
-
/**
|
|
69
|
-
* Reads the content of a virtual file under this provider as a string.
|
|
70
|
-
*
|
|
71
|
-
* @param path - The absolute virtual path of the file to read.
|
|
72
|
-
* @returns A Promise resolving to a Result containing the file contents as a string.
|
|
73
|
-
*/
|
|
74
|
-
read?(path: string): Promise<Result<string>>;
|
|
75
|
-
/**
|
|
76
|
-
* Reads the content of a virtual file under this provider as a binary Buffer.
|
|
77
|
-
*
|
|
78
|
-
* @param path - The absolute virtual path of the file to read.
|
|
79
|
-
* @returns A Promise resolving to a Result containing the file contents as a Buffer.
|
|
80
|
-
*/
|
|
81
|
-
readBinary?(path: string): Promise<Result<Buffer>>;
|
|
82
|
-
/**
|
|
83
|
-
* Writes a file whole, when the provider holds writable files (a feed's
|
|
84
|
-
* note under /proc). Absent or false, the path is read-only.
|
|
85
|
-
*
|
|
86
|
-
* @param path - The absolute path of the file.
|
|
87
|
-
* @param content - The new content, whole.
|
|
88
|
-
* @returns True when it was written.
|
|
89
|
-
*/
|
|
90
|
-
write?(path: string, content: string): Promise<boolean>;
|
|
91
|
-
/**
|
|
92
|
-
* Makes a folder, when the provider's folders are things a user makes (a
|
|
93
|
-
* tag under /proc/tags). Absent, the provider is read-only for mkdir.
|
|
94
|
-
* @param path - The absolute path of the new folder.
|
|
95
|
-
* @returns True when made; false with the reason stacked.
|
|
96
|
-
*/
|
|
97
|
-
mkdir?(path: string): Promise<boolean>;
|
|
98
|
-
/**
|
|
99
|
-
* Removes an empty folder (`rmdir`).
|
|
100
|
-
* @param path - The absolute path of the folder.
|
|
101
|
-
* @returns True when removed; false with the reason stacked.
|
|
102
|
-
*/
|
|
103
|
-
rmdir?(path: string): Promise<boolean>;
|
|
104
|
-
/**
|
|
105
|
-
* Renames an entry within this provider (`mv`).
|
|
106
|
-
* @param src - The absolute path now.
|
|
107
|
-
* @param dest - The absolute path it takes.
|
|
108
|
-
* @returns True when renamed; false with the reason stacked.
|
|
109
|
-
*/
|
|
110
|
-
rename?(src: string, dest: string): Promise<boolean>;
|
|
111
|
-
/**
|
|
112
|
-
* Resolves the target of a provider-defined lazy link when an operation
|
|
113
|
-
* actually follows it.
|
|
114
|
-
*
|
|
115
|
-
* Listings must not use this hook: providers may expose an unresolved link
|
|
116
|
-
* as structural metadata without paying for its target until navigation.
|
|
117
|
-
*
|
|
118
|
-
* @param path - Absolute virtual path naming the link.
|
|
119
|
-
* @returns The target path, or an error when the provider cannot resolve it.
|
|
120
|
-
*/
|
|
121
|
-
linkTarget_resolve?(path: string): Promise<Result<string>>;
|
|
122
|
-
}
|
|
10
|
+
export type { VFSProvider, VFSItem, CpOptions } from "@fnndsc/fond";
|
package/dist/vfs/provider.js
CHANGED
|
@@ -1,11 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file VFS Provider contracts and item interfaces.
|
|
4
|
-
*
|
|
5
|
-
* Defines the standard VFSItem, CpOptions, and VFSProvider interfaces
|
|
6
|
-
* to support extensible virtual file systems.
|
|
7
|
-
*
|
|
8
|
-
* @module
|
|
9
|
-
*/
|
|
10
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
3
|
//# sourceMappingURL=provider.js.map
|
package/dist/vfs/provider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/vfs/provider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/vfs/provider.ts"],"names":[],"mappings":""}
|
package/dist/vfs/sort.d.ts
CHANGED
|
@@ -1,18 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file
|
|
2
|
+
* @file Sorting a listing's items, re-exported from `@fnndsc/fond`.
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Sorts VFS items by a field (name/size/date/owner), non-destructively.
|
|
9
|
-
*
|
|
10
|
-
* Strings are compared with localeCompare, numbers numerically; mismatched or
|
|
11
|
-
* unsupported types are left in their original relative order.
|
|
12
|
-
*
|
|
13
|
-
* @param items - Items to sort.
|
|
14
|
-
* @param sortField - Field to sort by (default 'name').
|
|
15
|
-
* @param reverse - Whether to reverse the resulting order.
|
|
16
|
-
* @returns A new sorted array.
|
|
17
|
-
*/
|
|
18
|
-
export declare function vfsItems_sort(items: VFSItem[], sortField?: 'name' | 'size' | 'date' | 'owner', reverse?: boolean): VFSItem[];
|
|
6
|
+
export { vfsItems_sort } from "@fnndsc/fond";
|
package/dist/vfs/sort.js
CHANGED
|
@@ -1,33 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.vfsItems_sort =
|
|
3
|
+
exports.vfsItems_sort = void 0;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* @file Sorting a listing's items, re-exported from `@fnndsc/fond`.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* unsupported types are left in their original relative order.
|
|
9
|
-
*
|
|
10
|
-
* @param items - Items to sort.
|
|
11
|
-
* @param sortField - Field to sort by (default 'name').
|
|
12
|
-
* @param reverse - Whether to reverse the resulting order.
|
|
13
|
-
* @returns A new sorted array.
|
|
7
|
+
* @module
|
|
14
8
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const sorted = [...items].sort((a, b) => {
|
|
18
|
-
const valA = a[field];
|
|
19
|
-
const valB = b[field];
|
|
20
|
-
if (typeof valA === 'string' && typeof valB === 'string') {
|
|
21
|
-
return valA.localeCompare(valB);
|
|
22
|
-
}
|
|
23
|
-
if (typeof valA === 'number' && typeof valB === 'number') {
|
|
24
|
-
return valA - valB;
|
|
25
|
-
}
|
|
26
|
-
return 0;
|
|
27
|
-
});
|
|
28
|
-
if (reverse) {
|
|
29
|
-
sorted.reverse();
|
|
30
|
-
}
|
|
31
|
-
return sorted;
|
|
32
|
-
}
|
|
9
|
+
var fond_1 = require("@fnndsc/fond");
|
|
10
|
+
Object.defineProperty(exports, "vfsItems_sort", { enumerable: true, get: function () { return fond_1.vfsItems_sort; } });
|
|
33
11
|
//# sourceMappingURL=sort.js.map
|
package/dist/vfs/sort.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sort.js","sourceRoot":"","sources":["../../src/vfs/sort.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sort.js","sourceRoot":"","sources":["../../src/vfs/sort.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,qCAA6C;AAApC,qGAAA,aAAa,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fnndsc/salsa",
|
|
3
|
-
"version": "3.21.
|
|
3
|
+
"version": "3.21.2",
|
|
4
4
|
"description": "Shared Application Logic and Service Assets for ChRIS",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -60,7 +60,8 @@
|
|
|
60
60
|
"adm-zip": "npm:empty-npm-package@1.0.0"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@fnndsc/
|
|
63
|
+
"@fnndsc/fond": "^0.2.0",
|
|
64
|
+
"@fnndsc/cumin": "^3.27.9",
|
|
64
65
|
"axios": "^1.6.8",
|
|
65
66
|
"dcmjs": "^0.52.0",
|
|
66
67
|
"ws": "^8.21.0"
|