@biffo/cli 0.283.1 → 0.283.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/index.js +160 -66
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3007,8 +3007,16 @@ var GLOBAL_DISPATCH_WORKFLOW_PATHS = [
|
|
|
3007
3007
|
];
|
|
3008
3008
|
|
|
3009
3009
|
// src/lib/plugin-terraform-wiring.ts
|
|
3010
|
-
import {
|
|
3011
|
-
|
|
3010
|
+
import {
|
|
3011
|
+
existsSync as existsSync11,
|
|
3012
|
+
mkdirSync as mkdirSync3,
|
|
3013
|
+
readFileSync as readFileSync9,
|
|
3014
|
+
readdirSync as readdirSync3,
|
|
3015
|
+
rmSync as rmSync4,
|
|
3016
|
+
statSync as statSync2,
|
|
3017
|
+
writeFileSync as writeFileSync4
|
|
3018
|
+
} from "fs";
|
|
3019
|
+
import { join as join12, relative as relative2, sep as sep2 } from "path";
|
|
3012
3020
|
var TEMPLATE_MODULE_DIR = "_template";
|
|
3013
3021
|
var DEFAULT_PLUGIN_HANDLER = "src.lambda.main.handler";
|
|
3014
3022
|
var GENERATED_TF_FILE = "plugins.generated.tf";
|
|
@@ -3096,6 +3104,62 @@ function staleFirstPartyCopies(cwd) {
|
|
|
3096
3104
|
const copied = new Set(listPluginModules(cwd));
|
|
3097
3105
|
return firstPartyPluginNames(cwd).filter((name) => copied.has(name));
|
|
3098
3106
|
}
|
|
3107
|
+
function walkTfFiles(root) {
|
|
3108
|
+
const out = [];
|
|
3109
|
+
const walk2 = (dir) => {
|
|
3110
|
+
let entries;
|
|
3111
|
+
try {
|
|
3112
|
+
entries = readdirSync3(dir);
|
|
3113
|
+
} catch {
|
|
3114
|
+
return;
|
|
3115
|
+
}
|
|
3116
|
+
for (const entry of entries) {
|
|
3117
|
+
const p = join12(dir, entry);
|
|
3118
|
+
let st;
|
|
3119
|
+
try {
|
|
3120
|
+
st = statSync2(p);
|
|
3121
|
+
} catch {
|
|
3122
|
+
continue;
|
|
3123
|
+
}
|
|
3124
|
+
if (st.isDirectory()) {
|
|
3125
|
+
walk2(p);
|
|
3126
|
+
continue;
|
|
3127
|
+
}
|
|
3128
|
+
if (entry.endsWith(".tf")) out.push(p);
|
|
3129
|
+
}
|
|
3130
|
+
};
|
|
3131
|
+
walk2(root);
|
|
3132
|
+
return out.sort();
|
|
3133
|
+
}
|
|
3134
|
+
function escapeRegExp(value) {
|
|
3135
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3136
|
+
}
|
|
3137
|
+
function findPluginModuleReferences(cwd, name) {
|
|
3138
|
+
const infraDir = join12(cwd, "infra");
|
|
3139
|
+
const sourceSegments = ["modules", "plugins", name];
|
|
3140
|
+
const sourceLinePattern = /^\s*source\s*=\s*"([^"]+)"/;
|
|
3141
|
+
const moduleRefPattern = new RegExp(`module\\.plugin_${escapeRegExp(name)}(?![A-Za-z0-9_-])`);
|
|
3142
|
+
const refs = [];
|
|
3143
|
+
for (const absPath of walkTfFiles(infraDir)) {
|
|
3144
|
+
let contents;
|
|
3145
|
+
try {
|
|
3146
|
+
contents = readFileSync9(absPath, "utf8");
|
|
3147
|
+
} catch {
|
|
3148
|
+
continue;
|
|
3149
|
+
}
|
|
3150
|
+
const relPath = relative2(cwd, absPath).split(sep2).join("/");
|
|
3151
|
+
contents.split("\n").forEach((rawLine, idx) => {
|
|
3152
|
+
const sourceValue = sourceLinePattern.exec(rawLine)?.[1];
|
|
3153
|
+
const sourceValueSegments = sourceValue?.split("/").filter((s) => s.length > 0 && s !== ".");
|
|
3154
|
+
const isSourceRef = sourceValueSegments !== void 0 && sourceValueSegments.slice(-sourceSegments.length).join("/") === sourceSegments.join("/");
|
|
3155
|
+
const isExprRef = moduleRefPattern.test(rawLine);
|
|
3156
|
+
if (isSourceRef || isExprRef) {
|
|
3157
|
+
refs.push({ file: relPath, line: idx + 1, text: rawLine.trim() });
|
|
3158
|
+
}
|
|
3159
|
+
});
|
|
3160
|
+
}
|
|
3161
|
+
return refs;
|
|
3162
|
+
}
|
|
3099
3163
|
function listEnvironments(cwd) {
|
|
3100
3164
|
const dir = join12(cwd, "infra", "environments");
|
|
3101
3165
|
let entries;
|
|
@@ -4643,7 +4707,7 @@ import {
|
|
|
4643
4707
|
readdirSync as readdirSync4,
|
|
4644
4708
|
readFileSync as readFileSync10,
|
|
4645
4709
|
rmSync as rmSync6,
|
|
4646
|
-
statSync as
|
|
4710
|
+
statSync as statSync3,
|
|
4647
4711
|
writeFileSync as writeFileSync5
|
|
4648
4712
|
} from "fs";
|
|
4649
4713
|
import { homedir } from "os";
|
|
@@ -4677,7 +4741,7 @@ function findLatestSession() {
|
|
|
4677
4741
|
if (files.length === 0) return null;
|
|
4678
4742
|
const sorted = files.map((f) => {
|
|
4679
4743
|
const fullPath = join16(dir, f);
|
|
4680
|
-
const mtime = existsSync15(fullPath) ?
|
|
4744
|
+
const mtime = existsSync15(fullPath) ? statSync3(fullPath).mtimeMs : -1;
|
|
4681
4745
|
return { f, mtime };
|
|
4682
4746
|
}).sort((a, b) => b.mtime - a.mtime);
|
|
4683
4747
|
try {
|
|
@@ -4875,7 +4939,7 @@ async function resolveConfig(options) {
|
|
|
4875
4939
|
|
|
4876
4940
|
// src/commands/data-import.ts
|
|
4877
4941
|
import { execSync as execSync3 } from "child_process";
|
|
4878
|
-
import { cpSync, existsSync as existsSync17, mkdirSync as mkdirSync5, readdirSync as readdirSync5, statSync as
|
|
4942
|
+
import { cpSync, existsSync as existsSync17, mkdirSync as mkdirSync5, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
|
|
4879
4943
|
import { join as join17, resolve as resolve5 } from "path";
|
|
4880
4944
|
import chalk6 from "chalk";
|
|
4881
4945
|
import { Command as Command6 } from "commander";
|
|
@@ -4928,7 +4992,7 @@ async function runDataImport(name, options, deps) {
|
|
|
4928
4992
|
`DDL import '${name}' is already present at db/imports/${name}/. Remove it first to re-import.`
|
|
4929
4993
|
);
|
|
4930
4994
|
}
|
|
4931
|
-
const isLocalDir = existsSync17(options.source) &&
|
|
4995
|
+
const isLocalDir = existsSync17(options.source) && statSync4(options.source).isDirectory();
|
|
4932
4996
|
let sourceDir;
|
|
4933
4997
|
let cleanupClone = null;
|
|
4934
4998
|
if (isLocalDir) {
|
|
@@ -6013,8 +6077,8 @@ import { Command as Command12 } from "commander";
|
|
|
6013
6077
|
import inquirer5 from "inquirer";
|
|
6014
6078
|
|
|
6015
6079
|
// src/lib/build-freshness.ts
|
|
6016
|
-
import { existsSync as existsSync20, readdirSync as readdirSync7, statSync as
|
|
6017
|
-
import { dirname as dirname5, join as join19, relative as
|
|
6080
|
+
import { existsSync as existsSync20, readdirSync as readdirSync7, statSync as statSync5 } from "fs";
|
|
6081
|
+
import { dirname as dirname5, join as join19, relative as relative3, sep as sep3 } from "path";
|
|
6018
6082
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
6019
6083
|
var SKIP_ENV_VAR = "BIFFO_SKIP_BUILD_FRESHNESS_CHECK";
|
|
6020
6084
|
function checkBuildFreshness(options = {}) {
|
|
@@ -6048,8 +6112,8 @@ function checkBuildFreshness(options = {}) {
|
|
|
6048
6112
|
if (!existsSync20(entry)) {
|
|
6049
6113
|
return { status: "skipped", reason: `${entry} not found`, newerSources: [] };
|
|
6050
6114
|
}
|
|
6051
|
-
const builtAt =
|
|
6052
|
-
const newer = collectSourceFiles(srcDir).map((file) => ({ file, mtimeMs:
|
|
6115
|
+
const builtAt = statSync5(entry).mtimeMs;
|
|
6116
|
+
const newer = collectSourceFiles(srcDir).map((file) => ({ file, mtimeMs: statSync5(file).mtimeMs })).filter((f) => f.mtimeMs > builtAt).sort((a, b) => b.mtimeMs - a.mtimeMs).map((f) => relative3(packageRoot, f.file));
|
|
6053
6117
|
if (newer.length === 0) {
|
|
6054
6118
|
return { status: "fresh", reason: "dist is newer than src", newerSources: [] };
|
|
6055
6119
|
}
|
|
@@ -6116,8 +6180,8 @@ function findPackageRoot(from) {
|
|
|
6116
6180
|
}
|
|
6117
6181
|
function isInside(parent, child) {
|
|
6118
6182
|
if (child === parent) return true;
|
|
6119
|
-
const rel =
|
|
6120
|
-
return rel !== "" && !rel.startsWith("..") && !rel.startsWith(`..${
|
|
6183
|
+
const rel = relative3(parent, child);
|
|
6184
|
+
return rel !== "" && !rel.startsWith("..") && !rel.startsWith(`..${sep3}`);
|
|
6121
6185
|
}
|
|
6122
6186
|
|
|
6123
6187
|
// src/lib/credentials.ts
|
|
@@ -6402,7 +6466,7 @@ import {
|
|
|
6402
6466
|
readdirSync as readdirSync8,
|
|
6403
6467
|
readFileSync as readFileSync15,
|
|
6404
6468
|
rmSync as rmSync7,
|
|
6405
|
-
statSync as
|
|
6469
|
+
statSync as statSync6,
|
|
6406
6470
|
writeFileSync as writeFileSync6
|
|
6407
6471
|
} from "fs";
|
|
6408
6472
|
import { homedir as homedir3 } from "os";
|
|
@@ -8479,8 +8543,8 @@ function printEntry(entry) {
|
|
|
8479
8543
|
}
|
|
8480
8544
|
|
|
8481
8545
|
// src/commands/plugin-install.ts
|
|
8482
|
-
import { cpSync as cpSync5, existsSync as existsSync30, mkdirSync as mkdirSync11, readFileSync as readFileSync22, statSync as
|
|
8483
|
-
import { join as join32, relative as
|
|
8546
|
+
import { cpSync as cpSync5, existsSync as existsSync30, mkdirSync as mkdirSync11, readFileSync as readFileSync22, statSync as statSync7 } from "fs";
|
|
8547
|
+
import { join as join32, relative as relative4, resolve as resolve12 } from "path";
|
|
8484
8548
|
import chalk15 from "chalk";
|
|
8485
8549
|
import { Command as Command15 } from "commander";
|
|
8486
8550
|
|
|
@@ -8794,8 +8858,8 @@ function ensureWorkspaceSources(pluginPyprojectPath, memberNames) {
|
|
|
8794
8858
|
updated = `${text.slice(0, insertAt)}
|
|
8795
8859
|
${lines.join("\n")}${text.slice(insertAt)}`;
|
|
8796
8860
|
} else {
|
|
8797
|
-
const
|
|
8798
|
-
updated = `${text}${
|
|
8861
|
+
const sep5 = text.endsWith("\n") ? "" : "\n";
|
|
8862
|
+
updated = `${text}${sep5}
|
|
8799
8863
|
# Vendored into this instance by \`biffo plugin install\`: resolve dependencies the
|
|
8800
8864
|
# instance's uv workspace provides as members from the workspace, not PyPI.
|
|
8801
8865
|
[tool.uv.sources]
|
|
@@ -8850,7 +8914,7 @@ function resolveLocalPlugin(localPath) {
|
|
|
8850
8914
|
if (!existsSync30(localPath)) {
|
|
8851
8915
|
throw new Error(`--local path does not exist: ${localPath}`);
|
|
8852
8916
|
}
|
|
8853
|
-
if (!
|
|
8917
|
+
if (!statSync7(localPath).isDirectory()) {
|
|
8854
8918
|
throw new Error(`--local path is not a directory: ${localPath}`);
|
|
8855
8919
|
}
|
|
8856
8920
|
const manifestPath = join32(localPath, "biffo.plugin.json");
|
|
@@ -9009,10 +9073,10 @@ async function runPluginInstall(target, options, deps) {
|
|
|
9009
9073
|
log.info(`Generating migration for ${relTargetDir}/'s ${manifest.tables.length} table(s)...`);
|
|
9010
9074
|
const generatedPaths = await deps.migrations.generate(options.cwd, [pluginName]);
|
|
9011
9075
|
for (const absPath of generatedPaths) {
|
|
9012
|
-
stagePaths.push(
|
|
9076
|
+
stagePaths.push(relative4(options.cwd, absPath));
|
|
9013
9077
|
}
|
|
9014
9078
|
if (generatedPaths.length > 0) {
|
|
9015
|
-
log.success(`Generated migration: ${
|
|
9079
|
+
log.success(`Generated migration: ${relative4(options.cwd, generatedPaths[0])}`);
|
|
9016
9080
|
}
|
|
9017
9081
|
} else {
|
|
9018
9082
|
log.info(`${pluginName} declares no tables \u2014 nothing to migrate.`);
|
|
@@ -9143,8 +9207,8 @@ import { resolve as resolve14 } from "path";
|
|
|
9143
9207
|
import { Command as Command17 } from "commander";
|
|
9144
9208
|
|
|
9145
9209
|
// src/lib/plugin-staleness.ts
|
|
9146
|
-
import { existsSync as existsSync32, readFileSync as readFileSync24, readdirSync as readdirSync14, statSync as
|
|
9147
|
-
import { join as join34, relative as
|
|
9210
|
+
import { existsSync as existsSync32, readFileSync as readFileSync24, readdirSync as readdirSync14, statSync as statSync8 } from "fs";
|
|
9211
|
+
import { join as join34, relative as relative5 } from "path";
|
|
9148
9212
|
function discoverVendoredPlugins(servicesDir) {
|
|
9149
9213
|
if (!existsSync32(servicesDir)) return [];
|
|
9150
9214
|
return readdirSync14(servicesDir, { withFileTypes: true }).filter((e) => e.isDirectory() && !e.name.startsWith("_") && e.name !== "api").map((e) => e.name).filter((name) => existsSync32(join34(servicesDir, name, "biffo.plugin.json"))).sort();
|
|
@@ -9347,11 +9411,11 @@ function walkExcluding(root, dir, excludes) {
|
|
|
9347
9411
|
for (const entry of readdirSync14(dir)) {
|
|
9348
9412
|
if (excludes.has(entry) || entry === ".git") continue;
|
|
9349
9413
|
const full = join34(dir, entry);
|
|
9350
|
-
const stat =
|
|
9414
|
+
const stat = statSync8(full);
|
|
9351
9415
|
if (stat.isDirectory()) {
|
|
9352
9416
|
out.push(...walkExcluding(root, full, excludes));
|
|
9353
9417
|
} else {
|
|
9354
|
-
out.push(
|
|
9418
|
+
out.push(relative5(root, full));
|
|
9355
9419
|
}
|
|
9356
9420
|
}
|
|
9357
9421
|
return out;
|
|
@@ -9399,7 +9463,7 @@ var pluginStalenessCommand = new Command17("staleness").description(
|
|
|
9399
9463
|
|
|
9400
9464
|
// src/commands/plugin-sync-migrations.ts
|
|
9401
9465
|
import { existsSync as existsSync33 } from "fs";
|
|
9402
|
-
import { join as join35, relative as
|
|
9466
|
+
import { join as join35, relative as relative6, resolve as resolve15 } from "path";
|
|
9403
9467
|
import chalk17 from "chalk";
|
|
9404
9468
|
import { Command as Command18 } from "commander";
|
|
9405
9469
|
var pluginSyncMigrationsCommand = new Command18("sync-migrations").description(
|
|
@@ -9440,7 +9504,7 @@ async function runPluginSyncMigrations(name, options, deps) {
|
|
|
9440
9504
|
);
|
|
9441
9505
|
return;
|
|
9442
9506
|
}
|
|
9443
|
-
const relativePaths = generated.map((p) =>
|
|
9507
|
+
const relativePaths = generated.map((p) => relative6(options.cwd, p));
|
|
9444
9508
|
for (const p of relativePaths) {
|
|
9445
9509
|
log.success(`Generated ${p}`);
|
|
9446
9510
|
}
|
|
@@ -9532,6 +9596,19 @@ async function runPluginUninstall(name, options, deps) {
|
|
|
9532
9596
|
`${options.cwd} is not a git repository \u2014 biffo plugin uninstall must be run from a Biffo project checkout.`
|
|
9533
9597
|
);
|
|
9534
9598
|
}
|
|
9599
|
+
if (existsSync34(modulesDir)) {
|
|
9600
|
+
const refs = findPluginModuleReferences(options.cwd, name).filter(
|
|
9601
|
+
(r) => !r.file.endsWith(`/${GENERATED_TF_FILE}`) && r.file !== GENERATED_TF_FILE
|
|
9602
|
+
);
|
|
9603
|
+
if (refs.length > 0) {
|
|
9604
|
+
const refList = refs.map((r) => ` ${r.file}:${r.line} ${r.text}`).join("\n");
|
|
9605
|
+
throw new Error(
|
|
9606
|
+
`Refusing to uninstall '${name}' \u2014 its Terraform module is referenced outside the generated wiring, so removing it would break these hand-authored file(s):
|
|
9607
|
+
${refList}
|
|
9608
|
+
Remove the reference(s) above first, then re-run uninstall.`
|
|
9609
|
+
);
|
|
9610
|
+
}
|
|
9611
|
+
}
|
|
9535
9612
|
rmSync9(targetDir, { recursive: true, force: true });
|
|
9536
9613
|
log.success(`Removed services/${name}/`);
|
|
9537
9614
|
if (existsSync34(modulesDir)) {
|
|
@@ -9613,7 +9690,7 @@ function printDryRun5(name, version, stagePaths, keepData) {
|
|
|
9613
9690
|
|
|
9614
9691
|
// src/commands/plugin-upgrade.ts
|
|
9615
9692
|
import { cpSync as cpSync6, existsSync as existsSync35, mkdirSync as mkdirSync12, readFileSync as readFileSync26, rmSync as rmSync10 } from "fs";
|
|
9616
|
-
import { join as join37, relative as
|
|
9693
|
+
import { join as join37, relative as relative7, resolve as resolve17 } from "path";
|
|
9617
9694
|
import chalk19 from "chalk";
|
|
9618
9695
|
import { Command as Command20 } from "commander";
|
|
9619
9696
|
import inquirer7 from "inquirer";
|
|
@@ -9713,6 +9790,9 @@ async function runPluginUpgrade(target, options, deps) {
|
|
|
9713
9790
|
log.success(
|
|
9714
9791
|
`Manifest valid \u2014 ${manifest.tables.length} table(s), ${manifest.api_routes.length} route(s)`
|
|
9715
9792
|
);
|
|
9793
|
+
if (!existsSync35(join37(tmpDir, "terraform"))) {
|
|
9794
|
+
refuseIfModuleStillReferenced(options.cwd, modulesDir, entry.name);
|
|
9795
|
+
}
|
|
9716
9796
|
const previousProvenance = readProvenance(targetDir);
|
|
9717
9797
|
rmSync10(targetDir, { recursive: true, force: true });
|
|
9718
9798
|
mkdirSync12(targetDir, { recursive: true });
|
|
@@ -9741,10 +9821,10 @@ async function runPluginUpgrade(target, options, deps) {
|
|
|
9741
9821
|
);
|
|
9742
9822
|
const generatedPaths = await deps.migrations.generate(options.cwd, [entry.name]);
|
|
9743
9823
|
for (const absPath of generatedPaths) {
|
|
9744
|
-
stagePaths.push(
|
|
9824
|
+
stagePaths.push(relative7(options.cwd, absPath));
|
|
9745
9825
|
}
|
|
9746
9826
|
if (generatedPaths.length > 0) {
|
|
9747
|
-
log.success(`Generated migration: ${
|
|
9827
|
+
log.success(`Generated migration: ${relative7(options.cwd, generatedPaths[0])}`);
|
|
9748
9828
|
} else {
|
|
9749
9829
|
log.info(
|
|
9750
9830
|
`${entry.name}'s tables and columns already match the manifest \u2014 no migration needed.`
|
|
@@ -9805,6 +9885,9 @@ async function runLocalPluginRefresh(localPath, options, deps) {
|
|
|
9805
9885
|
log.success(
|
|
9806
9886
|
`Manifest valid \u2014 ${manifest.tables.length} table(s), ${manifest.api_routes.length} route(s)`
|
|
9807
9887
|
);
|
|
9888
|
+
if (!existsSync35(join37(source.sourceDir, "terraform"))) {
|
|
9889
|
+
refuseIfModuleStillReferenced(options.cwd, modulesDir, source.name);
|
|
9890
|
+
}
|
|
9808
9891
|
const previousProvenance = readProvenance(targetDir);
|
|
9809
9892
|
if (inTreeSource) {
|
|
9810
9893
|
log.info(
|
|
@@ -9836,10 +9919,10 @@ async function runLocalPluginRefresh(localPath, options, deps) {
|
|
|
9836
9919
|
);
|
|
9837
9920
|
const generatedPaths = await deps.migrations.generate(options.cwd, [source.name]);
|
|
9838
9921
|
for (const absPath of generatedPaths) {
|
|
9839
|
-
stagePaths.push(
|
|
9922
|
+
stagePaths.push(relative7(options.cwd, absPath));
|
|
9840
9923
|
}
|
|
9841
9924
|
if (generatedPaths.length > 0) {
|
|
9842
|
-
log.success(`Generated migration: ${
|
|
9925
|
+
log.success(`Generated migration: ${relative7(options.cwd, generatedPaths[0])}`);
|
|
9843
9926
|
} else {
|
|
9844
9927
|
log.info(
|
|
9845
9928
|
`${source.name}'s tables and columns already match the manifest \u2014 no migration needed.`
|
|
@@ -9870,6 +9953,17 @@ async function runLocalPluginRefresh(localPath, options, deps) {
|
|
|
9870
9953
|
source.cleanup();
|
|
9871
9954
|
}
|
|
9872
9955
|
}
|
|
9956
|
+
function refuseIfModuleStillReferenced(cwd, modulesDir, name) {
|
|
9957
|
+
if (!existsSync35(modulesDir)) return;
|
|
9958
|
+
const refs = findPluginModuleReferences(cwd, name);
|
|
9959
|
+
if (refs.length === 0) return;
|
|
9960
|
+
const refList = refs.map((r) => ` ${r.file}:${r.line} ${r.text}`).join("\n");
|
|
9961
|
+
throw new Error(
|
|
9962
|
+
`Refusing to remove modules/plugins/${name}/ \u2014 '${name}' ships no terraform/ directory in this version, but the module is still referenced:
|
|
9963
|
+
${refList}
|
|
9964
|
+
A plugin repo without terraform/ is missing the directory, not declaring that the module should go, and a wrong destructive action here is worse than no action. Either remove the reference(s) above yourself, or run 'biffo plugin uninstall ${name}', which removes the module and unwires the reference together.`
|
|
9965
|
+
);
|
|
9966
|
+
}
|
|
9873
9967
|
function readInstalledVersion2(targetDir) {
|
|
9874
9968
|
const manifestPath = join37(targetDir, "biffo.plugin.json");
|
|
9875
9969
|
if (!existsSync35(manifestPath)) return void 0;
|
|
@@ -10595,11 +10689,11 @@ async function runBranchProtectionCheck(explicitRepo, options = {}) {
|
|
|
10595
10689
|
|
|
10596
10690
|
// src/scripts/check-codeql-suppression.ts
|
|
10597
10691
|
import { existsSync as existsSync39 } from "fs";
|
|
10598
|
-
import { join as join41, relative as
|
|
10692
|
+
import { join as join41, relative as relative8 } from "path";
|
|
10599
10693
|
import { execa as execa9 } from "execa";
|
|
10600
10694
|
|
|
10601
10695
|
// src/lib/codeql-suppression-guard.ts
|
|
10602
|
-
import { readdirSync as readdirSync16, readFileSync as readFileSync29, statSync as
|
|
10696
|
+
import { readdirSync as readdirSync16, readFileSync as readFileSync29, statSync as statSync9 } from "fs";
|
|
10603
10697
|
import { join as join40 } from "path";
|
|
10604
10698
|
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
10605
10699
|
".git",
|
|
@@ -10634,7 +10728,7 @@ function walkSourceFiles(root) {
|
|
|
10634
10728
|
const p = join40(dir, entry);
|
|
10635
10729
|
let st;
|
|
10636
10730
|
try {
|
|
10637
|
-
st =
|
|
10731
|
+
st = statSync9(p);
|
|
10638
10732
|
} catch {
|
|
10639
10733
|
continue;
|
|
10640
10734
|
}
|
|
@@ -10681,7 +10775,7 @@ async function runCodeqlSuppressionCheck() {
|
|
|
10681
10775
|
"\u2717 codeql-suppression guard: found a `codeql[...]`-shaped comment, which does not suppress anything in this repo (#1491) \u2014 dismiss the real alert instead (UI, or `PATCH .../code-scanning/alerts/<n>` with a recorded reason)\n"
|
|
10682
10776
|
);
|
|
10683
10777
|
for (const hit of hits) {
|
|
10684
|
-
console.error(` ${
|
|
10778
|
+
console.error(` ${relative8(root, hit.path)}:${hit.line} ${hit.text.trim()}`);
|
|
10685
10779
|
}
|
|
10686
10780
|
process.exit(1);
|
|
10687
10781
|
}
|
|
@@ -10696,7 +10790,7 @@ async function runCodeqlSuppressionCheck() {
|
|
|
10696
10790
|
import { execa as execa10 } from "execa";
|
|
10697
10791
|
|
|
10698
10792
|
// src/lib/cognito-invite-template-guard.ts
|
|
10699
|
-
import { readdirSync as readdirSync17, readFileSync as readFileSync30, statSync as
|
|
10793
|
+
import { readdirSync as readdirSync17, readFileSync as readFileSync30, statSync as statSync10 } from "fs";
|
|
10700
10794
|
import { join as join42 } from "path";
|
|
10701
10795
|
var REQUIRED_INVITE_MEMBERS = ["email_subject", "email_message", "sms_message"];
|
|
10702
10796
|
var REQUIRED_INVITE_PLACEHOLDERS = ["{username}", "{####}"];
|
|
@@ -10771,7 +10865,7 @@ function memberBody(blockBody, member) {
|
|
|
10771
10865
|
}
|
|
10772
10866
|
function findModuleTerraformFiles(repoRoot) {
|
|
10773
10867
|
const found = [];
|
|
10774
|
-
const walk2 = (dir,
|
|
10868
|
+
const walk2 = (dir, relative11) => {
|
|
10775
10869
|
let entries;
|
|
10776
10870
|
try {
|
|
10777
10871
|
entries = readdirSync17(dir);
|
|
@@ -10781,8 +10875,8 @@ function findModuleTerraformFiles(repoRoot) {
|
|
|
10781
10875
|
for (const entry of entries) {
|
|
10782
10876
|
if (entry === "node_modules" || entry === ".git" || entry === ".worktrees") continue;
|
|
10783
10877
|
const full = join42(dir, entry);
|
|
10784
|
-
const rel = `${
|
|
10785
|
-
if (
|
|
10878
|
+
const rel = `${relative11}/${entry}`;
|
|
10879
|
+
if (statSync10(full).isDirectory()) {
|
|
10786
10880
|
walk2(full, rel);
|
|
10787
10881
|
} else if (entry.endsWith(".tf")) {
|
|
10788
10882
|
found.push(rel);
|
|
@@ -10826,7 +10920,7 @@ import { join as join44 } from "path";
|
|
|
10826
10920
|
import { execa as execa11 } from "execa";
|
|
10827
10921
|
|
|
10828
10922
|
// src/lib/core-direct-paths-audit.ts
|
|
10829
|
-
import { existsSync as existsSync40, readFileSync as readFileSync31, readdirSync as readdirSync18, statSync as
|
|
10923
|
+
import { existsSync as existsSync40, readFileSync as readFileSync31, readdirSync as readdirSync18, statSync as statSync11 } from "fs";
|
|
10830
10924
|
import { join as join43 } from "path";
|
|
10831
10925
|
var EXTERNAL_BASE_IDENTIFIERS = ["CORE_API_URL"];
|
|
10832
10926
|
var API_ROUTE_PREFIX = "/api/v1";
|
|
@@ -10994,7 +11088,7 @@ function walkFiles(root, accept, skipDir) {
|
|
|
10994
11088
|
const p = join43(dir, entry);
|
|
10995
11089
|
let st;
|
|
10996
11090
|
try {
|
|
10997
|
-
st =
|
|
11091
|
+
st = statSync11(p);
|
|
10998
11092
|
} catch {
|
|
10999
11093
|
continue;
|
|
11000
11094
|
}
|
|
@@ -11340,7 +11434,7 @@ ${BOLD}If the divergence is deliberate${OFF}
|
|
|
11340
11434
|
import { execa as execa13 } from "execa";
|
|
11341
11435
|
|
|
11342
11436
|
// src/lib/eventbridge-log-permission-guard.ts
|
|
11343
|
-
import { readFileSync as readFileSync32, readdirSync as readdirSync19, statSync as
|
|
11437
|
+
import { readFileSync as readFileSync32, readdirSync as readdirSync19, statSync as statSync12 } from "fs";
|
|
11344
11438
|
import { join as join45 } from "path";
|
|
11345
11439
|
var SKIP_DIRS2 = /* @__PURE__ */ new Set(["node_modules", ".git", ".terraform", ".worktrees", "dist"]);
|
|
11346
11440
|
var EVENT_TARGET_TYPE = "aws_cloudwatch_event_target";
|
|
@@ -11421,7 +11515,7 @@ function walkTerraformFiles(root) {
|
|
|
11421
11515
|
const p = join45(dir, entry);
|
|
11422
11516
|
let st;
|
|
11423
11517
|
try {
|
|
11424
|
-
st =
|
|
11518
|
+
st = statSync12(p);
|
|
11425
11519
|
} catch {
|
|
11426
11520
|
continue;
|
|
11427
11521
|
}
|
|
@@ -11558,7 +11652,7 @@ import { readFileSync as readFileSync34 } from "fs";
|
|
|
11558
11652
|
import { join as join47 } from "path";
|
|
11559
11653
|
|
|
11560
11654
|
// src/lib/terraform-input-guard.ts
|
|
11561
|
-
import { existsSync as existsSync41, readdirSync as readdirSync20, readFileSync as readFileSync33, statSync as
|
|
11655
|
+
import { existsSync as existsSync41, readdirSync as readdirSync20, readFileSync as readFileSync33, statSync as statSync13 } from "fs";
|
|
11562
11656
|
import { join as join46 } from "path";
|
|
11563
11657
|
var GUARDED_SUBCOMMANDS = [
|
|
11564
11658
|
"init",
|
|
@@ -11583,7 +11677,7 @@ function vendoredPluginServiceDirs(repoRoot) {
|
|
|
11583
11677
|
}
|
|
11584
11678
|
for (const entry of entries) {
|
|
11585
11679
|
const full = join46(servicesDir, entry);
|
|
11586
|
-
if (!existsSync41(full) || !
|
|
11680
|
+
if (!existsSync41(full) || !statSync13(full).isDirectory()) continue;
|
|
11587
11681
|
if (existsSync41(join46(full, "biffo.plugin.json"))) {
|
|
11588
11682
|
result.add(entry);
|
|
11589
11683
|
}
|
|
@@ -11593,7 +11687,7 @@ function vendoredPluginServiceDirs(repoRoot) {
|
|
|
11593
11687
|
function findWorkflowFiles(repoRoot) {
|
|
11594
11688
|
const found = [];
|
|
11595
11689
|
const vendoredPluginDirs = vendoredPluginServiceDirs(repoRoot);
|
|
11596
|
-
const walk2 = (dir,
|
|
11690
|
+
const walk2 = (dir, relative11) => {
|
|
11597
11691
|
let entries;
|
|
11598
11692
|
try {
|
|
11599
11693
|
entries = readdirSync20(dir);
|
|
@@ -11602,14 +11696,14 @@ function findWorkflowFiles(repoRoot) {
|
|
|
11602
11696
|
}
|
|
11603
11697
|
for (const entry of entries) {
|
|
11604
11698
|
if (entry === "node_modules" || entry === ".git" || entry === ".worktrees") continue;
|
|
11605
|
-
if (entry === ".github" &&
|
|
11699
|
+
if (entry === ".github" && relative11.startsWith("services/") && vendoredPluginDirs.has(relative11.slice("services/".length))) {
|
|
11606
11700
|
continue;
|
|
11607
11701
|
}
|
|
11608
11702
|
const full = join46(dir, entry);
|
|
11609
|
-
const rel =
|
|
11610
|
-
if (
|
|
11703
|
+
const rel = relative11 ? `${relative11}/${entry}` : entry;
|
|
11704
|
+
if (statSync13(full).isDirectory()) {
|
|
11611
11705
|
walk2(full, rel);
|
|
11612
|
-
} else if (/\.ya?ml$/.test(entry) &&
|
|
11706
|
+
} else if (/\.ya?ml$/.test(entry) && relative11.endsWith(".github/workflows")) {
|
|
11613
11707
|
found.push(rel);
|
|
11614
11708
|
}
|
|
11615
11709
|
}
|
|
@@ -11736,7 +11830,7 @@ async function runLambdaOutputCheck() {
|
|
|
11736
11830
|
|
|
11737
11831
|
// src/scripts/check-pipe-trap.ts
|
|
11738
11832
|
import { readFileSync as readFileSync35, readdirSync as readdirSync21 } from "fs";
|
|
11739
|
-
import { join as join48, relative as
|
|
11833
|
+
import { join as join48, relative as relative9 } from "path";
|
|
11740
11834
|
import { execa as execa15 } from "execa";
|
|
11741
11835
|
|
|
11742
11836
|
// src/lib/pipe-trap-guard.ts
|
|
@@ -11860,7 +11954,7 @@ async function runPipeTrapCheck() {
|
|
|
11860
11954
|
}
|
|
11861
11955
|
const findings = files.flatMap(
|
|
11862
11956
|
(file) => findPipeTraps(readFileSync35(file, "utf8")).map(
|
|
11863
|
-
(t) => `${
|
|
11957
|
+
(t) => `${relative9(root, file)}:${t.line} ${t.text}
|
|
11864
11958
|
${t.reason}`
|
|
11865
11959
|
)
|
|
11866
11960
|
);
|
|
@@ -11889,11 +11983,11 @@ var PROJECT = "<project>";
|
|
|
11889
11983
|
var ENV = "<env>";
|
|
11890
11984
|
var PLUGIN = "<plugin>";
|
|
11891
11985
|
var ACCOUNT = "<account>";
|
|
11892
|
-
function read(repoRoot,
|
|
11986
|
+
function read(repoRoot, relative11) {
|
|
11893
11987
|
try {
|
|
11894
|
-
return readFileSync36(join49(repoRoot,
|
|
11988
|
+
return readFileSync36(join49(repoRoot, relative11), "utf8");
|
|
11895
11989
|
} catch {
|
|
11896
|
-
throw new Error(`plugin-allowlist drift guard: cannot read ${
|
|
11990
|
+
throw new Error(`plugin-allowlist drift guard: cannot read ${relative11}`);
|
|
11897
11991
|
}
|
|
11898
11992
|
}
|
|
11899
11993
|
function assignedString(source, name) {
|
|
@@ -12017,7 +12111,7 @@ import { join as join51 } from "path";
|
|
|
12017
12111
|
import { execa as execa17 } from "execa";
|
|
12018
12112
|
|
|
12019
12113
|
// src/lib/plugin-collision-guard.ts
|
|
12020
|
-
import { existsSync as existsSync42, readdirSync as readdirSync22, statSync as
|
|
12114
|
+
import { existsSync as existsSync42, readdirSync as readdirSync22, statSync as statSync14 } from "fs";
|
|
12021
12115
|
import { join as join50 } from "path";
|
|
12022
12116
|
var PYTEST_SPECIAL = /* @__PURE__ */ new Set(["conftest.py"]);
|
|
12023
12117
|
var IGNORED_DIRS = /* @__PURE__ */ new Set([".venv", "node_modules", "__pycache__", ".git", "dist", "build"]);
|
|
@@ -12026,7 +12120,7 @@ function subdirectories(dir) {
|
|
|
12026
12120
|
return readdirSync22(dir).filter((entry) => {
|
|
12027
12121
|
if (IGNORED_DIRS.has(entry) || entry.startsWith(".")) return false;
|
|
12028
12122
|
try {
|
|
12029
|
-
return
|
|
12123
|
+
return statSync14(join50(dir, entry)).isDirectory();
|
|
12030
12124
|
} catch {
|
|
12031
12125
|
return false;
|
|
12032
12126
|
}
|
|
@@ -12107,7 +12201,7 @@ import { execa as execa18 } from "execa";
|
|
|
12107
12201
|
|
|
12108
12202
|
// src/lib/plugin-terraform-guard.ts
|
|
12109
12203
|
import { existsSync as existsSync44, readFileSync as readFileSync37, readdirSync as readdirSync23 } from "fs";
|
|
12110
|
-
import { dirname as dirname10, join as join52, relative as
|
|
12204
|
+
import { dirname as dirname10, join as join52, relative as relative10, sep as sep4 } from "path";
|
|
12111
12205
|
var SKIP_DIRS3 = /* @__PURE__ */ new Set(["node_modules", ".git", ".worktrees", "dist", ".venv", "__pycache__"]);
|
|
12112
12206
|
var PLUGIN_MANIFEST_FILE2 = "biffo.plugin.json";
|
|
12113
12207
|
function findPluginManifests(root) {
|
|
@@ -12124,7 +12218,7 @@ function findPluginManifests(root) {
|
|
|
12124
12218
|
if (SKIP_DIRS3.has(entry.name)) continue;
|
|
12125
12219
|
walk2(join52(dir, entry.name));
|
|
12126
12220
|
} else if (entry.isFile() && entry.name === PLUGIN_MANIFEST_FILE2) {
|
|
12127
|
-
found.push(
|
|
12221
|
+
found.push(relative10(root, join52(dir, entry.name)).split(sep4).join("/"));
|
|
12128
12222
|
}
|
|
12129
12223
|
}
|
|
12130
12224
|
};
|
|
@@ -12157,7 +12251,7 @@ function checkPluginTerraform(root) {
|
|
|
12157
12251
|
if (subscriptions === null) continue;
|
|
12158
12252
|
const pluginDir2 = dirname10(absManifest);
|
|
12159
12253
|
if (existsSync44(join52(pluginDir2, "terraform"))) continue;
|
|
12160
|
-
const relPluginDir =
|
|
12254
|
+
const relPluginDir = relative10(root, pluginDir2).split(sep4).join("/");
|
|
12161
12255
|
violations.push({
|
|
12162
12256
|
manifest,
|
|
12163
12257
|
expectedTerraformDir: relPluginDir ? `${relPluginDir}/terraform` : "terraform",
|
|
@@ -12192,7 +12286,7 @@ import { join as join54 } from "path";
|
|
|
12192
12286
|
import { execa as execa19 } from "execa";
|
|
12193
12287
|
|
|
12194
12288
|
// src/lib/plugin-tool-supply-audit.ts
|
|
12195
|
-
import { existsSync as existsSync45, readFileSync as readFileSync38, readdirSync as readdirSync24, statSync as
|
|
12289
|
+
import { existsSync as existsSync45, readFileSync as readFileSync38, readdirSync as readdirSync24, statSync as statSync15 } from "fs";
|
|
12196
12290
|
import { join as join53 } from "path";
|
|
12197
12291
|
|
|
12198
12292
|
// src/lib/openrouter-model-snapshot.ts
|
|
@@ -12610,7 +12704,7 @@ function listDirs(root) {
|
|
|
12610
12704
|
}
|
|
12611
12705
|
return entries.filter((e) => {
|
|
12612
12706
|
try {
|
|
12613
|
-
return
|
|
12707
|
+
return statSync15(join53(root, e)).isDirectory();
|
|
12614
12708
|
} catch {
|
|
12615
12709
|
return false;
|
|
12616
12710
|
}
|
|
@@ -12629,7 +12723,7 @@ function walkFiles2(root, accept, skipDir) {
|
|
|
12629
12723
|
const p = join53(dir, entry);
|
|
12630
12724
|
let st;
|
|
12631
12725
|
try {
|
|
12632
|
-
st =
|
|
12726
|
+
st = statSync15(p);
|
|
12633
12727
|
} catch {
|
|
12634
12728
|
continue;
|
|
12635
12729
|
}
|
|
@@ -12998,7 +13092,7 @@ function auditDeclaredModelIds(repoRoot, options = {}) {
|
|
|
12998
13092
|
function discoverPluginDirs(pluginsRoot) {
|
|
12999
13093
|
return listDirs(pluginsRoot).filter((name) => {
|
|
13000
13094
|
try {
|
|
13001
|
-
return
|
|
13095
|
+
return statSync15(join53(pluginsRoot, name, "biffo.plugin.json")).isFile();
|
|
13002
13096
|
} catch {
|
|
13003
13097
|
return false;
|
|
13004
13098
|
}
|
|
@@ -13357,7 +13451,7 @@ import { join as join56 } from "path";
|
|
|
13357
13451
|
import { execa as execa21 } from "execa";
|
|
13358
13452
|
|
|
13359
13453
|
// src/lib/skeleton-drift-guard.ts
|
|
13360
|
-
import { readFileSync as readFileSync39, readdirSync as readdirSync25, statSync as
|
|
13454
|
+
import { readFileSync as readFileSync39, readdirSync as readdirSync25, statSync as statSync16 } from "fs";
|
|
13361
13455
|
import { join as join55 } from "path";
|
|
13362
13456
|
var isWorkflow = (rel) => rel.startsWith(".github/workflows/") && (rel.endsWith(".yml") || rel.endsWith(".yaml"));
|
|
13363
13457
|
var isRootLayout = (rel) => rel.endsWith("src/app/layout.tsx");
|
|
@@ -13425,7 +13519,7 @@ function walk(dir, base = dir) {
|
|
|
13425
13519
|
const abs = join55(dir, entry);
|
|
13426
13520
|
let isDir;
|
|
13427
13521
|
try {
|
|
13428
|
-
isDir =
|
|
13522
|
+
isDir = statSync16(abs).isDirectory();
|
|
13429
13523
|
} catch {
|
|
13430
13524
|
continue;
|
|
13431
13525
|
}
|