improved checking and options
This commit is contained in:
parent
b602ffcbcc
commit
783970f2c0
4
app.tsx
4
app.tsx
@ -1 +1,3 @@
|
|||||||
export default ()=>{};
|
export default ()=><div>
|
||||||
|
<h1>App!</h1>
|
||||||
|
</div>;
|
203
checker.tsx
203
checker.tsx
@ -29,6 +29,7 @@ export async function HuntConfig()
|
|||||||
path = ".vscode/settings.json";
|
path = ".vscode/settings.json";
|
||||||
resp = await fetch(Root + "/" + path);
|
resp = await fetch(Root + "/" + path);
|
||||||
json = await resp.json();
|
json = await resp.json();
|
||||||
|
|
||||||
path = json["deno.config"];
|
path = json["deno.config"];
|
||||||
json = undefined;
|
json = undefined;
|
||||||
if(path)
|
if(path)
|
||||||
@ -44,7 +45,7 @@ export async function HuntConfig()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(text)
|
if(path)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -52,7 +53,6 @@ export async function HuntConfig()
|
|||||||
}
|
}
|
||||||
catch(e)
|
catch(e)
|
||||||
{
|
{
|
||||||
// malformed config
|
|
||||||
json = undefined;
|
json = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,18 +60,27 @@ export async function HuntConfig()
|
|||||||
let imports:ConfigCheck = {};
|
let imports:ConfigCheck = {};
|
||||||
if(json && json.imports)
|
if(json && json.imports)
|
||||||
{
|
{
|
||||||
|
// config.imports
|
||||||
imports.json = json;
|
imports.json = json;
|
||||||
imports.text = JSON.stringify(json);
|
imports.text = JSON.stringify(json);
|
||||||
imports.path = path;
|
imports.path = path;
|
||||||
}
|
}
|
||||||
else if(json && !json.imports && json.importMap)
|
else if(json && !json.imports && json.importMap)
|
||||||
{
|
{
|
||||||
|
// config.importMap
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
imports.path = json.importMap;
|
imports.path = json.importMap;
|
||||||
resp = await fetch(Root + "/" + imports.path);
|
resp = await fetch(Root + "/" + imports.path);
|
||||||
imports.text = await resp.text();
|
imports.text = await resp.text();
|
||||||
imports.json = JSONC(text);
|
try
|
||||||
|
{
|
||||||
|
imports.json = JSONC(imports.text);
|
||||||
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
imports.json = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(e)
|
catch(e)
|
||||||
{
|
{
|
||||||
@ -82,7 +91,7 @@ export async function HuntConfig()
|
|||||||
return [{path, text, json}, imports] as ConfigCheckPair
|
return [{path, text, json}, imports] as ConfigCheckPair
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function Install(file:string, handler:(content:string)=>string = (s)=>s)
|
export async function Install(file:string, overrideName?:string, handler?:(content:string)=>string)
|
||||||
{
|
{
|
||||||
const pathFile = RootHost + "install__/" + file;
|
const pathFile = RootHost + "install__/" + file;
|
||||||
|
|
||||||
@ -99,138 +108,167 @@ export async function Install(file:string, handler:(content:string)=>string = (s
|
|||||||
{
|
{
|
||||||
const resp = await fetch(pathFile);
|
const resp = await fetch(pathFile);
|
||||||
const text = await resp.text();
|
const text = await resp.text();
|
||||||
await Deno.writeTextFile(Deno.cwd()+"/"+file, handler(text));
|
const name = overrideName || file;
|
||||||
|
await Deno.writeTextFile(Deno.cwd()+"/"+name, handler ? handler(text) : text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export async function Check()
|
export async function Check()
|
||||||
{
|
{
|
||||||
console.info(`👷 Checking your project`);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
let [config, imports] = await HuntConfig();
|
let [config, imports] = await HuntConfig();
|
||||||
|
//console.log(config, imports);
|
||||||
if(!config.path)
|
if(!config.path)
|
||||||
{
|
{
|
||||||
if(confirm("🚨🚧 No Deno configuration found. Create a new one?"))
|
console.log(`🛠️ No Deno configuration found. Creating "deno.jsonc" now.`);
|
||||||
{
|
await Deno.writeTextFile(Deno.cwd()+"/deno.jsonc", `{"imports":{}}`);
|
||||||
await Install("deno.jsonc");
|
Check();
|
||||||
|
return;
|
||||||
Check();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw("⛔ Configuration is required.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if(!config.json)
|
||||||
else if(!imports.json || !imports.json?.imports)
|
|
||||||
{
|
{
|
||||||
const resp = confirm(`🚨🔧 Configuration found, but has no import map. Fix it now?`);
|
if(confirm(`🚧 Deno configuration is malformed. Replace "${config.path}" with a new one?.`))
|
||||||
if(resp)
|
|
||||||
{
|
{
|
||||||
const text = config.text||"";
|
await Deno.writeTextFile(Deno.cwd()+"/"+config.path, `{"imports":{}}`);
|
||||||
const startBracket = text.indexOf("{");
|
|
||||||
|
|
||||||
config.text = `{
|
|
||||||
"imports": {}${startBracket < 0 ? "\n}\n" : ",\n"}` + text.substring(startBracket+1);
|
|
||||||
|
|
||||||
await Deno.writeTextFile(Deno.cwd()+"/"+config.path, config.text);
|
|
||||||
|
|
||||||
Check();
|
Check();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw("⛔ Import maps are required.");
|
throw("⛔ Invalid configuration.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(!imports.json)
|
||||||
|
{
|
||||||
|
if(imports.path != config.path)
|
||||||
|
{
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(!imports.json?.imports)
|
||||||
|
{
|
||||||
|
imports.json.imports = {};
|
||||||
|
}
|
||||||
|
|
||||||
if(config.json && imports.text && imports.json?.imports)
|
if(config.json && imports.json?.imports)
|
||||||
{
|
{
|
||||||
const importMap = imports.json.imports as Record<string, string>;
|
const importMap = imports.json.imports as Record<string, string>;
|
||||||
let changes = ``;
|
const bake =async(obj:ConfigCheck)=> await Deno.writeTextFile(Deno.cwd()+"/"+obj.path, JSON.stringify(obj.json, null, "\t"));
|
||||||
|
|
||||||
const match = imports.text.search(/(?<=(['"`])imports\1[^{}]*{)/);
|
|
||||||
const part1 = imports.text.substring(0, match);
|
|
||||||
const part2 = imports.text.substring(match);
|
|
||||||
|
|
||||||
const bake =async()=> await Deno.writeTextFile(Deno.cwd()+"/"+config.path, part1 + changes + part2);
|
|
||||||
|
|
||||||
if(!importMap["react"])
|
if(!importMap["react"])
|
||||||
{
|
{
|
||||||
const resp = confirm(`🚨🔧 Import map has no specifier for React ("react"). Fix it now? (Will use Preact compat)`);
|
console.log(`🛠️ Adding React import specifier ("react")`);
|
||||||
if(resp)
|
importMap["react"] = `https://esm.sh/preact@10.16.0/compat`;
|
||||||
{
|
importMap["react/"] = `https://esm.sh/preact@10.16.0/compat/`;
|
||||||
changes += `"react": "https://esm.sh/preact@10.16.0/compat",\n`;
|
await bake(imports);
|
||||||
if(!importMap["react/"])
|
console.log(`🚦 NOTE: Deno will need to cache "react" for intellisense to work properly.`)
|
||||||
{
|
|
||||||
changes += `"react/": "https://esm.sh/preact@10.16.0/compat/",\n`;
|
|
||||||
}
|
|
||||||
await bake();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw(`⛔ A React import ("react") is required.`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(!importMap[">able/"])
|
if(!importMap[">able/"])
|
||||||
{
|
{
|
||||||
const resp = confirm(`🚨🔧 Import map has no specifier for Able (">able/"). Fix it now?`);
|
console.log(`🛠️ Adding Able import specifier (">able/").`);
|
||||||
if(resp)
|
importMap[">able/"] = `${RootHost}`;
|
||||||
{
|
await bake(imports);
|
||||||
changes += `">able/": "${RootHost}",\n`;
|
|
||||||
await bake();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw(`⛔ The Able import (">able/") is required.`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!importMap[">able/app.tsx"])
|
if(!importMap[">able/app.tsx"])
|
||||||
{
|
{
|
||||||
const resp = confirm(`🚨🔧 Import map has no specifier for your starter app (">able/app.tsx"). Fix it now?`);
|
const resp = confirm(`🤔 OPTIONAL: Import map has no specifier for your starter app (">able/app.tsx"). Create one?`);
|
||||||
if(resp)
|
if(resp)
|
||||||
{
|
{
|
||||||
changes += `">able/app.tsx": "./app.tsx",\n`;
|
importMap[">able/app.tsx"] = `./app.tsx`;
|
||||||
await bake();
|
await bake(imports);
|
||||||
await Install("app.tsx");
|
await Install("app.tsx");
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
throw(`⛔ The "starter app" import (">able/app.tsx") is required.`);
|
const app = await import(importMap[">able/app.tsx"]);
|
||||||
|
// @ts-ignore
|
||||||
|
const result = app.default().$$typeof;
|
||||||
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
console.log(e);
|
||||||
|
if(confirm(`🚧 Your starter app ("${importMap[">able/app.tsx"]}") does not export a default function that returns VDOM nodes. Replace it?`))
|
||||||
|
{
|
||||||
|
await Install("app.tsx", importMap[">able/app.tsx"]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw("⛔ Starter app has incorrect export types.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!importMap[">able/api.tsx"])
|
if(!importMap[">able/api.tsx"])
|
||||||
{
|
{
|
||||||
const resp = confirm(`🚨🔧 OPTIONAL: Import map has no specifier for your backend app (">able/api.tsx"). Fix it now?`);
|
const resp = confirm(`🤔 OPTIONAL: Import map has no specifier for your starter backend app (">able/api.tsx"). Create one?`);
|
||||||
if(resp)
|
if(resp)
|
||||||
{
|
{
|
||||||
changes += `">able/api.tsx": "./api.tsx",\n`;
|
importMap[">able/api.tsx"] = "./api.tsx";
|
||||||
await bake();
|
await bake(imports);
|
||||||
await Install("api.tsx");
|
await Install("api.tsx");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
|
||||||
const compOpts = imports.json.compilerOptions as Record<string, string>;
|
|
||||||
if(compOpts)
|
|
||||||
{
|
{
|
||||||
const compJSX = compOpts["jsx"];
|
try
|
||||||
const compJSXImportSource = compOpts["jsxImportSource"]
|
|
||||||
if(compJSX || compJSXImportSource)
|
|
||||||
{
|
{
|
||||||
if(!importMap["react/"])
|
const api = await import(importMap[">able/api.tsx"]);
|
||||||
|
const result = api.default(new Request(new URL("https://fake-deno-testing-domain.com/")));
|
||||||
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
if(confirm(`🚧 Your starter backend app ("${importMap[">able/api.tsx"]}") does not export a default function that accepts a Request. Replace it?`))
|
||||||
{
|
{
|
||||||
//const resp = await Prompt(` ! Import map has no specifier for React ("react"). Add it now? [y/n]`);
|
await Install("api.tsx", importMap[">able/api.tsx"]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw("⛔ Starter backend app has incorrect export types.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const options =
|
||||||
|
{
|
||||||
|
"lib": ["deno.window", "dom", "dom.asynciterable"],
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"jsxImportSource": "react"
|
||||||
|
}
|
||||||
|
|
||||||
|
const compOpts = config.json.compilerOptions as Record<string, string|string[]> || {};
|
||||||
|
const compJSX = compOpts.jsx == options.jsx;
|
||||||
|
const compJSXImportSource = compOpts.jsxImportSource == options.jsxImportSource;
|
||||||
|
const compLib:string[] = compOpts.lib as string[] || [];
|
||||||
|
let compLibHasAll = true;
|
||||||
|
options.lib.forEach(item=> !compLib.includes(item) && (compLibHasAll = false))
|
||||||
|
|
||||||
|
if(!compOpts || !compJSX || !compJSXImportSource || !compLibHasAll)
|
||||||
|
{
|
||||||
|
console.log(`🛠️ Adding values to "compilerOptions" configuration.`);
|
||||||
|
compOpts.jsx = options.jsx;
|
||||||
|
compOpts.jsxImportSource = options.jsxImportSource;
|
||||||
|
compOpts.lib = [...compLib, ...options.lib];
|
||||||
|
config.json.compilerOptions = compOpts;
|
||||||
|
await bake(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(e)
|
catch(e)
|
||||||
@ -242,5 +280,4 @@ export async function Check()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Check();
|
Check();
|
18
deno.jsonc
18
deno.jsonc
@ -1,6 +1,16 @@
|
|||||||
{
|
{
|
||||||
"imports": {},
|
"imports": {
|
||||||
|
"react": "https://esm.sh/preact@10.16.0/compat",
|
||||||
//imports?
|
"react/": "https://esm.sh/preact@10.16.0/compat/",
|
||||||
|
">able/": "file:///C:/Web%20Projects/able-baker/"
|
||||||
|
},
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"jsxImportSource": "react",
|
||||||
|
"lib": [
|
||||||
|
"deno.window",
|
||||||
|
"dom",
|
||||||
|
"dom.asynciterable"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "2",
|
|
||||||
"remote": {
|
|
||||||
"https://deno.land/x/jsonct@v0.1.0/mod.ts": "dba7e7f3529be6369f5c718e3a18b69f15ffa176006d2a7565073ce6c5bd9f3f",
|
|
||||||
"https://deno.land/x/jsonct@v0.1.0/src/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462",
|
|
||||||
"https://deno.land/x/jsonct@v0.1.0/src/parse.ts": "a3a016822446b0584b40bae9098df480db5590a9915c9e3c623ba2801cf1b8df"
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,7 +8,7 @@
|
|||||||
"react":"https://esm.sh/preact@10.15.1/compat",
|
"react":"https://esm.sh/preact@10.15.1/compat",
|
||||||
"react/":"https://esm.sh/preact@10.15.1/compat/",
|
"react/":"https://esm.sh/preact@10.15.1/compat/",
|
||||||
"react-original":"https://esm.sh/preact@10.15.1/compat",
|
"react-original":"https://esm.sh/preact@10.15.1/compat",
|
||||||
">able/": "http://localhost:4507/"
|
|
||||||
},
|
},
|
||||||
"tasks":
|
"tasks":
|
||||||
{
|
{
|
||||||
|
@ -1 +1,3 @@
|
|||||||
export default ()=>{};
|
export default ()=><div>
|
||||||
|
<h1>App!</h1>
|
||||||
|
</div>;
|
Loading…
Reference in New Issue
Block a user