@runa-ai/runa-cli 0.7.2 → 0.7.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.
- package/dist/{chunk-Z7A4BEWF.js → chunk-3JO6YP3T.js} +1 -1
- package/dist/{chunk-PMXE5XOJ.js → chunk-AO554K3G.js} +1 -1
- package/dist/{chunk-LCK2LGVR.js → chunk-PAWNJA3N.js} +1 -1
- package/dist/{cli-Q2XIQDRS.js → cli-SVXOSMW6.js} +8 -8
- package/dist/commands/db/utils/boundary-policy/types.d.ts +2 -0
- package/dist/constants/versions.d.ts +1 -1
- package/dist/{db-BPQ2TEQM.js → db-S4V4ETDR.js} +85 -11
- package/dist/index.js +3 -3
- package/dist/{init-S2ATHLJ6.js → init-35JLDFHI.js} +1 -1
- package/dist/{risk-detector-VO5HJR4R.js → risk-detector-S7XQF4I2.js} +1 -1
- package/dist/{risk-detector-core-7WZJZ5ZI.js → risk-detector-core-TGFKWHRS.js} +1 -1
- package/dist/{risk-detector-plpgsql-ULV7NLDB.js → risk-detector-plpgsql-O32TUR34.js} +103 -5
- package/dist/{upgrade-BDUWBRT5.js → upgrade-7L4JIE4K.js} +1 -1
- package/dist/{vuln-check-66RXX3TO.js → vuln-check-D575VXIQ.js} +1 -1
- package/dist/{vuln-checker-FFOGOJPT.js → vuln-checker-QV6XODTJ.js} +1 -1
- package/dist/{watch-ITYW57SL.js → watch-AL4LCBRM.js} +1 -1
- package/package.json +1 -1
|
@@ -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.7.
|
|
19
|
+
var COMPATIBLE_TEMPLATES_VERSION = "0.7.3";
|
|
20
20
|
var TEMPLATES_PACKAGE_NAME = "@r06-dev/runa-templates";
|
|
21
21
|
var GITHUB_PACKAGES_REGISTRY = "https://npm.pkg.github.com";
|
|
22
22
|
|
|
@@ -9,7 +9,7 @@ init_esm_shims();
|
|
|
9
9
|
var riskDetectorModulePromise = null;
|
|
10
10
|
async function loadRiskDetectorModule() {
|
|
11
11
|
if (!riskDetectorModulePromise) {
|
|
12
|
-
riskDetectorModulePromise = import('./risk-detector-core-
|
|
12
|
+
riskDetectorModulePromise = import('./risk-detector-core-TGFKWHRS.js').catch((error) => {
|
|
13
13
|
riskDetectorModulePromise = null;
|
|
14
14
|
throw error;
|
|
15
15
|
});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
3
|
import { enableNonInteractiveMode } from './chunk-6Y3LAUGL.js';
|
|
4
4
|
import { getRequestedCommandNameFromArgv } from './chunk-UWWSAPDR.js';
|
|
5
|
-
import { CLI_VERSION, HAS_ADMIN_COMMAND } from './chunk-
|
|
5
|
+
import { CLI_VERSION, HAS_ADMIN_COMMAND } from './chunk-AO554K3G.js';
|
|
6
6
|
import { emitDefaultSuccessIfNeeded } from './chunk-WJXC4MVY.js';
|
|
7
7
|
import { parseOutputFormat, setOutputFormat, getOutputFormatFromEnv } from './chunk-HKUWEGUX.js';
|
|
8
8
|
import { init_esm_shims } from './chunk-VRXHCR5K.js';
|
|
@@ -145,7 +145,7 @@ function isTestCommand(requested) {
|
|
|
145
145
|
async function registerProjectLifecycleCommands(program, requested, loadAllCommands) {
|
|
146
146
|
if (!loadAllCommands && requested) {
|
|
147
147
|
if (requested === "init") {
|
|
148
|
-
const { initCommand: initCommand2 } = await import('./init-
|
|
148
|
+
const { initCommand: initCommand2 } = await import('./init-35JLDFHI.js');
|
|
149
149
|
program.addCommand(initCommand2);
|
|
150
150
|
return;
|
|
151
151
|
}
|
|
@@ -155,7 +155,7 @@ async function registerProjectLifecycleCommands(program, requested, loadAllComma
|
|
|
155
155
|
return;
|
|
156
156
|
}
|
|
157
157
|
if (requested === "upgrade") {
|
|
158
|
-
const { upgradeCommand: upgradeCommand2 } = await import('./upgrade-
|
|
158
|
+
const { upgradeCommand: upgradeCommand2 } = await import('./upgrade-7L4JIE4K.js');
|
|
159
159
|
program.addCommand(upgradeCommand2);
|
|
160
160
|
return;
|
|
161
161
|
}
|
|
@@ -183,9 +183,9 @@ async function registerProjectLifecycleCommands(program, requested, loadAllComma
|
|
|
183
183
|
{ buildCommand },
|
|
184
184
|
{ devCommand }
|
|
185
185
|
] = await Promise.all([
|
|
186
|
-
import('./init-
|
|
186
|
+
import('./init-35JLDFHI.js'),
|
|
187
187
|
import('./prepare-32DOVHTE.js'),
|
|
188
|
-
import('./upgrade-
|
|
188
|
+
import('./upgrade-7L4JIE4K.js'),
|
|
189
189
|
import('./validate-CAAW4Y44.js'),
|
|
190
190
|
import('./build-HQMSVN6N.js'),
|
|
191
191
|
import('./dev-MLRKIP7F.js')
|
|
@@ -466,7 +466,7 @@ async function registerCiCommand(program) {
|
|
|
466
466
|
program.addCommand(ciCommand);
|
|
467
467
|
}
|
|
468
468
|
async function registerDbCommand(program) {
|
|
469
|
-
const { dbCommand } = await import('./db-
|
|
469
|
+
const { dbCommand } = await import('./db-S4V4ETDR.js');
|
|
470
470
|
program.addCommand(dbCommand);
|
|
471
471
|
}
|
|
472
472
|
async function registerServicesCommand(program) {
|
|
@@ -490,7 +490,7 @@ async function registerUiCommand(program) {
|
|
|
490
490
|
program.addCommand(uiCommand);
|
|
491
491
|
}
|
|
492
492
|
async function registerWatchCommand(program) {
|
|
493
|
-
const { watchCommand } = await import('./watch-
|
|
493
|
+
const { watchCommand } = await import('./watch-AL4LCBRM.js');
|
|
494
494
|
program.addCommand(watchCommand);
|
|
495
495
|
}
|
|
496
496
|
async function registerWorkflowCommand(program) {
|
|
@@ -498,7 +498,7 @@ async function registerWorkflowCommand(program) {
|
|
|
498
498
|
program.addCommand(workflowCommand);
|
|
499
499
|
}
|
|
500
500
|
async function registerVulnCheckCommand(program) {
|
|
501
|
-
const { vulnCheckCommand } = await import('./vuln-check-
|
|
501
|
+
const { vulnCheckCommand } = await import('./vuln-check-D575VXIQ.js');
|
|
502
502
|
program.addCommand(vulnCheckCommand);
|
|
503
503
|
}
|
|
504
504
|
async function registerTemplateCheckCommand(program) {
|
|
@@ -27,6 +27,7 @@ export type DirectoryPlacementAllowlistRule = {
|
|
|
27
27
|
id: string;
|
|
28
28
|
filePattern: RegExp;
|
|
29
29
|
messagePattern: RegExp;
|
|
30
|
+
objectPattern?: RegExp;
|
|
30
31
|
level?: BoundaryPolicyRiskLevel;
|
|
31
32
|
lineStart?: number;
|
|
32
33
|
lineEnd?: number;
|
|
@@ -65,6 +66,7 @@ export type RawRule = {
|
|
|
65
66
|
code?: unknown;
|
|
66
67
|
filePattern?: unknown;
|
|
67
68
|
anchorPattern?: unknown;
|
|
69
|
+
objectPattern?: unknown;
|
|
68
70
|
descriptionPattern?: unknown;
|
|
69
71
|
messagePattern?: unknown;
|
|
70
72
|
level?: unknown;
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*
|
|
21
21
|
* Sync strategy: Keep this in sync with packages/runa-templates/package.json version.
|
|
22
22
|
*/
|
|
23
|
-
export declare const COMPATIBLE_TEMPLATES_VERSION = "0.7.
|
|
23
|
+
export declare const COMPATIBLE_TEMPLATES_VERSION = "0.7.3";
|
|
24
24
|
/**
|
|
25
25
|
* Templates package name on GitHub Packages.
|
|
26
26
|
* Published to npm.pkg.github.com (requires NODE_AUTH_TOKEN).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
3
|
import { detectDatabaseStack, getStackPaths } from './chunk-CCKG5R4Y.js';
|
|
4
|
-
import { categorizeRisks, detectSchemaRisks } from './chunk-
|
|
4
|
+
import { categorizeRisks, detectSchemaRisks } from './chunk-PAWNJA3N.js';
|
|
5
5
|
import './chunk-ZZOXM6Q4.js';
|
|
6
6
|
import { createError } from './chunk-JQXOVCOP.js';
|
|
7
7
|
import { resolveDatabaseUrl, resolveDatabaseTarget, tryResolveDatabaseUrl } from './chunk-CKRLVEIO.js';
|
|
@@ -5947,7 +5947,7 @@ function logIdempotentRiskSummary(summary) {
|
|
|
5947
5947
|
async function detectIdempotentRiskSummary(schemasDir, files, verbose) {
|
|
5948
5948
|
const summary = emptyRiskSummary();
|
|
5949
5949
|
try {
|
|
5950
|
-
const { detectSchemaRisks: detectSchemaRisks2 } = await import('./risk-detector-
|
|
5950
|
+
const { detectSchemaRisks: detectSchemaRisks2 } = await import('./risk-detector-S7XQF4I2.js');
|
|
5951
5951
|
for (const file of files) {
|
|
5952
5952
|
const filePath = join(schemasDir, file);
|
|
5953
5953
|
const risks = await detectSchemaRisks2(filePath);
|
|
@@ -6673,8 +6673,28 @@ function buildDirectoryPlacementRule(entry, index, seenIds, issueFormatter) {
|
|
|
6673
6673
|
issueFormatter
|
|
6674
6674
|
);
|
|
6675
6675
|
reportDeprecatedLineUsage(id, line, lineStart, lineEnd, issueFormatter);
|
|
6676
|
-
const
|
|
6677
|
-
|
|
6676
|
+
const objectPatternStr = coerceOptionalString(
|
|
6677
|
+
rawRule.objectPattern,
|
|
6678
|
+
index,
|
|
6679
|
+
`directoryPlacementAllowlist[${index}].objectPattern`,
|
|
6680
|
+
issueFormatter
|
|
6681
|
+
);
|
|
6682
|
+
const compiledObjectPattern = compileOptionalRulePattern(
|
|
6683
|
+
objectPatternStr ?? null,
|
|
6684
|
+
issueFormatter
|
|
6685
|
+
);
|
|
6686
|
+
if (objectPatternStr && !compiledObjectPattern) return null;
|
|
6687
|
+
const hasObjectPattern = compiledObjectPattern !== void 0;
|
|
6688
|
+
let scopedLineRange;
|
|
6689
|
+
if (!hasObjectPattern) {
|
|
6690
|
+
scopedLineRange = toScopedLineRange(lineStart, lineEnd, id, section, issueFormatter);
|
|
6691
|
+
if (!scopedLineRange) return null;
|
|
6692
|
+
} else {
|
|
6693
|
+
if (lineStart !== void 0 && lineEnd !== void 0) {
|
|
6694
|
+
scopedLineRange = toScopedLineRange(lineStart, lineEnd, id, section, issueFormatter);
|
|
6695
|
+
if (!scopedLineRange) return null;
|
|
6696
|
+
}
|
|
6697
|
+
}
|
|
6678
6698
|
const expiresAt = coerceExpiresAt(
|
|
6679
6699
|
rawRule.expiresAt,
|
|
6680
6700
|
id,
|
|
@@ -6692,9 +6712,10 @@ function buildDirectoryPlacementRule(entry, index, seenIds, issueFormatter) {
|
|
|
6692
6712
|
id,
|
|
6693
6713
|
filePattern: compiledPatterns[0],
|
|
6694
6714
|
messagePattern: compiledPatterns[1],
|
|
6715
|
+
objectPattern: compiledObjectPattern,
|
|
6695
6716
|
level,
|
|
6696
|
-
lineStart: scopedLineRange
|
|
6697
|
-
lineEnd: scopedLineRange
|
|
6717
|
+
lineStart: scopedLineRange?.lineStart,
|
|
6718
|
+
lineEnd: scopedLineRange?.lineEnd,
|
|
6698
6719
|
reason,
|
|
6699
6720
|
owner,
|
|
6700
6721
|
ticket,
|
|
@@ -7044,6 +7065,10 @@ function findDirectoryPlacementAllowlistMatch(issue, policy) {
|
|
|
7044
7065
|
if (entry.level !== void 0 && entry.level !== issue.level) return false;
|
|
7045
7066
|
if (!entry.filePattern.test(issue.file)) return false;
|
|
7046
7067
|
if (!entry.messagePattern.test(issue.message)) return false;
|
|
7068
|
+
if (entry.objectPattern) {
|
|
7069
|
+
if (entry.objectPattern.test(issue.message)) return true;
|
|
7070
|
+
if (!hasExplicitLineScope(entry)) return false;
|
|
7071
|
+
}
|
|
7047
7072
|
if (!hasExplicitLineScope(entry)) return false;
|
|
7048
7073
|
return entryLineScopeMatches(issue.line, entry);
|
|
7049
7074
|
});
|
|
@@ -11996,7 +12021,9 @@ var IDEMPOTENT_DOWNGRADE_REASON_CODES = /* @__PURE__ */ new Set([
|
|
|
11996
12021
|
"MEDIUM_RISK_DROP_SEQUENCE",
|
|
11997
12022
|
"MEDIUM_RISK_DROP_INDEX",
|
|
11998
12023
|
"MEDIUM_RISK_REVOKE",
|
|
11999
|
-
"PLPGSQL_DO_BLOCK_DETECTED"
|
|
12024
|
+
"PLPGSQL_DO_BLOCK_DETECTED",
|
|
12025
|
+
"PLPGSQL_EXECUTE_BOUNDED_DISPATCH",
|
|
12026
|
+
"GUARDED_DDL_ADD_CONSTRAINT"
|
|
12000
12027
|
]);
|
|
12001
12028
|
var IDEMPOTENT_MEDIUM_REASON_CODES = /* @__PURE__ */ new Set([
|
|
12002
12029
|
"PLPGSQL_EXECUTE_UNRESOLVED",
|
|
@@ -12017,7 +12044,7 @@ init_esm_shims();
|
|
|
12017
12044
|
var riskDetectorLoader = null;
|
|
12018
12045
|
function loadRiskDetectorModule() {
|
|
12019
12046
|
if (!riskDetectorLoader) {
|
|
12020
|
-
riskDetectorLoader = import('./risk-detector-
|
|
12047
|
+
riskDetectorLoader = import('./risk-detector-S7XQF4I2.js').then((module) => ({
|
|
12021
12048
|
detectSchemaRisks: module.detectSchemaRisks
|
|
12022
12049
|
})).catch((error) => {
|
|
12023
12050
|
riskDetectorLoader = null;
|
|
@@ -12130,6 +12157,7 @@ function formatCollectedIdempotentRisks(collected, allowlist) {
|
|
|
12130
12157
|
}
|
|
12131
12158
|
const high = collected.filter((r) => r.level === "high");
|
|
12132
12159
|
const medium = collected.filter((r) => r.level === "medium");
|
|
12160
|
+
const low = collected.filter((r) => r.level === "low");
|
|
12133
12161
|
const blockers = [];
|
|
12134
12162
|
const warnings = [];
|
|
12135
12163
|
for (const risk of high) {
|
|
@@ -12138,6 +12166,9 @@ function formatCollectedIdempotentRisks(collected, allowlist) {
|
|
|
12138
12166
|
for (const risk of medium) {
|
|
12139
12167
|
warnings.push(` [MEDIUM] ${formatDeclarativeRiskMessage(risk)}`);
|
|
12140
12168
|
}
|
|
12169
|
+
for (const risk of low) {
|
|
12170
|
+
warnings.push(` [LOW] ${formatDeclarativeRiskMessage(risk)}`);
|
|
12171
|
+
}
|
|
12141
12172
|
return {
|
|
12142
12173
|
blockers: dedupeAndSort(blockers),
|
|
12143
12174
|
warnings: dedupeAndSort(warnings),
|
|
@@ -12198,6 +12229,45 @@ async function processDeclarativeRiskFile(params) {
|
|
|
12198
12229
|
});
|
|
12199
12230
|
return { kind: "ok", detector: detectorResult.detector };
|
|
12200
12231
|
}
|
|
12232
|
+
var CREATE_POLICY_NAME_PATTERN = /\bCREATE\s+(?:OR\s+REPLACE\s+)?POLICY\s+(?:"([^"]+)"|([A-Za-z_]\w*))/gi;
|
|
12233
|
+
var DROP_POLICY_NAME_LINE_PATTERN = /\bDROP\s+POLICY\s+IF\s+EXISTS\s+(?:"([^"]+)"|([A-Za-z_]\w*))/i;
|
|
12234
|
+
function extractCreatePolicyNames(content) {
|
|
12235
|
+
const names = /* @__PURE__ */ new Set();
|
|
12236
|
+
CREATE_POLICY_NAME_PATTERN.lastIndex = 0;
|
|
12237
|
+
let match = CREATE_POLICY_NAME_PATTERN.exec(content);
|
|
12238
|
+
while (match !== null) {
|
|
12239
|
+
const name = (match[1] ?? match[2] ?? "").toLowerCase();
|
|
12240
|
+
if (name) names.add(name);
|
|
12241
|
+
match = CREATE_POLICY_NAME_PATTERN.exec(content);
|
|
12242
|
+
}
|
|
12243
|
+
CREATE_POLICY_NAME_PATTERN.lastIndex = 0;
|
|
12244
|
+
return names;
|
|
12245
|
+
}
|
|
12246
|
+
function detectRecreatePairs(risks, absoluteFilePath) {
|
|
12247
|
+
const dropPolicyRisks = risks.filter((r) => r.reasonCode === "HIGH_RISK_DROP_POLICY");
|
|
12248
|
+
if (dropPolicyRisks.length === 0) return;
|
|
12249
|
+
let content;
|
|
12250
|
+
try {
|
|
12251
|
+
content = readFileSync(absoluteFilePath, "utf-8");
|
|
12252
|
+
} catch {
|
|
12253
|
+
return;
|
|
12254
|
+
}
|
|
12255
|
+
const createPolicyNames = extractCreatePolicyNames(content);
|
|
12256
|
+
if (createPolicyNames.size === 0) return;
|
|
12257
|
+
const lines = content.split("\n");
|
|
12258
|
+
for (const risk of dropPolicyRisks) {
|
|
12259
|
+
if (risk.line === void 0) continue;
|
|
12260
|
+
const startIdx = Math.max(0, risk.line - 2);
|
|
12261
|
+
const endIdx = Math.min(lines.length, risk.line + 1);
|
|
12262
|
+
const windowText = lines.slice(startIdx, endIdx).join(" ");
|
|
12263
|
+
const nameMatch = DROP_POLICY_NAME_LINE_PATTERN.exec(windowText);
|
|
12264
|
+
if (!nameMatch) continue;
|
|
12265
|
+
const dropName = (nameMatch[1] ?? nameMatch[2] ?? "").toLowerCase();
|
|
12266
|
+
if (dropName && createPolicyNames.has(dropName)) {
|
|
12267
|
+
risk.level = "low";
|
|
12268
|
+
}
|
|
12269
|
+
}
|
|
12270
|
+
}
|
|
12201
12271
|
async function collectDeclarativeRiskReport() {
|
|
12202
12272
|
const declarativeDir = path15.join(process.cwd(), "supabase", "schemas", "declarative");
|
|
12203
12273
|
if (!existsSync(declarativeDir)) {
|
|
@@ -12266,9 +12336,13 @@ async function collectIdempotentRiskReport() {
|
|
|
12266
12336
|
const risks = await detectSchemaRisks2(file);
|
|
12267
12337
|
if (risks.length === 0) continue;
|
|
12268
12338
|
const relPath = path15.relative(process.cwd(), file);
|
|
12269
|
-
|
|
12270
|
-
|
|
12271
|
-
|
|
12339
|
+
const fileRisks = risks.map((risk) => ({
|
|
12340
|
+
...risk,
|
|
12341
|
+
level: correctIdempotentRiskLevel(risk.level, risk.reasonCode),
|
|
12342
|
+
file: relPath
|
|
12343
|
+
}));
|
|
12344
|
+
detectRecreatePairs(fileRisks, file);
|
|
12345
|
+
for (const scopedRisk of fileRisks) {
|
|
12272
12346
|
const matched = findDeclarativeRiskAllowlistMatch(scopedRisk, policy);
|
|
12273
12347
|
if (matched) {
|
|
12274
12348
|
if (SHOW_ALLOWLIST_REPORT2) {
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
3
|
import { getRequestedCommandNameFromArgv } from './chunk-UWWSAPDR.js';
|
|
4
|
-
import { CLI_VERSION } from './chunk-
|
|
4
|
+
import { CLI_VERSION } from './chunk-AO554K3G.js';
|
|
5
5
|
import { init_esm_shims } from './chunk-VRXHCR5K.js';
|
|
6
6
|
import { realpathSync } from 'fs';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
@@ -36,7 +36,7 @@ async function getProgram(options) {
|
|
|
36
36
|
};
|
|
37
37
|
const nextKey = getProgramCacheKey(resolvedOptions);
|
|
38
38
|
if (!programInstance || programCacheKey !== nextKey) {
|
|
39
|
-
const { createProgram } = await import('./cli-
|
|
39
|
+
const { createProgram } = await import('./cli-SVXOSMW6.js');
|
|
40
40
|
programInstance = await createProgram(resolvedOptions);
|
|
41
41
|
programCacheKey = nextKey;
|
|
42
42
|
}
|
|
@@ -60,7 +60,7 @@ async function runCliFromProcessArgv() {
|
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
62
62
|
const { setupSignalHandlers } = await import('./signal-handler-DO3OANW5.js');
|
|
63
|
-
const { executeProgram } = await import('./cli-
|
|
63
|
+
const { executeProgram } = await import('./cli-SVXOSMW6.js');
|
|
64
64
|
setupSignalHandlers();
|
|
65
65
|
const options = getProgramLoadOptions(argv);
|
|
66
66
|
const program = await getProgram(options);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
3
|
import { diagnoseInitFailure } from './chunk-AAIE4F2U.js';
|
|
4
4
|
import { getVercelRootDirectory } from './chunk-MXRWBNIY.js';
|
|
5
|
-
import { fetchTemplates } from './chunk-
|
|
5
|
+
import { fetchTemplates } from './chunk-3JO6YP3T.js';
|
|
6
6
|
import { syncRunaConfigWithVercel } from './chunk-6AALH2ED.js';
|
|
7
7
|
import './chunk-DRSUEMAK.js';
|
|
8
8
|
import './chunk-RZLYEO4U.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
|
-
export { categorizeRisks, detectSchemaRisks } from './chunk-
|
|
3
|
+
export { categorizeRisks, detectSchemaRisks } from './chunk-PAWNJA3N.js';
|
|
4
4
|
import './chunk-VRXHCR5K.js';
|
|
5
5
|
|
|
6
6
|
createRequire(import.meta.url);
|
|
@@ -54,7 +54,7 @@ var UNQUALIFIED_EXTENSION_REFERENCE_PATTERNS = [
|
|
|
54
54
|
var plpgsqlModulePromise = null;
|
|
55
55
|
async function loadPlpgsqlRiskDetectorModule() {
|
|
56
56
|
if (!plpgsqlModulePromise) {
|
|
57
|
-
plpgsqlModulePromise = import('./risk-detector-plpgsql-
|
|
57
|
+
plpgsqlModulePromise = import('./risk-detector-plpgsql-O32TUR34.js').catch((error) => {
|
|
58
58
|
plpgsqlModulePromise = null;
|
|
59
59
|
throw error;
|
|
60
60
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
|
-
import { splitPlpgsqlStatementsWithOffsets, extractExecuteExpressions, skipWhitespace,
|
|
3
|
+
import { splitPlpgsqlStatementsWithOffsets, parseTopLevelAssignment, extractExecuteExpressions, skipWhitespace, extractStaticSqlFromExpression, mergeStringEnvValue, skipIdentifier } from './chunk-Y5ANTCKE.js';
|
|
4
4
|
import { stripSqlCommentsPreserveLines, buildLineStarts, lineNumberFromIndex, stripSqlStringsPreserveLines, detectRisksFromContent, stripSqlForPatternMatching } from './chunk-3FDQW524.js';
|
|
5
5
|
import { init_esm_shims } from './chunk-VRXHCR5K.js';
|
|
6
6
|
|
|
@@ -537,13 +537,74 @@ function maybeBuildUsingClauseRisk(execute, executeLine) {
|
|
|
537
537
|
}
|
|
538
538
|
};
|
|
539
539
|
}
|
|
540
|
+
var GUARD_START_PATTERN = /\bIF\s+NOT\s+EXISTS\s*\(/i;
|
|
541
|
+
var PG_CONSTRAINT_PATTERN = /\bpg_constraint\b/i;
|
|
542
|
+
var ADD_CONSTRAINT_PATTERN = /\bADD\s+CONSTRAINT\b/i;
|
|
543
|
+
var END_IF_PATTERN = /\bEND\s+IF\b/i;
|
|
544
|
+
var THEN_PATTERN = /\bTHEN\b/i;
|
|
545
|
+
function detectGuardedDdlLines(body) {
|
|
546
|
+
const guardedLines = /* @__PURE__ */ new Set();
|
|
547
|
+
const lines = body.split("\n");
|
|
548
|
+
const guardedRanges = [];
|
|
549
|
+
for (let i = 0; i < lines.length; i++) {
|
|
550
|
+
if (!GUARD_START_PATTERN.test(lines[i])) continue;
|
|
551
|
+
let foundPgConstraint = false;
|
|
552
|
+
let thenLine = -1;
|
|
553
|
+
const scanEnd = Math.min(i + 20, lines.length);
|
|
554
|
+
for (let j = i; j < scanEnd; j++) {
|
|
555
|
+
if (PG_CONSTRAINT_PATTERN.test(lines[j])) foundPgConstraint = true;
|
|
556
|
+
if (THEN_PATTERN.test(lines[j])) {
|
|
557
|
+
thenLine = j;
|
|
558
|
+
break;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
if (!foundPgConstraint || thenLine < 0) continue;
|
|
562
|
+
const endScan = Math.min(thenLine + 30, lines.length);
|
|
563
|
+
for (let j = thenLine + 1; j < endScan; j++) {
|
|
564
|
+
if (END_IF_PATTERN.test(lines[j])) {
|
|
565
|
+
guardedRanges.push({ thenLine: thenLine + 1, endIfLine: j + 1 });
|
|
566
|
+
break;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
for (let i = 0; i < lines.length; i++) {
|
|
571
|
+
if (!ADD_CONSTRAINT_PATTERN.test(lines[i])) continue;
|
|
572
|
+
const line1 = i + 1;
|
|
573
|
+
for (const range of guardedRanges) {
|
|
574
|
+
if (line1 >= range.thenLine && line1 <= range.endIfLine) {
|
|
575
|
+
guardedLines.add(line1);
|
|
576
|
+
break;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return guardedLines;
|
|
581
|
+
}
|
|
540
582
|
function pushBodyStaticRisks(risks, dedupe, body, bodyStartLine) {
|
|
541
583
|
const searchableBody = stripSqlStringsPreserveLines(body);
|
|
542
584
|
if (!searchableBody.trim()) return;
|
|
543
585
|
const bodyLineStarts = buildLineStarts(body);
|
|
544
586
|
const bodyRisks = detectRisksFromContent(searchableBody, body, bodyLineStarts);
|
|
587
|
+
const guardedDdlLines = detectGuardedDdlLines(body);
|
|
545
588
|
for (const risk of bodyRisks) {
|
|
546
|
-
const
|
|
589
|
+
const bodyRelativeLine = risk.line ?? 1;
|
|
590
|
+
const line = bodyStartLine + (bodyRelativeLine - 1);
|
|
591
|
+
if (risk.reasonCode === "MEDIUM_RISK_ADD_UNIQUE" && guardedDdlLines.has(bodyRelativeLine)) {
|
|
592
|
+
const dedupeKey2 = `body:GUARDED_DDL_ADD_CONSTRAINT:${line}`;
|
|
593
|
+
if (dedupe.has(dedupeKey2)) continue;
|
|
594
|
+
dedupe.add(dedupeKey2);
|
|
595
|
+
risks.push({
|
|
596
|
+
...risk,
|
|
597
|
+
level: "medium",
|
|
598
|
+
line,
|
|
599
|
+
reasonCode: "GUARDED_DDL_ADD_CONSTRAINT",
|
|
600
|
+
evidence: {
|
|
601
|
+
source: "plpgsql body",
|
|
602
|
+
snippet: body.trim().slice(0, 200),
|
|
603
|
+
detail: "ADD CONSTRAINT is guarded by IF NOT EXISTS (pg_constraint check)"
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
continue;
|
|
607
|
+
}
|
|
547
608
|
const dedupeKey = `body:${risk.reasonCode ?? risk.description}:${line}`;
|
|
548
609
|
if (dedupe.has(dedupeKey)) continue;
|
|
549
610
|
dedupe.add(dedupeKey);
|
|
@@ -574,14 +635,40 @@ function buildUnresolvedExecuteRisk(execute, executeLine, reason) {
|
|
|
574
635
|
}
|
|
575
636
|
};
|
|
576
637
|
}
|
|
577
|
-
function
|
|
638
|
+
function executeReferencesBoundedVars(expression, conditionallyRemoved) {
|
|
639
|
+
if (conditionallyRemoved.size === 0) return false;
|
|
640
|
+
const normalized = expression.toLowerCase();
|
|
641
|
+
for (const varName of conditionallyRemoved) {
|
|
642
|
+
if (normalized.includes(varName.toLowerCase())) return true;
|
|
643
|
+
}
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
646
|
+
function buildBoundedDispatchRisk(execute, executeLine, reason) {
|
|
647
|
+
return {
|
|
648
|
+
level: "medium",
|
|
649
|
+
description: `Bounded dynamic SQL dispatch in PL/pgSQL EXECUTE: ${reason}`,
|
|
650
|
+
mitigation: "SQL is constructed from a finite set of branches (IF/CASE). Review each branch for correctness.",
|
|
651
|
+
line: executeLine,
|
|
652
|
+
reasonCode: "PLPGSQL_EXECUTE_BOUNDED_DISPATCH",
|
|
653
|
+
confidence: "medium",
|
|
654
|
+
evidence: {
|
|
655
|
+
source: "extractStaticSqlFromExpression",
|
|
656
|
+
snippet: execute.expression.slice(0, 200),
|
|
657
|
+
detail: "EXECUTE expression uses variables assigned in conditional branches (bounded dispatch)"
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
function analyzeExecuteStatement(risks, dedupe, content, lineStarts, range, statement, execute, stringEnv, conditionallyRemoved = /* @__PURE__ */ new Set()) {
|
|
578
662
|
const executeLine = buildExecuteLine(content, lineStarts, range, statement, execute);
|
|
579
663
|
const executeKey = buildExecuteKey(range, statement, execute, executeLine);
|
|
580
664
|
if (dedupe.has(executeKey)) return;
|
|
581
665
|
dedupe.add(executeKey);
|
|
582
666
|
const extracted = extractStaticSqlFromExpression(execute.expression, stringEnv);
|
|
583
667
|
if (extracted.kind !== "static") {
|
|
584
|
-
|
|
668
|
+
const isBoundedDispatch = !execute.hasUsingClause && !execute.hasIntoClause && executeReferencesBoundedVars(execute.expression, conditionallyRemoved);
|
|
669
|
+
risks.push(
|
|
670
|
+
isBoundedDispatch ? buildBoundedDispatchRisk(execute, executeLine, extracted.reason) : buildUnresolvedExecuteRisk(execute, executeLine, extracted.reason)
|
|
671
|
+
);
|
|
585
672
|
return;
|
|
586
673
|
}
|
|
587
674
|
risks.push(buildStaticExecuteRisk(execute, executeLine));
|
|
@@ -605,8 +692,18 @@ function analyzeBodyRange(risks, dedupe, content, commentlessContent, lineStarts
|
|
|
605
692
|
}
|
|
606
693
|
pushBodyStaticRisks(risks, dedupe, body, declarationLine);
|
|
607
694
|
const stringEnv = /* @__PURE__ */ new Map();
|
|
695
|
+
const conditionallyRemoved = /* @__PURE__ */ new Set();
|
|
608
696
|
for (const statement of splitPlpgsqlStatementsWithOffsets(body)) {
|
|
697
|
+
const beforeKeys = new Set(stringEnv.keys());
|
|
609
698
|
applyStatementAssignment(statement, stringEnv);
|
|
699
|
+
const assignment = parseTopLevelAssignment(statement.statement);
|
|
700
|
+
if (assignment?.isConditionalContext) {
|
|
701
|
+
for (const key of beforeKeys) {
|
|
702
|
+
if (!stringEnv.has(key)) {
|
|
703
|
+
conditionallyRemoved.add(key);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
610
707
|
const executeStatements = extractExecuteExpressions(statement.statement);
|
|
611
708
|
for (const execute of executeStatements) {
|
|
612
709
|
analyzeExecuteStatement(
|
|
@@ -617,7 +714,8 @@ function analyzeBodyRange(risks, dedupe, content, commentlessContent, lineStarts
|
|
|
617
714
|
range,
|
|
618
715
|
statement,
|
|
619
716
|
execute,
|
|
620
|
-
stringEnv
|
|
717
|
+
stringEnv,
|
|
718
|
+
conditionallyRemoved
|
|
621
719
|
);
|
|
622
720
|
}
|
|
623
721
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
|
-
import { fetchTemplates } from './chunk-
|
|
3
|
+
import { fetchTemplates } from './chunk-3JO6YP3T.js';
|
|
4
4
|
import { updateRunaConfigSdkVersion } from './chunk-6AALH2ED.js';
|
|
5
5
|
import './chunk-DRSUEMAK.js';
|
|
6
6
|
import './chunk-RZLYEO4U.js';
|
|
@@ -71,7 +71,7 @@ var vulnCheckCommand = new Command("vuln-check").description("Run comprehensive
|
|
|
71
71
|
const logger = createCLILogger("vuln-check");
|
|
72
72
|
const isJsonMode = getOutputFormatFromEnv() === "json" || options.format === "json";
|
|
73
73
|
try {
|
|
74
|
-
const { VulnChecker } = await import('./vuln-checker-
|
|
74
|
+
const { VulnChecker } = await import('./vuln-checker-QV6XODTJ.js');
|
|
75
75
|
const categoryMap = {
|
|
76
76
|
code: ["injection", "auth", "crypto"],
|
|
77
77
|
deps: ["dependency"],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
|
-
import { CLI_VERSION } from './chunk-
|
|
3
|
+
import { CLI_VERSION } from './chunk-AO554K3G.js';
|
|
4
4
|
import { init_esm_shims } from './chunk-VRXHCR5K.js';
|
|
5
5
|
import { glob } from 'glob';
|
|
6
6
|
import { exec } from 'child_process';
|
|
@@ -284,7 +284,7 @@ function validateSqlSchema(content, errors, warnings) {
|
|
|
284
284
|
var riskDetectorLoader = null;
|
|
285
285
|
function loadRiskDetectorModule() {
|
|
286
286
|
if (!riskDetectorLoader) {
|
|
287
|
-
riskDetectorLoader = import('./risk-detector-
|
|
287
|
+
riskDetectorLoader = import('./risk-detector-S7XQF4I2.js').then((module) => ({
|
|
288
288
|
detectSchemaRisks: module.detectSchemaRisks
|
|
289
289
|
})).catch((error) => {
|
|
290
290
|
riskDetectorLoader = null;
|