pumuki 6.3.345 → 6.3.347

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.
@@ -1306,6 +1306,10 @@ struct CheckoutView: View {
1306
1306
  @State private var isLoading = false
1307
1307
 
1308
1308
  var body: some View {
1309
+ Button(action: navigateBack) {
1310
+ Image(systemName: "chevron.left")
1311
+ }
1312
+
1309
1313
  Button {
1310
1314
  if isLoading {
1311
1315
  return
@@ -1332,11 +1336,47 @@ struct CheckoutView: View {
1332
1336
  `;
1333
1337
 
1334
1338
  assert.equal(hasSwiftUiInlineActionLogicUsage(source), true);
1335
- assert.deepEqual(collectSwiftUiInlineActionLogicLines(source), [6]);
1339
+ assert.deepEqual(collectSwiftUiInlineActionLogicLines(source), [10]);
1336
1340
  assert.equal(hasSwiftUiInlineActionLogicUsage(safe), false);
1337
1341
  assert.deepEqual(collectSwiftUiInlineActionLogicLines(safe), []);
1338
1342
  });
1339
1343
 
1344
+ test('hasSwiftUiInlineActionLogicUsage preserva varios Button(action: metodo) aunque exista otro Button inline', () => {
1345
+ const source = `
1346
+ struct ProductDetailScreen: View {
1347
+ var body: some View {
1348
+ VStack {
1349
+ Button(action: navigateBackFromProductDetail) {
1350
+ Image(systemName: "chevron.left")
1351
+ }
1352
+ Button(action: toggleFavoriteProduct) {
1353
+ Image(systemName: "heart")
1354
+ }
1355
+ Button(action: decrementQuantity) {
1356
+ Text("-")
1357
+ }
1358
+ Button(action: incrementQuantity) {
1359
+ Text("+")
1360
+ }
1361
+ Button(action: addProductToCartAndNavigate) {
1362
+ Text("Add")
1363
+ }
1364
+ Button {
1365
+ if isLoading {
1366
+ return
1367
+ }
1368
+ } label: {
1369
+ Text("Retry")
1370
+ }
1371
+ }
1372
+ }
1373
+ }
1374
+ `;
1375
+
1376
+ assert.equal(hasSwiftUiInlineActionLogicUsage(source), true);
1377
+ assert.deepEqual(collectSwiftUiInlineActionLogicLines(source), [20]);
1378
+ });
1379
+
1340
1380
  test('hasSwiftAnimationWithoutReduceMotionUsage detecta animaciones sin preferencia reduce motion', () => {
1341
1381
  const source = `
1342
1382
  struct CheckoutView: View {
@@ -854,14 +854,35 @@ export const hasSwiftLargeViewBuilderFunctionUsage = (source: string): boolean =
854
854
  return collectSwiftLargeViewBuilderFunctionLines(source).length > 0;
855
855
  };
856
856
 
857
- export const hasSwiftUiInlineActionLogicUsage = (source: string): boolean => {
857
+ const swiftInlineActionLogicPattern = /\b(?:if|guard|switch|for|while|Task)\b/;
858
+
859
+ const swiftSnippetContainsInlineActionLogic = (snippet: string): boolean => {
860
+ return swiftInlineActionLogicPattern.test(snippet);
861
+ };
862
+
863
+ export const collectSwiftUiInlineActionLogicLines = (source: string): readonly number[] => {
858
864
  const swiftSource = sanitizeSwiftSourceForMultilineRegex(source);
865
+ const matches: number[] = [];
859
866
  const inlineButtonActionPattern =
860
- /\bButton\s*\{[\s\S]{0,900}\b(?:if|guard|switch|for|while|Task)\b[\s\S]{0,900}\}\s*label\s*:/;
867
+ /\bButton\s*\{(?<body>[\s\S]{0,900}?)\}\s*label\s*:/g;
861
868
  const inlineActionParameterPattern =
862
- /\bButton\s*\([^)]*\baction\s*:\s*\{[\s\S]{0,900}\b(?:if|guard|switch|for|while|Task)\b[\s\S]{0,900}\}/;
869
+ /\bButton\s*\([^)]*\baction\s*:\s*\{(?<body>[\s\S]{0,900}?)\}/g;
870
+
871
+ for (const pattern of [inlineButtonActionPattern, inlineActionParameterPattern]) {
872
+ for (const match of swiftSource.matchAll(pattern)) {
873
+ const body = match.groups?.body ?? '';
874
+ if (!swiftSnippetContainsInlineActionLogic(body)) {
875
+ continue;
876
+ }
877
+ matches.push(getLineNumberAtIndex(swiftSource, match.index ?? 0));
878
+ }
879
+ }
863
880
 
864
- return inlineButtonActionPattern.test(swiftSource) || inlineActionParameterPattern.test(swiftSource);
881
+ return sortedUniqueLines(matches);
882
+ };
883
+
884
+ export const hasSwiftUiInlineActionLogicUsage = (source: string): boolean => {
885
+ return collectSwiftUiInlineActionLogicLines(source).length > 0;
865
886
  };
866
887
 
867
888
  export const collectSwiftAnimationWithoutReduceMotionLines = (source: string): readonly number[] => {
@@ -880,13 +901,6 @@ export const hasSwiftAnimationWithoutReduceMotionUsage = (source: string): boole
880
901
  return collectSwiftAnimationWithoutReduceMotionLines(source).length > 0;
881
902
  };
882
903
 
883
- export const collectSwiftUiInlineActionLogicLines = (source: string): readonly number[] => {
884
- if (!hasSwiftUiInlineActionLogicUsage(source)) {
885
- return [];
886
- }
887
- return collectSwiftRegexLines(source, /\bButton\s*(?:\(|\{)/);
888
- };
889
-
890
904
  export const hasSwiftDispatchQueueUsage = (source: string): boolean => {
891
905
  return scanCodeLikeSource(source, ({ source: swiftSource, index, current }) => {
892
906
  if (current !== 'D' || !hasIdentifierAt(swiftSource, index, 'DispatchQueue')) {
@@ -52,6 +52,10 @@ const NON_CODE_RULE_PATTERNS: ReadonlyArray<RegExp> = [
52
52
  /\bdocumentation\b/,
53
53
  /\bdocumentacion\b/,
54
54
  /\breadme\b/,
55
+ /\buse grep\b/,
56
+ /\buse references\b/,
57
+ /\breferences\b.*\bmd\b/,
58
+ /\bwhen to use\b/,
55
59
  /\bci\/cd\b/,
56
60
  /\baaa pattern\b/,
57
61
  /\barrange\b.*\bact\b.*\bassert\b/,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pumuki",
3
- "version": "6.3.345",
3
+ "version": "6.3.347",
4
4
  "description": "Enterprise-grade AST Intelligence System with multi-platform support (iOS, Android, Backend, Frontend) and Feature-First + DDD + Clean Architecture enforcement. Includes dynamic violations API for intelligent querying.",
5
5
  "main": "index.js",
6
6
  "bin": {