@monorepolint/utils 0.5.0-beta.7 → 0.5.0-beta.9
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/.turbo/turbo-clean.log +4 -0
- package/.turbo/turbo-compile-typescript.log +4 -0
- package/.turbo/turbo-lint.log +15 -0
- package/.turbo/turbo-test.log +26 -0
- package/.turbo/turbo-transpile-typescript.log +14 -0
- package/CHANGELOG.md +6 -8
- package/build/js/index.js +894 -0
- package/build/js/index.js.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -0
- package/build/types/AggregateTiming.d.ts +15 -0
- package/build/types/AggregateTiming.d.ts.map +1 -0
- package/build/types/CachingHost.d.ts +39 -0
- package/build/types/CachingHost.d.ts.map +1 -0
- package/build/types/Host.d.ts +38 -0
- package/build/types/Host.d.ts.map +1 -0
- package/build/types/PackageJson.d.ts +20 -0
- package/build/types/PackageJson.d.ts.map +1 -0
- package/build/types/SimpleHost.d.ts +35 -0
- package/build/types/SimpleHost.d.ts.map +1 -0
- package/build/types/Table.d.ts +53 -0
- package/build/types/Table.d.ts.map +1 -0
- package/build/types/Timing.d.ts +9 -0
- package/build/types/Timing.d.ts.map +1 -0
- package/build/types/__tests__/CachingHost.spec.d.ts +2 -0
- package/build/types/__tests__/CachingHost.spec.d.ts.map +1 -0
- package/build/types/findWorkspaceDir.d.ts +10 -0
- package/build/types/findWorkspaceDir.d.ts.map +1 -0
- package/build/types/getPackageNameToDir.d.ts +14 -0
- package/build/types/getPackageNameToDir.d.ts.map +1 -0
- package/build/types/getWorkspacePackageDirs.d.ts +9 -0
- package/build/types/getWorkspacePackageDirs.d.ts.map +1 -0
- package/build/types/index.d.ts +20 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/matchesAnyGlob.d.ts +17 -0
- package/build/types/matchesAnyGlob.d.ts.map +1 -0
- package/build/types/mutateJson.d.ts +9 -0
- package/build/types/mutateJson.d.ts.map +1 -0
- package/build/types/nanosecondsToSanity.d.ts +8 -0
- package/build/types/nanosecondsToSanity.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,894 @@
|
|
|
1
|
+
// src/getWorkspacePackageDirs.ts
|
|
2
|
+
import { existsSync } from "fs";
|
|
3
|
+
import * as glob from "glob";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import * as fs from "node:fs";
|
|
6
|
+
import * as readYamlFile from "read-yaml-file";
|
|
7
|
+
import { findPackages } from "find-packages";
|
|
8
|
+
async function findPNPMWorkspacePackages(workspaceRoot) {
|
|
9
|
+
workspaceRoot = fs.realpathSync(workspaceRoot);
|
|
10
|
+
const workspaceManifest = await readYamlFile.default(
|
|
11
|
+
path.join(workspaceRoot, "pnpm-workspace.yaml")
|
|
12
|
+
);
|
|
13
|
+
return findPackages(workspaceRoot, {
|
|
14
|
+
ignore: ["**/node_modules/**", "**/bower_components/**"],
|
|
15
|
+
includeRoot: true,
|
|
16
|
+
patterns: workspaceManifest.packages
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async function getWorkspacePackageDirs(host, workspaceDir, resolvePaths = false) {
|
|
20
|
+
const packageJson = host.readJson(path.join(workspaceDir, "package.json"));
|
|
21
|
+
const isPnpmWorkspace = host.exists(path.join(workspaceDir, "pnpm-workspace.yaml"));
|
|
22
|
+
if (isPnpmWorkspace) {
|
|
23
|
+
const workspacePackages = await findPNPMWorkspacePackages(workspaceDir);
|
|
24
|
+
if (workspacePackages.length === 0) {
|
|
25
|
+
throw new Error("Invalid workspaceDir: " + workspaceDir);
|
|
26
|
+
}
|
|
27
|
+
return workspacePackages.map((project) => project.dir).filter((d) => d !== workspaceDir);
|
|
28
|
+
}
|
|
29
|
+
if (!packageJson.workspaces) {
|
|
30
|
+
throw new Error("Unsupported! Monorepo is not backed by either pnpm nor yarn workspaces.");
|
|
31
|
+
}
|
|
32
|
+
const ret = [];
|
|
33
|
+
const packageGlobs = Array.isArray(packageJson.workspaces) ? packageJson.workspaces : packageJson.workspaces.packages || [];
|
|
34
|
+
for (const pattern of packageGlobs) {
|
|
35
|
+
for (const packagePath of glob.sync(pattern, { cwd: workspaceDir })) {
|
|
36
|
+
const packageJsonPath = path.join(workspaceDir, packagePath, "package.json");
|
|
37
|
+
if (existsSync(packageJsonPath)) {
|
|
38
|
+
if (resolvePaths === true) {
|
|
39
|
+
ret.push(path.resolve(path.join(workspaceDir, packagePath)));
|
|
40
|
+
} else {
|
|
41
|
+
ret.push(packagePath);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return ret;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/mutateJson.ts
|
|
50
|
+
function mutateJson(path4, host, mutator) {
|
|
51
|
+
let file = host.readJson(path4);
|
|
52
|
+
file = mutator(file);
|
|
53
|
+
host.writeJson(path4, file);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/findWorkspaceDir.ts
|
|
57
|
+
import * as path2 from "path";
|
|
58
|
+
import * as fs2 from "fs";
|
|
59
|
+
import { findUp } from "find-up";
|
|
60
|
+
async function findPnpmWorkspaceDir(cwd) {
|
|
61
|
+
const workspaceManifestLocation = await findUp("pnpm-workspace.yaml", {
|
|
62
|
+
cwd: await fs2.promises.realpath(cwd)
|
|
63
|
+
});
|
|
64
|
+
return workspaceManifestLocation && path2.dirname(workspaceManifestLocation);
|
|
65
|
+
}
|
|
66
|
+
async function findWorkspaceDir(host, dir) {
|
|
67
|
+
const maybePnpmWorkspaceDir = await findPnpmWorkspaceDir(dir);
|
|
68
|
+
if (maybePnpmWorkspaceDir != null) {
|
|
69
|
+
return maybePnpmWorkspaceDir;
|
|
70
|
+
}
|
|
71
|
+
const packagePath = path2.join(dir, "package.json");
|
|
72
|
+
if (host.exists(packagePath)) {
|
|
73
|
+
const packageJson = host.readJson(packagePath);
|
|
74
|
+
if (packageJson.workspaces !== void 0) {
|
|
75
|
+
return dir;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const nextDir = path2.normalize(path2.join(dir, ".."));
|
|
79
|
+
if (nextDir === dir) {
|
|
80
|
+
return void 0;
|
|
81
|
+
}
|
|
82
|
+
return findWorkspaceDir(host, nextDir);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/getPackageNameToDir.ts
|
|
86
|
+
import { join as pathJoin } from "path";
|
|
87
|
+
async function getPackageNameToDir(host, workspaceDir, resolvePaths = false) {
|
|
88
|
+
const ret = /* @__PURE__ */ new Map();
|
|
89
|
+
const workspacePackages = await getWorkspacePackageDirs(host, workspaceDir, resolvePaths);
|
|
90
|
+
for (const packageDir of workspacePackages) {
|
|
91
|
+
const packagePath = pathJoin(packageDir, "package.json");
|
|
92
|
+
const { name } = host.readJson(packagePath);
|
|
93
|
+
if (name === void 0) {
|
|
94
|
+
throw new Error(`Package needs a name: ${packagePath}`);
|
|
95
|
+
}
|
|
96
|
+
ret.set(name, packageDir);
|
|
97
|
+
}
|
|
98
|
+
return ret;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/SimpleHost.ts
|
|
102
|
+
import * as realFs from "fs";
|
|
103
|
+
var SimpleHost = class {
|
|
104
|
+
constructor(fs3 = realFs) {
|
|
105
|
+
this.fs = fs3;
|
|
106
|
+
}
|
|
107
|
+
mkdir(directoryPath, opts) {
|
|
108
|
+
this.fs.mkdirSync(directoryPath, { recursive: (opts == null ? void 0 : opts.recursive) ?? false });
|
|
109
|
+
}
|
|
110
|
+
rmdir(directoryPath) {
|
|
111
|
+
this.fs.rmdirSync(directoryPath);
|
|
112
|
+
}
|
|
113
|
+
exists(path4) {
|
|
114
|
+
return this.fs.existsSync(path4);
|
|
115
|
+
}
|
|
116
|
+
writeFile(path4, body, opts) {
|
|
117
|
+
if (opts) {
|
|
118
|
+
this.fs.writeFileSync(path4, body, { encoding: opts.encoding });
|
|
119
|
+
} else {
|
|
120
|
+
this.fs.writeFileSync(path4, body);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
readFile(path4, opts) {
|
|
124
|
+
if (opts == null ? void 0 : opts.asJson) {
|
|
125
|
+
return JSON.parse(this.fs.readFileSync(path4, "utf-8"));
|
|
126
|
+
}
|
|
127
|
+
return this.fs.readFileSync(path4, opts == null ? void 0 : opts.encoding);
|
|
128
|
+
}
|
|
129
|
+
deleteFile(path4) {
|
|
130
|
+
this.fs.unlinkSync(path4);
|
|
131
|
+
}
|
|
132
|
+
readJson(filename) {
|
|
133
|
+
const contents = this.fs.readFileSync(filename, "utf-8");
|
|
134
|
+
return JSON.parse(contents);
|
|
135
|
+
}
|
|
136
|
+
writeJson(path4, o) {
|
|
137
|
+
return this.fs.writeFileSync(path4, JSON.stringify(o, void 0, 2) + "\n");
|
|
138
|
+
}
|
|
139
|
+
flush() {
|
|
140
|
+
return Promise.resolve();
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// src/CachingHost.ts
|
|
145
|
+
import * as realFs2 from "node:fs";
|
|
146
|
+
import * as path3 from "node:path";
|
|
147
|
+
function assertNoTombstone(node) {
|
|
148
|
+
if (node.tombstone) {
|
|
149
|
+
throw new Error(`Unexpected tombstone ${JSON.stringify(node)}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function assertNotType(node, type) {
|
|
153
|
+
if (node.type === type) {
|
|
154
|
+
throw new Error(`Unexpected node type ${JSON.stringify(node)}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function assertType(node, type) {
|
|
158
|
+
if (node.type !== type) {
|
|
159
|
+
throw new Error(`Unexpected node type ${JSON.stringify(node)}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function assertExists(node) {
|
|
163
|
+
if (!node) {
|
|
164
|
+
throw new Error(`Expected node to exist`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function assertHasParent(node) {
|
|
168
|
+
if (!node.parent) {
|
|
169
|
+
throw new Error("Expected node to have a parent directory");
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
var CachingHost = class {
|
|
173
|
+
constructor(fs3 = realFs2) {
|
|
174
|
+
this.fs = fs3;
|
|
175
|
+
}
|
|
176
|
+
// We need many trees because of windows, key is the `root`
|
|
177
|
+
#trees = /* @__PURE__ */ new Map();
|
|
178
|
+
#replaceNode(node, partialNewNode) {
|
|
179
|
+
if (!node.parent)
|
|
180
|
+
throw new Error("Cannot replace root node");
|
|
181
|
+
const newNode = {
|
|
182
|
+
...partialNewNode,
|
|
183
|
+
fullPath: node.fullPath,
|
|
184
|
+
parent: node.parent,
|
|
185
|
+
dir: node.dir
|
|
186
|
+
};
|
|
187
|
+
node.parent.dir.set(path3.basename(node.fullPath), newNode);
|
|
188
|
+
return newNode;
|
|
189
|
+
}
|
|
190
|
+
#unstubDirectory(node) {
|
|
191
|
+
for (const child of this.fs.readdirSync(node.fullPath)) {
|
|
192
|
+
this.#getNode(path3.join(node.fullPath, child));
|
|
193
|
+
}
|
|
194
|
+
node.stub = false;
|
|
195
|
+
}
|
|
196
|
+
#stubify(filePath, parent) {
|
|
197
|
+
const canonicalPath = path3.resolve(filePath);
|
|
198
|
+
if (!parent && canonicalPath !== path3.parse(canonicalPath).root) {
|
|
199
|
+
throw new Error(`parent can only be null if path is root. Instead got: ${canonicalPath}`);
|
|
200
|
+
}
|
|
201
|
+
const stat = this.fs.lstatSync(canonicalPath);
|
|
202
|
+
let node;
|
|
203
|
+
if (stat.isDirectory()) {
|
|
204
|
+
node = {
|
|
205
|
+
fullPath: canonicalPath,
|
|
206
|
+
type: "dir",
|
|
207
|
+
stub: true,
|
|
208
|
+
dir: /* @__PURE__ */ new Map(),
|
|
209
|
+
parent,
|
|
210
|
+
needsFlush: false
|
|
211
|
+
};
|
|
212
|
+
} else if (stat.isSymbolicLink()) {
|
|
213
|
+
node = {
|
|
214
|
+
fullPath: canonicalPath,
|
|
215
|
+
type: "symlink",
|
|
216
|
+
symlink: this.fs.readlinkSync(canonicalPath),
|
|
217
|
+
parent,
|
|
218
|
+
needsFlush: false
|
|
219
|
+
};
|
|
220
|
+
} else if (stat.isFile()) {
|
|
221
|
+
node = {
|
|
222
|
+
fullPath: canonicalPath,
|
|
223
|
+
type: "file",
|
|
224
|
+
stub: true,
|
|
225
|
+
parent,
|
|
226
|
+
needsFlush: false
|
|
227
|
+
};
|
|
228
|
+
} else {
|
|
229
|
+
throw new Error(`what is not a file nor symlink nor directory? nothing we care about: ${canonicalPath}`);
|
|
230
|
+
}
|
|
231
|
+
if (!parent && node.type === "dir") {
|
|
232
|
+
this.#trees.set(canonicalPath, node);
|
|
233
|
+
return node;
|
|
234
|
+
} else if (parent) {
|
|
235
|
+
parent.dir.set(path3.basename(canonicalPath), node);
|
|
236
|
+
} else {
|
|
237
|
+
throw new Error(`root can only be a dir, got ${JSON.stringify(node)} for path: ${canonicalPath}`);
|
|
238
|
+
}
|
|
239
|
+
return node;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Note: may return the node itself!
|
|
243
|
+
* You should check the `fullPath` of the result.
|
|
244
|
+
*/
|
|
245
|
+
#getNearestAncestorNode(filePath) {
|
|
246
|
+
const canonicalPath = path3.resolve(filePath);
|
|
247
|
+
const { root } = path3.parse(canonicalPath);
|
|
248
|
+
const parts = [];
|
|
249
|
+
let maybePath = canonicalPath;
|
|
250
|
+
while (maybePath !== root) {
|
|
251
|
+
parts.unshift(path3.basename(maybePath));
|
|
252
|
+
maybePath = path3.dirname(maybePath);
|
|
253
|
+
}
|
|
254
|
+
let curPath = root;
|
|
255
|
+
let curNode = this.#trees.get(root) ?? this.#stubify(curPath, void 0);
|
|
256
|
+
try {
|
|
257
|
+
for (const part of parts) {
|
|
258
|
+
assertNoTombstone(curNode);
|
|
259
|
+
assertNotType(curNode, "file");
|
|
260
|
+
if (curNode.type === "symlink") {
|
|
261
|
+
const linkedNode = this.#getNodeResolvingSymlinks(path3.resolve(path3.dirname(curPath), curNode.symlink));
|
|
262
|
+
assertExists(linkedNode);
|
|
263
|
+
assertNoTombstone(linkedNode);
|
|
264
|
+
assertType(linkedNode, "dir");
|
|
265
|
+
curNode = linkedNode;
|
|
266
|
+
}
|
|
267
|
+
assertType(curNode, "dir");
|
|
268
|
+
assertNoTombstone(curNode);
|
|
269
|
+
curNode = curNode.dir.get(part) ?? this.#stubify(path3.join(curNode.fullPath, part), curNode);
|
|
270
|
+
curPath = path3.join(curPath, part);
|
|
271
|
+
}
|
|
272
|
+
} catch (e) {
|
|
273
|
+
}
|
|
274
|
+
return { pathWithSymlinks: curPath, node: curNode };
|
|
275
|
+
}
|
|
276
|
+
#getNode(filePath) {
|
|
277
|
+
const canonicalPath = path3.resolve(filePath);
|
|
278
|
+
const { pathWithSymlinks, node } = this.#getNearestAncestorNode(canonicalPath);
|
|
279
|
+
if (pathWithSymlinks === canonicalPath) {
|
|
280
|
+
return node;
|
|
281
|
+
}
|
|
282
|
+
return void 0;
|
|
283
|
+
}
|
|
284
|
+
#getNodeResolvingSymlinks(filePath, follows = 100) {
|
|
285
|
+
const node = this.#getNode(filePath);
|
|
286
|
+
if (!node || node.type !== "symlink")
|
|
287
|
+
return node;
|
|
288
|
+
if (follows === 0)
|
|
289
|
+
throw new Error("Exhausted symlink follows");
|
|
290
|
+
return this.#getNodeResolvingSymlinks(node.symlink, follows--);
|
|
291
|
+
}
|
|
292
|
+
mkdir(filePath, opts = { recursive: false }) {
|
|
293
|
+
const canonicalPath = path3.resolve(filePath);
|
|
294
|
+
const { node, pathWithSymlinks } = this.#getNearestAncestorNode(canonicalPath);
|
|
295
|
+
if (filePath === pathWithSymlinks) {
|
|
296
|
+
assertType(node, "dir");
|
|
297
|
+
assertHasParent(node);
|
|
298
|
+
if (!node.tombstone)
|
|
299
|
+
return;
|
|
300
|
+
} else if (path3.dirname(filePath) === pathWithSymlinks) {
|
|
301
|
+
assertType(node, "dir");
|
|
302
|
+
assertNoTombstone(node);
|
|
303
|
+
node.dir.set(path3.basename(filePath), {
|
|
304
|
+
type: "dir",
|
|
305
|
+
fullPath: filePath,
|
|
306
|
+
parent: node,
|
|
307
|
+
dir: /* @__PURE__ */ new Map(),
|
|
308
|
+
needsFlush: true
|
|
309
|
+
});
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
if (!opts.recursive && path3.dirname(canonicalPath) !== pathWithSymlinks) {
|
|
313
|
+
throw new Error("no such file or directory");
|
|
314
|
+
}
|
|
315
|
+
const rootPath = pathWithSymlinks;
|
|
316
|
+
let maybePath = canonicalPath;
|
|
317
|
+
const toMake = [];
|
|
318
|
+
while (maybePath !== rootPath) {
|
|
319
|
+
toMake.unshift(path3.resolve(node.fullPath, path3.relative(rootPath, maybePath)));
|
|
320
|
+
maybePath = path3.dirname(maybePath);
|
|
321
|
+
}
|
|
322
|
+
for (const dirToMake of toMake) {
|
|
323
|
+
this.mkdir(dirToMake);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
rmdir(directoryPath) {
|
|
327
|
+
const node = this.#getNode(directoryPath);
|
|
328
|
+
if (!node || node.tombstone) {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
assertType(node, "dir");
|
|
332
|
+
if (node.stub) {
|
|
333
|
+
this.#unstubDirectory(node);
|
|
334
|
+
}
|
|
335
|
+
if (node.dir.size === 0) {
|
|
336
|
+
this.#replaceNode(node, {
|
|
337
|
+
type: "dir",
|
|
338
|
+
tombstone: true,
|
|
339
|
+
needsFlush: true
|
|
340
|
+
});
|
|
341
|
+
} else {
|
|
342
|
+
throw new Error("directory not empty");
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
exists(filePath) {
|
|
346
|
+
const node = this.#getNode(filePath);
|
|
347
|
+
return !!node && !node.tombstone;
|
|
348
|
+
}
|
|
349
|
+
readFile(filePath, opts) {
|
|
350
|
+
let node = this.#getNodeResolvingSymlinks(filePath);
|
|
351
|
+
if (!node) {
|
|
352
|
+
return void 0;
|
|
353
|
+
}
|
|
354
|
+
assertNotType(node, "dir");
|
|
355
|
+
assertNoTombstone(node);
|
|
356
|
+
if (node.stub) {
|
|
357
|
+
node = this.#replaceNode(node, {
|
|
358
|
+
type: "file",
|
|
359
|
+
file: this.fs.readFileSync(filePath),
|
|
360
|
+
needsFlush: false
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
if (!opts) {
|
|
364
|
+
return Buffer.from(node.file);
|
|
365
|
+
} else if (opts.asJson) {
|
|
366
|
+
return JSON.parse(node.file.toString("utf-8"));
|
|
367
|
+
} else {
|
|
368
|
+
return node.file.toString(opts.encoding);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
writeFile(filePath, body, opts) {
|
|
372
|
+
const fileContentsAsBuffer = typeof body === "string" ? Buffer.from(body, opts == null ? void 0 : opts.encoding) : Buffer.from(body);
|
|
373
|
+
const canonicalPath = path3.resolve(filePath);
|
|
374
|
+
const existingNode = this.#getNodeResolvingSymlinks(canonicalPath);
|
|
375
|
+
if (existingNode) {
|
|
376
|
+
if (existingNode.type === "dir") {
|
|
377
|
+
throw new Error("cant write file to a dir");
|
|
378
|
+
}
|
|
379
|
+
this.#replaceNode(existingNode, {
|
|
380
|
+
file: fileContentsAsBuffer,
|
|
381
|
+
type: "file",
|
|
382
|
+
needsFlush: true
|
|
383
|
+
});
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
const maybeDirNode = this.#getNodeResolvingSymlinks(path3.dirname(canonicalPath));
|
|
387
|
+
assertExists(maybeDirNode);
|
|
388
|
+
assertType(maybeDirNode, "dir");
|
|
389
|
+
assertNoTombstone(maybeDirNode);
|
|
390
|
+
maybeDirNode.dir.set(path3.basename(canonicalPath), {
|
|
391
|
+
type: "file",
|
|
392
|
+
fullPath: canonicalPath,
|
|
393
|
+
parent: maybeDirNode,
|
|
394
|
+
file: fileContentsAsBuffer,
|
|
395
|
+
needsFlush: true
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
deleteFile(filePath) {
|
|
399
|
+
const canonicalPath = path3.resolve(filePath);
|
|
400
|
+
const node = this.#getNode(canonicalPath);
|
|
401
|
+
if (!node || node.type === "file" && node.tombstone === true)
|
|
402
|
+
return;
|
|
403
|
+
assertNotType(node, "dir");
|
|
404
|
+
this.#replaceNode(node, {
|
|
405
|
+
type: "file",
|
|
406
|
+
tombstone: true,
|
|
407
|
+
needsFlush: true
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
readJson(filePath) {
|
|
411
|
+
return this.readFile(filePath, { asJson: true });
|
|
412
|
+
}
|
|
413
|
+
writeJson(filePath, o) {
|
|
414
|
+
return this.writeFile(filePath, JSON.stringify(o, void 0, 2) + "\n", {
|
|
415
|
+
encoding: "utf-8"
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
async #flushFileNode(node) {
|
|
419
|
+
if (node.tombstone) {
|
|
420
|
+
try {
|
|
421
|
+
await this.fs.promises.access(node.fullPath);
|
|
422
|
+
return this.fs.promises.unlink(node.fullPath);
|
|
423
|
+
} catch (e) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
} else if (node.stub === true || node.needsFlush === false) {
|
|
427
|
+
return;
|
|
428
|
+
} else {
|
|
429
|
+
return this.fs.promises.writeFile(node.fullPath, node.file);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
async #flushSymlinkNode(node) {
|
|
433
|
+
if (!node.needsFlush)
|
|
434
|
+
return;
|
|
435
|
+
try {
|
|
436
|
+
const linkValue = await this.fs.promises.readlink(node.fullPath);
|
|
437
|
+
if (linkValue === node.symlink) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
} catch (e) {
|
|
441
|
+
}
|
|
442
|
+
return this.fs.promises.symlink(node.symlink, node.fullPath);
|
|
443
|
+
}
|
|
444
|
+
async #flushDirNode(node) {
|
|
445
|
+
if (!node.tombstone && node.needsFlush) {
|
|
446
|
+
try {
|
|
447
|
+
await this.fs.promises.access(node.fullPath);
|
|
448
|
+
} catch (e) {
|
|
449
|
+
await this.fs.promises.mkdir(node.fullPath);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
const promises2 = [];
|
|
453
|
+
for (const child of node.dir.values()) {
|
|
454
|
+
if (node.tombstone && !child.tombstone) {
|
|
455
|
+
throw new Error("Unexpected failure during sanity check. A non-deleted child is on a deleted dir");
|
|
456
|
+
}
|
|
457
|
+
if (child.type === "dir") {
|
|
458
|
+
promises2.push(this.#flushDirNode(child));
|
|
459
|
+
} else if (child.type === "file") {
|
|
460
|
+
promises2.push(this.#flushFileNode(child));
|
|
461
|
+
} else if (child.type === "symlink") {
|
|
462
|
+
promises2.push(this.#flushSymlinkNode(child));
|
|
463
|
+
} else {
|
|
464
|
+
throw new Error("should never happen");
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
await Promise.all(promises2);
|
|
468
|
+
if (node.tombstone) {
|
|
469
|
+
return this.fs.promises.rmdir(node.fullPath);
|
|
470
|
+
}
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
flush() {
|
|
474
|
+
const promises2 = [];
|
|
475
|
+
for (const rootNode of this.#trees.values()) {
|
|
476
|
+
promises2.push(this.#flushDirNode(rootNode));
|
|
477
|
+
}
|
|
478
|
+
return Promise.all(promises2);
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
// src/matchesAnyGlob.ts
|
|
483
|
+
import micromatch from "micromatch";
|
|
484
|
+
|
|
485
|
+
// src/nanosecondsToSanity.ts
|
|
486
|
+
function nanosecondsToSanity(n, precision = 9) {
|
|
487
|
+
return n / BigInt(1e9) + "." + ("" + n % BigInt(1e9)).padStart(9, "0").substring(0, precision) + "s";
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// src/Table.ts
|
|
491
|
+
var Table = class {
|
|
492
|
+
#rows = [];
|
|
493
|
+
#config;
|
|
494
|
+
#columnWidths = [];
|
|
495
|
+
#footer = [];
|
|
496
|
+
#footerRowConfig;
|
|
497
|
+
#totalWidth = 0;
|
|
498
|
+
constructor(config) {
|
|
499
|
+
this.#config = {
|
|
500
|
+
padding: 2,
|
|
501
|
+
...config
|
|
502
|
+
};
|
|
503
|
+
this.#columnWidths.fill(0, 0, config.columns.length);
|
|
504
|
+
if (config.showFooter) {
|
|
505
|
+
this.#footerRowConfig = [];
|
|
506
|
+
for (const columnConfig of config.columns) {
|
|
507
|
+
if (columnConfig.footer === void 0) {
|
|
508
|
+
throw new Error("Must specify footer fields when showFooter is true");
|
|
509
|
+
} else if (typeof columnConfig.footer === "string") {
|
|
510
|
+
this.#footerRowConfig.push({
|
|
511
|
+
type: "string",
|
|
512
|
+
alignment: "left",
|
|
513
|
+
aggregate: "static",
|
|
514
|
+
value: columnConfig.footer
|
|
515
|
+
});
|
|
516
|
+
} else if ("value" in columnConfig.footer) {
|
|
517
|
+
this.#footerRowConfig.push({
|
|
518
|
+
type: "string",
|
|
519
|
+
alignment: "left",
|
|
520
|
+
...columnConfig.footer
|
|
521
|
+
});
|
|
522
|
+
} else if ("aggregate" in columnConfig.footer) {
|
|
523
|
+
if (columnConfig.type !== "bigint")
|
|
524
|
+
throw new Error("expecting bigint for aggregate");
|
|
525
|
+
this.#footerRowConfig.push({
|
|
526
|
+
type: columnConfig.type,
|
|
527
|
+
renderAs: columnConfig.renderAs,
|
|
528
|
+
precision: columnConfig.precision,
|
|
529
|
+
alignment: "right",
|
|
530
|
+
...columnConfig.footer
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
addRow(...data) {
|
|
537
|
+
this.#rows.push(data);
|
|
538
|
+
}
|
|
539
|
+
#sumColumn(c) {
|
|
540
|
+
let total = BigInt(0);
|
|
541
|
+
for (const row of this.#rows) {
|
|
542
|
+
total += row[c];
|
|
543
|
+
}
|
|
544
|
+
return total;
|
|
545
|
+
}
|
|
546
|
+
#updateFooterRow() {
|
|
547
|
+
const footerRowConfig = this.#footerRowConfig;
|
|
548
|
+
if (footerRowConfig) {
|
|
549
|
+
for (let c = 0; c < footerRowConfig.length; c++) {
|
|
550
|
+
const footerColConfig = footerRowConfig[c];
|
|
551
|
+
switch (footerColConfig.aggregate) {
|
|
552
|
+
case "sum":
|
|
553
|
+
this.#footer[c] = this.#sumColumn(c);
|
|
554
|
+
break;
|
|
555
|
+
case "average":
|
|
556
|
+
this.#footer[c] = this.#sumColumn(c) / BigInt(this.#rows.length);
|
|
557
|
+
break;
|
|
558
|
+
case "static":
|
|
559
|
+
this.#footer[c] = footerColConfig.value;
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
#calculateColumnWidths() {
|
|
566
|
+
var _a;
|
|
567
|
+
this.#columnWidths.fill(0, 0, this.#config.columns.length);
|
|
568
|
+
for (let c = 0; c < this.#config.columns.length; c++) {
|
|
569
|
+
const colConfig = this.#config.columns[c];
|
|
570
|
+
this.#columnWidths[c] = Math.max(
|
|
571
|
+
(this.#config.columns[c].header ?? "").length,
|
|
572
|
+
...this.#rows.map((a) => this.#getCellValueAsString(a[c], colConfig).length),
|
|
573
|
+
this.#footer && this.#footerRowConfig ? this.#getCellValueAsString(((_a = this.#footer) == null ? void 0 : _a[c]) ?? "", this.#footerRowConfig[c]).length : 0
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
this.#totalWidth = 0;
|
|
577
|
+
for (const colWidth of this.#columnWidths) {
|
|
578
|
+
this.#totalWidth += colWidth;
|
|
579
|
+
}
|
|
580
|
+
this.#totalWidth += (this.#columnWidths.length - 1) * this.#config.padding;
|
|
581
|
+
}
|
|
582
|
+
#printSeparator(fillString) {
|
|
583
|
+
const paddingString = "".padStart(this.#config.padding, " ");
|
|
584
|
+
let hr2 = "";
|
|
585
|
+
for (let c = 0; c < this.#columnWidths.length; c++) {
|
|
586
|
+
hr2 += "".padStart(this.#columnWidths[c], fillString) + paddingString;
|
|
587
|
+
}
|
|
588
|
+
hr2 = hr2.trimRight();
|
|
589
|
+
console.log(hr2);
|
|
590
|
+
}
|
|
591
|
+
#printHeaderRow() {
|
|
592
|
+
if (this.#config.showHeader) {
|
|
593
|
+
const colConfigs = this.#config.columns;
|
|
594
|
+
const paddingString = "".padStart(this.#config.padding, " ");
|
|
595
|
+
let hr = "";
|
|
596
|
+
for (let c = 0; c < colConfigs.length; c++) {
|
|
597
|
+
const heading = colConfigs[c].header ?? "";
|
|
598
|
+
hr += heading.padEnd(this.#columnWidths[c], " ") + paddingString;
|
|
599
|
+
}
|
|
600
|
+
hr = hr.trimRight();
|
|
601
|
+
console.log(hr);
|
|
602
|
+
this.#printSeparator("-");
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
#printFooterRow() {
|
|
606
|
+
const footerRow = this.#footer;
|
|
607
|
+
if (footerRow) {
|
|
608
|
+
this.#printSeparator("=");
|
|
609
|
+
const paddingString = "".padStart(this.#config.padding, " ");
|
|
610
|
+
let hr = "";
|
|
611
|
+
for (let c = 0; c < footerRow.length; c++) {
|
|
612
|
+
hr += this.#getCellValueAligned(footerRow[c], this.#footerRowConfig[c], c) + paddingString;
|
|
613
|
+
}
|
|
614
|
+
hr = hr.trimRight();
|
|
615
|
+
console.log(hr);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
print() {
|
|
619
|
+
if (this.#config.sortColumn !== void 0) {
|
|
620
|
+
}
|
|
621
|
+
this.#updateFooterRow();
|
|
622
|
+
this.#calculateColumnWidths();
|
|
623
|
+
console.log();
|
|
624
|
+
console.log(`${this.#config.title}`);
|
|
625
|
+
console.log("".padStart(this.#totalWidth, "="));
|
|
626
|
+
const paddingString = "".padStart(this.#config.padding, " ");
|
|
627
|
+
if (this.#config.showHeader) {
|
|
628
|
+
this.#printHeaderRow();
|
|
629
|
+
}
|
|
630
|
+
for (let r = 0; r < this.#rows.length; r++) {
|
|
631
|
+
let rowText = "";
|
|
632
|
+
for (let c = 0; c < this.#config.columns.length; c++) {
|
|
633
|
+
rowText += this.getEntryAsStringAligned(c, r) + paddingString;
|
|
634
|
+
}
|
|
635
|
+
rowText.trim();
|
|
636
|
+
console.log(rowText);
|
|
637
|
+
}
|
|
638
|
+
if (this.#config.showFooter)
|
|
639
|
+
this.#printFooterRow();
|
|
640
|
+
console.log();
|
|
641
|
+
}
|
|
642
|
+
#getCellValueAsString(value, config) {
|
|
643
|
+
if (config.type === "bigint" && config.renderAs === "nanoseconds") {
|
|
644
|
+
return nanosecondsToSanity(value, config.precision ?? 9);
|
|
645
|
+
} else {
|
|
646
|
+
return "" + value;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
#getCellValueAligned(value, config, column) {
|
|
650
|
+
let result;
|
|
651
|
+
if (config.type === "bigint" && config.renderAs === "nanoseconds") {
|
|
652
|
+
result = nanosecondsToSanity(value, config.precision ?? 9);
|
|
653
|
+
} else {
|
|
654
|
+
result = "" + value;
|
|
655
|
+
}
|
|
656
|
+
if (config.alignment === "left") {
|
|
657
|
+
return result.padEnd(this.#columnWidths[column]);
|
|
658
|
+
} else {
|
|
659
|
+
return result.padStart(this.#columnWidths[column]);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
getEntryAsString(colNum, rowNum) {
|
|
663
|
+
const config = this.#config.columns[colNum];
|
|
664
|
+
if (config.type === "bigint" && config.renderAs === "nanoseconds") {
|
|
665
|
+
return nanosecondsToSanity(this.#rows[rowNum][colNum], config.precision ?? 9);
|
|
666
|
+
} else {
|
|
667
|
+
return "" + this.#rows[rowNum][colNum];
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
getEntryAsStringAligned(colNum, rowNum) {
|
|
671
|
+
const config = this.#config.columns[colNum];
|
|
672
|
+
let result;
|
|
673
|
+
if (config.type === "bigint" && config.renderAs === "nanoseconds") {
|
|
674
|
+
result = nanosecondsToSanity(this.#rows[rowNum][colNum], config.precision ?? 9);
|
|
675
|
+
} else {
|
|
676
|
+
result = "" + this.#rows[rowNum][colNum];
|
|
677
|
+
}
|
|
678
|
+
if (config.alignment === "left") {
|
|
679
|
+
return result.padEnd(this.#columnWidths[colNum]);
|
|
680
|
+
} else {
|
|
681
|
+
return result.padStart(this.#columnWidths[colNum]);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
getColumnWidth(colNum, config) {
|
|
685
|
+
let maxWidth = Math.max(
|
|
686
|
+
(config.header ?? "").length,
|
|
687
|
+
this.#footer && this.#footerRowConfig ? this.#getCellValueAsString(this.#footer[colNum], this.#footerRowConfig[colNum]).length : 0
|
|
688
|
+
);
|
|
689
|
+
for (let r = 0; r < this.#rows.length; r++) {
|
|
690
|
+
maxWidth = Math.max(maxWidth, this.getEntryAsString(colNum, r).length);
|
|
691
|
+
}
|
|
692
|
+
return maxWidth;
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
// src/matchesAnyGlob.ts
|
|
697
|
+
var cache = /* @__PURE__ */ new Map();
|
|
698
|
+
var singleMatcherCache = /* @__PURE__ */ new Map();
|
|
699
|
+
var compiledGlobCache = /* @__PURE__ */ new Map();
|
|
700
|
+
var haystackMiss = 0;
|
|
701
|
+
var haystackHit = 0;
|
|
702
|
+
var matchTime = BigInt(0);
|
|
703
|
+
var singleMatcherHits = 0;
|
|
704
|
+
var singleMatcherMisses = 0;
|
|
705
|
+
var singleMatcherSaves = 0;
|
|
706
|
+
var matchesAnyGlob = function matchesAnyGlobFunc(needle, haystack) {
|
|
707
|
+
matchTime -= process.hrtime.bigint();
|
|
708
|
+
let cacheForHaystack = cache.get(haystack);
|
|
709
|
+
if (cacheForHaystack === void 0) {
|
|
710
|
+
cacheForHaystack = /* @__PURE__ */ new Map();
|
|
711
|
+
cache.set(haystack, cacheForHaystack);
|
|
712
|
+
}
|
|
713
|
+
let result = cacheForHaystack.get(needle);
|
|
714
|
+
if (result === void 0) {
|
|
715
|
+
haystackMiss++;
|
|
716
|
+
result = false;
|
|
717
|
+
for (const pattern of haystack) {
|
|
718
|
+
let patternCache = singleMatcherCache.get(pattern);
|
|
719
|
+
if (patternCache === void 0) {
|
|
720
|
+
patternCache = /* @__PURE__ */ new Map();
|
|
721
|
+
singleMatcherCache.set(pattern, patternCache);
|
|
722
|
+
}
|
|
723
|
+
result = patternCache.get(needle);
|
|
724
|
+
if (result === void 0) {
|
|
725
|
+
let regexp = compiledGlobCache.get(pattern);
|
|
726
|
+
if (regexp === void 0) {
|
|
727
|
+
regexp = micromatch.makeRe(pattern);
|
|
728
|
+
compiledGlobCache.set(pattern, regexp);
|
|
729
|
+
}
|
|
730
|
+
singleMatcherMisses++;
|
|
731
|
+
result = regexp.test(needle);
|
|
732
|
+
patternCache.set(needle, result);
|
|
733
|
+
} else {
|
|
734
|
+
singleMatcherHits++;
|
|
735
|
+
singleMatcherSaves++;
|
|
736
|
+
}
|
|
737
|
+
if (result)
|
|
738
|
+
break;
|
|
739
|
+
}
|
|
740
|
+
cacheForHaystack.set(needle, result);
|
|
741
|
+
} else {
|
|
742
|
+
singleMatcherSaves += haystack.length;
|
|
743
|
+
haystackHit++;
|
|
744
|
+
}
|
|
745
|
+
matchTime += process.hrtime.bigint();
|
|
746
|
+
return result;
|
|
747
|
+
};
|
|
748
|
+
matchesAnyGlob.printStats = () => {
|
|
749
|
+
const table = new Table({
|
|
750
|
+
title: "matchesAnyGlob stats",
|
|
751
|
+
showHeader: true,
|
|
752
|
+
showFooter: false,
|
|
753
|
+
columns: [
|
|
754
|
+
{ header: "Stat", type: "string" },
|
|
755
|
+
{ header: "Value", type: "string" }
|
|
756
|
+
]
|
|
757
|
+
});
|
|
758
|
+
table.addRow("Haystack Miss", "" + haystackMiss);
|
|
759
|
+
table.addRow("Haystack Hit", "" + haystackHit);
|
|
760
|
+
table.addRow("Single Glob Hits", "" + singleMatcherHits);
|
|
761
|
+
table.addRow("Single Glob Misses", "" + singleMatcherMisses);
|
|
762
|
+
table.addRow("Single Glob Saves", "" + singleMatcherSaves);
|
|
763
|
+
table.addRow("Total Time", nanosecondsToSanity(matchTime, 6));
|
|
764
|
+
table.print();
|
|
765
|
+
};
|
|
766
|
+
|
|
767
|
+
// src/AggregateTiming.ts
|
|
768
|
+
var AggregateTiming = class {
|
|
769
|
+
constructor(title) {
|
|
770
|
+
this.title = title;
|
|
771
|
+
}
|
|
772
|
+
#data = /* @__PURE__ */ new Map();
|
|
773
|
+
#last;
|
|
774
|
+
start(name) {
|
|
775
|
+
const time = process.hrtime.bigint();
|
|
776
|
+
if (this.#last) {
|
|
777
|
+
this.#last.total += time;
|
|
778
|
+
}
|
|
779
|
+
let data = this.#data.get(name);
|
|
780
|
+
if (data === void 0) {
|
|
781
|
+
data = { count: 1, total: -time };
|
|
782
|
+
this.#data.set(name, data);
|
|
783
|
+
} else {
|
|
784
|
+
data.total -= time;
|
|
785
|
+
data.count++;
|
|
786
|
+
}
|
|
787
|
+
this.#last = data;
|
|
788
|
+
}
|
|
789
|
+
stop() {
|
|
790
|
+
const time = process.hrtime.bigint();
|
|
791
|
+
if (this.#last) {
|
|
792
|
+
this.#last.total += time;
|
|
793
|
+
this.#last = void 0;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
printResults() {
|
|
797
|
+
const table = new Table({
|
|
798
|
+
sortColumn: -1,
|
|
799
|
+
showFooter: true,
|
|
800
|
+
showHeader: true,
|
|
801
|
+
title: this.title,
|
|
802
|
+
columns: [
|
|
803
|
+
{
|
|
804
|
+
header: "Duration",
|
|
805
|
+
type: "bigint",
|
|
806
|
+
renderAs: "nanoseconds",
|
|
807
|
+
footer: { aggregate: "sum" }
|
|
808
|
+
},
|
|
809
|
+
{ header: "Task", type: "string", alignment: "left", footer: "TOTAL" },
|
|
810
|
+
{ header: "Count", type: "bigint", footer: { aggregate: "sum" } },
|
|
811
|
+
{ header: "Avg", type: "bigint", footer: { aggregate: "average" } }
|
|
812
|
+
]
|
|
813
|
+
});
|
|
814
|
+
for (const [name, value] of this.#data) {
|
|
815
|
+
table.addRow(
|
|
816
|
+
value.total,
|
|
817
|
+
name,
|
|
818
|
+
BigInt(value.count),
|
|
819
|
+
// fixme this can be a number later
|
|
820
|
+
value.total / BigInt(value.count)
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
table.print();
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
// src/Timing.ts
|
|
828
|
+
var Timing = class {
|
|
829
|
+
constructor(title) {
|
|
830
|
+
this.title = title;
|
|
831
|
+
this.stop();
|
|
832
|
+
}
|
|
833
|
+
#starts = [];
|
|
834
|
+
start(name) {
|
|
835
|
+
this.#starts.push({ name, start: process.hrtime.bigint() });
|
|
836
|
+
}
|
|
837
|
+
stop() {
|
|
838
|
+
this.#starts.push({ start: process.hrtime.bigint() });
|
|
839
|
+
}
|
|
840
|
+
printResults() {
|
|
841
|
+
const table = new Table({
|
|
842
|
+
sortColumn: -1,
|
|
843
|
+
showFooter: true,
|
|
844
|
+
showHeader: true,
|
|
845
|
+
title: this.title,
|
|
846
|
+
columns: [
|
|
847
|
+
{
|
|
848
|
+
header: "Duration",
|
|
849
|
+
type: "bigint",
|
|
850
|
+
renderAs: "nanoseconds",
|
|
851
|
+
precision: 4,
|
|
852
|
+
footer: { aggregate: "sum" }
|
|
853
|
+
},
|
|
854
|
+
{ header: "Task", type: "string", footer: "TOTAL" }
|
|
855
|
+
]
|
|
856
|
+
});
|
|
857
|
+
this.stop();
|
|
858
|
+
let cur = this.#starts[0];
|
|
859
|
+
for (const entry of this.#starts) {
|
|
860
|
+
if (cur.name) {
|
|
861
|
+
const span = entry.start - cur.start;
|
|
862
|
+
table.addRow(span, cur.name);
|
|
863
|
+
}
|
|
864
|
+
cur = entry;
|
|
865
|
+
}
|
|
866
|
+
table.print();
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
export {
|
|
870
|
+
AggregateTiming,
|
|
871
|
+
CachingHost,
|
|
872
|
+
SimpleHost,
|
|
873
|
+
Table,
|
|
874
|
+
Timing,
|
|
875
|
+
findWorkspaceDir,
|
|
876
|
+
getPackageNameToDir,
|
|
877
|
+
getWorkspacePackageDirs,
|
|
878
|
+
matchesAnyGlob,
|
|
879
|
+
mutateJson,
|
|
880
|
+
nanosecondsToSanity
|
|
881
|
+
};
|
|
882
|
+
/*!
|
|
883
|
+
* Copyright 2019 Palantir Technologies, Inc.
|
|
884
|
+
*
|
|
885
|
+
* Licensed under the MIT license. See LICENSE file in the project root for details.
|
|
886
|
+
*
|
|
887
|
+
*/
|
|
888
|
+
/*!
|
|
889
|
+
* Copyright 2022 Palantir Technologies, Inc.
|
|
890
|
+
*
|
|
891
|
+
* Licensed under the MIT license. See LICENSE file in the project root for details.
|
|
892
|
+
*
|
|
893
|
+
*/
|
|
894
|
+
//# sourceMappingURL=index.js.map
|