pasika 0.10.74 → 0.10.76

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.
@@ -6092,6 +6092,86 @@ function directPropertyBinding(context, declarator) {
6092
6092
  function canGroupSource(source) {
6093
6093
  return source.type === "Identifier" || source.type === "ThisExpression";
6094
6094
  }
6095
+ function isStableObjectSource(source) {
6096
+ if (source.type === "Identifier" || source.type === "ThisExpression") return true;
6097
+ if (source.type !== "MemberExpression") return false;
6098
+ if (source.computed || source.optional || source.property.type !== "Identifier") return false;
6099
+ return isStableObjectSource(source.object);
6100
+ }
6101
+ function objectUsage(scope, sourceText) {
6102
+ let usage = scope.objects.get(sourceText);
6103
+ if (!usage) {
6104
+ usage = { propertyNames: /* @__PURE__ */ new Set(), directMembers: [] };
6105
+ scope.objects.set(sourceText, usage);
6106
+ }
6107
+ return usage;
6108
+ }
6109
+ function memberIsRead(context, member) {
6110
+ const parent = context.sourceCode.getAncestors(member).at(-1);
6111
+ if (!parent) return true;
6112
+ if (parent.type === "AssignmentExpression" && parent.left === member) return false;
6113
+ if (parent.type === "UpdateExpression" && parent.argument === member) return false;
6114
+ if (parent.type === "UnaryExpression" && parent.operator === "delete" && parent.argument === member) return false;
6115
+ if ((parent.type === "ForInStatement" || parent.type === "ForOfStatement") && parent.left === member) return false;
6116
+ if ((parent.type === "CallExpression" || parent.type === "NewExpression") && parent.callee === member) return false;
6117
+ if (parent.type === "TaggedTemplateExpression" && parent.tag === member) return false;
6118
+ return true;
6119
+ }
6120
+ function memberIsDirectVariableInitializer(context, member) {
6121
+ const parent = context.sourceCode.getAncestors(member).at(-1);
6122
+ return parent?.type === "VariableDeclarator" && parent.init === member;
6123
+ }
6124
+ function recordMemberUsage(context, scope, member) {
6125
+ if (!scope || member.computed || member.optional || member.property.type !== "Identifier") return;
6126
+ if (!isStableObjectSource(member.object) || !memberIsRead(context, member)) return;
6127
+ const sourceText = context.sourceCode.getText(member.object);
6128
+ const usage = objectUsage(scope, sourceText);
6129
+ const propertyName5 = member.property.name;
6130
+ usage.propertyNames.add(propertyName5);
6131
+ if (!memberIsDirectVariableInitializer(context, member)) {
6132
+ usage.directMembers.push({ member, propertyName: propertyName5 });
6133
+ }
6134
+ }
6135
+ function recordDestructuringUsage(context, scope, declaration) {
6136
+ if (!scope) return;
6137
+ for (const declarator of declaration.declarations) {
6138
+ if (declarator.id.type !== "ObjectPattern" || !declarator.init || !isStableObjectSource(declarator.init)) continue;
6139
+ const sourceText = context.sourceCode.getText(declarator.init);
6140
+ const usage = objectUsage(scope, sourceText);
6141
+ const propertyNames = /* @__PURE__ */ new Set();
6142
+ for (const property of declarator.id.properties) {
6143
+ if (property.type !== "Property" || property.computed || property.key.type !== "Identifier") continue;
6144
+ propertyNames.add(property.key.name);
6145
+ usage.propertyNames.add(property.key.name);
6146
+ }
6147
+ usage.destructuring ??= { pattern: declarator.id, propertyNames };
6148
+ }
6149
+ }
6150
+ function scopeUsageMessage(sourceText, propertyNames) {
6151
+ const names = [...propertyNames].map((name) => `"${name}"`).join(", ");
6152
+ return `${names} are read from "${sourceText}" in the same block. Destructure them together in one declaration. ${DOC5}`;
6153
+ }
6154
+ function hasBinding(context, node, name) {
6155
+ const initialScope = context.sourceCode.getScope(node);
6156
+ if (initialScope.variables.some((variable) => variable.name === name)) return true;
6157
+ for (let scope = initialScope.upper; scope !== null; scope = scope.upper) {
6158
+ if (scope.variables.some((variable) => variable.name === name)) return true;
6159
+ }
6160
+ return false;
6161
+ }
6162
+ function containingStatement(context, scopeNode, node) {
6163
+ if (scopeNode.type !== "Program" && scopeNode.type !== "BlockStatement") return void 0;
6164
+ const [nodeStart, nodeEnd] = context.sourceCode.getRange(node);
6165
+ return scopeNode.body.find((statement) => {
6166
+ const [statementStart, statementEnd] = context.sourceCode.getRange(statement);
6167
+ return statementStart <= nodeStart && statementEnd >= nodeEnd;
6168
+ });
6169
+ }
6170
+ function statementIndentation(context, statement) {
6171
+ const [start] = context.sourceCode.getRange(statement);
6172
+ const lineStart = context.sourceCode.text.lastIndexOf("\n", start - 1) + 1;
6173
+ return context.sourceCode.text.slice(lineStart, start);
6174
+ }
6095
6175
  function whitespaceKeepsStatementsAdjacent(text) {
6096
6176
  if (text.trim() !== "") return false;
6097
6177
  return (text.match(/\n/gu) ?? []).length <= 1;
@@ -6202,13 +6282,75 @@ var preferObjectDestructuringRule = {
6202
6282
  type: "problem",
6203
6283
  fixable: "code",
6204
6284
  docs: {
6205
- description: "Require locals derived directly from object properties to use object destructuring."
6285
+ description: "Require related object-property reads to use one object destructuring declaration."
6206
6286
  }
6207
6287
  },
6208
6288
  create(context) {
6209
6289
  const grouped = /* @__PURE__ */ new Set();
6290
+ const usageScopes = [];
6291
+ const currentUsageScope = () => usageScopes.at(-1);
6292
+ const enterUsageScope = (node) => {
6293
+ usageScopes.push({ node, objects: /* @__PURE__ */ new Map() });
6294
+ };
6295
+ const exitUsageScope = () => {
6296
+ const scope = usageScopes.pop();
6297
+ if (!scope) return;
6298
+ for (const [sourceText, usage] of scope.objects) {
6299
+ if (usage.propertyNames.size < 2 || usage.directMembers.length === 0) continue;
6300
+ const firstDirectUsage = usage.directMembers[0];
6301
+ if (!firstDirectUsage) continue;
6302
+ const { member: firstDirectMember } = firstDirectUsage;
6303
+ context.report({
6304
+ node: firstDirectMember,
6305
+ message: scopeUsageMessage(sourceText, usage.propertyNames),
6306
+ fix(fixer) {
6307
+ const propertyNames = [...usage.propertyNames];
6308
+ const missingPropertyNames = propertyNames.filter(
6309
+ (propertyName5) => !usage.destructuring?.propertyNames.has(propertyName5)
6310
+ );
6311
+ if (missingPropertyNames.some((propertyName5) => hasBinding(context, firstDirectMember, propertyName5))) {
6312
+ return null;
6313
+ }
6314
+ const memberFixes = usage.directMembers.map(
6315
+ ({ member, propertyName: propertyName5 }) => fixer.replaceText(member, propertyName5)
6316
+ );
6317
+ if (usage.destructuring) {
6318
+ if (missingPropertyNames.length === 0) return memberFixes;
6319
+ const patternText = context.sourceCode.getText(usage.destructuring.pattern);
6320
+ const closeIndex = patternText.lastIndexOf("}");
6321
+ const beforeClose = patternText.slice(0, closeIndex);
6322
+ const contentEnd = beforeClose.trimEnd().length;
6323
+ const trailingWhitespace = beforeClose.slice(contentEnd);
6324
+ const separator = usage.destructuring.propertyNames.size > 0 ? ", " : "";
6325
+ const replacement = `${beforeClose.slice(0, contentEnd)}${separator}${missingPropertyNames.join(", ")}${trailingWhitespace}${patternText.slice(closeIndex)}`;
6326
+ return [fixer.replaceText(usage.destructuring.pattern, replacement), ...memberFixes];
6327
+ }
6328
+ const statement = containingStatement(context, scope.node, firstDirectMember);
6329
+ if (!statement) return null;
6330
+ const indentation = statementIndentation(context, statement);
6331
+ const declaration = `const { ${propertyNames.join(", ")} } = ${sourceText};
6332
+ ${indentation}`;
6333
+ return [fixer.insertTextBefore(statement, declaration), ...memberFixes];
6334
+ }
6335
+ });
6336
+ }
6337
+ };
6210
6338
  return {
6339
+ Program: enterUsageScope,
6340
+ "Program:exit": exitUsageScope,
6341
+ BlockStatement: enterUsageScope,
6342
+ "BlockStatement:exit": exitUsageScope,
6343
+ FunctionDeclaration: enterUsageScope,
6344
+ "FunctionDeclaration:exit": exitUsageScope,
6345
+ FunctionExpression: enterUsageScope,
6346
+ "FunctionExpression:exit": exitUsageScope,
6347
+ ArrowFunctionExpression: enterUsageScope,
6348
+ "ArrowFunctionExpression:exit": exitUsageScope,
6349
+ MemberExpression(node) {
6350
+ recordMemberUsage(context, currentUsageScope(), node);
6351
+ },
6211
6352
  VariableDeclaration(node) {
6353
+ recordDestructuringUsage(context, currentUsageScope(), node);
6212
6354
  if (grouped.has(node)) return;
6213
6355
  const selection = destructuringSelection(context, node);
6214
6356
  if (selection) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.74",
3
+ "version": "0.10.76",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",