pasika 0.10.91 → 0.10.93

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.
@@ -6418,13 +6418,17 @@ function canGroupSource(source) {
6418
6418
  function isGroupedUsageSource(source) {
6419
6419
  return source.type === "Identifier" || source.type === "ThisExpression";
6420
6420
  }
6421
+ function supportsSinglePropertySource(source) {
6422
+ if (isGroupedUsageSource(source) || source.type === "CallExpression") return true;
6423
+ return source.type === "MemberExpression" && !source.computed && !source.optional && source.property.type === "Identifier" && supportsSinglePropertySource(source.object);
6424
+ }
6421
6425
  function rootIdentifierName(node) {
6422
6426
  if (node.type === "Identifier") return node.name;
6423
6427
  if (node.type !== "MemberExpression" || node.object.type === "Super") return void 0;
6424
6428
  return rootIdentifierName(node.object);
6425
6429
  }
6426
6430
  function isCompliantLocalName(propertyName5) {
6427
- return !propertyName5.includes("_");
6431
+ return !propertyName5.includes("_") || /^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$/u.test(propertyName5);
6428
6432
  }
6429
6433
  function propertyNameOf(node) {
6430
6434
  if (node.type !== "Property" || node.computed) return void 0;
@@ -6485,6 +6489,27 @@ function enumValueResolver(context) {
6485
6489
  return typeSymbol ? isEnumSymbol(typeSymbol) : localEnumBinding(context, node);
6486
6490
  };
6487
6491
  }
6492
+ function detachableCallResolver(context) {
6493
+ const services = typedParserServices(context.sourceCode.parserServices);
6494
+ if (!services) return () => false;
6495
+ const checker = services.program.getTypeChecker();
6496
+ const { esTreeNodeToTSNodeMap: nodeMap } = services;
6497
+ const isUnboundFunctionType = (type) => ts9.isFunctionTypeNode(type) && !type.parameters.some((parameter) => ts9.isIdentifier(parameter.name) && parameter.name.text === "this");
6498
+ return (member) => {
6499
+ const node = nodeMap.get(member);
6500
+ if (!node || !ts9.isPropertyAccessExpression(node)) return false;
6501
+ const symbol = checker.getSymbolAtLocation(node.name);
6502
+ const declarations = symbol?.declarations;
6503
+ if (!declarations?.length) return false;
6504
+ return declarations.every((declaration) => {
6505
+ if (ts9.isPropertySignature(declaration) || ts9.isPropertyDeclaration(declaration)) {
6506
+ return declaration.type !== void 0 && isUnboundFunctionType(declaration.type) || ts9.isPropertyDeclaration(declaration) && declaration.initializer !== void 0 && ts9.isArrowFunction(declaration.initializer);
6507
+ }
6508
+ if (ts9.isPropertyAssignment(declaration)) return ts9.isArrowFunction(declaration.initializer);
6509
+ return false;
6510
+ });
6511
+ };
6512
+ }
6488
6513
  function directMappingRequiresQualifiedAccess(context, ownershipResolver, member) {
6489
6514
  const mapping = renamedDirectMapping(context, member);
6490
6515
  if (!mapping || !ownershipResolver) return false;
@@ -6503,14 +6528,15 @@ function objectUsage(scope, sourceText) {
6503
6528
  }
6504
6529
  return usage;
6505
6530
  }
6506
- function memberIsRead(context, member) {
6531
+ function memberIsRead(context, member, detachableCall) {
6507
6532
  const parent = context.sourceCode.getAncestors(member).at(-1);
6508
6533
  if (!parent) return true;
6509
6534
  if (parent.type === "AssignmentExpression" && parent.left === member) return false;
6510
6535
  if (parent.type === "UpdateExpression" && parent.argument === member) return false;
6511
6536
  if (parent.type === "UnaryExpression" && parent.operator === "delete" && parent.argument === member) return false;
6512
6537
  if ((parent.type === "ForInStatement" || parent.type === "ForOfStatement") && parent.left === member) return false;
6513
- if ((parent.type === "CallExpression" || parent.type === "NewExpression") && parent.callee === member) return false;
6538
+ if (parent.type === "CallExpression" && parent.callee === member) return detachableCall(member);
6539
+ if (parent.type === "NewExpression" && parent.callee === member) return false;
6514
6540
  if (parent.type === "TaggedTemplateExpression" && parent.tag === member) return false;
6515
6541
  return true;
6516
6542
  }
@@ -6518,10 +6544,10 @@ function memberIsDirectVariableInitializer(context, member) {
6518
6544
  const parent = context.sourceCode.getAncestors(member).at(-1);
6519
6545
  return parent?.type === "VariableDeclarator" && parent.init === member;
6520
6546
  }
6521
- function recordMemberUsage(context, scope, ownershipResolver, member, isEnumValue) {
6547
+ function recordMemberUsage(context, scope, ownershipResolver, member, isEnumValue, detachableCall) {
6522
6548
  if (!scope || member.computed || member.optional || member.property.type !== "Identifier") return;
6523
6549
  if (!memberCanBeDestructured(context, ownershipResolver, member, isEnumValue)) return;
6524
- if (!isGroupedUsageSource(member.object) || !memberIsRead(context, member)) return;
6550
+ if (!isGroupedUsageSource(member.object) || !memberIsRead(context, member, detachableCall)) return;
6525
6551
  const sourceText = context.sourceCode.getText(member.object);
6526
6552
  const usage = objectUsage(scope, sourceText);
6527
6553
  const propertyName5 = member.property.name;
@@ -6667,8 +6693,8 @@ function groupedDestructuringSelections(context, first, isEnumValue) {
6667
6693
  function declarationTerminator(context, declaration) {
6668
6694
  return context.sourceCode.getText(declaration).trimEnd().endsWith(";") ? ";" : "";
6669
6695
  }
6670
- function singleMessage(binding) {
6671
- return `"${binding.localName}" is derived directly from "${binding.sourceText}.${binding.propertyName}". Use object destructuring. ${DOC5}`;
6696
+ function singlePropertyMessage(binding) {
6697
+ return `"${binding.propertyName}" is the only property bound from "${binding.sourceText}". Read "${binding.sourceText}.${binding.propertyName}" directly instead of creating a local binding. ${DOC5}`;
6672
6698
  }
6673
6699
  function groupMessage(bindings) {
6674
6700
  const firstBinding = bindings[0];
@@ -6688,17 +6714,18 @@ var preferObjectDestructuringRule = {
6688
6714
  type: "problem",
6689
6715
  fixable: "code",
6690
6716
  docs: {
6691
- description: "Require related object-property reads to use one object destructuring declaration."
6717
+ description: "Prefer direct access for one property and shared destructuring for related property reads."
6692
6718
  }
6693
6719
  },
6694
6720
  create(context) {
6695
6721
  const ownershipResolver = contractOwnershipResolver(context);
6696
6722
  const isEnumValue = enumValueResolver(context);
6723
+ const detachableCall = detachableCallResolver(context);
6697
6724
  const grouped = /* @__PURE__ */ new Set();
6698
6725
  const usageScopes = [];
6699
6726
  const currentUsageScope = () => usageScopes.at(-1);
6700
6727
  const enterUsageScope = (node) => {
6701
- usageScopes.push({ node, objects: /* @__PURE__ */ new Map() });
6728
+ usageScopes.push({ node, objects: /* @__PURE__ */ new Map(), singleProperties: [] });
6702
6729
  };
6703
6730
  const enterUsageBarrier = () => {
6704
6731
  usageScopes.push(void 0);
@@ -6722,6 +6749,12 @@ var preferObjectDestructuringRule = {
6722
6749
  node: firstDirectMember,
6723
6750
  message: scopeUsageMessage(sourceText, usage.propertyNames),
6724
6751
  fix(fixer) {
6752
+ if (usage.directMembers.some(({ member }) => {
6753
+ const parent = context.sourceCode.getAncestors(member).at(-1);
6754
+ return parent?.type === "CallExpression" && parent.callee === member;
6755
+ })) {
6756
+ return null;
6757
+ }
6725
6758
  const memberFixes = usage.directMembers.map(
6726
6759
  ({ member, propertyName: propertyName5 }) => fixer.replaceText(member, propertyName5)
6727
6760
  );
@@ -6745,6 +6778,31 @@ ${indentation}`;
6745
6778
  }
6746
6779
  });
6747
6780
  }
6781
+ for (const binding of scope.singleProperties) {
6782
+ const fromSameSource = scope.singleProperties.filter(({ sourceText }) => sourceText === binding.sourceText);
6783
+ if (fromSameSource[0] !== binding) continue;
6784
+ const usage = scope.objects.get(binding.sourceText);
6785
+ const usedProperties = usage?.propertyNames;
6786
+ if (usedProperties && usedProperties.size > 1 && usage.directMembers.length > 0) {
6787
+ if (scope.singleProperties.some(
6788
+ (item) => item.node.type === "ObjectPattern" && item.sourceText === binding.sourceText
6789
+ )) {
6790
+ continue;
6791
+ }
6792
+ }
6793
+ if (usedProperties && usedProperties.size > 1) {
6794
+ context.report({ node: binding.node, message: scopeUsageMessage(binding.sourceText, usedProperties) });
6795
+ continue;
6796
+ }
6797
+ if (fromSameSource.length > 1) {
6798
+ const names = new Set(fromSameSource.map(({ propertyName: propertyName5 }) => propertyName5));
6799
+ if (names.size > 1) {
6800
+ context.report({ node: binding.node, message: scopeUsageMessage(binding.sourceText, names) });
6801
+ continue;
6802
+ }
6803
+ }
6804
+ context.report({ node: binding.node, message: singlePropertyMessage(binding) });
6805
+ }
6748
6806
  };
6749
6807
  return {
6750
6808
  Program: enterUsageScope,
@@ -6758,7 +6816,7 @@ ${indentation}`;
6758
6816
  ArrowFunctionExpression: enterUsageBarrier,
6759
6817
  "ArrowFunctionExpression:exit": exitUsageScope,
6760
6818
  MemberExpression(node) {
6761
- recordMemberUsage(context, currentUsageScope(), ownershipResolver, node, isEnumValue);
6819
+ recordMemberUsage(context, currentUsageScope(), ownershipResolver, node, isEnumValue, detachableCall);
6762
6820
  },
6763
6821
  VariableDeclaration(node) {
6764
6822
  for (const declarator of node.declarations) {
@@ -6774,7 +6832,20 @@ ${indentation}`;
6774
6832
  const selection = destructuringSelection(context, node, isEnumValue);
6775
6833
  if (selection) {
6776
6834
  const group = groupedDestructuringSelections(context, selection, isEnumValue);
6777
- if (group.length <= 1) return;
6835
+ if (group.length <= 1) {
6836
+ if (node.kind === "const" && selection.propertyNames.length === 1 && supportsSinglePropertySource(selection.source)) {
6837
+ const declarator = node.declarations[0];
6838
+ const propertyName5 = selection.propertyNames[0];
6839
+ if (declarator && propertyName5) {
6840
+ currentUsageScope()?.singleProperties.push({
6841
+ node: declarator.id,
6842
+ sourceText: selection.sourceText,
6843
+ propertyName: propertyName5
6844
+ });
6845
+ }
6846
+ }
6847
+ return;
6848
+ }
6778
6849
  for (const item of group.slice(1)) grouped.add(item.declaration);
6779
6850
  const lastDeclaration = group.at(-1)?.declaration;
6780
6851
  if (!lastDeclaration) return;
@@ -6841,13 +6912,11 @@ ${indentation}`;
6841
6912
  }
6842
6913
  }
6843
6914
  for (const binding of bindings) {
6844
- if (!canGroupSource(binding.source)) continue;
6845
- context.report({
6915
+ if (node.kind !== "const" || !supportsSinglePropertySource(binding.source)) continue;
6916
+ currentUsageScope()?.singleProperties.push({
6846
6917
  node: binding.declarator,
6847
- message: singleMessage(binding),
6848
- fix(fixer) {
6849
- return fixer.replaceText(binding.declarator, `{ ${binding.bindingText} } = ${binding.sourceText}`);
6850
- }
6918
+ sourceText: binding.sourceText,
6919
+ propertyName: binding.propertyName
6851
6920
  });
6852
6921
  }
6853
6922
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.91",
3
+ "version": "0.10.93",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",