@plaudit/webpack-extensions 2.85.3 → 2.87.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.
@@ -1,5 +1,5 @@
1
1
  import type { Compilation } from "webpack";
2
- import { InlinedAsset, PathQueryParameters, ScriptArgsObject, UsageLocations } from "../shared";
2
+ import { InlinedAsset, PathQueryParameters, ScriptArgsObject } from "../shared";
3
3
  export declare function getAssetFileContents(compilation: Compilation, name: string): string;
4
4
  export declare function unpackPotentiallyPrefixedFilePath(filePath: string): [string, PathQueryParameters | undefined];
5
5
  /**
@@ -26,28 +26,32 @@ export declare function newInvalidFetchPriorityError(fetchpriority: unknown, fil
26
26
  export type PositionForInlineStrategy = 'before' | 'after';
27
27
  export declare function isValidPositionForInlineStrategy(position: unknown): position is PositionForInlineStrategy;
28
28
  export declare function newInvalidPositionForInlineStrategyError(position: unknown, file: string): import("webpack").WebpackError;
29
- export declare function mergeInPathQueryParameters(file: string, registerScriptArgs: UsageLocations['registerScriptArgs'], pathQueryParameters: PathQueryParameters | undefined): NormalizedScriptEnqueuingControlFlags | undefined;
30
29
  /**
31
30
  * This function ensures that the passed pathQueryParameters are normalized for the config-loading step, NOT the emission step
32
31
  */
33
- export type NormalizedScriptEnqueuingControlFlags = {
32
+ export type NormalizedEnqueuingControlFlags = {
34
33
  strategy?: Exclude<LoadingStrategy, 'inline'>;
35
34
  in_footer?: InFooter;
36
35
  inline?: boolean;
37
36
  fetchpriority?: FetchPriority;
38
37
  position?: 'before' | 'after';
39
38
  };
39
+ export declare function mergeTwoScriptEnqueuingControlFlagSets(file: string, baseArgs: NormalizedEnqueuingControlFlags | undefined, ancestorArgs: NormalizedEnqueuingControlFlags | undefined): NormalizedEnqueuingControlFlags | undefined;
40
+ export declare function unpackEnqueuingControlFlagsFromPathQueryParameters(pathQueryParameters: PathQueryParameters | undefined, file: string, sourceType: 'registerScriptArgs' | 'path query parameters'): {
41
+ flags?: NormalizedEnqueuingControlFlags;
42
+ remainder?: PathQueryParameters;
43
+ };
40
44
  /**
41
45
  * This function does a few things:
42
46
  * <ol>
43
- * <li>It extracts inline, position, strategy, in_footer, and fetchpriority from pathQueryParameters</li>
44
- * <li>If inline is true or the strategy is, 'inline', it records the contents of the asset for later injection inline and removes the asset from the compilation output</li>
47
+ * <li>It converts the strategy, in_footer, and fetchpriority flags into a valid script args object</li>
48
+ * <li>If inline is true, it records the contents of the asset and the value of the position flag for later injection and removes the asset from the compilation output</li>
45
49
  * </ol>
46
50
  * @param compilation
47
51
  * @param file
48
- * @param pathQueryParameters
52
+ * @param flags
49
53
  */
50
- export declare function parseScriptArgsObjectFromPathQueryParameters(compilation: Compilation, file: string, pathQueryParameters: PathQueryParameters | undefined): {
54
+ export declare function convertEnqueuingControlFlagsToScriptArgsObject(compilation: Compilation, file: string, flags: NormalizedEnqueuingControlFlags | undefined): {
51
55
  scriptArgsObject?: ScriptArgsObject;
52
56
  inlinedAsset?: InlinedAsset;
53
57
  };
@@ -11,8 +11,9 @@ exports.isValidFetchPriority = isValidFetchPriority;
11
11
  exports.newInvalidFetchPriorityError = newInvalidFetchPriorityError;
12
12
  exports.isValidPositionForInlineStrategy = isValidPositionForInlineStrategy;
13
13
  exports.newInvalidPositionForInlineStrategyError = newInvalidPositionForInlineStrategyError;
14
- exports.mergeInPathQueryParameters = mergeInPathQueryParameters;
15
- exports.parseScriptArgsObjectFromPathQueryParameters = parseScriptArgsObjectFromPathQueryParameters;
14
+ exports.mergeTwoScriptEnqueuingControlFlagSets = mergeTwoScriptEnqueuingControlFlagSets;
15
+ exports.unpackEnqueuingControlFlagsFromPathQueryParameters = unpackEnqueuingControlFlagsFromPathQueryParameters;
16
+ exports.convertEnqueuingControlFlagsToScriptArgsObject = convertEnqueuingControlFlagsToScriptArgsObject;
16
17
  const node_path_1 = require("node:path");
17
18
  const shared_1 = require("../shared");
18
19
  function getAssetFileContents(compilation, name) {
@@ -101,96 +102,98 @@ function isValidPositionForInlineStrategy(position) {
101
102
  function newInvalidPositionForInlineStrategyError(position, file) {
102
103
  return (0, shared_1.newWebpackErrorForFile)(`The position value for the inlined asset was invalid. Received: ${position}, Expected: undefined|'before'|'after'`, file);
103
104
  }
104
- function mergeInPathQueryParameters(file, registerScriptArgs, pathQueryParameters) {
105
- const baseArgs = unpackRegisterScriptArgsFromPathQueryParameters(typeof registerScriptArgs === 'object' ? registerScriptArgs : { strategy: registerScriptArgs }, file, 'registerScriptArgs');
106
- const pathQueryArgs = unpackRegisterScriptArgsFromPathQueryParameters(pathQueryParameters, file, 'path query parameters');
105
+ function mergeTwoScriptEnqueuingControlFlagSets(file, baseArgs, ancestorArgs) {
107
106
  if (baseArgs === undefined) {
108
- return pathQueryArgs;
107
+ return ancestorArgs;
109
108
  }
110
- if (pathQueryArgs === undefined) {
109
+ if (ancestorArgs === undefined) {
111
110
  return baseArgs;
112
111
  }
112
+ // This must be kept in sync with NormalizedScriptEnqueuingControlFlags
113
113
  for (const key of ['strategy', 'in_footer', 'fetchpriority', 'inline', 'position']) {
114
114
  if (key in baseArgs) {
115
- if (key in pathQueryArgs && pathQueryArgs[key] !== baseArgs[key]) {
115
+ if (key in ancestorArgs && ancestorArgs[key] !== baseArgs[key]) {
116
116
  throw (0, shared_1.newWebpackErrorForFile)(`The ${key} values in the registerScriptArgs and the pathQueryParameters for the file conflict`, file);
117
117
  }
118
118
  }
119
- else if (key in pathQueryArgs) {
120
- baseArgs[key] = pathQueryArgs[key];
119
+ else if (key in ancestorArgs) {
120
+ baseArgs[key] = ancestorArgs[key];
121
121
  }
122
122
  }
123
123
  return baseArgs;
124
124
  }
125
- function unpackRegisterScriptArgsFromPathQueryParameters(pathQueryParameters, file, sourceType) {
125
+ function unpackEnqueuingControlFlagsFromPathQueryParameters(pathQueryParameters, file, sourceType) {
126
126
  if (pathQueryParameters === undefined) {
127
- return undefined;
127
+ return {};
128
128
  }
129
- let baseArgs;
130
- const strategy = pathQueryParameters['strategy'];
129
+ const { strategy, in_footer: normalizedInFooter, 'in-footer': alternateInFooter, fetchpriority, position, ...remainder } = pathQueryParameters;
130
+ let flags;
131
131
  switch (strategy) {
132
132
  case 'defer':
133
133
  case 'async':
134
- baseArgs = { strategy };
134
+ flags = { strategy };
135
135
  break;
136
136
  case 'eager':
137
- baseArgs = { strategy: 'eager' };
137
+ flags = { strategy: 'eager' };
138
138
  break;
139
139
  case 'lazy':
140
- baseArgs = { strategy: 'defer', in_footer: true };
140
+ flags = { strategy: 'defer', in_footer: true };
141
141
  break;
142
142
  case 'inline':
143
- baseArgs = { inline: true };
143
+ flags = { inline: true };
144
144
  break;
145
145
  case true:
146
146
  case false:
147
- baseArgs = { in_footer: strategy };
147
+ flags = { in_footer: strategy };
148
148
  break;
149
149
  case null:
150
150
  case undefined:
151
- baseArgs = {};
151
+ flags = {};
152
152
  break;
153
153
  default:
154
154
  throw newInvalidLoadingStrategyError(strategy, file);
155
155
  }
156
- if (baseArgs.inline === undefined && pathQueryParameters['inline'] !== undefined) {
157
- baseArgs.inline = !!pathQueryParameters['inline'];
156
+ if (flags.inline === undefined && pathQueryParameters['inline'] !== undefined) {
157
+ flags.inline = !!pathQueryParameters['inline'];
158
158
  }
159
- const in_footer = pathQueryParameters['in_footer'] ?? pathQueryParameters['in-footer'];
159
+ const in_footer = normalizedInFooter ?? alternateInFooter;
160
160
  if (in_footer !== undefined) {
161
161
  if (!isValidInFooter(in_footer)) {
162
162
  throw newInvalidInFooterError(in_footer, file);
163
163
  }
164
- baseArgs.in_footer = in_footer;
164
+ flags.in_footer = in_footer;
165
165
  }
166
166
  if (pathQueryParameters['fetchpriority'] !== undefined) {
167
167
  if (!isValidFetchPriority(pathQueryParameters['fetchpriority'])) {
168
168
  throw newInvalidFetchPriorityError(pathQueryParameters['fetchpriority'], file);
169
169
  }
170
- if (baseArgs.fetchpriority !== undefined && baseArgs.fetchpriority !== pathQueryParameters['fetchpriority']) {
170
+ if (flags.fetchpriority !== undefined && flags.fetchpriority !== pathQueryParameters['fetchpriority']) {
171
171
  throw (0, shared_1.newWebpackErrorForFile)(`The strategy and fetchpriority values in the ${sourceType} for the file conflict. Got ${strategy} and ${pathQueryParameters['fetchpriority']}`, file);
172
172
  }
173
- baseArgs.fetchpriority = pathQueryParameters['fetchpriority'];
173
+ flags.fetchpriority = pathQueryParameters['fetchpriority'];
174
174
  }
175
- return Object.keys(baseArgs).length > 0 ? baseArgs : undefined;
175
+ if (flags.inline && (pathQueryParameters['position'] === 'before' || pathQueryParameters['position'] === 'after')) {
176
+ flags.position = pathQueryParameters['position'];
177
+ }
178
+ return Object.keys(flags).length > 0 ? { flags, remainder } : { remainder };
176
179
  }
177
180
  /**
178
181
  * This function does a few things:
179
182
  * <ol>
180
- * <li>It extracts inline, position, strategy, in_footer, and fetchpriority from pathQueryParameters</li>
181
- * <li>If inline is true or the strategy is, 'inline', it records the contents of the asset for later injection inline and removes the asset from the compilation output</li>
183
+ * <li>It converts the strategy, in_footer, and fetchpriority flags into a valid script args object</li>
184
+ * <li>If inline is true, it records the contents of the asset and the value of the position flag for later injection and removes the asset from the compilation output</li>
182
185
  * </ol>
183
186
  * @param compilation
184
187
  * @param file
185
- * @param pathQueryParameters
188
+ * @param flags
186
189
  */
187
- function parseScriptArgsObjectFromPathQueryParameters(compilation, file, pathQueryParameters) {
188
- if (pathQueryParameters === undefined) {
190
+ function convertEnqueuingControlFlagsToScriptArgsObject(compilation, file, flags) {
191
+ if (flags === undefined) {
189
192
  return {};
190
193
  }
194
+ const { strategy, in_footer, inline, position, fetchpriority } = flags;
191
195
  const scriptArgsObject = {};
192
196
  let inlinedAsset = undefined;
193
- const strategy = pathQueryParameters['strategy'];
194
197
  switch (strategy) {
195
198
  case 'async':
196
199
  case 'defer':
@@ -203,13 +206,6 @@ function parseScriptArgsObjectFromPathQueryParameters(compilation, file, pathQue
203
206
  scriptArgsObject.strategy = 'defer';
204
207
  scriptArgsObject.in_footer = true;
205
208
  break;
206
- case 'inline':
207
- inlinedAsset = { contents: getAssetFileContents(compilation, file) };
208
- removeFileAndAssetPHP(compilation, file);
209
- if ('inline' in pathQueryParameters) {
210
- compilation.warnings.push((0, shared_1.newWebpackErrorForFile)("The inline parameter should not be set when setting strategy to 'inline'", file));
211
- }
212
- break;
213
209
  case true:
214
210
  case false:
215
211
  scriptArgsObject.in_footer = strategy;
@@ -221,23 +217,20 @@ function parseScriptArgsObjectFromPathQueryParameters(compilation, file, pathQue
221
217
  default:
222
218
  throw newInvalidLoadingStrategyError(strategy, file);
223
219
  }
224
- const in_footer = pathQueryParameters['in_footer'] ?? pathQueryParameters['in-footer'];
225
220
  if (in_footer !== undefined) {
226
221
  if (!isValidInFooter(in_footer)) {
227
222
  throw newInvalidInFooterError(in_footer, file);
228
223
  }
229
224
  scriptArgsObject.in_footer = in_footer;
230
225
  }
231
- if (inlinedAsset === undefined && pathQueryParameters['inline']) {
226
+ if (inline) {
232
227
  inlinedAsset = { contents: getAssetFileContents(compilation, file) };
233
228
  removeFileAndAssetPHP(compilation, file);
234
- }
235
- if (inlinedAsset !== undefined) {
236
- if (pathQueryParameters['position'] !== undefined) {
237
- if (!isValidPositionForInlineStrategy(pathQueryParameters['position'])) {
238
- throw newInvalidPositionForInlineStrategyError(pathQueryParameters['position'], file);
229
+ if (position !== undefined) {
230
+ if (!isValidPositionForInlineStrategy(position)) {
231
+ throw newInvalidPositionForInlineStrategyError(position, file);
239
232
  }
240
- inlinedAsset.position = pathQueryParameters['position'];
233
+ inlinedAsset.position = position;
241
234
  }
242
235
  if (inlinedAsset.position !== 'before' && scriptArgsObject.strategy !== undefined) {
243
236
  compilation.warnings.push((0, shared_1.newWebpackErrorForFile)("Deferred and async scripts that have inlined JS attached in the 'after' position will cause WordPress to convert all of their dependencies to eager scripts at runtime", file));
@@ -246,7 +239,6 @@ function parseScriptArgsObjectFromPathQueryParameters(compilation, file, pathQue
246
239
  scriptArgsObject.in_footer = true;
247
240
  }
248
241
  }
249
- const fetchpriority = pathQueryParameters['fetchpriority'];
250
242
  if (fetchpriority !== undefined) {
251
243
  if (!isValidFetchPriority(fetchpriority)) {
252
244
  throw newInvalidFetchPriorityError(fetchpriority, file);
@@ -6,7 +6,9 @@ const node_fs_1 = require("node:fs");
6
6
  const promises_1 = require("node:fs/promises");
7
7
  const node_path_1 = require("node:path");
8
8
  const shared_1 = require("./shared");
9
+ const entrypoint_resolution_logic_1 = require("./utils/entrypoint-resolution-logic");
9
10
  const common_config_helpers_1 = require("./utils/common-config-helpers");
11
+ const path_query_and_related_helpers_1 = require("./utils/path-query-and-related-helpers");
10
12
  const AdditionalDependencyInjectorPlugin_1 = require("./plugins/AdditionalDependencyInjectorPlugin");
11
13
  const BrowserSyncPlugin_1 = require("./plugins/BrowserSyncPlugin");
12
14
  const dependency_extraction_webpack_plugin_config_builder_1 = require("./plugins/dependency-extraction-webpack-plugin-config-builder");
@@ -25,7 +27,7 @@ const UnifiedLoaderGenerator_1 = require("./plugins/UnifiedLoaderGenerator");
25
27
  const copy_webpack_plugin_1 = __importDefault(require("copy-webpack-plugin"));
26
28
  const fork_ts_checker_webpack_plugin_1 = __importDefault(require("fork-ts-checker-webpack-plugin"));
27
29
  const webpack_remove_empty_scripts_1 = __importDefault(require("webpack-remove-empty-scripts"));
28
- const path_query_and_related_helpers_1 = require("./utils/path-query-and-related-helpers");
30
+ const location_encoding_filename_parser_1 = require("./utils/location-encoding-filename-parser");
29
31
  function testForDuplicatedEntryPaths(sources) {
30
32
  const seenPaths = (0, common_config_helpers_1.groupEntrypointsByAssetFile)(Array.isArray(sources)
31
33
  ? sources.map(s => typeof s === 'string' ? s : s[1].destination)
@@ -164,6 +166,7 @@ function injectSupportForInliningSVGsAsStrings(rules) {
164
166
  });
165
167
  }
166
168
  function buildVerifiedConfig(config) {
169
+ config = (0, shared_1.applyStandards)(config);
167
170
  const { standaloneBlocks = false, stats = 'errors-warnings', variables: rawVariables, verbose = process.argv.includes('--verbose') || process.env['VERBOSE'] === 'true', postcss = {}, externals, assumeGlobalizedPlauditLibraries = true, processTranslationConfigs = true, combineAssetMetadata = true, useWebpackResourceFiltering = true, plainEntrypointsVersion = 1, srcDir = "", useUnifiedLoader = false, includePostInitFallback = false, omitDistDev = false, onlyRunPostCSSOnPCSS = false } = config;
168
171
  let outputDir = config.outputDir ?? "";
169
172
  if (outputDir && useUnifiedLoader && !omitDistDev && (process.env['SERVER_MODE'] ?? 'development') === 'development') {
@@ -189,23 +192,8 @@ function buildVerifiedConfig(config) {
189
192
  throw new Error("Plain Entrypoints V2 and higher require 'outputDir' to be set");
190
193
  }
191
194
  }
192
- const normalizeSrcAndDestination = ([rawSrc, dest]) => {
193
- let [src, pathQueryParameters] = (0, path_query_and_related_helpers_1.unpackPotentiallyPrefixedFilePath)(rawSrc);
194
- if (srcDir) {
195
- src = (0, node_path_1.join)(srcDir, src);
196
- }
197
- src = (0, node_path_1.isAbsolute)(src) ? (0, node_path_1.relative)(process.cwd(), src) : src;
198
- if (dest.destination !== undefined && (0, node_path_1.isAbsolute)(dest.destination)) {
199
- return [src, { ...dest, destination: (0, node_path_1.relative)(process.cwd(), dest.destination), pathQueryParameters }];
200
- }
201
- return [src, { ...dest, pathQueryParameters }];
202
- };
203
- const rawSources = Array.isArray(config.src)
204
- ? config.src.map(s => normalizeSrcAndDestination([s, { destination: s }]))
205
- : Object.entries(config.src)
206
- .map(([k, v]) => {
207
- return normalizeSrcAndDestination([k, typeof v === 'boolean' ? {} : (typeof v === 'string' ? { destination: v } : v)]);
208
- });
195
+ const { staticEntrypoints, dynamicEntrypoints } = (0, entrypoint_resolution_logic_1.resolveAllConfigLevelEntrypoints)(config);
196
+ const rawSources = [...staticEntrypoints, ...dynamicEntrypoints];
209
197
  let variablesFilePath = undefined;
210
198
  const currentVariables = rawVariables ?? {};
211
199
  if (!rawVariables) {
@@ -223,7 +211,9 @@ function buildVerifiedConfig(config) {
223
211
  // Destination -> source map
224
212
  const allocatedDestinations = {};
225
213
  const partiallyVerifiedSources = rawSources.map(rawSource => {
226
- const { destination, additionalDependencies = [], assumeGlobalizedPlauditLibraries = cfg.assumeGlobalizedPlauditLibraries, bundleAnalyzer = false, directoryLayout, externalize, withLegacyBlocksIn = false, lazyLoader, pathQueryParameters } = rawSource[1];
214
+ const { destination, additionalDependencies = [], assumeGlobalizedPlauditLibraries = cfg.assumeGlobalizedPlauditLibraries, bundleAnalyzer = false, directoryLayout, externalize, withLegacyBlocksIn = false, lazyLoader, pathQueryParameters: rawPathQueryParameters, enqueuingFlags: rawEnqueuingFlags } = rawSource[1];
215
+ const { flags: queryEnqueuingFlags, remainder: pathQueryParameters } = (0, path_query_and_related_helpers_1.unpackEnqueuingControlFlagsFromPathQueryParameters)(rawPathQueryParameters, rawSource[0], 'path query parameters');
216
+ const enqueuingFlags = (0, path_query_and_related_helpers_1.mergeTwoScriptEnqueuingControlFlagSets)(rawSource[0], rawEnqueuingFlags, queryEnqueuingFlags);
227
217
  const normalizedParts = { additionalDependencies, assumeGlobalizedPlauditLibraries, bundleAnalyzer, directoryLayout, externalize, withLegacyBlocksIn, lazyLoader };
228
218
  const locations = typeof rawSource[1].locations === 'string' || typeof rawSource[1].locations === 'function'
229
219
  ? { handle: rawSource[1].locations } : rawSource[1].locations ?? {};
@@ -233,12 +223,12 @@ function buildVerifiedConfig(config) {
233
223
  if (destination !== undefined) {
234
224
  const effectiveDestination = toEffectiveWebpackDestination(destination);
235
225
  allocatedDestinations[effectiveDestination] = rawSource[0]; // We need to pre-populate the allocatedDestinations map with statically declared destinations
236
- return [rawSource[0], { ...normalizedParts, locations, destination, effectiveDestination, staticallyDeclaredDestination: true, pathQueryParameters }];
226
+ return [rawSource[0], { ...normalizedParts, locations, destination, effectiveDestination, staticallyDeclaredDestination: true, pathQueryParameters, enqueuingFlags }];
237
227
  }
238
228
  else {
239
229
  const naiveDestination = deriveNaiveDestinationFromUnverifiedSourceEntry(rawSource, srcPrefixes);
240
230
  const effectiveDestination = toEffectiveWebpackDestination(naiveDestination);
241
- return [rawSource[0], { ...normalizedParts, locations, destination: naiveDestination, effectiveDestination, staticallyDeclaredDestination: false, pathQueryParameters }];
231
+ return [rawSource[0], { ...normalizedParts, locations, destination: naiveDestination, effectiveDestination, staticallyDeclaredDestination: false, pathQueryParameters, enqueuingFlags }];
242
232
  }
243
233
  });
244
234
  const dynamicEffectiveDestinationsWithExpectedNaiveDuplicates = partiallyVerifiedSources
@@ -517,12 +507,22 @@ function processIndividualWebpackConfig(config, webpackConfig, sources, canClean
517
507
  const entry = async () => {
518
508
  const rawEntrypoints = [];
519
509
  for await (const dirent of await (0, promises_1.opendir)(srcRoot)) {
520
- if (dirent.isFile() && !dirent.name.startsWith("~")) {
521
- if (commonConfig.scriptExtension.test(dirent.name) || shared_1.styleExtension.test(dirent.name)) {
510
+ if (dirent.name.startsWith("~")) {
511
+ continue;
512
+ }
513
+ if (dirent.isFile()) {
514
+ if ((commonConfig.scriptExtension.test(dirent.name) || shared_1.styleExtension.test(dirent.name))) {
522
515
  const absoluteSrc = (0, common_config_helpers_1.joinPossiblyAbsolutePaths)(srcRoot, dirent.name);
523
- rawEntrypoints.push([(0, node_path_1.join)(dest.destination, (0, node_path_1.basename)(absoluteSrc, (0, node_path_1.extname)(absoluteSrc))), { import: [absoluteSrc], plauditMetadata: { dest, absoluteSrc } }]);
516
+ const extensionId = (0, node_path_1.parse)(dirent.name).name;
517
+ rawEntrypoints.push([(0, node_path_1.join)(dest.destination, (0, node_path_1.basename)(absoluteSrc, (0, node_path_1.extname)(absoluteSrc))), {
518
+ import: [absoluteSrc],
519
+ plauditMetadata: { dest, absoluteSrc, extensionId }
520
+ }]);
524
521
  }
525
522
  }
523
+ else if (dirent.isDirectory()) {
524
+ rawEntrypoints.push(...await walkExtensionsTree((0, node_path_1.join)(srcRoot, dirent.name), dest, [dirent.name]));
525
+ }
526
526
  }
527
527
  return Object.fromEntries(rawEntrypoints);
528
528
  };
@@ -563,7 +563,7 @@ function processIndividualWebpackConfig(config, webpackConfig, sources, canClean
563
563
  if (canCopyFiles) {
564
564
  plugins.push(new copy_webpack_plugin_1.default({
565
565
  patterns: [{
566
- from: config.standaloneBlocks ? '**/*.(php|twig|svg)' : '**/*.(asset\.php|svg)',
566
+ from: config.standaloneBlocks ? '**/*.(php|twig|svg)' : '**/*.(asset\.php|svg)', //TODO: I'm pretty sure that the dots need proper escaping
567
567
  to: dest.destination,
568
568
  context: srcRoot /* canCopyFiles can only be true if srcRoot is a string, so this is safe */, noErrorOnMissing: true
569
569
  }]
@@ -574,6 +574,45 @@ function processIndividualWebpackConfig(config, webpackConfig, sources, canClean
574
574
  return (0, common_config_helpers_1.commonMakeWebpackConfig)(config, commonConfig, webpackConfig, externalize, plugins, canClean && batches.length < 2);
575
575
  }).filter(cfg => cfg !== undefined);
576
576
  }
577
+ async function walkExtensionsTree(srcRoot, dest, parents) {
578
+ const res = [];
579
+ for await (const dirent of await (0, promises_1.opendir)(srcRoot)) {
580
+ if (dirent.name.startsWith("~")) {
581
+ continue;
582
+ }
583
+ if (dirent.isFile()) {
584
+ const parsedFilename = (0, location_encoding_filename_parser_1.parseLocationEncodingFilename)(dirent.name);
585
+ if (parsedFilename === undefined) {
586
+ continue;
587
+ }
588
+ const absoluteSrc = (0, common_config_helpers_1.joinPossiblyAbsolutePaths)(srcRoot, dirent.name);
589
+ let destFile;
590
+ if (Object.keys(parsedFilename.locations).length === 1) {
591
+ if (parsedFilename.locations.clientView) {
592
+ destFile = `view-${parsedFilename.type}`;
593
+ }
594
+ else if (parsedFilename.locations.clientEditor) {
595
+ destFile = `editor-${parsedFilename.type}`;
596
+ }
597
+ else {
598
+ destFile = (0, node_path_1.basename)(absoluteSrc, (0, node_path_1.extname)(absoluteSrc));
599
+ }
600
+ }
601
+ else {
602
+ destFile = (0, node_path_1.basename)(absoluteSrc, (0, node_path_1.extname)(absoluteSrc));
603
+ }
604
+ const extensionId = parents.join("-") + "-" + destFile;
605
+ res.push([(0, node_path_1.join)(dest.destination, ...parents, destFile), {
606
+ import: [absoluteSrc],
607
+ plauditMetadata: { dest, absoluteSrc, extensionId }
608
+ }]);
609
+ }
610
+ else if (dirent.isDirectory()) {
611
+ res.push(...await walkExtensionsTree((0, node_path_1.join)(srcRoot, dirent.name), dest, [...parents, dirent.name]));
612
+ }
613
+ }
614
+ return res;
615
+ }
577
616
  function stripExtension(filepath) {
578
617
  return (0, node_path_1.join)((0, node_path_1.dirname)(filepath), (0, node_path_1.basename)(filepath, (0, node_path_1.extname)(filepath)));
579
618
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plaudit/webpack-extensions",
3
- "version": "2.85.3",
3
+ "version": "2.87.0",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "files": [
6
6
  "/build",
@@ -11,6 +11,7 @@
11
11
  ],
12
12
  "exports": {
13
13
  "./wordpress-scripts-wrapper": "./build/wordpress-scripts-wrapper.js",
14
+ "./location-encoding-filename-parser": "./build/utils/location-encoding-filename-parser.js",
14
15
  "./shared": "./build/shared.js"
15
16
  },
16
17
  "typesVersions": {
@@ -18,6 +19,9 @@
18
19
  "wordpress-scripts-wrapper": [
19
20
  "build/wordpress-scripts-wrapper.d.ts"
20
21
  ],
22
+ "location-encoding-filename-parser": [
23
+ "build/location-encoding-filename-parser.d.ts"
24
+ ],
21
25
  "shared": [
22
26
  "build/shared.d.ts"
23
27
  ]
@@ -26,7 +30,7 @@
26
30
  "devDependencies": {
27
31
  "@plaudit/gutenberg-api-extensions": "^2.87.0",
28
32
  "@types/browser-sync-webpack-plugin": "^2.2.5",
29
- "@types/node": "^25.3.5",
33
+ "@types/node": "^25.5.0",
30
34
  "@types/postcss-functions": "^4.0.4",
31
35
  "@types/tapable": "^2.3.0",
32
36
  "@types/webpack-sources": "^3.2.3",
@@ -65,7 +69,7 @@
65
69
  "postcss-url": "^10.1.3",
66
70
  "webpack": "^5.105.4",
67
71
  "webpack-remove-empty-scripts": "^1.1.1",
68
- "xml-formatter": "^3.6.7"
72
+ "xml-formatter": "^3.7.0"
69
73
  },
70
74
  "engines": {
71
75
  "node": ">=20"