mirror of
https://github.com/PR0M3TH3AN/bitgate.git
synced 2026-10-27 08:31:00 +00:00
fix: make workspace install under npm and enforce real guardrails
Replace pnpm-only workspace: protocol with npm workspace deps, pin BitVid and BitRoad reference commits, add Node types, and make the reference-import check scan package graphs and source for forbidden bitvid/bitroad imports.
This commit is contained in:
1 parent
81998396b9
commit
10326a2804
16 files changed
+2299
-109
No files matched your search
+11
@@ -0,0 +1,11 @@
|
|||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
coverage/
|
||||||
|
.DS_Store
|
||||||
|
*.log
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
.vite/
|
||||||
|
.turbo/
|
||||||
|
.cache/
|
||||||
|
*.tsbuildinfo
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Checkpoints
|
||||||
|
|
||||||
|
## Checkpoint 0 — Repo skeleton (current)
|
||||||
|
|
||||||
|
Delivered:
|
||||||
|
- npm workspaces monorepo
|
||||||
|
- Node 22 + ESM
|
||||||
|
- five empty packages under `packages/`
|
||||||
|
- Vitest harness
|
||||||
|
- TypeScript JSDoc typecheck
|
||||||
|
- GitHub Actions CI
|
||||||
|
- reference import guard
|
||||||
|
- provenance docs
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
npm run check:references
|
||||||
|
npm run typecheck
|
||||||
|
npm test
|
||||||
|
npm run build:types
|
||||||
|
```
|
||||||
|
|
||||||
|
Gate: do not add runtime or BitVid codecs until fixture corpus exists.
|
||||||
|
|
||||||
|
## Next checkpoint
|
||||||
|
|
||||||
|
Checkpoint 1 — BitVid fixture and conformance corpus only.
|
||||||
@@ -1,40 +1,46 @@
|
|||||||
# License and Provenance
|
# License and Provenance
|
||||||
|
|
||||||
## Source Licenses
|
## Reality check
|
||||||
|
|
||||||
- **BitVid:** GPL-3.0-or-later
|
BitVid is GPL-3.0-or-later. Direct ports of BitVid logic or structure into this
|
||||||
- **BitRoad:** MIT
|
repository create a derivative-work obligation. Do not pretend extracted
|
||||||
|
behavior is clean-room MIT unless it truly is independent work.
|
||||||
|
|
||||||
## Derived Works
|
BitRoad is MIT and is used here only as a target/model reference.
|
||||||
|
|
||||||
This repository combines:
|
## Working stance for this repo
|
||||||
|
|
||||||
1. **Original architectural work** (MIT)
|
Until a lawyer-ready SPDX audit is done, treat the repository as:
|
||||||
- Workspace structure
|
|
||||||
- Core target model
|
|
||||||
- Policy engine design
|
|
||||||
|
|
||||||
2. **GPL-encumbered behavior** (must remain GPL-compatible)
|
1. **Tooling / scaffolding** — original workspace layout, CI, docs structure.
|
||||||
- BitVid moderation thresholds
|
2. **Likely GPL-encumbered governance behavior** — anything characterized from
|
||||||
- Trust seed behavior
|
BitVid moderation thresholds, trust seeds, admin lists, report dedupe, mute
|
||||||
- Report aggregation rules
|
expiry, and related evaluator precedence.
|
||||||
|
3. **MIT-compatible address concepts** — BitRoad coordinate shapes, used as
|
||||||
|
consumer validation cases rather than copied UI/runtime code.
|
||||||
|
|
||||||
3. **MIT-licensed reference concepts**
|
## Package boundary intention
|
||||||
- BitRoad addressable targets
|
|
||||||
- Storefront/product identifiers
|
|
||||||
|
|
||||||
## Compliance Strategy
|
| Package | Intention |
|
||||||
|
| --- | --- |
|
||||||
|
| `@nostr-governance/core` | Clean API surface + pure evaluator. Avoid BitVid names. |
|
||||||
|
| `@nostr-governance/nostr` | Codecs. Legacy BitVid codec is provenance-sensitive. |
|
||||||
|
| `@nostr-governance/runtime` | Transport/storage orchestration. |
|
||||||
|
| `@nostr-governance/bitvid-compat` | Explicit BitVid-facing adapter. Most provenance-exposed. |
|
||||||
|
| `@nostr-governance/testing` | Fakes and fixture loaders. |
|
||||||
|
|
||||||
- Core policy engine is MIT-licensed original work
|
## Rules
|
||||||
- BitVid-compat adapter is GPL-3.0-or-later
|
|
||||||
- Clear separation between:
|
|
||||||
- Generic governance interfaces (MIT)
|
|
||||||
- BitVid-specific behavior (GPL)
|
|
||||||
|
|
||||||
## Audit Trails
|
- No direct imports from BitVid or BitRoad source trees.
|
||||||
|
- Fixtures copied into this repo must record the source commit in README or metadata.
|
||||||
|
- If a module is ported from BitVid rather than rewritten cleanly, document it in
|
||||||
|
the PR and keep SPDX compatible with GPL-3.0-or-later.
|
||||||
|
- Do not dual-license the whole monorepo casually. Prefer one root LICENSE once
|
||||||
|
chosen, and call out adapter exceptions only if they are scoped carefully.
|
||||||
|
|
||||||
All extracted behavior is documented in:
|
## Open decision (checkpoint 0)
|
||||||
|
|
||||||
- `fixtures/bitvid/` (input/output pairs)
|
Root license has not been finalized in this bootstrap.
|
||||||
- `docs/reference-map.md` (source locations)
|
Recommended default for continued extraction work: **GPL-3.0-or-later**.
|
||||||
- Commit history (clean room steps)
|
|
||||||
|
Decision needed from owner before publishing packages.
|
||||||
+30
-16
@@ -1,25 +1,39 @@
|
|||||||
# Reference Map
|
# Reference Map
|
||||||
|
|
||||||
## Pinned Versions
|
BitVid and BitRoad are **read-only reference repositories**.
|
||||||
|
This repo must not import their source trees.
|
||||||
|
|
||||||
- **BitVid:** `4525c1c` (2026-07-26)
|
## Pinned reference commits
|
||||||
- **BitRoad:** `bcd6c8e` (2026-07-26)
|
|
||||||
|
|
||||||
## Core Module References
|
| Repo | Short | Full |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| BitVid | `726c0d26` | `726c0d26ed98bf08e923ab895d23d0b5ac9ae173` |
|
||||||
|
| BitRoad | `bcd6c8e` | `bcd6c8efbd142d8923e7d4110432bdfa0a6cd2a2` |
|
||||||
|
|
||||||
| Module | BitVid Source | BitRoad Source | Purpose |
|
Pinned on 2026-07-26 from local checkouts under `/home/user/Documents/GitHub/`.
|
||||||
|--------|---------------|----------------|---------|
|
|
||||||
| identifiers | - | `src/commerce/address.mjs` | Coordinate parsing |
|
|
||||||
| targets | `js/services/moderationUtils.js` | `src/commerce/storefronts.mjs` | Addressable target model |
|
|
||||||
| authority | `js/accessControl.js` | - | Role resolution |
|
|
||||||
| policy | `js/services/moderationService.js` | - | Threshold handling |
|
|
||||||
|
|
||||||
## License Provenance
|
## Behavioral references (BitVid)
|
||||||
|
|
||||||
BitVid is licensed under GPL-3.0-or-later. This repository contains:
|
| Topic | BitVid path |
|
||||||
|
| --- | --- |
|
||||||
|
| Identifier / event ID helpers | `js/adminEventBlacklistHelpers.js` |
|
||||||
|
| Access control / roles | `js/accessControl.js` |
|
||||||
|
| Admin list persistence | `js/adminListStore.js` |
|
||||||
|
| Community blacklist batching | `js/adminListBatch.js` |
|
||||||
|
| Trust seeds | `js/services/trustBootstrap.js` |
|
||||||
|
| Report / mute aggregation | `js/services/moderationService.js` |
|
||||||
|
| Threshold / utility helpers | `js/services/moderationUtils.js` |
|
||||||
|
| Video presentation mapping | `js/services/moderationDecorator.js` |
|
||||||
|
|
||||||
- **Original work:** New architecture, neutral target model
|
## Structural references (BitRoad)
|
||||||
- **Derivative work:** Behavior extracted from BitVid fixtures
|
|
||||||
- **Reference-only:** BitRoad address semantics
|
|
||||||
|
|
||||||
Consult `docs/license-and-provenance.md` for detailed audit trails.
|
| Topic | BitRoad path |
|
||||||
|
| --- | --- |
|
||||||
|
| Address coordinates | `src/commerce/address.mjs` |
|
||||||
|
| Storefront replaceables | `src/commerce/storefronts.mjs` |
|
||||||
|
| Product replaceables | `src/commerce/product.mjs` |
|
||||||
|
|
||||||
|
## Extraction rule
|
||||||
|
|
||||||
|
Copy **behavior via fixtures and characterization**, not live imports.
|
||||||
|
Package source that imports BitVid/BitRoad fails `npm run check:references`.
|
||||||
Generated
+1904
File diff suppressed because it is too large.
Load diff
+6
-5
@@ -6,10 +6,10 @@
|
|||||||
"description": "Headless Nostr governance SDK for decentralized moderation and access control",
|
"description": "Headless Nostr governance SDK for decentralized moderation and access control",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "npm run test:unit && npm run test:conformance",
|
"test": "npm run test:unit && npm run test:conformance",
|
||||||
"test:unit": "vitest run",
|
"test:unit": "vitest run --passWithNoTests",
|
||||||
"test:conformance": "vitest run tests/conformance",
|
"test:conformance": "vitest run tests/conformance --passWithNoTests",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
||||||
"build:types": "tsc --emitDeclarationOnly",
|
"build:types": "tsc -p tsconfig.types.json",
|
||||||
"lint": "npm run check:references && npm run check:types",
|
"lint": "npm run check:references && npm run check:types",
|
||||||
"check:references": "node scripts/verify-no-reference-imports.mjs",
|
"check:references": "node scripts/verify-no-reference-imports.mjs",
|
||||||
"check:types": "npm run typecheck"
|
"check:types": "npm run typecheck"
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/node": "^22.10.0",
|
||||||
"typescript": "^5.4.5",
|
"typescript": "^5.4.5",
|
||||||
"vitest": "^1.6.0"
|
"vitest": "^1.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,12 +4,18 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"types": "dist/types/src/index.d.ts",
|
"types": "dist/types/src/index.d.ts",
|
||||||
"files": ["dist"],
|
"files": ["src", "dist"],
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/types/src/index.d.ts",
|
||||||
|
"import": "./src/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "vitest run"
|
"test": "vitest run"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nostr-governance/core": "workspace:*",
|
"@nostr-governance/core": "*",
|
||||||
"@nostr-governance/nostr": "workspace:*"
|
"@nostr-governance/nostr": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,9 +4,15 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"types": "dist/types/src/index.d.ts",
|
"types": "dist/types/src/index.d.ts",
|
||||||
"files": ["dist"],
|
"files": ["src", "dist"],
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/types/src/index.d.ts",
|
||||||
|
"import": "./src/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "vitest run"
|
"test": "vitest run"
|
||||||
},
|
},
|
||||||
"dependencies": {}
|
"dependencies": {}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
|
||||||
|
describe("@nostr-governance/core smoke", () => {
|
||||||
|
it("loads the package entrypoint", async () => {
|
||||||
|
const mod = await import("../src/index.js");
|
||||||
|
expect(mod).toBeTypeOf("object");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -4,11 +4,17 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"types": "dist/types/src/index.d.ts",
|
"types": "dist/types/src/index.d.ts",
|
||||||
"files": ["dist"],
|
"files": ["src", "dist"],
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/types/src/index.d.ts",
|
||||||
|
"import": "./src/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "vitest run"
|
"test": "vitest run"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nostr-governance/core": "workspace:*"
|
"@nostr-governance/core": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,12 +4,18 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"types": "dist/types/src/index.d.ts",
|
"types": "dist/types/src/index.d.ts",
|
||||||
"files": ["dist"],
|
"files": ["src", "dist"],
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/types/src/index.d.ts",
|
||||||
|
"import": "./src/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "vitest run"
|
"test": "vitest run"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nostr-governance/core": "workspace:*",
|
"@nostr-governance/core": "*",
|
||||||
"@nostr-governance/nostr": "workspace:*"
|
"@nostr-governance/nostr": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,11 +4,17 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"types": "dist/types/src/index.d.ts",
|
"types": "dist/types/src/index.d.ts",
|
||||||
"files": ["dist"],
|
"files": ["src", "dist"],
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/types/src/index.d.ts",
|
||||||
|
"import": "./src/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "vitest run"
|
"test": "vitest run"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nostr-governance/core": "workspace:*"
|
"@nostr-governance/core": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,42 +1,204 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* Fail if packages import BitVid/BitRoad source or depend on those trees.
|
||||||
|
* BitVid and BitRoad are read-only reference repos only.
|
||||||
|
*/
|
||||||
|
import { readdir, readFile, stat } from "node:fs/promises";
|
||||||
|
import { dirname, join, relative } from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
import { readFile } from 'node:fs/promises';
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
import { join } from 'node:path';
|
const ROOT = dirname(dirname(__filename));
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
|
|
||||||
const FORBIDDEN_PATHS = [
|
const FORBIDDEN_PATH_FRAGMENTS = [
|
||||||
'/home/user/Documents/GitHub/bitvid',
|
"/Documents/GitHub/bitvid",
|
||||||
'/home/user/Documents/GitHub/bitroad'
|
"/Documents/GitHub/bitroad",
|
||||||
|
"Documents/GitHub/bitvid",
|
||||||
|
"Documents/GitHub/bitroad",
|
||||||
];
|
];
|
||||||
|
|
||||||
async function checkImports(rootPath) {
|
const FORBIDDEN_PACKAGE_NAMES = ["bitvid", "bitroad"];
|
||||||
const pkgPath = join(rootPath, 'package.json');
|
|
||||||
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
const FORBIDDEN_IMPORT_RE =
|
||||||
|
/(?:from\s+|import\s*\(|require\s*\()\s*['"]([^'"]+)['"]/g;
|
||||||
|
|
||||||
|
const TEXT_EXTENSIONS = new Set([
|
||||||
|
".js",
|
||||||
|
".mjs",
|
||||||
|
".cjs",
|
||||||
|
".ts",
|
||||||
|
".tsx",
|
||||||
|
".jsx",
|
||||||
|
".json",
|
||||||
|
".md",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/** @param {string} dir */
|
||||||
|
async function walk(dir) {
|
||||||
|
/** @type {string[]} */
|
||||||
|
const files = [];
|
||||||
|
let entries;
|
||||||
|
try {
|
||||||
|
entries = await readdir(dir, { withFileTypes: true });
|
||||||
|
} catch {
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (
|
||||||
|
entry.name === "node_modules" ||
|
||||||
|
entry.name === ".git" ||
|
||||||
|
entry.name === "dist" ||
|
||||||
|
entry.name === "coverage"
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const full = join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
files.push(...(await walk(full)));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ext = entry.name.includes(".")
|
||||||
|
? `.${entry.name.split(".").pop()}`
|
||||||
|
: "";
|
||||||
|
if (TEXT_EXTENSIONS.has(ext)) {
|
||||||
|
files.push(full);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} value
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function isForbiddenImportSource(value) {
|
||||||
|
const normalized = value.replace(/\\/g, "/");
|
||||||
|
|
||||||
|
if (
|
||||||
|
normalized === "bitvid" ||
|
||||||
|
normalized === "bitroad" ||
|
||||||
|
normalized.startsWith("bitvid/") ||
|
||||||
|
normalized.startsWith("bitroad/")
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const fragment of FORBIDDEN_PATH_FRAGMENTS) {
|
||||||
|
if (normalized.includes(fragment)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Record<string, string> | undefined} deps
|
||||||
|
* @param {string} location
|
||||||
|
* @param {string[]} violations
|
||||||
|
*/
|
||||||
|
function checkDeps(deps, location, violations) {
|
||||||
|
for (const [name, version] of Object.entries(deps || {})) {
|
||||||
|
if (FORBIDDEN_PACKAGE_NAMES.includes(name) || isForbiddenImportSource(name)) {
|
||||||
|
violations.push(`${location}: forbidden dependency "${name}"`);
|
||||||
|
}
|
||||||
|
if (typeof version === "string" && isForbiddenImportSource(version)) {
|
||||||
|
violations.push(
|
||||||
|
`${location}: forbidden dependency version for "${name}": ${version}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const rootPkgPath = join(ROOT, "package.json");
|
||||||
|
await stat(rootPkgPath);
|
||||||
|
|
||||||
|
/** @type {string[]} */
|
||||||
const violations = [];
|
const violations = [];
|
||||||
|
|
||||||
for (const workspace of pkg.workspaces || []) {
|
const rootPkg = JSON.parse(await readFile(rootPkgPath, "utf8"));
|
||||||
const workspacePath = join(rootPath, workspace);
|
checkDeps(rootPkg.dependencies, "package.json", violations);
|
||||||
const workspacePkgPath = join(workspacePath, 'package.json');
|
checkDeps(rootPkg.devDependencies, "package.json", violations);
|
||||||
const workspacePkg = JSON.parse(await readFile(workspacePkgPath, 'utf-8'));
|
checkDeps(rootPkg.optionalDependencies, "package.json", violations);
|
||||||
|
checkDeps(rootPkg.peerDependencies, "package.json", violations);
|
||||||
for (const dep of Object.keys(workspacePkg.dependencies || {})) {
|
|
||||||
if (FORBIDDEN_PATHS.some(path => dep.startsWith(path))) {
|
const packagesDir = join(ROOT, "packages");
|
||||||
violations.push(`Workspace ${workspace} depends on forbidden path: ${dep}`);
|
let packageDirs = [];
|
||||||
|
try {
|
||||||
|
packageDirs = (await readdir(packagesDir, { withFileTypes: true }))
|
||||||
|
.filter((entry) => entry.isDirectory())
|
||||||
|
.map((entry) => join(packagesDir, entry.name));
|
||||||
|
} catch {
|
||||||
|
packageDirs = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const packageDir of packageDirs) {
|
||||||
|
const pkgPath = join(packageDir, "package.json");
|
||||||
|
let pkg;
|
||||||
|
try {
|
||||||
|
pkg = JSON.parse(await readFile(pkgPath, "utf8"));
|
||||||
|
} catch {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rel = relative(ROOT, pkgPath);
|
||||||
|
checkDeps(pkg.dependencies, rel, violations);
|
||||||
|
checkDeps(pkg.devDependencies, rel, violations);
|
||||||
|
checkDeps(pkg.optionalDependencies, rel, violations);
|
||||||
|
checkDeps(pkg.peerDependencies, rel, violations);
|
||||||
|
}
|
||||||
|
|
||||||
|
const scanRoots = [
|
||||||
|
join(ROOT, "packages"),
|
||||||
|
join(ROOT, "scripts"),
|
||||||
|
join(ROOT, "tests"),
|
||||||
|
join(ROOT, "examples"),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const scanRoot of scanRoots) {
|
||||||
|
const files = await walk(scanRoot);
|
||||||
|
for (const file of files) {
|
||||||
|
// Allow the guard script itself to mention forbidden path fragments.
|
||||||
|
if (file === __filename) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = await readFile(file, "utf8");
|
||||||
|
const rel = relative(ROOT, file);
|
||||||
|
|
||||||
|
for (const match of content.matchAll(FORBIDDEN_IMPORT_RE)) {
|
||||||
|
const source = match[1];
|
||||||
|
if (isForbiddenImportSource(source)) {
|
||||||
|
violations.push(`${rel}: forbidden import of "${source}"`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Catch file: / link: absolute path deps written into package.json files.
|
||||||
|
if (file.endsWith("package.json") && isForbiddenImportSource(content)) {
|
||||||
|
// Already covered via dependency version checks; keep for raw path mentions.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (violations.length > 0) {
|
if (violations.length > 0) {
|
||||||
console.error('\nReference import violations detected:');
|
console.error("Reference import guard failed:\n");
|
||||||
violations.forEach(v => console.error(`- ${v}`));
|
for (const violation of violations) {
|
||||||
|
console.error(`- ${violation}`);
|
||||||
|
}
|
||||||
|
console.error(
|
||||||
|
"\nBitVid and BitRoad are read-only reference repositories. Do not import from them.",
|
||||||
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('✓ No forbidden imports detected');
|
console.log("✓ No forbidden BitVid/BitRoad imports detected");
|
||||||
}
|
}
|
||||||
|
|
||||||
checkImports(fileURLToPath(new URL('.', import.meta.url))).catch(err => {
|
main().catch((error) => {
|
||||||
console.error('Check failed:', err);
|
console.error("check:references failed:", error);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
+20
-6
@@ -1,15 +1,29 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "ESNext",
|
"module": "NodeNext",
|
||||||
"moduleResolution": "Bundler",
|
"moduleResolution": "NodeNext",
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
|
"lib": ["ES2022"],
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"checkJs": true,
|
"checkJs": true,
|
||||||
"types": ["vitest/globals"]
|
"noImplicitAny": false,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"types": ["node", "vitest/globals"]
|
||||||
},
|
},
|
||||||
"include": ["**/*.js"],
|
"include": [
|
||||||
"exclude": ["node_modules"]
|
"packages/**/src/**/*.js",
|
||||||
}
|
"packages/**/test/**/*.js",
|
||||||
|
"tests/**/*.js",
|
||||||
|
"vitest.config.js"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"dist",
|
||||||
|
"coverage",
|
||||||
|
"**/dist/**",
|
||||||
|
"scripts/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
+15
-3
@@ -1,9 +1,21 @@
|
|||||||
{
|
{
|
||||||
"extends": "./tsconfig.json",
|
"extends": "./tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"noEmit": false,
|
||||||
"emitDeclarationOnly": true,
|
"emitDeclarationOnly": true,
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"outDir": "dist/types"
|
"declarationMap": true,
|
||||||
|
"outDir": "dist/types",
|
||||||
|
"rootDir": "."
|
||||||
},
|
},
|
||||||
"include": ["packages/**/src/*.js"]
|
"include": [
|
||||||
}
|
"packages/**/src/**/*.js"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"dist",
|
||||||
|
"coverage",
|
||||||
|
"**/test/**",
|
||||||
|
"**/*.test.js"
|
||||||
|
]
|
||||||
|
}
|
||||||
+9
-9
@@ -1,12 +1,12 @@
|
|||||||
import { defineConfig } from 'vitest/config';
|
import { defineConfig } from "vitest/config";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
test: {
|
test: {
|
||||||
include: ['**/*.test.js'],
|
include: [
|
||||||
environment: 'node',
|
"packages/**/test/**/*.test.js",
|
||||||
coverage: {
|
"tests/**/*.test.js",
|
||||||
provider: 'v8',
|
],
|
||||||
reporter: ['text', 'json-summary']
|
environment: "node",
|
||||||
}
|
passWithNoTests: true,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user