diff --git a/Build/build-public.ts b/Build/build-public.ts index d0e09569..62edf604 100644 --- a/Build/build-public.ts +++ b/Build/build-public.ts @@ -6,8 +6,9 @@ import { task } from './trace'; import { treeDir, TreeFileType } from './lib/tree-dir'; import type { TreeType, TreeTypeArray } from './lib/tree-dir'; -import { OUTPUT_MOCK_DIR, OUTPUT_MODULES_DIR, OUTPUT_MODULES_RULES_DIR, PUBLIC_DIR, ROOT_DIR } from './constants/dir'; +import { OUTPUT_MOCK_DIR, OUTPUT_MODULES_RULES_DIR, PUBLIC_DIR, ROOT_DIR } from './constants/dir'; import { fastStringCompare, mkdirp, writeFile } from './lib/misc'; +import type { VoidOrVoidArray } from './lib/misc'; import picocolors from 'picocolors'; import { tagged as html } from 'foxts/tagged'; import { compareAndWriteFile } from './lib/create-file'; @@ -15,9 +16,7 @@ import { compareAndWriteFile } from './lib/create-file'; const mockDir = path.join(ROOT_DIR, 'Mock'); const modulesDir = path.join(ROOT_DIR, 'Modules'); -async function copyDirContents(srcDir: string, destDir: string) { - const promises: Array> = []; - +async function copyDirContents(srcDir: string, destDir: string, promises: Array> = []): Promise>> { for await (const entry of await fsp.opendir(srcDir)) { const src = path.join(srcDir, entry.name); const dest = path.join(destDir, entry.name); @@ -28,21 +27,27 @@ async function copyDirContents(srcDir: string, destDir: string) { } } - return Promise.all(promises); + return promises; } export const buildPublic = task(require.main === module, __filename)(async (span) => { await span.traceChildAsync('copy rest of the files', async () => { - await Promise.all([ - // mkdirp(OUTPUT_MODULES_DIR), - mkdirp(OUTPUT_MODULES_RULES_DIR), - mkdirp(OUTPUT_MOCK_DIR) - ]); + const p: Array> = []; - await Promise.all([ - copyDirContents(modulesDir, OUTPUT_MODULES_DIR), - copyDirContents(mockDir, OUTPUT_MOCK_DIR) - ]); + let pt = mkdirp(OUTPUT_MODULES_RULES_DIR); + if (pt) { + p.push(pt.then(() => { copyDirContents(modulesDir, OUTPUT_MODULES_RULES_DIR, p); })); + } else { + p.push(copyDirContents(modulesDir, OUTPUT_MODULES_RULES_DIR, p)); + } + pt = mkdirp(OUTPUT_MOCK_DIR); + if (pt) { + p.push(pt.then(() => { copyDirContents(mockDir, OUTPUT_MOCK_DIR, p); })); + } else { + p.push(copyDirContents(mockDir, OUTPUT_MOCK_DIR, p)); + } + + await Promise.all(p); }); const html = await span @@ -108,7 +113,7 @@ const priorityOrder: Record<'default' | string & {}, number> = { }; const prioritySorter = (a: TreeType, b: TreeType) => ((priorityOrder[a.name] || priorityOrder.default) - (priorityOrder[b.name] || priorityOrder.default)) || fastStringCompare(a.name, b.name); -function walk(tree: TreeTypeArray) { +function treeHtml(tree: TreeTypeArray) { let result = ''; tree.sort(prioritySorter); for (let i = 0, len = tree.length; i < len; i++) { @@ -117,9 +122,7 @@ function walk(tree: TreeTypeArray) { result += html`
  • ${entry.name} -
      - ${walk(entry.children)} -
    +
      ${treeHtml(entry.children)}
  • `; } else if (/* entry.type === 'file' && */ entry.name !== 'index.html') { @@ -132,29 +135,29 @@ function walk(tree: TreeTypeArray) { function generateHtml(tree: TreeTypeArray) { return html` - + - - - Surge Ruleset Server | Sukka (@SukkaW) - - - - - - - + + + Surge Ruleset Server | Sukka (@SukkaW) + + + + + + + - + - - - - - - - - + + + + + + + +

    Sukka Ruleset Server

    @@ -163,9 +166,7 @@ function generateHtml(tree: TreeTypeArray) {

    Last Build: ${new Date().toISOString()}


    -
      - ${walk(tree)} -
    +
      ${treeHtml(tree)}
    diff --git a/Build/lib/misc.ts b/Build/lib/misc.ts index b9977665..93196212 100644 --- a/Build/lib/misc.ts +++ b/Build/lib/misc.ts @@ -32,6 +32,8 @@ interface Write { ): Promise } +export type VoidOrVoidArray = void | VoidOrVoidArray[]; + export function mkdirp(dir: string) { if (fs.existsSync(dir)) { return; diff --git a/Build/lib/tree-dir.ts b/Build/lib/tree-dir.ts index 3e24928e..848cc41a 100644 --- a/Build/lib/tree-dir.ts +++ b/Build/lib/tree-dir.ts @@ -1,5 +1,6 @@ import fsp from 'node:fs/promises'; import { sep } from 'node:path'; +import type { VoidOrVoidArray } from './misc'; // eslint-disable-next-line sukka/no-export-const-enum -- TODO: fix this in the future export const enum TreeFileType { @@ -23,13 +24,12 @@ interface TreeDirectoryType { export type TreeType = TreeDirectoryType | TreeFile; export type TreeTypeArray = TreeType[]; -type VoidOrVoidArray = void | VoidOrVoidArray[]; - export async function treeDir(rootPath: string): Promise { const tree: TreeTypeArray = []; + const promises: Array> = []; + const walk = async (dir: string, node: TreeTypeArray, dirRelativeToRoot = ''): Promise => { - const promises: Array> = []; for await (const child of await fsp.opendir(dir)) { // Ignore hidden files if (child.name[0] === '.' || child.name === 'CNAME') { @@ -60,10 +60,10 @@ export async function treeDir(rootPath: string): Promise { continue; } } - return Promise.all(promises); }; await walk(rootPath, tree); + await Promise.all(promises); return tree; }