metro 0.65.2 → 0.67.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +27 -27
- package/src/Assets.js +9 -9
- package/src/Assets.js.flow +5 -7
- package/src/Bundler/util.js +17 -15
- package/src/Bundler/util.js.flow +12 -10
- package/src/Bundler.js +22 -9
- package/src/Bundler.js.flow +20 -7
- package/src/DeltaBundler/DeltaCalculator.js +17 -15
- package/src/DeltaBundler/DeltaCalculator.js.flow +9 -7
- package/src/DeltaBundler/Serializers/baseBytecodeBundle.js +13 -13
- package/src/DeltaBundler/Serializers/baseBytecodeBundle.js.flow +6 -7
- package/src/DeltaBundler/Serializers/baseJSBundle.js +4 -4
- package/src/DeltaBundler/Serializers/baseJSBundle.js.flow +4 -4
- package/src/DeltaBundler/Serializers/getAllFiles.js +1 -1
- package/src/DeltaBundler/Serializers/getAllFiles.js.flow +3 -3
- package/src/DeltaBundler/Serializers/getAssets.js +3 -3
- package/src/DeltaBundler/Serializers/getAssets.js.flow +4 -5
- package/src/DeltaBundler/Serializers/getExplodedSourceMap.js +4 -4
- package/src/DeltaBundler/Serializers/getExplodedSourceMap.js.flow +4 -4
- package/src/DeltaBundler/Serializers/getRamBundleInfo.js +20 -20
- package/src/DeltaBundler/Serializers/getRamBundleInfo.js.flow +9 -10
- package/src/DeltaBundler/Serializers/helpers/bytecode.js +11 -11
- package/src/DeltaBundler/Serializers/helpers/bytecode.js.flow +5 -6
- package/src/DeltaBundler/Serializers/helpers/getInlineSourceMappingURL.js +1 -1
- package/src/DeltaBundler/Serializers/helpers/getInlineSourceMappingURL.js.flow +1 -1
- package/src/DeltaBundler/Serializers/helpers/getSourceMapInfo.js +2 -2
- package/src/DeltaBundler/Serializers/helpers/getSourceMapInfo.js.flow +4 -4
- package/src/DeltaBundler/Serializers/helpers/getTransitiveDependencies.js +1 -1
- package/src/DeltaBundler/Serializers/helpers/getTransitiveDependencies.js.flow +1 -1
- package/src/DeltaBundler/Serializers/helpers/js.js +18 -8
- package/src/DeltaBundler/Serializers/helpers/js.js.flow +19 -10
- package/src/DeltaBundler/Serializers/helpers/processBytecodeModules.js +4 -4
- package/src/DeltaBundler/Serializers/helpers/processBytecodeModules.js.flow +3 -3
- package/src/DeltaBundler/Serializers/helpers/processModules.js +4 -4
- package/src/DeltaBundler/Serializers/helpers/processModules.js.flow +3 -3
- package/src/DeltaBundler/Serializers/hmrJSBundle.js +9 -9
- package/src/DeltaBundler/Serializers/hmrJSBundle.js.flow +9 -8
- package/src/DeltaBundler/Serializers/sourceMapGenerator.js +6 -6
- package/src/DeltaBundler/Serializers/sourceMapGenerator.js.flow +3 -4
- package/src/DeltaBundler/Serializers/sourceMapObject.js +5 -5
- package/src/DeltaBundler/Serializers/sourceMapObject.js.flow +4 -4
- package/src/DeltaBundler/Serializers/sourceMapString.js +2 -2
- package/src/DeltaBundler/Serializers/sourceMapString.js.flow +3 -3
- package/src/DeltaBundler/Transformer.js +16 -14
- package/src/DeltaBundler/Transformer.js.flow +15 -15
- package/src/DeltaBundler/Worker.js +8 -11
- package/src/DeltaBundler/Worker.js.flow +8 -11
- package/src/DeltaBundler/WorkerFarm.js +15 -18
- package/src/DeltaBundler/WorkerFarm.js.flow +9 -11
- package/src/DeltaBundler/__fixtures__/hasteImpl.js +2 -2
- package/src/DeltaBundler/computeDelta.js +2 -2
- package/src/DeltaBundler/computeDelta.js.flow +2 -2
- package/src/DeltaBundler/getTransformCacheKey.js +4 -4
- package/src/DeltaBundler/getTransformCacheKey.js.flow +5 -6
- package/src/DeltaBundler/mergeDeltas.js +2 -2
- package/src/DeltaBundler/mergeDeltas.js.flow +1 -1
- package/src/DeltaBundler/traverseDependencies.js +22 -22
- package/src/DeltaBundler/traverseDependencies.js.flow +3 -3
- package/src/DeltaBundler/types.flow.js +1 -1
- package/src/DeltaBundler/types.flow.js.flow +15 -1
- package/src/DeltaBundler.js +5 -5
- package/src/DeltaBundler.js.flow +4 -4
- package/src/HmrServer.js +73 -55
- package/src/HmrServer.js.flow +42 -37
- package/src/IncrementalBundler/GraphNotFoundError.js +1 -1
- package/src/IncrementalBundler/GraphNotFoundError.js.flow +1 -1
- package/src/IncrementalBundler/ResourceNotFoundError.js +1 -1
- package/src/IncrementalBundler/ResourceNotFoundError.js.flow +1 -1
- package/src/IncrementalBundler/RevisionNotFoundError.js +1 -1
- package/src/IncrementalBundler/RevisionNotFoundError.js.flow +1 -1
- package/src/IncrementalBundler.js +46 -32
- package/src/IncrementalBundler.js.flow +32 -24
- package/src/ModuleGraph/module.js +3 -3
- package/src/ModuleGraph/module.js.flow +1 -1
- package/src/ModuleGraph/node-haste/HasteFS.js +5 -3
- package/src/ModuleGraph/node-haste/HasteFS.js.flow +3 -1
- package/src/ModuleGraph/node-haste/Module.js +1 -1
- package/src/ModuleGraph/node-haste/Module.js.flow +1 -1
- package/src/ModuleGraph/node-haste/ModuleCache.js +1 -1
- package/src/ModuleGraph/node-haste/ModuleCache.js.flow +3 -3
- package/src/ModuleGraph/node-haste/Package.js +3 -3
- package/src/ModuleGraph/node-haste/Package.js.flow +3 -3
- package/src/ModuleGraph/node-haste/node-haste.flow.js +1 -1
- package/src/ModuleGraph/node-haste/node-haste.flow.js.flow +1 -1
- package/src/ModuleGraph/node-haste/node-haste.js +41 -31
- package/src/ModuleGraph/node-haste/node-haste.js.flow +28 -22
- package/src/ModuleGraph/output/indexed-ram-bundle.js +17 -17
- package/src/ModuleGraph/output/indexed-ram-bundle.js.flow +41 -9
- package/src/ModuleGraph/output/multiple-files-ram-bundle.js +18 -18
- package/src/ModuleGraph/output/multiple-files-ram-bundle.js.flow +21 -9
- package/src/ModuleGraph/output/plain-bundle.js +6 -6
- package/src/ModuleGraph/output/plain-bundle.js.flow +7 -7
- package/src/ModuleGraph/output/reverse-dependency-map-references.js +3 -3
- package/src/ModuleGraph/output/reverse-dependency-map-references.js.flow +4 -8
- package/src/ModuleGraph/output/util.js +61 -40
- package/src/ModuleGraph/output/util.js.flow +51 -28
- package/src/ModuleGraph/silent-console.js +2 -2
- package/src/ModuleGraph/silent-console.js.flow +1 -1
- package/src/ModuleGraph/test-helpers.js +7 -7
- package/src/ModuleGraph/types.flow.js +1 -1
- package/src/ModuleGraph/types.flow.js.flow +47 -31
- package/src/ModuleGraph/worker/JsFileWrapping.js +16 -16
- package/src/ModuleGraph/worker/JsFileWrapping.js.flow +3 -2
- package/src/ModuleGraph/worker/Platforms.js +2 -2
- package/src/ModuleGraph/worker/Platforms.js.flow +1 -1
- package/src/ModuleGraph/worker/collectDependencies.js +24 -25
- package/src/ModuleGraph/worker/collectDependencies.js.flow +16 -18
- package/src/ModuleGraph/worker/generate.js +2 -2
- package/src/ModuleGraph/worker/generate.js.flow +3 -3
- package/src/ModuleGraph/worker/generateImportNames.js +5 -5
- package/src/ModuleGraph/worker/generateImportNames.js.flow +3 -5
- package/src/ModuleGraph/worker/mergeSourceMaps.js +8 -7
- package/src/ModuleGraph/worker/mergeSourceMaps.js.flow +3 -3
- package/src/Server/MultipartResponse.js +4 -8
- package/src/Server/symbolicate.js +8 -8
- package/src/Server/symbolicate.js.flow +17 -5
- package/src/Server.js +204 -150
- package/src/Server.js.flow +131 -87
- package/src/cli-utils.js +4 -4
- package/src/cli-utils.js.flow +15 -13
- package/src/cli.js +4 -4
- package/src/cli.js.flow +2 -4
- package/src/commands/build.js +23 -24
- package/src/commands/build.js.flow +6 -9
- package/src/commands/dependencies.js +25 -19
- package/src/commands/serve.js +19 -19
- package/src/commands/serve.js.flow +7 -9
- package/src/index.js +117 -50
- package/src/index.js.flow +108 -40
- package/src/integration_tests/basic_bundle/AssetRegistry.js +2 -2
- package/src/integration_tests/basic_bundle/AssetRegistry.js.flow +1 -1
- package/src/integration_tests/basic_bundle/Bar.js +2 -2
- package/src/integration_tests/basic_bundle/Bar.js.flow +1 -1
- package/src/integration_tests/basic_bundle/ErrorBundle.js +2 -2
- package/src/integration_tests/basic_bundle/ErrorBundle.js.flow +1 -1
- package/src/integration_tests/basic_bundle/Foo.js +2 -2
- package/src/integration_tests/basic_bundle/Foo.js.flow +1 -1
- package/src/integration_tests/basic_bundle/TestBundle.js +2 -2
- package/src/integration_tests/basic_bundle/TestBundle.js.flow +1 -1
- package/src/integration_tests/basic_bundle/TestPolyfill.js +1 -1
- package/src/integration_tests/basic_bundle/TestPolyfill.js.flow +1 -1
- package/src/integration_tests/basic_bundle/TypeScript.ts +1 -1
- package/src/integration_tests/basic_bundle/import-export/export-1.js +2 -2
- package/src/integration_tests/basic_bundle/import-export/export-1.js.flow +1 -1
- package/src/integration_tests/basic_bundle/import-export/export-2.js +2 -2
- package/src/integration_tests/basic_bundle/import-export/export-2.js.flow +1 -1
- package/src/integration_tests/basic_bundle/import-export/export-3.js +2 -2
- package/src/integration_tests/basic_bundle/import-export/export-3.js.flow +1 -1
- package/src/integration_tests/basic_bundle/import-export/export-4.js +2 -2
- package/src/integration_tests/basic_bundle/import-export/export-4.js.flow +1 -1
- package/src/integration_tests/basic_bundle/import-export/export-5.js +2 -2
- package/src/integration_tests/basic_bundle/import-export/export-5.js.flow +1 -1
- package/src/integration_tests/basic_bundle/import-export/export-6.js +2 -2
- package/src/integration_tests/basic_bundle/import-export/export-6.js.flow +1 -1
- package/src/integration_tests/basic_bundle/import-export/export-null.js +2 -2
- package/src/integration_tests/basic_bundle/import-export/export-null.js.flow +1 -1
- package/src/integration_tests/basic_bundle/import-export/export-primitive-default.js +2 -2
- package/src/integration_tests/basic_bundle/import-export/export-primitive-default.js.flow +1 -1
- package/src/integration_tests/basic_bundle/import-export/index.js +17 -17
- package/src/integration_tests/basic_bundle/import-export/index.js.flow +1 -1
- package/src/integration_tests/basic_bundle/polyfill.js +1 -1
- package/src/integration_tests/execBundle.js +2 -2
- package/src/integration_tests/execBundle.js.flow +1 -1
- package/src/integration_tests/metro.config.js +8 -8
- package/src/lib/BatchProcessor.js +10 -6
- package/src/lib/BatchProcessor.js.flow +6 -1
- package/src/lib/JsonReporter.js +3 -2
- package/src/lib/JsonReporter.js.flow +2 -1
- package/src/lib/RamBundleParser.js +1 -1
- package/src/lib/RamBundleParser.js.flow +1 -1
- package/src/lib/TerminalReporter.js +15 -15
- package/src/lib/TerminalReporter.js.flow +15 -16
- package/src/lib/bundleToBytecode.js +6 -7
- package/src/lib/bundleToBytecode.js.flow +8 -7
- package/src/lib/bundleToString.js +3 -3
- package/src/lib/bundleToString.js.flow +5 -4
- package/src/lib/countLines.js +3 -7
- package/src/lib/countLines.js.flow +4 -7
- package/src/lib/createModuleIdFactory.js +2 -2
- package/src/lib/createModuleIdFactory.js.flow +1 -1
- package/src/lib/{attachWebsocketServer.js → createWebsocketServer.js} +18 -17
- package/src/lib/{attachWebsocketServer.js.flow → createWebsocketServer.js.flow} +13 -23
- package/src/lib/debounceAsyncQueue.js +2 -2
- package/src/lib/debounceAsyncQueue.js.flow +1 -1
- package/src/lib/formatBundlingError.js +21 -21
- package/src/lib/formatBundlingError.js.flow +18 -20
- package/src/lib/getAppendScripts.js +26 -27
- package/src/lib/getAppendScripts.js.flow +7 -8
- package/src/lib/getGraphId.js +3 -3
- package/src/lib/getGraphId.js.flow +3 -3
- package/src/lib/getMaxWorkers.js +2 -2
- package/src/lib/getMaxWorkers.js.flow +1 -1
- package/src/lib/getPreludeCode.js +2 -2
- package/src/lib/getPreludeCode.js.flow +1 -1
- package/src/lib/getPrependedScripts.js +16 -15
- package/src/lib/getPrependedScripts.js.flow +8 -8
- package/src/lib/logToConsole.js +12 -5
- package/src/lib/logToConsole.js.flow +19 -6
- package/src/lib/parseCustomTransformOptions.js +2 -2
- package/src/lib/parseCustomTransformOptions.js.flow +3 -3
- package/src/lib/parseOptionsFromUrl.js +7 -7
- package/src/lib/parseOptionsFromUrl.js.flow +29 -9
- package/src/lib/relativizeSourceMap.js +1 -1
- package/src/lib/relativizeSourceMap.js.flow +3 -3
- package/src/lib/reporting.js +5 -5
- package/src/lib/reporting.js.flow +18 -4
- package/src/lib/splitBundleOptions.js +5 -5
- package/src/lib/splitBundleOptions.js.flow +1 -1
- package/src/lib/transformHelpers.js +11 -10
- package/src/lib/transformHelpers.js.flow +6 -13
- package/src/node-haste/DependencyGraph/ModuleResolution.js +51 -30
- package/src/node-haste/DependencyGraph/ModuleResolution.js.flow +49 -48
- package/src/node-haste/DependencyGraph/createHasteMap.js +99 -0
- package/src/node-haste/DependencyGraph/createHasteMap.js.flow +88 -0
- package/src/node-haste/DependencyGraph/{assets/empty-module.js → types.js} +2 -2
- package/src/node-haste/DependencyGraph/types.js.flow +88 -0
- package/src/node-haste/DependencyGraph.js +51 -118
- package/src/node-haste/DependencyGraph.js.flow +38 -111
- package/src/node-haste/Module.js +1 -1
- package/src/node-haste/Module.js.flow +3 -3
- package/src/node-haste/ModuleCache.js +54 -13
- package/src/node-haste/ModuleCache.js.flow +53 -12
- package/src/node-haste/Package.js +2 -2
- package/src/node-haste/Package.js.flow +1 -1
- package/src/node-haste/lib/AssetPaths.js +5 -5
- package/src/node-haste/lib/AssetPaths.js.flow +7 -6
- package/src/node-haste/lib/parsePlatformFilePath.js +4 -4
- package/src/node-haste/lib/parsePlatformFilePath.js.flow +2 -2
- package/src/shared/output/RamBundle/as-assets.js +14 -15
- package/src/shared/output/RamBundle/as-assets.js.flow +9 -11
- package/src/shared/output/RamBundle/as-indexed-file.js +14 -15
- package/src/shared/output/RamBundle/as-indexed-file.js.flow +8 -12
- package/src/shared/output/RamBundle/buildSourcemapWithMetadata.js +7 -7
- package/src/shared/output/RamBundle/buildSourcemapWithMetadata.js.flow +4 -4
- package/src/shared/output/RamBundle/magic-number.js +1 -1
- package/src/shared/output/RamBundle/magic-number.js.flow +1 -1
- package/src/shared/output/RamBundle/util.js +21 -19
- package/src/shared/output/RamBundle/util.js.flow +5 -8
- package/src/shared/output/RamBundle/write-sourcemap.js +1 -1
- package/src/shared/output/RamBundle/write-sourcemap.js.flow +1 -1
- package/src/shared/output/RamBundle.js +2 -2
- package/src/shared/output/RamBundle.js.flow +4 -5
- package/src/shared/output/bundle.js +6 -6
- package/src/shared/output/bundle.js.flow +4 -5
- package/src/shared/output/meta.js +4 -5
- package/src/shared/output/meta.js.flow +2 -4
- package/src/shared/output/unbundle.js +1 -1
- package/src/shared/output/unbundle.js.flow +1 -1
- package/src/shared/output/writeFile.js +1 -1
- package/src/shared/output/writeFile.js.flow +1 -1
- package/src/shared/types.flow.js +1 -1
- package/src/shared/types.flow.js.flow +6 -4
- package/src/node-haste/DependencyGraph/assets/empty-module.js.flow +0 -9
- package/src/node-haste/types.js +0 -10
- package/src/node-haste/types.js.flow +0 -23
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _jestHasteMap = require("jest-haste-map");
|
|
4
|
+
|
|
1
5
|
/**
|
|
2
|
-
* Copyright (c)
|
|
6
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
7
|
*
|
|
4
8
|
* This source code is licensed under the MIT license found in the
|
|
5
9
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -7,37 +11,31 @@
|
|
|
7
11
|
*
|
|
8
12
|
* @format
|
|
9
13
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const { AmbiguousModuleResolutionError } = require("metro-core");
|
|
13
|
-
|
|
14
|
-
const { DuplicateHasteCandidatesError } = require("jest-haste-map").ModuleMap;
|
|
14
|
+
const createHasteMap = require("./DependencyGraph/createHasteMap");
|
|
15
15
|
|
|
16
|
-
const {
|
|
17
|
-
|
|
18
|
-
const { PackageResolutionError } = require("metro-core");
|
|
19
|
-
|
|
20
|
-
const JestHasteMap = require("jest-haste-map");
|
|
16
|
+
const { ModuleResolver } = require("./DependencyGraph/ModuleResolution");
|
|
21
17
|
|
|
22
18
|
const Module = require("./Module");
|
|
23
19
|
|
|
24
20
|
const ModuleCache = require("./ModuleCache");
|
|
25
21
|
|
|
26
|
-
const
|
|
22
|
+
const { EventEmitter } = require("events");
|
|
27
23
|
|
|
28
24
|
const fs = require("fs");
|
|
29
25
|
|
|
30
|
-
const
|
|
26
|
+
const {
|
|
27
|
+
AmbiguousModuleResolutionError,
|
|
28
|
+
Logger: { createActionStartEntry, createActionEndEntry, log },
|
|
29
|
+
PackageResolutionError,
|
|
30
|
+
} = require("metro-core");
|
|
31
31
|
|
|
32
|
-
const {
|
|
32
|
+
const { InvalidPackageError } = require("metro-resolver");
|
|
33
33
|
|
|
34
|
-
const
|
|
34
|
+
const nullthrows = require("nullthrows");
|
|
35
35
|
|
|
36
|
-
const
|
|
37
|
-
Logger: { createActionStartEntry, createActionEndEntry, log }
|
|
38
|
-
} = require("metro-core");
|
|
36
|
+
const path = require("path");
|
|
39
37
|
|
|
40
|
-
const
|
|
38
|
+
const { DuplicateHasteCandidatesError } = _jestHasteMap.ModuleMap;
|
|
41
39
|
|
|
42
40
|
function getOrCreate(map, field) {
|
|
43
41
|
let subMap = map.get(field);
|
|
@@ -51,7 +49,6 @@ function getOrCreate(map, field) {
|
|
|
51
49
|
}
|
|
52
50
|
|
|
53
51
|
class DependencyGraph extends EventEmitter {
|
|
54
|
-
// $FlowFixMe[value-as-type]
|
|
55
52
|
constructor({ config, haste, initialHasteFS, initialModuleMap }) {
|
|
56
53
|
super();
|
|
57
54
|
this._config = config;
|
|
@@ -59,8 +56,8 @@ class DependencyGraph extends EventEmitter {
|
|
|
59
56
|
this._hasteFS = initialHasteFS;
|
|
60
57
|
this._moduleMap = initialModuleMap;
|
|
61
58
|
this._assetExtensions = new Set(
|
|
62
|
-
config.resolver.assetExts.map(asset => "." + asset)
|
|
63
|
-
);
|
|
59
|
+
config.resolver.assetExts.map((asset) => "." + asset)
|
|
60
|
+
); // $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
|
64
61
|
|
|
65
62
|
this._haste.on("change", this._onHasteChange.bind(this));
|
|
66
63
|
|
|
@@ -70,86 +67,32 @@ class DependencyGraph extends EventEmitter {
|
|
|
70
67
|
this._createModuleResolver();
|
|
71
68
|
}
|
|
72
69
|
|
|
73
|
-
static _getIgnorePattern(config) {
|
|
74
|
-
/*
|
|
75
|
-
For now we support both blockList and blacklistRE options
|
|
76
|
-
*/
|
|
77
|
-
const { blockList, blacklistRE } = config.resolver;
|
|
78
|
-
|
|
79
|
-
const combine = regexes =>
|
|
80
|
-
new RegExp(
|
|
81
|
-
regexes
|
|
82
|
-
.map(regex => "(" + regex.source.replace(/\//g, path.sep) + ")")
|
|
83
|
-
.join("|")
|
|
84
|
-
); // If `blacklistRE` is set - use it,
|
|
85
|
-
// if `blockList` is set - use it
|
|
86
|
-
|
|
87
|
-
const ignorePattern = blacklistRE || blockList; // If neither option has been set, use default pattern
|
|
88
|
-
|
|
89
|
-
if (!ignorePattern) {
|
|
90
|
-
return / ^/;
|
|
91
|
-
} // If ignorePattern is an array, merge it into one
|
|
92
|
-
|
|
93
|
-
if (Array.isArray(ignorePattern)) {
|
|
94
|
-
return combine(ignorePattern);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return ignorePattern;
|
|
98
|
-
} // $FlowFixMe[value-as-type]
|
|
99
|
-
|
|
100
|
-
static _createHaste(config, watch) {
|
|
101
|
-
const haste = new JestHasteMap({
|
|
102
|
-
cacheDirectory: config.hasteMapCacheDirectory,
|
|
103
|
-
dependencyExtractor: config.resolver.dependencyExtractor,
|
|
104
|
-
computeSha1: true,
|
|
105
|
-
extensions: config.resolver.sourceExts.concat(config.resolver.assetExts),
|
|
106
|
-
forceNodeFilesystemAPI: !config.resolver.useWatchman,
|
|
107
|
-
hasteImplModulePath: config.resolver.hasteImplModulePath,
|
|
108
|
-
ignorePattern: this._getIgnorePattern(config),
|
|
109
|
-
maxWorkers: config.maxWorkers,
|
|
110
|
-
mocksPattern: "",
|
|
111
|
-
name: "metro-" + JEST_HASTE_MAP_CACHE_BREAKER,
|
|
112
|
-
platforms: config.resolver.platforms,
|
|
113
|
-
retainAllFiles: true,
|
|
114
|
-
resetCache: config.resetCache,
|
|
115
|
-
rootDir: config.projectRoot,
|
|
116
|
-
roots: config.watchFolders,
|
|
117
|
-
throwOnModuleCollision: true,
|
|
118
|
-
useWatchman: config.resolver.useWatchman,
|
|
119
|
-
watch: watch == null ? !ci.isCI : watch
|
|
120
|
-
}); // We can have a lot of graphs listening to Haste for changes.
|
|
121
|
-
// Bump this up to silence the max listeners EventEmitter warning.
|
|
122
|
-
|
|
123
|
-
haste.setMaxListeners(1000);
|
|
124
|
-
return haste;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
70
|
static async load(config, options) {
|
|
71
|
+
const { hasReducedPerformance, watch } =
|
|
72
|
+
options !== null && options !== void 0 ? options : {};
|
|
128
73
|
const initializingMetroLogEntry = log(
|
|
129
74
|
createActionStartEntry("Initializing Metro")
|
|
130
75
|
);
|
|
131
76
|
config.reporter.update({
|
|
132
77
|
type: "dep_graph_loading",
|
|
133
|
-
hasReducedPerformance:
|
|
134
|
-
? Boolean(options.hasReducedPerformance)
|
|
135
|
-
: false
|
|
78
|
+
hasReducedPerformance: !!hasReducedPerformance,
|
|
136
79
|
});
|
|
80
|
+
const haste = createHasteMap(config, {
|
|
81
|
+
watch,
|
|
82
|
+
}); // We can have a lot of graphs listening to Haste for changes.
|
|
83
|
+
// Bump this up to silence the max listeners EventEmitter warning.
|
|
137
84
|
|
|
138
|
-
|
|
139
|
-
config,
|
|
140
|
-
options && options.watch
|
|
141
|
-
);
|
|
142
|
-
|
|
85
|
+
haste.setMaxListeners(1000);
|
|
143
86
|
const { hasteFS, moduleMap } = await haste.build();
|
|
144
87
|
log(createActionEndEntry(initializingMetroLogEntry));
|
|
145
88
|
config.reporter.update({
|
|
146
|
-
type: "dep_graph_loaded"
|
|
89
|
+
type: "dep_graph_loaded",
|
|
147
90
|
});
|
|
148
91
|
return new DependencyGraph({
|
|
149
92
|
haste,
|
|
150
93
|
initialHasteFS: hasteFS,
|
|
151
94
|
initialModuleMap: moduleMap,
|
|
152
|
-
config
|
|
95
|
+
config,
|
|
153
96
|
});
|
|
154
97
|
}
|
|
155
98
|
|
|
@@ -186,16 +129,19 @@ class DependencyGraph extends EventEmitter {
|
|
|
186
129
|
|
|
187
130
|
_createModuleResolver() {
|
|
188
131
|
this._moduleResolver = new ModuleResolver({
|
|
189
|
-
dirExists: filePath => {
|
|
132
|
+
dirExists: (filePath) => {
|
|
190
133
|
try {
|
|
191
134
|
return fs.lstatSync(filePath).isDirectory();
|
|
192
135
|
} catch (e) {}
|
|
193
136
|
|
|
194
137
|
return false;
|
|
195
138
|
},
|
|
139
|
+
disableHierarchicalLookup:
|
|
140
|
+
this._config.resolver.disableHierarchicalLookup,
|
|
196
141
|
doesFileExist: this._doesFileExist,
|
|
142
|
+
emptyModulePath: this._config.resolver.emptyModulePath,
|
|
197
143
|
extraNodeModules: this._config.resolver.extraNodeModules,
|
|
198
|
-
isAssetFile: file => this._assetExtensions.has(path.extname(file)),
|
|
144
|
+
isAssetFile: (file) => this._assetExtensions.has(path.extname(file)),
|
|
199
145
|
mainFields: this._config.resolver.resolverMainFields,
|
|
200
146
|
moduleCache: this._moduleCache,
|
|
201
147
|
moduleMap: this._moduleMap,
|
|
@@ -207,19 +153,20 @@ class DependencyGraph extends EventEmitter {
|
|
|
207
153
|
const assets = [
|
|
208
154
|
basePath + extension,
|
|
209
155
|
...this._config.resolver.assetResolutions.map(
|
|
210
|
-
resolution => basePath + "@" + resolution + "x" + extension
|
|
211
|
-
)
|
|
212
|
-
].filter(candidate => this._hasteFS.exists(candidate));
|
|
156
|
+
(resolution) => basePath + "@" + resolution + "x" + extension
|
|
157
|
+
),
|
|
158
|
+
].filter((candidate) => this._hasteFS.exists(candidate));
|
|
213
159
|
return assets.length ? assets : null;
|
|
214
160
|
},
|
|
215
161
|
resolveRequest: this._config.resolver.resolveRequest,
|
|
216
|
-
sourceExts: this._config.resolver.sourceExts
|
|
162
|
+
sourceExts: this._config.resolver.sourceExts,
|
|
217
163
|
});
|
|
218
164
|
}
|
|
219
165
|
|
|
220
166
|
_createModuleCache() {
|
|
221
167
|
return new ModuleCache({
|
|
222
|
-
|
|
168
|
+
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
|
169
|
+
getClosestPackage: this._getClosestPackage.bind(this),
|
|
223
170
|
});
|
|
224
171
|
}
|
|
225
172
|
|
|
@@ -248,7 +195,7 @@ class DependencyGraph extends EventEmitter {
|
|
|
248
195
|
}
|
|
249
196
|
|
|
250
197
|
return sha1;
|
|
251
|
-
}
|
|
198
|
+
}
|
|
252
199
|
|
|
253
200
|
getWatcher() {
|
|
254
201
|
return this._haste;
|
|
@@ -263,25 +210,22 @@ class DependencyGraph extends EventEmitter {
|
|
|
263
210
|
to,
|
|
264
211
|
platform,
|
|
265
212
|
{ assumeFlatNodeModules } = {
|
|
266
|
-
assumeFlatNodeModules: false
|
|
213
|
+
assumeFlatNodeModules: false,
|
|
267
214
|
}
|
|
268
215
|
) {
|
|
269
|
-
const
|
|
216
|
+
const isSensitiveToOriginFolder = // Resolution is always relative to the origin folder unless we assume a flat node_modules
|
|
217
|
+
!assumeFlatNodeModules || // Path requests are resolved relative to the origin folder
|
|
270
218
|
to.includes("/") ||
|
|
271
219
|
to === "." ||
|
|
272
|
-
to === ".." ||
|
|
220
|
+
to === ".." || // Preserve standard assumptions under node_modules
|
|
273
221
|
from.includes(path.sep + "node_modules" + path.sep);
|
|
274
222
|
const mapByDirectory = getOrCreate(
|
|
275
223
|
this._resolutionCache,
|
|
276
|
-
|
|
224
|
+
isSensitiveToOriginFolder ? path.dirname(from) : ""
|
|
277
225
|
);
|
|
278
|
-
|
|
226
|
+
const mapByPlatform = getOrCreate(mapByDirectory, to);
|
|
279
227
|
let modulePath = mapByPlatform.get(platform);
|
|
280
228
|
|
|
281
|
-
if (!modulePath) {
|
|
282
|
-
modulePath = this._moduleMap.getModule(to, platform, true);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
229
|
if (!modulePath) {
|
|
286
230
|
try {
|
|
287
231
|
modulePath = this._moduleResolver.resolveDependency(
|
|
@@ -289,18 +233,7 @@ class DependencyGraph extends EventEmitter {
|
|
|
289
233
|
to,
|
|
290
234
|
true,
|
|
291
235
|
platform
|
|
292
|
-
).path;
|
|
293
|
-
// we need to cache packages by directory instead of globally.
|
|
294
|
-
|
|
295
|
-
if (
|
|
296
|
-
!assumeFlatNodeModules &&
|
|
297
|
-
modulePath.includes(path.sep + "node_modules" + path.sep)
|
|
298
|
-
) {
|
|
299
|
-
mapByPlatform = getOrCreate(
|
|
300
|
-
getOrCreate(this._resolutionCache, path.dirname(from)),
|
|
301
|
-
to
|
|
302
|
-
);
|
|
303
|
-
}
|
|
236
|
+
).path;
|
|
304
237
|
} catch (error) {
|
|
305
238
|
if (error instanceof DuplicateHasteCandidatesError) {
|
|
306
239
|
throw new AmbiguousModuleResolutionError(from, error);
|
|
@@ -310,7 +243,7 @@ class DependencyGraph extends EventEmitter {
|
|
|
310
243
|
throw new PackageResolutionError({
|
|
311
244
|
packageError: error,
|
|
312
245
|
originModulePath: from,
|
|
313
|
-
targetModuleName: to
|
|
246
|
+
targetModuleName: to,
|
|
314
247
|
});
|
|
315
248
|
}
|
|
316
249
|
|
|
@@ -322,7 +255,7 @@ class DependencyGraph extends EventEmitter {
|
|
|
322
255
|
return modulePath;
|
|
323
256
|
}
|
|
324
257
|
|
|
325
|
-
_doesFileExist = filePath => {
|
|
258
|
+
_doesFileExist = (filePath) => {
|
|
326
259
|
return this._hasteFS.exists(filePath);
|
|
327
260
|
};
|
|
328
261
|
|
|
@@ -337,7 +270,7 @@ class DependencyGraph extends EventEmitter {
|
|
|
337
270
|
}
|
|
338
271
|
|
|
339
272
|
getDependencies(filePath) {
|
|
340
|
-
return this._hasteFS.getDependencies(filePath);
|
|
273
|
+
return nullthrows(this._hasteFS.getDependencies(filePath));
|
|
341
274
|
}
|
|
342
275
|
}
|
|
343
276
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -8,33 +8,28 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
import type {HasteFS, HasteMap, ModuleMap} from './DependencyGraph/types';
|
|
12
|
+
import type Package from './Package';
|
|
13
|
+
import type {ConfigT} from 'metro-config/src/configTypes.flow';
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
const {DuplicateHasteCandidatesError} = require('jest-haste-map').ModuleMap;
|
|
15
|
-
const {InvalidPackageError} = require('metro-resolver');
|
|
16
|
-
const {PackageResolutionError} = require('metro-core');
|
|
15
|
+
import {ModuleMap as JestHasteModuleMap} from 'jest-haste-map';
|
|
17
16
|
|
|
18
|
-
const
|
|
17
|
+
const createHasteMap = require('./DependencyGraph/createHasteMap');
|
|
18
|
+
const {ModuleResolver} = require('./DependencyGraph/ModuleResolution');
|
|
19
19
|
const Module = require('./Module');
|
|
20
20
|
const ModuleCache = require('./ModuleCache');
|
|
21
|
-
|
|
22
|
-
const ci = require('ci-info');
|
|
23
|
-
const fs = require('fs');
|
|
24
|
-
const path = require('path');
|
|
25
|
-
|
|
26
|
-
const {ModuleResolver} = require('./DependencyGraph/ModuleResolution');
|
|
27
21
|
const {EventEmitter} = require('events');
|
|
22
|
+
const fs = require('fs');
|
|
28
23
|
const {
|
|
24
|
+
AmbiguousModuleResolutionError,
|
|
29
25
|
Logger: {createActionStartEntry, createActionEndEntry, log},
|
|
26
|
+
PackageResolutionError,
|
|
30
27
|
} = require('metro-core');
|
|
28
|
+
const {InvalidPackageError} = require('metro-resolver');
|
|
29
|
+
const nullthrows = require('nullthrows');
|
|
30
|
+
const path = require('path');
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
import type Package from './Package';
|
|
34
|
-
import type {HasteFS} from './types';
|
|
35
|
-
import type {ConfigT} from 'metro-config/src/configTypes.flow';
|
|
36
|
-
|
|
37
|
-
const JEST_HASTE_MAP_CACHE_BREAKER = 5;
|
|
32
|
+
const {DuplicateHasteCandidatesError} = JestHasteModuleMap;
|
|
38
33
|
|
|
39
34
|
function getOrCreate<T>(
|
|
40
35
|
map: Map<string, Map<string, T>>,
|
|
@@ -51,8 +46,7 @@ function getOrCreate<T>(
|
|
|
51
46
|
class DependencyGraph extends EventEmitter {
|
|
52
47
|
_assetExtensions: Set<string>;
|
|
53
48
|
_config: ConfigT;
|
|
54
|
-
|
|
55
|
-
_haste: JestHasteMap;
|
|
49
|
+
_haste: HasteMap;
|
|
56
50
|
_hasteFS: HasteFS;
|
|
57
51
|
_moduleCache: ModuleCache;
|
|
58
52
|
_moduleMap: ModuleMap;
|
|
@@ -66,8 +60,7 @@ class DependencyGraph extends EventEmitter {
|
|
|
66
60
|
initialModuleMap,
|
|
67
61
|
}: {|
|
|
68
62
|
+config: ConfigT,
|
|
69
|
-
|
|
70
|
-
+haste: JestHasteMap,
|
|
63
|
+
+haste: HasteMap,
|
|
71
64
|
+initialHasteFS: HasteFS,
|
|
72
65
|
+initialModuleMap: ModuleMap,
|
|
73
66
|
|}) {
|
|
@@ -79,90 +72,32 @@ class DependencyGraph extends EventEmitter {
|
|
|
79
72
|
this._assetExtensions = new Set(
|
|
80
73
|
config.resolver.assetExts.map(asset => '.' + asset),
|
|
81
74
|
);
|
|
75
|
+
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
|
82
76
|
this._haste.on('change', this._onHasteChange.bind(this));
|
|
83
77
|
this._resolutionCache = new Map();
|
|
84
78
|
this._moduleCache = this._createModuleCache();
|
|
85
79
|
this._createModuleResolver();
|
|
86
80
|
}
|
|
87
81
|
|
|
88
|
-
static _getIgnorePattern(config: ConfigT): RegExp {
|
|
89
|
-
/*
|
|
90
|
-
For now we support both blockList and blacklistRE options
|
|
91
|
-
*/
|
|
92
|
-
const {blockList, blacklistRE} = config.resolver;
|
|
93
|
-
|
|
94
|
-
const combine = regexes =>
|
|
95
|
-
new RegExp(
|
|
96
|
-
regexes
|
|
97
|
-
.map(regex => '(' + regex.source.replace(/\//g, path.sep) + ')')
|
|
98
|
-
.join('|'),
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
// If `blacklistRE` is set - use it,
|
|
102
|
-
// if `blockList` is set - use it
|
|
103
|
-
const ignorePattern = blacklistRE || blockList;
|
|
104
|
-
|
|
105
|
-
// If neither option has been set, use default pattern
|
|
106
|
-
if (!ignorePattern) {
|
|
107
|
-
return / ^/;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// If ignorePattern is an array, merge it into one
|
|
111
|
-
if (Array.isArray(ignorePattern)) {
|
|
112
|
-
return combine(ignorePattern);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return ignorePattern;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// $FlowFixMe[value-as-type]
|
|
119
|
-
static _createHaste(config: ConfigT, watch?: boolean): JestHasteMap {
|
|
120
|
-
const haste = new JestHasteMap({
|
|
121
|
-
cacheDirectory: config.hasteMapCacheDirectory,
|
|
122
|
-
dependencyExtractor: config.resolver.dependencyExtractor,
|
|
123
|
-
computeSha1: true,
|
|
124
|
-
extensions: config.resolver.sourceExts.concat(config.resolver.assetExts),
|
|
125
|
-
forceNodeFilesystemAPI: !config.resolver.useWatchman,
|
|
126
|
-
hasteImplModulePath: config.resolver.hasteImplModulePath,
|
|
127
|
-
ignorePattern: this._getIgnorePattern(config),
|
|
128
|
-
maxWorkers: config.maxWorkers,
|
|
129
|
-
mocksPattern: '',
|
|
130
|
-
name: 'metro-' + JEST_HASTE_MAP_CACHE_BREAKER,
|
|
131
|
-
platforms: config.resolver.platforms,
|
|
132
|
-
retainAllFiles: true,
|
|
133
|
-
resetCache: config.resetCache,
|
|
134
|
-
rootDir: config.projectRoot,
|
|
135
|
-
roots: config.watchFolders,
|
|
136
|
-
throwOnModuleCollision: true,
|
|
137
|
-
useWatchman: config.resolver.useWatchman,
|
|
138
|
-
watch: watch == null ? !ci.isCI : watch,
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
// We can have a lot of graphs listening to Haste for changes.
|
|
142
|
-
// Bump this up to silence the max listeners EventEmitter warning.
|
|
143
|
-
haste.setMaxListeners(1000);
|
|
144
|
-
|
|
145
|
-
return haste;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
82
|
static async load(
|
|
149
83
|
config: ConfigT,
|
|
150
84
|
options?: {|+hasReducedPerformance?: boolean, +watch?: boolean|},
|
|
151
85
|
): Promise<DependencyGraph> {
|
|
86
|
+
const {hasReducedPerformance, watch} = options ?? {};
|
|
152
87
|
const initializingMetroLogEntry = log(
|
|
153
88
|
createActionStartEntry('Initializing Metro'),
|
|
154
89
|
);
|
|
155
90
|
|
|
156
91
|
config.reporter.update({
|
|
157
92
|
type: 'dep_graph_loading',
|
|
158
|
-
hasReducedPerformance:
|
|
159
|
-
? Boolean(options.hasReducedPerformance)
|
|
160
|
-
: false,
|
|
93
|
+
hasReducedPerformance: !!hasReducedPerformance,
|
|
161
94
|
});
|
|
162
|
-
const haste =
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
95
|
+
const haste = createHasteMap(config, {watch});
|
|
96
|
+
|
|
97
|
+
// We can have a lot of graphs listening to Haste for changes.
|
|
98
|
+
// Bump this up to silence the max listeners EventEmitter warning.
|
|
99
|
+
haste.setMaxListeners(1000);
|
|
100
|
+
|
|
166
101
|
const {hasteFS, moduleMap} = await haste.build();
|
|
167
102
|
|
|
168
103
|
log(createActionEndEntry(initializingMetroLogEntry));
|
|
@@ -209,7 +144,10 @@ class DependencyGraph extends EventEmitter {
|
|
|
209
144
|
} catch (e) {}
|
|
210
145
|
return false;
|
|
211
146
|
},
|
|
147
|
+
disableHierarchicalLookup:
|
|
148
|
+
this._config.resolver.disableHierarchicalLookup,
|
|
212
149
|
doesFileExist: this._doesFileExist,
|
|
150
|
+
emptyModulePath: this._config.resolver.emptyModulePath,
|
|
213
151
|
extraNodeModules: this._config.resolver.extraNodeModules,
|
|
214
152
|
isAssetFile: file => this._assetExtensions.has(path.extname(file)),
|
|
215
153
|
mainFields: this._config.resolver.resolverMainFields,
|
|
@@ -235,6 +173,7 @@ class DependencyGraph extends EventEmitter {
|
|
|
235
173
|
|
|
236
174
|
_createModuleCache() {
|
|
237
175
|
return new ModuleCache({
|
|
176
|
+
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
|
238
177
|
getClosestPackage: this._getClosestPackage.bind(this),
|
|
239
178
|
});
|
|
240
179
|
}
|
|
@@ -270,8 +209,7 @@ class DependencyGraph extends EventEmitter {
|
|
|
270
209
|
return sha1;
|
|
271
210
|
}
|
|
272
211
|
|
|
273
|
-
|
|
274
|
-
getWatcher(): JestHasteMap {
|
|
212
|
+
getWatcher(): EventEmitter {
|
|
275
213
|
return this._haste;
|
|
276
214
|
}
|
|
277
215
|
|
|
@@ -287,20 +225,21 @@ class DependencyGraph extends EventEmitter {
|
|
|
287
225
|
assumeFlatNodeModules: false,
|
|
288
226
|
},
|
|
289
227
|
): string {
|
|
290
|
-
const
|
|
228
|
+
const isSensitiveToOriginFolder =
|
|
229
|
+
// Resolution is always relative to the origin folder unless we assume a flat node_modules
|
|
230
|
+
!assumeFlatNodeModules ||
|
|
231
|
+
// Path requests are resolved relative to the origin folder
|
|
291
232
|
to.includes('/') ||
|
|
292
233
|
to === '.' ||
|
|
293
234
|
to === '..' ||
|
|
235
|
+
// Preserve standard assumptions under node_modules
|
|
294
236
|
from.includes(path.sep + 'node_modules' + path.sep);
|
|
295
237
|
const mapByDirectory = getOrCreate(
|
|
296
238
|
this._resolutionCache,
|
|
297
|
-
|
|
239
|
+
isSensitiveToOriginFolder ? path.dirname(from) : '',
|
|
298
240
|
);
|
|
299
|
-
|
|
241
|
+
const mapByPlatform = getOrCreate(mapByDirectory, to);
|
|
300
242
|
let modulePath = mapByPlatform.get(platform);
|
|
301
|
-
if (!modulePath) {
|
|
302
|
-
modulePath = this._moduleMap.getModule(to, platform, true);
|
|
303
|
-
}
|
|
304
243
|
|
|
305
244
|
if (!modulePath) {
|
|
306
245
|
try {
|
|
@@ -310,18 +249,6 @@ class DependencyGraph extends EventEmitter {
|
|
|
310
249
|
true,
|
|
311
250
|
platform,
|
|
312
251
|
).path;
|
|
313
|
-
|
|
314
|
-
// If we cannot assume that only one node_modules folder exists in the project,
|
|
315
|
-
// we need to cache packages by directory instead of globally.
|
|
316
|
-
if (
|
|
317
|
-
!assumeFlatNodeModules &&
|
|
318
|
-
modulePath.includes(path.sep + 'node_modules' + path.sep)
|
|
319
|
-
) {
|
|
320
|
-
mapByPlatform = getOrCreate(
|
|
321
|
-
getOrCreate(this._resolutionCache, path.dirname(from)),
|
|
322
|
-
to,
|
|
323
|
-
);
|
|
324
|
-
}
|
|
325
252
|
} catch (error) {
|
|
326
253
|
if (error instanceof DuplicateHasteCandidatesError) {
|
|
327
254
|
throw new AmbiguousModuleResolutionError(from, error);
|
|
@@ -356,7 +283,7 @@ class DependencyGraph extends EventEmitter {
|
|
|
356
283
|
}
|
|
357
284
|
|
|
358
285
|
getDependencies(filePath: string): Array<string> {
|
|
359
|
-
return this._hasteFS.getDependencies(filePath);
|
|
286
|
+
return nullthrows(this._hasteFS.getDependencies(filePath));
|
|
360
287
|
}
|
|
361
288
|
}
|
|
362
289
|
|
package/src/node-haste/Module.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
|
-
const isAbsolutePath = require('absolute-path');
|
|
14
|
-
|
|
15
13
|
import type ModuleCache from './ModuleCache';
|
|
16
14
|
import type Package from './Package';
|
|
17
15
|
|
|
16
|
+
const isAbsolutePath = require('absolute-path');
|
|
17
|
+
|
|
18
18
|
class Module {
|
|
19
19
|
path: string;
|
|
20
20
|
|