@runa-ai/runa-cli 0.7.0 → 0.7.2

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 (139) hide show
  1. package/dist/{build-V66FAQXB.js → build-HQMSVN6N.js} +3 -3
  2. package/dist/{check-LOMVIRHX.js → check-PCSQPYDM.js} +2 -2
  3. package/dist/{chunk-QM53IQHM.js → chunk-2QX7T24B.js} +1 -1
  4. package/dist/{chunk-XDCHRVE3.js → chunk-4XHZQRRK.js} +2 -2
  5. package/dist/{chunk-7B5C6U2K.js → chunk-A6A7JIRD.js} +35 -2
  6. package/dist/{chunk-Z4Z5DNW4.js → chunk-B3POLMII.js} +12 -0
  7. package/dist/chunk-CKRLVEIO.js +119 -0
  8. package/dist/{chunk-HD74F6W2.js → chunk-FWMGC5FP.js} +1 -0
  9. package/dist/{chunk-H2AHNI75.js → chunk-LCK2LGVR.js} +1 -1
  10. package/dist/{chunk-FHG3ILE4.js → chunk-OBYZDT2E.js} +38 -8
  11. package/dist/{chunk-AIP6MR42.js → chunk-PMXE5XOJ.js} +1 -1
  12. package/dist/{chunk-VM3IWOT5.js → chunk-QSEF4T3Y.js} +13 -5
  13. package/dist/{chunk-NPSRD26F.js → chunk-UHDAYPHH.js} +1 -1
  14. package/dist/{chunk-2APB25TT.js → chunk-VSH3IXDQ.js} +7 -3
  15. package/dist/{chunk-644FVGIQ.js → chunk-WPMR7RQ4.js} +9 -2
  16. package/dist/chunk-XVNDDHAF.js +65 -0
  17. package/dist/{risk-detector-plpgsql-HWKS4OLR.js → chunk-Y5ANTCKE.js} +3 -412
  18. package/dist/{chunk-SGJG3BKD.js → chunk-Z7A4BEWF.js} +1 -1
  19. package/dist/{ci-ZWRVWNFX.js → ci-Z4525QW6.js} +3095 -709
  20. package/dist/{cli-2JNBJUBB.js → cli-Q2XIQDRS.js} +72 -54
  21. package/dist/commands/ci/commands/ci-prod-db-operations.d.ts +6 -4
  22. package/dist/commands/ci/commands/ci-prod-types.d.ts +3 -0
  23. package/dist/commands/ci/commands/ci-prod-workflow.d.ts +1 -1
  24. package/dist/commands/ci/commands/ci-resolvers.d.ts +1 -1
  25. package/dist/commands/ci/commands/ci-supabase-local.d.ts +4 -0
  26. package/dist/commands/ci/machine/actors/build/build-and-playwright.d.ts +1 -1
  27. package/dist/commands/ci/machine/actors/db/collect-schema-stats.d.ts +15 -2
  28. package/dist/commands/ci/machine/actors/db/production-preview.d.ts +32 -4
  29. package/dist/commands/ci/machine/actors/db/schema-canonical-diff.d.ts +30 -1
  30. package/dist/commands/ci/machine/actors/db/sync-schema.d.ts +1 -0
  31. package/dist/commands/ci/machine/actors/finalize/index.d.ts +0 -1
  32. package/dist/commands/ci/machine/actors/index.d.ts +1 -1
  33. package/dist/commands/ci/machine/actors/setup/local.d.ts +2 -0
  34. package/dist/commands/ci/machine/actors/setup/pr-common.d.ts +3 -0
  35. package/dist/commands/ci/machine/actors/setup/pr-local.d.ts +2 -0
  36. package/dist/commands/ci/machine/commands/machine-runner.d.ts +6 -0
  37. package/dist/commands/ci/machine/commands/step-telemetry.d.ts +16 -0
  38. package/dist/commands/ci/machine/contract.d.ts +40 -0
  39. package/dist/commands/ci/machine/formatters/github-comment-types.d.ts +7 -2
  40. package/dist/commands/ci/machine/formatters/github-comment.d.ts +2 -1
  41. package/dist/commands/ci/machine/formatters/sections/final-comment.d.ts +2 -1
  42. package/dist/commands/ci/machine/formatters/sections/index.d.ts +1 -1
  43. package/dist/commands/ci/machine/formatters/sections/production-schema-status.d.ts +30 -0
  44. package/dist/commands/ci/machine/formatters/summary.d.ts +4 -4
  45. package/dist/commands/ci/machine/guards.d.ts +4 -0
  46. package/dist/commands/ci/machine/helpers.d.ts +33 -0
  47. package/dist/commands/ci/machine/machine-state-helpers.d.ts +1 -1
  48. package/dist/commands/ci/machine/machine.d.ts +71 -11
  49. package/dist/commands/ci/machine/types.d.ts +9 -0
  50. package/dist/commands/ci/utils/ci-diagnostics.d.ts +67 -0
  51. package/dist/commands/ci/utils/ci-summary.d.ts +118 -0
  52. package/dist/commands/ci/utils/db-url-utils.d.ts +4 -77
  53. package/dist/commands/ci/utils/github-api.d.ts +14 -0
  54. package/dist/commands/db/apply/contract.d.ts +73 -0
  55. package/dist/commands/db/apply/helpers/alter-statement-parsers.d.ts +95 -0
  56. package/dist/commands/db/apply/helpers/data-compatibility-checker.d.ts +0 -61
  57. package/dist/commands/db/apply/helpers/function-plan-false-positive-filter.d.ts +36 -0
  58. package/dist/commands/db/apply/helpers/hazard-handler.d.ts +4 -4
  59. package/dist/commands/db/apply/helpers/index.d.ts +14 -5
  60. package/dist/commands/db/apply/helpers/partition-acl-cleaner.d.ts +3 -1
  61. package/dist/commands/db/apply/helpers/pg-schema-diff-helpers.d.ts +69 -6
  62. package/dist/commands/db/apply/helpers/plan-ast.d.ts +56 -0
  63. package/dist/commands/db/apply/helpers/plan-check-filter.d.ts +26 -0
  64. package/dist/commands/db/apply/helpers/plan-drop-protection.d.ts +43 -0
  65. package/dist/commands/db/apply/helpers/plan-ordering.d.ts +6 -0
  66. package/dist/commands/db/apply/helpers/plan-statement-parser.d.ts +39 -0
  67. package/dist/commands/db/apply/helpers/plan-validator.d.ts +8 -40
  68. package/dist/commands/db/apply/helpers/retry-logic.d.ts +1 -10
  69. package/dist/commands/db/apply/helpers/temp-db-bootstrap.d.ts +18 -0
  70. package/dist/commands/db/apply/helpers/temp-db-dsn.d.ts +14 -0
  71. package/dist/commands/db/apply/machine.d.ts +56 -32
  72. package/dist/commands/db/commands/db-apply-error.d.ts +5 -0
  73. package/dist/commands/db/commands/db-apply.d.ts +2 -0
  74. package/dist/commands/db/commands/db-sync/directory-placement-check.d.ts +4 -0
  75. package/dist/commands/db/commands/db-sync/error-classifier.d.ts +1 -1
  76. package/dist/commands/db/commands/db-sync/plan-boundary-reconciliation.d.ts +3 -0
  77. package/dist/commands/db/commands/db-sync/precheck-helpers.d.ts +18 -0
  78. package/dist/commands/db/commands/db-sync/production-precheck.d.ts +15 -0
  79. package/dist/commands/db/commands/db-sync/risk-scan-collectors.d.ts +11 -0
  80. package/dist/commands/db/commands/db-sync.d.ts +11 -5
  81. package/dist/commands/db/sync/contract.d.ts +80 -0
  82. package/dist/commands/db/sync/machine.d.ts +60 -1
  83. package/dist/commands/db/types.d.ts +5 -0
  84. package/dist/commands/db/utils/boundary-policy/rule-compiler.d.ts +2 -1
  85. package/dist/commands/db/utils/boundary-policy/types.d.ts +21 -0
  86. package/dist/commands/db/utils/boundary-policy-runtime.d.ts +12 -3
  87. package/dist/commands/db/utils/boundary-policy.d.ts +1 -1
  88. package/dist/commands/db/utils/db-target.d.ts +5 -3
  89. package/dist/commands/db/utils/declarative-dependency-collectors.d.ts +6 -0
  90. package/dist/commands/db/utils/declarative-dependency-contract.d.ts +78 -0
  91. package/dist/commands/db/utils/declarative-dependency-sql-utils.d.ts +49 -0
  92. package/dist/commands/db/utils/declarative-dependency-warning-governance.d.ts +24 -0
  93. package/dist/commands/db/utils/preflight-check.d.ts +1 -1
  94. package/dist/commands/db/utils/preflight-checks/declarative-dependency-checks.d.ts +4 -0
  95. package/dist/commands/db/utils/preflight-checks/idempotent-risk-checks.d.ts +4 -0
  96. package/dist/commands/db/utils/preflight-checks/schema-boundary-checks.d.ts +4 -0
  97. package/dist/commands/db/utils/preflight-checks/schema-risk-policy.d.ts +4 -0
  98. package/dist/commands/db/utils/preflight-checks/supabase-checks.d.ts +12 -0
  99. package/dist/commands/db/utils/psql.d.ts +23 -0
  100. package/dist/commands/db/utils/sql-table-extractor.d.ts +42 -1
  101. package/dist/commands/env/commands/setup/types.d.ts +1 -0
  102. package/dist/commands/env/constants/local-supabase.d.ts +4 -1
  103. package/dist/commands/observability.d.ts +72 -0
  104. package/dist/commands/observability.helpers.d.ts +25 -0
  105. package/dist/commands/template-check/commands/template-check.d.ts +1 -0
  106. package/dist/commands/template-check/contract.d.ts +4 -3
  107. package/dist/commands/template-check/machine.d.ts +1 -1
  108. package/dist/commands/workflow/commands/deploy-production.d.ts +0 -1
  109. package/dist/constants/versions.d.ts +1 -1
  110. package/dist/{db-XULCILOU.js → db-BPQ2TEQM.js} +14618 -11273
  111. package/dist/{dev-5YXNPTCJ.js → dev-MLRKIP7F.js} +5 -5
  112. package/dist/{doctor-MZLOA53G.js → doctor-ROSWSMLH.js} +2 -2
  113. package/dist/{env-SS66PZ4B.js → env-WNHJVLOT.js} +37 -20
  114. package/dist/{env-HMMRSYCI.js → env-XPPACZM4.js} +2 -2
  115. package/dist/{env-files-2UIUYLLR.js → env-files-HRNUGZ5O.js} +1 -1
  116. package/dist/{error-handler-HEXBRNVV.js → error-handler-YRQWRDEF.js} +17 -0
  117. package/dist/{hotfix-YA3DGLOM.js → hotfix-Z5EGVSMH.js} +4 -4
  118. package/dist/index.js +4 -4
  119. package/dist/{init-ZIL6LRFO.js → init-S2ATHLJ6.js} +1 -1
  120. package/dist/{inject-test-attrs-P44BVTQS.js → inject-test-attrs-XN4I2AOR.js} +2 -2
  121. package/dist/internal/machines/index.d.ts +1 -1
  122. package/dist/internal/machines/snapshot-helpers.d.ts +6 -0
  123. package/dist/{manifest-TMFLESHW.js → manifest-EGCAZ4TK.js} +1 -1
  124. package/dist/observability-CJA5UFIC.js +721 -0
  125. package/dist/{risk-detector-4U6ZJ2G5.js → risk-detector-VO5HJR4R.js} +1 -1
  126. package/dist/{risk-detector-core-TK4OAI3N.js → risk-detector-core-7WZJZ5ZI.js} +61 -3
  127. package/dist/risk-detector-plpgsql-ULV7NLDB.js +638 -0
  128. package/dist/{template-check-3P4HZXVY.js → template-check-BDFMT6ZO.js} +23 -6
  129. package/dist/{upgrade-NUK3ZBCL.js → upgrade-BDUWBRT5.js} +1 -1
  130. package/dist/utils/db-url-utils.d.ts +81 -0
  131. package/dist/validators/risk-detector-plpgsql.d.ts +3 -1
  132. package/dist/{vuln-check-2W7N5TA2.js → vuln-check-66RXX3TO.js} +1 -1
  133. package/dist/{vuln-checker-IQJ56RUV.js → vuln-checker-FFOGOJPT.js} +1 -1
  134. package/dist/{watch-PNTKZYFB.js → watch-ITYW57SL.js} +1 -1
  135. package/dist/{workflow-H75N4BXX.js → workflow-UZIZ2JUS.js} +2 -3
  136. package/package.json +3 -3
  137. package/dist/chunk-IBVVGH6X.js +0 -33
  138. package/dist/chunk-KWX3JHCY.js +0 -85
  139. package/dist/commands/ci/machine/actors/finalize/summary.d.ts +0 -32
@@ -1,16 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'module';
3
- import { stripSqlCommentsPreserveLines, buildLineStarts, lineNumberFromIndex, stripSqlStringsPreserveLines, detectRisksFromContent, stripSqlForPatternMatching } from './chunk-3FDQW524.js';
4
3
  import { init_esm_shims } from './chunk-VRXHCR5K.js';
5
4
 
6
5
  createRequire(import.meta.url);
7
6
 
8
- // src/validators/risk-detector-plpgsql.ts
9
- init_esm_shims();
10
-
11
- // src/validators/risk-detector-plpgsql-parser.ts
12
- init_esm_shims();
13
-
14
7
  // src/validators/risk-detector-plpgsql-tokenizer.ts
15
8
  init_esm_shims();
16
9
  function skipWhitespace(content, index) {
@@ -1478,409 +1471,7 @@ function isPureLiteralValue(value) {
1478
1471
  return parseStaticSqlLiteral(trimmed) !== void 0 || parseDollarLiteral(trimmed) !== void 0;
1479
1472
  }
1480
1473
 
1481
- // src/validators/risk-detector-plpgsql.ts
1482
- var DO_STATEMENT_PATTERN = /\bDO\b/gi;
1483
- var CREATE_OR_ALTER_FUNCTION_PATTERN = /\b(?:CREATE|ALTER)\s+(?:OR\s+REPLACE\s+)?(?:FUNCTION|PROCEDURE)\b/gi;
1484
- function readDollarTag(content, index) {
1485
- const match = content.slice(index).match(/^\$([A-Za-z_][A-Za-z0-9_]*)?\$/);
1486
- return match ? match[0] : void 0;
1487
- }
1488
- function isWordChar2(char) {
1489
- return /[A-Za-z0-9_]/.test(char);
1490
- }
1491
- function isKeywordAt(content, contentIndex, keyword) {
1492
- const endIndex = contentIndex + keyword.length;
1493
- if (endIndex > content.length) return false;
1494
- if (content.slice(contentIndex, endIndex).toUpperCase() !== keyword) return false;
1495
- const before = contentIndex > 0 ? content[contentIndex - 1] : " ";
1496
- const after = endIndex < content.length ? content[endIndex] : " ";
1497
- return !isWordChar2(before) && !isWordChar2(after);
1498
- }
1499
- function consumeSingleQuote(content, state) {
1500
- if (!state.inSingleQuote) return false;
1501
- if (content[state.cursor] === "'" && content[state.cursor + 1] === "'") {
1502
- state.cursor += 2;
1503
- return true;
1504
- }
1505
- if (content[state.cursor] === "'") {
1506
- state.inSingleQuote = false;
1507
- }
1508
- state.cursor += 1;
1509
- return true;
1510
- }
1511
- function consumeDoubleQuote(content, state) {
1512
- if (!state.inDoubleQuote) return false;
1513
- if (content[state.cursor] === '"' && content[state.cursor + 1] === '"') {
1514
- state.cursor += 2;
1515
- return true;
1516
- }
1517
- if (content[state.cursor] === '"') {
1518
- state.inDoubleQuote = false;
1519
- }
1520
- state.cursor += 1;
1521
- return true;
1522
- }
1523
- function consumeDollarQuote(content, state) {
1524
- if (state.inDollarQuote === void 0) return false;
1525
- const close = `$${state.inDollarQuote}$`;
1526
- if (content.startsWith(close, state.cursor)) {
1527
- state.inDollarQuote = void 0;
1528
- state.cursor += close.length;
1529
- return true;
1530
- }
1531
- state.cursor += 1;
1532
- return true;
1533
- }
1534
- function consumeQuotedSpan(content, state) {
1535
- if (consumeSingleQuote(content, state)) return true;
1536
- if (consumeDoubleQuote(content, state)) return true;
1537
- return consumeDollarQuote(content, state);
1538
- }
1539
- function tryStartSingleQuote(content, state) {
1540
- if (content[state.cursor] !== "'") return false;
1541
- state.inSingleQuote = true;
1542
- state.cursor += 1;
1543
- return true;
1544
- }
1545
- function tryStartDoubleQuote(content, state) {
1546
- if (content[state.cursor] !== '"') return false;
1547
- state.inDoubleQuote = true;
1548
- state.cursor += 1;
1549
- return true;
1550
- }
1551
- function tryStartDollarQuote(content, state) {
1552
- const dollarTag = readDollarTag(content, state.cursor);
1553
- if (dollarTag === void 0) return false;
1554
- state.inDollarQuote = dollarTag.slice(1, -1);
1555
- state.cursor += dollarTag.length;
1556
- return true;
1557
- }
1558
- function tryStartQuotedSpan(content, state) {
1559
- if (tryStartSingleQuote(content, state)) return true;
1560
- if (tryStartDoubleQuote(content, state)) return true;
1561
- return tryStartDollarQuote(content, state);
1562
- }
1563
- function findKeywordFromOffset(content, start, keyword) {
1564
- const state = {
1565
- cursor: start,
1566
- inSingleQuote: false,
1567
- inDoubleQuote: false,
1568
- inDollarQuote: void 0
1569
- };
1570
- while (state.cursor < content.length) {
1571
- if (consumeQuotedSpan(content, state)) continue;
1572
- if (tryStartQuotedSpan(content, state)) continue;
1573
- if (isKeywordAt(content, state.cursor, keyword)) {
1574
- return state.cursor;
1575
- }
1576
- state.cursor += 1;
1577
- }
1578
- return void 0;
1579
- }
1580
- var MAX_DOLLAR_QUOTE_DEPTH = 50;
1581
- function skipUntilDollarClose(content, state, openTag, depth) {
1582
- if (depth >= MAX_DOLLAR_QUOTE_DEPTH) return -1;
1583
- const nestedTag = readDollarTag(content, state.cursor);
1584
- if (nestedTag === void 0 || nestedTag === openTag) {
1585
- return state.cursor;
1586
- }
1587
- const nestedStart = state.cursor + nestedTag.length;
1588
- const nestedEnd = closeIndexForDollarTag(content, nestedStart, nestedTag, depth + 1);
1589
- if (nestedEnd === -1) return -1;
1590
- state.cursor = nestedEnd + nestedTag.length;
1591
- return state.cursor;
1592
- }
1593
- function closeIndexForDollarTag(content, bodyStart, openTag, depth = 0) {
1594
- if (depth >= MAX_DOLLAR_QUOTE_DEPTH) return -1;
1595
- const state = {
1596
- cursor: bodyStart,
1597
- inSingleQuote: false,
1598
- inDoubleQuote: false,
1599
- inDollarQuote: void 0
1600
- };
1601
- while (state.cursor < content.length) {
1602
- if (consumeQuotedSpan(content, state)) continue;
1603
- if (content.startsWith(openTag, state.cursor)) {
1604
- return state.cursor;
1605
- }
1606
- const nestedCursor = skipUntilDollarClose(content, state, openTag, depth);
1607
- if (nestedCursor !== state.cursor) {
1608
- continue;
1609
- }
1610
- if (tryStartSingleQuote(content, state)) continue;
1611
- if (tryStartDoubleQuote(content, state)) continue;
1612
- state.cursor += 1;
1613
- }
1614
- return -1;
1615
- }
1616
- function resolveBodyRange(content, openTagStart, statementType) {
1617
- const openTag = readDollarTag(content, openTagStart);
1618
- if (openTag === void 0) return void 0;
1619
- const bodyStart = openTagStart + openTag.length;
1620
- const bodyEnd = closeIndexForDollarTag(content, bodyStart, openTag);
1621
- if (bodyEnd === -1) return void 0;
1622
- return {
1623
- range: { bodyStart, bodyEnd, statementType },
1624
- nextScanIndex: bodyEnd + openTag.length
1625
- };
1626
- }
1627
- function skipDoLanguageClause(content, cursor) {
1628
- if (!isKeywordAt(content, cursor, "LANGUAGE")) {
1629
- return cursor;
1630
- }
1631
- const langNameStart = skipWhitespace2(content, cursor + "LANGUAGE".length);
1632
- const afterLangName = skipIdentifier(content, langNameStart);
1633
- return skipWhitespace2(content, afterLangName);
1634
- }
1635
- function collectDoBodyRanges(content) {
1636
- const ranges = [];
1637
- DO_STATEMENT_PATTERN.lastIndex = 0;
1638
- let doMatch = DO_STATEMENT_PATTERN.exec(content);
1639
- while (doMatch !== null) {
1640
- const doStart = doMatch.index;
1641
- if (findKeywordFromOffset(content, doStart, "DO") !== doStart) {
1642
- DO_STATEMENT_PATTERN.lastIndex = doStart + doMatch[0].length;
1643
- doMatch = DO_STATEMENT_PATTERN.exec(content);
1644
- continue;
1645
- }
1646
- let cursor = skipWhitespace2(content, doStart + doMatch[0].length);
1647
- cursor = skipDoLanguageClause(content, cursor);
1648
- const resolved = resolveBodyRange(content, cursor, "do");
1649
- if (resolved !== void 0) {
1650
- ranges.push(resolved.range);
1651
- DO_STATEMENT_PATTERN.lastIndex = resolved.nextScanIndex;
1652
- }
1653
- doMatch = DO_STATEMENT_PATTERN.exec(content);
1654
- }
1655
- DO_STATEMENT_PATTERN.lastIndex = 0;
1656
- return ranges;
1657
- }
1658
- function collectFunctionBodyRanges(content) {
1659
- const ranges = [];
1660
- CREATE_OR_ALTER_FUNCTION_PATTERN.lastIndex = 0;
1661
- let functionMatch = CREATE_OR_ALTER_FUNCTION_PATTERN.exec(content);
1662
- while (functionMatch !== null) {
1663
- const start = functionMatch.index;
1664
- const asIndex = findKeywordFromOffset(content, start + functionMatch[0].length, "AS");
1665
- if (asIndex === void 0) {
1666
- CREATE_OR_ALTER_FUNCTION_PATTERN.lastIndex = start + functionMatch[0].length;
1667
- functionMatch = CREATE_OR_ALTER_FUNCTION_PATTERN.exec(content);
1668
- continue;
1669
- }
1670
- const bodyStartAt = skipWhitespace2(content, asIndex + 2);
1671
- const resolved = resolveBodyRange(content, bodyStartAt, "function");
1672
- if (resolved !== void 0) {
1673
- ranges.push(resolved.range);
1674
- CREATE_OR_ALTER_FUNCTION_PATTERN.lastIndex = resolved.nextScanIndex;
1675
- }
1676
- functionMatch = CREATE_OR_ALTER_FUNCTION_PATTERN.exec(content);
1677
- }
1678
- CREATE_OR_ALTER_FUNCTION_PATTERN.lastIndex = 0;
1679
- return ranges;
1680
- }
1681
- function findFunctionAndDoBodies(content) {
1682
- return [...collectDoBodyRanges(content), ...collectFunctionBodyRanges(content)];
1683
- }
1684
- function enrichStaticExecuteRiskFromSql(sql, sourceLine) {
1685
- const staticSql2 = stripSqlForPatternMatching(sql);
1686
- if (!staticSql2.trim()) return [];
1687
- const staticSqlLineStarts = buildLineStarts(sql);
1688
- return detectRisksFromContent(staticSql2, sql, staticSqlLineStarts).map((risk) => ({
1689
- ...risk,
1690
- line: sourceLine,
1691
- evidence: {
1692
- source: "static execute body",
1693
- snippet: sql.trim().slice(0, 200),
1694
- detail: "Reconstructed PL/pgSQL EXECUTE expression"
1695
- }
1696
- }));
1697
- }
1698
- function buildDoBlockRisk(commentlessContent, range, declarationLine) {
1699
- const bodyPreviewStart = Math.max(0, range.bodyStart - 80);
1700
- const bodyPreviewEnd = range.bodyEnd + 80;
1701
- return {
1702
- level: "medium",
1703
- description: "DO block detected in SQL",
1704
- mitigation: "Prefer static declarative SQL or move bootstrap logic to idempotent script files with clear intent",
1705
- line: declarationLine,
1706
- reasonCode: "PLPGSQL_DO_BLOCK_DETECTED",
1707
- confidence: "medium",
1708
- evidence: {
1709
- source: "findFunctionAndDoBodies",
1710
- snippet: range.statementType === "do" ? commentlessContent.slice(bodyPreviewStart, bodyPreviewEnd) : void 0,
1711
- detail: `${range.statementType.toUpperCase()} block detected in schema SQL`
1712
- }
1713
- };
1714
- }
1715
- function maybeAddDoBlockRisk(risks, dedupe, commentlessContent, range, declarationLine) {
1716
- if (range.statementType !== "do") return;
1717
- const doKey = `do:${range.statementType}:${declarationLine}`;
1718
- if (dedupe.has(doKey)) return;
1719
- dedupe.add(doKey);
1720
- risks.push(buildDoBlockRisk(commentlessContent, range, declarationLine));
1721
- }
1722
- function applyStatementAssignment(statement, stringEnv) {
1723
- const assignment = parseTopLevelAssignment(statement.statement);
1724
- if (!assignment) return;
1725
- const resolved = extractStaticSqlFromExpression(assignment.expression, stringEnv);
1726
- if (resolved.kind !== "static") {
1727
- stringEnv.delete(assignment.target);
1728
- return;
1729
- }
1730
- if (assignment.isConditionalContext) {
1731
- mergeStringEnvValue(stringEnv, assignment.target, resolved.sql);
1732
- return;
1733
- }
1734
- stringEnv.set(assignment.target, resolved.sql);
1735
- }
1736
- function buildExecuteLine(content, lineStarts, range, statement, execute) {
1737
- return lineNumberFromIndex(
1738
- content,
1739
- range.bodyStart + statement.startOffset + execute.statementStartOffset,
1740
- lineStarts
1741
- );
1742
- }
1743
- function buildExecuteKey(range, statement, execute, executeLine) {
1744
- return `execute:${range.statementType}:${statement.startOffset}:${execute.statementStartOffset}:${executeLine}`;
1745
- }
1746
- function buildStaticExecuteRisk(execute, executeLine) {
1747
- return {
1748
- level: "medium",
1749
- description: "Static EXECUTE SQL detected in PL/pgSQL body",
1750
- mitigation: "Prefer declarative/static SQL when possible; keep this change explicit in declarative schemas",
1751
- line: executeLine,
1752
- reasonCode: "PLPGSQL_EXECUTE_STATIC",
1753
- confidence: "low",
1754
- evidence: {
1755
- source: "extractExecuteExpressions",
1756
- snippet: execute.expression.slice(0, 200),
1757
- detail: "Static EXECUTE SQL detected from reconstructed expression"
1758
- }
1759
- };
1760
- }
1761
- function pushDerivedStaticRisks(risks, dedupe, staticSql2, executeLine, hasUsingClause) {
1762
- const staticRisks = enrichStaticExecuteRiskFromSql(staticSql2, executeLine);
1763
- for (const staticRisk of staticRisks) {
1764
- const key = `${staticRisk.level}:${staticRisk.description}:${executeLine}`;
1765
- const dedupeKey = `static:${key}`;
1766
- if (dedupe.has(dedupeKey)) continue;
1767
- dedupe.add(dedupeKey);
1768
- risks.push({
1769
- ...staticRisk,
1770
- reasonCode: staticRisk.reasonCode ?? "PLPGSQL_EXECUTE_STATIC",
1771
- confidence: staticRisk.confidence ?? "low",
1772
- evidence: {
1773
- ...staticRisk.evidence,
1774
- source: staticRisk.evidence?.source ?? "detectRisksFromContent",
1775
- detail: `Static EXECUTE SQL analyzed from reconstructed expression${hasUsingClause ? " (USING clause present)" : ""}`
1776
- }
1777
- });
1778
- }
1779
- }
1780
- function maybeBuildUsingClauseRisk(execute, executeLine) {
1781
- if (!execute.hasUsingClause) return void 0;
1782
- return {
1783
- level: "high",
1784
- description: "PL/pgSQL EXECUTE uses USING bindings; values are applied at runtime and must be auditable",
1785
- mitigation: "Avoid runtime-bound SQL mutation in migration paths, or keep this change in idempotent with explicit review",
1786
- line: executeLine,
1787
- reasonCode: "PLPGSQL_EXECUTE_DYNAMIC_USING",
1788
- confidence: "high",
1789
- evidence: {
1790
- source: "extractExecuteExpressions",
1791
- snippet: execute.expression.slice(0, 200),
1792
- detail: "EXECUTE contains USING clause"
1793
- }
1794
- };
1795
- }
1796
- function pushBodyStaticRisks(risks, dedupe, body, bodyStartLine) {
1797
- const searchableBody = stripSqlStringsPreserveLines(body);
1798
- if (!searchableBody.trim()) return;
1799
- const bodyLineStarts = buildLineStarts(body);
1800
- const bodyRisks = detectRisksFromContent(searchableBody, body, bodyLineStarts);
1801
- for (const risk of bodyRisks) {
1802
- const line = bodyStartLine + ((risk.line ?? 1) - 1);
1803
- const dedupeKey = `body:${risk.reasonCode ?? risk.description}:${line}`;
1804
- if (dedupe.has(dedupeKey)) continue;
1805
- dedupe.add(dedupeKey);
1806
- risks.push({
1807
- ...risk,
1808
- line,
1809
- evidence: {
1810
- source: "plpgsql body",
1811
- snippet: body.trim().slice(0, 200),
1812
- detail: `Matched ${risk.reasonCode ?? "pattern"} inside PL/pgSQL body`
1813
- }
1814
- });
1815
- }
1816
- }
1817
- function buildUnresolvedExecuteRisk(execute, executeLine, reason) {
1818
- const clauseSuffix = execute.hasUsingClause ? " includes USING clause" : execute.hasIntoClause ? " includes INTO clause" : "";
1819
- return {
1820
- level: "high",
1821
- description: `UNRESOLVED_DYNAMIC_SQL in PL/PGSQL EXECUTE: ${reason}${clauseSuffix}`,
1822
- mitigation: "Resolve SQL construction at migration time or add manual review before production apply preview",
1823
- line: executeLine,
1824
- reasonCode: execute.hasUsingClause ? "PLPGSQL_EXECUTE_DYNAMIC_USING" : execute.hasIntoClause ? "PLPGSQL_EXECUTE_DYNAMIC_INTO" : "PLPGSQL_EXECUTE_UNRESOLVED",
1825
- confidence: "high",
1826
- evidence: {
1827
- source: "extractStaticSqlFromExpression",
1828
- snippet: execute.expression.slice(0, 200),
1829
- detail: `Failed to reconstruct dynamic SQL (${reason})`
1830
- }
1831
- };
1832
- }
1833
- function analyzeExecuteStatement(risks, dedupe, content, lineStarts, range, statement, execute, stringEnv) {
1834
- const executeLine = buildExecuteLine(content, lineStarts, range, statement, execute);
1835
- const executeKey = buildExecuteKey(range, statement, execute, executeLine);
1836
- if (dedupe.has(executeKey)) return;
1837
- dedupe.add(executeKey);
1838
- const extracted = extractStaticSqlFromExpression(execute.expression, stringEnv);
1839
- if (extracted.kind !== "static") {
1840
- risks.push(buildUnresolvedExecuteRisk(execute, executeLine, extracted.reason));
1841
- return;
1842
- }
1843
- risks.push(buildStaticExecuteRisk(execute, executeLine));
1844
- pushDerivedStaticRisks(risks, dedupe, extracted.sql, executeLine, execute.hasUsingClause);
1845
- const usingRisk = maybeBuildUsingClauseRisk(execute, executeLine);
1846
- if (usingRisk !== void 0) {
1847
- risks.push(usingRisk);
1848
- }
1849
- }
1850
- function analyzeBodyRange(risks, dedupe, content, commentlessContent, lineStarts, range) {
1851
- const declarationLine = lineNumberFromIndex(commentlessContent, range.bodyStart, lineStarts);
1852
- maybeAddDoBlockRisk(risks, dedupe, commentlessContent, range, declarationLine);
1853
- const body = commentlessContent.slice(range.bodyStart, range.bodyEnd);
1854
- pushBodyStaticRisks(risks, dedupe, body, declarationLine);
1855
- const stringEnv = /* @__PURE__ */ new Map();
1856
- for (const statement of splitPlpgsqlStatementsWithOffsets(body)) {
1857
- applyStatementAssignment(statement, stringEnv);
1858
- const executeStatements = extractExecuteExpressions(statement.statement);
1859
- for (const execute of executeStatements) {
1860
- analyzeExecuteStatement(
1861
- risks,
1862
- dedupe,
1863
- content,
1864
- lineStarts,
1865
- range,
1866
- statement,
1867
- execute,
1868
- stringEnv
1869
- );
1870
- }
1871
- }
1872
- }
1873
- function detectPlpgsqlDynamicExecutionRisks(content) {
1874
- const commentlessContent = stripSqlCommentsPreserveLines(content);
1875
- const lineStarts = buildLineStarts(commentlessContent);
1876
- const ranges = findFunctionAndDoBodies(commentlessContent);
1877
- if (ranges.length === 0) return [];
1878
- const risks = [];
1879
- const dedupe = /* @__PURE__ */ new Set();
1880
- for (const range of ranges) {
1881
- analyzeBodyRange(risks, dedupe, content, commentlessContent, lineStarts, range);
1882
- }
1883
- return risks;
1884
- }
1474
+ // src/validators/risk-detector-plpgsql-parser.ts
1475
+ init_esm_shims();
1885
1476
 
1886
- export { detectPlpgsqlDynamicExecutionRisks };
1477
+ export { extractExecuteExpressions, extractStaticSqlFromExpression, mergeStringEnvValue, parseTopLevelAssignment, skipIdentifier, skipWhitespace2 as skipWhitespace, splitPlpgsqlStatementsWithOffsets };
@@ -16,7 +16,7 @@ init_esm_shims();
16
16
 
17
17
  // src/constants/versions.ts
18
18
  init_esm_shims();
19
- var COMPATIBLE_TEMPLATES_VERSION = "0.5.71";
19
+ var COMPATIBLE_TEMPLATES_VERSION = "0.7.2";
20
20
  var TEMPLATES_PACKAGE_NAME = "@r06-dev/runa-templates";
21
21
  var GITHUB_PACKAGES_REGISTRY = "https://npm.pkg.github.com";
22
22