项目文件夹

文件
wehub-resource-sync bcbd1bdb22
Integ / changes (push) Has been skipped
Pre-commit / pre-commit (push) Failing after 1s
CLI exit codes / changes (push) Has been skipped
Test (Install) / changes (push) Has been skipped
Test (Python) / changes (push) Has been skipped
Test (TypeScript) / changes (push) Has been skipped
CLI exit codes / cli-gate (push) Has been cancelled
Test (Install) / test-install-gate (push) Has been cancelled
Integ / integ-gate (push) Has been cancelled
Test (Python) / test-python-gate (push) Has been cancelled
Test (TypeScript) / test-typescript-gate (push) Has been cancelled
Test (Install) / python-minimal (3.12) (push) Has been cancelled
Test (Install) / python-minimal (3.11) (push) Has been cancelled
Test (Install) / python-extra (agno, mirage.agents.agno) (push) Has been cancelled
Test (Install) / python-extra (chroma, mirage.resource.chroma) (push) Has been cancelled
Test (Install) / python-extra (pdf, mirage.core.filetype.pdf) (push) Has been cancelled
Integ / integ (push) Has been cancelled
Integ / integ-database (push) Has been cancelled
Integ / integ-database-ts (push) Has been cancelled
Integ / integ-data (push) Has been cancelled
Integ / integ-ssh (push) Has been cancelled
Integ / integ-ssh-ts (push) Has been cancelled
Test (Python) / audit (push) Has been cancelled
Test (TypeScript) / test (push) Has been cancelled
Test (TypeScript) / python-fs-shim (push) Has been cancelled
CLI exit codes / Python CLI (push) Has been cancelled
CLI exit codes / TypeScript CLI (push) Has been cancelled
CLI exit codes / Cross-language snapshot interop (push) Has been cancelled
Test (Python) / test (push) Has been cancelled
Test (Python) / import-isolation (deepagents, openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Python) / import-isolation (deepagents, pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Integ / integ-ts (push) Has been cancelled
Integ / integ-fuse (push) Has been cancelled
Test (Install) / python-extra (databricks, mirage.resource.databricks_volume) (push) Has been cancelled
Test (Install) / python-extra (deepagents, mirage.agents.langchain) (push) Has been cancelled
Test (Install) / python-extra (email, mirage.resource.email) (push) Has been cancelled
Test (Install) / python-extra (fuse, mirage.fuse.mount) (push) Has been cancelled
Test (Install) / python-extra (hdf5, mirage.core.filetype.hdf5) (push) Has been cancelled
Test (Install) / python-extra (hf, mirage.resource.hf_buckets) (push) Has been cancelled
Test (Install) / python-extra (lancedb, mirage.resource.lancedb) (push) Has been cancelled
Test (Install) / python-extra (langfuse, mirage.resource.langfuse) (push) Has been cancelled
Test (Install) / python-extra (mongodb, mirage.resource.mongodb) (push) Has been cancelled
Test (Install) / python-extra (nextcloud, mirage.resource.nextcloud) (push) Has been cancelled
Test (Install) / python-extra (openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Install) / python-extra (openhands, mirage.agents.openhands, 3.12) (push) Has been cancelled
Test (Install) / python-extra (parquet, mirage.core.filetype.parquet) (push) Has been cancelled
Test (Install) / python-extra (postgres, mirage.resource.postgres) (push) Has been cancelled
Test (Install) / python-extra (pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Test (Install) / python-extra (qdrant, mirage.resource.qdrant) (push) Has been cancelled
Test (Install) / python-extra (redis, mirage.resource.redis) (push) Has been cancelled
Test (Install) / python-extra (s3, mirage.resource.s3) (push) Has been cancelled
Test (Install) / python-extra (ssh, mirage.resource.ssh) (push) Has been cancelled
Test (Install) / ts-minimal (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:44 +08:00

193 行
7.4 KiB
TypeScript

// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
import { Double, MongoClient } from "mongodb";
import {
CommandSafeguard,
MongoDBResource,
MountMode,
Workspace,
} from "@struktoai/mirage-node";
import { runNotFound, runProvisionProbe, runSedReadonlyProbe } from "./cases.ts";
const MONGODB_URI = process.env.MONGODB_URI ?? "mongodb://localhost:27017";
const DB = "mirage_integ";
const MOUNT = "/mongodb";
const DEC = new TextDecoder();
const BOOKS = [
{ _id: 1, title: "alpha", author: "ada", year: 2020, tags: ["fiction", "classic"], rating: 4.5 },
{ _id: 2, title: "beta", author: "ben", year: 2021, tags: ["fiction"], rating: 3.2 },
{ _id: 3, title: "gamma", author: "cara", year: 2022, rating: 5.0 },
{ _id: 4, title: "delta", author: "ada", year: 2023, tags: ["history"], rating: 4.0 },
{ _id: 5, title: "epsilon", author: "ben", year: 2024, rating: 2.5 },
];
const AUTHORS = [
{ _id: 1, name: "ada", books: 2 },
{ _id: 2, name: "ben", books: 2 },
{ _id: 3, name: "cara", books: 1 },
];
const CASES: ReadonlyArray<readonly [string, string]> = [
["ls_root", `ls ${MOUNT}/`],
["ls_db", `ls ${MOUNT}/${DB}/`],
["ls_collections", `ls ${MOUNT}/${DB}/collections/`],
["ls_views", `ls ${MOUNT}/${DB}/views/`],
["ls_entity", `ls ${MOUNT}/${DB}/collections/books/`],
["tree", `tree -L 3 ${MOUNT}/${DB}/`],
["cat_database_json", `cat ${MOUNT}/${DB}/database.json`],
["cat_schema_json", `cat ${MOUNT}/${DB}/collections/books/schema.json`],
["cat_docs", `cat ${MOUNT}/${DB}/collections/books/documents.jsonl`],
["head_2", `head -n 2 ${MOUNT}/${DB}/collections/books/documents.jsonl`],
["tail_2", `tail -n 2 ${MOUNT}/${DB}/collections/books/documents.jsonl`],
["wc_l_books", `wc -l ${MOUNT}/${DB}/collections/books/documents.jsonl`],
["wc_default_books", `wc ${MOUNT}/${DB}/collections/books/documents.jsonl`],
["wc_l_authors", `wc -l ${MOUNT}/${DB}/collections/authors/documents.jsonl`],
["stat_docs", `stat ${MOUNT}/${DB}/collections/books/documents.jsonl`],
["grep_c_title", `grep -c title ${MOUNT}/${DB}/collections/books/documents.jsonl`],
["grep_ada", `grep ada ${MOUNT}/${DB}/collections/books/documents.jsonl`],
["grep_e_multi", `grep -n -e ada -e ben ${MOUNT}/${DB}/collections/books/documents.jsonl`],
["grep_r_e_multi", `grep -r -e alpha -e beta ${MOUNT}/${DB}/collections/books`],
["grep_db_scope", `grep ada ${MOUNT}/${DB}/`],
["grep_root_scope", `grep ada ${MOUNT}/`],
["rg_db_scope", `rg ben ${MOUNT}/${DB}/`],
["rg_e_multi", `rg -e gamma -e cara ${MOUNT}/${DB}/collections/books`],
["find_docs", `find ${MOUNT}/${DB}/ -name documents.jsonl`],
["find_schema", `find ${MOUNT}/${DB}/ -name schema.json`],
["jq_titles", `jq '.title' ${MOUNT}/${DB}/collections/books/documents.jsonl`],
["pipe_grep_c", `cat ${MOUNT}/${DB}/collections/books/documents.jsonl | grep -c fiction`],
["cat_view_docs", `cat ${MOUNT}/${DB}/views/recent_books/documents.jsonl`],
["wc_l_view", `wc -l ${MOUNT}/${DB}/views/recent_books/documents.jsonl`],
["safeguard_cat_truncates", `cat ${MOUNT}/${DB}/collections/books/documents.jsonl`],
["safeguard_cat_pipe_uncapped", `cat ${MOUNT}/${DB}/collections/books/documents.jsonl | wc -l`],
// symlink to the database meta file (namespace state; read-only backend)
["sym_ln", `ln -s ${MOUNT}/${DB}/database.json ${MOUNT}/meta_link`],
["sym_readlink", `readlink ${MOUNT}/meta_link`],
["sym_cat", `cat ${MOUNT}/meta_link`],
["sym_ls", `ls -F ${MOUNT} | grep meta_link`],
["sym_rm", `rm ${MOUNT}/meta_link && ls ${MOUNT}`],
];
async function seed(client: MongoClient): Promise<void> {
const db = client.db(DB);
await db.dropDatabase();
// Python seeds floats (BSON double); insert Double so the inferred schema
// matches (JS whole numbers would otherwise serialize to BSON int32).
await db
.collection("books")
.insertMany(BOOKS.map((d) => ({ ...d, rating: new Double(d.rating) })));
await db.collection("authors").insertMany(AUTHORS.map((d) => ({ ...d })));
await db.createCollection("recent_books", {
viewOn: "books",
pipeline: [{ $match: { year: { $gte: 2022 } } }],
});
}
async function run(ws: Workspace, name: string, cmd: string): Promise<void> {
const result = await ws.execute(cmd);
const out = DEC.decode(result.stdout);
process.stdout.write(`=== ${name} ===\n`);
process.stdout.write(out.endsWith("\n") ? out : out + "\n");
if (name.startsWith("safeguard_")) {
const err = DEC.decode(result.stderr);
if (err) process.stdout.write(err.endsWith("\n") ? err : err + "\n");
}
}
async function insertUntilDone(
client: MongoClient,
done: () => boolean,
): Promise<void> {
let i = 0;
while (!done()) {
i += 1;
await client
.db(DB)
.collection("books")
.insertOne({ _id: 100 + i, title: "live_insert" });
await new Promise((r) => setTimeout(r, 500));
}
}
async function runFollow(ws: Workspace, client: MongoClient): Promise<void> {
const name = "tail_f_change_stream";
const cmd = `tail -f ${MOUNT}/${DB}/collections/books/documents.jsonl | head -n 1`;
let finished = false;
const followP = ws.execute(cmd).then((result) => {
finished = true;
return DEC.decode(result.stdout);
});
const inserter = insertUntilDone(client, () => finished);
const timeout = new Promise<never>((_, reject) =>
setTimeout(() => reject(new Error("tail -f change stream timed out")), 30000),
);
try {
const out = await Promise.race([followP, timeout]);
process.stdout.write(`=== ${name} ===\n`);
process.stdout.write(out.endsWith("\n") ? out : out + "\n");
} finally {
finished = true;
await inserter;
}
}
function setCatSafeguard(ws: Workspace, maxLines: number): void {
const sg = new CommandSafeguard({ maxLines });
for (const m of ws.registry.allMounts()) m.commandSafeguards.set("cat", sg);
}
async function main(): Promise<void> {
const seedClient = new MongoClient(MONGODB_URI);
await seedClient.connect();
try {
await seed(seedClient);
} finally {
await seedClient.close();
}
const resource = new MongoDBResource({ uri: MONGODB_URI, databases: [DB] });
const ws = new Workspace({ [MOUNT]: resource }, { mode: MountMode.READ });
try {
for (const [name, cmd] of CASES) {
if (name === "safeguard_cat_truncates") setCatSafeguard(ws, 2);
await run(ws, name, cmd);
}
await runNotFound(ws, MOUNT);
await runProvisionProbe(
ws,
`${MOUNT}/${DB}/collections/books/documents.jsonl`,
);
await runSedReadonlyProbe(
ws,
`${MOUNT}/${DB}/collections/books/documents.jsonl`,
);
const liveClient = new MongoClient(MONGODB_URI);
await liveClient.connect();
try {
await runFollow(ws, liveClient);
} finally {
await liveClient.close();
}
} finally {
await ws.close();
await resource.close();
}
}
main().catch((err: unknown) => {
console.error(err);
process.exit(1);
});