From 2d2ba6fa2ba6ca9b78d3df06e0a0cfa4f4b9079c Mon Sep 17 00:00:00 2001 From: Seth Trowbridge Date: Tue, 1 Aug 2023 17:23:19 -0400 Subject: [PATCH] install function --- cli.tsx | 76 ++++++++++++++++++++++++++++++++++++-------- deno.jsonc | 43 +++++++++++++++++++++++++ install__/api.tsx | 4 +++ install__/app.tsx | 1 + install__/deno.jsonc | 4 ++- 5 files changed, 113 insertions(+), 15 deletions(-) create mode 100644 deno.jsonc create mode 100644 install__/api.tsx create mode 100644 install__/app.tsx diff --git a/cli.tsx b/cli.tsx index 7740e3f..2a3c83c 100644 --- a/cli.tsx +++ b/cli.tsx @@ -1,12 +1,14 @@ 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() { let path:string, resp:Response, text="", json; try { path = "deno.json" - resp = await fetch(Root + "/" + path); + resp = await fetch(RootFile + "/" + path); text = await resp.text(); } catch(e) @@ -14,21 +16,21 @@ export async function HuntConfig() try { path = "deno.jsonc"; - resp = await fetch(Root + "/" + path); + resp = await fetch(RootFile + "/" + path); text = await resp.text(); } catch(e) { try { - path = Root+"/.vscode/settings.json" + path = RootFile+"/.vscode/settings.json" resp = await fetch(path); json = await resp.json(); path = json["deno.config"]; json = undefined; if(path) { - resp = await fetch(Root + "/" + path); + resp = await fetch(RootFile + "/" + path); text = await resp.text(); } } @@ -54,6 +56,11 @@ export async function HuntConfig() return {path, text, json}; } +export async function HuntImport() +{ + +} + async function Prompt(question: string):Promise { const buf = new Uint8Array(1024); @@ -92,26 +99,63 @@ export async function SubProcess(args:string[]) 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(); if(!config.path) { + const pathServer = import.meta.resolve("./"); try { - const resp = await Prompt("No Deno configuration found. Create one? [y/n]"); - if(resp == "y") + const resp1 = await Prompt("No Deno configuration found. Create one? [y/n]"); + if(resp1 == "y") { - const pathServer = import.meta.resolve("./"); - const pathConfig = pathServer + "install__/deno.jsonc"; + const resp2 = await Prompt("Do you also want to add starter files? [y/n]"); + 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"; + 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); - const text = await resp.text(); - Deno.writeTextFileSync(Deno.cwd()+"/deno.jsonc", text.replaceAll("{{server}}", pathServer)); + await Install("deno.jsonc", (s)=>s + .replace("{{server}}", RootHost) + .replace("{{app}}", replaceApp) + .replace("{{api}}", replaceApi) + .replace("{{commentApp}}", replaceCommentApp) + .replace("{{commentApi}}", replaceCommentApi) + ); } else { - throw(""); + throw("Config declined."); } } catch(e) @@ -119,5 +163,9 @@ if(!config.path) console.log(e, "(Exiting...)"); Deno.exit(); } +} +else if(config.json) +{ + } console.log(config); \ No newline at end of file diff --git a/deno.jsonc b/deno.jsonc new file mode 100644 index 0000000..ead660c --- /dev/null +++ b/deno.jsonc @@ -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">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"; + ... + +*/ +} \ No newline at end of file diff --git a/install__/api.tsx b/install__/api.tsx new file mode 100644 index 0000000..777ecae --- /dev/null +++ b/install__/api.tsx @@ -0,0 +1,4 @@ +export default (req:Request):Response|false=> +{ + return false; +} \ No newline at end of file diff --git a/install__/app.tsx b/install__/app.tsx new file mode 100644 index 0000000..2308168 --- /dev/null +++ b/install__/app.tsx @@ -0,0 +1 @@ +export default ()=>{}; \ No newline at end of file diff --git a/install__/deno.jsonc b/install__/deno.jsonc index 8dce7ac..de8f769 100644 --- a/install__/deno.jsonc +++ b/install__/deno.jsonc @@ -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/", // (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":