vite-plugin-enter-dev 0.0.12 → 0.0.14

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.
Files changed (2) hide show
  1. package/dist/configure.js +69 -9
  2. package/package.json +1 -1
package/dist/configure.js CHANGED
@@ -31,12 +31,15 @@ function configureVite(source) {
31
31
  if (!types.isIdentifier(config.callee) || !defineNames.includes(config.callee.name) || config.arguments.length !== 1) throw new Error("Unsupported Vite config wrapper");
32
32
  config = config.arguments[0];
33
33
  }
34
+ let setup = [];
34
35
  if (types.isArrowFunctionExpression(config) || types.isFunctionExpression(config)) {
35
36
  if (types.isBlockStatement(config.body)) {
36
- if (config.body.body.length !== 1 || !types.isReturnStatement(config.body.body[0])) {
37
+ const last = config.body.body.at(-1);
38
+ if (!types.isReturnStatement(last)) {
37
39
  throw new Error("Unsupported Vite config: expected a single unconditional return");
38
40
  }
39
- config = config.body.body[0].argument ?? void 0;
41
+ setup = config.body.body.slice(0, -1);
42
+ config = last.argument ?? void 0;
40
43
  } else {
41
44
  config = config.body;
42
45
  }
@@ -54,14 +57,16 @@ function configureVite(source) {
54
57
  config.properties.push(plugins);
55
58
  changed = true;
56
59
  }
57
- if (!types.isObjectProperty(plugins) || !types.isArrayExpression(plugins.value)) {
58
- throw new Error("Unsupported Vite config: expected a literal plugins array");
59
- }
60
- const calls = plugins.value.elements.map((node) => types.isSpreadElement(node) ? node.argument : node);
60
+ if (!types.isObjectProperty(plugins)) throw new Error("Unsupported plugins property");
61
+ const pluginArrays = resolvePluginArrays(plugins.value, setup);
62
+ const calls = pluginArrays.flatMap((group) => group.array.elements).map((node) => types.isSpreadElement(node) ? node.argument : node);
61
63
  if (calls.some((node) => !types.isCallExpression(node) && node !== null && !types.isBooleanLiteral(node))) {
62
64
  throw new Error("Unsupported Vite config: dynamic plugin list");
63
65
  }
64
- const hostReact = calls.some((node) => types.isCallExpression(node) && types.isIdentifier(node.callee) && reactNames.includes(node.callee.name));
66
+ const reactGroups = pluginArrays.filter((group) => group.array.elements.some((element) => {
67
+ const node = types.isSpreadElement(element) ? element.argument : element;
68
+ return types.isCallExpression(node) && types.isIdentifier(node.callee) && reactNames.includes(node.callee.name);
69
+ }));
65
70
  for (const name of ["enterProdPlugin", "enterDevPlugin"]) {
66
71
  const specifiers = imports.filter((node) => node.source.value === "vite-plugin-enter-dev").flatMap((node) => node.specifiers).filter((node) => types.isImportSpecifier(node) && types.isIdentifier(node.imported, { name }));
67
72
  const aliases = specifiers.map((node) => node.local.name);
@@ -77,10 +82,16 @@ function configureVite(source) {
77
82
  let call = matching[0];
78
83
  if (!call) {
79
84
  call = types.callExpression(types.identifier(local), []);
80
- plugins.value.elements.push(types.spreadElement(call));
85
+ pluginArrays[0].array.elements.push(types.spreadElement(call));
81
86
  changed = true;
82
87
  }
83
- if (name !== "enterDevPlugin" || !hostReact || !types.isCallExpression(call)) continue;
88
+ if (name !== "enterDevPlugin" || !types.isCallExpression(call)) continue;
89
+ const devGroup = pluginArrays.find((group) => group.array.elements.some((element) => (types.isSpreadElement(element) ? element.argument : element) === call));
90
+ const hosts = reactGroups.filter((group) => !group.conditions.some((condition) => devGroup.conditions.some((other) => other.node === condition.node && other.branch !== condition.branch)));
91
+ if (!hosts.length) continue;
92
+ if (!hosts.some((group) => group.conditions.every((condition) => devGroup.conditions.some((other) => other.node === condition.node && other.branch === condition.branch)))) {
93
+ throw new Error("Unsupported conditional React compiler ownership");
94
+ }
84
95
  if (call.arguments.length === 0) call.arguments.push(types.objectExpression([]));
85
96
  const options = call.arguments[0];
86
97
  if (!types.isObjectExpression(options) || options.properties.some((node) => !types.isObjectProperty(node) || node.computed)) {
@@ -119,5 +130,54 @@ function configureViteFile(path, check = false) {
119
130
  }
120
131
  return true;
121
132
  }
133
+ function resolvePluginArrays(value, setup) {
134
+ value = unwrapType(value);
135
+ if (types.isCallExpression(value) && types.isMemberExpression(value.callee) && !value.callee.computed && types.isIdentifier(value.callee.property, { name: "filter" }) && value.arguments.length === 1 && types.isIdentifier(value.arguments[0], { name: "Boolean" })) value = unwrapType(value.callee.object);
136
+ if (setup.length === 0 && types.isArrayExpression(value)) return [{ array: value, conditions: [] }];
137
+ if (!types.isIdentifier(value)) throw new Error("Unsupported dynamic plugins reference");
138
+ const name = value.name;
139
+ const declarations = setup.filter((statement) => types.isVariableDeclaration(statement) && statement.declarations.some((item) => types.isIdentifier(item.id, { name })));
140
+ const first = declarations.length === 1 ? declarations[0] : void 0;
141
+ if (!types.isVariableDeclaration(first, { kind: "const" }) || first.declarations.length !== 1) {
142
+ throw new Error("Unsupported plugins initializer");
143
+ }
144
+ const declaration = first.declarations[0];
145
+ const initial = declaration.init && unwrapType(declaration.init);
146
+ if (!types.isIdentifier(declaration.id, { name }) || !types.isArrayExpression(initial)) {
147
+ throw new Error("Unsupported plugins initializer");
148
+ }
149
+ const arrays = [{ array: initial, conditions: [] }];
150
+ const visit = (statement, conditions) => {
151
+ if (types.isVariableDeclaration(statement) && !referencesArray(statement, name)) return;
152
+ if (types.isIfStatement(statement)) {
153
+ if (referencesArray(statement.test, name)) throw new Error("Unsupported plugins mutation in condition");
154
+ visit(statement.consequent, [...conditions, { node: statement, branch: true }]);
155
+ if (statement.alternate) visit(statement.alternate, [...conditions, { node: statement, branch: false }]);
156
+ return;
157
+ }
158
+ if (types.isBlockStatement(statement)) {
159
+ statement.body.forEach((child) => visit(child, conditions));
160
+ return;
161
+ }
162
+ const call = types.isExpressionStatement(statement) ? statement.expression : void 0;
163
+ if (!types.isCallExpression(call) || !types.isMemberExpression(call.callee) || call.callee.computed || !types.isIdentifier(call.callee.object, { name }) || !types.isIdentifier(call.callee.property, { name: "push" }) || call.arguments.some((argument) => types.isJSXNamespacedName(argument) || types.isArgumentPlaceholder(argument))) {
164
+ throw new Error("Unsupported plugins mutation");
165
+ }
166
+ arrays.push({ array: types.arrayExpression(call.arguments), conditions });
167
+ };
168
+ setup.filter((statement) => statement !== first).forEach((statement) => visit(statement, []));
169
+ return arrays;
170
+ }
171
+ function unwrapType(node) {
172
+ while (types.isTSAsExpression(node) || types.isTSSatisfiesExpression(node)) node = node.expression;
173
+ return node;
174
+ }
175
+ function referencesArray(node, name) {
176
+ let found = false;
177
+ types.traverseFast(node, (child) => {
178
+ if (types.isIdentifier(child, { name })) found = true;
179
+ });
180
+ return found;
181
+ }
122
182
 
123
183
  export { configureVite, configureViteFile };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-enter-dev",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "description": "A Vite plugin for development enhancements",