@stll/oxlint-config 1.2.6 → 1.3.0
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.
|
@@ -532,16 +532,32 @@ const parseEnvFile = (input) => {
|
|
|
532
532
|
if (envFile.startsWith("/") || /^[A-Za-z]:/.test(envFile) || envFile.includes("\\") || /\p{Cc}/u.test(envFile) || envFile.split("/").some((part) => part === "" || part === "." || part === "..")) throw new Error("cloud.envFile must be a canonical repository-relative path");
|
|
533
533
|
return envFile;
|
|
534
534
|
};
|
|
535
|
+
const cloudPrepareScript = /^[a-z0-9][a-z0-9:._-]*$/;
|
|
536
|
+
const parsePrepare = (input) => {
|
|
537
|
+
if (input === void 0) return void 0;
|
|
538
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) throw new Error("cloud.prepare must be an object");
|
|
539
|
+
for (const key of Object.keys(input)) if (key !== "script" && key !== "seconds") throw new Error(`unsupported cloud.prepare key: ${key}`);
|
|
540
|
+
const script = "script" in input ? input.script : void 0;
|
|
541
|
+
if (typeof script !== "string" || !cloudPrepareScript.test(script)) throw new Error("cloud.prepare.script must name a package script");
|
|
542
|
+
const seconds = "seconds" in input ? input.seconds : void 0;
|
|
543
|
+
if (typeof seconds !== "number" || !Number.isInteger(seconds) || seconds < 1 || seconds > 900) throw new Error(`cloud.prepare.seconds must be an integer from 1 to 900`);
|
|
544
|
+
return {
|
|
545
|
+
script,
|
|
546
|
+
seconds
|
|
547
|
+
};
|
|
548
|
+
};
|
|
535
549
|
/** Parse an explicit declaration without assuming services for undeclared repositories. */
|
|
536
550
|
const parseCloudSetup = (input) => {
|
|
537
551
|
if (input === void 0) return void 0;
|
|
538
552
|
if (typeof input !== "object" || input === null || Array.isArray(input)) throw new Error("cloud must be an object");
|
|
539
|
-
for (const key of Object.keys(input)) if (key !== "services" && key !== "install" && key !== "envFile" && key !== "rust" && key !== "tools") throw new Error(`unsupported cloud key: ${key}`);
|
|
553
|
+
for (const key of Object.keys(input)) if (key !== "services" && key !== "install" && key !== "envFile" && key !== "rust" && key !== "tools" && key !== "prepare") throw new Error(`unsupported cloud key: ${key}`);
|
|
540
554
|
const rust = parseRust("rust" in input ? input.rust : void 0);
|
|
541
555
|
const tools = parseTools("tools" in input ? input.tools : void 0);
|
|
556
|
+
const prepare = parsePrepare("prepare" in input ? input.prepare : void 0);
|
|
542
557
|
const extensions = {
|
|
543
558
|
...rust === void 0 ? {} : { rust },
|
|
544
|
-
...tools === void 0 ? {} : { tools }
|
|
559
|
+
...tools === void 0 ? {} : { tools },
|
|
560
|
+
...prepare === void 0 ? {} : { prepare }
|
|
545
561
|
};
|
|
546
562
|
const selected = "services" in input ? input.services : [];
|
|
547
563
|
if (!Array.isArray(selected)) throw new Error("cloud.services must be an array when provided");
|
|
@@ -596,7 +612,9 @@ service_process_matches() {
|
|
|
596
612
|
owner="$(stat -c '%u' "/proc/$pid" 2>/dev/null)" || return 2
|
|
597
613
|
[[ "$owner" =~ ^[0-9]+$ ]] || return 2
|
|
598
614
|
[[ "$owner" == "$SERVICE_UID" ]] || return 1
|
|
599
|
-
|
|
615
|
+
# Read the executable link as its verified owner: container root may lack the ptrace
|
|
616
|
+
# capability that reading another user's /proc/<pid>/exe requires.
|
|
617
|
+
actual="$(service_run readlink -f "/proc/$pid/exe" 2>/dev/null)" || return 2
|
|
600
618
|
expected="$(readlink -f "$executable")" || return 2
|
|
601
619
|
[[ -n "$actual" && -n "$expected" && "$actual" != *' (deleted)' ]] || return 2
|
|
602
620
|
[[ "$actual" == "$expected" ]]
|
|
@@ -1171,12 +1189,15 @@ process.stdout.write([...hosts].sort().join(","));
|
|
|
1171
1189
|
|
|
1172
1190
|
@ENV_FUNCTIONS@
|
|
1173
1191
|
|
|
1192
|
+
@PREPARE_FUNCTION@
|
|
1193
|
+
|
|
1174
1194
|
if [[ "$MODE" == install ]]; then
|
|
1175
1195
|
step runtimes install_runtimes
|
|
1176
1196
|
step services install_services
|
|
1177
1197
|
step tools install_tools
|
|
1178
1198
|
step shell install_shell_environment
|
|
1179
1199
|
step dependencies dependency_install
|
|
1200
|
+
@PREPARE_STEP@
|
|
1180
1201
|
exit 0
|
|
1181
1202
|
fi
|
|
1182
1203
|
step runtime-check runtime_ready
|
|
@@ -1217,6 +1238,24 @@ write_environment() {
|
|
|
1217
1238
|
}
|
|
1218
1239
|
`;
|
|
1219
1240
|
const shellQuote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
1241
|
+
const renderPrepare = (prepare, files) => {
|
|
1242
|
+
if (prepare === void 0) return "";
|
|
1243
|
+
const manifest = files["package.json"];
|
|
1244
|
+
if (manifest === void 0) throw new Error("cloud.prepare requires a tracked root package.json");
|
|
1245
|
+
const parsed = JSON.parse(manifest);
|
|
1246
|
+
const scripts = typeof parsed === "object" && parsed !== null && "scripts" in parsed ? parsed.scripts : void 0;
|
|
1247
|
+
if (typeof scripts !== "object" || scripts === null || !Object.hasOwn(scripts, prepare.script) || typeof Reflect.get(scripts, prepare.script) !== "string") throw new Error(`cloud.prepare.script ${prepare.script} is not a root package script`);
|
|
1248
|
+
return [
|
|
1249
|
+
"prepare_sources() {",
|
|
1250
|
+
" local leader status=0",
|
|
1251
|
+
` timeout --kill-after=10 ${prepare.seconds} runuser -u "$OUTPUT_USER" -- env HOME="$OUTPUT_HOME" PATH="$PATH" "$BUN_DIR/bun" run ${shellQuote(prepare.script)} </dev/null &`,
|
|
1252
|
+
" leader=$!",
|
|
1253
|
+
" wait \"$leader\" || status=$?",
|
|
1254
|
+
" kill -KILL -- \"-$leader\" 2>/dev/null || true",
|
|
1255
|
+
" return \"$status\"",
|
|
1256
|
+
"}"
|
|
1257
|
+
].join("\n");
|
|
1258
|
+
};
|
|
1220
1259
|
const generateCloudSetup = ({ policy, cloud, nodeVersion, files = {}, rustExceptions = [] }) => {
|
|
1221
1260
|
const selected = parseCloudSetup(cloud);
|
|
1222
1261
|
if (selected === void 0) throw new Error("cloud declaration is required");
|
|
@@ -1253,6 +1292,8 @@ const generateCloudSetup = ({ policy, cloud, nodeVersion, files = {}, rustExcept
|
|
|
1253
1292
|
["@ENV_FUNCTIONS@", selected.envFile === void 0 ? "" : environmentFunctions],
|
|
1254
1293
|
["@ENV_VALIDATE@", selected.envFile === void 0 ? "" : "DATABASE_URL=''\nREDIS_URL=''\nvalidate_environment"],
|
|
1255
1294
|
["@ENV_WRITE@", selected.envFile === void 0 ? "" : "write_environment"],
|
|
1295
|
+
["@PREPARE_FUNCTION@", renderPrepare(selected.prepare, files)],
|
|
1296
|
+
["@PREPARE_STEP@", selected.prepare === void 0 ? "" : " step prepare prepare_sources"],
|
|
1256
1297
|
["@SERVICE_INSTALL@", renderCloudServiceInstall({
|
|
1257
1298
|
services,
|
|
1258
1299
|
postgres: policy.postgres,
|