@plaudit/webpack-extensions 2.95.0 → 2.96.1

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/CHANGELOG.md CHANGED
@@ -60,6 +60,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
60
60
  - Legacy PostCSS features that have been integrated into modern CSS
61
61
  - `@extends` support
62
62
 
63
+ ## [2.96.1] - 2026-08-10
64
+ ### Fixed
65
+ - An error in how externalized dependencies were resolved that caused jquery to never be emitted as a depenedency
66
+
67
+ ## [2.96.0] - 2026-08-07
68
+ ### Added
69
+ - A port of WordPress's Dependency Extraction Webpack Plugin because they keep breaking it
70
+ - Warnings and additional info for entrypoints that are lazy-loaded and assigned to actual locations
71
+
72
+ ### Removed
73
+ - "combineAssetMetadata" - it has never actually been a valid prop
74
+
75
+ ### Fixed
76
+ - Path-query handle handling
77
+ - Double emission of CSS from entrypoint.json files when module processing is enabled
78
+ - A bug that could result in writes outside the webpack context root
79
+
80
+ ### Changed
81
+ - Backported the hook_name fix from the 3.x branch
82
+
63
83
  ## [2.95.0] - 2026-08-04
64
84
  ### Added
65
85
  - Logic so that files and directories with names equal to "example" or "examples" or that include "example" as a name segment are skipped
@@ -295,7 +315,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
295
315
 
296
316
  ## [2.72.1] - 2025-10-29
297
317
  ### Fixed
298
- - The wrapper being unable to find the `DependencyExtractionWebpackPlugin` due to version desyncs
318
+ - The wrapper being unable to find the `EnhancedDependencyExtractionWebpackPlugin` due to version desyncs
299
319
  - This isn't so much a "fix" as it is a "mitigation" - version desyncs are not fixable at the library level
300
320
 
301
321
  ## [2.72.0] - 2025-10-13
package/USER-GUIDE.md CHANGED
@@ -314,7 +314,7 @@ src: {
314
314
  | `srcDir` | `string` | `""` | Source directory (**Required** on new sites) |
315
315
  | `outputDir` | `string` | `""` | Output directory (**Required** on new sites) |
316
316
  | `useUnifiedLoader` | `boolean` | `false` | Generate unified-loader.php (always set to `true` on new sites!) |
317
- | `useWebpackResourceFiltering` | `boolean` | `false` | Generates versioned copies of images, fonts, etc (always set to `true` on new sites!) |
317
+ | `useWebpackResourceFiltering` | `boolean` | `true` | Generates versioned copies of images, fonts, etc (always set to `true` on new sites!) |
318
318
  | `plainEntrypointsVersion` | `1\|2` | `1` | Use 2 for new sites |
319
319
  | `extensionsVersion` | `1\|2\|3` | `1` | Use 3 for new sites |
320
320
  | `verbose` | `boolean` | `false` | Verbose logging |
@@ -2,7 +2,7 @@ import { MinimumViableMetadata, ParsedAssetJsonProvider, ParsedAssetsJson } from
2
2
  import type { ExtensibleEntryObject, VerifiedPlauditWordpressWebpackConfig } from "../utils/common-config-helpers";
3
3
  import { PseudoSemaphore } from "../utils/pseduo-semaphore";
4
4
  import { AbstractBiPhasicGroupPlugin } from "./AbstractBiPhasicGroupPlugin";
5
- import { Compilation, Compiler, Entrypoint } from "webpack";
5
+ import { type Compilation, type Compiler, type Entrypoint } from "webpack";
6
6
  export type EntryProvider<M extends MinimumViableMetadata = MinimumViableMetadata> = () => ExtensibleEntryObject<M> | Promise<ExtensibleEntryObject<M>>;
7
7
  export declare abstract class AbstractBiPhasicGroupAndEntryPlugin<M extends MinimumViableMetadata = MinimumViableMetadata> extends AbstractBiPhasicGroupPlugin {
8
8
  private readonly context;
@@ -24,6 +24,7 @@ export declare class EnhancedBlockJSONPlugin extends AbstractBiPhasicGroupAndEnt
24
24
  constructor(config: VerifiedPlauditWordpressWebpackConfig, dest: VerifiedAdvancedOutputConfig, webpackRemoveEmptyScriptsPlugin: WebpackRemoveEmptyScriptsPlugin, context: string, entry: EntryProvider<BlockEntrypointInfo>);
25
25
  protected processAssets(compilation: Compilation, parsedAssetJsonProvider: ParsedAssetJsonProvider): Promise<void>;
26
26
  private emitBlockLoaderFile;
27
+ private static readonly THEME_JSON_FLAG_PROPS;
27
28
  private static pickOutFlagPropsFromBlockSupports;
28
29
  private callRegisterFunction;
29
30
  private transformBlocks;
@@ -226,37 +226,48 @@ class EnhancedBlockJSONPlugin extends AbstractBiPhasicGroupAndEntryPlugin_1.Abst
226
226
  compilation.emitAsset((0, node_path_1.join)(this.dest.destination, "blockdir.config.php"), new webpack_1.sources.RawSource((0, shared_1.makeEmittableConfigPHP)(blockDirConfig, true)));
227
227
  }
228
228
  }
229
- // This isn't strictly necessary, but it allows us to trivially eliminate commonly-used block supports flags that aren't used in theme.json
230
- // private static readonly IGNORED_THEME_JSON_FLAG_PROPS = ['align', 'alignWide', 'anchor', 'contentRole', 'inserter', 'interactivity', 'listView', 'plaudit'];
229
+ /*
230
+ * The block supports that have a boolean counterpart under theme.json's settings, as
231
+ * `settings key -> {support prop: settings prop}`. This is an allow-list rather than an ignore-list
232
+ * because most supports (align, alignWide, anchor, contentRole, inserter, interactivity, listView,
233
+ * plaudit, ...) have no theme.json settings equivalent at all, and the ones that do don't always
234
+ * share a name: typography's fontSize is settings.typography.customFontSize, and Gutenberg still
235
+ * ships several of these under an __experimental prefix.
236
+ */
237
+ static THEME_JSON_FLAG_PROPS = {
238
+ color: { background: 'background', link: 'link', text: 'text' },
239
+ dimensions: { aspectRatio: 'aspectRatio', minHeight: 'minHeight' },
240
+ spacing: { blockGap: 'blockGap', margin: 'margin', padding: 'padding' },
241
+ typography: {
242
+ fontSize: 'customFontSize',
243
+ lineHeight: 'lineHeight',
244
+ textAlign: 'textAlign',
245
+ fontStyle: 'fontStyle', __experimentalFontStyle: 'fontStyle',
246
+ fontWeight: 'fontWeight', __experimentalFontWeight: 'fontWeight',
247
+ letterSpacing: 'letterSpacing', __experimentalLetterSpacing: 'letterSpacing',
248
+ textDecoration: 'textDecoration', __experimentalTextDecoration: 'textDecoration',
249
+ textTransform: 'textTransform', __experimentalTextTransform: 'textTransform',
250
+ writingMode: 'writingMode', __experimentalWritingMode: 'writingMode'
251
+ }
252
+ };
231
253
  static pickOutFlagPropsFromBlockSupports(supports) {
232
254
  function isRecord(value) {
233
255
  return typeof value === 'object' && !!value && !Array.isArray(value);
234
256
  }
235
257
  let addedProp = false;
236
258
  const res = {};
237
- if ('color' in supports) {
238
- const color = supports.color;
239
- if (isRecord(color)) {
240
- const colorFlags = {};
241
- for (const prop of ['background', 'link', 'text']) {
242
- if (supports[prop]) {
243
- colorFlags[prop] = true;
244
- res.color = colorFlags;
245
- addedProp = true;
246
- }
247
- }
259
+ for (const [settingsKey, props] of Object.entries(EnhancedBlockJSONPlugin.THEME_JSON_FLAG_PROPS)) {
260
+ const support = supports[settingsKey];
261
+ if (!isRecord(support)) {
262
+ continue;
248
263
  }
249
- }
250
- if ('dimensions' in supports) {
251
- const dimensions = supports.dimensions;
252
- if (isRecord(dimensions)) {
253
- const dimensionsFlags = {};
254
- for (const prop of ['aspectRatio']) {
255
- if (supports[prop]) {
256
- dimensionsFlags[prop] = true;
257
- res.color = dimensionsFlags;
258
- addedProp = true;
259
- }
264
+ const flags = {};
265
+ for (const [supportProp, settingsProp] of Object.entries(props)) {
266
+ // A sided support such as `"margin": ["top", "bottom"]` is still just "on" as far as theme.json is concerned
267
+ if (support[supportProp]) {
268
+ flags[settingsProp] = true;
269
+ res[settingsKey] = flags;
270
+ addedProp = true;
260
271
  }
261
272
  }
262
273
  }
@@ -43,7 +43,7 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
43
43
  for (const { src, rest, locations, type, handleName, lazyLoader, ...otherProps } of handles) {
44
44
  const cleanBasename = (0, node_path_1.basename)(src).replace(/_(?:script(?:-\d+)?\.js|style(?:-\d+)?\.css)$|(?<!_(script|style))\.(js|css)$/, "");
45
45
  let finalHandleName;
46
- if (typeof handleName === 'string') {
46
+ if (handleName !== undefined) {
47
47
  finalHandleName = (0, shared_1.convertUsageLocationsHandleToEmittableHandle)(handleName, cleanBasename);
48
48
  }
49
49
  else {
@@ -57,13 +57,13 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
57
57
  plainEntrypointsConfig[`${type}Handles`][finalHandleName] = { src, rest, locations, type, lazyLoader, ...otherProps };
58
58
  }
59
59
  }
60
- PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists('script', Object.entries(plainEntrypointsConfig.scriptHandles)
60
+ PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists(compilation, 'script', Object.entries(plainEntrypointsConfig.scriptHandles)
61
61
  .toSorted(([a], [b]) => a.localeCompare(b)), handleLists);
62
- PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists('script_module', Object.entries(plainEntrypointsConfig.script_moduleHandles)
62
+ PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists(compilation, 'script_module', Object.entries(plainEntrypointsConfig.script_moduleHandles)
63
63
  .toSorted(([a], [b]) => a.localeCompare(b)), handleLists);
64
64
  const sortedStyleHandles = Object.entries(plainEntrypointsConfig.styleHandles)
65
65
  .toSorted(([a], [b]) => a.localeCompare(b));
66
- PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists('style', sortedStyleHandles, handleLists);
66
+ PlainEntrypointsConfigFileGeneratorPlugin.addHandlesToHandleLists(compilation, 'style', sortedStyleHandles, handleLists);
67
67
  const callItemSorter = (a, b) => a.handle.localeCompare(b.handle);
68
68
  for (const list of Object.values(handleLists)) {
69
69
  list.sort(callItemSorter);
@@ -121,8 +121,10 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
121
121
  writer.return(editorSettings);
122
122
  }, { functionArgParameters: [editorSettings], accountForAlreadyDoing: false });
123
123
  }
124
- const lazyLoadedHandles = Object.values(handleLists)
125
- .flatMap(handleList => handleList.map(handle => [handle.data.lazyLoader, handle]))
124
+ // Only the register and inline lists, which are mutually exclusive, so each handle is collected
125
+ // exactly once. Flattening every list instead would collect a handle once per location it declares.
126
+ const lazyLoadedHandles = [...handleLists.register, ...handleLists.inline]
127
+ .map(handle => [handle.data.lazyLoader, handle])
126
128
  .filter((entry) => entry[0] !== undefined)
127
129
  .sort((a, b) => a[0].localeCompare(b[0]) || a[1].priority - b[1].priority);
128
130
  if (lazyLoadedHandles.length > 0) {
@@ -142,7 +144,7 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
142
144
  }
143
145
  (0, shared_1.emitPHPWriterAsAsset)(writer, compilation, "plain-entrypoints-loader.php");
144
146
  }
145
- static addHandlesToHandleLists(type, handles, handleLists) {
147
+ static addHandlesToHandleLists(compilation, type, handles, handleLists) {
146
148
  const defaultPriority = 10;
147
149
  for (const [handle, data] of handles) {
148
150
  if (data.locations.register !== false) {
@@ -151,6 +153,19 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
151
153
  else if (data.inlinedAsset !== undefined) {
152
154
  handleLists.inline.push({ handle, type, data, priority: typeof data.locations.inline === 'number' ? data.locations.inline : 10 });
153
155
  }
156
+ if (data.lazyLoader !== undefined) {
157
+ // A lazily loaded handle is enqueued by its generated function and never by an action, so it
158
+ // is deliberately kept out of the location lists. Those lists are also what the lazy function
159
+ // is built from, and a handle present in several of them would be enqueued once per list.
160
+ const declaredLocations = (0, shared_1.constantKeys)(shared_1.standardLocationNamesMeta)
161
+ .filter(location => data.locations[location] || typeof data.locations[location] === 'number');
162
+ if (declaredLocations.length > 0) {
163
+ const locText = declaredLocations.length === 1 ? "location" : "locations";
164
+ compilation.warnings.push((0, shared_1.newWebpackErrorForFile)(`The handle "${handle}" declares both a lazyLoader (${data.lazyLoader}) and the ${declaredLocations.join(", ")} ${locText}.`
165
+ + ` It will only be enqueued by ${data.lazyLoader}(); remove either the ${locText} or the lazyLoader.`, data.src));
166
+ }
167
+ continue;
168
+ }
154
169
  for (const location of (0, shared_1.constantKeys)(shared_1.standardLocationNamesMeta)) {
155
170
  let priority, hook_name;
156
171
  const dataLocation = data.locations[location];
@@ -194,7 +209,6 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
194
209
  }
195
210
  }
196
211
  static appendEnqueuingHandleLists(writer, handleLists) {
197
- const lazyLoadableHandles = {};
198
212
  for (const [sln, { action, supports_hook_name, additional_action_code }] of (0, shared_1.constantEntries)(shared_1.standardLocationNamesMeta)) {
199
213
  const handleList = handleLists[sln];
200
214
  if (handleList.length > 0) {
@@ -202,11 +216,14 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
202
216
  for (const [priority, prioritizedHandleList] of PlainEntrypointsConfigFileGeneratorPlugin.separateHandleListByPriority(handleList)) {
203
217
  if (supports_hook_name) {
204
218
  const hookNamedHandleLists = PlainEntrypointsConfigFileGeneratorPlugin.separateHandleListByHookName(prioritizedHandleList);
205
- if (!(0, shared_1.arrayIsLength)(hookNamedHandleLists, 1) || hookNamedHandleLists[0][0] !== "") {
219
+ if (hookNamedHandleLists.named.length > 0) {
206
220
  const hook_name_var = new expressions_1.Var("hook_name", "?string");
207
221
  writer.action(action, writer => {
208
222
  additional_action_code?.before?.(writer);
209
- for (const [hook_name, handles] of hookNamedHandleLists) {
223
+ for (const handle of hookNamedHandleLists.global) {
224
+ writer.call(`wp_enqueue_${handle.type}`, [handle.handle]);
225
+ }
226
+ for (const [hook_name, handles] of hookNamedHandleLists.named) {
210
227
  writer.if(expressions_1.Op.binary(hook_name_var, " === ", hook_name));
211
228
  for (const handle of handles) {
212
229
  writer.call(`wp_enqueue_${handle.type}`, [handle.handle]);
@@ -228,7 +245,6 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
228
245
  }
229
246
  }
230
247
  }
231
- return lazyLoadableHandles;
232
248
  }
233
249
  static separateHandleListByPriority(handleItems) {
234
250
  const lists = new Map();
@@ -249,9 +265,16 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
249
265
  * @private
250
266
  */
251
267
  static separateHandleListByHookName(handleItems) {
268
+ const global = [];
252
269
  const lists = new Map();
253
270
  for (const handleItem of handleItems) {
254
271
  const hook_name = handleItem.hook_name ?? "";
272
+ if (hook_name === "" || (Array.isArray(hook_name) && hook_name.includes(""))) {
273
+ // We're going to be handling global hooks (aka those without a name restriction) separately anyway,
274
+ // so there's no sense in mixing them in with the non-global ones
275
+ global.push(handleItem);
276
+ continue;
277
+ }
255
278
  for (const hn of Array.isArray(hook_name) ? hook_name : [hook_name]) {
256
279
  const list = lists.get(hn);
257
280
  if (list) {
@@ -262,15 +285,7 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractBiPhasicGroupAnd
262
285
  }
263
286
  }
264
287
  }
265
- return lists.entries().toArray().sort((a, b) => {
266
- if (a[0] === "") {
267
- return b[0] === "" ? 0 : -1;
268
- }
269
- else if (b[0] === "") {
270
- return 1;
271
- }
272
- return a[0].localeCompare(b[0]);
273
- });
288
+ return { global, named: lists.entries().toArray().sort((a, b) => a[0].localeCompare(b[0])) };
274
289
  }
275
290
  attachUniquePhase(compilation) {
276
291
  compilation.hooks.processAssets.tapPromise({ name: this.constructor.name, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_REPORT }, async () => {
@@ -1,7 +1,4 @@
1
- import DependencyExtractionWebpackPlugin from "@wordpress/dependency-extraction-webpack-plugin";
2
- import { Externals } from "../shared";
1
+ import type { Externals } from "../shared";
2
+ import { EnhancedDependencyExtractionWebpackPlugin } from "../wordpress-ports/dependency-extraction-webpack-plugin";
3
3
  import type { Configuration } from "webpack";
4
- export declare function makeDependencyExtractionPlugin(externals: Externals | undefined, assumeGlobalizedPlauditLibraries: boolean, wantsGroupedDepData: boolean, externalizing: Required<Configuration>['output']['library']): {
5
- instance: DependencyExtractionWebpackPlugin;
6
- addExternalizedDep: (dep: string) => void;
7
- };
4
+ export declare function makeDependencyExtractionPlugin(externals: Externals | undefined, assumeGlobalizedPlauditLibraries: boolean, externalizing: Required<Configuration>['output']['library']): EnhancedDependencyExtractionWebpackPlugin;
@@ -1,19 +1,10 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.makeDependencyExtractionPlugin = makeDependencyExtractionPlugin;
7
- const dependency_extraction_webpack_plugin_1 = __importDefault(require("@wordpress/dependency-extraction-webpack-plugin"));
8
- function makeDependencyExtractionPlugin(externals, assumeGlobalizedPlauditLibraries, wantsGroupedDepData, externalizing) {
9
- const baseProps = makeDependencyExtractionPluginProps(externals, assumeGlobalizedPlauditLibraries, externalizing);
10
- const instance = new dependency_extraction_webpack_plugin_1.default(wantsGroupedDepData ? { ...baseProps, outputFormat: "json", combineAssets: true } : baseProps);
11
- return {
12
- instance,
13
- addExternalizedDep: (dep) => {
14
- instance.externalizedDeps.add(dep);
15
- }
16
- };
4
+ const dependency_extraction_webpack_plugin_1 = require("../wordpress-ports/dependency-extraction-webpack-plugin");
5
+ const util_1 = require("../wordpress-ports/dependency-extraction-webpack-plugin/util");
6
+ function makeDependencyExtractionPlugin(externals, assumeGlobalizedPlauditLibraries, externalizing) {
7
+ return new dependency_extraction_webpack_plugin_1.EnhancedDependencyExtractionWebpackPlugin(makeDependencyExtractionPluginProps(externals, assumeGlobalizedPlauditLibraries, externalizing));
17
8
  }
18
9
  function makeDependencyExtractionPluginProps(externals, assumeGlobalizedPlauditLibraries, externalizing) {
19
10
  if (!externals) {
@@ -93,7 +84,7 @@ const EXTERNALIZABLE_PLAUDIT_LIBRARIES = {
93
84
  ...Object.fromEntries(['@plaudit/frontend-apis', '@plaudit/library-extensions', '@plaudit/block-supports', '@plaudit/gutenberg-api-extensions']
94
85
  .map(req => {
95
86
  return [req, {
96
- import: ['plaudit', camelCaseDash(req.substring(PLAUDIT_NAMESPACE.length))],
87
+ import: ['plaudit', (0, util_1.camelCaseDash)(req.substring(PLAUDIT_NAMESPACE.length))],
97
88
  handle: `plaudit-${req.substring(PLAUDIT_NAMESPACE.length)}`
98
89
  }];
99
90
  })),
@@ -116,12 +107,6 @@ function normalizeRequest(request) {
116
107
  function curryRequestHandlers(primary, secondary) {
117
108
  return (...args) => primary(...args) ?? secondary(...args);
118
109
  }
119
- /**
120
- * Copied from @wordpress/dependency-extraction-webpack-plugin for consistency
121
- */
122
- function camelCaseDash(string) {
123
- return string.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
124
- }
125
110
  function handleExternalizingEqualsPossibleExternal(possibleExternal, ext) {
126
111
  if (!ext || !possibleExternal) {
127
112
  return possibleExternal;
@@ -151,7 +136,9 @@ function handleExternalizingEqualsPossibleExternal(possibleExternal, ext) {
151
136
  }
152
137
  else {
153
138
  for (const key of ['amd', 'commonjs', 'root']) {
154
- if (key in ext && handleExternalizingEqualsPossibleExternal(possibleExternal, ext[key])) {
139
+ // The recursion returns the external when it should be kept and undefined when it matched, so
140
+ // only an undefined result means this umd name is the thing being built and must not externalize.
141
+ if (key in ext && handleExternalizingEqualsPossibleExternal(possibleExternal, ext[key]) === undefined) {
155
142
  return undefined;
156
143
  }
157
144
  }
package/dist/shared.d.ts CHANGED
@@ -5,17 +5,20 @@ import { type AssetInfo, type Compilation, type Configuration, type Entrypoint,
5
5
  import { SourceType } from "./utils/entrypoint-resolution-logic";
6
6
  import type { NormalizedEnqueuingControlFlags } from "./utils/path-query-and-related-helpers";
7
7
  export * from "./utils/entrypoint-resolution-logic";
8
- export type WPModuleDependency = {
8
+ export type WPModuleDependency = string | {
9
9
  id: string;
10
10
  import?: string;
11
11
  };
12
- export type ParsedAssetsJson = Record<string, {
13
- dependencies: string[];
12
+ export type ParsedAssetJson = {
13
+ dependencies: WPModuleDependency[];
14
+ module_dependencies?: WPModuleDependency[];
14
15
  version: string;
15
- module_dependencies?: (string | WPModuleDependency)[];
16
- }>;
16
+ type?: 'module';
17
+ handle?: string;
18
+ };
19
+ export type ParsedAssetsJson = Record<string, ParsedAssetJson>;
17
20
  export declare function isParsedAssetsJson(thing: any): thing is ParsedAssetsJson;
18
- type BaseRestType = [/* dependencies: */ string[], /* version: */ string];
21
+ type BaseRestType = [/* dependencies: */ WPModuleDependency[], /* version: */ string];
19
22
  export type AssetMetaSegment = {
20
23
  inlinedAsset: InlinedAsset;
21
24
  assetContents: string;
@@ -28,7 +31,7 @@ export type ScriptArgsObject = {
28
31
  strategy?: 'defer' | 'async';
29
32
  in_footer?: boolean;
30
33
  fetchpriority?: 'auto' | 'low' | 'high';
31
- module_dependencies?: (string | WPModuleDependency)[];
34
+ module_dependencies?: WPModuleDependency[];
32
35
  };
33
36
  export type InlinedAsset = {
34
37
  position?: 'before' | 'after';
@@ -118,7 +121,7 @@ export type AdvancedOutputConfig = {
118
121
  directoryLayout?: SourceType;
119
122
  assumeGlobalizedPlauditLibraries?: boolean;
120
123
  externalize?: Required<Configuration>['output']['library'];
121
- bundleAnalyzer?: boolean;
124
+ bundleAnalyzer?: boolean | 'no-auto-open';
122
125
  locations?: UsageLocations | UsageLocations['handle'];
123
126
  lazyLoader?: string;
124
127
  pathQueryParameters?: PathQueryParameters;
@@ -143,7 +146,6 @@ export type PlauditWordpressWebpackConfig = {
143
146
  externals?: Externals;
144
147
  assumeGlobalizedPlauditLibraries?: boolean;
145
148
  processTranslationConfigs?: boolean;
146
- combineAssetMetadata?: boolean;
147
149
  useWebpackResourceFiltering?: boolean;
148
150
  outputDir?: string;
149
151
  extensionsVersion?: 1 | 2 | 3;
@@ -170,7 +172,6 @@ export declare function applyStandards(config: PlauditWordpressWebpackConfig): {
170
172
  readonly externals?: Externals;
171
173
  readonly assumeGlobalizedPlauditLibraries?: boolean;
172
174
  readonly processTranslationConfigs?: boolean;
173
- readonly combineAssetMetadata?: boolean;
174
175
  useWebpackResourceFiltering?: boolean;
175
176
  outputDir?: string;
176
177
  extensionsVersion?: 1 | 2 | 3;
@@ -228,7 +229,7 @@ export declare const styleExtension: RegExp;
228
229
  export declare function scriptOrStyleTest(entryPath: string, scriptExtension: RegExp): "script" | "style" | "";
229
230
  export declare function isStyleField(field: string): field is 'style' | 'viewStyle' | 'editorStyle';
230
231
  export declare function isScriptModuleField(field: string): field is 'viewScriptModule';
231
- export declare function mergeModuleDependencyArrays(a: (string | WPModuleDependency)[] | undefined, b: (string | WPModuleDependency)[] | undefined): (string | WPModuleDependency)[] | undefined;
232
+ export declare function mergeModuleDependencyArrays(a: WPModuleDependency[] | undefined, b: WPModuleDependency[] | undefined): WPModuleDependency[] | undefined;
232
233
  export declare function getHandleGroup(field: string): 'styleHandles' | 'scriptHandles' | 'scriptModuleHandles';
233
234
  export type StripFirstTwoItems<A extends any[]> = A extends [any, any, ...rest: infer R] ? R : never;
234
235
  export declare function hasAtLeastOneItem<T>(list: T[]): list is [T, ...T[]];
@@ -254,7 +255,7 @@ export declare function getParsedAssetsJsonDataForEntrypoint(compilation: Compil
254
255
  assetData: ParsedAssetsJson[string];
255
256
  } | undefined;
256
257
  export declare function emitPHPWriterAsAsset(writer: PHPWriter, compilation: Compilation, file: string, assetInfo?: AssetInfo): void;
257
- export declare function dedent(text: TemplateStringsArray): string;
258
+ export declare function dedent(text: TemplateStringsArray, ...values: unknown[]): string;
258
259
  export declare function resolveLegacyBlockScriptsInFolder(folder: string): string[];
259
260
  /**
260
261
  * @param compilation
package/dist/shared.js CHANGED
@@ -85,7 +85,7 @@ exports.standardLocationNamesMeta = {
85
85
  analytics: { action: "plaudit_enqueue_analytics" },
86
86
  };
87
87
  function isStandardLocationName(name) {
88
- return name in exports.standardLocationNamesMeta;
88
+ return Object.hasOwn(exports.standardLocationNamesMeta, name);
89
89
  }
90
90
  function isRegisterScriptArgsShorthandName(name) {
91
91
  return ['lazy', 'eager', 'inline'].includes(name);
@@ -271,18 +271,10 @@ function emitResolveBaseUriFunction(writer) {
271
271
  }
272
272
  function getAssetsJson(compilation) {
273
273
  const asset = compilation.getAsset("assets.json");
274
- if (!asset) {
275
- throw new Error("assets.json is unexpectedly missing");
276
- }
277
- if (isParsedAssetsJson(asset.info["parsed-assets-json"])) {
274
+ if (asset && isParsedAssetsJson(asset.info["parsed-assets-json"])) {
278
275
  return asset.info["parsed-assets-json"];
279
276
  }
280
- const parsedAssetJson = JSON.parse(asset.source.source().toString('utf-8'));
281
- if (!isParsedAssetsJson(parsedAssetJson)) {
282
- throw new Error("assets.json is does not match the RawAssetData format");
283
- }
284
- compilation.updateAsset("assets.json", s => s, a => ({ ...a, "parsed-assets-json": parsedAssetJson }));
285
- return parsedAssetJson;
277
+ throw new Error("assets.json is unexpectedly missing");
286
278
  }
287
279
  function getParsedAssetsJsonDataForEntrypoint(compilation, entrypoint, metadata) {
288
280
  const dest = metadata.dest;
@@ -322,13 +314,24 @@ function emitPHPWriterAsAsset(writer, compilation, file, assetInfo) {
322
314
  const contents = writer.toString() + "\n";
323
315
  compilation[file in compilation.assets ? 'updateAsset' : 'emitAsset'](file, new webpack_1.sources.RawSource(contents), { size: Buffer.byteLength(contents), ...assetInfo });
324
316
  }
325
- function dedent(text) {
326
- const actualText = text.join("\n");
327
- const firstLineIndent = actualText.split("\r?\n").find(line => line.length > 0)?.match(/^\s+/)?.[0];
328
- if (!firstLineIndent) {
329
- return actualText;
317
+ function dedent(text, ...values) {
318
+ const lines = text.reduce((result, part, i) => result + String(values[i - 1]) + part).split(/\r?\n/);
319
+ // A template that opens and closes on its own line frames the content with two throwaway lines
320
+ if (lines[0]?.trim() === "") {
321
+ lines.shift();
322
+ }
323
+ if (lines.length > 1 && lines.at(-1)?.trim() === "") {
324
+ lines.pop();
330
325
  }
331
- return actualText.replaceAll(new RegExp("^" + firstLineIndent, 'mg'), "").replace(/\n{2}$/, "\n");
326
+ // Only the lines with content get a say in the indent, and a line break must never count as one
327
+ const indent = lines.filter(line => line.trim() !== "")
328
+ .reduce((shortest, line) => {
329
+ const lineIndent = /^[ \t]*/.exec(line)?.[0] ?? "";
330
+ return shortest === undefined || lineIndent.length < shortest.length ? lineIndent : shortest;
331
+ }, undefined);
332
+ return indent
333
+ ? lines.map(line => line.startsWith(indent) ? line.substring(indent.length) : line).join("\n")
334
+ : lines.join("\n");
332
335
  }
333
336
  function resolveLegacyBlockScriptsInFolder(folder) {
334
337
  const blockScriptEntrypoints = [];
@@ -233,7 +233,10 @@ function resolveEntryFromDirectory(commonConfig, srcRoot, dest) {
233
233
  const resolvedBlockEntrypoints = presentEntrypoints
234
234
  .map(presentEntrypoint => {
235
235
  const overallSource = (0, node_path_1.dirname)(blockJsonOrigin);
236
- const overallSourceRelativeName = (0, node_path_1.relative)(overallSource, (0, node_path_1.normalize)((0, node_path_1.join)(blockJsonOrigin, (0, node_path_1.relative)(overallSource, presentEntrypoint.extensionlessExpectedSrc))));
236
+ // The handle suffix is the asset's extensionless name relative to its own block, so it
237
+ // has to come off the real on-disk path rather than the destination-relative expected src.
238
+ const parsedAbsoluteSrc = (0, node_path_1.parse)(presentEntrypoint.absoluteSrc);
239
+ const overallSourceRelativeName = (0, node_path_1.normalize)((0, node_path_1.join)((0, node_path_1.relative)(overallSource, parsedAbsoluteSrc.dir), parsedAbsoluteSrc.name));
237
240
  const handleSuffix = (0, shared_1.convertUsageLocationsHandleToEmittableHandle)(dest.locations.handle, overallSourceRelativeName);
238
241
  const handleGroup = (0, shared_1.getHandleGroup)(presentEntrypoint.entrypointField);
239
242
  if (presentEntrypoint.handle) {
@@ -277,15 +280,15 @@ function resolveEntryFromDirectory(commonConfig, srcRoot, dest) {
277
280
  const packageJsonOrigin = (0, node_path_1.join)(dir, 'package.json');
278
281
  const packageJson = JSON.parse(await (0, promises_1.readFile)(packageJsonOrigin, 'utf8'));
279
282
  if (packageJson['main']) {
280
- rawEntrypoints.push(...mapToRealEntrypoints(packageJson['main'], dir, commonConfig.scriptExtension.test, { dest, entrypointJsonOrigin: packageJsonOrigin }));
283
+ rawEntrypoints.push(...mapToRealEntrypoints(packageJson['main'], dir, s => commonConfig.scriptExtension.test(s), { dest, entrypointJsonOrigin: packageJsonOrigin }));
281
284
  }
282
285
  if (!processingModules && packageJson['style']) {
283
- rawEntrypoints.push(...mapToRealEntrypoints(packageJson['style'], dir, shared_1.styleExtension.test, { dest, entrypointJsonOrigin: packageJsonOrigin }));
286
+ rawEntrypoints.push(...mapToRealEntrypoints(packageJson['style'], dir, s => shared_1.styleExtension.test(s), { dest, entrypointJsonOrigin: packageJsonOrigin }));
284
287
  }
285
288
  }
286
289
  catch (e) {
287
290
  try {
288
- rawEntrypoints.push(...parseEntrypointsJSON(dir, dest, ep => commonConfig.scriptExtension.test(ep) || shared_1.styleExtension.test(ep)));
291
+ rawEntrypoints.push(...parseEntrypointsJSON(dir, dest, ep => commonConfig.scriptExtension.test(ep) || (!processingModules && shared_1.styleExtension.test(ep))));
289
292
  }
290
293
  catch (e) {
291
294
  // This just means that the directory doesn't contain any declared entrypoints.
@@ -9,7 +9,7 @@ function convertToCSS(writableCSSObject, pretty = true) {
9
9
  return convertToCSSPretty(writableCSSObject, "");
10
10
  }
11
11
  else {
12
- return convertToCSS(writableCSSObject);
12
+ return convertToCSSUgly(writableCSSObject);
13
13
  }
14
14
  }
15
15
  function convertToCSSPretty(writableCSSObject, indentation) {
@@ -23,7 +23,7 @@ function convertToCSSPretty(writableCSSObject, indentation) {
23
23
  }
24
24
  else {
25
25
  res += " {\n";
26
- res += convertToCSSPretty(writableCSSObject, indentation + "\t");
26
+ res += convertToCSSPretty(value, indentation + "\t");
27
27
  res += indentation + "}\n";
28
28
  }
29
29
  }
@@ -39,7 +39,7 @@ function convertToCSSUgly(writableCSSObject) {
39
39
  res += `:${value};`;
40
40
  }
41
41
  else {
42
- res += "{" + convertToCSSUgly(writableCSSObject) + "}";
42
+ res += "{" + convertToCSSUgly(value) + "}";
43
43
  }
44
44
  }
45
45
  return res;
@@ -84,7 +84,7 @@ function parseLocationEncodingFilenameForBlock(filename, errorBuilder = shared_1
84
84
  const parsedFilename = parseLocationEncodingFilename(filename);
85
85
  if (parsedFilename !== undefined) {
86
86
  if ((0, shared_1.constantKeys)(parsedFilename.locations).some(value => value !== 'clientView' && value !== 'clientEditor')) {
87
- throw errorBuilder(`Block assets cannot be enqueued anywhere other than view, editor, or both. Saw: ${(0, shared_1.constantKeys)(parsedFilename).join(", ")}`, filename);
87
+ throw errorBuilder(`Block assets cannot be enqueued anywhere other than view, editor, or both. Saw: ${(0, shared_1.constantKeys)(parsedFilename.locations).join(", ")}`, filename);
88
88
  }
89
89
  if (Object.values(parsedFilename.locations).some(value => typeof value === 'number')) {
90
90
  throw errorBuilder(`Block assets cannot be enqueued with a priority`, filename);
@@ -15,7 +15,6 @@ export declare function unpackPotentiallyPrefixedFilePath(filePath: string): [st
15
15
  */
16
16
  export declare function unpackPathQuery(pathQuery: string): PathQueryParameters | undefined;
17
17
  export type LoadingStrategy = boolean | 'defer' | 'async' | 'eager' | 'lazy' | 'inline';
18
- export declare function isValidLoadingStrategy(strategy: any): strategy is LoadingStrategy | undefined;
19
18
  export declare function newInvalidLoadingStrategyError(strategy: unknown, file: string): import("webpack").WebpackError;
20
19
  export type InFooter = boolean;
21
20
  export declare function isValidInFooter(in_footer: unknown): in_footer is InFooter;
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getAssetFileContents = getAssetFileContents;
4
4
  exports.unpackPotentiallyPrefixedFilePath = unpackPotentiallyPrefixedFilePath;
5
5
  exports.unpackPathQuery = unpackPathQuery;
6
- exports.isValidLoadingStrategy = isValidLoadingStrategy;
7
6
  exports.newInvalidLoadingStrategyError = newInvalidLoadingStrategyError;
8
7
  exports.isValidInFooter = isValidInFooter;
9
8
  exports.newInvalidInFooterError = newInvalidInFooterError;
@@ -78,9 +77,6 @@ function unpackPathQuery(pathQuery) {
78
77
  }, {});
79
78
  }
80
79
  const namedStrategies = ['defer', 'async', 'eager', 'lazy', 'inline'];
81
- function isValidLoadingStrategy(strategy) {
82
- return strategy === undefined || (typeof strategy === 'string' && namedStrategies.includes(strategy));
83
- }
84
80
  function newInvalidLoadingStrategyError(strategy, file) {
85
81
  return (0, shared_1.newWebpackErrorForFile)(`The strategy was invalid. Received: ${strategy}, Expected: undefined|boolean|'${namedStrategies.join("'|'")}'`, file);
86
82
  }