cli #6

Merged
SethTrowbridge merged 11 commits from cli into master 2023-09-24 09:33:29 -04:00
5 changed files with 113 additions and 15 deletions
Showing only changes of commit 2d2ba6fa2b - Show all commits

76
cli.tsx
View File

@ -1,12 +1,14 @@
import { parse as JSONC } from "https://deno.land/x/jsonct@v0.1.0/mod.ts"; import { parse as JSONC } from "https://deno.land/x/jsonct@v0.1.0/mod.ts";
const Root = new URL(`file://${Deno.cwd().replaceAll("\\", "/")}`).toString(); const RootFile = new URL(`file://${Deno.cwd().replaceAll("\\", "/")}`).toString();
const RootHost = import.meta.resolve("./");
export async function HuntConfig() export async function HuntConfig()
{ {
let path:string, resp:Response, text="", json; let path:string, resp:Response, text="", json;
try try
{ {
path = "deno.json" path = "deno.json"
resp = await fetch(Root + "/" + path); resp = await fetch(RootFile + "/" + path);
text = await resp.text(); text = await resp.text();
} }
catch(e) catch(e)
@ -14,21 +16,21 @@ export async function HuntConfig()
try try
{ {
path = "deno.jsonc"; path = "deno.jsonc";
resp = await fetch(Root + "/" + path); resp = await fetch(RootFile + "/" + path);
text = await resp.text(); text = await resp.text();
} }
catch(e) catch(e)
{ {
try try
{ {
path = Root+"/.vscode/settings.json" path = RootFile+"/.vscode/settings.json"
resp = await fetch(path); resp = await fetch(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)
{ {
resp = await fetch(Root + "/" + path); resp = await fetch(RootFile + "/" + path);
text = await resp.text(); text = await resp.text();
} }
} }
@ -54,6 +56,11 @@ export async function HuntConfig()
return {path, text, json}; return {path, text, json};
} }
export async function HuntImport()
{
}
async function Prompt(question: string):Promise<string> async function Prompt(question: string):Promise<string>
{ {
const buf = new Uint8Array(1024); const buf = new Uint8Array(1024);
@ -92,26 +99,63 @@ export async function SubProcess(args:string[])
const status = await child.status; const status = await child.status;
} }
export async function Install(file:string, handler:(content:string)=>string = (s)=>s)
{
const pathFile = RootHost + "install__/" + file;
try{
const check = await Deno.readTextFile(Deno.cwd()+"/"+file);
const replace = await Prompt(`The file "${file}" already exists. Replace it? [y/n]`);
if(replace == "y")
{
throw("")
}
console.log(`Skipping "${file}" for now.`);
}
catch(e)
{
const resp = await fetch(pathFile);
const text = await resp.text();
await Deno.writeTextFile(Deno.cwd()+"/"+file, handler(text));
}
}
const config = await HuntConfig(); const config = await HuntConfig();
if(!config.path) if(!config.path)
{ {
const pathServer = import.meta.resolve("./");
try try
{ {
const resp = await Prompt("No Deno configuration found. Create one? [y/n]"); const resp1 = await Prompt("No Deno configuration found. Create one? [y/n]");
if(resp == "y") if(resp1 == "y")
{ {
const pathServer = import.meta.resolve("./"); const resp2 = await Prompt("Do you also want to add starter files? [y/n]");
const pathConfig = pathServer + "install__/deno.jsonc"; let replaceApp = "./path/to/app.tsx";
let replaceApi = "./path/to/api.tsx";
let replaceCommentApp = "// (required) module with default export ()=>React.JSX.Element";
let replaceCommentApi = "// (optional) module with default export (req:Request, url:URL)=>Promise<Response|false>";
if(resp2 == "y")
{
replaceApp = "./app.tsx";
replaceApi = "./api.tsx";
replaceCommentApp = "";
replaceCommentApi = "";
console.log(pathServer, pathConfig); await Install("app.tsx");
await Install("api.tsx");
}
const resp = await fetch(pathConfig); await Install("deno.jsonc", (s)=>s
const text = await resp.text(); .replace("{{server}}", RootHost)
Deno.writeTextFileSync(Deno.cwd()+"/deno.jsonc", text.replaceAll("{{server}}", pathServer)); .replace("{{app}}", replaceApp)
.replace("{{api}}", replaceApi)
.replace("{{commentApp}}", replaceCommentApp)
.replace("{{commentApi}}", replaceCommentApi)
);
} }
else else
{ {
throw(""); throw("Config declined.");
} }
} }
catch(e) catch(e)
@ -119,5 +163,9 @@ if(!config.path)
console.log(e, "(Exiting...)"); console.log(e, "(Exiting...)");
Deno.exit(); Deno.exit();
} }
}
else if(config.json)
{
} }
console.log(config); console.log(config);

43
deno.jsonc Normal file
View File

@ -0,0 +1,43 @@
{
"imports":
{
"react":"https://esm.sh/preact@10.15.1/compat", // (required) Specifier for 'react'
"react/":"https://esm.sh/preact@10.15.1/compat/", // (conditional) This allows the use of JSX without explicitly importing React into a module. If you choose to remove this (and make importing react required), also remove "jsx" and "jsxImportSource" from "compilerOptions" (below)
">able/": "http://localhost:4507/", // (required) Specifier 'able'. (See note below about "isomorphic proxies")
// (required) module with default export ()=>React.JSX.Element">able/app.tsx": "./path/to/app.tsx",
// (optional) module with default export (req:Request, url:URL)=>Promise<Response|false>">able/api.tsx": "./path/to/api.tsx"
},
"tasks":
{
"local": "deno run -A --reload=http://localhost:4507 --no-lock ./run-local.tsx --port=1234",
"serve": "deno run -A --reload=http://localhost:4507 --no-lock ./run-serve.tsx --port=1234",
"cloud": "deno run -A --reload=http://localhost:4507 --no-lock ./run-deploy.tsx",
"debug": "deno run -A --reload=http://localhost:4507 --no-lock --inspect-wait ./run-serve.tsx --port=1234"
},
"compilerOptions":
{
"lib": ["deno.window", "dom"], // makes the Deno Language Server OK with browser-specific code
"jsx": "react-jsx", // see "react/" import above
"jsxImportSource": "react" // ^
}
/*
Imports prefixed with ">" are "isomorphic proxies."
In addition to functioning normally as bare module specifiers for Deno, **these imports are added as routes when the server starts**.
Assuming the specifier points to remotely a hosted directory containing typescript files, requests to your running Able server on these proxy routes are actually fetched from the remote, then transpiled (and cached), then send back as a response.
For example, after the Able server starts, if it sees a web request to '/>able/iso-elements.tsx' it would actually return a browser-friendly transpiled copy of what was on the remote.
Conversely, if the Deno Language Server were to see: `import * as Iso from ">able/iso-elements.tsx";` in one of your modules,
that will be resolved normally with the import map and Deno will just receive the tsx file as-is from the remote, typings and all, so intellisense will work in your IDE.
While ">able/" is a required "import proxy" to pull in Able source code, you are free to use this convention to also add your own proxies as you see fit.
E.g. adding this record to imports:
">your-import/": "https://raw.githubusercontent.com/your-name/your-lib/master/"
will give both Deno and browsers running your Able project everything they need
import CoolComponent from ">your-import/cc.tsx";
...
*/
}

4
install__/api.tsx Normal file
View File

@ -0,0 +1,4 @@
export default (req:Request):Response|false=>
{
return false;
}

1
install__/app.tsx Normal file
View File

@ -0,0 +1 @@
export default ()=>{};

View File

@ -3,7 +3,9 @@
{ {
"react":"https://esm.sh/preact@10.15.1/compat", // (required) Specifier for 'react' "react":"https://esm.sh/preact@10.15.1/compat", // (required) Specifier for 'react'
"react/":"https://esm.sh/preact@10.15.1/compat/", // (conditional) This allows the use of JSX without explicitly importing React into a module. If you choose to remove this (and make importing react required), also remove "jsx" and "jsxImportSource" from "compilerOptions" (below) "react/":"https://esm.sh/preact@10.15.1/compat/", // (conditional) This allows the use of JSX without explicitly importing React into a module. If you choose to remove this (and make importing react required), also remove "jsx" and "jsxImportSource" from "compilerOptions" (below)
">able/": "{{server}}" // (required) Specifier 'able'. (See note below about "isomorphic proxies") ">able/": "{{server}}", // (required) Specifier 'able'. (See note below about "isomorphic proxies")
{{commentApp}}">able/app.tsx": "{{app}}",
{{commentApi}}">able/api.tsx": "{{api}}"
}, },
"tasks": "tasks":