@atri-build/api@0.0.2
latest
It is unknown whether this package works with Cloudflare Workers, Node.js, Deno, Bun, Browsers




JSR Score
29%
Published
3 months ago (0.0.2)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121import { parseArgs } from "jsr:/@std/cli@1/parse-args"; export interface FileMapping { fromTarget: string; fromFile: string; toFile: string; } export interface BuildTarget { name: string; deps?: BuildTarget[]; type: string; mappings?: FileMapping[]; } export function finalizeBuildTargets(targets: BuildTarget[]) { // traverse the targets and resolve the dependencies const targetsSet = new Set<BuildTarget>(); // add all targets and their dependencies to the set for (const target of targets) { resolveDependencies(target, targetsSet); } // flatten the targets const names = new Set<string>(); const flattenedTargets = Array.from(targetsSet).map((target) => { if (names.has(target.name)) { throw new Error( `Target with name ${target.name} defined multiple times` ); } names.add(target.name); return { ...target, deps: target.deps?.map((dep) => { return dep.name; }), }; }); // Check for circular dependencies const inDegree = new Map<string, number>(); const queue: (typeof flattenedTargets)[number][] = []; for (const target of flattenedTargets) { inDegree.set(target.name, 0); } for (const target of flattenedTargets) { if (target.deps) { for (const dep of target.deps) { inDegree.set(dep, inDegree.get(dep)! + 1); } } } for (const target of flattenedTargets) { if (inDegree.get(target.name) === 0) { queue.push(target); } } let count = 0; const order: string[] = []; while (queue.length) { const target = queue.shift()!; order.push(target.name); count++; if (target.deps) { for (const dep of target.deps) { inDegree.set(dep, inDegree.get(dep)! - 1); if (inDegree.get(dep) === 0) { queue.push(flattenedTargets.find((t) => t.name === dep)!); } } } } if (count !== flattenedTargets.length) { throw new Error("Cycle detected in the targets"); } // if generated folder does not exist, create it Deno.mkdirSync("generated", { recursive: true }); // export the targets to generated/build_targets.json Deno.writeTextFileSync( "generated/build_targets.json", JSON.stringify(flattenedTargets) ); } type Props = Record<string, string | boolean>; export function finalizeBuildTargetsWithProps( targetsFn: (p: Props) => BuildTarget[], validator: (p: Props) => boolean | string ) { const props = parseArgs(Deno.args) as Props; const validation = validator(props); if (validation !== true) { if (typeof validation === "string") { throw new Error("Validation failed: " + validation); } else { throw new Error("Validation failed"); } } const targets = targetsFn(props); finalizeBuildTargets(targets); } function resolveDependencies( target: BuildTarget, targetsSet: Set<BuildTarget> ) { // resolve the dependencies of the target targetsSet.add(target); if (target.deps) { for (const dep of target.deps) { if (!targetsSet.has(dep)) { resolveDependencies(dep, targetsSet); } } } }