@plaudit/webpack-extensions 2.58.0 → 2.58.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.
@@ -60,14 +60,14 @@ class ExtensionsConfigFileGeneratorPlugin {
60
60
  }
61
61
  writer
62
62
  .use("Plaudit\\Base\\API\\ThemeUtils")
63
+ .withScope(writer => writer
63
64
  .assign("$filePathPrefix", new php_writer_1.Expr(`__DIR__.${php_writer_1.Expr.convertJsonToPHP(finalExtensionsDest)}`))
64
65
  .call("plaudit_webpack_extensions__resolve_base_uri", [new php_writer_1.Expr("$filePathPrefix")], { assignTo: "$fileUriPrefix" })
65
66
  .call("ThemeUtils::loadExtensionsV2", [
66
67
  new php_writer_1.Expr(`__DIR__.${php_writer_1.Expr.convertJsonToPHP(finalExtensionsDest + "mapping.config.php")}`),
67
68
  new php_writer_1.Expr(`$filePathPrefix`), new php_writer_1.Expr("$fileUriPrefix"),
68
69
  `${this.handlePrefix ? this.handlePrefix : node_path_1.default.basename(process.cwd())}_extension_`
69
- ])
70
- .call("unset", [new php_writer_1.Expr("$filePathPrefix"), new php_writer_1.Expr("$fileUriPrefix")]);
70
+ ]));
71
71
  }]);
72
72
  });
73
73
  compilation.hooks.processAssets.tapPromise(tapName, async (assets) => {
@@ -24,11 +24,13 @@ export declare class PHPWriter {
24
24
  private printingInPHP;
25
25
  private fileNamespace;
26
26
  private useList;
27
+ private scopeStack;
27
28
  constructor(inlineFirstLine?: boolean);
28
29
  indent(): this;
29
30
  outdent(): this;
30
31
  append(...lines: (string | Expr)[]): this;
31
32
  assign(variable: string | string[], expression: unknown | Expr, opts?: {
33
+ chain?: boolean;
32
34
  return?: boolean;
33
35
  }): this;
34
36
  return(line: string | Expr): this;
@@ -39,7 +41,7 @@ export declare class PHPWriter {
39
41
  linebreak(): this;
40
42
  call(func: string, args: unknown[], opts?: {
41
43
  chain?: boolean;
42
- assignTo?: string;
44
+ assignTo?: string | string[];
43
45
  return?: boolean;
44
46
  }): this;
45
47
  action(name: string | Expr, contents: (writer: this) => void, args?: ActionOrFilterArgs): this;
@@ -54,6 +56,24 @@ export declare class PHPWriter {
54
56
  openPHP(): this;
55
57
  namespace(namespace: string): this;
56
58
  use(...uses: string[]): this;
59
+ /**
60
+ * Starts a scope that, when paired with {@link #closeScope()}, allows for automating unset calls.
61
+ * All scopes started MUST be paired with either an {@link #closeScope()} or {@link #popScope()} call.
62
+ */
63
+ openScope(): this;
64
+ /**
65
+ * Pops the top scope from the stack AND unsets all variables that were assigned within it
66
+ */
67
+ closeScope(): this;
68
+ /**
69
+ * Pops the top scope from the stack WITHOUT calling unset for the variables that were assigned within it.
70
+ * This is used to allow function bodies to be safely created without disrupting their containing scope.
71
+ */
72
+ popScope(): this;
73
+ withScope(code: (writer: this) => void, opts?: {
74
+ actionDescription?: string;
75
+ usePopScopeInstead?: boolean;
76
+ }): this;
57
77
  toString(): string;
58
78
  emitAsset(compilation: Compilation, file: string, assetInfo?: AssetInfo): void;
59
79
  }
@@ -27,6 +27,7 @@ class PHPWriter {
27
27
  printingInPHP = true;
28
28
  fileNamespace = "";
29
29
  useList = [];
30
+ scopeStack = [];
30
31
  constructor(inlineFirstLine = false) {
31
32
  this.inlineFirstLine = inlineFirstLine;
32
33
  }
@@ -45,12 +46,24 @@ class PHPWriter {
45
46
  return this;
46
47
  }
47
48
  assign(variable, expression, opts = {}) {
48
- const lineComponents = (typeof variable === 'string' ? [variable] : variable).map(v => `${v} =`);
49
+ let lineComponents;
50
+ if (typeof variable === 'string') {
51
+ if (this.scopeStack.length > 0) {
52
+ this.scopeStack[this.scopeStack.length - 1].push(variable);
53
+ }
54
+ lineComponents = [`${variable} =`];
55
+ }
56
+ else {
57
+ if (this.scopeStack.length > 0) {
58
+ this.scopeStack[this.scopeStack.length - 1].push(...variable);
59
+ }
60
+ lineComponents = variable.map(v => `${v} =`);
61
+ }
49
62
  if (opts.return) {
50
63
  lineComponents.splice(0, 0, "return");
51
64
  }
52
65
  lineComponents.push(Expr.convertJsonToPHP(expression));
53
- return this.append(lineComponents.join(" ") + ';');
66
+ return this.append(!opts.chain ? lineComponents.join(" ") + ';' : lineComponents.join(" "));
54
67
  }
55
68
  return(line) {
56
69
  return this.append(`return ${line};`);
@@ -72,15 +85,16 @@ class PHPWriter {
72
85
  return this;
73
86
  }
74
87
  call(func, args, opts = {}) {
88
+ const functionCall = `${func}(${args.map(Expr.convertJsonToPHP).join(", ")})`;
89
+ if (opts.assignTo) {
90
+ return this.assign(opts.assignTo, new Expr(functionCall), opts);
91
+ }
75
92
  const lineComponents = [];
76
93
  if (opts.return) {
77
94
  lineComponents.push("return");
78
95
  }
79
- if (opts.assignTo) {
80
- lineComponents.push(`${opts.assignTo} =`);
81
- }
82
- lineComponents.push(`${func}(${args.map(Expr.convertJsonToPHP).join(", ")})${opts.chain === true ? "" : ";"}`);
83
- return this.append(lineComponents.join(" "));
96
+ lineComponents.push(functionCall);
97
+ return this.append(!opts.chain ? lineComponents.join(" ") + ';' : lineComponents.join(" "));
84
98
  }
85
99
  action(name, contents, args = {}) {
86
100
  return this.actionOrFilter('action', name, contents, args);
@@ -98,7 +112,9 @@ class PHPWriter {
98
112
  declarationComponents.push("{");
99
113
  this.openPHP().append(`add_${type}(${declarationComponents.join(" ")}`);
100
114
  this.indent();
101
- contents(this);
115
+ // We start a new scope here just in case this was called within an existing scope
116
+ // We pop the scope instead of closing it because we don't actually want to unset any variables that were created within the function
117
+ this.withScope(contents, { actionDescription: `closing the function call for the ${name} ${type}.`, usePopScopeInstead: true });
102
118
  this.openPHP().outdent();
103
119
  const actionOrFilterArgs = ["}"];
104
120
  const accepted_args = Math.max(functionArgParameters.length, 1); // This avoids us unnecessarily setting the accepted_args value to 0 for actions
@@ -150,7 +166,9 @@ class PHPWriter {
150
166
  declarationComponents.push("{");
151
167
  this.append(declarationComponents.join(' '));
152
168
  this.indent();
153
- body(this);
169
+ // We start a new scope here just in case this was called within an existing scope
170
+ // We pop the scope instead of closing it because we don't actually want to unset any variables that were created within the function
171
+ this.withScope(body, { actionDescription: `closing the "${name}" function`, usePopScopeInstead: true });
154
172
  this.openPHP().outdent().append("}");
155
173
  if (args.includeExistenceCheck) {
156
174
  return this.endIf();
@@ -183,7 +201,48 @@ class PHPWriter {
183
201
  }
184
202
  return this;
185
203
  }
204
+ /**
205
+ * Starts a scope that, when paired with {@link #closeScope()}, allows for automating unset calls.
206
+ * All scopes started MUST be paired with either an {@link #closeScope()} or {@link #popScope()} call.
207
+ */
208
+ openScope() {
209
+ this.scopeStack.push([]);
210
+ return this;
211
+ }
212
+ /**
213
+ * Pops the top scope from the stack AND unsets all variables that were assigned within it
214
+ */
215
+ closeScope() {
216
+ const scope = this.scopeStack.pop();
217
+ return scope?.length ? this.call("unset", scope.map(v => new Expr(v))) : this;
218
+ }
219
+ /**
220
+ * Pops the top scope from the stack WITHOUT calling unset for the variables that were assigned within it.
221
+ * This is used to allow function bodies to be safely created without disrupting their containing scope.
222
+ */
223
+ popScope() {
224
+ this.scopeStack.pop();
225
+ return this;
226
+ }
227
+ withScope(code, opts = {}) {
228
+ const expectedScopeCount = this.scopeStack.length;
229
+ this.openScope();
230
+ code(this);
231
+ if (opts.usePopScopeInstead) {
232
+ this.popScope();
233
+ }
234
+ else {
235
+ this.closeScope();
236
+ }
237
+ if (expectedScopeCount !== this.scopeStack.length) {
238
+ console.trace(`Encountered an unexpected number of scopes (saw: ${this.scopeStack.length}, expected: ${expectedScopeCount})`, `while ${opts.actionDescription ?? "ending an encapsulating scope"}.`);
239
+ }
240
+ return this;
241
+ }
186
242
  toString() {
243
+ if (this.scopeStack.length) {
244
+ console.trace("toString() was called on a PHPWriter that has a dangling scope");
245
+ }
187
246
  const fileContents = [];
188
247
  let canInline = true;
189
248
  if (this.fileNamespace) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plaudit/webpack-extensions",
3
- "version": "2.58.0",
3
+ "version": "2.58.1",
4
4
  "license": "UNLICENSED",
5
5
  "files": [
6
6
  "/build"
@@ -63,7 +63,7 @@
63
63
  "postcss-url": "^10.1.3",
64
64
  "react": "^18.3.1",
65
65
  "react-dom": "^18.3.1",
66
- "webpack": "^5.101.1",
66
+ "webpack": "^5.101.2",
67
67
  "webpack-remove-empty-scripts": "^1.1.1",
68
68
  "xml-formatter": "^3.6.6"
69
69
  },