@plaudit/webpack-extensions 2.61.2 → 2.62.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/build/plugins/AbstractMultiPhaseLibraryPlugin.d.ts +14 -0
- package/build/plugins/AbstractMultiPhaseLibraryPlugin.js +88 -0
- package/build/plugins/ExtensionsConfigFileGeneratorPlugin.d.ts +5 -6
- package/build/plugins/ExtensionsConfigFileGeneratorPlugin.js +83 -118
- package/build/plugins/ExtensionsConfigFileGeneratorPluginV1.d.ts +8 -0
- package/build/plugins/ExtensionsConfigFileGeneratorPluginV1.js +49 -0
- package/build/plugins/PlainEntrypointsConfigFileGeneratorPlugin.d.ts +5 -10
- package/build/plugins/PlainEntrypointsConfigFileGeneratorPlugin.js +36 -62
- package/build/plugins/PlainEntrypointsStyleBlockJSONPlugin.d.ts +25 -0
- package/build/plugins/PlainEntrypointsStyleBlockJSONPlugin.js +434 -0
- package/build/plugins/SpecialAssetHandlingPlugin.d.ts +4 -4
- package/build/plugins/SpecialAssetHandlingPlugin.js +13 -19
- package/build/plugins/UnifiedLoaderGenerator.js +2 -2
- package/build/plugins/WPMLConfigBuilder.d.ts +1 -3
- package/build/plugins/WPMLConfigBuilder.js +14 -22
- package/build/shared.d.ts +33 -17
- package/build/shared.js +80 -27
- package/build/utils/common-config-helpers.d.ts +2 -2
- package/build/utils/common-config-helpers.js +84 -27
- package/build/utils/php-writer.d.ts +129 -16
- package/build/utils/php-writer.js +261 -41
- package/build/wordpress-scripts-wrapper.js +14 -10
- package/package.json +1 -1
- package/build/plugins/BlockJSONManagingPlugin.d.ts +0 -40
- package/build/plugins/BlockJSONManagingPlugin.js +0 -594
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PlainEntrypointsStyleBlockJSONPlugin = void 0;
|
|
7
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const AbstractMultiPhaseLibraryPlugin_1 = require("./AbstractMultiPhaseLibraryPlugin");
|
|
11
|
+
const UnifiedLoaderGenerator_1 = require("./UnifiedLoaderGenerator");
|
|
12
|
+
const shared_1 = require("../shared");
|
|
13
|
+
const php_writer_1 = require("../utils/php-writer");
|
|
14
|
+
const pseduo_semaphore_1 = require("../utils/pseduo-semaphore");
|
|
15
|
+
const webpack_1 = require("webpack");
|
|
16
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
17
|
+
class PlainEntrypointsStyleBlockJSONPlugin extends AbstractMultiPhaseLibraryPlugin_1.AbstractMultiPhaseLibraryPlugin {
|
|
18
|
+
config;
|
|
19
|
+
blocksDest;
|
|
20
|
+
webpackRemoveEmptyScriptsPlugin;
|
|
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]);
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.blocksDest = blocksDest;
|
|
26
|
+
this.webpackRemoveEmptyScriptsPlugin = webpackRemoveEmptyScriptsPlugin;
|
|
27
|
+
}
|
|
28
|
+
apply(compiler) {
|
|
29
|
+
super.apply(compiler);
|
|
30
|
+
compiler.hooks.compilation.tap(this.constructor.name, compilation => {
|
|
31
|
+
compilation.hooks.processAssets.tapPromise({ name: this.constructor.name, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_ANALYSE, additionalAssets: true }, async (assets) => {
|
|
32
|
+
if (!("assets.json" in assets)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const rawAssetDataSource = assets["assets.json"]?.source();
|
|
37
|
+
if (typeof rawAssetDataSource !== 'string') {
|
|
38
|
+
PlainEntrypointsStyleBlockJSONPlugin.semaphore.reject(this.id);
|
|
39
|
+
compilation.errors.push(new Error("assets.json is unexpectedly missing or not a string"));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const assetDataSource = JSON.parse(rawAssetDataSource);
|
|
43
|
+
if (!(0, shared_1.isRawAssetData)(assetDataSource)) {
|
|
44
|
+
PlainEntrypointsStyleBlockJSONPlugin.semaphore.reject(this.id);
|
|
45
|
+
compilation.errors.push(new Error("assets.json is does not match the RawAssetData format"));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
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 = compilation.entrypoints.values()
|
|
61
|
+
.map(entrypoint => {
|
|
62
|
+
const entrypointChunk = entrypoint.getEntrypointChunk();
|
|
63
|
+
const entrypointLibrary = entrypointChunk.getEntryOptions()?.library;
|
|
64
|
+
if (entrypointLibrary?.type !== this.libraryType) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
const srcPath = entrypoint.origins[0]?.request;
|
|
68
|
+
if (!srcPath) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
return { entrypoint, entrypointChunk, entrypointLibrary, srcPath };
|
|
72
|
+
})
|
|
73
|
+
.filter(item => item !== undefined)
|
|
74
|
+
.toArray();
|
|
75
|
+
const blockJsonOriginToOutputMapping = {};
|
|
76
|
+
for (const { entrypoint, entrypointChunk, entrypointLibrary, srcPath } of relevantEntrypoints) {
|
|
77
|
+
if (node_path_1.default.basename(srcPath).toLowerCase() !== "block.json" || entrypointLibrary.name !== "block-json-inclusion-assurance") {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const asset = [...compilation.chunkGraph.getChunkEntryModulesIterable(entrypointChunk)][0]?.originalSource();
|
|
81
|
+
if (asset) {
|
|
82
|
+
//TODO: Can we guarantee that entrypoint.name is always non-null?
|
|
83
|
+
const epBlockJson = entrypoint.name + ".json";
|
|
84
|
+
if (!applicableBlockJsonFiles[epBlockJson]) {
|
|
85
|
+
const blockJsonText = PlainEntrypointsStyleBlockJSONPlugin.extractAssetSource(compilation, epBlockJson)
|
|
86
|
+
?? await promises_1.default.readFile(srcPath, 'utf-8');
|
|
87
|
+
if (!blockJsonText) {
|
|
88
|
+
compilation.errors.push((0, shared_1.newWebpackErrorForFile)(`Unable to extract the source for ${epBlockJson}`, srcPath));
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
applicableBlockJsonFiles[epBlockJson] = { sourcePath: srcPath, workableBlockEntrypointsInfo: [], blockJsonText };
|
|
92
|
+
}
|
|
93
|
+
blockJsonOriginToOutputMapping[srcPath] = epBlockJson;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
for (const { entrypoint, entrypointChunk, entrypointLibrary, srcPath } of relevantEntrypoints) {
|
|
97
|
+
if (node_path_1.default.basename(srcPath).toLowerCase() === "block.json" && entrypointLibrary.name === "block-json-inclusion-assurance") {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const blockEntrypointInfo = (0, shared_1.unpackSmuggledBlockEntrypointInfo)(entrypointLibrary);
|
|
101
|
+
if (!blockEntrypointInfo) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const epBlockJson = entrypointChunk.auxiliaryFiles.values().find(auxFile => node_path_1.default.basename(auxFile) === "block.json")
|
|
105
|
+
?? blockJsonOriginToOutputMapping[blockEntrypointInfo.blockJsonOrigin];
|
|
106
|
+
if (epBlockJson) {
|
|
107
|
+
//TODO: Do we need to handle a single entrypoint potentially emitting multiple primary files?
|
|
108
|
+
const assetData = entrypointChunk.files.values().map(file => assetDataSource[file])
|
|
109
|
+
.find(assetData => assetData !== undefined);
|
|
110
|
+
if (!assetData) {
|
|
111
|
+
compilation.errors.push((0, shared_1.newWebpackErrorForFile)(`assets.json did not contain information for ${srcPath}`, srcPath));
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const workableBlockEntrypointsInfo = entrypoint.getFiles()
|
|
115
|
+
.map(file => this.stripOffBlocksDestPrefix(file))
|
|
116
|
+
.filter(file => !this.webpackRemoveEmptyScriptsPlugin['trash'].includes(node_path_1.default.join(this.blocksDest, file)))
|
|
117
|
+
.map(file => [file, (0, shared_1.scriptOrStyleTest)(file, shared_1.scriptExtension)])
|
|
118
|
+
.filter((item) => item[1] !== '')
|
|
119
|
+
.map(([file, assetType]) => {
|
|
120
|
+
const wasOriginallyAStyleField = (0, shared_1.isStyleField)(blockEntrypointInfo.entrypointField);
|
|
121
|
+
if (wasOriginallyAStyleField !== (assetType === "style")) { // This means that the file is extracted
|
|
122
|
+
return {
|
|
123
|
+
...blockEntrypointInfo, outputPath: file, assetData, originalValue: undefined, hash: entrypointChunk.hash ?? "",
|
|
124
|
+
entrypointField: (0, shared_1.convertEntrypointFieldForAssetType)(blockEntrypointInfo.entrypointField, assetType)
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return ({ ...blockEntrypointInfo, outputPath: file, assetData, hash: entrypointChunk.hash ?? "" });
|
|
128
|
+
});
|
|
129
|
+
if (applicableBlockJsonFiles[epBlockJson]) {
|
|
130
|
+
applicableBlockJsonFiles[epBlockJson].workableBlockEntrypointsInfo.push(...workableBlockEntrypointsInfo);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
applicableBlockJsonFiles[epBlockJson] = { sourcePath: workableBlockEntrypointsInfo[0]?.blockJsonOrigin, workableBlockEntrypointsInfo: workableBlockEntrypointsInfo };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
compilation.deleteAsset("assets.json");
|
|
138
|
+
PlainEntrypointsStyleBlockJSONPlugin.semaphore.resolve(this.id, {
|
|
139
|
+
collatableWorkableBlockInfo: applicableBlockJsonFiles, blocksDest: this.blocksDest,
|
|
140
|
+
emittingWpmlXml: compilation.getAsset(node_path_1.default.join(this.blocksDest, "wpml-config.xml")) !== undefined
|
|
141
|
+
});
|
|
142
|
+
UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore.resolve(this.id, Object.keys(applicableBlockJsonFiles).length ? {
|
|
143
|
+
group: this.libraryType,
|
|
144
|
+
requiresBaseURI: false,
|
|
145
|
+
action: writer => writer.append(`require_once __DIR__.${php_writer_1.Expr.convertJsonToPHP("/" + node_path_1.default.join(this.blocksDest, "blockdir-loader.php"))};`)
|
|
146
|
+
} : undefined);
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
PlainEntrypointsStyleBlockJSONPlugin.semaphore.reject(this.id);
|
|
150
|
+
UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore.reject(this.id);
|
|
151
|
+
throw e;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
emitBlockLoaderFile(compilation, blockData) {
|
|
157
|
+
if (this.config.useUnifiedLoader) {
|
|
158
|
+
const metadata = blockData['__metadata'];
|
|
159
|
+
delete blockData['__metadata'];
|
|
160
|
+
new php_writer_1.PHPWriter()
|
|
161
|
+
.action("init", writer => {
|
|
162
|
+
writer.call("\\Plaudit\\Common\\ACF\\BlockManager::autoloadSubfoldersV3", [php_writer_1.Constants.__DIR__, new php_writer_1.EnclosedLiteral((0, shared_1.makeEmittableConfigPHP)(blockData, false, "\t")),
|
|
163
|
+
php_writer_1.Constants.__FILE__, new php_writer_1.EnclosedLiteral((0, shared_1.makeEmittableConfigPHP)(metadata, false, "\t")), null]);
|
|
164
|
+
}, { accountForAlreadyDoing: true })
|
|
165
|
+
.emitAsset(compilation, node_path_1.default.join(this.blocksDest, "blockdir-loader.php"));
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
compilation.emitAsset(node_path_1.default.join(this.blocksDest, "blockdir.config.php"), new webpack_1.sources.RawSource((0, shared_1.makeEmittableConfigPHP)(blockData, true)));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
transformBlocks(compilation, collatedWorkableBlockInfo, emittingWpmlXml) {
|
|
172
|
+
const handleData = Object.values(collatedWorkableBlockInfo)
|
|
173
|
+
.flatMap(bi => bi.workableBlockEntrypointsInfo)
|
|
174
|
+
.sort((a, b) => a.handle.localeCompare(b.handle) || a.entrypointField.localeCompare(b.entrypointField));
|
|
175
|
+
const blockData = {};
|
|
176
|
+
for (const [blockJsonAssetName, { sourcePath: blockJsonSourcePath, workableBlockEntrypointsInfo, blockJsonText }] of Object.entries(collatedWorkableBlockInfo)) {
|
|
177
|
+
if (!blockJsonSourcePath) {
|
|
178
|
+
compilation.errors.push((0, shared_1.newWebpackErrorForFile)(`${blockJsonAssetName} does not have a source path`, blockJsonAssetName));
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (!blockJsonText) {
|
|
182
|
+
compilation.errors.push((0, shared_1.newWebpackErrorForFile)(`${blockJsonAssetName} does not have recorded text`, blockJsonAssetName));
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const sourceDir = node_path_1.default.dirname(blockJsonSourcePath);
|
|
186
|
+
const outputDir = node_path_1.default.join(compilation.compiler.outputPath, node_path_1.default.dirname(blockJsonAssetName));
|
|
187
|
+
const blockJson = JSON.parse(blockJsonText);
|
|
188
|
+
const pathsNeedRemapping = !this.config.standaloneBlocks && blockJson["plaudit"] !== "simple";
|
|
189
|
+
PlainEntrypointsStyleBlockJSONPlugin.remapReferencedPHPFilesOnKey(blockJson, "setup", pathsNeedRemapping, sourceDir, outputDir, compilation, true);
|
|
190
|
+
PlainEntrypointsStyleBlockJSONPlugin.remapReferencedPHPFilesOnKey(blockJson, "variations", pathsNeedRemapping, sourceDir, outputDir, compilation, false);
|
|
191
|
+
PlainEntrypointsStyleBlockJSONPlugin.normalizeRenderTemplate(blockJson, pathsNeedRemapping, sourceDir, outputDir, compilation);
|
|
192
|
+
const hashForVersion = PlainEntrypointsStyleBlockJSONPlugin
|
|
193
|
+
.hashThingForAsset([blockJsonText, ...workableBlockEntrypointsInfo.map(bi => bi.hash)].join("~"));
|
|
194
|
+
if (blockJson["version"]) {
|
|
195
|
+
blockJson["version"] = `${blockJson["version"]}-${hashForVersion}`;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
blockJson["version"] = hashForVersion;
|
|
199
|
+
}
|
|
200
|
+
const blockDirName = node_path_1.default.dirname(node_path_1.default.relative(this.blocksDest, blockJsonAssetName));
|
|
201
|
+
blockData[blockDirName] = PlainEntrypointsStyleBlockJSONPlugin
|
|
202
|
+
.doFileOrHandleReplacements(compilation, Object.fromEntries(Object.entries(blockJson).filter(([k]) => k !== '$schema')), workableBlockEntrypointsInfo, epi => epi.handle);
|
|
203
|
+
compilation[blockJsonAssetName in compilation.assets ? 'updateAsset' : 'emitAsset'](blockJsonAssetName, new webpack_1.sources.RawSource(JSON.stringify(PlainEntrypointsStyleBlockJSONPlugin
|
|
204
|
+
.doFileOrHandleReplacements(compilation, blockJson, workableBlockEntrypointsInfo, epi => "file:./" + node_path_1.default.relative(blockDirName, epi.outputPath)), undefined, " ")));
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
__metadata: {
|
|
208
|
+
version: 3,
|
|
209
|
+
"wpml-config": emittingWpmlXml,
|
|
210
|
+
scriptHandles: Object.fromEntries(PlainEntrypointsStyleBlockJSONPlugin
|
|
211
|
+
.convertToScriptHandles(handleData.filter(hd => !(0, shared_1.isStyleField)(hd.entrypointField) && !(0, shared_1.isScriptModuleField)(hd.entrypointField)))),
|
|
212
|
+
scriptModuleHandles: Object.fromEntries(PlainEntrypointsStyleBlockJSONPlugin
|
|
213
|
+
.convertToScriptHandles(handleData.filter(hd => !(0, shared_1.isStyleField)(hd.entrypointField) && (0, shared_1.isScriptModuleField)(hd.entrypointField)))),
|
|
214
|
+
styleHandles: Object.fromEntries(handleData.filter(hd => (0, shared_1.isStyleField)(hd.entrypointField))
|
|
215
|
+
.map(hd => [hd.handle, { src: hd.outputPath, rest: [hd.assetData.dependencies, hd.assetData.version] }]))
|
|
216
|
+
},
|
|
217
|
+
...Object.fromEntries(Object.entries(blockData).sort((a, b) => a[0].localeCompare(b[0])))
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
static extractAssetSource(compilation, assetName) {
|
|
221
|
+
const assetSource = compilation.getAsset(assetName)?.source.source();
|
|
222
|
+
return typeof assetSource === 'string' ? assetSource : assetSource?.toString('utf-8');
|
|
223
|
+
}
|
|
224
|
+
static convertToScriptHandles(handleData) {
|
|
225
|
+
return handleData.map(hd => {
|
|
226
|
+
return [hd.handle, { src: hd.outputPath, rest: hd.entrypointField.startsWith("editor")
|
|
227
|
+
? [hd.assetData.dependencies, hd.assetData.version] : [hd.assetData.dependencies, hd.assetData.version, { strategy: "defer" }] }];
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
static doFileOrHandleReplacements(compilation, blockJson, workableBlockEntrypointsInfo, getter) {
|
|
231
|
+
for (const entrypointInfo of workableBlockEntrypointsInfo) {
|
|
232
|
+
const fieldValue = blockJson[entrypointInfo.entrypointField];
|
|
233
|
+
if (!fieldValue) {
|
|
234
|
+
blockJson[entrypointInfo.entrypointField] = getter(entrypointInfo);
|
|
235
|
+
}
|
|
236
|
+
else if (entrypointInfo.originalValue) {
|
|
237
|
+
if (entrypointInfo.originalValue === fieldValue) {
|
|
238
|
+
blockJson[entrypointInfo.entrypointField] = getter(entrypointInfo);
|
|
239
|
+
}
|
|
240
|
+
else if (typeof fieldValue === 'string') {
|
|
241
|
+
blockJson[entrypointInfo.entrypointField] = [fieldValue, getter(entrypointInfo)];
|
|
242
|
+
}
|
|
243
|
+
else if (Array.isArray(fieldValue)) {
|
|
244
|
+
const replacementPos = fieldValue.indexOf(entrypointInfo.originalValue);
|
|
245
|
+
if (replacementPos === -1) {
|
|
246
|
+
compilation.warnings.push((0, shared_1.newWebpackErrorForFile)(`Unable to find ${entrypointInfo.originalValue} in ${entrypointInfo.entrypointField}`, entrypointInfo.blockJsonOrigin));
|
|
247
|
+
blockJson[entrypointInfo.entrypointField] = fieldValue.concat(getter(entrypointInfo));
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
blockJson[entrypointInfo.entrypointField] = fieldValue.toSpliced(replacementPos, 1, getter(entrypointInfo));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
blockJson[entrypointInfo.entrypointField] = getter(entrypointInfo);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
if (typeof fieldValue === 'string') {
|
|
259
|
+
blockJson[entrypointInfo.entrypointField] = [fieldValue, getter(entrypointInfo)];
|
|
260
|
+
}
|
|
261
|
+
else if (Array.isArray(fieldValue)) {
|
|
262
|
+
blockJson[entrypointInfo.entrypointField] = fieldValue.concat(getter(entrypointInfo));
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
blockJson[entrypointInfo.entrypointField] = getter(entrypointInfo);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return blockJson;
|
|
270
|
+
}
|
|
271
|
+
stripOffBlocksDestPrefix(file) {
|
|
272
|
+
file = node_path_1.default.normalize(file);
|
|
273
|
+
return this.blocksDest && file.startsWith(this.blocksDest + "/") ? file.substring(this.blocksDest.length + 1 /* we also need to drop the "/" */) : file;
|
|
274
|
+
}
|
|
275
|
+
static hashThingForAsset(thing) {
|
|
276
|
+
return node_crypto_1.default.createHash('md5').update(thing).digest("hex").substring(0, 20).toLowerCase();
|
|
277
|
+
}
|
|
278
|
+
static stripFilePrefix(file) {
|
|
279
|
+
return file.startsWith("file:./") ? file.substring(7) : file;
|
|
280
|
+
}
|
|
281
|
+
static findCommonAncestor(...paths) {
|
|
282
|
+
return paths.map(p => node_path_1.default.normalize(p).split(node_path_1.default.sep)).reduce((prior, current) => {
|
|
283
|
+
for (let i = 0, limit = Math.min(prior.length, current.length); i < limit; i++) {
|
|
284
|
+
if (prior[i] !== current[i]) {
|
|
285
|
+
return prior.slice(0, i);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return current.length < prior.length ? current : prior;
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
static findRelativeRouteBetween(path1, path2) {
|
|
292
|
+
const commonAncestor = PlainEntrypointsStyleBlockJSONPlugin.findCommonAncestor(path1, path2);
|
|
293
|
+
const route = Array(path1.split(node_path_1.default.sep).length - commonAncestor.length).fill("..");
|
|
294
|
+
route.push(node_path_1.default.relative(commonAncestor.join(node_path_1.default.sep), path2));
|
|
295
|
+
return route.join(node_path_1.default.sep);
|
|
296
|
+
}
|
|
297
|
+
static remapReferencedPHPFilesOnKey(blockJson, key, pathsNeedRemapping, sourceDir, outputDir, compilation, inPlaudit) {
|
|
298
|
+
const rawValue = (inPlaudit ? blockJson["plaudit"] : blockJson)?.[key];
|
|
299
|
+
let rawFiles;
|
|
300
|
+
let deleteOnEmpty = true;
|
|
301
|
+
if (typeof rawValue === 'string') {
|
|
302
|
+
rawFiles = [rawValue];
|
|
303
|
+
}
|
|
304
|
+
else if (Array.isArray(rawValue) && rawValue.length > 0) {
|
|
305
|
+
const fileReferences = rawValue.filter((value) => typeof value === 'string' && value.startsWith("file:./"));
|
|
306
|
+
if (fileReferences.length === rawValue.length) {
|
|
307
|
+
rawFiles = fileReferences;
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
if (fileReferences.length !== 0) {
|
|
311
|
+
compilation.warnings.push((0, shared_1.newWebpackErrorForFile)(`Encountered a block with a mixture of file-reference and non-file-reference elements in the "${inPlaudit ? 'plaudit.' : ''}${key}" property`, node_path_1.default.join(sourceDir, 'block.json')));
|
|
312
|
+
rawFiles = fileReferences;
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
rawFiles = [`${key}.php`]; // We want to emit an error if both an appropriately-named file AND an incompatible value exist, so we still need to do the check
|
|
316
|
+
}
|
|
317
|
+
deleteOnEmpty = false;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
if (rawValue && (!Array.isArray(rawValue) || rawValue.length === 0)) {
|
|
322
|
+
deleteOnEmpty = false;
|
|
323
|
+
}
|
|
324
|
+
rawFiles = [`${key}.php`];
|
|
325
|
+
}
|
|
326
|
+
const mappedFiles = pathsNeedRemapping
|
|
327
|
+
? rawFiles
|
|
328
|
+
.map(p => node_path_1.default.normalize(node_path_1.default.join(sourceDir, PlainEntrypointsStyleBlockJSONPlugin.stripFilePrefix(p))))
|
|
329
|
+
.filter(p => node_fs_1.default.existsSync(p))
|
|
330
|
+
.map(p => `file:./${PlainEntrypointsStyleBlockJSONPlugin.findRelativeRouteBetween(outputDir, p)}`)
|
|
331
|
+
: rawFiles
|
|
332
|
+
.filter(p => node_fs_1.default.existsSync(node_path_1.default.normalize(node_path_1.default.join(sourceDir, PlainEntrypointsStyleBlockJSONPlugin.stripFilePrefix(p)))));
|
|
333
|
+
if (mappedFiles.length === 0) {
|
|
334
|
+
if (deleteOnEmpty && rawValue !== undefined) {
|
|
335
|
+
delete (inPlaudit ? blockJson["plaudit"] : blockJson)[key];
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
if (inPlaudit && typeof blockJson["plaudit"] !== 'object') {
|
|
340
|
+
if (blockJson["plaudit"] === "native") {
|
|
341
|
+
blockJson["plaudit"] = { type: "native" };
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
blockJson["plaudit"] = {};
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
(inPlaudit ? blockJson["plaudit"] : blockJson)[key] = mappedFiles.length === 1 ? mappedFiles[0] : mappedFiles;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
static normalizeRenderTemplate(blockJson, pathsNeedRemapping, sourceDir, outputDir, compilation) {
|
|
351
|
+
if (blockJson["acf"]) {
|
|
352
|
+
if (blockJson["acf"]["renderTemplate"]) {
|
|
353
|
+
blockJson["render_template"] = blockJson["acf"]["renderTemplate"];
|
|
354
|
+
delete blockJson["acf"]["renderTemplate"];
|
|
355
|
+
}
|
|
356
|
+
else if (blockJson["acf"]["render_template"]) {
|
|
357
|
+
blockJson["render_template"] = blockJson["acf"]["render_template"];
|
|
358
|
+
delete blockJson["acf"]["render_template"];
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
const blockName = blockJson["name"]?.toString() || "non-existent/block-name";
|
|
362
|
+
let rawRenderTemplate = blockJson["render"] ?? blockJson["render_template"];
|
|
363
|
+
rawRenderTemplate = (rawRenderTemplate
|
|
364
|
+
? (typeof rawRenderTemplate === 'string' ? [rawRenderTemplate] : rawRenderTemplate)
|
|
365
|
+
: [`${blockName.substring(blockName.indexOf('/') + 1)}.php`, "template.php", "template.twig"]);
|
|
366
|
+
const renderTemplate = pathsNeedRemapping
|
|
367
|
+
? rawRenderTemplate
|
|
368
|
+
.map(p => node_path_1.default.normalize(node_path_1.default.join(sourceDir, PlainEntrypointsStyleBlockJSONPlugin.stripFilePrefix(p))))
|
|
369
|
+
.filter(p => node_fs_1.default.existsSync(p))
|
|
370
|
+
.map(p => `file:./${PlainEntrypointsStyleBlockJSONPlugin.findRelativeRouteBetween(outputDir, p)}`)
|
|
371
|
+
: rawRenderTemplate
|
|
372
|
+
.filter(p => node_fs_1.default.existsSync(node_path_1.default.normalize(node_path_1.default.join(sourceDir, PlainEntrypointsStyleBlockJSONPlugin.stripFilePrefix(p)))));
|
|
373
|
+
if (renderTemplate.length === 0) {
|
|
374
|
+
delete blockJson["render_template"];
|
|
375
|
+
delete blockJson["render"];
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
let validTemplateLocation, invalidTemplateLocation;
|
|
379
|
+
if (blockJson["acf"] || (blockJson["plaudit"] && (blockJson["plaudit"] !== "native" && (typeof blockJson["plaudit"] !== 'object' || blockJson["plaudit"]?.["type"] !== "native")))) {
|
|
380
|
+
// ACF-like blocks need to have the template stored in render_template.
|
|
381
|
+
// Because we can statically detect ACF-like blocks, we can make the move here instead of at run-time.
|
|
382
|
+
validTemplateLocation = "render_template";
|
|
383
|
+
invalidTemplateLocation = "render";
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
validTemplateLocation = "render";
|
|
387
|
+
invalidTemplateLocation = "render_template";
|
|
388
|
+
}
|
|
389
|
+
delete blockJson[invalidTemplateLocation];
|
|
390
|
+
if (renderTemplate.length > 1) {
|
|
391
|
+
compilation.warnings.push((0, shared_1.newWebpackErrorForFile)("Encountered a block with multiple possible render files", node_path_1.default.join(sourceDir, 'block.json')));
|
|
392
|
+
blockJson[validTemplateLocation] = renderTemplate.find(p => p.endsWith(".php")) ?? renderTemplate[0];
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
blockJson[validTemplateLocation] = renderTemplate[0];
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
attachSecondPhase(compilation) {
|
|
400
|
+
compilation.hooks.processAssets.tapPromise({ name: `${this.constructor.name}_CompileLoader`, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_REPORT }, async () => {
|
|
401
|
+
const allSemaphoreData = (await PlainEntrypointsStyleBlockJSONPlugin.semaphore.wait())
|
|
402
|
+
.reduce((acc, cur) => {
|
|
403
|
+
(acc[cur.blocksDest] ?? (acc[cur.blocksDest] = [])).push(cur);
|
|
404
|
+
return acc;
|
|
405
|
+
}, {});
|
|
406
|
+
const semaphoreData = allSemaphoreData[this.blocksDest];
|
|
407
|
+
if (semaphoreData === undefined) {
|
|
408
|
+
compilation.errors.push(new Error(`Semaphore data missing for ${this.blocksDest}`));
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
const workableBlockInfo = semaphoreData.map(sd => sd.collatableWorkableBlockInfo)
|
|
412
|
+
.reduce((acc, cur) => {
|
|
413
|
+
for (const [k, v] of Object.entries(cur)) {
|
|
414
|
+
if (acc[k]) {
|
|
415
|
+
acc[k].workableBlockEntrypointsInfo.push(...v.workableBlockEntrypointsInfo);
|
|
416
|
+
if (!acc[k].sourcePath && v.sourcePath) {
|
|
417
|
+
acc[k].sourcePath = v.sourcePath;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
acc[k] = { ...v, workableBlockEntrypointsInfo: [...v.workableBlockEntrypointsInfo] };
|
|
422
|
+
}
|
|
423
|
+
acc[k].workableBlockEntrypointsInfo.sort((a, b) => {
|
|
424
|
+
return a.handle.localeCompare(b.handle) || a.entrypointField.localeCompare(b.entrypointField);
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
return acc;
|
|
428
|
+
}, {});
|
|
429
|
+
const blockData = this.transformBlocks(compilation, workableBlockInfo, semaphoreData.some(sd => sd.emittingWpmlXml));
|
|
430
|
+
this.emitBlockLoaderFile(compilation, blockData);
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
exports.PlainEntrypointsStyleBlockJSONPlugin = PlainEntrypointsStyleBlockJSONPlugin;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { VerifiedPlauditWordpressWebpackConfig } from "../utils/common-config-helpers";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { Compilation, type Compiler } from "webpack";
|
|
3
|
+
import { AbstractMultiPhaseLibraryPlugin } from "./AbstractMultiPhaseLibraryPlugin";
|
|
4
|
+
export declare class SpecialAssetHandlingPlugin extends AbstractMultiPhaseLibraryPlugin {
|
|
4
5
|
private readonly config;
|
|
5
6
|
private static readonly semaphore;
|
|
6
|
-
private static hasAttachedAssetCollatorForCurrentBatch;
|
|
7
7
|
private static validPathname?;
|
|
8
|
-
private readonly id;
|
|
9
8
|
constructor(config: VerifiedPlauditWordpressWebpackConfig);
|
|
10
9
|
apply(compiler: Compiler): void;
|
|
11
10
|
private collateAssets;
|
|
11
|
+
protected attachSecondPhase(compilation: Compilation): void;
|
|
12
12
|
}
|
|
@@ -5,37 +5,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.SpecialAssetHandlingPlugin = void 0;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const shared_1 = require("../shared");
|
|
8
9
|
const php_writer_1 = require("../utils/php-writer");
|
|
9
10
|
const pseduo_semaphore_1 = require("../utils/pseduo-semaphore");
|
|
10
|
-
const PlainEntrypointsConfigFileGeneratorPlugin_1 = require("./PlainEntrypointsConfigFileGeneratorPlugin");
|
|
11
11
|
const UnifiedLoaderGenerator_1 = require("./UnifiedLoaderGenerator");
|
|
12
12
|
const webpack_1 = require("webpack");
|
|
13
|
-
|
|
13
|
+
const AbstractMultiPhaseLibraryPlugin_1 = require("./AbstractMultiPhaseLibraryPlugin");
|
|
14
|
+
class SpecialAssetHandlingPlugin extends AbstractMultiPhaseLibraryPlugin_1.AbstractMultiPhaseLibraryPlugin {
|
|
14
15
|
config;
|
|
15
16
|
static semaphore = new pseduo_semaphore_1.PseudoSemaphore({}, "Special");
|
|
16
|
-
static hasAttachedAssetCollatorForCurrentBatch = false;
|
|
17
17
|
static validPathname = undefined;
|
|
18
|
-
id;
|
|
19
18
|
constructor(config) {
|
|
19
|
+
super("special-assets", [SpecialAssetHandlingPlugin.semaphore, UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore]);
|
|
20
20
|
this.config = config;
|
|
21
|
-
this.id = Math.random().toString();
|
|
22
21
|
}
|
|
23
22
|
apply(compiler) {
|
|
24
23
|
if (!this.config.useWebpackResourceFiltering) {
|
|
25
24
|
return;
|
|
26
25
|
}
|
|
27
|
-
|
|
28
|
-
UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore.register(this.id);
|
|
26
|
+
super.apply(compiler);
|
|
29
27
|
compiler.hooks.compilation.tap(this.constructor.name, compilation => {
|
|
30
|
-
SpecialAssetHandlingPlugin.hasAttachedAssetCollatorForCurrentBatch = false;
|
|
31
|
-
SpecialAssetHandlingPlugin.semaphore.reset(this.id);
|
|
32
|
-
UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore.reset(this.id);
|
|
33
|
-
compilation.hooks.beforeChunkIds.tap(this.constructor.name, () => {
|
|
34
|
-
if (!SpecialAssetHandlingPlugin.hasAttachedAssetCollatorForCurrentBatch) {
|
|
35
|
-
SpecialAssetHandlingPlugin.hasAttachedAssetCollatorForCurrentBatch = true;
|
|
36
|
-
compilation.hooks.processAssets.tapPromise({ name: `${this.constructor.name}_CompileLoader`, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_REPORT }, () => this.collateAssets(compilation));
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
28
|
compilation.hooks.processAssets.tapPromise({ name: this.constructor.name, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_ANALYSE }, async (assets) => {
|
|
40
29
|
try {
|
|
41
30
|
const specialAssetData = {};
|
|
@@ -71,6 +60,7 @@ class SpecialAssetHandlingPlugin {
|
|
|
71
60
|
}
|
|
72
61
|
catch (e) {
|
|
73
62
|
SpecialAssetHandlingPlugin.semaphore.reject(this.id);
|
|
63
|
+
UnifiedLoaderGenerator_1.UnifiedLoaderGenerator.semaphore.reject(this.id);
|
|
74
64
|
throw e;
|
|
75
65
|
}
|
|
76
66
|
});
|
|
@@ -91,10 +81,11 @@ class SpecialAssetHandlingPlugin {
|
|
|
91
81
|
return;
|
|
92
82
|
}
|
|
93
83
|
if (!this.config.useUnifiedLoader) {
|
|
94
|
-
|
|
84
|
+
(0, shared_1.emitResolveBaseUriFunction)(writer);
|
|
95
85
|
}
|
|
96
86
|
writer.action("wp_head", writer => {
|
|
97
|
-
|
|
87
|
+
const baseUriVar = new php_writer_1.Var("base_uri");
|
|
88
|
+
writer.call("plaudit_webpack_extensions__resolve_base_uri", [php_writer_1.Constants.__DIR__], { assignTo: baseUriVar }).closePHP();
|
|
98
89
|
for (let [filename, { preload, fetchpriority, crossorigin }] of preloadedAssets) {
|
|
99
90
|
if (!preload) {
|
|
100
91
|
continue;
|
|
@@ -133,11 +124,14 @@ class SpecialAssetHandlingPlugin {
|
|
|
133
124
|
attributes.push(["crossorigin", crossorigin]);
|
|
134
125
|
}
|
|
135
126
|
const dynamicAttrs = attributes.map(([k, v]) => v ? `${k}="${v}"` : k).join(" ");
|
|
136
|
-
writer.append(`<link rel="preload" href="<?= esc_url(
|
|
127
|
+
writer.append(`<link rel="preload" href="<?= ${php_writer_1.Expr.call("esc_url", [php_writer_1.Op.join(baseUriVar, filename)])} ?>" ${dynamicAttrs}>`);
|
|
137
128
|
}
|
|
138
129
|
writer.openPHP();
|
|
139
130
|
});
|
|
140
131
|
writer.emitAsset(compilation, outputFile);
|
|
141
132
|
}
|
|
133
|
+
attachSecondPhase(compilation) {
|
|
134
|
+
compilation.hooks.processAssets.tapPromise({ name: this.constructor.name, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_REPORT }, () => this.collateAssets(compilation));
|
|
135
|
+
}
|
|
142
136
|
}
|
|
143
137
|
exports.SpecialAssetHandlingPlugin = SpecialAssetHandlingPlugin;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.UnifiedLoaderGenerator = void 0;
|
|
4
|
+
const shared_1 = require("../shared");
|
|
4
5
|
const pseduo_semaphore_1 = require("../utils/pseduo-semaphore");
|
|
5
6
|
const php_writer_1 = require("../utils/php-writer");
|
|
6
|
-
const PlainEntrypointsConfigFileGeneratorPlugin_1 = require("./PlainEntrypointsConfigFileGeneratorPlugin");
|
|
7
7
|
const webpack_1 = require("webpack");
|
|
8
8
|
class UnifiedLoaderGenerator {
|
|
9
9
|
config;
|
|
@@ -40,7 +40,7 @@ class UnifiedLoaderGenerator {
|
|
|
40
40
|
compilation.hooks.afterProcessAssets.tap(this.constructor.name, () => {
|
|
41
41
|
const writer = new php_writer_1.PHPWriter();
|
|
42
42
|
if (writerCallbacks.some(wc => wc.requiresBaseURI)) {
|
|
43
|
-
|
|
43
|
+
(0, shared_1.emitResolveBaseUriFunction)(writer);
|
|
44
44
|
}
|
|
45
45
|
for (const writerCallback of writerCallbacks) {
|
|
46
46
|
writerCallback.action(writer);
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import { BlockJSONManagingPlugin } from "./BlockJSONManagingPlugin";
|
|
2
1
|
import { type Compiler, type WebpackPluginInstance } from "webpack";
|
|
3
2
|
export declare class WPMLConfigBuilderPlugin implements WebpackPluginInstance {
|
|
4
|
-
private readonly blockJSONManagingPlugin;
|
|
5
3
|
private readonly destDir;
|
|
6
4
|
private static jsdomInstance?;
|
|
7
5
|
private static domParser?;
|
|
8
6
|
private static xmlSerializer?;
|
|
9
7
|
private readonly parsedDocumentsCache;
|
|
10
|
-
constructor(
|
|
8
|
+
constructor(destDir: string);
|
|
11
9
|
apply(compiler: Compiler): void;
|
|
12
10
|
private static getJSDOMInstance;
|
|
13
11
|
private static getDOMParser;
|