@cleanslate/sdk 0.1.0 → 1.0.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.
Files changed (156) hide show
  1. package/README.md +11 -3
  2. package/VENDOR.md +15 -4
  3. package/dist/agent/cleanSlateAgentSession.d.ts +5 -0
  4. package/dist/agent/cleanSlateAgentSession.d.ts.map +1 -1
  5. package/dist/agent/cleanSlateAgentSession.js +5 -0
  6. package/dist/agent/cleanSlateAgentSession.js.map +1 -1
  7. package/dist/agent/cleanSlateExecutionQuery.d.ts.map +1 -1
  8. package/dist/agent/cleanSlateExecutionQuery.js +2 -1
  9. package/dist/agent/cleanSlateExecutionQuery.js.map +1 -1
  10. package/dist/agent/cleanSlateProviderMessageOrder.d.ts +24 -0
  11. package/dist/agent/cleanSlateProviderMessageOrder.d.ts.map +1 -0
  12. package/dist/agent/cleanSlateProviderMessageOrder.js +37 -0
  13. package/dist/agent/cleanSlateProviderMessageOrder.js.map +1 -0
  14. package/dist/agent/cleanSlateStreamReveal.d.ts +46 -0
  15. package/dist/agent/cleanSlateStreamReveal.d.ts.map +1 -0
  16. package/dist/agent/cleanSlateStreamReveal.js +94 -0
  17. package/dist/agent/cleanSlateStreamReveal.js.map +1 -0
  18. package/dist/composer/instructions/baseInstructions.d.ts +1 -1
  19. package/dist/composer/instructions/baseInstructions.d.ts.map +1 -1
  20. package/dist/composer/instructions/baseInstructions.js +1 -1
  21. package/dist/composer/kernel/coreKernel.d.ts +1 -1
  22. package/dist/composer/kernel/coreKernel.d.ts.map +1 -1
  23. package/dist/composer/kernel/coreKernel.js +1 -1
  24. package/dist/core/buffer.d.ts +19 -15
  25. package/dist/core/buffer.d.ts.map +1 -1
  26. package/dist/core/buffer.js +129 -12
  27. package/dist/core/buffer.js.map +1 -1
  28. package/dist/core/path.d.ts +40 -0
  29. package/dist/core/path.d.ts.map +1 -0
  30. package/dist/core/path.js +1461 -0
  31. package/dist/core/path.js.map +1 -0
  32. package/dist/core/platform.d.ts.map +1 -1
  33. package/dist/core/platform.js +20 -9
  34. package/dist/core/platform.js.map +1 -1
  35. package/dist/core/process.d.ts +13 -0
  36. package/dist/core/process.d.ts.map +1 -0
  37. package/dist/core/process.js +25 -0
  38. package/dist/core/process.js.map +1 -0
  39. package/dist/core/resources.js +3 -3
  40. package/dist/core/uri.js +1 -1
  41. package/dist/host/browserAutomation.d.ts +3 -3
  42. package/dist/host/browserAutomation.d.ts.map +1 -1
  43. package/dist/host/events.d.ts +21 -0
  44. package/dist/host/events.d.ts.map +1 -0
  45. package/dist/host/events.js +6 -0
  46. package/dist/host/events.js.map +1 -0
  47. package/dist/host/files.d.ts +11 -2
  48. package/dist/host/files.d.ts.map +1 -1
  49. package/dist/host/services.d.ts +4 -4
  50. package/dist/host/services.d.ts.map +1 -1
  51. package/dist/host/textModel.d.ts +9 -3
  52. package/dist/host/textModel.d.ts.map +1 -1
  53. package/dist/host/workspace.d.ts +18 -5
  54. package/dist/host/workspace.d.ts.map +1 -1
  55. package/dist/host/workspace.js.map +1 -1
  56. package/dist/index.d.ts +7 -5
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +1 -1
  59. package/dist/index.js.map +1 -1
  60. package/dist/node/cleanSlateHeadlessRunner.d.ts +8 -0
  61. package/dist/node/cleanSlateHeadlessRunner.d.ts.map +1 -1
  62. package/dist/node/cleanSlateHeadlessRunner.js +1 -1
  63. package/dist/node/cleanSlateHeadlessRunner.js.map +1 -1
  64. package/dist/node/cleanSlateMemoryVectorStore.d.ts +19 -0
  65. package/dist/node/cleanSlateMemoryVectorStore.d.ts.map +1 -0
  66. package/dist/node/cleanSlateMemoryVectorStore.js +73 -0
  67. package/dist/node/cleanSlateMemoryVectorStore.js.map +1 -0
  68. package/dist/node/cleanSlateNodeAgentRuntime.d.ts +8 -1
  69. package/dist/node/cleanSlateNodeAgentRuntime.d.ts.map +1 -1
  70. package/dist/node/cleanSlateNodeAgentRuntime.js +41 -2
  71. package/dist/node/cleanSlateNodeAgentRuntime.js.map +1 -1
  72. package/dist/node/cleanSlateNodeHttpTransport.d.ts +33 -0
  73. package/dist/node/cleanSlateNodeHttpTransport.d.ts.map +1 -0
  74. package/dist/node/cleanSlateNodeHttpTransport.js +181 -0
  75. package/dist/node/cleanSlateNodeHttpTransport.js.map +1 -0
  76. package/dist/node/cleanSlateNodeIndexService.d.ts +88 -10
  77. package/dist/node/cleanSlateNodeIndexService.d.ts.map +1 -1
  78. package/dist/node/cleanSlateNodeIndexService.js +447 -93
  79. package/dist/node/cleanSlateNodeIndexService.js.map +1 -1
  80. package/dist/node/cleanSlateNodeMainService.d.ts +18 -10
  81. package/dist/node/cleanSlateNodeMainService.d.ts.map +1 -1
  82. package/dist/node/cleanSlateNodeMainService.js +169 -121
  83. package/dist/node/cleanSlateNodeMainService.js.map +1 -1
  84. package/dist/node/cleanSlateNodeSearchService.d.ts +7 -1
  85. package/dist/node/cleanSlateNodeSearchService.d.ts.map +1 -1
  86. package/dist/node/cleanSlateNodeSearchService.js +11 -11
  87. package/dist/node/cleanSlateNodeSearchService.js.map +1 -1
  88. package/dist/node/cleanSlateNodeToolContext.d.ts +2 -0
  89. package/dist/node/cleanSlateNodeToolContext.d.ts.map +1 -1
  90. package/dist/node/cleanSlateNodeToolContext.js +20 -1
  91. package/dist/node/cleanSlateNodeToolContext.js.map +1 -1
  92. package/dist/node/cleanSlateNodeWebRetrieval.d.ts +3 -0
  93. package/dist/node/cleanSlateNodeWebRetrieval.d.ts.map +1 -1
  94. package/dist/node/cleanSlateNodeWebRetrieval.js +6 -1
  95. package/dist/node/cleanSlateNodeWebRetrieval.js.map +1 -1
  96. package/dist/node/cleanSlateOpenAIMessageAdapter.d.ts.map +1 -1
  97. package/dist/node/cleanSlateOpenAIMessageAdapter.js +4 -0
  98. package/dist/node/cleanSlateOpenAIMessageAdapter.js.map +1 -1
  99. package/dist/node/index.d.ts +4 -0
  100. package/dist/node/index.d.ts.map +1 -1
  101. package/dist/node/index.js +2 -0
  102. package/dist/node/index.js.map +1 -1
  103. package/dist/protocol/cleanSlateAI.d.ts +13 -13
  104. package/dist/protocol/cleanSlateAI.d.ts.map +1 -1
  105. package/dist/protocol/cleanSlateCodeParser.d.ts +13 -0
  106. package/dist/protocol/cleanSlateCodeParser.d.ts.map +1 -0
  107. package/dist/protocol/cleanSlateCodeParser.js +102 -0
  108. package/dist/protocol/cleanSlateCodeParser.js.map +1 -0
  109. package/dist/protocol/cleanSlateModelsDevCatalog.d.ts +27 -0
  110. package/dist/protocol/cleanSlateModelsDevCatalog.d.ts.map +1 -0
  111. package/dist/protocol/cleanSlateModelsDevCatalog.js +87 -0
  112. package/dist/protocol/cleanSlateModelsDevCatalog.js.map +1 -0
  113. package/dist/protocol/cleanSlateProviderTranscript.d.ts +25 -0
  114. package/dist/protocol/cleanSlateProviderTranscript.d.ts.map +1 -0
  115. package/dist/protocol/cleanSlateProviderTranscript.js +125 -0
  116. package/dist/protocol/cleanSlateProviderTranscript.js.map +1 -0
  117. package/dist/protocol/cleanSlateRuntimeConfig.d.ts +33 -0
  118. package/dist/protocol/cleanSlateRuntimeConfig.d.ts.map +1 -0
  119. package/dist/protocol/cleanSlateRuntimeConfig.js +63 -0
  120. package/dist/protocol/cleanSlateRuntimeConfig.js.map +1 -0
  121. package/dist/protocol/cleanSlateService.js.map +1 -1
  122. package/dist/protocol/cleanSlateThreadSession.d.ts +17 -0
  123. package/dist/protocol/cleanSlateThreadSession.d.ts.map +1 -0
  124. package/dist/protocol/cleanSlateThreadSession.js +34 -0
  125. package/dist/protocol/cleanSlateThreadSession.js.map +1 -0
  126. package/dist/services/cleanSlateCommandExecutionService.d.ts +3 -3
  127. package/dist/services/cleanSlateCommandExecutionService.d.ts.map +1 -1
  128. package/dist/services/cleanSlateFileHistory.js +3 -4
  129. package/dist/services/cleanSlateFileHistory.js.map +1 -1
  130. package/dist/tools/FindByNameTool.js +2 -2
  131. package/dist/tools/FindByNameTool.js.map +1 -1
  132. package/dist/tools/FindReferencesTool.js +2 -2
  133. package/dist/tools/FindReferencesTool.js.map +1 -1
  134. package/dist/tools/GetDefinitionsTool.js +2 -2
  135. package/dist/tools/GetDefinitionsTool.js.map +1 -1
  136. package/dist/tools/GrepSearchTool.d.ts.map +1 -1
  137. package/dist/tools/GrepSearchTool.js +16 -10
  138. package/dist/tools/GrepSearchTool.js.map +1 -1
  139. package/dist/tools/ListDirTool.js +2 -2
  140. package/dist/tools/ListDirTool.js.map +1 -1
  141. package/dist/tools/ReadFileRangeTool.js +2 -2
  142. package/dist/tools/ReadFileRangeTool.js.map +1 -1
  143. package/dist/tools/ReadFileTool.js +2 -2
  144. package/dist/tools/ReadFileTool.js.map +1 -1
  145. package/dist/tools/ReadLintsTool.js +3 -3
  146. package/dist/tools/ReadLintsTool.js.map +1 -1
  147. package/dist/tools/ReadSymbolsTool.js +2 -2
  148. package/dist/tools/ReadSymbolsTool.js.map +1 -1
  149. package/dist/tools/SubmitArtifactTool.d.ts.map +1 -1
  150. package/dist/tools/SubmitArtifactTool.js +4 -6
  151. package/dist/tools/SubmitArtifactTool.js.map +1 -1
  152. package/dist/tools/utils.d.ts +19 -1
  153. package/dist/tools/utils.d.ts.map +1 -1
  154. package/dist/tools/utils.js +64 -16
  155. package/dist/tools/utils.js.map +1 -1
  156. package/package.json +14 -2
@@ -0,0 +1,1461 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /*
6
+ * Vendored from microsoft/vscode (vs/base/common/path.ts) for @cleanslate/sdk.
7
+ * Changes: see packages/cleanslate-sdk/VENDOR.md.
8
+ */
9
+ // NOTE: VSCode's copy of nodejs path library to be usable in common (non-node) namespace
10
+ // Copied from: https://github.com/nodejs/node/commits/v22.15.0/lib/path.js
11
+ // Excluding: the change that adds primordials
12
+ // (https://github.com/nodejs/node/commit/187a862d221dec42fa9a5c4214e7034d9092792f and others)
13
+ // Excluding: the change that adds glob matching
14
+ // (https://github.com/nodejs/node/commit/57b8b8e18e5e2007114c63b71bf0baedc01936a6)
15
+ /**
16
+ * Copyright Joyent, Inc. and other Node contributors.
17
+ *
18
+ * Permission is hereby granted, free of charge, to any person obtaining a
19
+ * copy of this software and associated documentation files (the
20
+ * "Software"), to deal in the Software without restriction, including
21
+ * without limitation the rights to use, copy, modify, merge, publish,
22
+ * distribute, sublicense, and/or sell copies of the Software, and to permit
23
+ * persons to whom the Software is furnished to do so, subject to the
24
+ * following conditions:
25
+ *
26
+ * The above copyright notice and this permission notice shall be included
27
+ * in all copies or substantial portions of the Software.
28
+ *
29
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
30
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
32
+ * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
33
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
34
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
35
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
36
+ */
37
+ import * as process from './process.js';
38
+ const CHAR_UPPERCASE_A = 65; /* A */
39
+ const CHAR_LOWERCASE_A = 97; /* a */
40
+ const CHAR_UPPERCASE_Z = 90; /* Z */
41
+ const CHAR_LOWERCASE_Z = 122; /* z */
42
+ const CHAR_DOT = 46; /* . */
43
+ const CHAR_FORWARD_SLASH = 47; /* / */
44
+ const CHAR_BACKWARD_SLASH = 92; /* \ */
45
+ const CHAR_COLON = 58; /* : */
46
+ const CHAR_QUESTION_MARK = 63; /* ? */
47
+ class ErrorInvalidArgType extends Error {
48
+ constructor(name, expected, actual) {
49
+ // determiner: 'must be' or 'must not be'
50
+ let determiner;
51
+ if (typeof expected === 'string' && expected.indexOf('not ') === 0) {
52
+ determiner = 'must not be';
53
+ expected = expected.replace(/^not /, '');
54
+ }
55
+ else {
56
+ determiner = 'must be';
57
+ }
58
+ const type = name.indexOf('.') !== -1 ? 'property' : 'argument';
59
+ let msg = `The "${name}" ${type} ${determiner} of type ${expected}`;
60
+ msg += `. Received type ${typeof actual}`;
61
+ super(msg);
62
+ this.code = 'ERR_INVALID_ARG_TYPE';
63
+ }
64
+ }
65
+ function validateObject(pathObject, name) {
66
+ if (pathObject === null || typeof pathObject !== 'object') {
67
+ throw new ErrorInvalidArgType(name, 'Object', pathObject);
68
+ }
69
+ }
70
+ function validateString(value, name) {
71
+ if (typeof value !== 'string') {
72
+ throw new ErrorInvalidArgType(name, 'string', value);
73
+ }
74
+ }
75
+ const platformIsWin32 = (process.platform === 'win32');
76
+ function isPathSeparator(code) {
77
+ return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
78
+ }
79
+ function isPosixPathSeparator(code) {
80
+ return code === CHAR_FORWARD_SLASH;
81
+ }
82
+ function isWindowsDeviceRoot(code) {
83
+ return (code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z) ||
84
+ (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z);
85
+ }
86
+ // Resolves . and .. elements in a path with directory names
87
+ function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
88
+ let res = '';
89
+ let lastSegmentLength = 0;
90
+ let lastSlash = -1;
91
+ let dots = 0;
92
+ let code = 0;
93
+ for (let i = 0; i <= path.length; ++i) {
94
+ if (i < path.length) {
95
+ code = path.charCodeAt(i);
96
+ }
97
+ else if (isPathSeparator(code)) {
98
+ break;
99
+ }
100
+ else {
101
+ code = CHAR_FORWARD_SLASH;
102
+ }
103
+ if (isPathSeparator(code)) {
104
+ if (lastSlash === i - 1 || dots === 1) {
105
+ // NOOP
106
+ }
107
+ else if (dots === 2) {
108
+ if (res.length < 2 || lastSegmentLength !== 2 ||
109
+ res.charCodeAt(res.length - 1) !== CHAR_DOT ||
110
+ res.charCodeAt(res.length - 2) !== CHAR_DOT) {
111
+ if (res.length > 2) {
112
+ const lastSlashIndex = res.lastIndexOf(separator);
113
+ if (lastSlashIndex === -1) {
114
+ res = '';
115
+ lastSegmentLength = 0;
116
+ }
117
+ else {
118
+ res = res.slice(0, lastSlashIndex);
119
+ lastSegmentLength = res.length - 1 - res.lastIndexOf(separator);
120
+ }
121
+ lastSlash = i;
122
+ dots = 0;
123
+ continue;
124
+ }
125
+ else if (res.length !== 0) {
126
+ res = '';
127
+ lastSegmentLength = 0;
128
+ lastSlash = i;
129
+ dots = 0;
130
+ continue;
131
+ }
132
+ }
133
+ if (allowAboveRoot) {
134
+ res += res.length > 0 ? `${separator}..` : '..';
135
+ lastSegmentLength = 2;
136
+ }
137
+ }
138
+ else {
139
+ if (res.length > 0) {
140
+ res += `${separator}${path.slice(lastSlash + 1, i)}`;
141
+ }
142
+ else {
143
+ res = path.slice(lastSlash + 1, i);
144
+ }
145
+ lastSegmentLength = i - lastSlash - 1;
146
+ }
147
+ lastSlash = i;
148
+ dots = 0;
149
+ }
150
+ else if (code === CHAR_DOT && dots !== -1) {
151
+ ++dots;
152
+ }
153
+ else {
154
+ dots = -1;
155
+ }
156
+ }
157
+ return res;
158
+ }
159
+ function formatExt(ext) {
160
+ return ext ? `${ext[0] === '.' ? '' : '.'}${ext}` : '';
161
+ }
162
+ function _format(sep, pathObject) {
163
+ validateObject(pathObject, 'pathObject');
164
+ const dir = pathObject.dir || pathObject.root;
165
+ const base = pathObject.base ||
166
+ `${pathObject.name || ''}${formatExt(pathObject.ext)}`;
167
+ if (!dir) {
168
+ return base;
169
+ }
170
+ return dir === pathObject.root ? `${dir}${base}` : `${dir}${sep}${base}`;
171
+ }
172
+ export const win32 = {
173
+ // path.resolve([from ...], to)
174
+ resolve(...pathSegments) {
175
+ let resolvedDevice = '';
176
+ let resolvedTail = '';
177
+ let resolvedAbsolute = false;
178
+ for (let i = pathSegments.length - 1; i >= -1; i--) {
179
+ let path;
180
+ if (i >= 0) {
181
+ path = pathSegments[i];
182
+ validateString(path, `paths[${i}]`);
183
+ // Skip empty entries
184
+ if (path.length === 0) {
185
+ continue;
186
+ }
187
+ }
188
+ else if (resolvedDevice.length === 0) {
189
+ path = process.cwd();
190
+ }
191
+ else {
192
+ // Windows has the concept of drive-specific current working
193
+ // directories. If we've resolved a drive letter but not yet an
194
+ // absolute path, get cwd for that drive, or the process cwd if
195
+ // the drive cwd is not available. We're sure the device is not
196
+ // a UNC path at this points, because UNC paths are always absolute.
197
+ path = process.env[`=${resolvedDevice}`] || process.cwd();
198
+ // Verify that a cwd was found and that it actually points
199
+ // to our drive. If not, default to the drive's root.
200
+ if (path === undefined ||
201
+ (path.slice(0, 2).toLowerCase() !== resolvedDevice.toLowerCase() &&
202
+ path.charCodeAt(2) === CHAR_BACKWARD_SLASH)) {
203
+ path = `${resolvedDevice}\\`;
204
+ }
205
+ }
206
+ const len = path.length;
207
+ let rootEnd = 0;
208
+ let device = '';
209
+ let isAbsolute = false;
210
+ const code = path.charCodeAt(0);
211
+ // Try to match a root
212
+ if (len === 1) {
213
+ if (isPathSeparator(code)) {
214
+ // `path` contains just a path separator
215
+ rootEnd = 1;
216
+ isAbsolute = true;
217
+ }
218
+ }
219
+ else if (isPathSeparator(code)) {
220
+ // Possible UNC root
221
+ // If we started with a separator, we know we at least have an
222
+ // absolute path of some kind (UNC or otherwise)
223
+ isAbsolute = true;
224
+ if (isPathSeparator(path.charCodeAt(1))) {
225
+ // Matched double path separator at beginning
226
+ let j = 2;
227
+ let last = j;
228
+ // Match 1 or more non-path separators
229
+ while (j < len && !isPathSeparator(path.charCodeAt(j))) {
230
+ j++;
231
+ }
232
+ if (j < len && j !== last) {
233
+ const firstPart = path.slice(last, j);
234
+ // Matched!
235
+ last = j;
236
+ // Match 1 or more path separators
237
+ while (j < len && isPathSeparator(path.charCodeAt(j))) {
238
+ j++;
239
+ }
240
+ if (j < len && j !== last) {
241
+ // Matched!
242
+ last = j;
243
+ // Match 1 or more non-path separators
244
+ while (j < len && !isPathSeparator(path.charCodeAt(j))) {
245
+ j++;
246
+ }
247
+ if (j === len || j !== last) {
248
+ // We matched a UNC root
249
+ device = `\\\\${firstPart}\\${path.slice(last, j)}`;
250
+ rootEnd = j;
251
+ }
252
+ }
253
+ }
254
+ }
255
+ else {
256
+ rootEnd = 1;
257
+ }
258
+ }
259
+ else if (isWindowsDeviceRoot(code) &&
260
+ path.charCodeAt(1) === CHAR_COLON) {
261
+ // Possible device root
262
+ device = path.slice(0, 2);
263
+ rootEnd = 2;
264
+ if (len > 2 && isPathSeparator(path.charCodeAt(2))) {
265
+ // Treat separator following drive name as an absolute path
266
+ // indicator
267
+ isAbsolute = true;
268
+ rootEnd = 3;
269
+ }
270
+ }
271
+ if (device.length > 0) {
272
+ if (resolvedDevice.length > 0) {
273
+ if (device.toLowerCase() !== resolvedDevice.toLowerCase()) {
274
+ // This path points to another device so it is not applicable
275
+ continue;
276
+ }
277
+ }
278
+ else {
279
+ resolvedDevice = device;
280
+ }
281
+ }
282
+ if (resolvedAbsolute) {
283
+ if (resolvedDevice.length > 0) {
284
+ break;
285
+ }
286
+ }
287
+ else {
288
+ resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`;
289
+ resolvedAbsolute = isAbsolute;
290
+ if (isAbsolute && resolvedDevice.length > 0) {
291
+ break;
292
+ }
293
+ }
294
+ }
295
+ // At this point the path should be resolved to a full absolute path,
296
+ // but handle relative paths to be safe (might happen when process.cwd()
297
+ // fails)
298
+ // Normalize the tail path
299
+ resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, '\\', isPathSeparator);
300
+ return resolvedAbsolute ?
301
+ `${resolvedDevice}\\${resolvedTail}` :
302
+ `${resolvedDevice}${resolvedTail}` || '.';
303
+ },
304
+ normalize(path) {
305
+ validateString(path, 'path');
306
+ const len = path.length;
307
+ if (len === 0) {
308
+ return '.';
309
+ }
310
+ let rootEnd = 0;
311
+ let device;
312
+ let isAbsolute = false;
313
+ const code = path.charCodeAt(0);
314
+ // Try to match a root
315
+ if (len === 1) {
316
+ // `path` contains just a single char, exit early to avoid
317
+ // unnecessary work
318
+ return isPosixPathSeparator(code) ? '\\' : path;
319
+ }
320
+ if (isPathSeparator(code)) {
321
+ // Possible UNC root
322
+ // If we started with a separator, we know we at least have an absolute
323
+ // path of some kind (UNC or otherwise)
324
+ isAbsolute = true;
325
+ if (isPathSeparator(path.charCodeAt(1))) {
326
+ // Matched double path separator at beginning
327
+ let j = 2;
328
+ let last = j;
329
+ // Match 1 or more non-path separators
330
+ while (j < len && !isPathSeparator(path.charCodeAt(j))) {
331
+ j++;
332
+ }
333
+ if (j < len && j !== last) {
334
+ const firstPart = path.slice(last, j);
335
+ // Matched!
336
+ last = j;
337
+ // Match 1 or more path separators
338
+ while (j < len && isPathSeparator(path.charCodeAt(j))) {
339
+ j++;
340
+ }
341
+ if (j < len && j !== last) {
342
+ // Matched!
343
+ last = j;
344
+ // Match 1 or more non-path separators
345
+ while (j < len && !isPathSeparator(path.charCodeAt(j))) {
346
+ j++;
347
+ }
348
+ if (j === len) {
349
+ // We matched a UNC root only
350
+ // Return the normalized version of the UNC root since there
351
+ // is nothing left to process
352
+ return `\\\\${firstPart}\\${path.slice(last)}\\`;
353
+ }
354
+ if (j !== last) {
355
+ // We matched a UNC root with leftovers
356
+ device = `\\\\${firstPart}\\${path.slice(last, j)}`;
357
+ rootEnd = j;
358
+ }
359
+ }
360
+ }
361
+ }
362
+ else {
363
+ rootEnd = 1;
364
+ }
365
+ }
366
+ else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {
367
+ // Possible device root
368
+ device = path.slice(0, 2);
369
+ rootEnd = 2;
370
+ if (len > 2 && isPathSeparator(path.charCodeAt(2))) {
371
+ // Treat separator following drive name as an absolute path
372
+ // indicator
373
+ isAbsolute = true;
374
+ rootEnd = 3;
375
+ }
376
+ }
377
+ let tail = rootEnd < len ?
378
+ normalizeString(path.slice(rootEnd), !isAbsolute, '\\', isPathSeparator) :
379
+ '';
380
+ if (tail.length === 0 && !isAbsolute) {
381
+ tail = '.';
382
+ }
383
+ if (tail.length > 0 && isPathSeparator(path.charCodeAt(len - 1))) {
384
+ tail += '\\';
385
+ }
386
+ if (!isAbsolute && device === undefined && path.includes(':')) {
387
+ // If the original path was not absolute and if we have not been able to
388
+ // resolve it relative to a particular device, we need to ensure that the
389
+ // `tail` has not become something that Windows might interpret as an
390
+ // absolute path. See CVE-2024-36139.
391
+ if (tail.length >= 2 &&
392
+ isWindowsDeviceRoot(tail.charCodeAt(0)) &&
393
+ tail.charCodeAt(1) === CHAR_COLON) {
394
+ return `.\\${tail}`;
395
+ }
396
+ let index = path.indexOf(':');
397
+ do {
398
+ if (index === len - 1 || isPathSeparator(path.charCodeAt(index + 1))) {
399
+ return `.\\${tail}`;
400
+ }
401
+ } while ((index = path.indexOf(':', index + 1)) !== -1);
402
+ }
403
+ if (device === undefined) {
404
+ return isAbsolute ? `\\${tail}` : tail;
405
+ }
406
+ return isAbsolute ? `${device}\\${tail}` : `${device}${tail}`;
407
+ },
408
+ isAbsolute(path) {
409
+ validateString(path, 'path');
410
+ const len = path.length;
411
+ if (len === 0) {
412
+ return false;
413
+ }
414
+ const code = path.charCodeAt(0);
415
+ return isPathSeparator(code) ||
416
+ // Possible device root
417
+ (len > 2 &&
418
+ isWindowsDeviceRoot(code) &&
419
+ path.charCodeAt(1) === CHAR_COLON &&
420
+ isPathSeparator(path.charCodeAt(2)));
421
+ },
422
+ join(...paths) {
423
+ if (paths.length === 0) {
424
+ return '.';
425
+ }
426
+ let joined;
427
+ let firstPart;
428
+ for (let i = 0; i < paths.length; ++i) {
429
+ const arg = paths[i];
430
+ validateString(arg, 'path');
431
+ if (arg.length > 0) {
432
+ if (joined === undefined) {
433
+ joined = firstPart = arg;
434
+ }
435
+ else {
436
+ joined += `\\${arg}`;
437
+ }
438
+ }
439
+ }
440
+ if (joined === undefined) {
441
+ return '.';
442
+ }
443
+ // Make sure that the joined path doesn't start with two slashes, because
444
+ // normalize() will mistake it for a UNC path then.
445
+ //
446
+ // This step is skipped when it is very clear that the user actually
447
+ // intended to point at a UNC path. This is assumed when the first
448
+ // non-empty string arguments starts with exactly two slashes followed by
449
+ // at least one more non-slash character.
450
+ //
451
+ // Note that for normalize() to treat a path as a UNC path it needs to
452
+ // have at least 2 components, so we don't filter for that here.
453
+ // This means that the user can use join to construct UNC paths from
454
+ // a server name and a share name; for example:
455
+ // path.join('//server', 'share') -> '\\\\server\\share\\')
456
+ let needsReplace = true;
457
+ let slashCount = 0;
458
+ if (typeof firstPart === 'string' && isPathSeparator(firstPart.charCodeAt(0))) {
459
+ ++slashCount;
460
+ const firstLen = firstPart.length;
461
+ if (firstLen > 1 && isPathSeparator(firstPart.charCodeAt(1))) {
462
+ ++slashCount;
463
+ if (firstLen > 2) {
464
+ if (isPathSeparator(firstPart.charCodeAt(2))) {
465
+ ++slashCount;
466
+ }
467
+ else {
468
+ // We matched a UNC path in the first part
469
+ needsReplace = false;
470
+ }
471
+ }
472
+ }
473
+ }
474
+ if (needsReplace) {
475
+ // Find any more consecutive slashes we need to replace
476
+ while (slashCount < joined.length &&
477
+ isPathSeparator(joined.charCodeAt(slashCount))) {
478
+ slashCount++;
479
+ }
480
+ // Replace the slashes if needed
481
+ if (slashCount >= 2) {
482
+ joined = `\\${joined.slice(slashCount)}`;
483
+ }
484
+ }
485
+ return win32.normalize(joined);
486
+ },
487
+ // It will solve the relative path from `from` to `to`, for instance:
488
+ // from = 'C:\\orandea\\test\\aaa'
489
+ // to = 'C:\\orandea\\impl\\bbb'
490
+ // The output of the function should be: '..\\..\\impl\\bbb'
491
+ relative(from, to) {
492
+ validateString(from, 'from');
493
+ validateString(to, 'to');
494
+ if (from === to) {
495
+ return '';
496
+ }
497
+ const fromOrig = win32.resolve(from);
498
+ const toOrig = win32.resolve(to);
499
+ if (fromOrig === toOrig) {
500
+ return '';
501
+ }
502
+ from = fromOrig.toLowerCase();
503
+ to = toOrig.toLowerCase();
504
+ if (from === to) {
505
+ return '';
506
+ }
507
+ if (fromOrig.length !== from.length || toOrig.length !== to.length) {
508
+ const fromSplit = fromOrig.split('\\');
509
+ const toSplit = toOrig.split('\\');
510
+ if (fromSplit[fromSplit.length - 1] === '') {
511
+ fromSplit.pop();
512
+ }
513
+ if (toSplit[toSplit.length - 1] === '') {
514
+ toSplit.pop();
515
+ }
516
+ const fromLen = fromSplit.length;
517
+ const toLen = toSplit.length;
518
+ const length = fromLen < toLen ? fromLen : toLen;
519
+ let i;
520
+ for (i = 0; i < length; i++) {
521
+ if (fromSplit[i].toLowerCase() !== toSplit[i].toLowerCase()) {
522
+ break;
523
+ }
524
+ }
525
+ if (i === 0) {
526
+ return toOrig;
527
+ }
528
+ else if (i === length) {
529
+ if (toLen > length) {
530
+ return toSplit.slice(i).join('\\');
531
+ }
532
+ if (fromLen > length) {
533
+ return '..\\'.repeat(fromLen - 1 - i) + '..';
534
+ }
535
+ return '';
536
+ }
537
+ return '..\\'.repeat(fromLen - i) + toSplit.slice(i).join('\\');
538
+ }
539
+ // Trim any leading backslashes
540
+ let fromStart = 0;
541
+ while (fromStart < from.length &&
542
+ from.charCodeAt(fromStart) === CHAR_BACKWARD_SLASH) {
543
+ fromStart++;
544
+ }
545
+ // Trim trailing backslashes (applicable to UNC paths only)
546
+ let fromEnd = from.length;
547
+ while (fromEnd - 1 > fromStart &&
548
+ from.charCodeAt(fromEnd - 1) === CHAR_BACKWARD_SLASH) {
549
+ fromEnd--;
550
+ }
551
+ const fromLen = fromEnd - fromStart;
552
+ // Trim any leading backslashes
553
+ let toStart = 0;
554
+ while (toStart < to.length &&
555
+ to.charCodeAt(toStart) === CHAR_BACKWARD_SLASH) {
556
+ toStart++;
557
+ }
558
+ // Trim trailing backslashes (applicable to UNC paths only)
559
+ let toEnd = to.length;
560
+ while (toEnd - 1 > toStart &&
561
+ to.charCodeAt(toEnd - 1) === CHAR_BACKWARD_SLASH) {
562
+ toEnd--;
563
+ }
564
+ const toLen = toEnd - toStart;
565
+ // Compare paths to find the longest common path from root
566
+ const length = fromLen < toLen ? fromLen : toLen;
567
+ let lastCommonSep = -1;
568
+ let i = 0;
569
+ for (; i < length; i++) {
570
+ const fromCode = from.charCodeAt(fromStart + i);
571
+ if (fromCode !== to.charCodeAt(toStart + i)) {
572
+ break;
573
+ }
574
+ else if (fromCode === CHAR_BACKWARD_SLASH) {
575
+ lastCommonSep = i;
576
+ }
577
+ }
578
+ // We found a mismatch before the first common path separator was seen, so
579
+ // return the original `to`.
580
+ if (i !== length) {
581
+ if (lastCommonSep === -1) {
582
+ return toOrig;
583
+ }
584
+ }
585
+ else {
586
+ if (toLen > length) {
587
+ if (to.charCodeAt(toStart + i) === CHAR_BACKWARD_SLASH) {
588
+ // We get here if `from` is the exact base path for `to`.
589
+ // For example: from='C:\\foo\\bar'; to='C:\\foo\\bar\\baz'
590
+ return toOrig.slice(toStart + i + 1);
591
+ }
592
+ if (i === 2) {
593
+ // We get here if `from` is the device root.
594
+ // For example: from='C:\\'; to='C:\\foo'
595
+ return toOrig.slice(toStart + i);
596
+ }
597
+ }
598
+ if (fromLen > length) {
599
+ if (from.charCodeAt(fromStart + i) === CHAR_BACKWARD_SLASH) {
600
+ // We get here if `to` is the exact base path for `from`.
601
+ // For example: from='C:\\foo\\bar'; to='C:\\foo'
602
+ lastCommonSep = i;
603
+ }
604
+ else if (i === 2) {
605
+ // We get here if `to` is the device root.
606
+ // For example: from='C:\\foo\\bar'; to='C:\\'
607
+ lastCommonSep = 3;
608
+ }
609
+ }
610
+ if (lastCommonSep === -1) {
611
+ lastCommonSep = 0;
612
+ }
613
+ }
614
+ let out = '';
615
+ // Generate the relative path based on the path difference between `to` and
616
+ // `from`
617
+ for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
618
+ if (i === fromEnd || from.charCodeAt(i) === CHAR_BACKWARD_SLASH) {
619
+ out += out.length === 0 ? '..' : '\\..';
620
+ }
621
+ }
622
+ toStart += lastCommonSep;
623
+ // Lastly, append the rest of the destination (`to`) path that comes after
624
+ // the common path parts
625
+ if (out.length > 0) {
626
+ return `${out}${toOrig.slice(toStart, toEnd)}`;
627
+ }
628
+ if (toOrig.charCodeAt(toStart) === CHAR_BACKWARD_SLASH) {
629
+ ++toStart;
630
+ }
631
+ return toOrig.slice(toStart, toEnd);
632
+ },
633
+ toNamespacedPath(path) {
634
+ // Note: this will *probably* throw somewhere.
635
+ if (typeof path !== 'string' || path.length === 0) {
636
+ return path;
637
+ }
638
+ const resolvedPath = win32.resolve(path);
639
+ if (resolvedPath.length <= 2) {
640
+ return path;
641
+ }
642
+ if (resolvedPath.charCodeAt(0) === CHAR_BACKWARD_SLASH) {
643
+ // Possible UNC root
644
+ if (resolvedPath.charCodeAt(1) === CHAR_BACKWARD_SLASH) {
645
+ const code = resolvedPath.charCodeAt(2);
646
+ if (code !== CHAR_QUESTION_MARK && code !== CHAR_DOT) {
647
+ // Matched non-long UNC root, convert the path to a long UNC path
648
+ return `\\\\?\\UNC\\${resolvedPath.slice(2)}`;
649
+ }
650
+ }
651
+ }
652
+ else if (isWindowsDeviceRoot(resolvedPath.charCodeAt(0)) &&
653
+ resolvedPath.charCodeAt(1) === CHAR_COLON &&
654
+ resolvedPath.charCodeAt(2) === CHAR_BACKWARD_SLASH) {
655
+ // Matched device root, convert the path to a long UNC path
656
+ return `\\\\?\\${resolvedPath}`;
657
+ }
658
+ return resolvedPath;
659
+ },
660
+ dirname(path) {
661
+ validateString(path, 'path');
662
+ const len = path.length;
663
+ if (len === 0) {
664
+ return '.';
665
+ }
666
+ let rootEnd = -1;
667
+ let offset = 0;
668
+ const code = path.charCodeAt(0);
669
+ if (len === 1) {
670
+ // `path` contains just a path separator, exit early to avoid
671
+ // unnecessary work or a dot.
672
+ return isPathSeparator(code) ? path : '.';
673
+ }
674
+ // Try to match a root
675
+ if (isPathSeparator(code)) {
676
+ // Possible UNC root
677
+ rootEnd = offset = 1;
678
+ if (isPathSeparator(path.charCodeAt(1))) {
679
+ // Matched double path separator at beginning
680
+ let j = 2;
681
+ let last = j;
682
+ // Match 1 or more non-path separators
683
+ while (j < len && !isPathSeparator(path.charCodeAt(j))) {
684
+ j++;
685
+ }
686
+ if (j < len && j !== last) {
687
+ // Matched!
688
+ last = j;
689
+ // Match 1 or more path separators
690
+ while (j < len && isPathSeparator(path.charCodeAt(j))) {
691
+ j++;
692
+ }
693
+ if (j < len && j !== last) {
694
+ // Matched!
695
+ last = j;
696
+ // Match 1 or more non-path separators
697
+ while (j < len && !isPathSeparator(path.charCodeAt(j))) {
698
+ j++;
699
+ }
700
+ if (j === len) {
701
+ // We matched a UNC root only
702
+ return path;
703
+ }
704
+ if (j !== last) {
705
+ // We matched a UNC root with leftovers
706
+ // Offset by 1 to include the separator after the UNC root to
707
+ // treat it as a "normal root" on top of a (UNC) root
708
+ rootEnd = offset = j + 1;
709
+ }
710
+ }
711
+ }
712
+ }
713
+ // Possible device root
714
+ }
715
+ else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {
716
+ rootEnd = len > 2 && isPathSeparator(path.charCodeAt(2)) ? 3 : 2;
717
+ offset = rootEnd;
718
+ }
719
+ let end = -1;
720
+ let matchedSlash = true;
721
+ for (let i = len - 1; i >= offset; --i) {
722
+ if (isPathSeparator(path.charCodeAt(i))) {
723
+ if (!matchedSlash) {
724
+ end = i;
725
+ break;
726
+ }
727
+ }
728
+ else {
729
+ // We saw the first non-path separator
730
+ matchedSlash = false;
731
+ }
732
+ }
733
+ if (end === -1) {
734
+ if (rootEnd === -1) {
735
+ return '.';
736
+ }
737
+ end = rootEnd;
738
+ }
739
+ return path.slice(0, end);
740
+ },
741
+ basename(path, suffix) {
742
+ if (suffix !== undefined) {
743
+ validateString(suffix, 'suffix');
744
+ }
745
+ validateString(path, 'path');
746
+ let start = 0;
747
+ let end = -1;
748
+ let matchedSlash = true;
749
+ let i;
750
+ // Check for a drive letter prefix so as not to mistake the following
751
+ // path separator as an extra separator at the end of the path that can be
752
+ // disregarded
753
+ if (path.length >= 2 &&
754
+ isWindowsDeviceRoot(path.charCodeAt(0)) &&
755
+ path.charCodeAt(1) === CHAR_COLON) {
756
+ start = 2;
757
+ }
758
+ if (suffix !== undefined && suffix.length > 0 && suffix.length <= path.length) {
759
+ if (suffix === path) {
760
+ return '';
761
+ }
762
+ let extIdx = suffix.length - 1;
763
+ let firstNonSlashEnd = -1;
764
+ for (i = path.length - 1; i >= start; --i) {
765
+ const code = path.charCodeAt(i);
766
+ if (isPathSeparator(code)) {
767
+ // If we reached a path separator that was not part of a set of path
768
+ // separators at the end of the string, stop now
769
+ if (!matchedSlash) {
770
+ start = i + 1;
771
+ break;
772
+ }
773
+ }
774
+ else {
775
+ if (firstNonSlashEnd === -1) {
776
+ // We saw the first non-path separator, remember this index in case
777
+ // we need it if the extension ends up not matching
778
+ matchedSlash = false;
779
+ firstNonSlashEnd = i + 1;
780
+ }
781
+ if (extIdx >= 0) {
782
+ // Try to match the explicit extension
783
+ if (code === suffix.charCodeAt(extIdx)) {
784
+ if (--extIdx === -1) {
785
+ // We matched the extension, so mark this as the end of our path
786
+ // component
787
+ end = i;
788
+ }
789
+ }
790
+ else {
791
+ // Extension does not match, so our result is the entire path
792
+ // component
793
+ extIdx = -1;
794
+ end = firstNonSlashEnd;
795
+ }
796
+ }
797
+ }
798
+ }
799
+ if (start === end) {
800
+ end = firstNonSlashEnd;
801
+ }
802
+ else if (end === -1) {
803
+ end = path.length;
804
+ }
805
+ return path.slice(start, end);
806
+ }
807
+ for (i = path.length - 1; i >= start; --i) {
808
+ if (isPathSeparator(path.charCodeAt(i))) {
809
+ // If we reached a path separator that was not part of a set of path
810
+ // separators at the end of the string, stop now
811
+ if (!matchedSlash) {
812
+ start = i + 1;
813
+ break;
814
+ }
815
+ }
816
+ else if (end === -1) {
817
+ // We saw the first non-path separator, mark this as the end of our
818
+ // path component
819
+ matchedSlash = false;
820
+ end = i + 1;
821
+ }
822
+ }
823
+ if (end === -1) {
824
+ return '';
825
+ }
826
+ return path.slice(start, end);
827
+ },
828
+ extname(path) {
829
+ validateString(path, 'path');
830
+ let start = 0;
831
+ let startDot = -1;
832
+ let startPart = 0;
833
+ let end = -1;
834
+ let matchedSlash = true;
835
+ // Track the state of characters (if any) we see before our first dot and
836
+ // after any path separator we find
837
+ let preDotState = 0;
838
+ // Check for a drive letter prefix so as not to mistake the following
839
+ // path separator as an extra separator at the end of the path that can be
840
+ // disregarded
841
+ if (path.length >= 2 &&
842
+ path.charCodeAt(1) === CHAR_COLON &&
843
+ isWindowsDeviceRoot(path.charCodeAt(0))) {
844
+ start = startPart = 2;
845
+ }
846
+ for (let i = path.length - 1; i >= start; --i) {
847
+ const code = path.charCodeAt(i);
848
+ if (isPathSeparator(code)) {
849
+ // If we reached a path separator that was not part of a set of path
850
+ // separators at the end of the string, stop now
851
+ if (!matchedSlash) {
852
+ startPart = i + 1;
853
+ break;
854
+ }
855
+ continue;
856
+ }
857
+ if (end === -1) {
858
+ // We saw the first non-path separator, mark this as the end of our
859
+ // extension
860
+ matchedSlash = false;
861
+ end = i + 1;
862
+ }
863
+ if (code === CHAR_DOT) {
864
+ // If this is our first dot, mark it as the start of our extension
865
+ if (startDot === -1) {
866
+ startDot = i;
867
+ }
868
+ else if (preDotState !== 1) {
869
+ preDotState = 1;
870
+ }
871
+ }
872
+ else if (startDot !== -1) {
873
+ // We saw a non-dot and non-path separator before our dot, so we should
874
+ // have a good chance at having a non-empty extension
875
+ preDotState = -1;
876
+ }
877
+ }
878
+ if (startDot === -1 ||
879
+ end === -1 ||
880
+ // We saw a non-dot character immediately before the dot
881
+ preDotState === 0 ||
882
+ // The (right-most) trimmed path component is exactly '..'
883
+ (preDotState === 1 &&
884
+ startDot === end - 1 &&
885
+ startDot === startPart + 1)) {
886
+ return '';
887
+ }
888
+ return path.slice(startDot, end);
889
+ },
890
+ format: _format.bind(null, '\\'),
891
+ parse(path) {
892
+ validateString(path, 'path');
893
+ const ret = { root: '', dir: '', base: '', ext: '', name: '' };
894
+ if (path.length === 0) {
895
+ return ret;
896
+ }
897
+ const len = path.length;
898
+ let rootEnd = 0;
899
+ let code = path.charCodeAt(0);
900
+ if (len === 1) {
901
+ if (isPathSeparator(code)) {
902
+ // `path` contains just a path separator, exit early to avoid
903
+ // unnecessary work
904
+ ret.root = ret.dir = path;
905
+ return ret;
906
+ }
907
+ ret.base = ret.name = path;
908
+ return ret;
909
+ }
910
+ // Try to match a root
911
+ if (isPathSeparator(code)) {
912
+ // Possible UNC root
913
+ rootEnd = 1;
914
+ if (isPathSeparator(path.charCodeAt(1))) {
915
+ // Matched double path separator at beginning
916
+ let j = 2;
917
+ let last = j;
918
+ // Match 1 or more non-path separators
919
+ while (j < len && !isPathSeparator(path.charCodeAt(j))) {
920
+ j++;
921
+ }
922
+ if (j < len && j !== last) {
923
+ // Matched!
924
+ last = j;
925
+ // Match 1 or more path separators
926
+ while (j < len && isPathSeparator(path.charCodeAt(j))) {
927
+ j++;
928
+ }
929
+ if (j < len && j !== last) {
930
+ // Matched!
931
+ last = j;
932
+ // Match 1 or more non-path separators
933
+ while (j < len && !isPathSeparator(path.charCodeAt(j))) {
934
+ j++;
935
+ }
936
+ if (j === len) {
937
+ // We matched a UNC root only
938
+ rootEnd = j;
939
+ }
940
+ else if (j !== last) {
941
+ // We matched a UNC root with leftovers
942
+ rootEnd = j + 1;
943
+ }
944
+ }
945
+ }
946
+ }
947
+ }
948
+ else if (isWindowsDeviceRoot(code) && path.charCodeAt(1) === CHAR_COLON) {
949
+ // Possible device root
950
+ if (len <= 2) {
951
+ // `path` contains just a drive root, exit early to avoid
952
+ // unnecessary work
953
+ ret.root = ret.dir = path;
954
+ return ret;
955
+ }
956
+ rootEnd = 2;
957
+ if (isPathSeparator(path.charCodeAt(2))) {
958
+ if (len === 3) {
959
+ // `path` contains just a drive root, exit early to avoid
960
+ // unnecessary work
961
+ ret.root = ret.dir = path;
962
+ return ret;
963
+ }
964
+ rootEnd = 3;
965
+ }
966
+ }
967
+ if (rootEnd > 0) {
968
+ ret.root = path.slice(0, rootEnd);
969
+ }
970
+ let startDot = -1;
971
+ let startPart = rootEnd;
972
+ let end = -1;
973
+ let matchedSlash = true;
974
+ let i = path.length - 1;
975
+ // Track the state of characters (if any) we see before our first dot and
976
+ // after any path separator we find
977
+ let preDotState = 0;
978
+ // Get non-dir info
979
+ for (; i >= rootEnd; --i) {
980
+ code = path.charCodeAt(i);
981
+ if (isPathSeparator(code)) {
982
+ // If we reached a path separator that was not part of a set of path
983
+ // separators at the end of the string, stop now
984
+ if (!matchedSlash) {
985
+ startPart = i + 1;
986
+ break;
987
+ }
988
+ continue;
989
+ }
990
+ if (end === -1) {
991
+ // We saw the first non-path separator, mark this as the end of our
992
+ // extension
993
+ matchedSlash = false;
994
+ end = i + 1;
995
+ }
996
+ if (code === CHAR_DOT) {
997
+ // If this is our first dot, mark it as the start of our extension
998
+ if (startDot === -1) {
999
+ startDot = i;
1000
+ }
1001
+ else if (preDotState !== 1) {
1002
+ preDotState = 1;
1003
+ }
1004
+ }
1005
+ else if (startDot !== -1) {
1006
+ // We saw a non-dot and non-path separator before our dot, so we should
1007
+ // have a good chance at having a non-empty extension
1008
+ preDotState = -1;
1009
+ }
1010
+ }
1011
+ if (end !== -1) {
1012
+ if (startDot === -1 ||
1013
+ // We saw a non-dot character immediately before the dot
1014
+ preDotState === 0 ||
1015
+ // The (right-most) trimmed path component is exactly '..'
1016
+ (preDotState === 1 &&
1017
+ startDot === end - 1 &&
1018
+ startDot === startPart + 1)) {
1019
+ ret.base = ret.name = path.slice(startPart, end);
1020
+ }
1021
+ else {
1022
+ ret.name = path.slice(startPart, startDot);
1023
+ ret.base = path.slice(startPart, end);
1024
+ ret.ext = path.slice(startDot, end);
1025
+ }
1026
+ }
1027
+ // If the directory is the root, use the entire root as the `dir` including
1028
+ // the trailing slash if any (`C:\abc` -> `C:\`). Otherwise, strip out the
1029
+ // trailing slash (`C:\abc\def` -> `C:\abc`).
1030
+ if (startPart > 0 && startPart !== rootEnd) {
1031
+ ret.dir = path.slice(0, startPart - 1);
1032
+ }
1033
+ else {
1034
+ ret.dir = ret.root;
1035
+ }
1036
+ return ret;
1037
+ },
1038
+ sep: '\\',
1039
+ delimiter: ';',
1040
+ win32: null,
1041
+ posix: null
1042
+ };
1043
+ const posixCwd = (() => {
1044
+ if (platformIsWin32) {
1045
+ // Converts Windows' backslash path separators to POSIX forward slashes
1046
+ // and truncates any drive indicator
1047
+ const regexp = /\\/g;
1048
+ return () => {
1049
+ const cwd = process.cwd().replace(regexp, '/');
1050
+ return cwd.slice(cwd.indexOf('/'));
1051
+ };
1052
+ }
1053
+ // We're already on POSIX, no need for any transformations
1054
+ return () => process.cwd();
1055
+ })();
1056
+ export const posix = {
1057
+ // path.resolve([from ...], to)
1058
+ resolve(...pathSegments) {
1059
+ let resolvedPath = '';
1060
+ let resolvedAbsolute = false;
1061
+ for (let i = pathSegments.length - 1; i >= 0 && !resolvedAbsolute; i--) {
1062
+ const path = pathSegments[i];
1063
+ validateString(path, `paths[${i}]`);
1064
+ // Skip empty entries
1065
+ if (path.length === 0) {
1066
+ continue;
1067
+ }
1068
+ resolvedPath = `${path}/${resolvedPath}`;
1069
+ resolvedAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;
1070
+ }
1071
+ if (!resolvedAbsolute) {
1072
+ const cwd = posixCwd();
1073
+ resolvedPath = `${cwd}/${resolvedPath}`;
1074
+ resolvedAbsolute =
1075
+ cwd.charCodeAt(0) === CHAR_FORWARD_SLASH;
1076
+ }
1077
+ // At this point the path should be resolved to a full absolute path, but
1078
+ // handle relative paths to be safe (might happen when process.cwd() fails)
1079
+ // Normalize the path
1080
+ resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, '/', isPosixPathSeparator);
1081
+ if (resolvedAbsolute) {
1082
+ return `/${resolvedPath}`;
1083
+ }
1084
+ return resolvedPath.length > 0 ? resolvedPath : '.';
1085
+ },
1086
+ normalize(path) {
1087
+ validateString(path, 'path');
1088
+ if (path.length === 0) {
1089
+ return '.';
1090
+ }
1091
+ const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;
1092
+ const trailingSeparator = path.charCodeAt(path.length - 1) === CHAR_FORWARD_SLASH;
1093
+ // Normalize the path
1094
+ path = normalizeString(path, !isAbsolute, '/', isPosixPathSeparator);
1095
+ if (path.length === 0) {
1096
+ if (isAbsolute) {
1097
+ return '/';
1098
+ }
1099
+ return trailingSeparator ? './' : '.';
1100
+ }
1101
+ if (trailingSeparator) {
1102
+ path += '/';
1103
+ }
1104
+ return isAbsolute ? `/${path}` : path;
1105
+ },
1106
+ isAbsolute(path) {
1107
+ validateString(path, 'path');
1108
+ return path.length > 0 && path.charCodeAt(0) === CHAR_FORWARD_SLASH;
1109
+ },
1110
+ join(...paths) {
1111
+ if (paths.length === 0) {
1112
+ return '.';
1113
+ }
1114
+ const path = [];
1115
+ for (let i = 0; i < paths.length; ++i) {
1116
+ const arg = paths[i];
1117
+ validateString(arg, 'path');
1118
+ if (arg.length > 0) {
1119
+ path.push(arg);
1120
+ }
1121
+ }
1122
+ if (path.length === 0) {
1123
+ return '.';
1124
+ }
1125
+ return posix.normalize(path.join('/'));
1126
+ },
1127
+ relative(from, to) {
1128
+ validateString(from, 'from');
1129
+ validateString(to, 'to');
1130
+ if (from === to) {
1131
+ return '';
1132
+ }
1133
+ // Trim leading forward slashes.
1134
+ from = posix.resolve(from);
1135
+ to = posix.resolve(to);
1136
+ if (from === to) {
1137
+ return '';
1138
+ }
1139
+ const fromStart = 1;
1140
+ const fromEnd = from.length;
1141
+ const fromLen = fromEnd - fromStart;
1142
+ const toStart = 1;
1143
+ const toLen = to.length - toStart;
1144
+ // Compare paths to find the longest common path from root
1145
+ const length = (fromLen < toLen ? fromLen : toLen);
1146
+ let lastCommonSep = -1;
1147
+ let i = 0;
1148
+ for (; i < length; i++) {
1149
+ const fromCode = from.charCodeAt(fromStart + i);
1150
+ if (fromCode !== to.charCodeAt(toStart + i)) {
1151
+ break;
1152
+ }
1153
+ else if (fromCode === CHAR_FORWARD_SLASH) {
1154
+ lastCommonSep = i;
1155
+ }
1156
+ }
1157
+ if (i === length) {
1158
+ if (toLen > length) {
1159
+ if (to.charCodeAt(toStart + i) === CHAR_FORWARD_SLASH) {
1160
+ // We get here if `from` is the exact base path for `to`.
1161
+ // For example: from='/foo/bar'; to='/foo/bar/baz'
1162
+ return to.slice(toStart + i + 1);
1163
+ }
1164
+ if (i === 0) {
1165
+ // We get here if `from` is the root
1166
+ // For example: from='/'; to='/foo'
1167
+ return to.slice(toStart + i);
1168
+ }
1169
+ }
1170
+ else if (fromLen > length) {
1171
+ if (from.charCodeAt(fromStart + i) === CHAR_FORWARD_SLASH) {
1172
+ // We get here if `to` is the exact base path for `from`.
1173
+ // For example: from='/foo/bar/baz'; to='/foo/bar'
1174
+ lastCommonSep = i;
1175
+ }
1176
+ else if (i === 0) {
1177
+ // We get here if `to` is the root.
1178
+ // For example: from='/foo/bar'; to='/'
1179
+ lastCommonSep = 0;
1180
+ }
1181
+ }
1182
+ }
1183
+ let out = '';
1184
+ // Generate the relative path based on the path difference between `to`
1185
+ // and `from`.
1186
+ for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
1187
+ if (i === fromEnd || from.charCodeAt(i) === CHAR_FORWARD_SLASH) {
1188
+ out += out.length === 0 ? '..' : '/..';
1189
+ }
1190
+ }
1191
+ // Lastly, append the rest of the destination (`to`) path that comes after
1192
+ // the common path parts.
1193
+ return `${out}${to.slice(toStart + lastCommonSep)}`;
1194
+ },
1195
+ toNamespacedPath(path) {
1196
+ // Non-op on posix systems
1197
+ return path;
1198
+ },
1199
+ dirname(path) {
1200
+ validateString(path, 'path');
1201
+ if (path.length === 0) {
1202
+ return '.';
1203
+ }
1204
+ const hasRoot = path.charCodeAt(0) === CHAR_FORWARD_SLASH;
1205
+ let end = -1;
1206
+ let matchedSlash = true;
1207
+ for (let i = path.length - 1; i >= 1; --i) {
1208
+ if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) {
1209
+ if (!matchedSlash) {
1210
+ end = i;
1211
+ break;
1212
+ }
1213
+ }
1214
+ else {
1215
+ // We saw the first non-path separator
1216
+ matchedSlash = false;
1217
+ }
1218
+ }
1219
+ if (end === -1) {
1220
+ return hasRoot ? '/' : '.';
1221
+ }
1222
+ if (hasRoot && end === 1) {
1223
+ return '//';
1224
+ }
1225
+ return path.slice(0, end);
1226
+ },
1227
+ basename(path, suffix) {
1228
+ if (suffix !== undefined) {
1229
+ validateString(suffix, 'suffix');
1230
+ }
1231
+ validateString(path, 'path');
1232
+ let start = 0;
1233
+ let end = -1;
1234
+ let matchedSlash = true;
1235
+ let i;
1236
+ if (suffix !== undefined && suffix.length > 0 && suffix.length <= path.length) {
1237
+ if (suffix === path) {
1238
+ return '';
1239
+ }
1240
+ let extIdx = suffix.length - 1;
1241
+ let firstNonSlashEnd = -1;
1242
+ for (i = path.length - 1; i >= 0; --i) {
1243
+ const code = path.charCodeAt(i);
1244
+ if (code === CHAR_FORWARD_SLASH) {
1245
+ // If we reached a path separator that was not part of a set of path
1246
+ // separators at the end of the string, stop now
1247
+ if (!matchedSlash) {
1248
+ start = i + 1;
1249
+ break;
1250
+ }
1251
+ }
1252
+ else {
1253
+ if (firstNonSlashEnd === -1) {
1254
+ // We saw the first non-path separator, remember this index in case
1255
+ // we need it if the extension ends up not matching
1256
+ matchedSlash = false;
1257
+ firstNonSlashEnd = i + 1;
1258
+ }
1259
+ if (extIdx >= 0) {
1260
+ // Try to match the explicit extension
1261
+ if (code === suffix.charCodeAt(extIdx)) {
1262
+ if (--extIdx === -1) {
1263
+ // We matched the extension, so mark this as the end of our path
1264
+ // component
1265
+ end = i;
1266
+ }
1267
+ }
1268
+ else {
1269
+ // Extension does not match, so our result is the entire path
1270
+ // component
1271
+ extIdx = -1;
1272
+ end = firstNonSlashEnd;
1273
+ }
1274
+ }
1275
+ }
1276
+ }
1277
+ if (start === end) {
1278
+ end = firstNonSlashEnd;
1279
+ }
1280
+ else if (end === -1) {
1281
+ end = path.length;
1282
+ }
1283
+ return path.slice(start, end);
1284
+ }
1285
+ for (i = path.length - 1; i >= 0; --i) {
1286
+ if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) {
1287
+ // If we reached a path separator that was not part of a set of path
1288
+ // separators at the end of the string, stop now
1289
+ if (!matchedSlash) {
1290
+ start = i + 1;
1291
+ break;
1292
+ }
1293
+ }
1294
+ else if (end === -1) {
1295
+ // We saw the first non-path separator, mark this as the end of our
1296
+ // path component
1297
+ matchedSlash = false;
1298
+ end = i + 1;
1299
+ }
1300
+ }
1301
+ if (end === -1) {
1302
+ return '';
1303
+ }
1304
+ return path.slice(start, end);
1305
+ },
1306
+ extname(path) {
1307
+ validateString(path, 'path');
1308
+ let startDot = -1;
1309
+ let startPart = 0;
1310
+ let end = -1;
1311
+ let matchedSlash = true;
1312
+ // Track the state of characters (if any) we see before our first dot and
1313
+ // after any path separator we find
1314
+ let preDotState = 0;
1315
+ for (let i = path.length - 1; i >= 0; --i) {
1316
+ const char = path[i];
1317
+ if (char === '/') {
1318
+ // If we reached a path separator that was not part of a set of path
1319
+ // separators at the end of the string, stop now
1320
+ if (!matchedSlash) {
1321
+ startPart = i + 1;
1322
+ break;
1323
+ }
1324
+ continue;
1325
+ }
1326
+ if (end === -1) {
1327
+ // We saw the first non-path separator, mark this as the end of our
1328
+ // extension
1329
+ matchedSlash = false;
1330
+ end = i + 1;
1331
+ }
1332
+ if (char === '.') {
1333
+ // If this is our first dot, mark it as the start of our extension
1334
+ if (startDot === -1) {
1335
+ startDot = i;
1336
+ }
1337
+ else if (preDotState !== 1) {
1338
+ preDotState = 1;
1339
+ }
1340
+ }
1341
+ else if (startDot !== -1) {
1342
+ // We saw a non-dot and non-path separator before our dot, so we should
1343
+ // have a good chance at having a non-empty extension
1344
+ preDotState = -1;
1345
+ }
1346
+ }
1347
+ if (startDot === -1 ||
1348
+ end === -1 ||
1349
+ // We saw a non-dot character immediately before the dot
1350
+ preDotState === 0 ||
1351
+ // The (right-most) trimmed path component is exactly '..'
1352
+ (preDotState === 1 &&
1353
+ startDot === end - 1 &&
1354
+ startDot === startPart + 1)) {
1355
+ return '';
1356
+ }
1357
+ return path.slice(startDot, end);
1358
+ },
1359
+ format: _format.bind(null, '/'),
1360
+ parse(path) {
1361
+ validateString(path, 'path');
1362
+ const ret = { root: '', dir: '', base: '', ext: '', name: '' };
1363
+ if (path.length === 0) {
1364
+ return ret;
1365
+ }
1366
+ const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;
1367
+ let start;
1368
+ if (isAbsolute) {
1369
+ ret.root = '/';
1370
+ start = 1;
1371
+ }
1372
+ else {
1373
+ start = 0;
1374
+ }
1375
+ let startDot = -1;
1376
+ let startPart = 0;
1377
+ let end = -1;
1378
+ let matchedSlash = true;
1379
+ let i = path.length - 1;
1380
+ // Track the state of characters (if any) we see before our first dot and
1381
+ // after any path separator we find
1382
+ let preDotState = 0;
1383
+ // Get non-dir info
1384
+ for (; i >= start; --i) {
1385
+ const code = path.charCodeAt(i);
1386
+ if (code === CHAR_FORWARD_SLASH) {
1387
+ // If we reached a path separator that was not part of a set of path
1388
+ // separators at the end of the string, stop now
1389
+ if (!matchedSlash) {
1390
+ startPart = i + 1;
1391
+ break;
1392
+ }
1393
+ continue;
1394
+ }
1395
+ if (end === -1) {
1396
+ // We saw the first non-path separator, mark this as the end of our
1397
+ // extension
1398
+ matchedSlash = false;
1399
+ end = i + 1;
1400
+ }
1401
+ if (code === CHAR_DOT) {
1402
+ // If this is our first dot, mark it as the start of our extension
1403
+ if (startDot === -1) {
1404
+ startDot = i;
1405
+ }
1406
+ else if (preDotState !== 1) {
1407
+ preDotState = 1;
1408
+ }
1409
+ }
1410
+ else if (startDot !== -1) {
1411
+ // We saw a non-dot and non-path separator before our dot, so we should
1412
+ // have a good chance at having a non-empty extension
1413
+ preDotState = -1;
1414
+ }
1415
+ }
1416
+ if (end !== -1) {
1417
+ const start = startPart === 0 && isAbsolute ? 1 : startPart;
1418
+ if (startDot === -1 ||
1419
+ // We saw a non-dot character immediately before the dot
1420
+ preDotState === 0 ||
1421
+ // The (right-most) trimmed path component is exactly '..'
1422
+ (preDotState === 1 &&
1423
+ startDot === end - 1 &&
1424
+ startDot === startPart + 1)) {
1425
+ ret.base = ret.name = path.slice(start, end);
1426
+ }
1427
+ else {
1428
+ ret.name = path.slice(start, startDot);
1429
+ ret.base = path.slice(start, end);
1430
+ ret.ext = path.slice(startDot, end);
1431
+ }
1432
+ }
1433
+ if (startPart > 0) {
1434
+ ret.dir = path.slice(0, startPart - 1);
1435
+ }
1436
+ else if (isAbsolute) {
1437
+ ret.dir = '/';
1438
+ }
1439
+ return ret;
1440
+ },
1441
+ sep: '/',
1442
+ delimiter: ':',
1443
+ win32: null,
1444
+ posix: null
1445
+ };
1446
+ posix.win32 = win32.win32 = win32;
1447
+ posix.posix = win32.posix = posix;
1448
+ export const normalize = (platformIsWin32 ? win32.normalize : posix.normalize);
1449
+ export const isAbsolute = (platformIsWin32 ? win32.isAbsolute : posix.isAbsolute);
1450
+ export const join = (platformIsWin32 ? win32.join : posix.join);
1451
+ export const resolve = (platformIsWin32 ? win32.resolve : posix.resolve);
1452
+ export const relative = (platformIsWin32 ? win32.relative : posix.relative);
1453
+ export const dirname = (platformIsWin32 ? win32.dirname : posix.dirname);
1454
+ export const basename = (platformIsWin32 ? win32.basename : posix.basename);
1455
+ export const extname = (platformIsWin32 ? win32.extname : posix.extname);
1456
+ export const format = (platformIsWin32 ? win32.format : posix.format);
1457
+ export const parse = (platformIsWin32 ? win32.parse : posix.parse);
1458
+ export const toNamespacedPath = (platformIsWin32 ? win32.toNamespacedPath : posix.toNamespacedPath);
1459
+ export const sep = (platformIsWin32 ? win32.sep : posix.sep);
1460
+ export const delimiter = (platformIsWin32 ? win32.delimiter : posix.delimiter);
1461
+ //# sourceMappingURL=path.js.map