Skip to main content

latest
It is unknown whether this package works with Cloudflare Workers, Node.js, Deno, Bun, Browsers
It is unknown whether this package works with Cloudflare Workers
It is unknown whether this package works with Node.js
It is unknown whether this package works with Deno
It is unknown whether this package works with Bun
It is unknown whether this package works with Browsers
JSR Score
29%
Published
3 months ago (0.0.2)
Package root>target.ts
import { 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); } } } }