import { join } from "path"; import { $, cd } from "zx"; import { existsSync } from "node:fs"; import { readdir } from "node:fs/promises"; import { getTxzName, pluginName, startingDir } from "./utils/consts"; import { setupTxzEnv, TxzEnv } from "./cli/setup-txz-environment"; import { cleanupTxzFiles } from "./utils/cleanup"; import { apiDir } from "./utils/paths"; // Recursively search for manifest files const findManifestFiles = async (dir: string): Promise => { try { const entries = await readdir(dir, { withFileTypes: true }); const files: string[] = []; for (const entry of entries) { const fullPath = join(dir, entry.name); if (entry.isDirectory()) { try { files.push(...(await findManifestFiles(fullPath))); } catch (error) { // Log and continue if a subdirectory can't be read console.warn(`Warning: Could not read directory ${fullPath}: ${error.message}`); } } else if ( entry.isFile() && (entry.name === "manifest.json" || entry.name === "ui.manifest.json") ) { files.push(entry.name); } } return files; } catch (error) { if (error.code === 'ENOENT') { console.warn(`Directory does not exist: ${dir}`); return []; } throw error; // Re-throw other errors } }; const validateSourceDir = async (validatedEnv: TxzEnv) => { if (!validatedEnv.ci) { console.log("Validating TXZ source directory"); } const sourceDir = join(startingDir, "source"); if (!existsSync(sourceDir)) { throw new Error(`Source directory ${sourceDir} does not exist`); } // Validate existence of webcomponent files: // source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components const webcomponentDir = join( sourceDir, "dynamix.unraid.net", "usr", "local", "emhttp", "plugins", "dynamix.my.servers", "unraid-components" ); if (!existsSync(webcomponentDir)) { throw new Error(`Webcomponent directory ${webcomponentDir} does not exist`); } const manifestFiles = await findManifestFiles(webcomponentDir); const hasManifest = manifestFiles.includes("manifest.json"); const hasUiManifest = manifestFiles.includes("ui.manifest.json"); if (!hasManifest || !hasUiManifest) { console.log("Existing Manifest Files:", manifestFiles); throw new Error( `Webcomponents must contain both "ui.manifest.json" and "manifest.json" - be sure to have run pnpm build:wc in unraid-ui` ); } if (!existsSync(apiDir)) { throw new Error(`API directory ${apiDir} does not exist`); } const packageJson = join(apiDir, "package.json"); if (!existsSync(packageJson)) { throw new Error(`API package.json file ${packageJson} does not exist`); } // Now CHMOD the api/dist directory files to allow execution await $`chmod +x ${apiDir}/dist/*.js`; }; const buildTxz = async (validatedEnv: TxzEnv) => { await validateSourceDir(validatedEnv); const txzPath = join(validatedEnv.txzOutputDir, getTxzName()); // Create package - must be run from within the pre-pack directory // Use cd option to run command from prePackDir await cd(join(startingDir, "source", pluginName)); $.verbose = true; await $`${join(startingDir, "scripts/makepkg")} --chown y --compress -${ validatedEnv.compress } --linkadd y ${txzPath}`; $.verbose = false; await cd(startingDir); }; const main = async () => { try { const validatedEnv = await setupTxzEnv(process.argv); await cleanupTxzFiles(); await buildTxz(validatedEnv); } catch (error) { console.error(error); process.exit(1); } }; await main();