@plaudit/webpack-extensions 2.39.0 → 2.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/wordpress-scripts-wrapper/AdditionalDependencyInjectorPlugin.d.ts +2 -1
- package/build/wordpress-scripts-wrapper/AdditionalDependencyInjectorPlugin.js +29 -36
- package/build/wordpress-scripts-wrapper/BlockJSONManagingPlugin.d.ts +1 -0
- package/build/wordpress-scripts-wrapper/BlockJSONManagingPlugin.js +56 -2
- package/build/wordpress-scripts-wrapper/WPMLConfigBuilder.d.ts +16 -0
- package/build/wordpress-scripts-wrapper/WPMLConfigBuilder.js +471 -0
- package/build/wordpress-scripts-wrapper/dependency-extraction-webpack-plugin-config-builder.d.ts +4 -1
- package/build/wordpress-scripts-wrapper/dependency-extraction-webpack-plugin-config-builder.js +22 -9
- package/build/wordpress-scripts-wrapper.d.ts +2 -0
- package/build/wordpress-scripts-wrapper.js +89 -44
- package/package.json +6 -4
|
@@ -2,6 +2,7 @@ import { type Compiler, type WebpackPluginInstance } from "webpack";
|
|
|
2
2
|
export default class AdditionalDependencyInjectorPlugin implements WebpackPluginInstance {
|
|
3
3
|
private readonly entrypointAdditionalDependencies;
|
|
4
4
|
private readonly processingModules;
|
|
5
|
-
|
|
5
|
+
private readonly addExternalizedDep;
|
|
6
|
+
constructor(entrypointAdditionalDependencies: string[], processingModules: boolean, addExternalizedDep: (dep: string) => void);
|
|
6
7
|
apply(compiler: Compiler): void;
|
|
7
8
|
}
|
|
@@ -8,53 +8,46 @@ const webpack_1 = require("webpack");
|
|
|
8
8
|
class AdditionalDependencyInjectorPlugin {
|
|
9
9
|
entrypointAdditionalDependencies;
|
|
10
10
|
processingModules;
|
|
11
|
-
|
|
11
|
+
addExternalizedDep;
|
|
12
|
+
constructor(entrypointAdditionalDependencies, processingModules, addExternalizedDep) {
|
|
12
13
|
this.entrypointAdditionalDependencies = entrypointAdditionalDependencies;
|
|
13
14
|
this.processingModules = processingModules;
|
|
15
|
+
this.addExternalizedDep = addExternalizedDep;
|
|
14
16
|
}
|
|
15
17
|
apply(compiler) {
|
|
16
18
|
compiler.hooks.thisCompilation.tap("AdditionalDependencyInjectorPlugin", compilation => {
|
|
17
19
|
compilation.hooks.processAssets.tap({
|
|
18
|
-
name: "
|
|
19
|
-
stage: webpack_1.Compilation.
|
|
20
|
-
},
|
|
21
|
-
const usableEntrypointTest = this.processingModules ? /\.
|
|
22
|
-
const assetSources = new Map();
|
|
20
|
+
name: "AdditionalDependencyInjectorPlugin_ProcessAssets_AddFakeModules",
|
|
21
|
+
stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS
|
|
22
|
+
}, () => {
|
|
23
|
+
const usableEntrypointTest = this.processingModules ? /\.m[jt]sx?$/i : /\.[jt]sx?$/i;
|
|
23
24
|
for (const entrypoint of compilation.entrypoints.values()) {
|
|
24
25
|
const req = entrypoint.origins.filter(origin => usableEntrypointTest.test(origin.request))[0]?.request;
|
|
25
|
-
if (req) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
if (!req) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const additionalDependencies = [...this.entrypointAdditionalDependencies];
|
|
30
|
+
const firstLine = node_fs_1.default.readFileSync(req, 'utf8').trim().split(/\r?\n/)[0];
|
|
31
|
+
if (firstLine?.startsWith("//ADDITIONAL_DEPENDENCIES:")) {
|
|
32
|
+
additionalDependencies.push(...firstLine.substring(26).trim().split(',').map(dep => dep.trim()));
|
|
33
|
+
}
|
|
34
|
+
const chunk = entrypoint.getEntrypointChunk();
|
|
35
|
+
for (const additionalDep of additionalDependencies) {
|
|
36
|
+
this.addExternalizedDep(additionalDep);
|
|
37
|
+
compilation.chunkGraph.connectChunkAndModule(chunk, new webpack_1.ExternalModule("__REMOVE_ME__", "", additionalDep));
|
|
33
38
|
}
|
|
34
39
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
if (additionalDependencies.length > 0) {
|
|
47
|
-
const seen = new Set();
|
|
48
|
-
const additionalDeps = additionalDependencies.filter(dep => !seen.has(dep) && seen.add(dep)).sort().map(v => `'${v}'`).join(', ');
|
|
49
|
-
if (additionalDeps.length > 0) {
|
|
50
|
-
compilation.updateAsset(name, new webpack_1.sources.RawSource(asset.source().toString()
|
|
51
|
-
.replaceAll(/(?:, )?'wp-[^']+\/[^']+'/gi, '')
|
|
52
|
-
.replace(/('dependencies'\s+=>\s+(?:array\(|\[))(.*)([)\]], 'version')/g, (match, g1, g2, g3) => `${g1}${g2.length > 0 ? `${g2}, ${additionalDeps}` : additionalDeps}${g3}`)));
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
40
|
+
});
|
|
41
|
+
compilation.hooks.processAssets.tap({
|
|
42
|
+
name: "AdditionalDependencyInjectorPlugin_ProcessAssets_RemoveFakeModules",
|
|
43
|
+
stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_REPORT
|
|
44
|
+
}, () => {
|
|
45
|
+
for (const entrypoint of compilation.entrypoints.values()) {
|
|
46
|
+
const entrypointChunk = entrypoint.getEntrypointChunk();
|
|
47
|
+
for (const module of compilation.chunkGraph.getChunkModules(entrypointChunk)) {
|
|
48
|
+
if (module instanceof webpack_1.ExternalModule && module.request === '__REMOVE_ME__') {
|
|
49
|
+
compilation.chunkGraph.disconnectChunkAndModule(entrypointChunk, module);
|
|
55
50
|
}
|
|
56
|
-
compilation.updateAsset(name, new webpack_1.sources.RawSource(asset.source().toString()
|
|
57
|
-
.replaceAll(/(?:, )?'wp-[^']+\/[^']+'/gi, '')));
|
|
58
51
|
}
|
|
59
52
|
}
|
|
60
53
|
});
|
|
@@ -12,6 +12,7 @@ export default class BlockJSONManagingPlugin implements WebpackPluginInstance {
|
|
|
12
12
|
private static readonly blockJSONAssetSourceDirs;
|
|
13
13
|
private static readonly blockJsonAssetKeyMapping;
|
|
14
14
|
private static readonly blockJsonAssetKeyReadinessMapping;
|
|
15
|
+
readonly additionalMetadata: Map<string, any>;
|
|
15
16
|
constructor(standaloneBlocks: boolean, processingModules: boolean);
|
|
16
17
|
static recordRawDependency(entrypoint: string, dependency: string): void;
|
|
17
18
|
static recordBlockJSONAssetSourceDir(entrypoint: string, source: string): void;
|
|
@@ -21,6 +21,7 @@ class BlockJSONManagingPlugin {
|
|
|
21
21
|
static blockJSONAssetSourceDirs = new Map();
|
|
22
22
|
static blockJsonAssetKeyMapping = new Map();
|
|
23
23
|
static blockJsonAssetKeyReadinessMapping = new Map();
|
|
24
|
+
additionalMetadata = new Map();
|
|
24
25
|
constructor(standaloneBlocks, processingModules) {
|
|
25
26
|
this.standaloneBlocks = standaloneBlocks;
|
|
26
27
|
this.processingModules = processingModules;
|
|
@@ -37,6 +38,7 @@ class BlockJSONManagingPlugin {
|
|
|
37
38
|
}
|
|
38
39
|
apply(compiler) {
|
|
39
40
|
compiler.hooks.compilation.tap(this.constructor.name, compilation => {
|
|
41
|
+
this.additionalMetadata.clear();
|
|
40
42
|
this.registerAssetProcessor(compilation);
|
|
41
43
|
if (!this.processingModules) {
|
|
42
44
|
this.registerBlockJsonProcessor(compilation);
|
|
@@ -373,8 +375,46 @@ class BlockJSONManagingPlugin {
|
|
|
373
375
|
compilation[name in compilation.assets ? 'updateAsset' : 'emitAsset'](name, new webpack_1.sources.RawSource(JSON.stringify(json, undefined, " ")));
|
|
374
376
|
blockDirConfigData[node_path_1.default.dirname(name)] = json;
|
|
375
377
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
+
let sortedBlockDirConfigData;
|
|
379
|
+
const blockDirConfigs = Object.entries(blockDirConfigData).sort(([a], [b]) => a.localeCompare(b));
|
|
380
|
+
const rawAssetDataSource = compilation.assets["assets.json"]?.source();
|
|
381
|
+
if (typeof rawAssetDataSource === 'string') {
|
|
382
|
+
const scriptHandles = {};
|
|
383
|
+
const styleHandles = {};
|
|
384
|
+
const rawAssetData = JSON.parse(rawAssetDataSource);
|
|
385
|
+
const mappableKeys = [...BlockJSONManagingPlugin.mappableModuleKeys, ...BlockJSONManagingPlugin.mappableNonModuleKeys];
|
|
386
|
+
for (const [blockFolder, config] of blockDirConfigs) {
|
|
387
|
+
for (const mappableKey of mappableKeys) {
|
|
388
|
+
const cfg = config[mappableKey];
|
|
389
|
+
if (cfg) {
|
|
390
|
+
if (Array.isArray(cfg)) {
|
|
391
|
+
for (let i = 0; i < cfg.length; i++) {
|
|
392
|
+
const assetDetails = getAssetDetails(blockFolder, cfg[i], rawAssetData);
|
|
393
|
+
if (assetDetails) {
|
|
394
|
+
(assetDetails[0] ? styleHandles : scriptHandles)[assetDetails[1]] = assetDetails[2];
|
|
395
|
+
cfg[i] = assetDetails[1];
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
const assetDetails = getAssetDetails(blockFolder, cfg, rawAssetData);
|
|
401
|
+
if (assetDetails) {
|
|
402
|
+
(assetDetails[0] ? styleHandles : scriptHandles)[assetDetails[1]] = assetDetails[2];
|
|
403
|
+
config[mappableKey] = assetDetails[1];
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
sortedBlockDirConfigData = Object.fromEntries([
|
|
410
|
+
["__metadata", { version: 2, ...Object.fromEntries(this.additionalMetadata.entries()), scriptHandles, styleHandles }],
|
|
411
|
+
...blockDirConfigs
|
|
412
|
+
]);
|
|
413
|
+
compilation.deleteAsset("assets.json");
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
sortedBlockDirConfigData = Object.fromEntries([["__metadata", { version: 1, ...Object.fromEntries(this.additionalMetadata.entries()) }], ...blockDirConfigs]);
|
|
417
|
+
}
|
|
378
418
|
compilation.emitAsset("blockdir.config", new webpack_1.sources.RawSource((0, php_serializer_1.default)(sortedBlockDirConfigData, { excludedKeys: ["$schema"] })));
|
|
379
419
|
});
|
|
380
420
|
}
|
|
@@ -447,3 +487,17 @@ function makeSync() {
|
|
|
447
487
|
});
|
|
448
488
|
return res;
|
|
449
489
|
}
|
|
490
|
+
function getAssetDetails(blockFolder, asset, rawAssetData) {
|
|
491
|
+
if (!asset.startsWith("file:./")) {
|
|
492
|
+
return undefined;
|
|
493
|
+
}
|
|
494
|
+
const src = `${blockFolder}/${asset.substring(7)}`;
|
|
495
|
+
const isCss = src.endsWith(".css");
|
|
496
|
+
const assetData = isCss
|
|
497
|
+
? rawAssetData[src.substring(0, src.length - 3) + "js"] ?? rawAssetData[src.substring(0, src.length - 3).replace("style-style", "style") + "js"]
|
|
498
|
+
: rawAssetData[src];
|
|
499
|
+
if (!assetData) {
|
|
500
|
+
return undefined;
|
|
501
|
+
}
|
|
502
|
+
return [isCss, src.substring(0, src.length - (isCss ? 4 : 3)), { src, rest: [assetData.dependencies, assetData.version] }];
|
|
503
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Compiler, type WebpackPluginInstance } from "webpack";
|
|
2
|
+
import BlockJSONManagingPlugin from "./BlockJSONManagingPlugin";
|
|
3
|
+
export default class WPMLConfigBuilder implements WebpackPluginInstance {
|
|
4
|
+
private readonly blockJSONManagingPlugin;
|
|
5
|
+
private static jsdomInstance?;
|
|
6
|
+
private static domParser?;
|
|
7
|
+
private static xmlSerializer?;
|
|
8
|
+
private readonly parsedDocumentsCache;
|
|
9
|
+
constructor(blockJSONManagingPlugin: BlockJSONManagingPlugin);
|
|
10
|
+
apply(compiler: Compiler): void;
|
|
11
|
+
private static getJSDOMInstance;
|
|
12
|
+
private static getDOMParser;
|
|
13
|
+
private static getXMLSerializer;
|
|
14
|
+
private static prettyPrintXML;
|
|
15
|
+
private loadWPMLConfigXML;
|
|
16
|
+
}
|
|
@@ -0,0 +1,471 @@
|
|
|
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
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
7
|
+
const jsdom_1 = require("jsdom");
|
|
8
|
+
const webpack_1 = require("webpack");
|
|
9
|
+
const xml_formatter_1 = __importDefault(require("xml-formatter"));
|
|
10
|
+
class WPMLConfigBuilder {
|
|
11
|
+
blockJSONManagingPlugin;
|
|
12
|
+
static jsdomInstance;
|
|
13
|
+
static domParser;
|
|
14
|
+
static xmlSerializer;
|
|
15
|
+
parsedDocumentsCache = new Map();
|
|
16
|
+
constructor(blockJSONManagingPlugin) {
|
|
17
|
+
this.blockJSONManagingPlugin = blockJSONManagingPlugin;
|
|
18
|
+
}
|
|
19
|
+
apply(compiler) {
|
|
20
|
+
compiler.hooks.compilation.tap(this.constructor.name, compilation => {
|
|
21
|
+
compilation.hooks.processAssets.tapPromise({ name: `${this.constructor.name}__processXML`, stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL }, async (assets) => {
|
|
22
|
+
const entrypoint = compilation.entrypoints.get("wpml-config.xml");
|
|
23
|
+
if (!entrypoint) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const files = Promise.all([
|
|
27
|
+
Promise.all(entrypoint.origins.map(origin => origin.request).filter(request => request.endsWith("wpml-config.xml"))
|
|
28
|
+
.map(async (request) => this.loadWPMLConfigXML(request, compilation))),
|
|
29
|
+
Promise.all(entrypoint.origins.map(origin => origin.request).filter(request => request.endsWith("block.json"))
|
|
30
|
+
.map(async (request) => [JSON.parse(await promises_1.default.readFile(request, 'utf8')), request]))
|
|
31
|
+
]);
|
|
32
|
+
for (const name of Object.keys(assets)) {
|
|
33
|
+
if (name.startsWith("wpml-config.xml")) {
|
|
34
|
+
compilation.deleteAsset(name);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const [wpmlConfigs, blockJsons] = await files;
|
|
38
|
+
if (!wpmlConfigs.length && !blockJsons.length) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const mergedConfig = {
|
|
42
|
+
customFields: {}, customTermFields: {}, customTypes: {}, gutenbergBlocks: {}, shortcodeList: new Set(), shortcodes: {}, taxonomies: {}
|
|
43
|
+
};
|
|
44
|
+
const nonMergeableCategories = ['customFields', 'customTermFields', 'customTypes', 'shortcodes', 'taxonomies'];
|
|
45
|
+
for (const [wpmlConfig, file] of wpmlConfigs) {
|
|
46
|
+
for (const category of nonMergeableCategories) {
|
|
47
|
+
for (const [key, value] of Object.entries(wpmlConfig[category])) {
|
|
48
|
+
if (key in mergedConfig[category]) {
|
|
49
|
+
compilation.errors.push(newWebpackErrorForFile(`Already encountered a definition for the ${category} entry named, "${key}"`, file));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
mergedConfig[category][key] = value;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
for (const shortcode of wpmlConfig.shortcodeList) {
|
|
57
|
+
mergedConfig.shortcodeList.add(shortcode);
|
|
58
|
+
}
|
|
59
|
+
for (const [type, block] of Object.entries(wpmlConfig.gutenbergBlocks)) {
|
|
60
|
+
const existing = mergedConfig.gutenbergBlocks[type];
|
|
61
|
+
try {
|
|
62
|
+
mergedConfig.gutenbergBlocks[type] = existing ? mergeWPMLGutenbergBlocks(existing, block) : block;
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
if (typeof e === 'string') {
|
|
66
|
+
compilation.errors.push(newWebpackErrorForFile(e, file));
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
compilation.errors.push(e);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (const [blockJson, file] of blockJsons) {
|
|
75
|
+
const type = blockJson["name"]?.toString();
|
|
76
|
+
if (typeof type !== 'string') {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const blockConfig = { type, translate: '1', keys: [], xPaths: [] };
|
|
80
|
+
if (blockJson['plaudit']?.['properties']) {
|
|
81
|
+
const snps = blockJson['plaudit']['properties'];
|
|
82
|
+
if (Array.isArray(snps)) {
|
|
83
|
+
for (const snp of snps) {
|
|
84
|
+
convertSNPToKeys(snp, blockConfig.keys);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
convertSNPToKeys(snps, blockConfig.keys);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (typeof blockJson['attributes'] === 'object') {
|
|
92
|
+
for (const [name, { translatable }] of Object.entries(blockJson['attributes'])) {
|
|
93
|
+
if (translatable) {
|
|
94
|
+
blockConfig.keys.push({ name, keys: [] });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const existing = mergedConfig.gutenbergBlocks[blockConfig.type];
|
|
99
|
+
if (blockConfig.keys.length || blockConfig.xPaths.length) {
|
|
100
|
+
mergedConfig.gutenbergBlocks[blockConfig.type] = existing ? mergeWPMLGutenbergBlocks(existing, blockConfig) : blockConfig;
|
|
101
|
+
}
|
|
102
|
+
else if (!existing) {
|
|
103
|
+
mergedConfig.gutenbergBlocks[blockConfig.type] = blockConfig;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const config = WPMLConfigBuilder.getDOMParser().parseFromString("<wpml-config></wpml-config>", "application/xml");
|
|
107
|
+
appendNamedElementsListToConfig("custom-fields", mergedConfig.customFields, config);
|
|
108
|
+
appendNamedElementsListToConfig("custom-term-fields", mergedConfig.customTermFields, config);
|
|
109
|
+
appendNamedElementsListToConfig("custom-types", mergedConfig.customTypes, config);
|
|
110
|
+
const gutenbergBlocks = Object.values(mergedConfig.gutenbergBlocks);
|
|
111
|
+
if (gutenbergBlocks.length) {
|
|
112
|
+
const gutenbergBlocksElement = config.createElement("gutenberg-blocks");
|
|
113
|
+
gutenbergBlocksElement.append(...gutenbergBlocks
|
|
114
|
+
.sort((a, b) => a.type.localeCompare(b.type))
|
|
115
|
+
.map(gutenbergBlock => {
|
|
116
|
+
const gutenbergBlockElement = config.createElement("gutenberg-block");
|
|
117
|
+
gutenbergBlockElement.setAttribute("type", gutenbergBlock.type);
|
|
118
|
+
if (gutenbergBlock.label) {
|
|
119
|
+
gutenbergBlockElement.setAttribute("label", gutenbergBlock.label);
|
|
120
|
+
}
|
|
121
|
+
gutenbergBlockElement.setAttribute("translate", gutenbergBlock.translate);
|
|
122
|
+
writeGenericSettingsKeys(gutenbergBlock.keys, gutenbergBlockElement, config);
|
|
123
|
+
gutenbergBlockElement.append(...gutenbergBlock.xPaths
|
|
124
|
+
.sort((a, b) => a.path.localeCompare(b.path))
|
|
125
|
+
.map(xPath => {
|
|
126
|
+
const xPathElement = config.createElement("xpath");
|
|
127
|
+
writeCommonGenericSettingsItemProps(xPathElement, xPath);
|
|
128
|
+
xPathElement.append(xPath.path);
|
|
129
|
+
return xPathElement;
|
|
130
|
+
}));
|
|
131
|
+
return gutenbergBlockElement;
|
|
132
|
+
}));
|
|
133
|
+
config.documentElement.append(gutenbergBlocksElement);
|
|
134
|
+
}
|
|
135
|
+
if (mergedConfig.shortcodeList.size) {
|
|
136
|
+
const node = config.createElement("shortcode-list");
|
|
137
|
+
node.append([...mergedConfig.shortcodeList].sort().join(","));
|
|
138
|
+
config.documentElement.appendChild(node);
|
|
139
|
+
}
|
|
140
|
+
appendNamedElementsListToConfig("shortcodes", mergedConfig.shortcodes, config);
|
|
141
|
+
appendNamedElementsListToConfig("taxonomies", mergedConfig.taxonomies, config);
|
|
142
|
+
this.blockJSONManagingPlugin.additionalMetadata.set("wpml-config", true);
|
|
143
|
+
compilation["wpml-config.xml" in compilation.assets ? 'updateAsset' : 'emitAsset']("wpml-config.xml", new webpack_1.sources.RawSource(WPMLConfigBuilder.prettyPrintXML(config)));
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
static getJSDOMInstance() {
|
|
148
|
+
return WPMLConfigBuilder.jsdomInstance ?? (WPMLConfigBuilder.jsdomInstance = new jsdom_1.JSDOM("", { contentType: "text/html" }));
|
|
149
|
+
}
|
|
150
|
+
static getDOMParser() {
|
|
151
|
+
return WPMLConfigBuilder.domParser ?? (WPMLConfigBuilder.domParser = new (WPMLConfigBuilder.getJSDOMInstance().window.DOMParser)());
|
|
152
|
+
}
|
|
153
|
+
static getXMLSerializer() {
|
|
154
|
+
return WPMLConfigBuilder.xmlSerializer ?? (WPMLConfigBuilder.xmlSerializer = new (WPMLConfigBuilder.getJSDOMInstance().window.XMLSerializer)());
|
|
155
|
+
}
|
|
156
|
+
static prettyPrintXML(document) {
|
|
157
|
+
return (0, xml_formatter_1.default)(WPMLConfigBuilder.getXMLSerializer().serializeToString(document), {
|
|
158
|
+
indentation: '\t',
|
|
159
|
+
collapseContent: true,
|
|
160
|
+
lineSeparator: '\n',
|
|
161
|
+
whiteSpaceAtEndOfSelfclosingTag: true,
|
|
162
|
+
forceSelfClosingEmptyTag: true,
|
|
163
|
+
strictMode: true,
|
|
164
|
+
filter(node) {
|
|
165
|
+
return node.type === 'Element' || node.type === 'Text';
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
async loadWPMLConfigXML(file, compilation) {
|
|
170
|
+
const contents = await promises_1.default.readFile(file, 'utf8');
|
|
171
|
+
const existing = this.parsedDocumentsCache.get(file);
|
|
172
|
+
if (existing?.raw === contents) {
|
|
173
|
+
return [existing, file];
|
|
174
|
+
}
|
|
175
|
+
const wpmlConfig = WPMLConfigBuilder.getDOMParser().parseFromString(contents.replaceAll(/\s+xmlns=['"][^'"]+['"]/sig, ""), "application/xml");
|
|
176
|
+
const res = { raw: contents, customFields: {}, customTermFields: {}, customTypes: {}, gutenbergBlocks: {}, shortcodeList: new Set(), shortcodes: {}, taxonomies: {} };
|
|
177
|
+
for (const element of wpmlConfig.documentElement.children) {
|
|
178
|
+
switch (element.nodeName) {
|
|
179
|
+
case "custom-fields":
|
|
180
|
+
importStandardTranslateActionMap(element, file, "custom-field", res.customFields, compilation);
|
|
181
|
+
break;
|
|
182
|
+
case "custom-term-fields":
|
|
183
|
+
importStandardTranslateActionMap(element, file, "custom-term-field", res.customTermFields, compilation);
|
|
184
|
+
break;
|
|
185
|
+
case "custom-types":
|
|
186
|
+
importStandardTranslateOptionMap(element, file, "custom-type", res.customTypes, compilation);
|
|
187
|
+
break;
|
|
188
|
+
case "gutenberg-blocks":
|
|
189
|
+
for (const child of element.children) {
|
|
190
|
+
try {
|
|
191
|
+
const block = convertGutenbergBlockToJSRepresentation(child);
|
|
192
|
+
const existing = res.gutenbergBlocks[block.type];
|
|
193
|
+
if (existing) {
|
|
194
|
+
res.gutenbergBlocks[block.type] = mergeWPMLGutenbergBlocks(existing, block);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
res.gutenbergBlocks[block.type] = block;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch (e) {
|
|
201
|
+
if (typeof e === 'string') {
|
|
202
|
+
compilation.errors.push(newWebpackErrorForFile(e, file));
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
compilation.errors.push(e);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
break;
|
|
210
|
+
case "shortcode-list":
|
|
211
|
+
if (element.textContent) {
|
|
212
|
+
for (const shortcode of element.textContent.split(",")) {
|
|
213
|
+
res.shortcodeList.add(shortcode.trim());
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
217
|
+
case "shortcodes":
|
|
218
|
+
for (const child of element.children) {
|
|
219
|
+
const tag = child.getElementsByTagName("tag")[0];
|
|
220
|
+
const shortcodeName = tag?.textContent?.trim();
|
|
221
|
+
if (!shortcodeName) {
|
|
222
|
+
compilation.errors.push(newWebpackErrorForFile(`A shortcode entry in a wpml-config.xml file is missing its tag name.`, file));
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
const existing = res.shortcodes[shortcodeName];
|
|
226
|
+
if (existing) {
|
|
227
|
+
compilation.errors.push(newWebpackErrorForFile(`Already encountered a definition for the shortcode entry named, "${shortcodeName}"`, file));
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
res.shortcodes[shortcodeName] = child;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
case "taxonomies":
|
|
235
|
+
importStandardTranslateOptionMap(element, file, "taxonomy", res.taxonomies, compilation);
|
|
236
|
+
break;
|
|
237
|
+
default:
|
|
238
|
+
compilation.errors.push(newWebpackErrorForFile(`Unsupported element type in a wpml-config.xml file: ${element.nodeName}`, file));
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
this.parsedDocumentsCache.set(file, res);
|
|
243
|
+
return [res, file];
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
exports.default = WPMLConfigBuilder;
|
|
247
|
+
function importStandardTranslateOptionMap(element, file, type, actionMap, compilation) {
|
|
248
|
+
for (const child of element.children) {
|
|
249
|
+
const field = child.textContent;
|
|
250
|
+
if (!field) {
|
|
251
|
+
compilation.errors.push(newWebpackErrorForFile(`Encountered an empty ${type} entry in a wpml-config.xml file.`, file));
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
const translate = child.getAttribute("translate");
|
|
255
|
+
if (!translate) {
|
|
256
|
+
compilation.errors.push(newWebpackErrorForFile(`The ${type} entry for ${field} is missing the translate attribute.`, file));
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
const existing = actionMap[field];
|
|
260
|
+
if (existing) {
|
|
261
|
+
compilation.errors.push(newWebpackErrorForFile(`Already encountered a definition for the ${type} entry named, "${field}"`, file));
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
actionMap[field] = child;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function importStandardTranslateActionMap(element, file, type, actionMap, compilation) {
|
|
269
|
+
for (const child of element.children) {
|
|
270
|
+
const field = child.textContent?.trim();
|
|
271
|
+
if (!field) {
|
|
272
|
+
compilation.errors.push(newWebpackErrorForFile(`Encountered a empty ${type} entry without a name in a wpml-config.xml file.`, file));
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
const action = child.getAttribute("action");
|
|
276
|
+
if (!action) {
|
|
277
|
+
compilation.errors.push(newWebpackErrorForFile(`The ${type} entry for ${field} is missing an action.`, file));
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
const existing = actionMap[field];
|
|
281
|
+
if (existing) {
|
|
282
|
+
compilation.errors.push(newWebpackErrorForFile(`Already encountered a definition for the ${type} entry named, "${field}"`, file));
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
actionMap[field] = child;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function convertSNPToKeys(prop, keys) {
|
|
290
|
+
if (Array.isArray(prop)) {
|
|
291
|
+
for (const p of prop) {
|
|
292
|
+
convertSNPToKeys(p, keys);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
else if ('properties' in prop) {
|
|
296
|
+
for (const item of prop.properties) {
|
|
297
|
+
convertSNPToKeys(item, keys);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
else if ('items' in prop) {
|
|
301
|
+
for (const item of prop.items) {
|
|
302
|
+
convertSNPToKeys(item, keys);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
if (prop.translatable) {
|
|
307
|
+
keys.push({ name: prop.name, keys: [] });
|
|
308
|
+
}
|
|
309
|
+
else if ('fields' in prop) {
|
|
310
|
+
if (prop.fields) {
|
|
311
|
+
const nestedKeys = [];
|
|
312
|
+
convertSNPToKeys(prop.fields, nestedKeys);
|
|
313
|
+
if (nestedKeys.length) {
|
|
314
|
+
keys.push({ name: prop.name, keys: nestedKeys });
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
else if ('itemType' in prop && Array.isArray(prop.itemType)) {
|
|
319
|
+
const nestedKeys = [];
|
|
320
|
+
convertSNPToKeys(prop.itemType, nestedKeys);
|
|
321
|
+
if (nestedKeys.length) {
|
|
322
|
+
keys.push({ name: prop.name, keys: nestedKeys });
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
function convertGutenbergBlockToJSRepresentation(element) {
|
|
328
|
+
const type = element.getAttribute("type");
|
|
329
|
+
if (!type) {
|
|
330
|
+
throw `A gutenberg-block entry in a wpml-config.xml file is missing its type attribute.`;
|
|
331
|
+
}
|
|
332
|
+
const translate = element.getAttribute("translate");
|
|
333
|
+
if (!translate) {
|
|
334
|
+
throw `The gutenberg-block entry for ${type} is missing its translate attribute.`;
|
|
335
|
+
}
|
|
336
|
+
if (translate !== '0' && translate !== '1') {
|
|
337
|
+
throw `The gutenberg-block entry for ${type} has an invalid translate attribute. Expected 0 or 1, but got, "${translate}"`;
|
|
338
|
+
}
|
|
339
|
+
const keys = [];
|
|
340
|
+
const xPaths = [];
|
|
341
|
+
for (const child of element.children) {
|
|
342
|
+
if (child.nodeName === 'key') {
|
|
343
|
+
keys.push(convertGenericSettingsKeyToJSRepresentation(child, `a gutenberg-block entry for ${type}`));
|
|
344
|
+
}
|
|
345
|
+
else if (child.nodeName === 'xpath') {
|
|
346
|
+
xPaths.push(convertGenericSettingsXPathToJSRepresentation(child, `a gutenberg-block entry for ${type}`));
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
throw `The gutenberg-block entry for ${type} has an unsupported child node ("${child.nodeName}")`;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return { type, label: element.getAttribute("label"), translate, keys, xPaths };
|
|
353
|
+
}
|
|
354
|
+
function convertGenericSettingsKeyToJSRepresentation(element, containerName) {
|
|
355
|
+
const name = element.getAttribute("name");
|
|
356
|
+
if (!name) {
|
|
357
|
+
throw `Encountered a key without a name in ${containerName}.`;
|
|
358
|
+
}
|
|
359
|
+
let encoding = element.getAttribute("encoding");
|
|
360
|
+
if (encoding && encoding !== 'json') {
|
|
361
|
+
throw `Encountered an invalid encoding on a key named, "${name}" in ${containerName}. It must be either blank or JSON`;
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
encoding = null;
|
|
365
|
+
}
|
|
366
|
+
let searchMethod = element.getAttribute("searchMethod");
|
|
367
|
+
if (searchMethod && searchMethod !== 'wildcards' && searchMethod !== 'regex') {
|
|
368
|
+
throw `Encountered an invalid search-method on a key named, "${name}" in ${containerName}. It must be either blank or JSON`;
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
searchMethod = null;
|
|
372
|
+
}
|
|
373
|
+
return {
|
|
374
|
+
name,
|
|
375
|
+
label: element.getAttribute("label"),
|
|
376
|
+
type: element.getAttribute("type"),
|
|
377
|
+
subType: element.getAttribute("sub-type"),
|
|
378
|
+
encoding,
|
|
379
|
+
searchMethod,
|
|
380
|
+
keys: [...element.children].map(child => convertGenericSettingsKeyToJSRepresentation(child, containerName))
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
function convertGenericSettingsXPathToJSRepresentation(element, containerName) {
|
|
384
|
+
if (!element.textContent) {
|
|
385
|
+
throw `Encountered an empty XPath in ${containerName}.`;
|
|
386
|
+
}
|
|
387
|
+
return {
|
|
388
|
+
path: element.textContent,
|
|
389
|
+
label: element.getAttribute("label"),
|
|
390
|
+
type: element.getAttribute("type"),
|
|
391
|
+
subType: element.getAttribute("sub-type")
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
function mergeWPMLGutenbergBlocks(existing, novel) {
|
|
395
|
+
if (novel.type && existing.type !== novel.type) {
|
|
396
|
+
throw `Cannot merge WPML Gutenberg Blocks of differing types`;
|
|
397
|
+
}
|
|
398
|
+
if (novel.translate && existing.translate !== novel.translate) {
|
|
399
|
+
throw `Cannot merge WPML Gutenberg Blocks (${existing.type} and ${novel.type ?? existing.type}) with differing translate values`;
|
|
400
|
+
}
|
|
401
|
+
return {
|
|
402
|
+
type: existing.type,
|
|
403
|
+
translate: existing.translate,
|
|
404
|
+
label: novel.label ?? existing.label,
|
|
405
|
+
keys: novel.keys?.length ? (existing.keys.length ? mergeGenericSettingsKeyLists(existing.keys, novel.keys) : novel.keys) : existing.keys,
|
|
406
|
+
xPaths: novel.xPaths?.length ? (existing.xPaths.length ? [...existing.xPaths, ...novel.xPaths] : novel.xPaths) : existing.xPaths
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
function mergeGenericSettingsKeyLists(existingKeys, novelKeys) {
|
|
410
|
+
const keys = {};
|
|
411
|
+
for (const key of existingKeys) {
|
|
412
|
+
const existing = keys[key.name];
|
|
413
|
+
keys[key.name] = existing ? mergeGenericSettingsKeys(existing, key) : key;
|
|
414
|
+
}
|
|
415
|
+
for (const key of novelKeys) {
|
|
416
|
+
const existing = keys[key.name];
|
|
417
|
+
keys[key.name] = existing ? mergeGenericSettingsKeys(existing, key) : key;
|
|
418
|
+
}
|
|
419
|
+
return Object.values(keys);
|
|
420
|
+
}
|
|
421
|
+
function mergeGenericSettingsKeys(existing, novel) {
|
|
422
|
+
if (existing.encoding && novel.encoding && existing.encoding !== novel.encoding) {
|
|
423
|
+
throw `Cannot merge WPMLGenericSettingsKeys with differing encoding values (${existing.encoding} and ${novel.encoding}) on ${novel.name}.`;
|
|
424
|
+
}
|
|
425
|
+
if (existing.searchMethod && novel.searchMethod && existing.searchMethod !== novel.searchMethod) {
|
|
426
|
+
throw `Cannot merge WPMLGenericSettingsKeys with differing search-method values (${existing.searchMethod} and ${novel.searchMethod}) on ${novel.name}.`;
|
|
427
|
+
}
|
|
428
|
+
return { ...existing, ...novel, keys: mergeGenericSettingsKeyLists(existing.keys, novel.keys) };
|
|
429
|
+
}
|
|
430
|
+
function newWebpackErrorForFile(error, file) {
|
|
431
|
+
const res = new webpack_1.WebpackError(error);
|
|
432
|
+
res.hideStack = true;
|
|
433
|
+
res.file = file;
|
|
434
|
+
return res;
|
|
435
|
+
}
|
|
436
|
+
function writeGenericSettingsKeys(keys, parent, document) {
|
|
437
|
+
parent.append(...keys.sort((a, b) => a.name.localeCompare(b.name)).map(key => {
|
|
438
|
+
const element = document.createElement("key");
|
|
439
|
+
element.setAttribute("name", key.name);
|
|
440
|
+
writeCommonGenericSettingsItemProps(element, key);
|
|
441
|
+
if (key.encoding) {
|
|
442
|
+
element.setAttribute("encoding", key.encoding);
|
|
443
|
+
}
|
|
444
|
+
if (key.searchMethod) {
|
|
445
|
+
element.setAttribute("search-method", key.searchMethod);
|
|
446
|
+
}
|
|
447
|
+
writeGenericSettingsKeys(key.keys, element, document);
|
|
448
|
+
return element;
|
|
449
|
+
}));
|
|
450
|
+
}
|
|
451
|
+
function appendNamedElementsListToConfig(containerName, elements, config) {
|
|
452
|
+
const allElements = Object.entries(elements);
|
|
453
|
+
if (allElements.length) {
|
|
454
|
+
const containerElement = config.createElement(containerName);
|
|
455
|
+
config.documentElement.append(containerElement);
|
|
456
|
+
containerElement.append(...allElements
|
|
457
|
+
.sort(([fieldNameA], [fieldNameB]) => fieldNameA.localeCompare(fieldNameB))
|
|
458
|
+
.map(([_, element]) => element));
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
function writeCommonGenericSettingsItemProps(element, item) {
|
|
462
|
+
if (item.label) {
|
|
463
|
+
element.setAttribute("label", item.label);
|
|
464
|
+
}
|
|
465
|
+
if (item.type) {
|
|
466
|
+
element.setAttribute("type", item.type);
|
|
467
|
+
}
|
|
468
|
+
if (item.subType) {
|
|
469
|
+
element.setAttribute("sub-type", item.subType);
|
|
470
|
+
}
|
|
471
|
+
}
|
package/build/wordpress-scripts-wrapper/dependency-extraction-webpack-plugin-config-builder.d.ts
CHANGED
|
@@ -6,4 +6,7 @@ export type IndividualExternalDepConfig = string | {
|
|
|
6
6
|
export type Externals = {
|
|
7
7
|
[dep: string]: IndividualExternalDepConfig;
|
|
8
8
|
};
|
|
9
|
-
export declare function makeDependencyExtractionPlugin(externals: Externals | undefined, assumeGlobalizedPlauditLibraries: boolean):
|
|
9
|
+
export declare function makeDependencyExtractionPlugin(externals: Externals | undefined, assumeGlobalizedPlauditLibraries: boolean, wantsGroupedDepData: boolean): {
|
|
10
|
+
instance: DependencyExtractionWebpackPlugin;
|
|
11
|
+
addExternalizedDep: (dep: string) => void;
|
|
12
|
+
};
|
package/build/wordpress-scripts-wrapper/dependency-extraction-webpack-plugin-config-builder.js
CHANGED
|
@@ -5,15 +5,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.makeDependencyExtractionPlugin = makeDependencyExtractionPlugin;
|
|
7
7
|
const dependency_extraction_webpack_plugin_1 = __importDefault(require("@wordpress/dependency-extraction-webpack-plugin"));
|
|
8
|
-
function makeDependencyExtractionPlugin(externals, assumeGlobalizedPlauditLibraries) {
|
|
8
|
+
function makeDependencyExtractionPlugin(externals, assumeGlobalizedPlauditLibraries, wantsGroupedDepData) {
|
|
9
|
+
const baseProps = makeDependencyExtractionPluginProps(externals, assumeGlobalizedPlauditLibraries);
|
|
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
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function makeDependencyExtractionPluginProps(externals, assumeGlobalizedPlauditLibraries) {
|
|
9
19
|
if (!externals) {
|
|
10
20
|
if (assumeGlobalizedPlauditLibraries) {
|
|
11
|
-
return
|
|
21
|
+
return {
|
|
12
22
|
requestToExternal: plauditRequestToExternal,
|
|
13
23
|
requestToHandle: plauditRequestToHandle
|
|
14
|
-
}
|
|
24
|
+
};
|
|
15
25
|
}
|
|
16
|
-
return
|
|
26
|
+
return {};
|
|
17
27
|
}
|
|
18
28
|
const exactExternals = {};
|
|
19
29
|
const suffixExternals = [];
|
|
@@ -54,15 +64,18 @@ function makeDependencyExtractionPlugin(externals, assumeGlobalizedPlauditLibrar
|
|
|
54
64
|
}
|
|
55
65
|
return undefined;
|
|
56
66
|
};
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
if (assumeGlobalizedPlauditLibraries) {
|
|
68
|
+
return {
|
|
59
69
|
requestToExternal: curryRequestHandlers(baselineRequestToExternal, plauditRequestToExternal),
|
|
60
70
|
requestToHandle: curryRequestHandlers(baselineRequestToHandle, plauditRequestToHandle),
|
|
61
|
-
}
|
|
62
|
-
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
return {
|
|
63
75
|
requestToExternal: baselineRequestToExternal,
|
|
64
76
|
requestToHandle: baselineRequestToHandle,
|
|
65
|
-
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
66
79
|
}
|
|
67
80
|
const PLAUDIT_NAMESPACE = '@plaudit/';
|
|
68
81
|
const EXTERNALIZABLE_PLAUDIT_LIBRARIES = ['@plaudit/library-extensions'];
|
|
@@ -19,6 +19,8 @@ type PlauditWordpressWebpackConfig = {
|
|
|
19
19
|
};
|
|
20
20
|
externals?: Externals;
|
|
21
21
|
assumeGlobalizedPlauditLibraries?: boolean;
|
|
22
|
+
processTranslationConfigs?: boolean;
|
|
23
|
+
combineAssetMetadata?: boolean;
|
|
22
24
|
};
|
|
23
25
|
declare const _default: (config: PlauditWordpressWebpackConfig, webpackConfig?: Configuration[] | Configuration) => Configuration[];
|
|
24
26
|
export = _default;
|
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
6
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
6
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
7
8
|
const AdditionalDependencyInjectorPlugin_1 = __importDefault(require("./wordpress-scripts-wrapper/AdditionalDependencyInjectorPlugin"));
|
|
8
9
|
const BlockJSONManagingPlugin_1 = __importDefault(require("./wordpress-scripts-wrapper/BlockJSONManagingPlugin"));
|
|
@@ -12,6 +13,7 @@ const MiniCSSExtractPluginErrorCleaner_1 = __importDefault(require("./wordpress-
|
|
|
12
13
|
const VariablesJSMonitorPlugin_1 = __importDefault(require("./wordpress-scripts-wrapper/VariablesJSMonitorPlugin"));
|
|
13
14
|
const BrowserSyncPlugin_1 = require("./wordpress-scripts-wrapper/BrowserSyncPlugin");
|
|
14
15
|
const static_configs_1 = require("./wordpress-scripts-wrapper/static-configs");
|
|
16
|
+
const WPMLConfigBuilder_1 = __importDefault(require("./wordpress-scripts-wrapper/WPMLConfigBuilder"));
|
|
15
17
|
const dependency_extraction_webpack_plugin_1 = __importDefault(require("@wordpress/dependency-extraction-webpack-plugin"));
|
|
16
18
|
const copy_webpack_plugin_1 = __importDefault(require("copy-webpack-plugin"));
|
|
17
19
|
const fork_ts_checker_webpack_plugin_1 = __importDefault(require("fork-ts-checker-webpack-plugin"));
|
|
@@ -246,7 +248,7 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
|
|
|
246
248
|
scriptExtension = scriptWithoutModuleExtension;
|
|
247
249
|
entrypointFields = ["editorStyle", "viewStyle", "style", "editorScript", "viewScript", "script"];
|
|
248
250
|
}
|
|
249
|
-
const { standaloneBlocks, variablesFilePath, verbose, externals, assumeGlobalizedPlauditLibraries } = config;
|
|
251
|
+
const { standaloneBlocks, variablesFilePath, verbose, externals, assumeGlobalizedPlauditLibraries, combineAssetMetadata } = config;
|
|
250
252
|
let currentVariables = config.currentVariables;
|
|
251
253
|
const fixedRules = [
|
|
252
254
|
replaceDefaultURLProcessing,
|
|
@@ -255,6 +257,16 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
|
|
|
255
257
|
},
|
|
256
258
|
injectSupportForInliningSVGsAsStrings
|
|
257
259
|
].reduce((r, a) => a(r), webpackConfig.module?.rules ?? []);
|
|
260
|
+
if (config.processTranslationConfigs) {
|
|
261
|
+
fixedRules.push({
|
|
262
|
+
test: /wpml-config\.xml$/i,
|
|
263
|
+
type: 'asset/resource',
|
|
264
|
+
generator: {
|
|
265
|
+
filename: '[name][ext]',
|
|
266
|
+
emit: false
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
}
|
|
258
270
|
return sources.map(([src, dest]) => {
|
|
259
271
|
const srcRoots = (typeof dest !== 'string' && dest.withLegacyBlocksIn
|
|
260
272
|
? [...src.split(','), ...resolveLegacyBlockScriptsInFolder(dest.withLegacyBlocksIn)]
|
|
@@ -302,22 +314,26 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
|
|
|
302
314
|
if (variablesFilePath) {
|
|
303
315
|
plugins.push(new VariablesJSMonitorPlugin_1.default(variablesFilePath));
|
|
304
316
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
317
|
+
const forBlocksDirectory = copyFiles && (typeof dest === 'string' || dest.directoryLayout !== 'extensions');
|
|
318
|
+
if (forBlocksDirectory) {
|
|
319
|
+
const blockJSONManagingPlugin = new BlockJSONManagingPlugin_1.default(standaloneBlocks, processingModules);
|
|
320
|
+
plugins.push(blockJSONManagingPlugin);
|
|
321
|
+
if (config.processTranslationConfigs && srcIsDirectory && !processingModules) {
|
|
322
|
+
plugins.push(new WPMLConfigBuilder_1.default(blockJSONManagingPlugin));
|
|
323
|
+
}
|
|
311
324
|
}
|
|
312
325
|
const pluginIndex = plugins.findIndex(plugin => plugin instanceof dependency_extraction_webpack_plugin_1.default);
|
|
313
326
|
if (pluginIndex === -1) {
|
|
314
327
|
console.error("Cannot apply externals when they have been disabled via CLI flag. This will greatly increase bundle size and will likely cause the build to file");
|
|
315
328
|
}
|
|
316
329
|
else {
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
330
|
+
const localAssumeGlobalizedPlauditLibraries = typeof dest !== 'string' ? dest.assumeGlobalizedPlauditLibraries : undefined;
|
|
331
|
+
const builtDependencyExtractionWebpackPlugin = (0, dependency_extraction_webpack_plugin_config_builder_1.makeDependencyExtractionPlugin)(externals, localAssumeGlobalizedPlauditLibraries ?? assumeGlobalizedPlauditLibraries, combineAssetMetadata && !processingModules && forBlocksDirectory);
|
|
332
|
+
plugins[pluginIndex] = builtDependencyExtractionWebpackPlugin.instance;
|
|
333
|
+
plugins.push(new AdditionalDependencyInjectorPlugin_1.default(typeof dest !== 'string' && dest.additionalDependencies ? dest.additionalDependencies : [], processingModules, builtDependencyExtractionWebpackPlugin.addExternalizedDep));
|
|
334
|
+
}
|
|
335
|
+
if (srcIsDirectory && (typeof dest !== 'string' && dest.directoryLayout === 'extensions')) {
|
|
336
|
+
plugins.push(new ExtensionsConfigFileGeneratorPlugin_1.default(srcRoot));
|
|
321
337
|
}
|
|
322
338
|
if (process.argv.includes('--browser-sync') || process.env['BROWSER_SYNC'] === 'true') {
|
|
323
339
|
plugins.push(new BrowserSyncPlugin_1.BrowserSyncPlugin());
|
|
@@ -325,50 +341,69 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
|
|
|
325
341
|
let entry;
|
|
326
342
|
if (srcIsDirectory) {
|
|
327
343
|
if (typeof dest !== 'string' && dest.directoryLayout === 'extensions') {
|
|
328
|
-
entry = () => {
|
|
329
|
-
const rawEntrypoints =
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
344
|
+
entry = async () => {
|
|
345
|
+
const rawEntrypoints = [];
|
|
346
|
+
for await (const dirent of await promises_1.default.opendir(srcRoot)) {
|
|
347
|
+
if (dirent.isFile()) {
|
|
348
|
+
if (scriptExtension.test(dirent.name) || styleExtension.test(dirent.name)) {
|
|
349
|
+
const file = joinPossiblyAbsolutePaths(srcRoot, dirent.name);
|
|
350
|
+
rawEntrypoints.push([node_path_1.default.basename(file, node_path_1.default.extname(file)), file]);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
333
354
|
return Object.fromEntries(rawEntrypoints);
|
|
334
355
|
};
|
|
335
356
|
}
|
|
336
357
|
else {
|
|
337
|
-
entry = () => {
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
const res = [];
|
|
343
|
-
try {
|
|
344
|
-
const blockJSON = JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.join(dir, 'block.json'), 'utf8'));
|
|
345
|
-
const blockJSONChunkName = node_path_1.default.join(node_path_1.default.basename(dir), "block.json");
|
|
346
|
-
for (const key of entrypointFields) {
|
|
347
|
-
if (key in blockJSON) {
|
|
348
|
-
res.push(...mapToRealEntrypoints(blockJSON[key], dir, ep => ep.startsWith("file:") ? ep.substring(5) : ep, blockJSONChunkName));
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
BlockJSONManagingPlugin_1.default.recordBlockJSONAssetSourceDir(blockJSONChunkName, dir);
|
|
352
|
-
return res;
|
|
358
|
+
entry = async () => {
|
|
359
|
+
const loadingEntrypoints = [];
|
|
360
|
+
for await (const dirent of await promises_1.default.opendir(srcRoot)) {
|
|
361
|
+
if (!dirent.isDirectory()) {
|
|
362
|
+
continue;
|
|
353
363
|
}
|
|
354
|
-
|
|
364
|
+
const dir = joinPossiblyAbsolutePaths(srcRoot, dirent.name);
|
|
365
|
+
loadingEntrypoints.push(new Promise(async (resolve) => {
|
|
366
|
+
const rawEntrypoints = [];
|
|
367
|
+
const wpmlFiles = [];
|
|
355
368
|
try {
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
369
|
+
const blockJSON = JSON.parse(await promises_1.default.readFile(node_path_1.default.join(dir, 'block.json'), 'utf8'));
|
|
370
|
+
const blockJSONChunkName = node_path_1.default.join(node_path_1.default.basename(dir), "block.json");
|
|
371
|
+
for (const key of entrypointFields) {
|
|
372
|
+
if (key in blockJSON) {
|
|
373
|
+
rawEntrypoints.push(...mapToRealEntrypoints(blockJSON[key], dir, ep => ep.startsWith("file:") ? ep.substring(5) : ep, blockJSONChunkName));
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
wpmlFiles.push(node_path_1.default.join(dir, 'block.json'));
|
|
377
|
+
BlockJSONManagingPlugin_1.default.recordBlockJSONAssetSourceDir(blockJSONChunkName, dir);
|
|
359
378
|
}
|
|
360
379
|
catch (e) {
|
|
361
380
|
try {
|
|
362
|
-
|
|
381
|
+
const packageJSON = JSON.parse(await promises_1.default.readFile(node_path_1.default.join(dir, 'package.json'), 'utf8'));
|
|
382
|
+
rawEntrypoints.push(...mapToRealEntrypoints(packageJSON['main'], dir));
|
|
383
|
+
rawEntrypoints.push(...mapToRealEntrypoints(packageJSON['style'], dir));
|
|
363
384
|
}
|
|
364
385
|
catch (e) {
|
|
365
|
-
|
|
386
|
+
try {
|
|
387
|
+
rawEntrypoints.push(...parseEntrypointsJSON(dir));
|
|
388
|
+
}
|
|
389
|
+
catch (e) {
|
|
390
|
+
// This just means that the directory doesn't contain any declared entrypoints.
|
|
391
|
+
}
|
|
366
392
|
}
|
|
367
393
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
394
|
+
try {
|
|
395
|
+
const wpmlFilePath = node_path_1.default.join(dir, "wpml-config.xml");
|
|
396
|
+
await promises_1.default.access(wpmlFilePath);
|
|
397
|
+
wpmlFiles.push(wpmlFilePath);
|
|
398
|
+
}
|
|
399
|
+
catch (e) {
|
|
400
|
+
// This just means that the file doesn't exist
|
|
401
|
+
}
|
|
402
|
+
resolve([rawEntrypoints, wpmlFiles]);
|
|
403
|
+
}));
|
|
404
|
+
}
|
|
405
|
+
const allEntrypoints = await Promise.all(loadingEntrypoints);
|
|
406
|
+
const perAssetPathGroupedEntrypoints = groupEntrypointsByAssetFile(allEntrypoints.flatMap(e => e[0]), e => e[0]);
|
|
372
407
|
const currentEntry = {};
|
|
373
408
|
for (const groupedEntrypoints of perAssetPathGroupedEntrypoints.values()) {
|
|
374
409
|
if (groupedEntrypoints.length === 1 && groupedEntrypoints[0] !== undefined) {
|
|
@@ -387,6 +422,16 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
|
|
|
387
422
|
BlockJSONManagingPlugin_1.default.recordRawDependency(entry.lazyDependent, key);
|
|
388
423
|
}
|
|
389
424
|
}
|
|
425
|
+
const wpmlEntrypointFiles = allEntrypoints.flatMap(e => e[1]);
|
|
426
|
+
try {
|
|
427
|
+
await promises_1.default.access(node_path_1.default.join(srcRoot, "wpml-config.xml"));
|
|
428
|
+
currentEntry["wpml-config.xml"] = { import: [node_path_1.default.join(srcRoot, "wpml-config.xml"), ...wpmlEntrypointFiles] };
|
|
429
|
+
}
|
|
430
|
+
catch (e) {
|
|
431
|
+
if (wpmlEntrypointFiles.length) {
|
|
432
|
+
currentEntry["wpml-config.xml"] = { import: wpmlEntrypointFiles };
|
|
433
|
+
}
|
|
434
|
+
}
|
|
390
435
|
return currentEntry;
|
|
391
436
|
};
|
|
392
437
|
}
|
|
@@ -469,13 +514,13 @@ function processIndividualWebpackConfig(config, webpackConfig, sources) {
|
|
|
469
514
|
}
|
|
470
515
|
module.exports = function (config, webpackConfig = require("@wordpress/scripts/config/webpack.config")) {
|
|
471
516
|
testForDuplicatedEntryPaths(config);
|
|
472
|
-
const { standaloneBlocks = false, stats = 'errors-warnings', variables: rawVariables, verbose = process.argv.includes('--verbose') || process.env['VERBOSE'] === 'true', postcss = {}, externals, assumeGlobalizedPlauditLibraries = true } = config;
|
|
517
|
+
const { standaloneBlocks = false, stats = 'errors-warnings', variables: rawVariables, verbose = process.argv.includes('--verbose') || process.env['VERBOSE'] === 'true', postcss = {}, externals, assumeGlobalizedPlauditLibraries = true, processTranslationConfigs = true, combineAssetMetadata = true } = config;
|
|
473
518
|
let variablesFilePath = undefined;
|
|
474
519
|
const currentVariables = rawVariables ?? {};
|
|
475
520
|
if (!rawVariables) {
|
|
476
521
|
variablesFilePath = ["variables.js", "src/site/variables.js"].map(p => node_path_1.default.join(process.cwd(), p)).filter(p => node_fs_1.default.existsSync(p))[0];
|
|
477
522
|
}
|
|
478
|
-
const cfg = { currentVariables, postcss, standaloneBlocks, stats, variablesFilePath, verbose, externals, assumeGlobalizedPlauditLibraries };
|
|
523
|
+
const cfg = { currentVariables, postcss, standaloneBlocks, stats, variablesFilePath, verbose, externals, assumeGlobalizedPlauditLibraries, processTranslationConfigs, combineAssetMetadata };
|
|
479
524
|
const sources = Array.isArray(config.src) ? config.src.map(s => [s, s]) : Object.entries(config.src);
|
|
480
525
|
if (Array.isArray(webpackConfig)) {
|
|
481
526
|
return webpackConfig.toSorted((a, b) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plaudit/webpack-extensions",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.40.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"prepublishOnly": "rm -rf build && mkdir build && tsc",
|
|
@@ -21,8 +21,9 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
+
"@plaudit/gutenberg-api-extensions": "^2.66.0",
|
|
24
25
|
"@types/browser-sync-webpack-plugin": "^2.2.5",
|
|
25
|
-
"@types/node": "^22.13.
|
|
26
|
+
"@types/node": "^22.13.13",
|
|
26
27
|
"@types/postcss-functions": "^4.0.4",
|
|
27
28
|
"@types/tapable": "^2.2.7",
|
|
28
29
|
"@types/webpack": "^5.28.5",
|
|
@@ -42,7 +43,7 @@
|
|
|
42
43
|
"autoprefixer": "^10.4.21",
|
|
43
44
|
"browser-sync": "^3.0.3",
|
|
44
45
|
"clean-webpack-plugin": "^4.0.0",
|
|
45
|
-
"copy-webpack-plugin": "^
|
|
46
|
+
"copy-webpack-plugin": "^10.2.4",
|
|
46
47
|
"cssnano": "^6.1.2",
|
|
47
48
|
"eslint": "^8.57.1",
|
|
48
49
|
"eslint-plugin-jsdoc": "^48.11.0",
|
|
@@ -69,7 +70,8 @@
|
|
|
69
70
|
"react": "^18.3.1",
|
|
70
71
|
"react-dom": "^18.3.1",
|
|
71
72
|
"webpack": "^5.98.0",
|
|
72
|
-
"webpack-remove-empty-scripts": "^1.0.4"
|
|
73
|
+
"webpack-remove-empty-scripts": "^1.0.4",
|
|
74
|
+
"xml-formatter": "^3.6.5"
|
|
73
75
|
},
|
|
74
76
|
"engines": {
|
|
75
77
|
"node": ">=20"
|