vite-plugin-enter-dev 0.0.13 → 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 +40 -19
  2. package/package.json +1 -1
package/dist/configure.js CHANGED
@@ -59,14 +59,14 @@ function configureVite(source) {
59
59
  }
60
60
  if (!types.isObjectProperty(plugins)) throw new Error("Unsupported plugins property");
61
61
  const pluginArrays = resolvePluginArrays(plugins.value, setup);
62
- if (!pluginArrays.length) {
63
- throw new Error("Unsupported Vite config: expected a literal plugins array");
64
- }
65
- const calls = pluginArrays.flatMap((array) => array.elements).map((node) => types.isSpreadElement(node) ? node.argument : node);
62
+ const calls = pluginArrays.flatMap((group) => group.array.elements).map((node) => types.isSpreadElement(node) ? node.argument : node);
66
63
  if (calls.some((node) => !types.isCallExpression(node) && node !== null && !types.isBooleanLiteral(node))) {
67
64
  throw new Error("Unsupported Vite config: dynamic plugin list");
68
65
  }
69
- 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
+ }));
70
70
  for (const name of ["enterProdPlugin", "enterDevPlugin"]) {
71
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 }));
72
72
  const aliases = specifiers.map((node) => node.local.name);
@@ -82,10 +82,16 @@ function configureVite(source) {
82
82
  let call = matching[0];
83
83
  if (!call) {
84
84
  call = types.callExpression(types.identifier(local), []);
85
- pluginArrays[0].elements.push(types.spreadElement(call));
85
+ pluginArrays[0].array.elements.push(types.spreadElement(call));
86
86
  changed = true;
87
87
  }
88
- 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
+ }
89
95
  if (call.arguments.length === 0) call.arguments.push(types.objectExpression([]));
90
96
  const options = call.arguments[0];
91
97
  if (!types.isObjectExpression(options) || options.properties.some((node) => !types.isObjectProperty(node) || node.computed)) {
@@ -125,38 +131,53 @@ function configureViteFile(path, check = false) {
125
131
  return true;
126
132
  }
127
133
  function resolvePluginArrays(value, setup) {
128
- if (setup.length === 0 && types.isArrayExpression(value)) return [value];
129
- if (types.isTSAsExpression(value) || types.isTSSatisfiesExpression(value)) value = value.expression;
130
- 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 = value.callee.object;
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: [] }];
131
137
  if (!types.isIdentifier(value)) throw new Error("Unsupported dynamic plugins reference");
132
138
  const name = value.name;
133
- const first = setup[0];
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;
134
141
  if (!types.isVariableDeclaration(first, { kind: "const" }) || first.declarations.length !== 1) {
135
142
  throw new Error("Unsupported plugins initializer");
136
143
  }
137
144
  const declaration = first.declarations[0];
138
- if (!types.isIdentifier(declaration.id, { name }) || !types.isArrayExpression(declaration.init)) {
145
+ const initial = declaration.init && unwrapType(declaration.init);
146
+ if (!types.isIdentifier(declaration.id, { name }) || !types.isArrayExpression(initial)) {
139
147
  throw new Error("Unsupported plugins initializer");
140
148
  }
141
- const arrays = [declaration.init];
142
- const visit = (statement) => {
149
+ const arrays = [{ array: initial, conditions: [] }];
150
+ const visit = (statement, conditions) => {
151
+ if (types.isVariableDeclaration(statement) && !referencesArray(statement, name)) return;
143
152
  if (types.isIfStatement(statement)) {
144
- visit(statement.consequent);
145
- if (statement.alternate) visit(statement.alternate);
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 }]);
146
156
  return;
147
157
  }
148
158
  if (types.isBlockStatement(statement)) {
149
- statement.body.forEach(visit);
159
+ statement.body.forEach((child) => visit(child, conditions));
150
160
  return;
151
161
  }
152
162
  const call = types.isExpressionStatement(statement) ? statement.expression : void 0;
153
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))) {
154
164
  throw new Error("Unsupported plugins mutation");
155
165
  }
156
- arrays.push(types.arrayExpression(call.arguments));
166
+ arrays.push({ array: types.arrayExpression(call.arguments), conditions });
157
167
  };
158
- setup.slice(1).forEach(visit);
168
+ setup.filter((statement) => statement !== first).forEach((statement) => visit(statement, []));
159
169
  return arrays;
160
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
+ }
161
182
 
162
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.13",
3
+ "version": "0.0.14",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "description": "A Vite plugin for development enhancements",