@tissuumaps/core 0.1.0-beta.2 → 0.1.0-beta.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.
- package/CHANGELOG.md +16 -0
- package/README.md +3 -3
- package/dist/index.d.ts +271 -91
- package/dist/index.js +213 -72
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @tissuumaps/core
|
|
2
2
|
|
|
3
|
+
## 0.1.0-beta.3
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#302](https://github.com/TissUUmaps/TissUUmaps/pull/302) [`a422564`](https://github.com/TissUUmaps/TissUUmaps/commit/a4225640dd4be545727210c11e5c12d3d81d650a) Thanks [@jwindhager](https://github.com/jwindhager)! - Data providers gain the optional `supports`, `readName` and `prepareDataSource` methods, and `SourceUtils` gains `getPathSegments`, `getStem`, `getExtension` and `makeProjectPath`.
|
|
8
|
+
|
|
9
|
+
Breaking: data provider UI schemas no longer contain the `source` control, which the app now renders itself.
|
|
10
|
+
|
|
11
|
+
- [#300](https://github.com/TissUUmaps/TissUUmaps/pull/300) [`9fc85a9`](https://github.com/TissUUmaps/TissUUmaps/commit/9fc85a9148be339aa0e419620253f03aace7041a) Thanks [@jwindhager](https://github.com/jwindhager)! - The app store tracks the active panel (`activePanelId`) and the expanded objects of each panel (`expandedImageIds` etc.).
|
|
12
|
+
|
|
13
|
+
Breaking: `showImageSettings` etc. and the `imageSettingsRequest` etc. state are removed. Plugins call `setExpandedImageIds` etc. and `setActivePanelId` instead.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#307](https://github.com/TissUUmaps/TissUUmaps/pull/307) [`16e181e`](https://github.com/TissUUmaps/TissUUmaps/commit/16e181efd919f11a54b259c7e96231b724e628dd) Thanks [@jwindhager](https://github.com/jwindhager)! - Documentation links point to the new TissUUmaps website at https://tissuumaps.github.io/: the app's Docs link, and the packages' READMEs and homepages.
|
|
18
|
+
|
|
3
19
|
## 0.1.0-beta.2
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -19,6 +19,6 @@ stores and the data provider interfaces) silently degrade to `any` when
|
|
|
19
19
|
|
|
20
20
|
## Documentation
|
|
21
21
|
|
|
22
|
-
- [API reference](https://tissuumaps.github.io/
|
|
23
|
-
- [Data model](https://tissuumaps.github.io/
|
|
24
|
-
- [Code architecture](https://tissuumaps.github.io/
|
|
22
|
+
- [API reference](https://tissuumaps.github.io/docs/api/@tissuumaps/core/)
|
|
23
|
+
- [Data model](https://tissuumaps.github.io/docs/concepts/data-model/)
|
|
24
|
+
- [Code architecture](https://tissuumaps.github.io/docs/development/code-architecture/)
|
package/dist/index.d.ts
CHANGED
|
@@ -98,33 +98,46 @@ export declare type AppStoreActions = {
|
|
|
98
98
|
*/
|
|
99
99
|
setHighlightedItemGroup: (highlightedItemGroup: HighlightedItemGroup | null) => void;
|
|
100
100
|
/**
|
|
101
|
-
*
|
|
102
|
-
* and the settings are expanded
|
|
101
|
+
* Makes a panel the active panel, bringing its tab to the front
|
|
103
102
|
*
|
|
104
|
-
*
|
|
103
|
+
* An ID that does not identify a panel of the layout, e.g. that of the viewer
|
|
104
|
+
* or of a plugin that is not mounted, is reverted, leaving the layout
|
|
105
|
+
* unchanged.
|
|
106
|
+
*
|
|
107
|
+
* @param activePanelId - The ID of the panel, see
|
|
108
|
+
* {@link AppStoreState.activePanelId}
|
|
109
|
+
*/
|
|
110
|
+
setActivePanelId: (activePanelId: string) => void;
|
|
111
|
+
/**
|
|
112
|
+
* Sets the images whose entries are expanded in the Images panel
|
|
113
|
+
*
|
|
114
|
+
* @param expandedImageIds - The IDs of the images, in any order
|
|
105
115
|
*/
|
|
106
|
-
|
|
116
|
+
setExpandedImageIds: (expandedImageIds: string[]) => void;
|
|
107
117
|
/**
|
|
108
|
-
*
|
|
109
|
-
* and the settings are expanded
|
|
118
|
+
* Sets the labels whose entries are expanded in the Labels panel
|
|
110
119
|
*
|
|
111
|
-
* @param
|
|
120
|
+
* @param expandedLabelsIds - The IDs of the labels, in any order
|
|
112
121
|
*/
|
|
113
|
-
|
|
122
|
+
setExpandedLabelsIds: (expandedLabelsIds: string[]) => void;
|
|
114
123
|
/**
|
|
115
|
-
*
|
|
116
|
-
* and the settings are expanded
|
|
124
|
+
* Sets the points whose entries are expanded in the Points panel
|
|
117
125
|
*
|
|
118
|
-
* @param
|
|
126
|
+
* @param expandedPointsIds - The IDs of the points, in any order
|
|
119
127
|
*/
|
|
120
|
-
|
|
128
|
+
setExpandedPointsIds: (expandedPointsIds: string[]) => void;
|
|
121
129
|
/**
|
|
122
|
-
*
|
|
123
|
-
* and the settings are expanded
|
|
130
|
+
* Sets the shapes whose entries are expanded in the Shapes panel
|
|
124
131
|
*
|
|
125
|
-
* @param
|
|
132
|
+
* @param expandedShapesIds - The IDs of the shapes, in any order
|
|
126
133
|
*/
|
|
127
|
-
|
|
134
|
+
setExpandedShapesIds: (expandedShapesIds: string[]) => void;
|
|
135
|
+
/**
|
|
136
|
+
* Sets the tables whose entries are expanded in the Tables panel
|
|
137
|
+
*
|
|
138
|
+
* @param expandedTableIds - The IDs of the tables, in any order
|
|
139
|
+
*/
|
|
140
|
+
setExpandedTableIds: (expandedTableIds: string[]) => void;
|
|
128
141
|
/**
|
|
129
142
|
* Registers an image data provider
|
|
130
143
|
*
|
|
@@ -214,45 +227,45 @@ export declare type AppStoreState = {
|
|
|
214
227
|
container?: HTMLElement;
|
|
215
228
|
}>;
|
|
216
229
|
/**
|
|
217
|
-
* The
|
|
218
|
-
* been none
|
|
230
|
+
* The ID of the active panel, i.e. the panel whose tab was selected last
|
|
219
231
|
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
232
|
+
* Either the ID of a built-in panel or that of a mounted plugin's panel, as
|
|
233
|
+
* listed in the plugin documentation. Kept in sync with the panel layout in
|
|
234
|
+
* both directions: selecting a tab sets it, and setting it brings that
|
|
235
|
+
* panel's tab to the front and activates its group. The viewer has no tab and
|
|
236
|
+
* is never the active panel, so focusing it leaves this unchanged.
|
|
222
237
|
*/
|
|
223
|
-
|
|
224
|
-
imageId: string;
|
|
225
|
-
} | null;
|
|
238
|
+
activePanelId: string;
|
|
226
239
|
/**
|
|
227
|
-
* The
|
|
228
|
-
* been none
|
|
240
|
+
* The IDs of the images whose entries are expanded in the Images panel
|
|
229
241
|
*
|
|
230
|
-
*
|
|
231
|
-
* that a repeated request for the same labels is a change too.
|
|
242
|
+
* Cleared whenever another project is loaded or the project is closed.
|
|
232
243
|
*/
|
|
233
|
-
|
|
234
|
-
labelsId: string;
|
|
235
|
-
} | null;
|
|
244
|
+
expandedImageIds: string[];
|
|
236
245
|
/**
|
|
237
|
-
* The
|
|
238
|
-
* been none
|
|
246
|
+
* The IDs of the labels whose entries are expanded in the Labels panel
|
|
239
247
|
*
|
|
240
|
-
*
|
|
241
|
-
* that a repeated request for the same points is a change too.
|
|
248
|
+
* Cleared whenever another project is loaded or the project is closed.
|
|
242
249
|
*/
|
|
243
|
-
|
|
244
|
-
pointsId: string;
|
|
245
|
-
} | null;
|
|
250
|
+
expandedLabelsIds: string[];
|
|
246
251
|
/**
|
|
247
|
-
* The
|
|
248
|
-
* been none
|
|
252
|
+
* The IDs of the points whose entries are expanded in the Points panel
|
|
249
253
|
*
|
|
250
|
-
*
|
|
251
|
-
* that a repeated request for the same shapes is a change too.
|
|
254
|
+
* Cleared whenever another project is loaded or the project is closed.
|
|
252
255
|
*/
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
+
expandedPointsIds: string[];
|
|
257
|
+
/**
|
|
258
|
+
* The IDs of the shapes whose entries are expanded in the Shapes panel
|
|
259
|
+
*
|
|
260
|
+
* Cleared whenever another project is loaded or the project is closed.
|
|
261
|
+
*/
|
|
262
|
+
expandedShapesIds: string[];
|
|
263
|
+
/**
|
|
264
|
+
* The IDs of the tables whose entries are expanded in the Tables panel
|
|
265
|
+
*
|
|
266
|
+
* Cleared whenever another project is loaded or the project is closed.
|
|
267
|
+
*/
|
|
268
|
+
expandedTableIds: string[];
|
|
256
269
|
};
|
|
257
270
|
|
|
258
271
|
/**
|
|
@@ -907,7 +920,12 @@ export declare interface DataProvider<TDataSource extends DataSource, TData exte
|
|
|
907
920
|
readonly name: string;
|
|
908
921
|
/** The JSON schema for the data source */
|
|
909
922
|
readonly schema: JsonSchema;
|
|
910
|
-
/**
|
|
923
|
+
/**
|
|
924
|
+
* The JSON Forms UI schema for the data source
|
|
925
|
+
*
|
|
926
|
+
* It must not contain a control for the data source's `source`, which the
|
|
927
|
+
* application renders itself if the schema declares it, as a string.
|
|
928
|
+
*/
|
|
911
929
|
readonly uischema: UISchemaElement;
|
|
912
930
|
/**
|
|
913
931
|
* Returns the data source with all of this data provider's defaults applied
|
|
@@ -935,6 +953,60 @@ export declare interface DataProvider<TDataSource extends DataSource, TData exte
|
|
|
935
953
|
* @returns The normalized data source
|
|
936
954
|
*/
|
|
937
955
|
normalize(dataSource: TDataSource, workspace: FileSystemDirectoryHandle | null, projectSource: string | null): TNormalizedDataSource;
|
|
956
|
+
/**
|
|
957
|
+
* Returns whether this data provider can likely open a source
|
|
958
|
+
*
|
|
959
|
+
* Used to pick a data provider for a source the user entered or dropped,
|
|
960
|
+
* e.g. by its file extension or by cheaply reading its metadata. A data
|
|
961
|
+
* provider without this method is never picked automatically, but can
|
|
962
|
+
* still be chosen by the user. Callers treat a rejection as `false`.
|
|
963
|
+
*
|
|
964
|
+
* @param normalizedSource - The source, normalized with
|
|
965
|
+
* `SourceUtils.normalizeSource` like {@link DataProvider.normalize} does
|
|
966
|
+
* @param workspace - The directory handle of the open workspace, if any
|
|
967
|
+
* @param options - Optional abort signal
|
|
968
|
+
* @returns A promise that resolves to whether the source is supported
|
|
969
|
+
*/
|
|
970
|
+
supports?(normalizedSource: string, workspace: FileSystemDirectoryHandle | null, options?: {
|
|
971
|
+
signal?: AbortSignal;
|
|
972
|
+
}): Promise<boolean>;
|
|
973
|
+
/**
|
|
974
|
+
* Reads the name a source stores in its metadata
|
|
975
|
+
*
|
|
976
|
+
* Used to name data objects added from a source the user entered or
|
|
977
|
+
* dropped. Only names stored in the source are returned, never names
|
|
978
|
+
* derived from the source itself, such as from its path. Without this
|
|
979
|
+
* method, or if it resolves to `undefined`, callers derive the name from the
|
|
980
|
+
* file name. Callers treat a rejection like `undefined`.
|
|
981
|
+
*
|
|
982
|
+
* @param normalizedSource - The source, normalized with
|
|
983
|
+
* `SourceUtils.normalizeSource` like {@link DataProvider.normalize} does
|
|
984
|
+
* @param workspace - The directory handle of the open workspace, if any
|
|
985
|
+
* @param options - Optional abort signal
|
|
986
|
+
* @returns A promise that resolves to the name, if any
|
|
987
|
+
*/
|
|
988
|
+
readName?(normalizedSource: string, workspace: FileSystemDirectoryHandle | null, options?: {
|
|
989
|
+
signal?: AbortSignal;
|
|
990
|
+
}): Promise<string | undefined>;
|
|
991
|
+
/**
|
|
992
|
+
* Prepares a data source before a data object backed by it is added, or
|
|
993
|
+
* before it is saved with a changed source or type
|
|
994
|
+
*
|
|
995
|
+
* Called once per added data object, with the data source the user entered,
|
|
996
|
+
* and once per saved edit that changes the data source's `source` or `type`.
|
|
997
|
+
* May create the data objects the data source depends on, and returns the
|
|
998
|
+
* data source to add or save.
|
|
999
|
+
*
|
|
1000
|
+
* @param dataSource - The data source to prepare, not normalized
|
|
1001
|
+
* @param workspace - The directory handle of the open workspace, if any
|
|
1002
|
+
* @param projectSource - Where the project was loaded from, if anywhere (see
|
|
1003
|
+
* {@link DataProvider.normalize})
|
|
1004
|
+
* @param options - Optional abort signal
|
|
1005
|
+
* @returns A promise that resolves to the data source to add or save
|
|
1006
|
+
*/
|
|
1007
|
+
prepareDataSource?(dataSource: TDataSource, workspace: FileSystemDirectoryHandle | null, projectSource: string | null, options?: {
|
|
1008
|
+
signal?: AbortSignal;
|
|
1009
|
+
}): Promise<TDataSource>;
|
|
938
1010
|
/**
|
|
939
1011
|
* Opens a data source and returns the loaded data accessor
|
|
940
1012
|
*
|
|
@@ -3985,6 +4057,14 @@ export declare type SizeConfig = ConstantConfig<number, {
|
|
|
3985
4057
|
* URL's path are dropped silently. Resolving within the workspace collapses the
|
|
3986
4058
|
* segments and fails if the path leaves the workspace.
|
|
3987
4059
|
*
|
|
4060
|
+
* Helpers work on normalized sources: {@link SourceUtils.isWorkspacePath}
|
|
4061
|
+
* classifies them, {@link SourceUtils.makeWorkspacePath} builds them,
|
|
4062
|
+
* {@link SourceUtils.getPathSegments}, {@link SourceUtils.getParentSource},
|
|
4063
|
+
* {@link SourceUtils.getStem} and {@link SourceUtils.getExtension} take them
|
|
4064
|
+
* apart, and
|
|
4065
|
+
* {@link SourceUtils.makeProjectPath} turns them back into project-relative
|
|
4066
|
+
* paths.
|
|
4067
|
+
*
|
|
3988
4068
|
* A relative path whose first segment contains a colon (e.g.
|
|
3989
4069
|
* `sample1:ch2.tif`) is taken for a URL; write it as `./sample1:ch2.tif`
|
|
3990
4070
|
* instead.
|
|
@@ -3994,38 +4074,6 @@ export declare class SourceUtils {
|
|
|
3994
4074
|
private static readonly _appPathPrefix;
|
|
3995
4075
|
private static readonly _workspacePathPrefix;
|
|
3996
4076
|
private static readonly _urlSchemePattern;
|
|
3997
|
-
/**
|
|
3998
|
-
* Returns whether a normalized source refers to a file or directory within
|
|
3999
|
-
* the workspace
|
|
4000
|
-
*
|
|
4001
|
-
* @param normalizedSource - The normalized source (see
|
|
4002
|
-
* {@link SourceUtils.normalizeSource})
|
|
4003
|
-
* @returns `true` for workspace-relative paths, `false` for URLs and
|
|
4004
|
-
* app-relative paths
|
|
4005
|
-
*/
|
|
4006
|
-
static isWorkspacePath(normalizedSource: string): boolean;
|
|
4007
|
-
/**
|
|
4008
|
-
* Builds a workspace-relative path from the segments of a path within the
|
|
4009
|
-
* workspace, as returned by `FileSystemDirectoryHandle.resolve`
|
|
4010
|
-
*
|
|
4011
|
-
* @param segments - The path segments, from the workspace root down to the
|
|
4012
|
-
* file or directory
|
|
4013
|
-
* @returns The workspace-relative path (with `/` prefix)
|
|
4014
|
-
*/
|
|
4015
|
-
static makeWorkspacePath(segments: string[]): string;
|
|
4016
|
-
/**
|
|
4017
|
-
* Returns the directory that contains a normalized source
|
|
4018
|
-
*
|
|
4019
|
-
* @param normalizedSource - The normalized source (see
|
|
4020
|
-
* {@link SourceUtils.normalizeSource})
|
|
4021
|
-
* @returns The normalized parent source and the name of the source within
|
|
4022
|
-
* it, decoded for URLs; `null` if the source is the root of its URL's path
|
|
4023
|
-
* or lies directly in the workspace, as the workspace root is no source
|
|
4024
|
-
*/
|
|
4025
|
-
static getParentSource(normalizedSource: string): {
|
|
4026
|
-
parentSource: string;
|
|
4027
|
-
name: string;
|
|
4028
|
-
} | null;
|
|
4029
4077
|
/**
|
|
4030
4078
|
* Normalizes a source, applying the fallbacks for missing project sources
|
|
4031
4079
|
* and workspaces
|
|
@@ -4098,6 +4146,24 @@ export declare class SourceUtils {
|
|
|
4098
4146
|
static resolveSourceFile(normalizedSource: string, workspace: FileSystemDirectoryHandle | null, options?: {
|
|
4099
4147
|
signal?: AbortSignal;
|
|
4100
4148
|
}): Promise<string | FileSystemFileHandle>;
|
|
4149
|
+
/**
|
|
4150
|
+
* Resolves a normalized source to an absolute URL or a directory handle
|
|
4151
|
+
*
|
|
4152
|
+
* Like {@link SourceUtils.resolveSource}, for sources that have to refer to
|
|
4153
|
+
* a directory.
|
|
4154
|
+
*
|
|
4155
|
+
* @param normalizedSource - See {@link SourceUtils.resolveSource}
|
|
4156
|
+
* @param workspace - See {@link SourceUtils.resolveSource}
|
|
4157
|
+
* @param options - See {@link SourceUtils.resolveSource}
|
|
4158
|
+
* @returns A promise that resolves to the absolute URL, or to the directory
|
|
4159
|
+
* handle for sources within the workspace
|
|
4160
|
+
* @throws See {@link SourceUtils.resolveSource}
|
|
4161
|
+
* @throws DOMException if the source refers to a file within the workspace
|
|
4162
|
+
* (`TypeMismatchError`)
|
|
4163
|
+
*/
|
|
4164
|
+
static resolveSourceDirectory(normalizedSource: string, workspace: FileSystemDirectoryHandle | null, options?: {
|
|
4165
|
+
signal?: AbortSignal;
|
|
4166
|
+
}): Promise<string | FileSystemDirectoryHandle>;
|
|
4101
4167
|
/**
|
|
4102
4168
|
* Resolves a normalized source to an absolute URL or an opened file
|
|
4103
4169
|
*
|
|
@@ -4128,23 +4194,102 @@ export declare class SourceUtils {
|
|
|
4128
4194
|
file: File;
|
|
4129
4195
|
}>;
|
|
4130
4196
|
/**
|
|
4131
|
-
*
|
|
4197
|
+
* Returns whether a normalized source refers to a file or directory within
|
|
4198
|
+
* the workspace
|
|
4132
4199
|
*
|
|
4133
|
-
*
|
|
4134
|
-
*
|
|
4200
|
+
* @param normalizedSource - The normalized source (see
|
|
4201
|
+
* {@link SourceUtils.normalizeSource})
|
|
4202
|
+
* @returns `true` for workspace-relative paths, `false` for URLs and
|
|
4203
|
+
* app-relative paths
|
|
4204
|
+
*/
|
|
4205
|
+
static isWorkspacePath(normalizedSource: string): boolean;
|
|
4206
|
+
/**
|
|
4207
|
+
* Builds a workspace-relative path from the segments of a path within the
|
|
4208
|
+
* workspace, as returned by `FileSystemDirectoryHandle.resolve`
|
|
4135
4209
|
*
|
|
4136
|
-
* @param
|
|
4137
|
-
*
|
|
4138
|
-
* @
|
|
4139
|
-
* @returns A promise that resolves to the absolute URL, or to the directory
|
|
4140
|
-
* handle for sources within the workspace
|
|
4141
|
-
* @throws See {@link SourceUtils.resolveSource}
|
|
4142
|
-
* @throws DOMException if the source refers to a file within the workspace
|
|
4143
|
-
* (`TypeMismatchError`)
|
|
4210
|
+
* @param segments - The path segments, from the workspace root down to the
|
|
4211
|
+
* file or directory
|
|
4212
|
+
* @returns The workspace-relative path (with `/` prefix)
|
|
4144
4213
|
*/
|
|
4145
|
-
static
|
|
4146
|
-
|
|
4147
|
-
|
|
4214
|
+
static makeWorkspacePath(segments: string[]): string;
|
|
4215
|
+
/**
|
|
4216
|
+
* Turns a workspace-relative path into a path relative to the project file,
|
|
4217
|
+
* if the project was loaded from the workspace
|
|
4218
|
+
*
|
|
4219
|
+
* The result normalizes back to the same workspace-relative path (see
|
|
4220
|
+
* {@link SourceUtils.normalizeSource}), so data sources stay valid when the
|
|
4221
|
+
* project and its data are moved together. A first segment that contains a
|
|
4222
|
+
* colon gets a `./` prefix where it would otherwise be taken for a URL.
|
|
4223
|
+
*
|
|
4224
|
+
* @param normalizedSource - The normalized source (see
|
|
4225
|
+
* {@link SourceUtils.normalizeSource}); a workspace-relative path has to
|
|
4226
|
+
* name a file or directory within the workspace, not its root
|
|
4227
|
+
* @param projectSource - Where the project was loaded from (see
|
|
4228
|
+
* {@link SourceUtils.normalizeSource})
|
|
4229
|
+
* @returns The project-relative path (e.g. `points.csv` or
|
|
4230
|
+
* `../shared/x.csv`, or `.` for the project file's own directory) if both
|
|
4231
|
+
* the source and the project source are workspace-relative; the source
|
|
4232
|
+
* unchanged otherwise
|
|
4233
|
+
*/
|
|
4234
|
+
static makeProjectPath(normalizedSource: string, projectSource: string | null): string;
|
|
4235
|
+
/**
|
|
4236
|
+
* Returns the path segments of a normalized source
|
|
4237
|
+
*
|
|
4238
|
+
* @param normalizedSource - The normalized source (see
|
|
4239
|
+
* {@link SourceUtils.normalizeSource})
|
|
4240
|
+
* @returns The segments from the workspace root down to the file or
|
|
4241
|
+
* directory, or the decoded segments of a URL's path, without its query and
|
|
4242
|
+
* hash; empty for URLs without a path, such as `data:` URLs, and for the
|
|
4243
|
+
* root of an origin
|
|
4244
|
+
* @throws TypeError if the source is neither a workspace-relative path nor
|
|
4245
|
+
* an absolute URL
|
|
4246
|
+
* @throws Error if a workspace-relative path leads above the workspace root
|
|
4247
|
+
*/
|
|
4248
|
+
static getPathSegments(normalizedSource: string): string[];
|
|
4249
|
+
/**
|
|
4250
|
+
* Returns the directory that contains a normalized source
|
|
4251
|
+
*
|
|
4252
|
+
* @param normalizedSource - The normalized source (see
|
|
4253
|
+
* {@link SourceUtils.normalizeSource})
|
|
4254
|
+
* @returns The normalized parent source and the name of the source within
|
|
4255
|
+
* it, decoded for URLs; `null` if the source is the root of its URL's path,
|
|
4256
|
+
* is a URL without a path (such as a `data:` URL), or lies directly in the
|
|
4257
|
+
* workspace, as the workspace root is no source
|
|
4258
|
+
* @throws See {@link SourceUtils.getPathSegments}
|
|
4259
|
+
*/
|
|
4260
|
+
static getParentSource(normalizedSource: string): {
|
|
4261
|
+
parentSource: string;
|
|
4262
|
+
name: string;
|
|
4263
|
+
} | null;
|
|
4264
|
+
/**
|
|
4265
|
+
* Returns the name of the file or directory a normalized source refers to,
|
|
4266
|
+
* without its last extension
|
|
4267
|
+
*
|
|
4268
|
+
* Only the last extension is dropped, so `cells.ome.zarr` gives `cells.ome`.
|
|
4269
|
+
* A leading dot does not start an extension, so `.hidden` stays as is.
|
|
4270
|
+
*
|
|
4271
|
+
* @param normalizedSource - The normalized source (see
|
|
4272
|
+
* {@link SourceUtils.normalizeSource})
|
|
4273
|
+
* @returns The stem of the last path segment, decoded for URLs; an empty
|
|
4274
|
+
* string for URLs without a path, such as `data:` URLs or the root of an
|
|
4275
|
+
* origin
|
|
4276
|
+
* @throws See {@link SourceUtils.getPathSegments}
|
|
4277
|
+
*/
|
|
4278
|
+
static getStem(normalizedSource: string): string;
|
|
4279
|
+
/**
|
|
4280
|
+
* Returns the last extension of the file or directory a normalized source
|
|
4281
|
+
* refers to, lower-cased for comparison
|
|
4282
|
+
*
|
|
4283
|
+
* Only the last extension is returned, so `cells.ome.zarr` gives `.zarr`.
|
|
4284
|
+
* A leading dot does not start an extension, so `.hidden` has none.
|
|
4285
|
+
*
|
|
4286
|
+
* @param normalizedSource - The normalized source (see
|
|
4287
|
+
* {@link SourceUtils.normalizeSource})
|
|
4288
|
+
* @returns The extension including its dot (e.g. `.csv`), or an empty
|
|
4289
|
+
* string if the last path segment has none
|
|
4290
|
+
* @throws See {@link SourceUtils.getPathSegments}
|
|
4291
|
+
*/
|
|
4292
|
+
static getExtension(normalizedSource: string): string;
|
|
4148
4293
|
/**
|
|
4149
4294
|
* Normalizes a project-relative path
|
|
4150
4295
|
*
|
|
@@ -4201,6 +4346,25 @@ export declare class SourceUtils {
|
|
|
4201
4346
|
* @throws TypeError if the path does not form a valid URL with the base URL
|
|
4202
4347
|
*/
|
|
4203
4348
|
private static _normalizeAppPath;
|
|
4349
|
+
/**
|
|
4350
|
+
* Splits a workspace-relative path into its collapsed segments, the inverse
|
|
4351
|
+
* of {@link SourceUtils.makeWorkspacePath}
|
|
4352
|
+
*
|
|
4353
|
+
* @param workspacePath - The workspace-relative path (with `/` prefix)
|
|
4354
|
+
* @returns The segments from the workspace root down to the file or
|
|
4355
|
+
* directory, empty for the root itself
|
|
4356
|
+
* @throws Error if the path leads above the workspace root
|
|
4357
|
+
*/
|
|
4358
|
+
private static _getWorkspaceSegments;
|
|
4359
|
+
/**
|
|
4360
|
+
* Splits the path of a URL into its segments
|
|
4361
|
+
*
|
|
4362
|
+
* @param url - The URL
|
|
4363
|
+
* @returns The non-empty, still encoded segments of the URL's path; empty
|
|
4364
|
+
* for URLs without a hierarchical path, such as `data:` and `blob:` URLs,
|
|
4365
|
+
* whose path does not start with `/`
|
|
4366
|
+
*/
|
|
4367
|
+
private static _getURLSegments;
|
|
4204
4368
|
/**
|
|
4205
4369
|
* Splits a path into segments, dropping empty and `.` segments and
|
|
4206
4370
|
* collapsing `..` segments against the segments preceding them
|
|
@@ -4212,6 +4376,22 @@ export declare class SourceUtils {
|
|
|
4212
4376
|
* @throws Error if the path leads above the root
|
|
4213
4377
|
*/
|
|
4214
4378
|
private static _collapseSegments;
|
|
4379
|
+
/**
|
|
4380
|
+
* Returns where the last extension of a file or directory name starts
|
|
4381
|
+
*
|
|
4382
|
+
* @param name - The name
|
|
4383
|
+
* @returns The index of the extension's dot, or `-1` if the name has no
|
|
4384
|
+
* extension; a leading dot does not start one
|
|
4385
|
+
*/
|
|
4386
|
+
private static _getExtensionIndex;
|
|
4387
|
+
/**
|
|
4388
|
+
* Decodes a percent-encoded URL path segment
|
|
4389
|
+
*
|
|
4390
|
+
* @param segment - The encoded segment
|
|
4391
|
+
* @returns The decoded segment, or the segment as is if it holds a malformed
|
|
4392
|
+
* escape (e.g. a stray `%`), which the URL parser lets through
|
|
4393
|
+
*/
|
|
4394
|
+
private static _decodeSegment;
|
|
4215
4395
|
}
|
|
4216
4396
|
|
|
4217
4397
|
/**
|
package/dist/index.js
CHANGED
|
@@ -2346,6 +2346,14 @@ var ProjectUtils = class {
|
|
|
2346
2346
|
* URL's path are dropped silently. Resolving within the workspace collapses the
|
|
2347
2347
|
* segments and fails if the path leaves the workspace.
|
|
2348
2348
|
*
|
|
2349
|
+
* Helpers work on normalized sources: {@link SourceUtils.isWorkspacePath}
|
|
2350
|
+
* classifies them, {@link SourceUtils.makeWorkspacePath} builds them,
|
|
2351
|
+
* {@link SourceUtils.getPathSegments}, {@link SourceUtils.getParentSource},
|
|
2352
|
+
* {@link SourceUtils.getStem} and {@link SourceUtils.getExtension} take them
|
|
2353
|
+
* apart, and
|
|
2354
|
+
* {@link SourceUtils.makeProjectPath} turns them back into project-relative
|
|
2355
|
+
* paths.
|
|
2356
|
+
*
|
|
2349
2357
|
* A relative path whose first segment contains a colon (e.g.
|
|
2350
2358
|
* `sample1:ch2.tif`) is taken for a URL; write it as `./sample1:ch2.tif`
|
|
2351
2359
|
* instead.
|
|
@@ -2356,58 +2364,6 @@ var SourceUtils = class SourceUtils {
|
|
|
2356
2364
|
static _workspacePathPrefix = SourceUtils._pathSep;
|
|
2357
2365
|
static _urlSchemePattern = /^[a-z][a-z0-9+.-]*:/i;
|
|
2358
2366
|
/**
|
|
2359
|
-
* Returns whether a normalized source refers to a file or directory within
|
|
2360
|
-
* the workspace
|
|
2361
|
-
*
|
|
2362
|
-
* @param normalizedSource - The normalized source (see
|
|
2363
|
-
* {@link SourceUtils.normalizeSource})
|
|
2364
|
-
* @returns `true` for workspace-relative paths, `false` for URLs and
|
|
2365
|
-
* app-relative paths
|
|
2366
|
-
*/
|
|
2367
|
-
static isWorkspacePath(normalizedSource) {
|
|
2368
|
-
return normalizedSource.startsWith(SourceUtils._workspacePathPrefix) && !normalizedSource.startsWith(SourceUtils._appPathPrefix);
|
|
2369
|
-
}
|
|
2370
|
-
/**
|
|
2371
|
-
* Builds a workspace-relative path from the segments of a path within the
|
|
2372
|
-
* workspace, as returned by `FileSystemDirectoryHandle.resolve`
|
|
2373
|
-
*
|
|
2374
|
-
* @param segments - The path segments, from the workspace root down to the
|
|
2375
|
-
* file or directory
|
|
2376
|
-
* @returns The workspace-relative path (with `/` prefix)
|
|
2377
|
-
*/
|
|
2378
|
-
static makeWorkspacePath(segments) {
|
|
2379
|
-
return SourceUtils._workspacePathPrefix + segments.join(SourceUtils._pathSep);
|
|
2380
|
-
}
|
|
2381
|
-
/**
|
|
2382
|
-
* Returns the directory that contains a normalized source
|
|
2383
|
-
*
|
|
2384
|
-
* @param normalizedSource - The normalized source (see
|
|
2385
|
-
* {@link SourceUtils.normalizeSource})
|
|
2386
|
-
* @returns The normalized parent source and the name of the source within
|
|
2387
|
-
* it, decoded for URLs; `null` if the source is the root of its URL's path
|
|
2388
|
-
* or lies directly in the workspace, as the workspace root is no source
|
|
2389
|
-
*/
|
|
2390
|
-
static getParentSource(normalizedSource) {
|
|
2391
|
-
if (SourceUtils.isWorkspacePath(normalizedSource)) {
|
|
2392
|
-
const segments = normalizedSource.substring(SourceUtils._workspacePathPrefix.length).split(SourceUtils._pathSep);
|
|
2393
|
-
const name = segments.pop();
|
|
2394
|
-
if (name === void 0 || segments.length === 0) return null;
|
|
2395
|
-
return {
|
|
2396
|
-
parentSource: SourceUtils.makeWorkspacePath(segments),
|
|
2397
|
-
name
|
|
2398
|
-
};
|
|
2399
|
-
}
|
|
2400
|
-
const url = new URL(normalizedSource);
|
|
2401
|
-
const segments = url.pathname.split(SourceUtils._pathSep).filter((segment) => segment !== "");
|
|
2402
|
-
const name = segments.pop();
|
|
2403
|
-
if (name === void 0) return null;
|
|
2404
|
-
url.pathname = segments.join(SourceUtils._pathSep);
|
|
2405
|
-
return {
|
|
2406
|
-
parentSource: url.toString(),
|
|
2407
|
-
name: decodeURIComponent(name)
|
|
2408
|
-
};
|
|
2409
|
-
}
|
|
2410
|
-
/**
|
|
2411
2367
|
* Normalizes a source, applying the fallbacks for missing project sources
|
|
2412
2368
|
* and workspaces
|
|
2413
2369
|
*
|
|
@@ -2471,7 +2427,7 @@ var SourceUtils = class SourceUtils {
|
|
|
2471
2427
|
signal?.throwIfAborted();
|
|
2472
2428
|
if (!SourceUtils.isWorkspacePath(normalizedSource)) return normalizedSource;
|
|
2473
2429
|
if (workspace === null) throw new Error(`Cannot resolve workspace-relative path without workspace: ${normalizedSource}`);
|
|
2474
|
-
const segments = SourceUtils.
|
|
2430
|
+
const segments = SourceUtils._getWorkspaceSegments(normalizedSource);
|
|
2475
2431
|
const entryName = segments.pop();
|
|
2476
2432
|
if (entryName === void 0) throw new Error(`Not a workspace file or directory: ${normalizedSource}`);
|
|
2477
2433
|
let dir = workspace;
|
|
@@ -2511,6 +2467,26 @@ var SourceUtils = class SourceUtils {
|
|
|
2511
2467
|
return resolvedSource;
|
|
2512
2468
|
}
|
|
2513
2469
|
/**
|
|
2470
|
+
* Resolves a normalized source to an absolute URL or a directory handle
|
|
2471
|
+
*
|
|
2472
|
+
* Like {@link SourceUtils.resolveSource}, for sources that have to refer to
|
|
2473
|
+
* a directory.
|
|
2474
|
+
*
|
|
2475
|
+
* @param normalizedSource - See {@link SourceUtils.resolveSource}
|
|
2476
|
+
* @param workspace - See {@link SourceUtils.resolveSource}
|
|
2477
|
+
* @param options - See {@link SourceUtils.resolveSource}
|
|
2478
|
+
* @returns A promise that resolves to the absolute URL, or to the directory
|
|
2479
|
+
* handle for sources within the workspace
|
|
2480
|
+
* @throws See {@link SourceUtils.resolveSource}
|
|
2481
|
+
* @throws DOMException if the source refers to a file within the workspace
|
|
2482
|
+
* (`TypeMismatchError`)
|
|
2483
|
+
*/
|
|
2484
|
+
static async resolveSourceDirectory(normalizedSource, workspace, options) {
|
|
2485
|
+
const resolvedSource = await SourceUtils.resolveSource(normalizedSource, workspace, options);
|
|
2486
|
+
if (typeof resolvedSource !== "string" && resolvedSource.kind !== "directory") throw new DOMException(`Not a workspace directory: ${normalizedSource}`, "TypeMismatchError");
|
|
2487
|
+
return resolvedSource;
|
|
2488
|
+
}
|
|
2489
|
+
/**
|
|
2514
2490
|
* Resolves a normalized source to an absolute URL or an opened file
|
|
2515
2491
|
*
|
|
2516
2492
|
* Like {@link SourceUtils.resolveSourceFile}, for readers that take either
|
|
@@ -2539,24 +2515,141 @@ var SourceUtils = class SourceUtils {
|
|
|
2539
2515
|
return { file };
|
|
2540
2516
|
}
|
|
2541
2517
|
/**
|
|
2542
|
-
*
|
|
2518
|
+
* Returns whether a normalized source refers to a file or directory within
|
|
2519
|
+
* the workspace
|
|
2543
2520
|
*
|
|
2544
|
-
*
|
|
2545
|
-
*
|
|
2521
|
+
* @param normalizedSource - The normalized source (see
|
|
2522
|
+
* {@link SourceUtils.normalizeSource})
|
|
2523
|
+
* @returns `true` for workspace-relative paths, `false` for URLs and
|
|
2524
|
+
* app-relative paths
|
|
2525
|
+
*/
|
|
2526
|
+
static isWorkspacePath(normalizedSource) {
|
|
2527
|
+
return normalizedSource.startsWith(SourceUtils._workspacePathPrefix) && !normalizedSource.startsWith(SourceUtils._appPathPrefix);
|
|
2528
|
+
}
|
|
2529
|
+
/**
|
|
2530
|
+
* Builds a workspace-relative path from the segments of a path within the
|
|
2531
|
+
* workspace, as returned by `FileSystemDirectoryHandle.resolve`
|
|
2546
2532
|
*
|
|
2547
|
-
* @param
|
|
2548
|
-
*
|
|
2549
|
-
* @
|
|
2550
|
-
* @returns A promise that resolves to the absolute URL, or to the directory
|
|
2551
|
-
* handle for sources within the workspace
|
|
2552
|
-
* @throws See {@link SourceUtils.resolveSource}
|
|
2553
|
-
* @throws DOMException if the source refers to a file within the workspace
|
|
2554
|
-
* (`TypeMismatchError`)
|
|
2533
|
+
* @param segments - The path segments, from the workspace root down to the
|
|
2534
|
+
* file or directory
|
|
2535
|
+
* @returns The workspace-relative path (with `/` prefix)
|
|
2555
2536
|
*/
|
|
2556
|
-
static
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2537
|
+
static makeWorkspacePath(segments) {
|
|
2538
|
+
return SourceUtils._workspacePathPrefix + segments.join(SourceUtils._pathSep);
|
|
2539
|
+
}
|
|
2540
|
+
/**
|
|
2541
|
+
* Turns a workspace-relative path into a path relative to the project file,
|
|
2542
|
+
* if the project was loaded from the workspace
|
|
2543
|
+
*
|
|
2544
|
+
* The result normalizes back to the same workspace-relative path (see
|
|
2545
|
+
* {@link SourceUtils.normalizeSource}), so data sources stay valid when the
|
|
2546
|
+
* project and its data are moved together. A first segment that contains a
|
|
2547
|
+
* colon gets a `./` prefix where it would otherwise be taken for a URL.
|
|
2548
|
+
*
|
|
2549
|
+
* @param normalizedSource - The normalized source (see
|
|
2550
|
+
* {@link SourceUtils.normalizeSource}); a workspace-relative path has to
|
|
2551
|
+
* name a file or directory within the workspace, not its root
|
|
2552
|
+
* @param projectSource - Where the project was loaded from (see
|
|
2553
|
+
* {@link SourceUtils.normalizeSource})
|
|
2554
|
+
* @returns The project-relative path (e.g. `points.csv` or
|
|
2555
|
+
* `../shared/x.csv`, or `.` for the project file's own directory) if both
|
|
2556
|
+
* the source and the project source are workspace-relative; the source
|
|
2557
|
+
* unchanged otherwise
|
|
2558
|
+
*/
|
|
2559
|
+
static makeProjectPath(normalizedSource, projectSource) {
|
|
2560
|
+
if (projectSource === null || !SourceUtils.isWorkspacePath(projectSource) || !SourceUtils.isWorkspacePath(normalizedSource)) return normalizedSource;
|
|
2561
|
+
const projectDirSegments = SourceUtils._getWorkspaceSegments(projectSource).slice(0, -1);
|
|
2562
|
+
const segments = SourceUtils._getWorkspaceSegments(normalizedSource);
|
|
2563
|
+
let commonLength = 0;
|
|
2564
|
+
while (commonLength < projectDirSegments.length && commonLength < segments.length && projectDirSegments[commonLength] === segments[commonLength]) commonLength++;
|
|
2565
|
+
const projectPath = [...Array(projectDirSegments.length - commonLength).fill(".."), ...segments.slice(commonLength)].join(SourceUtils._pathSep);
|
|
2566
|
+
if (projectPath === "") return ".";
|
|
2567
|
+
return SourceUtils._urlSchemePattern.test(projectPath) ? `.${SourceUtils._pathSep}${projectPath}` : projectPath;
|
|
2568
|
+
}
|
|
2569
|
+
/**
|
|
2570
|
+
* Returns the path segments of a normalized source
|
|
2571
|
+
*
|
|
2572
|
+
* @param normalizedSource - The normalized source (see
|
|
2573
|
+
* {@link SourceUtils.normalizeSource})
|
|
2574
|
+
* @returns The segments from the workspace root down to the file or
|
|
2575
|
+
* directory, or the decoded segments of a URL's path, without its query and
|
|
2576
|
+
* hash; empty for URLs without a path, such as `data:` URLs, and for the
|
|
2577
|
+
* root of an origin
|
|
2578
|
+
* @throws TypeError if the source is neither a workspace-relative path nor
|
|
2579
|
+
* an absolute URL
|
|
2580
|
+
* @throws Error if a workspace-relative path leads above the workspace root
|
|
2581
|
+
*/
|
|
2582
|
+
static getPathSegments(normalizedSource) {
|
|
2583
|
+
if (SourceUtils.isWorkspacePath(normalizedSource)) return SourceUtils._getWorkspaceSegments(normalizedSource);
|
|
2584
|
+
return SourceUtils._getURLSegments(new URL(normalizedSource)).map((segment) => SourceUtils._decodeSegment(segment));
|
|
2585
|
+
}
|
|
2586
|
+
/**
|
|
2587
|
+
* Returns the directory that contains a normalized source
|
|
2588
|
+
*
|
|
2589
|
+
* @param normalizedSource - The normalized source (see
|
|
2590
|
+
* {@link SourceUtils.normalizeSource})
|
|
2591
|
+
* @returns The normalized parent source and the name of the source within
|
|
2592
|
+
* it, decoded for URLs; `null` if the source is the root of its URL's path,
|
|
2593
|
+
* is a URL without a path (such as a `data:` URL), or lies directly in the
|
|
2594
|
+
* workspace, as the workspace root is no source
|
|
2595
|
+
* @throws See {@link SourceUtils.getPathSegments}
|
|
2596
|
+
*/
|
|
2597
|
+
static getParentSource(normalizedSource) {
|
|
2598
|
+
if (SourceUtils.isWorkspacePath(normalizedSource)) {
|
|
2599
|
+
const segments = SourceUtils._getWorkspaceSegments(normalizedSource);
|
|
2600
|
+
const name = segments.pop();
|
|
2601
|
+
if (name === void 0 || segments.length === 0) return null;
|
|
2602
|
+
return {
|
|
2603
|
+
parentSource: SourceUtils.makeWorkspacePath(segments),
|
|
2604
|
+
name
|
|
2605
|
+
};
|
|
2606
|
+
}
|
|
2607
|
+
const url = new URL(normalizedSource);
|
|
2608
|
+
const segments = SourceUtils._getURLSegments(url);
|
|
2609
|
+
const name = segments.pop();
|
|
2610
|
+
if (name === void 0) return null;
|
|
2611
|
+
url.pathname = segments.join(SourceUtils._pathSep);
|
|
2612
|
+
return {
|
|
2613
|
+
parentSource: url.toString(),
|
|
2614
|
+
name: SourceUtils._decodeSegment(name)
|
|
2615
|
+
};
|
|
2616
|
+
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Returns the name of the file or directory a normalized source refers to,
|
|
2619
|
+
* without its last extension
|
|
2620
|
+
*
|
|
2621
|
+
* Only the last extension is dropped, so `cells.ome.zarr` gives `cells.ome`.
|
|
2622
|
+
* A leading dot does not start an extension, so `.hidden` stays as is.
|
|
2623
|
+
*
|
|
2624
|
+
* @param normalizedSource - The normalized source (see
|
|
2625
|
+
* {@link SourceUtils.normalizeSource})
|
|
2626
|
+
* @returns The stem of the last path segment, decoded for URLs; an empty
|
|
2627
|
+
* string for URLs without a path, such as `data:` URLs or the root of an
|
|
2628
|
+
* origin
|
|
2629
|
+
* @throws See {@link SourceUtils.getPathSegments}
|
|
2630
|
+
*/
|
|
2631
|
+
static getStem(normalizedSource) {
|
|
2632
|
+
const name = SourceUtils.getPathSegments(normalizedSource).at(-1) ?? "";
|
|
2633
|
+
const extensionIndex = SourceUtils._getExtensionIndex(name);
|
|
2634
|
+
return extensionIndex !== -1 ? name.substring(0, extensionIndex) : name;
|
|
2635
|
+
}
|
|
2636
|
+
/**
|
|
2637
|
+
* Returns the last extension of the file or directory a normalized source
|
|
2638
|
+
* refers to, lower-cased for comparison
|
|
2639
|
+
*
|
|
2640
|
+
* Only the last extension is returned, so `cells.ome.zarr` gives `.zarr`.
|
|
2641
|
+
* A leading dot does not start an extension, so `.hidden` has none.
|
|
2642
|
+
*
|
|
2643
|
+
* @param normalizedSource - The normalized source (see
|
|
2644
|
+
* {@link SourceUtils.normalizeSource})
|
|
2645
|
+
* @returns The extension including its dot (e.g. `.csv`), or an empty
|
|
2646
|
+
* string if the last path segment has none
|
|
2647
|
+
* @throws See {@link SourceUtils.getPathSegments}
|
|
2648
|
+
*/
|
|
2649
|
+
static getExtension(normalizedSource) {
|
|
2650
|
+
const name = SourceUtils.getPathSegments(normalizedSource).at(-1) ?? "";
|
|
2651
|
+
const extensionIndex = SourceUtils._getExtensionIndex(name);
|
|
2652
|
+
return extensionIndex !== -1 ? name.substring(extensionIndex).toLowerCase() : "";
|
|
2560
2653
|
}
|
|
2561
2654
|
/**
|
|
2562
2655
|
* Normalizes a project-relative path
|
|
@@ -2585,7 +2678,7 @@ var SourceUtils = class SourceUtils {
|
|
|
2585
2678
|
} catch (error) {
|
|
2586
2679
|
throw new Error(`Invalid project-relative path: ${projectPath}`, { cause: error });
|
|
2587
2680
|
}
|
|
2588
|
-
const projectDirSegments = SourceUtils.
|
|
2681
|
+
const projectDirSegments = SourceUtils._getWorkspaceSegments(projectSource).slice(0, -1);
|
|
2589
2682
|
const segments = SourceUtils._collapseSegments(projectPath, projectDirSegments);
|
|
2590
2683
|
return SourceUtils._normalizeWorkspacePath(SourceUtils.makeWorkspacePath(segments), workspace, options);
|
|
2591
2684
|
}
|
|
@@ -2612,13 +2705,12 @@ var SourceUtils = class SourceUtils {
|
|
|
2612
2705
|
*/
|
|
2613
2706
|
static _normalizeWorkspacePath(workspacePath, workspace, options) {
|
|
2614
2707
|
if (!workspacePath.startsWith(SourceUtils._workspacePathPrefix)) throw new Error(`Invalid workspace-relative path: ${workspacePath}`);
|
|
2615
|
-
const path = workspacePath.substring(SourceUtils._workspacePathPrefix.length);
|
|
2616
2708
|
if (workspace !== null) {
|
|
2617
|
-
const segments = SourceUtils.
|
|
2709
|
+
const segments = SourceUtils._getWorkspaceSegments(workspacePath);
|
|
2618
2710
|
if (segments.length === 0) throw new Error(`Not a workspace file or directory: ${workspacePath}`);
|
|
2619
2711
|
return SourceUtils.makeWorkspacePath(segments);
|
|
2620
2712
|
}
|
|
2621
|
-
return SourceUtils._normalizeAppPath(SourceUtils._appPathPrefix +
|
|
2713
|
+
return SourceUtils._normalizeAppPath(SourceUtils._appPathPrefix + workspacePath.substring(SourceUtils._workspacePathPrefix.length), options);
|
|
2622
2714
|
}
|
|
2623
2715
|
/**
|
|
2624
2716
|
* Normalizes an app-relative path to an absolute URL
|
|
@@ -2641,6 +2733,30 @@ var SourceUtils = class SourceUtils {
|
|
|
2641
2733
|
return new URL(path, baseUrl).toString();
|
|
2642
2734
|
}
|
|
2643
2735
|
/**
|
|
2736
|
+
* Splits a workspace-relative path into its collapsed segments, the inverse
|
|
2737
|
+
* of {@link SourceUtils.makeWorkspacePath}
|
|
2738
|
+
*
|
|
2739
|
+
* @param workspacePath - The workspace-relative path (with `/` prefix)
|
|
2740
|
+
* @returns The segments from the workspace root down to the file or
|
|
2741
|
+
* directory, empty for the root itself
|
|
2742
|
+
* @throws Error if the path leads above the workspace root
|
|
2743
|
+
*/
|
|
2744
|
+
static _getWorkspaceSegments(workspacePath) {
|
|
2745
|
+
return SourceUtils._collapseSegments(workspacePath.substring(SourceUtils._workspacePathPrefix.length));
|
|
2746
|
+
}
|
|
2747
|
+
/**
|
|
2748
|
+
* Splits the path of a URL into its segments
|
|
2749
|
+
*
|
|
2750
|
+
* @param url - The URL
|
|
2751
|
+
* @returns The non-empty, still encoded segments of the URL's path; empty
|
|
2752
|
+
* for URLs without a hierarchical path, such as `data:` and `blob:` URLs,
|
|
2753
|
+
* whose path does not start with `/`
|
|
2754
|
+
*/
|
|
2755
|
+
static _getURLSegments(url) {
|
|
2756
|
+
if (!url.pathname.startsWith(SourceUtils._pathSep)) return [];
|
|
2757
|
+
return url.pathname.split(SourceUtils._pathSep).filter((segment) => segment !== "");
|
|
2758
|
+
}
|
|
2759
|
+
/**
|
|
2644
2760
|
* Splits a path into segments, dropping empty and `.` segments and
|
|
2645
2761
|
* collapsing `..` segments against the segments preceding them
|
|
2646
2762
|
*
|
|
@@ -2661,6 +2777,31 @@ var SourceUtils = class SourceUtils {
|
|
|
2661
2777
|
}
|
|
2662
2778
|
return segments;
|
|
2663
2779
|
}
|
|
2780
|
+
/**
|
|
2781
|
+
* Returns where the last extension of a file or directory name starts
|
|
2782
|
+
*
|
|
2783
|
+
* @param name - The name
|
|
2784
|
+
* @returns The index of the extension's dot, or `-1` if the name has no
|
|
2785
|
+
* extension; a leading dot does not start one
|
|
2786
|
+
*/
|
|
2787
|
+
static _getExtensionIndex(name) {
|
|
2788
|
+
const extensionIndex = name.lastIndexOf(".");
|
|
2789
|
+
return extensionIndex > 0 ? extensionIndex : -1;
|
|
2790
|
+
}
|
|
2791
|
+
/**
|
|
2792
|
+
* Decodes a percent-encoded URL path segment
|
|
2793
|
+
*
|
|
2794
|
+
* @param segment - The encoded segment
|
|
2795
|
+
* @returns The decoded segment, or the segment as is if it holds a malformed
|
|
2796
|
+
* escape (e.g. a stray `%`), which the URL parser lets through
|
|
2797
|
+
*/
|
|
2798
|
+
static _decodeSegment(segment) {
|
|
2799
|
+
try {
|
|
2800
|
+
return decodeURIComponent(segment);
|
|
2801
|
+
} catch {
|
|
2802
|
+
return segment;
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2664
2805
|
};
|
|
2665
2806
|
//#endregion
|
|
2666
2807
|
//#region src/utils/TableUtils.ts
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tissuumaps/core",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.3",
|
|
4
4
|
"description": "Core model, types and utilities shared by the TissUUmaps packages",
|
|
5
|
-
"homepage": "https://tissuumaps.github.io/
|
|
5
|
+
"homepage": "https://tissuumaps.github.io/",
|
|
6
6
|
"bugs": "https://github.com/TissUUmaps/TissUUmaps/issues",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|