able-baker/checker.tsx

222 lines
6.8 KiB
TypeScript
Raw Normal View History

2023-08-12 20:30:44 -04:00
import { parse as JSONC } from "https://deno.land/x/jsonct@v0.1.0/mod.ts";
type ConfigCheck = {path?:string, text?:string, json?:Record<string, string|Record<string, string|string[]>>};
type ConfigCheckPair = [config:ConfigCheck, imports:ConfigCheck];
export const RootHost = import.meta.resolve("./");
export const Root = new URL(`file://${Deno.cwd().replaceAll("\\", "/")}`).toString();
export async function HuntConfig()
{
2023-09-24 09:19:50 -04:00
console.log("hunting in", Root);
2023-08-12 20:30:44 -04:00
let path:string, resp:Response, text="", json;
try
{
path = "deno.json"
resp = await fetch(Root + "/" + path);
text = await resp.text();
}
catch(e)
{
try
{
path = "deno.jsonc";
resp = await fetch(Root + "/" + path);
text = await resp.text();
}
catch(e)
{
try
{
path = ".vscode/settings.json";
resp = await fetch(Root + "/" + path);
json = await resp.json();
2023-08-13 11:00:48 -04:00
2023-08-12 20:30:44 -04:00
path = json["deno.config"];
json = undefined;
if(path)
{
resp = await fetch(Root + "/" + path);
text = await resp.text();
}
}
catch(e)
{
path = "";
}
}
}
2023-08-13 11:00:48 -04:00
if(path)
2023-08-12 20:30:44 -04:00
{
try
{
json = JSONC(text);
}
catch(e)
{
json = undefined;
}
}
let imports:ConfigCheck = {};
if(json && json.imports)
{
2023-08-13 11:00:48 -04:00
// config.imports
2023-08-12 20:30:44 -04:00
imports.json = json;
imports.text = JSON.stringify(json);
imports.path = path;
}
else if(json && !json.imports && json.importMap)
{
2023-08-13 11:00:48 -04:00
// config.importMap
2023-08-12 20:30:44 -04:00
try
{
imports.path = json.importMap;
resp = await fetch(Root + "/" + imports.path);
imports.text = await resp.text();
2023-08-13 11:00:48 -04:00
try
{
imports.json = JSONC(imports.text);
}
catch(e)
{
imports.json = undefined;
}
2023-08-12 20:30:44 -04:00
}
catch(e)
{
// malformed import map
}
}
return [{path, text, json}, imports] as ConfigCheckPair
}
2023-08-13 11:00:48 -04:00
export async function Install(file:string, overrideName?:string, handler?:(content:string)=>string)
2023-08-12 20:30:44 -04:00
{
const pathFile = RootHost + "install__/" + file;
try{
const check = await Deno.readTextFile(Deno.cwd()+"/"+file);
const replace = confirm(`⚠️🚧 The file "${file}" already exists. Replace it?`);
if(replace)
{
throw("")
}
console.log(`Using pre-existing "${file}" for now.`);
}
catch(e)
{
const resp = await fetch(pathFile);
const text = await resp.text();
2023-08-13 11:00:48 -04:00
const name = overrideName || file;
await Deno.writeTextFile(Deno.cwd()+"/"+name, handler ? handler(text) : text);
2023-08-12 20:30:44 -04:00
}
}
export async function Check()
{
2023-08-28 22:16:56 -04:00
let [config, imports] = await HuntConfig();
2023-08-12 20:30:44 -04:00
try
{
2023-08-28 22:16:56 -04:00
2023-08-13 11:00:48 -04:00
//console.log(config, imports);
2023-08-12 20:30:44 -04:00
if(!config.path)
{
2023-09-24 09:19:50 -04:00
console.log(`🛠️ No Deno configuration found. Creating "deno.json" now.`);
await Deno.writeTextFile(Deno.cwd()+"/deno.json", `{"imports":{}}`);
2023-08-13 11:00:48 -04:00
Check();
return;
}
else if(!config.json)
{
if(confirm(`🚧 Deno configuration is malformed. Replace "${config.path}" with a new one?.`))
2023-08-12 20:30:44 -04:00
{
2023-08-13 11:00:48 -04:00
await Deno.writeTextFile(Deno.cwd()+"/"+config.path, `{"imports":{}}`);
2023-08-12 20:30:44 -04:00
Check();
return;
}
else
{
2023-08-13 11:00:48 -04:00
throw("⛔ Invalid configuration.");
2023-08-12 20:30:44 -04:00
}
}
2023-08-13 11:00:48 -04:00
else if(!imports.json)
{
if(imports.path != config.path)
2023-08-12 20:30:44 -04:00
{
2023-08-13 11:00:48 -04:00
if(confirm(`🚧 External import map "${imports.path}" is missing or malformed. Replace it with defaults?.`))
{
await Deno.writeTextFile(Deno.cwd()+"/"+imports.path, `{"imports":{}}`);
Check();
return;
}
else
{
throw("⛔ Invalid configuration.");
}
2023-08-12 20:30:44 -04:00
}
}
2023-08-13 11:00:48 -04:00
else if(!imports.json?.imports)
{
imports.json.imports = {};
}
2023-08-12 20:30:44 -04:00
2023-08-13 11:00:48 -04:00
if(config.json && imports.json?.imports)
2023-08-12 20:30:44 -04:00
{
const importMap = imports.json.imports as Record<string, string>;
2023-08-13 11:00:48 -04:00
const bake =async(obj:ConfigCheck)=> await Deno.writeTextFile(Deno.cwd()+"/"+obj.path, JSON.stringify(obj.json, null, "\t"));
2023-08-12 20:30:44 -04:00
2023-09-24 09:19:50 -04:00
importMap["react"] = `https://esm.sh/preact@10.17.1/compat`;
importMap["react/"] = `https://esm.sh/preact@10.17.1/compat/`;
importMap["@preact/signals"] = `https://esm.sh/@preact/signals@1.2.1`;
importMap[">able/"] = `${RootHost}`;
if(!importMap[">able/app.tsx"])
2023-08-12 20:30:44 -04:00
{
2023-09-24 09:19:50 -04:00
importMap[">able/app.tsx"] = `./app.tsx`;
await Install("app.tsx");
2023-08-12 20:30:44 -04:00
}
2023-09-24 09:19:50 -04:00
if(!importMap[">able/api.tsx"])
2023-08-12 20:30:44 -04:00
{
2023-09-24 09:19:50 -04:00
if(confirm(`🤔 OPTIONAL: Add backend ">able/api.tsx"?`))
{
importMap[">able/api.tsx"] = "./api.tsx";
await Install("api.tsx");
}
2023-08-12 20:30:44 -04:00
}
2023-08-13 11:00:48 -04:00
2023-08-28 22:16:56 -04:00
const tasks:Record<string, string> = {
"check": `deno run -A --no-lock ${RootHost}cli.tsx check`,
"local": `deno run -A --no-lock ${RootHost}cli.tsx local`,
"debug": `deno run -A --no-lock ${RootHost}cli.tsx debug`,
"serve": `deno run -A --no-lock ${RootHost}cli.tsx serve`,
"cloud": `deno run -A --no-lock ${RootHost}cli.tsx cloud`
};
const confTasks = (config.json.tasks || {}) as Record<string, string>;
2023-09-24 09:19:50 -04:00
config.json.tasks = {...confTasks, ...tasks};
2023-08-28 22:16:56 -04:00
const options =
{
"lib": ["deno.window", "dom", "dom.asynciterable"],
"jsx": "react-jsx",
"jsxImportSource": "react"
}
const compOpts = config.json.compilerOptions as Record<string, string|string[]> || {};
const compLib:string[] = compOpts.lib as string[] || [];
2023-09-24 09:19:50 -04:00
compOpts.jsx = options.jsx;
compOpts.jsxImportSource = options.jsxImportSource;
compOpts.lib = [...compLib, ...options.lib];
config.json.compilerOptions = compOpts;
2023-08-13 11:00:48 -04:00
2023-09-24 09:19:50 -04:00
await bake(imports);
await bake(config);
2023-08-12 20:30:44 -04:00
}
}
catch(e)
{
console.log(e, "\n (Able Exiting...)");
Deno.exit();
}
console.log(`🚗 Good to go!`);
2023-08-28 22:16:56 -04:00
}