import { join, relative } from "https://deno.land/std@0.214.0/path/mod.ts";
import type { Manifest } from "$fresh/server.ts";
import { existsSync, walk } from "jsr:@std/fs@^1.0.13";
const infinityImport = (path: string, index: number) => [`import * as $_${index} from "@infinity-beyond/${relative(Deno.cwd(), path)}"`.replace(/\\+/g, '/'), `$_${index}`];
const islandImport = (path: string, index: number) => [`import * as $_${index} from "@islands/${relative(join(Deno.cwd(), '/ui/islands/'), path)}"`.replace(/\\+/g, '/'), `$_${index}`];
const route_file_pattern = /\.tsx?$/;
const buildInfinityManifest = async () => {
const manifest: Manifest = {routes: {}, islands: {}, baseUrl: ''};
const www_path = join(Deno.cwd(), 'ui');
if(!existsSync(www_path)) return { manifest, import_statements: [] };
const import_statements: string[] = [];
const routes_path = join(www_path, '/routes');
if(existsSync(routes_path)) {
for await (const dirEntry of walk(routes_path, { includeDirs: false })) {
if(!route_file_pattern.test(dirEntry.name)) continue;
let relative_path = `/${relative(www_path, dirEntry.path)}`.replace(/\\+/g, '/');
if(relative_path.endsWith('/index')) relative_path = relative_path.replace(/\/index$/, '');
const [import_statement, placeholder] = infinityImport(dirEntry.path, import_statements.length);
import_statements.push(import_statement);
manifest.routes['.'+relative_path] = placeholder as any;
}
}
const islands_path = join(www_path, '/islands');
if(existsSync(islands_path)) {
for await (const dirEntry of walk(islands_path, { includeDirs: false })) {
if(!route_file_pattern.test(dirEntry.name)) continue;
let relative_path = `/${relative(www_path, dirEntry.path)}`.replace(/\\+/g, '/');
if(relative_path.endsWith('/index')) relative_path = relative_path.replace(/\/index$/, '');
const [import_statement, placeholder] = islandImport(dirEntry.path, import_statements.length);
import_statements.push(import_statement);
manifest.islands['.'+relative_path] = placeholder as any;
}
}
return { manifest, import_statements };
}
const { manifest: infinity_manifest, import_statements } = await buildInfinityManifest();
const infinity_manifest_output = JSON.stringify(infinity_manifest, null, 2)
.replace(/"(\$_\d+)"/g, '$1')
.replace(/\"(routes|islands|baseUrl)\"\: /g, "$1: ");
const full_output = `import type { Manifest } from "$fresh/server.ts";
${import_statements.join('\n')}
export const manifest: Manifest = ${infinity_manifest_output}\n`;
const infinity_manifest_path = join(Deno.cwd(), 'dist/manifest.ts');
Deno.writeTextFileSync(infinity_manifest_path, full_output);