{"version":3,"file":"main.mjs","names":[],"sources":["../src/LinkCli.ts","../src/main.ts"],"sourcesContent":["import path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { resolve } from \"import-meta-resolve\";\nimport {\n  astToString,\n  link,\n  log,\n  RecordResolver,\n  scopeToString,\n  type WeslBundle,\n} from \"wesl/core\";\nimport {\n  dependencyBundles,\n  loadModules,\n  versionFromPackageJson,\n} from \"wesl-tooling\";\nimport yargs from \"yargs\";\n\ntype CliArgs = Awaited<ReturnType<typeof parseArgs>>;\n\nexport async function cli(rawArgs: string[]): Promise<void> {\n  const argv = await parseArgs(rawArgs);\n  await linkNormally(argv);\n}\n\nasync function parseArgs(args: string[]) {\n  const toolDir = new URL(\"..\", import.meta.url).href;\n  const appVersion = await versionFromPackageJson(toolDir);\n  return yargs(args)\n    .version(appVersion)\n    .command(\"$0 [module]\", false, yargs => {\n      yargs.positional(\"module\", {\n        type: \"string\",\n        describe:\n          \"root module to link. Use :: for package references (lygia::utils), / for current package (utils/foo)\",\n      });\n    })\n    .option(\"src\", {\n      type: \"string\",\n      describe:\n        \"WGSL/WESL files to bundle in the package (glob syntax, defaults to wesl.toml or shaders/**/*.w[eg]sl)\",\n    })\n    .option(\"rootModule\", {\n      type: \"string\",\n      default: \"main\",\n      describe: \"start linking from this module name\",\n    })\n    .option(\"conditions\", {\n      type: \"array\",\n      describe: \"settings for conditional compilation\",\n    })\n    .option(\"baseDir\", {\n      requiresArg: true,\n      type: \"string\",\n      describe: \"root directory for shaders (defaults to wesl.toml or shaders)\",\n    })\n    .option(\"projectDir\", {\n      requiresArg: true,\n      type: \"string\",\n      default: \".\",\n      describe: \"directory containing package.json\",\n    })\n    .option(\"details\", {\n      type: \"boolean\",\n      default: false,\n      hidden: true,\n      describe: \"show details about parsed files\",\n    })\n    .option(\"emit\", {\n      type: \"boolean\",\n      default: true,\n      hidden: true,\n      describe: \"emit linked result\",\n    })\n    .help()\n    .parse();\n}\n\nasync function linkNormally(argv: CliArgs): Promise<void> {\n  const { baseDir, projectDir, module, rootModule } = argv;\n  const weslSrc = await loadModules(projectDir, baseDir, argv.src);\n  const projectDirAbs = path.resolve(projectDir);\n  const libs = await dependencyBundles(weslSrc, projectDirAbs);\n\n  const conditionEntries = argv.conditions?.map(c => [c, true]) || [];\n  const conditions = Object.fromEntries(conditionEntries);\n\n  // Use positional module argument if provided, otherwise use --rootModule option (default \"main\")\n  const rootModuleName = (module || rootModule || \"main\") as string;\n  const rootLib = await rootModuleLib(rootModuleName, projectDir, libs);\n  if (rootLib) libs.push(rootLib);\n\n  if (argv.emit) {\n    const linked = await link({ weslSrc, rootModuleName, libs, conditions });\n    log(linked.dest);\n  }\n\n  if (argv.details) {\n    const resolver = new RecordResolver(weslSrc);\n    for (const [modulePath, ast] of resolver.allModules()) {\n      log(`---\\n${modulePath}`);\n      log(`\\n->ast`);\n      log(astToString(ast.moduleElem));\n      log(`\\n->scope`);\n      log(scopeToString(ast.rootScope));\n      log();\n    }\n  }\n}\n\n/** load the weslbundle containing the root module (if we haven't already loaded it) */\nasync function rootModuleLib(\n  rootModuleName: string,\n  projectDir: string,\n  libs: WeslBundle[],\n): Promise<WeslBundle | undefined> {\n  // Check if root module is from a dependency (contains :: and doesn't start with \"package\")\n  if (rootModuleName.includes(\"::\")) {\n    const packageName = rootModuleName.split(\"::\")[0];\n    if (packageName !== \"package\") {\n      const alreadyLoaded = libs.some(lib => lib.name === packageName);\n      if (!alreadyLoaded) {\n        const depBundle = await loadWeslBundle(packageName, projectDir);\n        if (depBundle) {\n          return depBundle;\n        }\n      }\n    }\n  }\n}\n\n/**\n * Load a specific dependency wesl bundle by package name.\n *\n * @param packageName npm package name (e.g., \"random_wgsl\" or \"foo/bar\")\n * @param projectDir directory containing package.json\n */\nasync function loadWeslBundle(\n  packageName: string,\n  projectDir: string,\n): Promise<WeslBundle | undefined> {\n  const projectDirAbs = path.resolve(path.join(projectDir, \"dummy.js\"));\n  const projectURL = pathToFileURL(projectDirAbs).href;\n\n  try {\n    const url = resolve(packageName, projectURL);\n    const module = await import(url);\n    return module.default;\n  } catch {\n    return undefined;\n  }\n}\n","#!/usr/bin/env node\nimport { hideBin } from \"yargs/helpers\";\nimport { cli } from \"./LinkCli.ts\";\n\nconst rawArgs = hideBin(process.argv);\n\ncli(rawArgs);\n"],"mappings":";;;;;;;;;AAoBA,eAAsB,IAAI,SAAkC;AAE1D,OAAM,aADO,MAAM,UAAU,QAAQ,CACb;;AAG1B,eAAe,UAAU,MAAgB;CACvC,MAAM,UAAU,IAAI,IAAI,MAAM,OAAO,KAAK,IAAI,CAAC;CAC/C,MAAM,aAAa,MAAM,uBAAuB,QAAQ;AACxD,QAAO,MAAM,KAAK,CACf,QAAQ,WAAW,CACnB,QAAQ,eAAe,QAAO,UAAS;AACtC,QAAM,WAAW,UAAU;GACzB,MAAM;GACN,UACE;GACH,CAAC;GACF,CACD,OAAO,OAAO;EACb,MAAM;EACN,UACE;EACH,CAAC,CACD,OAAO,cAAc;EACpB,MAAM;EACN,SAAS;EACT,UAAU;EACX,CAAC,CACD,OAAO,cAAc;EACpB,MAAM;EACN,UAAU;EACX,CAAC,CACD,OAAO,WAAW;EACjB,aAAa;EACb,MAAM;EACN,UAAU;EACX,CAAC,CACD,OAAO,cAAc;EACpB,aAAa;EACb,MAAM;EACN,SAAS;EACT,UAAU;EACX,CAAC,CACD,OAAO,WAAW;EACjB,MAAM;EACN,SAAS;EACT,QAAQ;EACR,UAAU;EACX,CAAC,CACD,OAAO,QAAQ;EACd,MAAM;EACN,SAAS;EACT,QAAQ;EACR,UAAU;EACX,CAAC,CACD,MAAM,CACN,OAAO;;AAGZ,eAAe,aAAa,MAA8B;CACxD,MAAM,EAAE,SAAS,YAAY,QAAQ,eAAe;CACpD,MAAM,UAAU,MAAM,YAAY,YAAY,SAAS,KAAK,IAAI;CAEhE,MAAM,OAAO,MAAM,kBAAkB,SADf,KAAK,QAAQ,WAAW,CACc;CAE5D,MAAM,mBAAmB,KAAK,YAAY,KAAI,MAAK,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE;CACnE,MAAM,aAAa,OAAO,YAAY,iBAAiB;CAGvD,MAAM,iBAAkB,UAAU,cAAc;CAChD,MAAM,UAAU,MAAM,cAAc,gBAAgB,YAAY,KAAK;AACrE,KAAI,QAAS,MAAK,KAAK,QAAQ;AAE/B,KAAI,KAAK,KAEP,MADe,MAAM,KAAK;EAAE;EAAS;EAAgB;EAAM;EAAY,CAAC,EAC7D,KAAK;AAGlB,KAAI,KAAK,SAAS;EAChB,MAAM,WAAW,IAAI,eAAe,QAAQ;AAC5C,OAAK,MAAM,CAAC,YAAY,QAAQ,SAAS,YAAY,EAAE;AACrD,OAAI,QAAQ,aAAa;AACzB,OAAI,UAAU;AACd,OAAI,YAAY,IAAI,WAAW,CAAC;AAChC,OAAI,YAAY;AAChB,OAAI,cAAc,IAAI,UAAU,CAAC;AACjC,QAAK;;;;;AAMX,eAAe,cACb,gBACA,YACA,MACiC;AAEjC,KAAI,eAAe,SAAS,KAAK,EAAE;EACjC,MAAM,cAAc,eAAe,MAAM,KAAK,CAAC;AAC/C,MAAI,gBAAgB;OAEd,CADkB,KAAK,MAAK,QAAO,IAAI,SAAS,YAAY,EAC5C;IAClB,MAAM,YAAY,MAAM,eAAe,aAAa,WAAW;AAC/D,QAAI,UACF,QAAO;;;;;;;;;;;AAajB,eAAe,eACb,aACA,YACiC;CAEjC,MAAM,aAAa,cADG,KAAK,QAAQ,KAAK,KAAK,YAAY,WAAW,CAAC,CACtB,CAAC;AAEhD,KAAI;AAGF,UADe,MAAM,OADT,QAAQ,aAAa,WAAW,GAE9B;SACR;AACN;;;;;AC/IJ,IAFgB,QAAQ,QAAQ,KAAK,CAEzB"}