@plaudit/webpack-extensions 2.62.3 → 2.63.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.
@@ -0,0 +1,19 @@
1
+ import { PseudoSemaphore } from "../utils/pseduo-semaphore";
2
+ import type { ExtensibleEntryObject } from "../utils/common-config-helpers";
3
+ import { AbstractMultiPhaseLibraryPlugin } from "./AbstractMultiPhaseLibraryPlugin";
4
+ import { Compilation, Compiler, Entrypoint } from "webpack";
5
+ export type EntryProvider<M> = () => ExtensibleEntryObject<M> | Promise<ExtensibleEntryObject<M>>;
6
+ export declare abstract class AbstractMultiPhaseLibraryAndEntryPlugin<M> extends AbstractMultiPhaseLibraryPlugin {
7
+ private readonly context;
8
+ private readonly entry;
9
+ protected readonly entryMetadataRecord: {
10
+ [entryName: string]: M;
11
+ };
12
+ protected constructor(libraryType: string, semaphores: PseudoSemaphore<any>[], context: string, entry: EntryProvider<M>);
13
+ apply(compiler: Compiler): void;
14
+ protected getRelevantEntrypoints(compilation: Compilation): {
15
+ entrypoint: Entrypoint;
16
+ srcPath: string;
17
+ metadata: M;
18
+ }[];
19
+ }
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbstractMultiPhaseLibraryAndEntryPlugin = void 0;
4
+ const AbstractMultiPhaseLibraryPlugin_1 = require("./AbstractMultiPhaseLibraryPlugin");
5
+ const webpack_1 = require("webpack");
6
+ class AbstractMultiPhaseLibraryAndEntryPlugin extends AbstractMultiPhaseLibraryPlugin_1.AbstractMultiPhaseLibraryPlugin {
7
+ context;
8
+ entry;
9
+ entryMetadataRecord = {};
10
+ constructor(libraryType, semaphores, context, entry) {
11
+ super(libraryType, semaphores);
12
+ this.context = context;
13
+ this.entry = entry;
14
+ }
15
+ apply(compiler) {
16
+ super.apply(compiler);
17
+ compiler.hooks.compilation.tap(this.constructor.name, (compilation, { normalModuleFactory }) => {
18
+ const dummyEntry = webpack_1.EntryPlugin.createDependency("", "");
19
+ compilation.dependencyFactories.set(dummyEntry.constructor, normalModuleFactory);
20
+ });
21
+ compiler.hooks.make.tapPromise(this.constructor.name, async (compilation) => {
22
+ const entry = await this.entry();
23
+ const promises = [];
24
+ for (const [name, { plauditMetadata, ...desc }] of Object.entries(entry)) {
25
+ const options = webpack_1.EntryOptionPlugin.entryDescriptionToOptions(compiler, name, desc);
26
+ this.entryMetadataRecord[name] = plauditMetadata;
27
+ for (const entry of desc.import) {
28
+ promises.push(new Promise((resolve, reject) => {
29
+ compilation.addEntry(this.context, webpack_1.EntryPlugin.createDependency(entry, options), options, err => {
30
+ if (err) {
31
+ return reject(err);
32
+ }
33
+ resolve();
34
+ });
35
+ }));
36
+ }
37
+ }
38
+ await Promise.all(promises);
39
+ });
40
+ }
41
+ getRelevantEntrypoints(compilation) {
42
+ return compilation.entrypoints.values()
43
+ .map(entrypoint => {
44
+ const name = entrypoint.name;
45
+ if (!name) {
46
+ return undefined;
47
+ }
48
+ const metadata = this.entryMetadataRecord[name];
49
+ if (metadata === undefined) {
50
+ return undefined;
51
+ }
52
+ const srcPath = entrypoint.origins[0]?.request;
53
+ if (!srcPath) {
54
+ return undefined;
55
+ }
56
+ return { entrypoint, srcPath, metadata };
57
+ })
58
+ .filter(item => item !== undefined)
59
+ .toArray();
60
+ }
61
+ }
62
+ exports.AbstractMultiPhaseLibraryAndEntryPlugin = AbstractMultiPhaseLibraryAndEntryPlugin;
@@ -11,10 +11,4 @@ export declare abstract class AbstractMultiPhaseLibraryPlugin implements Webpack
11
11
  apply(compiler: Compiler): void;
12
12
  protected resetSemaphores(): void;
13
13
  protected abstract attachSecondPhase(compilation: Compilation): void;
14
- protected getRelevantEntrypoints(compilation: Compilation): {
15
- entrypoint: import("webpack").Entrypoint;
16
- entrypointChunk: import("webpack").Chunk;
17
- entrypointLibrary: import("webpack").LibraryOptions;
18
- srcPath: string;
19
- }[];
20
14
  }
@@ -27,79 +27,11 @@ class AbstractMultiPhaseLibraryPlugin {
27
27
  }
28
28
  });
29
29
  });
30
- // compiler.hooks.compilation.tap(
31
- // this.constructor.name,
32
- // (compilation, { normalModuleFactory }) => {
33
- // const dummyEntry = EntryPlugin.createDependency("", "");
34
- // compilation.dependencyFactories.set(
35
- // dummyEntry.constructor as any,
36
- // normalModuleFactory
37
- // );
38
- // }
39
- // );
40
- //
41
- // compiler.hooks.make.tapPromise(this.constructor.name, (compilation) =>
42
- // Promise.resolve(this.entry())
43
- // .then((entry) => {
44
- // const promises = [];
45
- // for (const name of Object.keys(entry)) {
46
- // const desc = entry[name];
47
- // const options = EntryOptionPlugin.entryDescriptionToOptions(
48
- // compiler,
49
- // name,
50
- // desc
51
- // );
52
- // for (const entry of /** @type {NonNullable<EntryDescriptionNormalized["import"]>} */ (
53
- // desc.import
54
- // )) {
55
- // promises.push(
56
- // new Promise(
57
- // /**
58
- // * @param {(value?: undefined) => void} resolve resolve
59
- // * @param {(reason?: Error) => void} reject reject
60
- // */
61
- // (resolve, reject) => {
62
- // compilation.addEntry(
63
- // this.context,
64
- // EntryPlugin.createDependency(entry, options),
65
- // options,
66
- // (err) => {
67
- // if (err) return reject(err);
68
- // resolve();
69
- // }
70
- // );
71
- // }
72
- // )
73
- // );
74
- // }
75
- // }
76
- // return Promise.all(promises);
77
- // })
78
- // .then(() => {})
79
- // );
80
30
  }
81
- // protected abstract generateEntries(compiler: Compiler, context: string, entry: EntryStaticNormalized): void;
82
31
  resetSemaphores() {
83
32
  for (const semaphore of this.semaphores) {
84
33
  semaphore.reset(this.id);
85
34
  }
86
35
  }
87
- getRelevantEntrypoints(compilation) {
88
- return compilation.entrypoints.values()
89
- .map(entrypoint => {
90
- const entrypointChunk = entrypoint.getEntrypointChunk();
91
- const entrypointLibrary = entrypointChunk.getEntryOptions()?.library;
92
- if (entrypointLibrary?.type !== this.libraryType) {
93
- return undefined;
94
- }
95
- const srcPath = entrypoint.origins[0]?.request;
96
- if (!srcPath) {
97
- return undefined;
98
- }
99
- return { entrypoint, entrypointChunk, entrypointLibrary, srcPath };
100
- })
101
- .filter(item => item !== undefined)
102
- .toArray();
103
- }
104
36
  }
105
37
  exports.AbstractMultiPhaseLibraryPlugin = AbstractMultiPhaseLibraryPlugin;
@@ -1,14 +1,15 @@
1
+ import { AbstractMultiPhaseLibraryAndEntryPlugin, EntryProvider } from "./AbstractMultiPhaseLibraryAndEntryPlugin";
2
+ import { UnpackedBlockEntrypointInfo, VerifiedAdvancedOutputConfig } from "../shared";
1
3
  import type { VerifiedPlauditWordpressWebpackConfig } from "../utils/common-config-helpers";
2
4
  import { Compilation, type Compiler } from "webpack";
3
- import { AbstractMultiPhaseLibraryPlugin } from "./AbstractMultiPhaseLibraryPlugin";
4
- export declare class ExtensionsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryPlugin {
5
+ export declare class ExtensionsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryAndEntryPlugin<UnpackedBlockEntrypointInfo | string> {
5
6
  private readonly config;
6
7
  private readonly extensionsPath;
7
- private readonly extensionsDest;
8
+ private readonly dest;
8
9
  private static readonly semaphore;
9
- constructor(config: VerifiedPlauditWordpressWebpackConfig, extensionsPath: string, extensionsDest: string);
10
+ private static readonly perLibraryTypeSetupFilePaths;
11
+ constructor(config: VerifiedPlauditWordpressWebpackConfig, extensionsPath: string, dest: VerifiedAdvancedOutputConfig, context: string, entry: EntryProvider<UnpackedBlockEntrypointInfo | string>);
10
12
  apply(compiler: Compiler): void;
11
13
  private generateVersionTwoConfigFile;
12
- private stripExtensionsDest;
13
14
  protected attachSecondPhase(compilation: Compilation): void;
14
15
  }
@@ -6,22 +6,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ExtensionsConfigFileGeneratorPlugin = void 0;
7
7
  const promises_1 = __importDefault(require("node:fs/promises"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
+ const AbstractMultiPhaseLibraryAndEntryPlugin_1 = require("./AbstractMultiPhaseLibraryAndEntryPlugin");
9
10
  const UnifiedLoaderGenerator_1 = require("./UnifiedLoaderGenerator");
10
11
  const shared_1 = require("../shared");
11
12
  const php_writer_1 = require("../utils/php-writer");
12
13
  const pseduo_semaphore_1 = require("../utils/pseduo-semaphore");
13
14
  const webpack_1 = require("webpack");
14
- const AbstractMultiPhaseLibraryPlugin_1 = require("./AbstractMultiPhaseLibraryPlugin");
15
- class ExtensionsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryPlugin_1.AbstractMultiPhaseLibraryPlugin {
15
+ class ExtensionsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryAndEntryPlugin_1.AbstractMultiPhaseLibraryAndEntryPlugin {
16
16
  config;
17
17
  extensionsPath;
18
- extensionsDest;
18
+ dest;
19
19
  static semaphore = new pseduo_semaphore_1.PseudoSemaphore({ libraryType: "", assets: [], setupFiles: [] }, "Extensions");
20
- constructor(config, extensionsPath, extensionsDest) {
21
- super(`extensions-v2-${extensionsDest}`, [ExtensionsConfigFileGeneratorPlugin.semaphore, UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore]);
20
+ static perLibraryTypeSetupFilePaths = {};
21
+ constructor(config, extensionsPath, dest, context, entry) {
22
+ super(`extensions-v2-${dest.destination}`, [ExtensionsConfigFileGeneratorPlugin.semaphore, UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore], context, entry);
22
23
  this.config = config;
23
24
  this.extensionsPath = extensionsPath;
24
- this.extensionsDest = extensionsDest;
25
+ this.dest = dest;
25
26
  }
26
27
  apply(compiler) {
27
28
  super.apply(compiler);
@@ -30,16 +31,19 @@ class ExtensionsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryPlugi
30
31
  compilation.contextDependencies.add(this.extensionsPath);
31
32
  }
32
33
  const emissionPromises = [];
33
- for (const setupFilePath of await promises_1.default.readdir(this.extensionsPath)) {
34
+ for await (const { name: setupFilePath } of await promises_1.default.opendir(this.extensionsPath, { encoding: 'utf-8' })) {
34
35
  if (setupFilePath.endsWith("-setup.php")) {
35
36
  const setupFileSourcePath = node_path_1.default.join(this.extensionsPath, setupFilePath);
36
37
  compilation.fileDependencies.add(setupFileSourcePath);
37
38
  emissionPromises.push(promises_1.default.readFile(setupFileSourcePath).then(contents => {
38
- return compilation.emitAsset(node_path_1.default.join(this.extensionsDest, setupFilePath), new webpack_1.sources.RawSource(contents), { size: Buffer.byteLength(contents) });
39
+ compilation.emitAsset(node_path_1.default.join(this.dest.destination, setupFilePath), new webpack_1.sources.RawSource(contents), { size: Buffer.byteLength(contents) });
40
+ const blockSlug = /^(.+?)-setup.php$/i.exec(setupFilePath)?.[1];
41
+ return [blockSlug, setupFilePath];
39
42
  }));
40
43
  }
41
44
  }
42
- await Promise.all(emissionPromises);
45
+ ExtensionsConfigFileGeneratorPlugin.perLibraryTypeSetupFilePaths[this.libraryType] = (await Promise.all(emissionPromises))
46
+ .filter((item) => item[0] !== undefined).sort((a, b) => a[0].localeCompare(b[0]));
43
47
  });
44
48
  compiler.hooks.compilation.tap(this.constructor.name, compilation => {
45
49
  compilation.hooks.processAssets.tapPromise({ name: this.constructor.name, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_ANALYSE, additionalAssets: true }, async (assets) => {
@@ -49,15 +53,8 @@ class ExtensionsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryPlugi
49
53
  try {
50
54
  //TODO: It should be possible to use EntryPoints to determine the "original" file
51
55
  //TODO: There is no reason to not use basically the exact same logic to implement support for this in plain file contexts
52
- const myCacheData = { libraryType: this.libraryType, assets: [], setupFiles: [] };
53
- //TODO: Load up the -setup.php files as "entrypoints" in the same way that we're loading up block.json files
54
- // That way, we'll be able to distinguish which ones go where
55
- for (const asset of Object.keys(compilation.assets).map(asset => this.stripExtensionsDest(asset))) {
56
- const blockSlug = /^(.+?)-setup.php$/i.exec(asset)?.[1];
57
- if (blockSlug) {
58
- myCacheData.setupFiles.push([blockSlug, asset]);
59
- }
60
- }
56
+ const myCacheData = { libraryType: this.libraryType, assets: [],
57
+ setupFiles: ExtensionsConfigFileGeneratorPlugin.perLibraryTypeSetupFilePaths[this.libraryType] ?? [] };
61
58
  const rawAssetDataSource = assets["assets.json"]?.source();
62
59
  if (typeof rawAssetDataSource !== 'string') {
63
60
  ExtensionsConfigFileGeneratorPlugin.semaphore.reject(this.id);
@@ -72,8 +69,8 @@ class ExtensionsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryPlugi
72
69
  }
73
70
  const relevantAssetData = {};
74
71
  const relevantEntrypoints = this.getRelevantEntrypoints(compilation);
75
- for (const { entrypointChunk, srcPath } of relevantEntrypoints) {
76
- const fileWithAssetData = entrypointChunk.files.values().find(file => assetDataSource[file]);
72
+ for (const { entrypoint, srcPath } of relevantEntrypoints) {
73
+ const fileWithAssetData = entrypoint.getEntrypointChunk().files.values().find(file => assetDataSource[file]);
77
74
  if (!fileWithAssetData) {
78
75
  compilation.errors.push((0, shared_1.newWebpackErrorForFile)(`assets.json did not contain information for ${srcPath}`, srcPath));
79
76
  continue;
@@ -87,22 +84,40 @@ class ExtensionsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryPlugi
87
84
  group: this.libraryType,
88
85
  requiresBaseURI: true,
89
86
  action: writer => {
90
- let finalExtensionsDest = this.extensionsDest.endsWith("/") ? this.extensionsDest : this.extensionsDest + "/";
91
- if (!finalExtensionsDest.startsWith("/")) {
92
- finalExtensionsDest = "/" + finalExtensionsDest;
87
+ const generateLoader = (writer) => {
88
+ let finalExtensionsDest = this.dest.destination.endsWith("/") ? this.dest.destination : this.dest.destination + "/";
89
+ if (!finalExtensionsDest.startsWith("/")) {
90
+ finalExtensionsDest = "/" + finalExtensionsDest;
91
+ }
92
+ const filePathPrefixVar = new php_writer_1.Var("filePathPrefix");
93
+ const fileUriPrefixVar = new php_writer_1.Var("fileUriPrefix");
94
+ writer
95
+ .assign(filePathPrefixVar, new php_writer_1.Literal(`__DIR__.${php_writer_1.Expr.convertJsonToPHP(finalExtensionsDest)}`))
96
+ .call("plaudit_webpack_extensions__resolve_base_uri", [filePathPrefixVar], { assignTo: fileUriPrefixVar })
97
+ .call("GutenbergUtils::loadExtensionsV2", [
98
+ new php_writer_1.Literal(`__DIR__.${php_writer_1.Expr.convertJsonToPHP(finalExtensionsDest + "mapping.config.php")}`),
99
+ filePathPrefixVar, fileUriPrefixVar,
100
+ `${this.config.plainEntrypointsHandlePrefix || node_path_1.default.basename(process.cwd())}_extension_`
101
+ ]);
102
+ };
103
+ writer.use("Plaudit\\Common\\Lib\\GutenbergUtils");
104
+ const potentialHandle = this.dest.locations?.handle;
105
+ if (potentialHandle) {
106
+ if (typeof potentialHandle === 'string') {
107
+ try {
108
+ //TODO: Generate a function
109
+ writer.function(potentialHandle, [], generateLoader, { returnType: 'void' });
110
+ return;
111
+ }
112
+ catch (e) {
113
+ compilation.errors.push((0, shared_1.newWebpackErrorForFile)(["An error occurred while emitting a function for dynamically loading extensions", { cause: e }], this.extensionsPath));
114
+ }
115
+ }
116
+ else {
117
+ compilation.errors.push(new Error("The extensions directoryLayout's handle support is limited to static strings"));
118
+ }
93
119
  }
94
- const filePathPrefixVar = new php_writer_1.Var("filePathPrefix");
95
- const fileUriPrefixVar = new php_writer_1.Var("fileUriPrefix");
96
- writer
97
- .use("Plaudit\\Common\\Lib\\GutenbergUtils")
98
- .withScope(writer => writer
99
- .assign(filePathPrefixVar, new php_writer_1.Literal(`__DIR__.${php_writer_1.Expr.convertJsonToPHP(finalExtensionsDest)}`))
100
- .call("plaudit_webpack_extensions__resolve_base_uri", [filePathPrefixVar], { assignTo: fileUriPrefixVar })
101
- .call("GutenbergUtils::loadExtensionsV2", [
102
- new php_writer_1.Literal(`__DIR__.${php_writer_1.Expr.convertJsonToPHP(finalExtensionsDest + "mapping.config.php")}`),
103
- filePathPrefixVar, fileUriPrefixVar,
104
- `${this.config.plainEntrypointsHandlePrefix || node_path_1.default.basename(process.cwd())}_extension_`
105
- ]));
120
+ writer.withScope(generateLoader);
106
121
  }
107
122
  } : undefined);
108
123
  }
@@ -126,8 +141,8 @@ class ExtensionsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryPlugi
126
141
  for (const assetDataSource of combinedExtensionData.assets) {
127
142
  const normalizedAssetData = Object.entries(assetDataSource)
128
143
  .map(entry => {
129
- const assetPath = this.extensionsDest && entry[0].startsWith(this.extensionsDest + "/")
130
- ? entry[0].substring(this.extensionsDest.length + 1) : entry[0];
144
+ const assetPath = this.dest.destination && entry[0].startsWith(this.dest.destination + "/")
145
+ ? entry[0].substring(this.dest.destination.length + 1) : entry[0];
131
146
  return [assetPath, entry[1]];
132
147
  });
133
148
  for (const [assetPath, assetData] of normalizedAssetData) {
@@ -168,10 +183,7 @@ class ExtensionsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryPlugi
168
183
  return [block[0], Object.fromEntries(Object.entries(block[1]).toSorted(([a], [b]) => a.localeCompare(b)))];
169
184
  })
170
185
  .toSorted(([a], [b]) => a.localeCompare(b)));
171
- compilation.emitAsset(node_path_1.default.join(this.extensionsDest, "mapping.config.php"), new webpack_1.sources.RawSource((0, shared_1.makeEmittableConfigPHP)(blockExtensionsConfig, true)));
172
- }
173
- stripExtensionsDest(item) {
174
- return this.extensionsDest && item.startsWith(this.extensionsDest + "/") ? item.substring(this.extensionsDest.length + 1 /* we also need to drop the "/" */) : item;
186
+ compilation.emitAsset(node_path_1.default.join(this.dest.destination, "mapping.config.php"), new webpack_1.sources.RawSource((0, shared_1.makeEmittableConfigPHP)(blockExtensionsConfig, true)));
175
187
  }
176
188
  attachSecondPhase(compilation) {
177
189
  compilation.hooks.processAssets.tapPromise({ name: `${this.constructor.name}_GenerateConfigFile`, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_REPORT }, async () => {
@@ -1,14 +1,14 @@
1
- import { UsageLocations } from "../shared";
2
- import { AbstractMultiPhaseLibraryPlugin } from "./AbstractMultiPhaseLibraryPlugin";
1
+ import { UnpackedBlockEntrypointInfo, UsageLocations } from "../shared";
2
+ import { AbstractMultiPhaseLibraryAndEntryPlugin, EntryProvider } from "./AbstractMultiPhaseLibraryAndEntryPlugin";
3
3
  import { Compilation, type Compiler } from "webpack";
4
- export declare class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryPlugin {
4
+ export declare class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryAndEntryPlugin<UnpackedBlockEntrypointInfo | string> {
5
5
  private readonly buildRoot;
6
6
  private readonly outputDir;
7
7
  private readonly usageLocations;
8
8
  private readonly handlePrefix;
9
9
  private readonly useUnifiedLoader;
10
10
  private static readonly semaphore;
11
- constructor(buildRoot: string, outputDir: string, usageLocations: UsageLocations, handlePrefix: string, useUnifiedLoader: boolean);
11
+ constructor(buildRoot: string, outputDir: string, usageLocations: UsageLocations, handlePrefix: string, useUnifiedLoader: boolean, context: string, entry: EntryProvider<UnpackedBlockEntrypointInfo | string>);
12
12
  apply(compiler: Compiler): void;
13
13
  private generatePlainEntrypointsLoader;
14
14
  private static addHandlesToHandleLists;
@@ -8,18 +8,18 @@ const node_path_1 = __importDefault(require("node:path"));
8
8
  const shared_1 = require("../shared");
9
9
  const php_writer_1 = require("../utils/php-writer");
10
10
  const pseduo_semaphore_1 = require("../utils/pseduo-semaphore");
11
- const AbstractMultiPhaseLibraryPlugin_1 = require("./AbstractMultiPhaseLibraryPlugin");
11
+ const AbstractMultiPhaseLibraryAndEntryPlugin_1 = require("./AbstractMultiPhaseLibraryAndEntryPlugin");
12
12
  const UnifiedLoaderGenerator_1 = require("./UnifiedLoaderGenerator");
13
13
  const webpack_1 = require("webpack");
14
- class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryPlugin_1.AbstractMultiPhaseLibraryPlugin {
14
+ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibraryAndEntryPlugin_1.AbstractMultiPhaseLibraryAndEntryPlugin {
15
15
  buildRoot;
16
16
  outputDir;
17
17
  usageLocations;
18
18
  handlePrefix;
19
19
  useUnifiedLoader;
20
20
  static semaphore = new pseduo_semaphore_1.PseudoSemaphore([], "Plain");
21
- constructor(buildRoot, outputDir, usageLocations, handlePrefix, useUnifiedLoader) {
22
- super("plain-entrypoints-v2", [PlainEntrypointsConfigFileGeneratorPlugin.semaphore, UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore]);
21
+ constructor(buildRoot, outputDir, usageLocations, handlePrefix, useUnifiedLoader, context, entry) {
22
+ super("plain-entrypoints-v2", [PlainEntrypointsConfigFileGeneratorPlugin.semaphore, UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore], context, entry);
23
23
  this.buildRoot = buildRoot;
24
24
  this.outputDir = outputDir;
25
25
  this.usageLocations = usageLocations;
@@ -48,11 +48,7 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibrar
48
48
  }
49
49
  const isScriptRegex = /\.m?[jt]sx?(\?|$)/i;
50
50
  const myAssetHandles = [];
51
- for (const entrypoint of compilation.entrypoints.values()) {
52
- const srcPath = entrypoint.origins.map(origin => origin.request)[0];
53
- if (!srcPath) {
54
- continue;
55
- }
51
+ for (const { entrypoint, srcPath } of this.getRelevantEntrypoints(compilation)) {
56
52
  const entrypointChunk = entrypoint.getEntrypointChunk();
57
53
  const assetData = entrypointChunk.files.values()
58
54
  .map(file => assetDataSource[file]).find(v => v !== undefined);
@@ -84,7 +80,6 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibrar
84
80
  }
85
81
  myAssetHandles.push({
86
82
  handles,
87
- usageLocations: this.usageLocations,
88
83
  handlePrefix: this.handlePrefix
89
84
  });
90
85
  }
@@ -126,15 +121,15 @@ class PlainEntrypointsConfigFileGeneratorPlugin extends AbstractMultiPhaseLibrar
126
121
  const plainEntrypointsConfig = { scriptHandles: {}, script_moduleHandles: {}, styleHandles: {} };
127
122
  for (const { handles, handlePrefix } of assets) {
128
123
  for (const { src, rest, locations, type, handleName } of handles) {
124
+ const basename = node_path_1.default.basename(src).replace(/_(?:script(?:-\d+)?\.js|style(?:-\d+)?\.css)$|(?<!_(script|style))\.(js|css)$/, "");
129
125
  let finalHandleName;
130
- if (handleName) {
131
- finalHandleName = handleName;
126
+ if (typeof handleName === 'string') {
127
+ finalHandleName = (0, shared_1.convertUsageLocationsHandleToEmittableHandle)(handleName, basename);
132
128
  }
133
129
  else {
134
- const basename = node_path_1.default.basename(src).replace(/_(?:script(?:-\d+)?\.js|style(?:-\d+)?\.css)$|(?<!_(script|style))\.(js|css)$/, "");
135
130
  const baseFinalHandleName = `${handlePrefix}.${(0, shared_1.kebabCase)(basename)}`;
136
131
  const handleNameMap = usedHandleNames[type];
137
- finalHandleName = baseFinalHandleName;
132
+ finalHandleName = (0, shared_1.convertUsageLocationsHandleToEmittableHandle)(handleName, basename);
138
133
  for (let count = 0; finalHandleName in handleNameMap && handleNameMap[finalHandleName] !== src;) {
139
134
  finalHandleName = `${baseFinalHandleName}-${++count}`;
140
135
  }
@@ -1,13 +1,14 @@
1
- import { AbstractMultiPhaseLibraryPlugin } from "./AbstractMultiPhaseLibraryPlugin";
1
+ import { AbstractMultiPhaseLibraryAndEntryPlugin, EntryProvider } from "./AbstractMultiPhaseLibraryAndEntryPlugin";
2
+ import { UnpackedBlockEntrypointInfo } from "../shared";
2
3
  import type { VerifiedPlauditWordpressWebpackConfig } from "../utils/common-config-helpers";
3
4
  import { Compilation, type Compiler } from "webpack";
4
5
  import type WebpackRemoveEmptyScriptsPlugin from "webpack-remove-empty-scripts";
5
- export declare class PlainEntrypointsStyleBlockJSONPlugin extends AbstractMultiPhaseLibraryPlugin {
6
+ export declare class PlainEntrypointsStyleBlockJSONPlugin extends AbstractMultiPhaseLibraryAndEntryPlugin<UnpackedBlockEntrypointInfo | string> {
6
7
  private readonly config;
7
8
  private readonly blocksDest;
8
9
  private readonly webpackRemoveEmptyScriptsPlugin;
9
10
  private static readonly semaphore;
10
- constructor(config: VerifiedPlauditWordpressWebpackConfig, blocksDest: string, webpackRemoveEmptyScriptsPlugin: WebpackRemoveEmptyScriptsPlugin);
11
+ constructor(config: VerifiedPlauditWordpressWebpackConfig, blocksDest: string, webpackRemoveEmptyScriptsPlugin: WebpackRemoveEmptyScriptsPlugin, context: string, entry: EntryProvider<UnpackedBlockEntrypointInfo | string>);
11
12
  apply(compiler: Compiler): void;
12
13
  private emitBlockLoaderFile;
13
14
  private transformBlocks;
@@ -7,20 +7,20 @@ exports.PlainEntrypointsStyleBlockJSONPlugin = void 0;
7
7
  const node_crypto_1 = __importDefault(require("node:crypto"));
8
8
  const node_fs_1 = __importDefault(require("node:fs"));
9
9
  const node_path_1 = __importDefault(require("node:path"));
10
- const AbstractMultiPhaseLibraryPlugin_1 = require("./AbstractMultiPhaseLibraryPlugin");
10
+ const AbstractMultiPhaseLibraryAndEntryPlugin_1 = require("./AbstractMultiPhaseLibraryAndEntryPlugin");
11
11
  const UnifiedLoaderGenerator_1 = require("./UnifiedLoaderGenerator");
12
12
  const shared_1 = require("../shared");
13
13
  const php_writer_1 = require("../utils/php-writer");
14
14
  const pseduo_semaphore_1 = require("../utils/pseduo-semaphore");
15
15
  const webpack_1 = require("webpack");
16
16
  const promises_1 = __importDefault(require("node:fs/promises"));
17
- class PlainEntrypointsStyleBlockJSONPlugin extends AbstractMultiPhaseLibraryPlugin_1.AbstractMultiPhaseLibraryPlugin {
17
+ class PlainEntrypointsStyleBlockJSONPlugin extends AbstractMultiPhaseLibraryAndEntryPlugin_1.AbstractMultiPhaseLibraryAndEntryPlugin {
18
18
  config;
19
19
  blocksDest;
20
20
  webpackRemoveEmptyScriptsPlugin;
21
21
  static semaphore = new pseduo_semaphore_1.PseudoSemaphore({ collatableWorkableBlockInfo: {}, blocksDest: "", emittingWpmlXml: false }, "Block JSON v3");
22
- constructor(config, blocksDest, webpackRemoveEmptyScriptsPlugin) {
23
- super(`block-json-${blocksDest}`, [PlainEntrypointsStyleBlockJSONPlugin.semaphore, UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore]);
22
+ constructor(config, blocksDest, webpackRemoveEmptyScriptsPlugin, context, entry) {
23
+ super(`block-json-${blocksDest}`, [PlainEntrypointsStyleBlockJSONPlugin.semaphore, UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore], context, entry);
24
24
  this.config = config;
25
25
  this.blocksDest = blocksDest;
26
26
  this.webpackRemoveEmptyScriptsPlugin = webpackRemoveEmptyScriptsPlugin;
@@ -46,23 +46,18 @@ class PlainEntrypointsStyleBlockJSONPlugin extends AbstractMultiPhaseLibraryPlug
46
46
  return;
47
47
  }
48
48
  const applicableBlockJsonFiles = {};
49
- compilation.modules.values()
50
- .filter(mod => mod.type === 'json')
51
- .flatMap(mod => compilation.chunkGraph.getModuleChunks(mod))
52
- .filter(chunk => {
53
- const entryOptions = chunk.getEntryOptions();
54
- return entryOptions?.library?.type === this.libraryType && entryOptions.library.name === "block-json-inclusion-assurance";
55
- })
56
- .flatMap(chunk => chunk.files.values().toArray())
57
- .forEach(danglingBlockJsFile => {
58
- compilation.deleteAsset(danglingBlockJsFile);
59
- });
60
- const relevantEntrypoints = this.getRelevantEntrypoints(compilation);
61
49
  const blockJsonOriginToOutputMapping = {};
62
- for (const { entrypoint, entrypointChunk, entrypointLibrary, srcPath } of relevantEntrypoints) {
63
- if (node_path_1.default.basename(srcPath).toLowerCase() !== "block.json" || entrypointLibrary.name !== "block-json-inclusion-assurance") {
50
+ const relevantEntrypoints = this.getRelevantEntrypoints(compilation);
51
+ for (const { entrypoint, metadata, srcPath } of relevantEntrypoints) {
52
+ if (node_path_1.default.basename(srcPath).toLowerCase() !== "block.json" || metadata !== "block-json-inclusion-assurance") {
64
53
  continue;
65
54
  }
55
+ const entrypointChunk = entrypoint.getEntrypointChunk();
56
+ for (const danglingBlockJsFile of [...entrypointChunk.files, ...entrypointChunk.auxiliaryFiles]) {
57
+ if (!danglingBlockJsFile.endsWith("block.json")) {
58
+ compilation.deleteAsset(danglingBlockJsFile);
59
+ }
60
+ }
66
61
  const asset = [...compilation.chunkGraph.getChunkEntryModulesIterable(entrypointChunk)][0]?.originalSource();
67
62
  if (asset) {
68
63
  //TODO: Can we guarantee that entrypoint.name is always non-null?
@@ -79,16 +74,13 @@ class PlainEntrypointsStyleBlockJSONPlugin extends AbstractMultiPhaseLibraryPlug
79
74
  blockJsonOriginToOutputMapping[srcPath] = epBlockJson;
80
75
  }
81
76
  }
82
- for (const { entrypoint, entrypointChunk, entrypointLibrary, srcPath } of relevantEntrypoints) {
83
- if (node_path_1.default.basename(srcPath).toLowerCase() === "block.json" && entrypointLibrary.name === "block-json-inclusion-assurance") {
84
- continue;
85
- }
86
- const blockEntrypointInfo = (0, shared_1.unpackSmuggledBlockEntrypointInfo)(entrypointLibrary);
87
- if (!blockEntrypointInfo) {
77
+ for (const { entrypoint, metadata, srcPath } of relevantEntrypoints) {
78
+ if (node_path_1.default.basename(srcPath).toLowerCase() === "block.json" || typeof metadata === 'string') {
88
79
  continue;
89
80
  }
81
+ const entrypointChunk = entrypoint.getEntrypointChunk();
90
82
  const epBlockJson = entrypointChunk.auxiliaryFiles.values().find(auxFile => node_path_1.default.basename(auxFile) === "block.json")
91
- ?? blockJsonOriginToOutputMapping[blockEntrypointInfo.blockJsonOrigin];
83
+ ?? blockJsonOriginToOutputMapping[metadata.blockJsonOrigin];
92
84
  if (epBlockJson) {
93
85
  //TODO: Do we need to handle a single entrypoint potentially emitting multiple primary files?
94
86
  const assetData = entrypointChunk.files.values().map(file => assetDataSource[file])
@@ -103,14 +95,14 @@ class PlainEntrypointsStyleBlockJSONPlugin extends AbstractMultiPhaseLibraryPlug
103
95
  .map(file => [file, (0, shared_1.scriptOrStyleTest)(file, shared_1.scriptExtension)])
104
96
  .filter((item) => item[1] !== '')
105
97
  .map(([file, assetType]) => {
106
- const wasOriginallyAStyleField = (0, shared_1.isStyleField)(blockEntrypointInfo.entrypointField);
98
+ const wasOriginallyAStyleField = (0, shared_1.isStyleField)(metadata.entrypointField);
107
99
  if (wasOriginallyAStyleField !== (assetType === "style")) { // This means that the file is extracted
108
100
  return {
109
- ...blockEntrypointInfo, outputPath: file, assetData, originalValue: undefined, hash: entrypointChunk.hash ?? "",
110
- entrypointField: (0, shared_1.convertEntrypointFieldForAssetType)(blockEntrypointInfo.entrypointField, assetType)
101
+ ...metadata, outputPath: file, assetData, originalValue: undefined, hash: entrypointChunk.hash ?? "",
102
+ entrypointField: (0, shared_1.convertEntrypointFieldForAssetType)(metadata.entrypointField, assetType)
111
103
  };
112
104
  }
113
- return ({ ...blockEntrypointInfo, outputPath: file, assetData, hash: entrypointChunk.hash ?? "" });
105
+ return ({ ...metadata, outputPath: file, assetData, hash: entrypointChunk.hash ?? "" });
114
106
  });
115
107
  if (applicableBlockJsonFiles[epBlockJson]) {
116
108
  applicableBlockJsonFiles[epBlockJson].workableBlockEntrypointsInfo.push(...workableBlockEntrypointsInfo);
@@ -255,7 +247,6 @@ class PlainEntrypointsStyleBlockJSONPlugin extends AbstractMultiPhaseLibraryPlug
255
247
  return blockJson;
256
248
  }
257
249
  stripOffBlocksDestPrefix(file) {
258
- file = node_path_1.default.normalize(file);
259
250
  return this.blocksDest && file.startsWith(this.blocksDest + "/") ? file.substring(this.blocksDest.length + 1 /* we also need to drop the "/" */) : file;
260
251
  }
261
252
  static hashThingForAsset(thing) {
@@ -1,6 +1,6 @@
1
1
  import type { VerifiedPlauditWordpressWebpackConfig } from "../utils/common-config-helpers";
2
- import { Compilation, type Compiler } from "webpack";
3
2
  import { AbstractMultiPhaseLibraryPlugin } from "./AbstractMultiPhaseLibraryPlugin";
3
+ import { Compilation, type Compiler } from "webpack";
4
4
  export declare class SpecialAssetHandlingPlugin extends AbstractMultiPhaseLibraryPlugin {
5
5
  private readonly config;
6
6
  private static readonly semaphore;
@@ -8,9 +8,9 @@ const node_path_1 = __importDefault(require("node:path"));
8
8
  const shared_1 = require("../shared");
9
9
  const php_writer_1 = require("../utils/php-writer");
10
10
  const pseduo_semaphore_1 = require("../utils/pseduo-semaphore");
11
+ const AbstractMultiPhaseLibraryPlugin_1 = require("./AbstractMultiPhaseLibraryPlugin");
11
12
  const UnifiedLoaderGenerator_1 = require("./UnifiedLoaderGenerator");
12
13
  const webpack_1 = require("webpack");
13
- const AbstractMultiPhaseLibraryPlugin_1 = require("./AbstractMultiPhaseLibraryPlugin");
14
14
  class SpecialAssetHandlingPlugin extends AbstractMultiPhaseLibraryPlugin_1.AbstractMultiPhaseLibraryPlugin {
15
15
  config;
16
16
  static semaphore = new pseduo_semaphore_1.PseudoSemaphore({}, "Special");