Files
suaveplan/scripts/ensure-category-subcategory-intros.ts
2026-05-27 23:47:53 +01:00

179 lines
8.6 KiB
TypeScript

#!/usr/bin/env bun
/**
* ensure-category-subcategory-intros — writes placeholder `_intro.md` files
* for every category and subcategory that lacks one. Existing files are never
* overwritten.
*
* Usage: bun scripts/ensure-category-subcategory-intros.ts
*/
import { existsSync, readdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { CONFIG } from "./lib/config.js";
import { isDirectorySafe } from "./lib/doc-tree.js";
const ROOT = CONFIG.paths.root;
const PACKAGES_ROOT = join(ROOT, CONFIG.paths.packagesRoot);
const CATEGORY_INTROS: Record<string, string> = {
"api-stack":
"# `api-stack`\n\nAPI infrastructure, plugin framework, and HTTP orchestration layer for the Suaveplan monorepo.",
commerce:
"# `commerce`\n\nBooking engines, contact management, payment plugins, and commerce primitives.",
communication:
"# `communication`\n\nEmail delivery, messaging channels, and webhook clients.",
devtools:
"# `devtools`\n\nDeveloper tooling, documentation generators, Docker helpers, and build utilities.",
foundation:
"# `foundation`\n\nFoundational primitives — types, errors, configuration, data structures, and cross-cutting utilities.",
gaming: "# `gaming`\n\nGame engines, entity-component systems, and simulation libraries.",
geospatial:
"# `geospatial`\n\nGeospatial data, mapping, planetary coordinates, and logistics utilities.",
identity:
"# `identity`\n\nAuthentication, authorization, identity resolution, and credential management.",
localization:
"# `localization`\n\nInternationalization, localization, locale detection, and translation infrastructure.",
media: "# `media`\n\nAudio, video, image, and font processing libraries.",
money: "# `money`\n\nPayments, currencies, cryptocurrency, and financial primitives.",
networking:
"# `networking`\n\nDistributed networking, event buses, drive mesh, and network discovery.",
observability:
"# `observability`\n\nMonitoring, logging, health checks, audit trails, and analytics.",
persistence:
"# `persistence`\n\nCaching, database adapters, search engines, and storage abstractions.",
"security-stack":
"# `security-stack`\n\nCryptography, vaults, security utilities, and threat-detection primitives.",
testkit:
"# `testkit`\n\nTesting frameworks, A/B testing, and quality-assurance utilities.",
threejs:
"# `threejs`\n\nThree.js and React Three Fiber integrations.",
ui: "# `ui`\n\nReact components, forms, and user-interface primitives.",
};
const SUBCATEGORY_INTROS: Record<string, string> = {
api: "API orchestration, plugin lifecycle, routing, workers, and tenant resolution.",
audio: "Audio processing, playback, analysis, and effect plugins.",
"audio-fx": "Real-time audio effects and DSP plugins.",
"audio-ir": "Impulse-response capture, loading, and room-acoustic plugins.",
auth: "Authentication providers, JWT, WebAuthn, OAuth, and session resolution.",
barcode: "1-D barcode generation and parsing.",
bitpacker:
"Bit-level binary packing, schemas, compression, and streaming codecs.",
booking:
"Universal booking engine with availability, conflict detection, and pricing.",
cache: "Caching abstractions, memory caches, and Redis backends.",
contacts:
"Contact and group management with deduplication and import/export.",
core: "Core foundation — types, errors, configuration, schema registry, and utilities.",
crypto: "Cryptographic primitives, ciphers, hashes, curves, and key management.",
data: "Data manipulation, masking, deduplication, diffing, and byte utilities.",
database: "Database adapters, migrations, seeding, and SQLite support.",
datetime: "Timezone-aware date/time utilities, calendars, and recurrence.",
docker: "Docker helpers and GPU runtime configuration.",
docs: "Documentation utilities, SVG compression, PDF handling, and sitemap generation.",
drive: "Virtual filesystem, mesh networking, and chunk-addressed storage plugins.",
emails:
"Email delivery, DMARC parsing, templates, campaigns, and suppression lists.",
env: "Type-safe environment variable loading and validation.",
error: "Foundation error substrate, code registries, and wire formats.",
etl: "Extract-Transform-Load pipeline engine with typed stages.",
events: "Typed event bus, event sourcing, metrics, and transport bridges.",
"feature-flags": "Feature-flag evaluation engine with percentage and attribute targeting.",
finance:
"Currency conversion, cryptocurrency utilities, and exchange-rate providers.",
flow: "Finite state machines, CRDTs, idempotency, and CBOR serialization.",
fonts: "Font packing, compression, subsetting, and conversion tools.",
games: "Game controllers, entity-component systems, and game-server logic.",
geo: "Geospatial coordinates, planetary data, and solar-system modelling.",
i18n: "Internationalization core, backends, detectors, and locale resolution.",
image: "Image compression, colour conversion, EXIF handling, and optimisation.",
logistics: "Port data and logistics primitives.",
messaging:
"Messaging adapters — Discord, Slack, Telegram, SMS, iMessage, and notifications.",
midi: "MIDI message parsing, control surfaces, and hardware integration.",
migration: "Schema migration runners and ledger tracking.",
monitor: "Logging, health checks, audit logging, and analytics instrumentation.",
network:
"Mesh networking, WebSocket transports, bootstrap, and discovery protocols.",
payment:
"Payment intent lifecycle, provider adapters, and fraud detection.",
ports: "Maritime port and logistics data.",
random: "Pseudo-random generators, noise functions, and deterministic sequences.",
r3f: "React Three Fiber networking and scene components.",
search: "Full-text search, BM25, fuzzy matching, and faceted search.",
security: "Have-I-Been-Pwned checks, JWS, licensing, and OTP utilities.",
storage: "Storage abstractions, browser backends, S3, CDN, and URI routing.",
testing: "Testing runners, DOM helpers, E2E harnesses, and A/B testing.",
timing: "Cron, stopwatches, throttling, debouncing, and scheduling.",
tooling: "CLI frameworks, installers, and build tooling.",
"webhook-client": "Webhook delivery client with retry logic and HMAC verification.",
video: "Video encoding, decoding, and thumbnail generation.",
voice: "Voice synthesis, speech-to-text, and provider adapters.",
forms: "Form builders, validation, and React form components.",
react: "React hooks and components for audio, auth, and UI surfaces.",
};
function ensureIntro(path: string, content: string): boolean {
if (existsSync(path)) return false;
writeFileSync(path, content + "\n");
return true;
}
function main(): void {
if (!isDirectorySafe(PACKAGES_ROOT)) {
console.error(`Packages root not found: ${PACKAGES_ROOT}`);
process.exit(2);
}
let created = 0;
let skipped = 0;
const catEntries = readdirSync(PACKAGES_ROOT, { withFileTypes: true });
for (const cat of catEntries) {
if (!cat.isDirectory() || cat.name.startsWith(".")) continue;
const categoryDir = join(PACKAGES_ROOT, cat.name);
// Category intro
const catIntro = CATEGORY_INTROS[cat.name];
if (catIntro) {
const didCreate = ensureIntro(
join(categoryDir, "_intro.md"),
catIntro
);
didCreate ? created++ : skipped++;
}
const subEntries = readdirSync(categoryDir, { withFileTypes: true });
for (const sub of subEntries) {
if (!sub.isDirectory() || sub.name.startsWith(".")) continue;
const subDir = join(categoryDir, sub.name);
// Check if this subcategory actually contains packages
const pkgEntries = readdirSync(subDir, { withFileTypes: true });
const hasPackages = pkgEntries.some(
(e) =>
e.isDirectory() &&
!e.name.startsWith(".") &&
existsSync(join(subDir, e.name, "package.json"))
);
if (!hasPackages) continue;
const subIntro = SUBCATEGORY_INTROS[sub.name];
if (subIntro) {
const didCreate = ensureIntro(
join(subDir, "_intro.md"),
subIntro
);
didCreate ? created++ : skipped++;
}
}
}
console.log(`Created: ${created}`);
console.log(`Skipped (already exist): ${skipped}`);
}
main();