@plumeria/unplugin 18.2.1 → 18.2.3

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 (3) hide show
  1. package/dist/core.js +93 -44
  2. package/dist/core.mjs +93 -44
  3. package/package.json +2 -2
package/dist/core.js CHANGED
@@ -250,6 +250,31 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
250
250
  addDependency(parentFile);
251
251
  }
252
252
  }
253
+ const components = [];
254
+ for (const node of ast.body) {
255
+ const statement = utils_1.t.isExportDeclaration(node) ? node.declaration : node;
256
+ if (statement.type === 'FunctionDeclaration' && statement.identifier) {
257
+ components.push({
258
+ name: statement.identifier.value,
259
+ node: statement,
260
+ });
261
+ }
262
+ else if (utils_1.t.isVariableDeclaration(statement)) {
263
+ for (const decl of statement.declarations) {
264
+ if (utils_1.t.isIdentifier(decl.id) &&
265
+ (decl.init?.type === 'ArrowFunctionExpression' ||
266
+ decl.init?.type === 'FunctionExpression')) {
267
+ components.push({ name: decl.id.value, node: decl.init });
268
+ }
269
+ }
270
+ }
271
+ }
272
+ const appliedStyleProps = new Set();
273
+ const markStylePropApplied = (name, at) => {
274
+ const owner = components.find((c) => at.span.start >= c.node.span.start &&
275
+ at.span.start <= c.node.span.end);
276
+ appliedStyleProps.add(`${owner ? owner.name : '*'}:${name}`);
277
+ };
253
278
  const extractedSheets = [];
254
279
  const addSheet = (sheet) => {
255
280
  if (!extractedSheets.includes(sheet)) {
@@ -1165,56 +1190,68 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1165
1190
  else if (node.type === 'ParenthesisExpression') {
1166
1191
  return collectConditions(node.expression, currentTestStrings, argOrder);
1167
1192
  }
1193
+ if (pushPropPossibilities(node, currentTestStrings))
1194
+ return true;
1168
1195
  assertResolvable(node);
1169
1196
  return false;
1170
1197
  };
1171
- for (const arg of args) {
1172
- const expr = arg.expression;
1173
- if (utils_1.t.isIdentifier(expr) ||
1174
- (utils_1.t.isMemberExpression(expr) &&
1175
- utils_1.t.isIdentifier(expr.object) &&
1176
- componentParamNames.has(expr.object.value) &&
1177
- utils_1.t.isIdentifier(expr.property))) {
1178
- const varName = utils_1.t.isIdentifier(expr)
1179
- ? expr.value
1180
- : expr.property.value;
1181
- const testLHS = utils_1.t.isIdentifier(expr) ? varName : getSource(expr);
1182
- let propPossibilities;
1183
- for (const key of Object.keys(scannedTables.componentPropsTable || {})) {
1184
- if (key.startsWith(`${resourcePath}-`)) {
1185
- if (scannedTables.componentPropsTable?.[key]?.[varName]) {
1186
- propPossibilities =
1187
- scannedTables.componentPropsTable?.[key]?.[varName];
1188
- break;
1189
- }
1190
- }
1191
- }
1192
- if (propPossibilities && propPossibilities.length > 0) {
1193
- const currentGroupId = ++groupIdCounter;
1194
- const currentOrder = sourceOrder++;
1195
- const uniqueEntries = [];
1196
- propPossibilities.forEach((entry) => {
1197
- if (!uniqueEntries.some((x) => x.key === entry.key)) {
1198
- uniqueEntries.push(entry);
1199
- }
1200
- });
1201
- uniqueEntries.forEach((entry) => {
1202
- conditionals.push({
1203
- test: expr,
1204
- testLHS,
1205
- testString: `${testLHS} === ${JSON.stringify(entry.key)}`,
1206
- truthy: entry.styleObj,
1207
- falsy: {},
1208
- groupId: currentGroupId,
1209
- order: currentOrder,
1210
- groupName: undefined,
1211
- valueName: entry.key,
1212
- varName,
1213
- });
1214
- });
1198
+ const pushPropPossibilities = (expr, gates) => {
1199
+ const isParamMember = utils_1.t.isMemberExpression(expr) &&
1200
+ utils_1.t.isIdentifier(expr.object) &&
1201
+ componentParamNames.has(expr.object.value) &&
1202
+ utils_1.t.isIdentifier(expr.property);
1203
+ if (!utils_1.t.isIdentifier(expr) && !isParamMember)
1204
+ return false;
1205
+ const varName = utils_1.t.isIdentifier(expr)
1206
+ ? expr.value
1207
+ : expr.property.value;
1208
+ const source = utils_1.t.isIdentifier(expr) ? varName : getSource(expr);
1209
+ markStylePropApplied(varName, expr);
1210
+ let possibilities;
1211
+ for (const key of Object.keys(scannedTables.componentPropsTable || {})) {
1212
+ if (!key.startsWith(`${resourcePath}-`))
1215
1213
  continue;
1214
+ if (scannedTables.componentPropsTable?.[key]?.[varName]) {
1215
+ possibilities = scannedTables.componentPropsTable[key][varName];
1216
+ break;
1216
1217
  }
1217
1218
  }
1219
+ if (!possibilities || possibilities.length === 0)
1220
+ return false;
1221
+ const testLHS = gates.length
1222
+ ? `((${gates.join(' && ')}) ? ${source} : "")`
1223
+ : source;
1224
+ const currentGroupId = ++groupIdCounter;
1225
+ const currentOrder = sourceOrder++;
1226
+ const seen = new Set();
1227
+ const pushOption = (valueName, style) => {
1228
+ conditionals.push({
1229
+ test: expr,
1230
+ testLHS,
1231
+ testString: `${testLHS} === ${JSON.stringify(valueName)}`,
1232
+ truthy: style,
1233
+ falsy: {},
1234
+ groupId: currentGroupId,
1235
+ order: currentOrder,
1236
+ groupName: undefined,
1237
+ valueName,
1238
+ varName,
1239
+ });
1240
+ };
1241
+ possibilities.forEach((entry) => {
1242
+ if (seen.has(entry.key))
1243
+ return;
1244
+ seen.add(entry.key);
1245
+ pushOption(entry.key, entry.styleObj);
1246
+ });
1247
+ if (gates.length)
1248
+ pushOption('', {});
1249
+ return true;
1250
+ };
1251
+ for (const arg of args) {
1252
+ const expr = arg.expression;
1253
+ if (pushPropPossibilities(expr, []))
1254
+ continue;
1218
1255
  if (utils_1.t.isCallExpression(expr) && utils_1.t.isIdentifier(expr.callee)) {
1219
1256
  const varName = expr.callee.value;
1220
1257
  const uniqueKey = `${resourcePath}-${varName}`;
@@ -2049,6 +2086,18 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
2049
2086
  }
2050
2087
  },
2051
2088
  });
2089
+ for (const { name, node } of components) {
2090
+ const props = scannedTables.componentPropsTable?.[`${resourcePath}-${name}`];
2091
+ for (const propName of Object.keys(props ?? {})) {
2092
+ if (appliedStyleProps.has(`${name}:${propName}`) ||
2093
+ appliedStyleProps.has(`*:${propName}`)) {
2094
+ continue;
2095
+ }
2096
+ throwCompilationError(`Plumeria: "${propName}" is a style received through a prop but is never applied ` +
2097
+ `to ${styleProp} or css.use() here. Apply it on an element this component renders; ` +
2098
+ `a style prop cannot be passed on to another component.`, node);
2099
+ }
2100
+ }
2052
2101
  const buildExportedInit = (info) => {
2053
2102
  const keys = Object.keys(info.obj);
2054
2103
  if (!isDev || keys.length === 0) {
package/dist/core.mjs CHANGED
@@ -214,6 +214,31 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
214
214
  addDependency(parentFile);
215
215
  }
216
216
  }
217
+ const components = [];
218
+ for (const node of ast.body) {
219
+ const statement = t.isExportDeclaration(node) ? node.declaration : node;
220
+ if (statement.type === 'FunctionDeclaration' && statement.identifier) {
221
+ components.push({
222
+ name: statement.identifier.value,
223
+ node: statement,
224
+ });
225
+ }
226
+ else if (t.isVariableDeclaration(statement)) {
227
+ for (const decl of statement.declarations) {
228
+ if (t.isIdentifier(decl.id) &&
229
+ (decl.init?.type === 'ArrowFunctionExpression' ||
230
+ decl.init?.type === 'FunctionExpression')) {
231
+ components.push({ name: decl.id.value, node: decl.init });
232
+ }
233
+ }
234
+ }
235
+ }
236
+ const appliedStyleProps = new Set();
237
+ const markStylePropApplied = (name, at) => {
238
+ const owner = components.find((c) => at.span.start >= c.node.span.start &&
239
+ at.span.start <= c.node.span.end);
240
+ appliedStyleProps.add(`${owner ? owner.name : '*'}:${name}`);
241
+ };
217
242
  const extractedSheets = [];
218
243
  const addSheet = (sheet) => {
219
244
  if (!extractedSheets.includes(sheet)) {
@@ -1129,56 +1154,68 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1129
1154
  else if (node.type === 'ParenthesisExpression') {
1130
1155
  return collectConditions(node.expression, currentTestStrings, argOrder);
1131
1156
  }
1157
+ if (pushPropPossibilities(node, currentTestStrings))
1158
+ return true;
1132
1159
  assertResolvable(node);
1133
1160
  return false;
1134
1161
  };
1135
- for (const arg of args) {
1136
- const expr = arg.expression;
1137
- if (t.isIdentifier(expr) ||
1138
- (t.isMemberExpression(expr) &&
1139
- t.isIdentifier(expr.object) &&
1140
- componentParamNames.has(expr.object.value) &&
1141
- t.isIdentifier(expr.property))) {
1142
- const varName = t.isIdentifier(expr)
1143
- ? expr.value
1144
- : expr.property.value;
1145
- const testLHS = t.isIdentifier(expr) ? varName : getSource(expr);
1146
- let propPossibilities;
1147
- for (const key of Object.keys(scannedTables.componentPropsTable || {})) {
1148
- if (key.startsWith(`${resourcePath}-`)) {
1149
- if (scannedTables.componentPropsTable?.[key]?.[varName]) {
1150
- propPossibilities =
1151
- scannedTables.componentPropsTable?.[key]?.[varName];
1152
- break;
1153
- }
1154
- }
1155
- }
1156
- if (propPossibilities && propPossibilities.length > 0) {
1157
- const currentGroupId = ++groupIdCounter;
1158
- const currentOrder = sourceOrder++;
1159
- const uniqueEntries = [];
1160
- propPossibilities.forEach((entry) => {
1161
- if (!uniqueEntries.some((x) => x.key === entry.key)) {
1162
- uniqueEntries.push(entry);
1163
- }
1164
- });
1165
- uniqueEntries.forEach((entry) => {
1166
- conditionals.push({
1167
- test: expr,
1168
- testLHS,
1169
- testString: `${testLHS} === ${JSON.stringify(entry.key)}`,
1170
- truthy: entry.styleObj,
1171
- falsy: {},
1172
- groupId: currentGroupId,
1173
- order: currentOrder,
1174
- groupName: undefined,
1175
- valueName: entry.key,
1176
- varName,
1177
- });
1178
- });
1162
+ const pushPropPossibilities = (expr, gates) => {
1163
+ const isParamMember = t.isMemberExpression(expr) &&
1164
+ t.isIdentifier(expr.object) &&
1165
+ componentParamNames.has(expr.object.value) &&
1166
+ t.isIdentifier(expr.property);
1167
+ if (!t.isIdentifier(expr) && !isParamMember)
1168
+ return false;
1169
+ const varName = t.isIdentifier(expr)
1170
+ ? expr.value
1171
+ : expr.property.value;
1172
+ const source = t.isIdentifier(expr) ? varName : getSource(expr);
1173
+ markStylePropApplied(varName, expr);
1174
+ let possibilities;
1175
+ for (const key of Object.keys(scannedTables.componentPropsTable || {})) {
1176
+ if (!key.startsWith(`${resourcePath}-`))
1179
1177
  continue;
1178
+ if (scannedTables.componentPropsTable?.[key]?.[varName]) {
1179
+ possibilities = scannedTables.componentPropsTable[key][varName];
1180
+ break;
1180
1181
  }
1181
1182
  }
1183
+ if (!possibilities || possibilities.length === 0)
1184
+ return false;
1185
+ const testLHS = gates.length
1186
+ ? `((${gates.join(' && ')}) ? ${source} : "")`
1187
+ : source;
1188
+ const currentGroupId = ++groupIdCounter;
1189
+ const currentOrder = sourceOrder++;
1190
+ const seen = new Set();
1191
+ const pushOption = (valueName, style) => {
1192
+ conditionals.push({
1193
+ test: expr,
1194
+ testLHS,
1195
+ testString: `${testLHS} === ${JSON.stringify(valueName)}`,
1196
+ truthy: style,
1197
+ falsy: {},
1198
+ groupId: currentGroupId,
1199
+ order: currentOrder,
1200
+ groupName: undefined,
1201
+ valueName,
1202
+ varName,
1203
+ });
1204
+ };
1205
+ possibilities.forEach((entry) => {
1206
+ if (seen.has(entry.key))
1207
+ return;
1208
+ seen.add(entry.key);
1209
+ pushOption(entry.key, entry.styleObj);
1210
+ });
1211
+ if (gates.length)
1212
+ pushOption('', {});
1213
+ return true;
1214
+ };
1215
+ for (const arg of args) {
1216
+ const expr = arg.expression;
1217
+ if (pushPropPossibilities(expr, []))
1218
+ continue;
1182
1219
  if (t.isCallExpression(expr) && t.isIdentifier(expr.callee)) {
1183
1220
  const varName = expr.callee.value;
1184
1221
  const uniqueKey = `${resourcePath}-${varName}`;
@@ -2013,6 +2050,18 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
2013
2050
  }
2014
2051
  },
2015
2052
  });
2053
+ for (const { name, node } of components) {
2054
+ const props = scannedTables.componentPropsTable?.[`${resourcePath}-${name}`];
2055
+ for (const propName of Object.keys(props ?? {})) {
2056
+ if (appliedStyleProps.has(`${name}:${propName}`) ||
2057
+ appliedStyleProps.has(`*:${propName}`)) {
2058
+ continue;
2059
+ }
2060
+ throwCompilationError(`Plumeria: "${propName}" is a style received through a prop but is never applied ` +
2061
+ `to ${styleProp} or css.use() here. Apply it on an element this component renders; ` +
2062
+ `a style prop cannot be passed on to another component.`, node);
2063
+ }
2064
+ }
2016
2065
  const buildExportedInit = (info) => {
2017
2066
  const keys = Object.keys(info.obj);
2018
2067
  if (!isDev || keys.length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/unplugin",
3
- "version": "18.2.1",
3
+ "version": "18.2.3",
4
4
  "description": "Universal Plumeria plugin for various build tools",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -89,7 +89,7 @@
89
89
  "dependencies": {
90
90
  "@rollup/pluginutils": "^5.4.0",
91
91
  "unplugin": "^3.0.0",
92
- "@plumeria/utils": "^18.2.1"
92
+ "@plumeria/utils": "^18.2.3"
93
93
  },
94
94
  "devDependencies": {
95
95
  "@swc/core": "1.15.47",