webpack 5.101.2 → 5.102.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.
Files changed (323) hide show
  1. package/README.md +21 -26
  2. package/lib/APIPlugin.js +30 -36
  3. package/lib/AsyncDependenciesBlock.js +1 -4
  4. package/lib/BannerPlugin.js +0 -1
  5. package/lib/Cache.js +7 -6
  6. package/lib/CacheFacade.js +0 -1
  7. package/lib/Chunk.js +49 -31
  8. package/lib/ChunkGraph.js +35 -25
  9. package/lib/ChunkGroup.js +8 -10
  10. package/lib/ChunkTemplate.js +1 -1
  11. package/lib/CleanPlugin.js +3 -3
  12. package/lib/CodeGenerationResults.js +2 -1
  13. package/lib/CompatibilityPlugin.js +29 -12
  14. package/lib/Compilation.js +204 -185
  15. package/lib/Compiler.js +36 -35
  16. package/lib/ConcatenationScope.js +6 -1
  17. package/lib/ConditionalInitFragment.js +1 -1
  18. package/lib/ConstPlugin.js +18 -10
  19. package/lib/ContextExclusionPlugin.js +0 -1
  20. package/lib/ContextModule.js +22 -20
  21. package/lib/ContextModuleFactory.js +30 -11
  22. package/lib/ContextReplacementPlugin.js +38 -15
  23. package/lib/DefinePlugin.js +18 -8
  24. package/lib/DelegatedModule.js +7 -11
  25. package/lib/DependenciesBlock.js +0 -2
  26. package/lib/Dependency.js +9 -11
  27. package/lib/DependencyTemplates.js +1 -3
  28. package/lib/DllModule.js +1 -7
  29. package/lib/DllReferencePlugin.js +2 -4
  30. package/lib/DynamicEntryPlugin.js +0 -2
  31. package/lib/EntryOptionPlugin.js +0 -5
  32. package/lib/EnvironmentNotSupportAsyncWarning.js +0 -3
  33. package/lib/EvalDevToolModulePlugin.js +4 -3
  34. package/lib/EvalSourceMapDevToolPlugin.js +3 -4
  35. package/lib/ExportsInfo.js +50 -49
  36. package/lib/ExternalModule.js +84 -52
  37. package/lib/ExternalModuleFactoryPlugin.js +27 -7
  38. package/lib/ExternalsPlugin.js +24 -17
  39. package/lib/FileSystemInfo.js +96 -78
  40. package/lib/FlagDependencyUsagePlugin.js +3 -4
  41. package/lib/Generator.js +2 -13
  42. package/lib/GraphHelpers.js +0 -3
  43. package/lib/HookWebpackError.js +0 -2
  44. package/lib/HotModuleReplacementPlugin.js +22 -24
  45. package/lib/HotUpdateChunk.js +0 -3
  46. package/lib/IgnorePlugin.js +5 -2
  47. package/lib/InitFragment.js +41 -29
  48. package/lib/InvalidDependenciesModuleWarning.js +0 -1
  49. package/lib/LibManifestPlugin.js +4 -6
  50. package/lib/LoaderOptionsPlugin.js +1 -10
  51. package/lib/MainTemplate.js +8 -19
  52. package/lib/Module.js +32 -20
  53. package/lib/ModuleFactory.js +1 -1
  54. package/lib/ModuleFilenameHelpers.js +41 -24
  55. package/lib/ModuleGraph.js +30 -16
  56. package/lib/ModuleInfoHeaderPlugin.js +0 -1
  57. package/lib/ModuleTemplate.js +0 -2
  58. package/lib/ModuleTypeConstants.js +11 -1
  59. package/lib/MultiCompiler.js +23 -15
  60. package/lib/MultiWatching.js +6 -10
  61. package/lib/NodeStuffPlugin.js +2 -10
  62. package/lib/NormalModule.js +145 -88
  63. package/lib/NormalModuleFactory.js +59 -40
  64. package/lib/OptionsApply.js +1 -1
  65. package/lib/Parser.js +1 -1
  66. package/lib/ProgressPlugin.js +6 -10
  67. package/lib/ProvidePlugin.js +5 -7
  68. package/lib/RawModule.js +1 -6
  69. package/lib/RecordIdsPlugin.js +10 -6
  70. package/lib/ResolverFactory.js +0 -2
  71. package/lib/RuntimeGlobals.js +5 -0
  72. package/lib/RuntimeModule.js +1 -3
  73. package/lib/RuntimePlugin.js +26 -22
  74. package/lib/RuntimeTemplate.js +12 -11
  75. package/lib/SourceMapDevToolModuleOptionsPlugin.js +2 -2
  76. package/lib/SourceMapDevToolPlugin.js +6 -11
  77. package/lib/Stats.js +0 -1
  78. package/lib/Template.js +6 -11
  79. package/lib/TemplatedPathPlugin.js +2 -1
  80. package/lib/WatchIgnorePlugin.js +2 -3
  81. package/lib/Watching.js +15 -15
  82. package/lib/WebpackIsIncludedPlugin.js +0 -2
  83. package/lib/WebpackOptionsApply.js +74 -107
  84. package/lib/asset/AssetBytesGenerator.js +166 -0
  85. package/lib/asset/AssetBytesParser.js +37 -0
  86. package/lib/asset/AssetGenerator.js +20 -34
  87. package/lib/asset/AssetModulesPlugin.js +34 -16
  88. package/lib/asset/AssetParser.js +7 -3
  89. package/lib/asset/AssetSourceGenerator.js +1 -1
  90. package/lib/asset/RawDataUrlModule.js +3 -2
  91. package/lib/async-modules/AsyncModuleHelpers.js +6 -4
  92. package/lib/async-modules/AwaitDependenciesInitFragment.js +4 -1
  93. package/lib/buildChunkGraph.js +0 -1
  94. package/lib/cache/MemoryCachePlugin.js +0 -2
  95. package/lib/cache/MemoryWithGcCachePlugin.js +0 -2
  96. package/lib/cache/PackFileCacheStrategy.js +14 -1
  97. package/lib/cache/ResolverCachePlugin.js +9 -15
  98. package/lib/config/defaults.js +155 -21
  99. package/lib/config/normalization.js +18 -3
  100. package/lib/container/ContainerEntryDependency.js +0 -1
  101. package/lib/container/ContainerEntryModule.js +3 -7
  102. package/lib/container/ContainerPlugin.js +1 -2
  103. package/lib/container/ContainerReferencePlugin.js +0 -1
  104. package/lib/container/FallbackDependency.js +2 -1
  105. package/lib/container/FallbackModule.js +6 -7
  106. package/lib/container/ModuleFederationPlugin.js +0 -1
  107. package/lib/container/RemoteModule.js +8 -8
  108. package/lib/container/RemoteRuntimeModule.js +2 -2
  109. package/lib/css/CssGenerator.js +3 -6
  110. package/lib/css/CssLoadingRuntimeModule.js +6 -9
  111. package/lib/css/CssModulesPlugin.js +11 -13
  112. package/lib/css/CssParser.js +3 -3
  113. package/lib/css/walkCssTokens.js +1 -1
  114. package/lib/debug/ProfilingPlugin.js +35 -8
  115. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +12 -17
  116. package/lib/dependencies/AMDPlugin.js +2 -2
  117. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +1 -2
  118. package/lib/dependencies/CachedConstDependency.js +0 -4
  119. package/lib/dependencies/CommonJsExportRequireDependency.js +20 -14
  120. package/lib/dependencies/CommonJsExportsDependency.js +2 -1
  121. package/lib/dependencies/CommonJsExportsParserPlugin.js +20 -5
  122. package/lib/dependencies/CommonJsFullRequireDependency.js +6 -4
  123. package/lib/dependencies/CommonJsImportsParserPlugin.js +16 -7
  124. package/lib/dependencies/CommonJsRequireContextDependency.js +1 -1
  125. package/lib/dependencies/CommonJsSelfReferenceDependency.js +4 -4
  126. package/lib/dependencies/ConstDependency.js +2 -2
  127. package/lib/dependencies/ContextDependency.js +9 -4
  128. package/lib/dependencies/ContextDependencyHelpers.js +2 -2
  129. package/lib/dependencies/ContextDependencyTemplateAsId.js +9 -9
  130. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +9 -9
  131. package/lib/dependencies/ContextElementDependency.js +22 -11
  132. package/lib/dependencies/CssIcssImportDependency.js +0 -2
  133. package/lib/dependencies/CssIcssSymbolDependency.js +2 -2
  134. package/lib/dependencies/CssImportDependency.js +0 -8
  135. package/lib/dependencies/CssLocalIdentifierDependency.js +3 -4
  136. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +2 -2
  137. package/lib/dependencies/CssUrlDependency.js +0 -6
  138. package/lib/dependencies/ExportsInfoDependency.js +7 -9
  139. package/lib/dependencies/ExternalModuleDependency.js +0 -3
  140. package/lib/dependencies/ExternalModuleInitFragment.js +1 -1
  141. package/lib/dependencies/HarmonyAcceptDependency.js +1 -1
  142. package/lib/dependencies/HarmonyAcceptImportDependency.js +0 -4
  143. package/lib/dependencies/HarmonyCompatibilityDependency.js +0 -1
  144. package/lib/dependencies/HarmonyDetectionParserPlugin.js +0 -14
  145. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +3 -3
  146. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +4 -1
  147. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +29 -35
  148. package/lib/dependencies/HarmonyImportDependency.js +30 -14
  149. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +38 -24
  150. package/lib/dependencies/HarmonyImportSideEffectDependency.js +0 -4
  151. package/lib/dependencies/HarmonyImportSpecifierDependency.js +46 -31
  152. package/lib/dependencies/HarmonyModulesPlugin.js +3 -3
  153. package/lib/dependencies/ImportDependency.js +18 -6
  154. package/lib/dependencies/ImportEagerDependency.js +2 -3
  155. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +8 -5
  156. package/lib/dependencies/ImportMetaContextPlugin.js +0 -1
  157. package/lib/dependencies/ImportMetaPlugin.js +8 -1
  158. package/lib/dependencies/ImportParserPlugin.js +294 -45
  159. package/lib/dependencies/ImportWeakDependency.js +2 -3
  160. package/lib/dependencies/JsonExportsDependency.js +0 -1
  161. package/lib/dependencies/LoaderDependency.js +0 -3
  162. package/lib/dependencies/LoaderImportDependency.js +0 -3
  163. package/lib/dependencies/LoaderPlugin.js +11 -5
  164. package/lib/dependencies/ModuleDecoratorDependency.js +2 -4
  165. package/lib/dependencies/ModuleDependency.js +3 -9
  166. package/lib/dependencies/NullDependency.js +2 -0
  167. package/lib/dependencies/ProvidedDependency.js +6 -8
  168. package/lib/dependencies/PureExpressionDependency.js +0 -1
  169. package/lib/dependencies/RequireEnsureDependenciesBlock.js +0 -1
  170. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +1 -2
  171. package/lib/dependencies/RequireIncludeDependency.js +2 -2
  172. package/lib/dependencies/RequireResolveDependency.js +2 -2
  173. package/lib/dependencies/RuntimeRequirementsDependency.js +2 -3
  174. package/lib/dependencies/StaticExportsDependency.js +3 -5
  175. package/lib/dependencies/URLDependency.js +2 -7
  176. package/lib/dependencies/URLPlugin.js +1 -2
  177. package/lib/dependencies/WebAssemblyExportImportedDependency.js +2 -2
  178. package/lib/dependencies/WebAssemblyImportDependency.js +2 -2
  179. package/lib/dependencies/WebpackIsIncludedDependency.js +2 -3
  180. package/lib/dependencies/WorkerDependency.js +2 -3
  181. package/lib/dependencies/WorkerPlugin.js +3 -9
  182. package/lib/dependencies/processExportInfo.js +2 -3
  183. package/lib/esm/ModuleChunkFormatPlugin.js +0 -3
  184. package/lib/esm/ModuleChunkLoadingPlugin.js +2 -1
  185. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +7 -7
  186. package/lib/hmr/LazyCompilationPlugin.js +6 -4
  187. package/lib/hmr/lazyCompilationBackend.js +13 -10
  188. package/lib/ids/DeterministicChunkIdsPlugin.js +0 -1
  189. package/lib/ids/NamedChunkIdsPlugin.js +1 -6
  190. package/lib/ids/NamedModuleIdsPlugin.js +1 -5
  191. package/lib/ids/NaturalChunkIdsPlugin.js +0 -1
  192. package/lib/ids/NaturalModuleIdsPlugin.js +0 -1
  193. package/lib/ids/OccurrenceChunkIdsPlugin.js +0 -1
  194. package/lib/ids/OccurrenceModuleIdsPlugin.js +0 -1
  195. package/lib/ids/SyncModuleIdsPlugin.js +4 -3
  196. package/lib/index.js +8 -7
  197. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +4 -1
  198. package/lib/javascript/BasicEvaluatedExpression.js +13 -6
  199. package/lib/javascript/ChunkFormatHelpers.js +1 -1
  200. package/lib/javascript/CommonJsChunkFormatPlugin.js +0 -1
  201. package/lib/javascript/JavascriptGenerator.js +2 -3
  202. package/lib/javascript/JavascriptModulesPlugin.js +44 -21
  203. package/lib/javascript/JavascriptParser.js +159 -93
  204. package/lib/javascript/JavascriptParserHelpers.js +2 -2
  205. package/lib/javascript/StartupHelpers.js +2 -4
  206. package/lib/json/JsonData.js +1 -1
  207. package/lib/json/JsonGenerator.js +4 -5
  208. package/lib/json/JsonModulesPlugin.js +0 -3
  209. package/lib/json/JsonParser.js +4 -2
  210. package/lib/library/AbstractLibraryPlugin.js +2 -2
  211. package/lib/library/AmdLibraryPlugin.js +0 -1
  212. package/lib/library/AssignLibraryPlugin.js +23 -12
  213. package/lib/library/EnableLibraryPlugin.js +7 -11
  214. package/lib/library/ExportPropertyLibraryPlugin.js +8 -20
  215. package/lib/library/JsonpLibraryPlugin.js +5 -2
  216. package/lib/library/ModuleLibraryPlugin.js +88 -43
  217. package/lib/library/SystemLibraryPlugin.js +0 -1
  218. package/lib/library/UmdLibraryPlugin.js +12 -18
  219. package/lib/logging/Logger.js +12 -10
  220. package/lib/logging/createConsoleLogger.js +15 -14
  221. package/lib/logging/truncateArgs.js +1 -1
  222. package/lib/node/CommonJsChunkLoadingPlugin.js +2 -1
  223. package/lib/node/NodeWatchFileSystem.js +4 -4
  224. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +2 -2
  225. package/lib/node/RequireChunkLoadingRuntimeModule.js +5 -2
  226. package/lib/node/nodeConsole.js +2 -2
  227. package/lib/optimize/AggressiveSplittingPlugin.js +2 -0
  228. package/lib/optimize/ConcatenatedModule.js +142 -100
  229. package/lib/optimize/InnerGraph.js +17 -11
  230. package/lib/optimize/InnerGraphPlugin.js +0 -3
  231. package/lib/optimize/ModuleConcatenationPlugin.js +3 -4
  232. package/lib/optimize/RuntimeChunkPlugin.js +0 -1
  233. package/lib/optimize/SideEffectsFlagPlugin.js +3 -10
  234. package/lib/optimize/SplitChunksPlugin.js +46 -40
  235. package/lib/performance/SizeLimitsPlugin.js +2 -1
  236. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +5 -7
  237. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +0 -2
  238. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +0 -1
  239. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +2 -2
  240. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +2 -2
  241. package/lib/rules/BasicMatcherRulePlugin.js +0 -2
  242. package/lib/rules/ObjectMatcherRulePlugin.js +0 -1
  243. package/lib/rules/RuleSetCompiler.js +8 -6
  244. package/lib/runtime/BaseUriRuntimeModule.js +2 -2
  245. package/lib/runtime/CompatRuntimeModule.js +0 -1
  246. package/lib/runtime/GetChunkFilenameRuntimeModule.js +8 -9
  247. package/lib/runtime/LoadScriptRuntimeModule.js +0 -2
  248. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +1 -1
  249. package/lib/runtime/PublicPathRuntimeModule.js +2 -2
  250. package/lib/runtime/StartupEntrypointRuntimeModule.js +0 -1
  251. package/lib/runtime/SystemContextRuntimeModule.js +0 -2
  252. package/lib/runtime/ToBinaryRuntimeModule.js +64 -0
  253. package/lib/schemes/DataUriPlugin.js +2 -28
  254. package/lib/schemes/FileUriPlugin.js +5 -2
  255. package/lib/schemes/HttpUriPlugin.js +4 -2
  256. package/lib/schemes/VirtualUrlPlugin.js +11 -11
  257. package/lib/serialization/NullPrototypeObjectSerializer.js +5 -3
  258. package/lib/serialization/ObjectMiddleware.js +30 -19
  259. package/lib/serialization/SerializerMiddleware.js +1 -3
  260. package/lib/serialization/types.js +1 -1
  261. package/lib/sharing/ConsumeSharedModule.js +3 -5
  262. package/lib/sharing/ConsumeSharedPlugin.js +2 -4
  263. package/lib/sharing/ConsumeSharedRuntimeModule.js +9 -6
  264. package/lib/sharing/ProvideSharedModule.js +3 -7
  265. package/lib/sharing/SharePlugin.js +0 -2
  266. package/lib/sharing/ShareRuntimeModule.js +4 -1
  267. package/lib/sharing/resolveMatchedConfigs.js +14 -6
  268. package/lib/sharing/utils.js +0 -6
  269. package/lib/stats/DefaultStatsFactoryPlugin.js +178 -94
  270. package/lib/stats/DefaultStatsPresetPlugin.js +15 -9
  271. package/lib/stats/DefaultStatsPrinterPlugin.js +77 -113
  272. package/lib/stats/StatsFactory.js +14 -11
  273. package/lib/url/URLParserPlugin.js +2 -4
  274. package/lib/util/ArrayHelpers.js +4 -4
  275. package/lib/util/AsyncQueue.js +1 -0
  276. package/lib/util/LazySet.js +2 -2
  277. package/lib/util/StackedCacheMap.js +0 -2
  278. package/lib/util/TupleSet.js +9 -4
  279. package/lib/util/URLAbsoluteSpecifier.js +0 -1
  280. package/lib/util/WeakTupleMap.js +1 -1
  281. package/lib/util/chainedImports.js +3 -1
  282. package/lib/util/cleverMerge.js +15 -18
  283. package/lib/util/comparators.js +2 -4
  284. package/lib/util/compileBooleanMatcher.js +11 -9
  285. package/lib/util/concatenate.js +1 -2
  286. package/lib/util/create-schema-validation.js +0 -1
  287. package/lib/util/dataURL.js +39 -0
  288. package/lib/util/deprecation.js +29 -31
  289. package/lib/util/deterministicGrouping.js +34 -30
  290. package/lib/util/extractSourceMap.js +319 -0
  291. package/lib/util/findGraphRoots.js +15 -5
  292. package/lib/util/fs.js +29 -8
  293. package/lib/util/semver.js +9 -8
  294. package/lib/util/smartGrouping.js +41 -26
  295. package/lib/util/traverseDestructuringAssignmentProperties.js +45 -0
  296. package/lib/wasm/EnableWasmLoadingPlugin.js +3 -2
  297. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +5 -1
  298. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +2 -13
  299. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +2 -9
  300. package/lib/wasm-async/AsyncWebAssemblyParser.js +2 -1
  301. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +6 -4
  302. package/lib/wasm-sync/WebAssemblyGenerator.js +1 -3
  303. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +1 -4
  304. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +2 -7
  305. package/lib/wasm-sync/WebAssemblyParser.js +1 -4
  306. package/lib/web/JsonpChunkLoadingPlugin.js +2 -1
  307. package/lib/web/JsonpChunkLoadingRuntimeModule.js +1 -1
  308. package/lib/web/JsonpTemplatePlugin.js +0 -1
  309. package/lib/webpack.js +21 -8
  310. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +2 -1
  311. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +1 -1
  312. package/package.json +13 -13
  313. package/schemas/WebpackOptions.check.js +1 -1
  314. package/schemas/WebpackOptions.json +77 -93
  315. package/schemas/plugins/BannerPlugin.check.js +1 -1
  316. package/schemas/plugins/BannerPlugin.json +4 -0
  317. package/schemas/plugins/IgnorePlugin.json +1 -1
  318. package/schemas/plugins/ProgressPlugin.json +1 -1
  319. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  320. package/schemas/plugins/SourceMapDevToolPlugin.json +5 -1
  321. package/schemas/plugins/schemes/VirtualUrlPlugin.json +3 -3
  322. package/types.d.ts +1140 -505
  323. package/SECURITY.md +0 -9
@@ -0,0 +1,319 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Natsu @xiaoxiaojx
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const path = require("path");
9
+ const urlUtils = require("url");
10
+ const { isAbsolute, join } = require("./fs");
11
+
12
+ /** @typedef {import("./fs").InputFileSystem} InputFileSystem */
13
+
14
+ /**
15
+ * @typedef {(input: string | Buffer<ArrayBufferLike>, resourcePath: string, fs: InputFileSystem) => Promise<{source: string | Buffer<ArrayBufferLike>, sourceMap: string | RawSourceMap | undefined, fileDependencies: string[]}>} SourceMapExtractorFunction
16
+ */
17
+
18
+ /** @typedef {import("webpack-sources").RawSourceMap} RawSourceMap */
19
+
20
+ /**
21
+ * @typedef {(resourcePath: string) => Promise<string | Buffer<ArrayBufferLike>>} ReadResource
22
+ */
23
+
24
+ /**
25
+ * @typedef {object} SourceMappingURL
26
+ * @property {string} sourceMappingURL
27
+ * @property {string} replacementString
28
+ */
29
+
30
+ // Matches only the last occurrence of sourceMappingURL
31
+ const innerRegex = /\s*[#@]\s*sourceMappingURL\s*=\s*([^\s'"]*)\s*/;
32
+
33
+ const validProtocolPattern = /^[a-z][a-z0-9+.-]*:/i;
34
+
35
+ const sourceMappingURLRegex = new RegExp(
36
+ "(?:" +
37
+ "/\\*" +
38
+ "(?:\\s*\r?\n(?://)?)?" +
39
+ `(?:${innerRegex.source})` +
40
+ "\\s*" +
41
+ "\\*/" +
42
+ "|" +
43
+ `//(?:${innerRegex.source})` +
44
+ ")" +
45
+ "\\s*"
46
+ );
47
+
48
+ /**
49
+ * Extract source mapping URL from code comments
50
+ * @param {string} code source code content
51
+ * @returns {SourceMappingURL} source mapping information
52
+ */
53
+ function getSourceMappingURL(code) {
54
+ const lines = code.split(/^/m);
55
+ let match;
56
+
57
+ for (let i = lines.length - 1; i >= 0; i--) {
58
+ match = lines[i].match(sourceMappingURLRegex);
59
+ if (match) {
60
+ break;
61
+ }
62
+ }
63
+
64
+ const sourceMappingURL = match ? match[1] || match[2] || "" : "";
65
+
66
+ return {
67
+ sourceMappingURL: sourceMappingURL
68
+ ? decodeURI(sourceMappingURL)
69
+ : sourceMappingURL,
70
+ replacementString: match ? match[0] : ""
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Get absolute path for source file
76
+ * @param {string} context context directory
77
+ * @param {string} request file request
78
+ * @param {string} sourceRoot source root directory
79
+ * @returns {string} absolute path
80
+ */
81
+ function getAbsolutePath(context, request, sourceRoot) {
82
+ if (sourceRoot) {
83
+ if (isAbsolute(sourceRoot)) {
84
+ return join(undefined, sourceRoot, request);
85
+ }
86
+
87
+ return join(undefined, join(undefined, context, sourceRoot), request);
88
+ }
89
+
90
+ return join(undefined, context, request);
91
+ }
92
+
93
+ /**
94
+ * Check if value is a URL
95
+ * @param {string} value string to check
96
+ * @returns {boolean} true if value is a URL
97
+ */
98
+ function isURL(value) {
99
+ return validProtocolPattern.test(value) && !path.win32.isAbsolute(value);
100
+ }
101
+
102
+ /**
103
+ * Fetch from multiple possible file paths
104
+ * @param {ReadResource} readResource read resource function
105
+ * @param {string[]} possibleRequests array of possible file paths
106
+ * @param {string} errorsAccumulator accumulated error messages
107
+ * @returns {Promise<{path: string, data?: string}>} source content promise
108
+ */
109
+ async function fetchPathsFromURL(
110
+ readResource,
111
+ possibleRequests,
112
+ errorsAccumulator = ""
113
+ ) {
114
+ let result;
115
+
116
+ try {
117
+ result = await readResource(possibleRequests[0]);
118
+ } catch (error) {
119
+ errorsAccumulator += `${/** @type {Error} */ (error).message}\n\n`;
120
+
121
+ const [, ...tailPossibleRequests] = possibleRequests;
122
+
123
+ if (tailPossibleRequests.length === 0) {
124
+ /** @type {Error} */ (error).message = errorsAccumulator;
125
+
126
+ throw error;
127
+ }
128
+
129
+ return fetchPathsFromURL(
130
+ readResource,
131
+ tailPossibleRequests,
132
+ errorsAccumulator
133
+ );
134
+ }
135
+
136
+ return {
137
+ path: possibleRequests[0],
138
+ data: result.toString("utf8")
139
+ };
140
+ }
141
+
142
+ /**
143
+ * Fetch source content from URL
144
+ * @param {ReadResource} readResource The read resource function
145
+ * @param {string} context context directory
146
+ * @param {string} url source URL
147
+ * @param {string=} sourceRoot source root directory
148
+ * @param {boolean=} skipReading whether to skip reading file content
149
+ * @returns {Promise<{sourceURL: string, sourceContent?: string | Buffer<ArrayBufferLike>}>} source content promise
150
+ */
151
+ async function fetchFromURL(
152
+ readResource,
153
+ context,
154
+ url,
155
+ sourceRoot,
156
+ skipReading = false
157
+ ) {
158
+ // 1. It's an absolute url and it is not `windows` path like `C:\dir\file`
159
+ if (isURL(url)) {
160
+ // eslint-disable-next-line n/no-deprecated-api
161
+ const { protocol } = urlUtils.parse(url);
162
+ if (protocol === "data:") {
163
+ const sourceContent = skipReading ? "" : await readResource(url);
164
+
165
+ return { sourceURL: "", sourceContent };
166
+ }
167
+
168
+ if (protocol === "file:") {
169
+ const pathFromURL = urlUtils.fileURLToPath(url);
170
+ const sourceURL = path.normalize(pathFromURL);
171
+ const sourceContent = skipReading ? "" : await readResource(sourceURL);
172
+
173
+ return { sourceURL, sourceContent };
174
+ }
175
+
176
+ const sourceContent = skipReading ? "" : await readResource(url);
177
+ return { sourceURL: url, sourceContent };
178
+ }
179
+
180
+ // 3. Absolute path
181
+ if (isAbsolute(url)) {
182
+ let sourceURL = path.normalize(url);
183
+
184
+ let sourceContent;
185
+
186
+ if (!skipReading) {
187
+ const possibleRequests = [sourceURL];
188
+
189
+ if (url.startsWith("/")) {
190
+ possibleRequests.push(
191
+ getAbsolutePath(context, sourceURL.slice(1), sourceRoot || "")
192
+ );
193
+ }
194
+
195
+ const result = await fetchPathsFromURL(readResource, possibleRequests);
196
+
197
+ sourceURL = result.path;
198
+ sourceContent = result.data;
199
+ }
200
+
201
+ return { sourceURL, sourceContent };
202
+ }
203
+
204
+ // 4. Relative path
205
+ const sourceURL = getAbsolutePath(context, url, sourceRoot || "");
206
+ let sourceContent;
207
+
208
+ if (!skipReading) {
209
+ sourceContent = await readResource(sourceURL);
210
+ }
211
+
212
+ return { sourceURL, sourceContent };
213
+ }
214
+
215
+ /**
216
+ * Extract source map from code content
217
+ * @param {string | Buffer<ArrayBufferLike>} stringOrBuffer The input code content as string or buffer
218
+ * @param {string} resourcePath The path to the resource file
219
+ * @param {ReadResource} readResource The read resource function
220
+ * @returns {Promise<{source: string | Buffer<ArrayBufferLike>, sourceMap: string | RawSourceMap | undefined}>} Promise resolving to extracted source map information
221
+ */
222
+ async function extractSourceMap(stringOrBuffer, resourcePath, readResource) {
223
+ const input =
224
+ typeof stringOrBuffer === "string"
225
+ ? stringOrBuffer
226
+ : stringOrBuffer.toString("utf8");
227
+ const inputSourceMap = undefined;
228
+ const output = {
229
+ source: stringOrBuffer,
230
+ sourceMap: inputSourceMap
231
+ };
232
+ const { sourceMappingURL, replacementString } = getSourceMappingURL(input);
233
+
234
+ if (!sourceMappingURL) {
235
+ return output;
236
+ }
237
+
238
+ const baseContext = path.dirname(resourcePath);
239
+
240
+ const { sourceURL, sourceContent } = await fetchFromURL(
241
+ readResource,
242
+ baseContext,
243
+ sourceMappingURL
244
+ );
245
+
246
+ if (!sourceContent) {
247
+ return output;
248
+ }
249
+
250
+ /** @type {RawSourceMap} */
251
+ const map = JSON.parse(
252
+ sourceContent.toString("utf8").replace(/^\)\]\}'/, "")
253
+ );
254
+
255
+ const context = sourceURL ? path.dirname(sourceURL) : baseContext;
256
+
257
+ const resolvedSources = await Promise.all(
258
+ map.sources.map(
259
+ async (/** @type {string} */ source, /** @type {number} */ i) => {
260
+ const originalSourceContent =
261
+ map.sourcesContent &&
262
+ typeof map.sourcesContent[i] !== "undefined" &&
263
+ map.sourcesContent[i] !== null
264
+ ? map.sourcesContent[i]
265
+ : undefined;
266
+ const skipReading = typeof originalSourceContent !== "undefined";
267
+ // We do not skipReading here, because we need absolute paths in sources.
268
+ // This is necessary so that for sourceMaps with the same file structure in sources, name collisions do not occur.
269
+ // https://github.com/webpack-contrib/source-map-loader/issues/51
270
+ let { sourceURL, sourceContent } = await fetchFromURL(
271
+ readResource,
272
+ context,
273
+ source,
274
+ map.sourceRoot,
275
+ skipReading
276
+ );
277
+
278
+ if (skipReading) {
279
+ sourceContent = originalSourceContent;
280
+ }
281
+
282
+ // Return original value of `source` when error happens
283
+ return { sourceURL, sourceContent };
284
+ }
285
+ )
286
+ );
287
+
288
+ /** @type {RawSourceMap} */
289
+ const newMap = { ...map };
290
+
291
+ newMap.sources = [];
292
+ newMap.sourcesContent = [];
293
+
294
+ delete newMap.sourceRoot;
295
+
296
+ for (const source of resolvedSources) {
297
+ const { sourceURL, sourceContent } = source;
298
+
299
+ newMap.sources.push(sourceURL || "");
300
+ newMap.sourcesContent.push(
301
+ sourceContent ? sourceContent.toString("utf8") : ""
302
+ );
303
+ }
304
+
305
+ const sourcesContentIsEmpty =
306
+ newMap.sourcesContent.filter(Boolean).length === 0;
307
+
308
+ if (sourcesContentIsEmpty) {
309
+ delete newMap.sourcesContent;
310
+ }
311
+
312
+ return {
313
+ source: input.replace(replacementString, ""),
314
+ sourceMap: /** @type {RawSourceMap} */ (newMap)
315
+ };
316
+ }
317
+
318
+ module.exports = extractSourceMap;
319
+ module.exports.getSourceMappingURL = getSourceMappingURL;
@@ -11,6 +11,16 @@ const DONE_MARKER = 2;
11
11
  const DONE_MAYBE_ROOT_CYCLE_MARKER = 3;
12
12
  const DONE_AND_ROOT_MARKER = 4;
13
13
 
14
+ /**
15
+ * @template T
16
+ * @typedef {Set<Node<T>>} Nodes
17
+ */
18
+
19
+ /**
20
+ * @template T
21
+ * @typedef {Set<Cycle<T>>} Cycles
22
+ */
23
+
14
24
  /**
15
25
  * @template T
16
26
  */
@@ -20,7 +30,7 @@ class Node {
20
30
  */
21
31
  constructor(item) {
22
32
  this.item = item;
23
- /** @type {Set<Node<T>>} */
33
+ /** @type {Nodes<T>} */
24
34
  this.dependencies = new Set();
25
35
  this.marker = NO_MARKER;
26
36
  /** @type {Cycle<T> | undefined} */
@@ -34,7 +44,7 @@ class Node {
34
44
  */
35
45
  class Cycle {
36
46
  constructor() {
37
- /** @type {Set<Node<T>>} */
47
+ /** @type {Nodes<T>} */
38
48
  this.nodes = new Set();
39
49
  }
40
50
  }
@@ -75,13 +85,13 @@ module.exports = (items, getDependencies) => {
75
85
 
76
86
  // Set of current root modules
77
87
  // items will be removed if a new reference to it has been found
78
- /** @type {Set<Node<T>>} */
88
+ /** @type {Nodes<T>} */
79
89
  const roots = new Set();
80
90
 
81
91
  // Set of current cycles without references to it
82
92
  // cycles will be removed if a new reference to it has been found
83
93
  // that is not part of the cycle
84
- /** @type {Set<Cycle<T>>} */
94
+ /** @type {Cycles<T>} */
85
95
  const rootCycles = new Set();
86
96
 
87
97
  // For all non-marked nodes
@@ -201,7 +211,7 @@ module.exports = (items, getDependencies) => {
201
211
  // inside of the cycle
202
212
  for (const cycle of rootCycles) {
203
213
  let max = 0;
204
- /** @type {Set<Node<T>>} */
214
+ /** @type {Nodes<T>} */
205
215
  const cycleRoots = new Set();
206
216
  const nodes = cycle.nodes;
207
217
  for (const node of nodes) {
package/lib/util/fs.js CHANGED
@@ -85,17 +85,17 @@ const path = require("path");
85
85
 
86
86
  /** @typedef {Map<string, FileSystemInfoEntry | "ignore">} TimeInfoEntries */
87
87
 
88
+ /** @typedef {Set<string>} Changes */
89
+ /** @typedef {Set<string>} Removals */
90
+
88
91
  /**
89
92
  * @typedef {object} WatcherInfo
90
- * @property {Set<string> | null} changes get current aggregated changes that have not yet send to callback
91
- * @property {Set<string> | null} removals get current aggregated removals that have not yet send to callback
93
+ * @property {Changes | null} changes get current aggregated changes that have not yet send to callback
94
+ * @property {Removals | null} removals get current aggregated removals that have not yet send to callback
92
95
  * @property {TimeInfoEntries} fileTimeInfoEntries get info about files
93
96
  * @property {TimeInfoEntries} contextTimeInfoEntries get info about directories
94
97
  */
95
98
 
96
- /** @typedef {Set<string>} Changes */
97
- /** @typedef {Set<string>} Removals */
98
-
99
99
  // TODO webpack 6 deprecate missing getInfo
100
100
  /**
101
101
  * @typedef {object} Watcher
@@ -345,16 +345,29 @@ const path = require("path");
345
345
  * @typedef {(pathLike: PathLike, callback: NoParamCallback) => void} Unlink
346
346
  */
347
347
 
348
+ /**
349
+ * @typedef {FSImplementation & { read: (...args: EXPECTED_ANY[]) => EXPECTED_ANY }} CreateReadStreamFSImplementation
350
+ */
351
+
352
+ /**
353
+ * @typedef {StreamOptions & { fs?: CreateReadStreamFSImplementation | null | undefined, end?: number | undefined }} ReadStreamOptions
354
+ */
355
+
356
+ /**
357
+ * @typedef {(path: PathLike, options?: BufferEncoding | ReadStreamOptions) => NodeJS.ReadableStream} CreateReadStream
358
+ */
359
+
348
360
  /**
349
361
  * @typedef {object} OutputFileSystem
350
- * @property {WriteFile} writeFile
351
362
  * @property {Mkdir} mkdir
352
363
  * @property {Readdir=} readdir
353
364
  * @property {Rmdir=} rmdir
365
+ * @property {WriteFile} writeFile
354
366
  * @property {Unlink=} unlink
355
367
  * @property {Stat} stat
356
368
  * @property {LStat=} lstat
357
369
  * @property {ReadFile} readFile
370
+ * @property {CreateReadStream=} createReadStream
358
371
  * @property {((path1: string, path2: string) => string)=} join
359
372
  * @property {((from: string, to: string) => string)=} relative
360
373
  * @property {((dirname: string) => string)=} dirname
@@ -396,7 +409,7 @@ const path = require("path");
396
409
  */
397
410
 
398
411
  /**
399
- * @typedef {StreamOptions & { fs?: CreateWriteStreamFSImplementation | null | undefined }} WriteStreamOptions
412
+ * @typedef {StreamOptions & { fs?: CreateWriteStreamFSImplementation | null | undefined, flush?: boolean | undefined }} WriteStreamOptions
400
413
  */
401
414
 
402
415
  /**
@@ -461,7 +474,7 @@ const path = require("path");
461
474
  /** @typedef {InputFileSystem & OutputFileSystem & IntermediateFileSystemExtras} IntermediateFileSystem */
462
475
 
463
476
  /**
464
- * @param {InputFileSystem|OutputFileSystem|undefined} fs a file system
477
+ * @param {InputFileSystem | OutputFileSystem|undefined} fs a file system
465
478
  * @param {string} rootPath the root path
466
479
  * @param {string} targetPath the target path
467
480
  * @returns {string} location of targetPath relative to rootPath
@@ -649,7 +662,15 @@ const lstatReadlinkAbsolute = (fs, p, callback) => {
649
662
  doReadLink();
650
663
  };
651
664
 
665
+ /**
666
+ * @param {string} pathname a path
667
+ * @returns {boolean} is absolute
668
+ */
669
+ const isAbsolute = (pathname) =>
670
+ path.posix.isAbsolute(pathname) || path.win32.isAbsolute(pathname);
671
+
652
672
  module.exports.dirname = dirname;
673
+ module.exports.isAbsolute = isAbsolute;
653
674
  module.exports.join = join;
654
675
  module.exports.lstatReadlinkAbsolute = lstatReadlinkAbsolute;
655
676
  module.exports.mkdirp = mkdirp;
@@ -6,7 +6,8 @@
6
6
  "use strict";
7
7
 
8
8
  /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
9
- /** @typedef {string | number | undefined} SemVerRangeItem */
9
+ /** @typedef {string | number} VersionValue */
10
+ /** @typedef {VersionValue | undefined} SemVerRangeItem */
10
11
  /** @typedef {(SemVerRangeItem | SemVerRangeItem[])[]} SemVerRange */
11
12
 
12
13
  /**
@@ -16,12 +17,12 @@
16
17
  const parseVersion = (str) => {
17
18
  /**
18
19
  * @param {str} str str
19
- * @returns {(string | number)[]} result
20
+ * @returns {VersionValue[]} result
20
21
  */
21
22
  var splitAndConvert = function (str) {
22
23
  return str.split(".").map(function (item) {
23
24
  // eslint-disable-next-line eqeqeq
24
- return +item == /** @type {EXPECTED_ANY} */ (item) ? +item : item;
25
+ return +item == /** @type {string | number} */ (item) ? +item : item;
25
26
  });
26
27
  };
27
28
 
@@ -29,7 +30,7 @@ const parseVersion = (str) => {
29
30
  /** @type {RegExpExecArray} */
30
31
  (/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(str));
31
32
 
32
- /** @type {(string | number | undefined | [])[]} */
33
+ /** @type {(VersionValue | undefined | [])[]} */
33
34
  var ver = match[1] ? splitAndConvert(match[1]) : [];
34
35
 
35
36
  if (match[2]) {
@@ -103,7 +104,7 @@ module.exports.versionLt = versionLt;
103
104
  module.exports.parseRange = (str) => {
104
105
  /**
105
106
  * @param {string} str str
106
- * @returns {(string | number)[]} result
107
+ * @returns {VersionValue[]} result
107
108
  */
108
109
  const splitAndConvert = (str) => {
109
110
  return str
@@ -429,7 +430,7 @@ const satisfy = (range, version) => {
429
430
  /** @type {"s" | "n" | "u" | ""} */
430
431
  (j < range.length ? (typeof range[j])[0] : "");
431
432
 
432
- /** @type {number | string | undefined} */
433
+ /** @type {VersionValue | undefined} */
433
434
  var versionValue;
434
435
  /** @type {"n" | "s" | "u" | "o" | undefined} */
435
436
  var versionType;
@@ -470,8 +471,8 @@ const satisfy = (range, version) => {
470
471
  // Handles "cmp" cases
471
472
  if (
472
473
  negated
473
- ? versionValue > /** @type {(number | string)[]} */ (range)[j]
474
- : versionValue < /** @type {(number | string)[]} */ (range)[j]
474
+ ? versionValue > /** @type {VersionValue[]} */ (range)[j]
475
+ : versionValue < /** @type {VersionValue[]} */ (range)[j]
475
476
  ) {
476
477
  return false;
477
478
  }
@@ -13,42 +13,53 @@
13
13
  */
14
14
 
15
15
  /**
16
- * @template T
17
- * @template R
16
+ * @template I
17
+ * @template G
18
18
  * @typedef {object} GroupConfig
19
- * @property {(item: T) => string[] | undefined} getKeys
20
- * @property {(key: string, children: (R | T)[], items: T[]) => R} createGroup
21
- * @property {(name: string, items: T[]) => GroupOptions=} getOptions
19
+ * @property {(item: I) => string[] | undefined} getKeys
20
+ * @property {(name: string, items: I[]) => GroupOptions=} getOptions
21
+ * @property {(key: string, children: I[], items: I[]) => G} createGroup
22
22
  */
23
23
 
24
24
  /**
25
- * @template T
26
- * @template R
25
+ * @template I
26
+ * @template G
27
+ * @typedef {{ config: GroupConfig<I, G>, name: string, alreadyGrouped: boolean, items: Items<I, G> | undefined }} Group
28
+ */
29
+
30
+ /**
31
+ * @template I, G
32
+ * @typedef {Set<Group<I, G>>} Groups
33
+ */
34
+
35
+ /**
36
+ * @template I
37
+ * @template G
27
38
  * @typedef {object} ItemWithGroups
28
- * @property {T} item
29
- * @property {Set<Group<T, R>>} groups
39
+ * @property {I} item
40
+ * @property {Groups<I, G>} groups
30
41
  */
31
42
 
32
43
  /**
33
- * @template T
34
- * @template R
35
- * @typedef {{ config: GroupConfig<T, R>, name: string, alreadyGrouped: boolean, items: Set<ItemWithGroups<T, R>> | undefined }} Group
44
+ * @template T, G
45
+ * @typedef {Set<ItemWithGroups<T, G>>} Items
36
46
  */
37
47
 
38
48
  /**
39
- * @template T
49
+ * @template I
50
+ * @template G
40
51
  * @template R
41
- * @param {T[]} items the list of items
42
- * @param {GroupConfig<T, R>[]} groupConfigs configuration
43
- * @returns {(R | T)[]} grouped items
52
+ * @param {I[]} items the list of items
53
+ * @param {GroupConfig<I, G>[]} groupConfigs configuration
54
+ * @returns {(I | G)[]} grouped items
44
55
  */
45
56
  const smartGrouping = (items, groupConfigs) => {
46
- /** @type {Set<ItemWithGroups<T, R>>} */
57
+ /** @type {Items<I, G>} */
47
58
  const itemsWithGroups = new Set();
48
- /** @type {Map<string, Group<T, R>>} */
59
+ /** @type {Map<string, Group<I, G>>} */
49
60
  const allGroups = new Map();
50
61
  for (const item of items) {
51
- /** @type {Set<Group<T, R>>} */
62
+ /** @type {Groups<I, G>} */
52
63
  const groups = new Set();
53
64
  for (let i = 0; i < groupConfigs.length; i++) {
54
65
  const groupConfig = groupConfigs[i];
@@ -77,9 +88,10 @@ const smartGrouping = (items, groupConfigs) => {
77
88
  groups
78
89
  });
79
90
  }
91
+
80
92
  /**
81
- * @param {Set<ItemWithGroups<T, R>>} itemsWithGroups input items with groups
82
- * @returns {(T | R)[]} groups items
93
+ * @param {Items<I, G>} itemsWithGroups input items with groups
94
+ * @returns {(I | G)[]} groups items
83
95
  */
84
96
  const runGrouping = (itemsWithGroups) => {
85
97
  const totalSize = itemsWithGroups.size;
@@ -94,7 +106,7 @@ const smartGrouping = (items, groupConfigs) => {
94
106
  }
95
107
  }
96
108
  }
97
- /** @type {Map<Group<T, R>, { items: Set<ItemWithGroups<T, R>>, options: GroupOptions | false | undefined, used: boolean }>} */
109
+ /** @type {Map<Group<I, G>, { items: Items<I, G>, options: GroupOptions | false | undefined, used: boolean }>} */
98
110
  const groupMap = new Map();
99
111
  for (const group of allGroups.values()) {
100
112
  if (group.items) {
@@ -107,13 +119,15 @@ const smartGrouping = (items, groupConfigs) => {
107
119
  });
108
120
  }
109
121
  }
110
- /** @type {(T | R)[]} */
122
+ /** @type {(I | G)[]} */
111
123
  const results = [];
112
124
  for (;;) {
113
- /** @type {Group<T, R> | undefined} */
125
+ /** @type {Group<I, G> | undefined} */
114
126
  let bestGroup;
115
127
  let bestGroupSize = -1;
128
+ /** @type {Items<I, G> | undefined} */
116
129
  let bestGroupItems;
130
+ /** @type {GroupOptions | false | undefined} */
117
131
  let bestGroupOptions;
118
132
  for (const [group, state] of groupMap) {
119
133
  const { items, used } = state;
@@ -192,8 +206,9 @@ const smartGrouping = (items, groupConfigs) => {
192
206
  bestGroup.alreadyGrouped = true;
193
207
  const children = groupChildren ? runGrouping(items) : allItems;
194
208
  bestGroup.alreadyGrouped = false;
195
-
196
- results.push(groupConfig.createGroup(key, children, allItems));
209
+ results.push(
210
+ groupConfig.createGroup(key, /** @type {I[]} */ (children), allItems)
211
+ );
197
212
  }
198
213
  for (const { item } of itemsWithGroups) {
199
214
  results.push(item);
@@ -0,0 +1,45 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+
6
+ "use strict";
7
+
8
+ /** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperties} DestructuringAssignmentProperties */
9
+ /** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperty} DestructuringAssignmentProperty */
10
+
11
+ /**
12
+ * Deep first traverse the properties of a destructuring assignment.
13
+ * @param {DestructuringAssignmentProperties} properties destructuring assignment properties
14
+ * @param {((stack: DestructuringAssignmentProperty[]) => void) | undefined=} onLeftNode on left node callback
15
+ * @param {((stack: DestructuringAssignmentProperty[]) => void) | undefined=} enterNode enter node callback
16
+ * @param {((stack: DestructuringAssignmentProperty[]) => void) | undefined=} exitNode exit node callback
17
+ * @param {DestructuringAssignmentProperty[] | undefined=} stack stack of the walking nodes
18
+ */
19
+ function traverseDestructuringAssignmentProperties(
20
+ properties,
21
+ onLeftNode,
22
+ enterNode,
23
+ exitNode,
24
+ stack = []
25
+ ) {
26
+ for (const property of properties) {
27
+ stack.push(property);
28
+ if (enterNode) enterNode(stack);
29
+ if (property.pattern) {
30
+ traverseDestructuringAssignmentProperties(
31
+ property.pattern,
32
+ onLeftNode,
33
+ enterNode,
34
+ exitNode,
35
+ stack
36
+ );
37
+ } else if (onLeftNode) {
38
+ onLeftNode(stack);
39
+ }
40
+ if (exitNode) exitNode(stack);
41
+ stack.pop();
42
+ }
43
+ }
44
+
45
+ module.exports = traverseDestructuringAssignmentProperties;