@ccheever/exact-ibex-runtime 0.1.0
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/package.json +63 -0
- package/src/abort/AbortController.ts +23 -0
- package/src/abort/AbortSignal.ts +152 -0
- package/src/abort/index.ts +2 -0
- package/src/accessibility.ts +12 -0
- package/src/arraybuffer-detach.ts +109 -0
- package/src/base64/base64.ts +168 -0
- package/src/base64/index.ts +1 -0
- package/src/blob/Blob.ts +259 -0
- package/src/blob/File.ts +59 -0
- package/src/blob/FormData.ts +323 -0
- package/src/blob/index.ts +3 -0
- package/src/bootstrap.ts +1946 -0
- package/src/broadcast/BroadcastChannel.ts +280 -0
- package/src/broadcast/index.ts +5 -0
- package/src/cache/Cache.ts +349 -0
- package/src/cache/CacheStorage.ts +89 -0
- package/src/cache/index.ts +27 -0
- package/src/camera/index.ts +6202 -0
- package/src/camera/processor.worker.ts +194 -0
- package/src/camera/scene.ts +195 -0
- package/src/clipboard/Clipboard.ts +129 -0
- package/src/clipboard/ClipboardItem.ts +97 -0
- package/src/clipboard/index.ts +6 -0
- package/src/clone/index.ts +1 -0
- package/src/clone/structuredClone.ts +389 -0
- package/src/clone/transferableSymbols.ts +2 -0
- package/src/compression/CompressionStream.ts +146 -0
- package/src/compression/DecompressionStream.ts +342 -0
- package/src/compression/index.ts +4 -0
- package/src/console/Console.ts +341 -0
- package/src/console/index.ts +2 -0
- package/src/core/accessibility-state.ts +263 -0
- package/src/core/accessibility.ts +184 -0
- package/src/core/agent-state.ts +37 -0
- package/src/core/diagnostics-logs.ts +144 -0
- package/src/core/host-call-bridge.ts +16 -0
- package/src/core/i18n-helpers.ts +189 -0
- package/src/core/locale-state.ts +253 -0
- package/src/core/locale.ts +95 -0
- package/src/crypto/Crypto.ts +2743 -0
- package/src/crypto/index.ts +1 -0
- package/src/diagnostics/logs.ts +7 -0
- package/src/encoding/TextDecoder.ts +1181 -0
- package/src/encoding/TextDecoderStream.ts +58 -0
- package/src/encoding/TextEncoder.ts +180 -0
- package/src/encoding/TextEncoderStream.ts +39 -0
- package/src/encoding/index.ts +8 -0
- package/src/events/CloseEvent.ts +91 -0
- package/src/events/DOMException.ts +409 -0
- package/src/events/ErrorEvent.ts +39 -0
- package/src/events/Event.ts +151 -0
- package/src/events/EventTarget.ts +280 -0
- package/src/events/FocusEvent.ts +27 -0
- package/src/events/KeyboardEvent.ts +46 -0
- package/src/events/MessageEvent.ts +61 -0
- package/src/events/ProgressEvent.ts +33 -0
- package/src/events/PromiseRejectionEvent.ts +31 -0
- package/src/events/index.ts +52 -0
- package/src/eventsource/EventSource.ts +371 -0
- package/src/eventsource/index.ts +2 -0
- package/src/fetch/Headers.ts +642 -0
- package/src/fetch/Request.ts +760 -0
- package/src/fetch/Response.ts +543 -0
- package/src/fetch/body.ts +1256 -0
- package/src/fetch/cookie-jar.ts +566 -0
- package/src/fetch/demo.ts +207 -0
- package/src/fetch/errors.ts +101 -0
- package/src/fetch/fetch.ts +2610 -0
- package/src/fetch/index.ts +101 -0
- package/src/fetch/native-bridge.ts +65 -0
- package/src/fetch/types.ts +258 -0
- package/src/filereader/FileReader.ts +236 -0
- package/src/filereader/index.ts +1 -0
- package/src/fs/Dirent.ts +39 -0
- package/src/fs/ExactFile.ts +450 -0
- package/src/fs/Stats.ts +80 -0
- package/src/fs/index.ts +944 -0
- package/src/fs/promises.ts +386 -0
- package/src/fs/shared.ts +328 -0
- package/src/http-server/index.js +697 -0
- package/src/http-server/index.ts +27 -0
- package/src/identity.generated.ts +14 -0
- package/src/index.ts +283 -0
- package/src/indexeddb/IDBCursor.ts +188 -0
- package/src/indexeddb/IDBDatabase.ts +343 -0
- package/src/indexeddb/IDBFactory.ts +269 -0
- package/src/indexeddb/IDBIndex.ts +194 -0
- package/src/indexeddb/IDBKeyRange.ts +109 -0
- package/src/indexeddb/IDBObjectStore.ts +468 -0
- package/src/indexeddb/IDBRequest.ts +163 -0
- package/src/indexeddb/IDBTransaction.ts +207 -0
- package/src/indexeddb/index.ts +34 -0
- package/src/indexeddb/utils.ts +52 -0
- package/src/inspect/index.ts +1 -0
- package/src/inspect/inspect.ts +465 -0
- package/src/internal/detect.ts +104 -0
- package/src/locale.ts +10 -0
- package/src/location/index.ts +1059 -0
- package/src/locks/LockManager.ts +460 -0
- package/src/locks/index.ts +12 -0
- package/src/media/VideoFrame.ts +58 -0
- package/src/messaging/MessageChannel.ts +31 -0
- package/src/messaging/MessagePort.ts +180 -0
- package/src/messaging/index.ts +2 -0
- package/src/messaging.ts +247 -0
- package/src/native/NativeModules.ts +354 -0
- package/src/native/index.ts +1 -0
- package/src/navigator/Navigator.ts +351 -0
- package/src/navigator/index.ts +1 -0
- package/src/node/Buffer.ts +1786 -0
- package/src/node/index.ts +4 -0
- package/src/node/path.ts +495 -0
- package/src/node/process.ts +2528 -0
- package/src/performance/Performance.ts +532 -0
- package/src/performance/index.ts +21 -0
- package/src/polyfills/array.ts +236 -0
- package/src/polyfills/arraybuffer.ts +172 -0
- package/src/polyfills/groupby.ts +85 -0
- package/src/polyfills/index.ts +85 -0
- package/src/polyfills/intl.ts +1956 -0
- package/src/polyfills/iterator.ts +479 -0
- package/src/polyfills/promise.ts +37 -0
- package/src/polyfills/set.ts +245 -0
- package/src/polyfills/string.ts +85 -0
- package/src/polyfills/typedarray.ts +110 -0
- package/src/promise-rejection-tracking.ts +464 -0
- package/src/react-native/index.ts +388 -0
- package/src/runtime-entry.ts +55 -0
- package/src/scheduling/AnimationFrame.ts +105 -0
- package/src/scheduling/IdleCallback.ts +167 -0
- package/src/scheduling/index.ts +13 -0
- package/src/security/Capabilities.ts +1146 -0
- package/src/security/Permissions.ts +392 -0
- package/src/security/capability-bits.generated.ts +63 -0
- package/src/security/index.ts +16 -0
- package/src/sqlite/Database.ts +456 -0
- package/src/sqlite/Statement.ts +206 -0
- package/src/sqlite/constants.ts +79 -0
- package/src/sqlite/errors.ts +25 -0
- package/src/sqlite/index.ts +34 -0
- package/src/sqlite/module.js +438 -0
- package/src/storage/Storage.ts +291 -0
- package/src/storage/StorageManager.ts +91 -0
- package/src/storage/index.ts +3 -0
- package/src/stream-compat.ts +47 -0
- package/src/streams/ReadableStream.ts +4131 -0
- package/src/streams/TransformStream.ts +375 -0
- package/src/streams/WritableStream.ts +866 -0
- package/src/streams/index.ts +41 -0
- package/src/timers/Timers.ts +296 -0
- package/src/timers/index.ts +11 -0
- package/src/url/URL.ts +656 -0
- package/src/url/URLPattern.ts +850 -0
- package/src/url/URLSearchParams.ts +244 -0
- package/src/url/index.ts +9 -0
- package/src/websocket/WebSocket.ts +770 -0
- package/src/websocket/WebSocketError.ts +52 -0
- package/src/websocket/WebSocketStream.ts +628 -0
- package/src/websocket/index.ts +7 -0
- package/src/window/index.ts +872 -0
package/src/node/path.ts
ADDED
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* path module implementation for Ibex runtime (Node.js compatibility)
|
|
3
|
+
*
|
|
4
|
+
* Provides path manipulation utilities compatible with Node.js path module.
|
|
5
|
+
* Since mobile apps run on Unix-like systems (iOS/Android), we only implement
|
|
6
|
+
* the POSIX path semantics.
|
|
7
|
+
*
|
|
8
|
+
* @see https://nodejs.org/api/path.html
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Path segment separator (always '/' on mobile platforms)
|
|
13
|
+
*/
|
|
14
|
+
export const sep = '/';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Path delimiter for PATH-like environment variables
|
|
18
|
+
*/
|
|
19
|
+
export const delimiter = ':';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Platform-specific path object (POSIX)
|
|
23
|
+
*/
|
|
24
|
+
export const posix = {
|
|
25
|
+
sep: '/',
|
|
26
|
+
delimiter: ':',
|
|
27
|
+
basename,
|
|
28
|
+
dirname,
|
|
29
|
+
extname,
|
|
30
|
+
format,
|
|
31
|
+
isAbsolute,
|
|
32
|
+
join,
|
|
33
|
+
normalize,
|
|
34
|
+
parse,
|
|
35
|
+
relative,
|
|
36
|
+
resolve,
|
|
37
|
+
toNamespacedPath,
|
|
38
|
+
posix: undefined as unknown as any,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Windows path object (stub - not supported on mobile)
|
|
43
|
+
*/
|
|
44
|
+
export const win32 = {
|
|
45
|
+
sep: '\\',
|
|
46
|
+
delimiter: ';',
|
|
47
|
+
basename: () => { throw new Error('win32 paths not supported'); },
|
|
48
|
+
dirname: () => { throw new Error('win32 paths not supported'); },
|
|
49
|
+
extname: () => { throw new Error('win32 paths not supported'); },
|
|
50
|
+
format: () => { throw new Error('win32 paths not supported'); },
|
|
51
|
+
isAbsolute: () => { throw new Error('win32 paths not supported'); },
|
|
52
|
+
join: () => { throw new Error('win32 paths not supported'); },
|
|
53
|
+
normalize: () => { throw new Error('win32 paths not supported'); },
|
|
54
|
+
parse: () => { throw new Error('win32 paths not supported'); },
|
|
55
|
+
relative: () => { throw new Error('win32 paths not supported'); },
|
|
56
|
+
resolve: () => { throw new Error('win32 paths not supported'); },
|
|
57
|
+
toNamespacedPath: () => { throw new Error('win32 paths not supported'); },
|
|
58
|
+
win32: undefined as unknown as any,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export interface ParsedPath {
|
|
62
|
+
root: string;
|
|
63
|
+
dir: string;
|
|
64
|
+
base: string;
|
|
65
|
+
ext: string;
|
|
66
|
+
name: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface FormatInputPathObject {
|
|
70
|
+
root?: string;
|
|
71
|
+
dir?: string;
|
|
72
|
+
base?: string;
|
|
73
|
+
ext?: string;
|
|
74
|
+
name?: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Return the last portion of a path.
|
|
79
|
+
*
|
|
80
|
+
* @param path - The path to evaluate
|
|
81
|
+
* @param suffix - An optional suffix to remove
|
|
82
|
+
* @returns The last portion of the path
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* path.basename('/foo/bar/baz.txt') // 'baz.txt'
|
|
86
|
+
* path.basename('/foo/bar/baz.txt', '.txt') // 'baz'
|
|
87
|
+
*/
|
|
88
|
+
export function basename(path: string, suffix?: string): string {
|
|
89
|
+
if (typeof path !== 'string') {
|
|
90
|
+
throw new TypeError('Path must be a string');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Remove trailing slashes
|
|
94
|
+
let end = path.length;
|
|
95
|
+
while (end > 0 && path[end - 1] === '/') {
|
|
96
|
+
end--;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (end === 0) {
|
|
100
|
+
return '';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Find start of basename
|
|
104
|
+
let start = end - 1;
|
|
105
|
+
while (start >= 0 && path[start] !== '/') {
|
|
106
|
+
start--;
|
|
107
|
+
}
|
|
108
|
+
start++;
|
|
109
|
+
|
|
110
|
+
let base = path.slice(start, end);
|
|
111
|
+
|
|
112
|
+
// Remove suffix if provided
|
|
113
|
+
if (suffix && base.endsWith(suffix)) {
|
|
114
|
+
base = base.slice(0, -suffix.length);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return base;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Return the directory name of a path.
|
|
122
|
+
*
|
|
123
|
+
* @param path - The path to evaluate
|
|
124
|
+
* @returns The directory name
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* path.dirname('/foo/bar/baz.txt') // '/foo/bar'
|
|
128
|
+
*/
|
|
129
|
+
export function dirname(path: string): string {
|
|
130
|
+
if (typeof path !== 'string') {
|
|
131
|
+
throw new TypeError('Path must be a string');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (path.length === 0) {
|
|
135
|
+
return '.';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Check if path is absolute
|
|
139
|
+
const isAbs = path[0] === '/';
|
|
140
|
+
|
|
141
|
+
// Remove trailing slashes
|
|
142
|
+
let end = path.length;
|
|
143
|
+
while (end > 1 && path[end - 1] === '/') {
|
|
144
|
+
end--;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Find the last separator
|
|
148
|
+
let last = end - 1;
|
|
149
|
+
while (last > 0 && path[last] !== '/') {
|
|
150
|
+
last--;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (last === 0) {
|
|
154
|
+
return isAbs ? '/' : '.';
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Remove trailing slashes from result
|
|
158
|
+
while (last > 1 && path[last - 1] === '/') {
|
|
159
|
+
last--;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return path.slice(0, last);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Return the extension of the path.
|
|
167
|
+
*
|
|
168
|
+
* @param path - The path to evaluate
|
|
169
|
+
* @returns The extension (including the dot)
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* path.extname('index.html') // '.html'
|
|
173
|
+
* path.extname('index.coffee.md') // '.md'
|
|
174
|
+
*/
|
|
175
|
+
export function extname(path: string): string {
|
|
176
|
+
if (typeof path !== 'string') {
|
|
177
|
+
throw new TypeError('Path must be a string');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const base = basename(path);
|
|
181
|
+
const dotIndex = base.lastIndexOf('.');
|
|
182
|
+
|
|
183
|
+
// No dot, or dot is first character (hidden file)
|
|
184
|
+
if (dotIndex <= 0) {
|
|
185
|
+
return '';
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return base.slice(dotIndex);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Return a path string from an object.
|
|
193
|
+
*
|
|
194
|
+
* @param pathObject - Object with path components
|
|
195
|
+
* @returns The formatted path string
|
|
196
|
+
*/
|
|
197
|
+
export function format(pathObject: FormatInputPathObject): string {
|
|
198
|
+
if (pathObject === null || typeof pathObject !== 'object') {
|
|
199
|
+
throw new TypeError('Path object must be an object');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const { root = '', dir, base, ext = '', name = '' } = pathObject;
|
|
203
|
+
|
|
204
|
+
// If dir is provided, use it; otherwise use root
|
|
205
|
+
const directory = dir !== undefined ? dir : root;
|
|
206
|
+
|
|
207
|
+
// If base is provided, use it; otherwise construct from name + ext
|
|
208
|
+
const filename = base !== undefined ? base : `${name}${ext}`;
|
|
209
|
+
|
|
210
|
+
if (!directory) {
|
|
211
|
+
return filename;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (directory === root) {
|
|
215
|
+
return `${directory}${filename}`;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return `${directory}/${filename}`;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Determine if a path is absolute.
|
|
223
|
+
*
|
|
224
|
+
* @param path - The path to check
|
|
225
|
+
* @returns true if the path is absolute
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* path.isAbsolute('/foo/bar') // true
|
|
229
|
+
* path.isAbsolute('foo/bar') // false
|
|
230
|
+
*/
|
|
231
|
+
export function isAbsolute(path: string): boolean {
|
|
232
|
+
if (typeof path !== 'string') {
|
|
233
|
+
throw new TypeError('Path must be a string');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return path.length > 0 && path[0] === '/';
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Join all arguments together and normalize the resulting path.
|
|
241
|
+
*
|
|
242
|
+
* @param paths - A sequence of paths to join
|
|
243
|
+
* @returns The joined path
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* path.join('/foo', 'bar', 'baz/asdf', 'quux', '..') // '/foo/bar/baz/asdf'
|
|
247
|
+
*/
|
|
248
|
+
export function join(...paths: string[]): string {
|
|
249
|
+
if (paths.length === 0) {
|
|
250
|
+
return '.';
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
let joined = '';
|
|
254
|
+
for (const path of paths) {
|
|
255
|
+
if (typeof path !== 'string') {
|
|
256
|
+
throw new TypeError('Path must be a string');
|
|
257
|
+
}
|
|
258
|
+
if (path.length > 0) {
|
|
259
|
+
if (joined.length === 0) {
|
|
260
|
+
joined = path;
|
|
261
|
+
} else {
|
|
262
|
+
joined += '/' + path;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (joined.length === 0) {
|
|
268
|
+
return '.';
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return normalize(joined);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Normalize a path, resolving '..' and '.' segments.
|
|
276
|
+
*
|
|
277
|
+
* @param path - The path to normalize
|
|
278
|
+
* @returns The normalized path
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* path.normalize('/foo/bar//baz/asdf/quux/..') // '/foo/bar/baz/asdf'
|
|
282
|
+
*/
|
|
283
|
+
export function normalize(path: string): string {
|
|
284
|
+
if (typeof path !== 'string') {
|
|
285
|
+
throw new TypeError('Path must be a string');
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (path.length === 0) {
|
|
289
|
+
return '.';
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const isAbs = path[0] === '/';
|
|
293
|
+
const trailingSep = path[path.length - 1] === '/';
|
|
294
|
+
|
|
295
|
+
// Split into segments and process
|
|
296
|
+
const segments = path.split('/');
|
|
297
|
+
const result: string[] = [];
|
|
298
|
+
|
|
299
|
+
for (const segment of segments) {
|
|
300
|
+
if (segment === '' || segment === '.') {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (segment === '..') {
|
|
305
|
+
if (result.length > 0 && result[result.length - 1] !== '..') {
|
|
306
|
+
result.pop();
|
|
307
|
+
} else if (!isAbs) {
|
|
308
|
+
result.push('..');
|
|
309
|
+
}
|
|
310
|
+
} else {
|
|
311
|
+
result.push(segment);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
let normalized = result.join('/');
|
|
316
|
+
|
|
317
|
+
if (isAbs) {
|
|
318
|
+
normalized = '/' + normalized;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (trailingSep && normalized.length > 0 && normalized[normalized.length - 1] !== '/') {
|
|
322
|
+
normalized += '/';
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (normalized.length === 0) {
|
|
326
|
+
return isAbs ? '/' : '.';
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return normalized;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Parse a path into an object with its components.
|
|
334
|
+
*
|
|
335
|
+
* @param path - The path to parse
|
|
336
|
+
* @returns An object with root, dir, base, ext, and name
|
|
337
|
+
*
|
|
338
|
+
* @example
|
|
339
|
+
* path.parse('/home/user/file.txt')
|
|
340
|
+
* // { root: '/', dir: '/home/user', base: 'file.txt', ext: '.txt', name: 'file' }
|
|
341
|
+
*/
|
|
342
|
+
export function parse(path: string): ParsedPath {
|
|
343
|
+
if (typeof path !== 'string') {
|
|
344
|
+
throw new TypeError('Path must be a string');
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const root = path[0] === '/' ? '/' : '';
|
|
348
|
+
const dir = dirname(path);
|
|
349
|
+
const base = basename(path);
|
|
350
|
+
const ext = extname(path);
|
|
351
|
+
const name = ext ? base.slice(0, -ext.length) : base;
|
|
352
|
+
|
|
353
|
+
return { root, dir, base, ext, name };
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Solve the relative path from `from` to `to`.
|
|
358
|
+
*
|
|
359
|
+
* @param from - The source path
|
|
360
|
+
* @param to - The destination path
|
|
361
|
+
* @returns The relative path
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb')
|
|
365
|
+
* // '../../impl/bbb'
|
|
366
|
+
*/
|
|
367
|
+
export function relative(from: string, to: string): string {
|
|
368
|
+
if (typeof from !== 'string') {
|
|
369
|
+
throw new TypeError('From path must be a string');
|
|
370
|
+
}
|
|
371
|
+
if (typeof to !== 'string') {
|
|
372
|
+
throw new TypeError('To path must be a string');
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (from === to) {
|
|
376
|
+
return '';
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Resolve both paths
|
|
380
|
+
const fromAbs = resolve(from);
|
|
381
|
+
const toAbs = resolve(to);
|
|
382
|
+
|
|
383
|
+
if (fromAbs === toAbs) {
|
|
384
|
+
return '';
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Split into segments
|
|
388
|
+
const fromParts = fromAbs.split('/').filter(Boolean);
|
|
389
|
+
const toParts = toAbs.split('/').filter(Boolean);
|
|
390
|
+
|
|
391
|
+
// Find common prefix
|
|
392
|
+
let commonLength = 0;
|
|
393
|
+
const minLength = Math.min(fromParts.length, toParts.length);
|
|
394
|
+
while (commonLength < minLength && fromParts[commonLength] === toParts[commonLength]) {
|
|
395
|
+
commonLength++;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Build relative path
|
|
399
|
+
const upCount = fromParts.length - commonLength;
|
|
400
|
+
const relativeParts: string[] = [];
|
|
401
|
+
|
|
402
|
+
for (let i = 0; i < upCount; i++) {
|
|
403
|
+
relativeParts.push('..');
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
for (let i = commonLength; i < toParts.length; i++) {
|
|
407
|
+
relativeParts.push(toParts[i]);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return relativeParts.join('/') || '.';
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Resolve a sequence of paths into an absolute path.
|
|
415
|
+
*
|
|
416
|
+
* @param paths - A sequence of paths to resolve
|
|
417
|
+
* @returns The resolved absolute path
|
|
418
|
+
*
|
|
419
|
+
* @example
|
|
420
|
+
* path.resolve('/foo/bar', './baz') // '/foo/bar/baz'
|
|
421
|
+
* path.resolve('/foo/bar', '/tmp/file/') // '/tmp/file'
|
|
422
|
+
*/
|
|
423
|
+
export function resolve(...paths: string[]): string {
|
|
424
|
+
let resolvedPath = '';
|
|
425
|
+
let resolvedAbsolute = false;
|
|
426
|
+
|
|
427
|
+
// Process from right to left, stopping at first absolute path
|
|
428
|
+
for (let i = paths.length - 1; i >= -1 && !resolvedAbsolute; i--) {
|
|
429
|
+
let path: string;
|
|
430
|
+
|
|
431
|
+
if (i >= 0) {
|
|
432
|
+
path = paths[i];
|
|
433
|
+
if (typeof path !== 'string') {
|
|
434
|
+
throw new TypeError('Path must be a string');
|
|
435
|
+
}
|
|
436
|
+
} else {
|
|
437
|
+
// Use cwd as implicit first argument
|
|
438
|
+
path = (globalThis as any).process?.cwd?.() ?? '/';
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
if (path.length === 0) {
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
resolvedPath = path + '/' + resolvedPath;
|
|
446
|
+
resolvedAbsolute = path[0] === '/';
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Normalize and remove trailing slash
|
|
450
|
+
resolvedPath = normalize(resolvedPath);
|
|
451
|
+
|
|
452
|
+
if (resolvedAbsolute) {
|
|
453
|
+
return resolvedPath.length > 0 ? resolvedPath : '/';
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return resolvedPath.length > 0 ? resolvedPath : '.';
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Return the path unchanged (no-op on POSIX systems).
|
|
461
|
+
* On Windows, this would convert to a namespace path.
|
|
462
|
+
*
|
|
463
|
+
* @param path - The path to convert
|
|
464
|
+
* @returns The same path
|
|
465
|
+
*/
|
|
466
|
+
export function toNamespacedPath(path: string): string {
|
|
467
|
+
// No-op on POSIX
|
|
468
|
+
return path;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Default export with all path functions
|
|
473
|
+
*/
|
|
474
|
+
const path = {
|
|
475
|
+
sep,
|
|
476
|
+
delimiter,
|
|
477
|
+
posix,
|
|
478
|
+
win32,
|
|
479
|
+
basename,
|
|
480
|
+
dirname,
|
|
481
|
+
extname,
|
|
482
|
+
format,
|
|
483
|
+
isAbsolute,
|
|
484
|
+
join,
|
|
485
|
+
normalize,
|
|
486
|
+
parse,
|
|
487
|
+
relative,
|
|
488
|
+
resolve,
|
|
489
|
+
toNamespacedPath,
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
posix.posix = posix;
|
|
493
|
+
win32.win32 = win32;
|
|
494
|
+
|
|
495
|
+
export default path;
|