Compare commits
	
		
			6 Commits
		
	
	
		
			master
			...
			full-stack
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 91542c30a5 | |||
| 9d31b9a08c | |||
| bef45f9107 | |||
| 9fbd811101 | |||
| 8d89cebe12 | |||
| f0c34f461e | 
							
								
								
									
										28
									
								
								.github/workflows/deploy.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								.github/workflows/deploy.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| name: Deploy to GitHub Pages | ||||
| 
 | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|       - master | ||||
| 
 | ||||
| jobs: | ||||
|   deploy: | ||||
|     runs-on: ubuntu-latest | ||||
| 
 | ||||
|     steps: | ||||
|       - name: Checkout Repository | ||||
|         uses: actions/checkout@v2 | ||||
| 
 | ||||
|       - name: Setup Deno | ||||
|         uses: denolib/setup-deno@v2 | ||||
|         with: | ||||
|           deno-version: 1.8 | ||||
| 
 | ||||
|       - name: Run Deno Script | ||||
|         run: deno run -A --no-lock cli.tsx baker | ||||
| 
 | ||||
|       - name: Deploy to GitHub Pages | ||||
|         uses: peaceiris/actions-gh-pages@v3 | ||||
|         with: | ||||
|           github_token: ${{ secrets.GITHUB_TOKEN }} | ||||
|           publish_dir: ./.bake | ||||
| @ -1,2 +1 @@ | ||||
| deno.lock | ||||
| .env | ||||
							
								
								
									
										7
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							| @ -5,7 +5,7 @@ | ||||
|     "version": "0.2.0", | ||||
|     "configurations": [ | ||||
|         { | ||||
|             "name": "Debug Serve Mode", | ||||
|             "name": "Host Process", | ||||
|             "request": "launch", | ||||
|             "type": "node", | ||||
|             "runtimeExecutable": "deno", | ||||
| @ -13,9 +13,10 @@ | ||||
|             "attachSimplePort": 9229 | ||||
|         }, | ||||
|         { | ||||
|             "name":"Attach", | ||||
|             "name": "Subprocess", | ||||
|             "request": "attach", | ||||
|             "type": "node" | ||||
|             "type": "node", | ||||
|             "port": 9230 | ||||
|         } | ||||
|     ] | ||||
| } | ||||
							
								
								
									
										6
									
								
								app.tsx
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								app.tsx
									
									
									
									
									
								
							| @ -1,7 +1,3 @@ | ||||
| import * as ISO from ">able/iso-elements.tsx"; | ||||
| 
 | ||||
| console.log(ISO) | ||||
| 
 | ||||
| export default ()=><div> | ||||
|     <h1 class="p-4 bg-red-500 text-white">App</h1> | ||||
|     <h1>App!</h1> | ||||
| </div>; | ||||
							
								
								
									
										14
									
								
								checker.tsx
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								checker.tsx
									
									
									
									
									
								
							| @ -3,7 +3,9 @@ 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]; | ||||
| 
 | ||||
| /** The full url location of checker.tsx wherever it is hosted */ | ||||
| export const RootHost = import.meta.resolve("./"); | ||||
| /** The file system url where deno is currently running */ | ||||
| export const Root = new URL(`file://${Deno.cwd().replaceAll("\\", "/")}`).toString(); | ||||
| export async function HuntConfig() | ||||
| { | ||||
| @ -58,7 +60,7 @@ export async function HuntConfig() | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let imports:ConfigCheck = {}; | ||||
|     const imports:ConfigCheck = {}; | ||||
|     if(json && json.imports) | ||||
|     { | ||||
|         // config.imports
 | ||||
| @ -116,7 +118,7 @@ export async function Install(file:string, overrideName?:string, handler?:(conte | ||||
| 
 | ||||
| export async function Check() | ||||
| { | ||||
|     let [config, imports] = await HuntConfig(); | ||||
|     const [config, imports] = await HuntConfig(); | ||||
|     try | ||||
|     { | ||||
|          | ||||
| @ -169,8 +171,8 @@ export async function Check() | ||||
| 
 | ||||
|             importMap["react"] = `https://esm.sh/preact@10.20.2/compat`; | ||||
|             importMap["react/"] = `https://esm.sh/preact@10.20.2/compat/`; | ||||
|             importMap["@preact/signals"] = `https://esm.sh/@preact/signals@1.2.3?deps=preact@10.20.2`; | ||||
|             importMap["@twind/core"] = `https://esm.sh/v126/@twind/core@1.1.3/es2022/core.mjs`; | ||||
|             importMap["@preact/signals"] = `https://esm.sh/@preact/signals@1.2.3`; | ||||
|             importMap["@twind/core"] = `https://esm.sh/@twind/core@1.1.3`; | ||||
|             importMap[">able/"] = `${RootHost}`; | ||||
|             if(!importMap[">able/app.tsx"]) | ||||
|             { | ||||
| @ -199,7 +201,8 @@ export async function Check() | ||||
|             const optionsRequired =  | ||||
|             { | ||||
|                 "lib": ["deno.window", "dom", "dom.iterable", "dom.asynciterable"], | ||||
|                 "jsx": "react-jsx" | ||||
|                 "jsx": "react-jsx", | ||||
|                 "jsxImportSource": "react" | ||||
|             } | ||||
|             const optionsCurrent = config.json.compilerOptions as Record<string, string|string[]> || {}; | ||||
|             //const compLib:string[] = compOpts.lib as string[] || [];
 | ||||
| @ -217,6 +220,7 @@ export async function Check() | ||||
|             }); | ||||
| 
 | ||||
|             optionsCurrent.jsx = optionsRequired.jsx; | ||||
|             optionsCurrent.jsxImportSource = optionsRequired.jsxImportSource; | ||||
|             config.json.compilerOptions = optionsCurrent; | ||||
| 
 | ||||
|             await bake(imports); | ||||
|  | ||||
							
								
								
									
										28
									
								
								cli.tsx
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								cli.tsx
									
									
									
									
									
								
							| @ -4,7 +4,7 @@ import { RootHost, HuntConfig, Install, Check } from "./checker.tsx"; | ||||
| 
 | ||||
| let arg = await Arg.parse(Deno.args); | ||||
| let env = await Env.load(); | ||||
| const collect =async(inKey:string, inArg:Record<string, string>, inEnv:Record<string, string>):Promise<string|undefined>=> | ||||
| const collect =(inKey:string, inArg:Record<string, string>, inEnv:Record<string, string>):string|undefined=> | ||||
| { | ||||
|     const scanArg = inArg[inKey]; | ||||
|     const scanEnvFile = inEnv[inKey]; | ||||
| @ -87,13 +87,12 @@ if(arg._.length) | ||||
|         } | ||||
|         case "debug" : | ||||
|         { | ||||
|             await SubProcess(["run", `-A`, `--no-lock`, `--config=${config.path}`, `--inspect-brk`, RootHost+"run.tsx", "--dev", ...Deno.args]); | ||||
|             await SubProcess(["run", `-A`, `--no-lock`, `--config=${config.path}`, `--inspect-wait=127.0.0.1:9230`, RootHost+"run.tsx", "--dev", ...Deno.args]); | ||||
|             break; | ||||
|         } | ||||
|         case "serve" : | ||||
|         { | ||||
|             const args = ["run", `-A`, `--no-lock`, `--config=${config.path}`, RootHost+"run.tsx", ...Deno.args]; | ||||
|             console.log("args are", args); | ||||
|             await SubProcess(args); | ||||
|             break; | ||||
|         } | ||||
| @ -102,15 +101,12 @@ if(arg._.length) | ||||
|             const useToken = await collect("DENO_DEPLOY_TOKEN", arg, env); | ||||
|             const useProject = await collect("DENO_DEPLOY_PROJECT", arg, env); | ||||
|              | ||||
|             let scanProd:string[]|string|null = prompt(`Do you want to deploy to *production*?`); | ||||
|             let scanProd = confirm(`Do you want to deploy to *production*?`); | ||||
|             let argProd:string[] = []; | ||||
|             if(scanProd) | ||||
|             { | ||||
|                 scanProd = prompt(`Are you sure? This will update the live project at "${useProject}"`); | ||||
|                 scanProd = scanProd ? ["--prod"] : []; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 scanProd = []; | ||||
|                 scanProd = confirm(`Are you sure? This will update the live project at "${useProject}"`); | ||||
|                 argProd = scanProd ? ["--prod"] : []; | ||||
|             } | ||||
| 
 | ||||
|             const command = [ | ||||
| @ -118,19 +114,25 @@ if(arg._.length) | ||||
|                 "-A", | ||||
|                 "--no-lock", | ||||
|                 `--config=${config.path}`, | ||||
|                 "https://deno.land/x/deploy@1.12.0/deployctl.ts", | ||||
|                 "https://deno.land/x/deploy/deployctl.ts", | ||||
|                 "deploy", | ||||
|                 `--project=${useProject}`, | ||||
|                 `--token=${useToken}`, | ||||
|                 `--import-map=${imports.path}`, | ||||
|                 `--exclude=.*`, | ||||
|                 ...scanProd, | ||||
|                 `--exclude=.*,.*/,`, | ||||
|                 ...argProd, | ||||
|                 RootHost+"run.tsx"]; | ||||
| 
 | ||||
|             await SubProcess(command); | ||||
| 
 | ||||
|             break; | ||||
|         } | ||||
|         case "baker" : | ||||
|         { | ||||
|             const args = ["run", `-A`, `--no-lock`, `--config=${config.path}`, RootHost+"run-baker.tsx", ...Deno.args]; | ||||
|             await SubProcess(args); | ||||
|             break; | ||||
|         } | ||||
|         case "upgrade" : | ||||
|         { | ||||
|             await SubProcess(["install", `-A`, `-r`, `-f`, `--no-lock`, `--config=${config.path}`, RootHost+"cli.tsx", ...Deno.args]); | ||||
|  | ||||
							
								
								
									
										26
									
								
								deno.jsonc
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								deno.jsonc
									
									
									
									
									
								
							| @ -1,28 +1,30 @@ | ||||
| { | ||||
| 	"imports": { | ||||
| 
 | ||||
| 		"react": "https://esm.sh/preact@10.20.2/compat", | ||||
| 		"react-original": "https://esm.sh/preact@10.20.2/compat", | ||||
| 		"react-original/": "https://esm.sh/preact@10.20.2/compat/", | ||||
| 		"react/": "https://esm.sh/preact@10.20.2/compat/", | ||||
| 		"@preact/signals": "https://esm.sh/@preact/signals@1.2.3?deps=preact@10.20.2", | ||||
| 		"signals-original": "https://esm.sh/@preact/signals@1.2.3?deps=preact@10.20.2", | ||||
| 		"@twind/core": "https://esm.sh/v126/@twind/core@1.1.3/es2022/core.mjs", | ||||
| 
 | ||||
| 		">other/": "https://esm.sh/", | ||||
| 		"react": "https://esm.sh/preact@10.18.1/compat", | ||||
| 		"react-original": "https://esm.sh/preact@10.18.1/compat", | ||||
| 		"react/": "https://esm.sh/preact@10.18.1/compat/", | ||||
| 		"@preact/signals": "https://esm.sh/@preact/signals@1.2.1", | ||||
| 		"signals-original": "https://esm.sh/@preact/signals@1.2.1", | ||||
| 		"@twind/core": "https://esm.sh/@twind/core@1.1.3", | ||||
| 		">able/": "./", | ||||
| 		">able/app.tsx": "./app.tsx" | ||||
| 	}, | ||||
| 	"tasks": { | ||||
| 		"check": "deno run -A --no-lock ./cli.tsx check", | ||||
| 		"local": "deno run -A --no-lock ./cli.tsx local", | ||||
| 		"debug": "deno run -A --no-lock ./cli.tsx debug", | ||||
| 		"debug": "deno run -A --no-lock --inspect-wait=127.0.0.1:9229 ./cli.tsx debug", | ||||
| 		"serve": "deno run -A --no-lock ./cli.tsx serve", | ||||
| 		"cloud": "deno run -A --no-lock ./cli.tsx cloud", | ||||
| 		"baker": "deno run -A --no-lock ./cli.tsx baker", | ||||
| 		"install": "deno install -A -r -f -n able ./cli.tsx" | ||||
| 	}, | ||||
| 	"compilerOptions": { | ||||
| 		"jsx": "react-jsx", | ||||
| 		"lib": ["deno.window", "dom", "dom.iterable", "dom.asynciterable"] | ||||
| 		"jsxImportSource": "react", | ||||
| 		"lib": [ | ||||
| 			"deno.window", | ||||
| 			"dom",  | ||||
| 			"dom.asynciterable" | ||||
| 		] | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										32
									
								
								deno.lock
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								deno.lock
									
									
									
									
									
								
							| @ -1,32 +0,0 @@ | ||||
| { | ||||
|   "version": "3", | ||||
|   "remote": { | ||||
|     "https://deno.land/std@0.180.0/media_types/_db.ts": "7606d83e31f23ce1a7968cbaee852810c2cf477903a095696cdc62eaab7ce570", | ||||
|     "https://deno.land/std@0.180.0/media_types/_util.ts": "916efbd30b6148a716f110e67a4db29d6949bf4048997b754415dd7e42c52378", | ||||
|     "https://deno.land/std@0.180.0/media_types/content_type.ts": "c682589a0aeb016bfed355cc1ed6fbb3ead2ea48fc0000ac5de6a5730613ad1c", | ||||
|     "https://deno.land/std@0.180.0/media_types/extension.ts": "7a4ef2813d7182f724a941f38161525996e4a67abc3cf6a0f9bc2168d73a0f0e", | ||||
|     "https://deno.land/std@0.180.0/media_types/extensions_by_type.ts": "4358023feac696e6e9d49c0f1e76a859f03ca254df57812f31f8536890c3a443", | ||||
|     "https://deno.land/std@0.180.0/media_types/format_media_type.ts": "1e35e16562e5c417401ffc388a9f8f421f97f0ee06259cbe990c51bae4e6c7a8", | ||||
|     "https://deno.land/std@0.180.0/media_types/get_charset.ts": "8be15a1fd31a545736b91ace56d0e4c66ea0d7b3fdc5c90760e8202e7b4b1fad", | ||||
|     "https://deno.land/std@0.180.0/media_types/mod.ts": "d3f0b99f85053bc0b98ecc24eaa3546dfa09b856dc0bbaf60d8956d2cdd710c8", | ||||
|     "https://deno.land/std@0.180.0/media_types/parse_media_type.ts": "bed260d868ea271445ae41d748e7afed9b5a7f407d2777ead08cecf73e9278de", | ||||
|     "https://deno.land/std@0.180.0/media_types/type_by_extension.ts": "6076a7fc63181d70f92ec582fdea2c927eb2cfc7f9c9bee9d6add2aca86f2355", | ||||
|     "https://deno.land/std@0.180.0/media_types/vendor/mime-db.v1.52.0.ts": "6925bbcae81ca37241e3f55908d0505724358cda3384eaea707773b2c7e99586", | ||||
|     "https://deno.land/std@0.194.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", | ||||
|     "https://deno.land/std@0.194.0/collections/filter_values.ts": "5b9feaf17b9a6e5ffccdd36cf6f38fa4ffa94cff2602d381c2ad0c2a97929652", | ||||
|     "https://deno.land/std@0.194.0/collections/without_all.ts": "a89f5da0b5830defed4f59666e188df411d8fece35a5f6ca69be6ca71a95c185", | ||||
|     "https://deno.land/std@0.194.0/dotenv/mod.ts": "39e5d19e077e55d7e01ea600eb1c6d1e18a8dfdfc65d68826257a576788da3a4", | ||||
|     "https://deno.land/std@0.194.0/flags/mod.ts": "17f444ddbee43c5487568de0c6a076c7729cfe90d96d2ffcd2b8f8adadafb6e8", | ||||
|     "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", | ||||
|     "https://esm.sh/@swc/wasm-web@1.3.62": "b43fb5cde95beb7736182fa62250235dfa6b71717b9d38aa4e6077f05ec90e5e", | ||||
|     "https://esm.sh/preact@10.20.2/compat/jsx-runtime": "e3942a5ffd734d5eaf0790ada3ed4ad81c0c0c2ff56a8e4740247de259f7fb65", | ||||
|     "https://esm.sh/stable/preact@10.20.2/denonext/compat.js": "2e0564fd10e09b587503f9ecd4407ac8726c79beae80026ac89034a47b270c68", | ||||
|     "https://esm.sh/stable/preact@10.20.2/denonext/compat/jsx-runtime.js": "fbbbceb98af95d1c73181f9e5043fad6cdae30ef9e5fcf90d44ffd6fa6055c02", | ||||
|     "https://esm.sh/stable/preact@10.20.2/denonext/hooks.js": "91d64a217b2f2c9f724042d0ed1b87bf3edf721261e86358aa6fd55501ee915f", | ||||
|     "https://esm.sh/stable/preact@10.20.2/denonext/jsx-runtime.js": "2a5b981955e92e3ff86906ac0e5955ec0e6e5ca71032f3f063912cb85ae9a7f1", | ||||
|     "https://esm.sh/stable/preact@10.20.2/denonext/preact.mjs": "f418bc70c24b785703afb9d4dea8cdc1e315e43c8df620a0c52fd27ad9bd70eb", | ||||
|     "https://esm.sh/v135/@swc/wasm-web@1.3.62/denonext/wasm-web.mjs": "57046d46c9ef1398a294ba7447034f5966e48866a05c309cccec4bb4d6e7c61b" | ||||
|   } | ||||
| } | ||||
| @ -1,3 +1,4 @@ | ||||
| //@able-types
 | ||||
| import React from "react"; | ||||
| 
 | ||||
| type MetasInputs = { [Property in MetaKeys]?: string }; | ||||
| @ -192,7 +193,7 @@ export const Router = { | ||||
| 
 | ||||
|         React.useEffect(()=>{ | ||||
|             history.replaceState({...routeGet, URL:undefined}, "", routeGet.URL); | ||||
|             window.addEventListener("popstate", ({state})=> | ||||
|             self.addEventListener("popstate", ({state})=> | ||||
|             { | ||||
|                 dirtySet(true); | ||||
|                 routeUpdate(state.Path, state.Params, state.Anchor); | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| //@able-types
 | ||||
| import React from "react"; | ||||
| 
 | ||||
| type StateArgs = {done?:boolean, open?:boolean}; | ||||
|  | ||||
							
								
								
									
										111
									
								
								run-baker.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								run-baker.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | ||||
| import { walk, type WalkOptions, ensureFile } from "https://deno.land/std@0.204.0/fs/mod.ts"; | ||||
| 
 | ||||
| import ts, { isAssertEntry } from "npm:typescript"; | ||||
| const tsopts:ts.CompilerOptions = { declaration: true, emitDeclarationOnly: true }; | ||||
| const tshost = ts.createCompilerHost(tsopts); | ||||
| const tstypes =(fileName: string):string=> { | ||||
|     let output = ""; | ||||
|     tshost.writeFile = (fileName: string, contents: string) => output = contents; | ||||
|     ts.createProgram([fileName], tsopts, tshost).emit(); | ||||
|     return output; | ||||
| } | ||||
| const tstypes_all =(fileNames: string[]):string[]=> { | ||||
|     const output:string[] = []; | ||||
|     tshost.writeFile = (fileName: string, contents: string) => output[fileName.indexOf(fileName)] = contents; | ||||
|     ts.createProgram(fileNames, tsopts, tshost).emit(); | ||||
|     return output; | ||||
| } | ||||
| 
 | ||||
| import * as SWCW from "https://esm.sh/@swc/wasm-web@1.3.62"; | ||||
| 
 | ||||
| await SWCW.default(); | ||||
| const options:SWCW.Options = { | ||||
|     sourceMaps: false, | ||||
|     minify: true, | ||||
|     jsc: | ||||
|     { | ||||
|         target:"es2022", | ||||
|         minify: | ||||
|         { | ||||
|             compress: { unused: true }, | ||||
|             mangle: false | ||||
|         }, | ||||
|         parser: | ||||
|         { | ||||
|             syntax: "typescript", | ||||
|             tsx: true, | ||||
|         }, | ||||
|         transform: | ||||
|         { | ||||
|             react: { runtime: "automatic" } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| const dir = Deno.cwd(); | ||||
| const folder = dir.substring(dir.lastIndexOf("\\")+1); | ||||
| console.log("searching", dir); | ||||
| const extensions = ["tsx", "ts", "jsx", "js"]; | ||||
| try | ||||
| { | ||||
|     await Deno.remove(".bake", { recursive: true }); | ||||
|     console.log("rebuilding baked files"); | ||||
| } | ||||
| catch(e) | ||||
| { | ||||
|     console.log("fresh bake"); | ||||
| } | ||||
| for await(const file of walk(dir, {includeDirs:false})) | ||||
| {     | ||||
|     const pathClean = file.path.replaceAll("\\", "/"); | ||||
|     const pathRel = pathClean.substring(dir.length); | ||||
| 
 | ||||
|     if(!pathRel.startsWith(".") && !pathRel.includes("/.")) | ||||
|     {   | ||||
|         const extension = file.name.substring(file.name.lastIndexOf(".")+1); | ||||
|         const pathBake = `.bake${pathRel}`; | ||||
|         if(extensions.includes(extension)) | ||||
|         { | ||||
|             const pathDTS = pathBake.substring(0, pathBake.lastIndexOf("."))+".d.ts"; | ||||
| 
 | ||||
|             console.log("processing", pathRel); | ||||
|      | ||||
|             const text = await Deno.readTextFile(pathClean); | ||||
|             const {code} = await SWCW.transform(text, { ...options, filename:file.name});         | ||||
| 
 | ||||
|             // check for types export directive
 | ||||
|             let tripleSlash = ""; | ||||
|             const read = await Deno.open(file.path); | ||||
|             const buffer = new Uint8Array(256); // Set the buffer size to the maximum line length
 | ||||
|             try { | ||||
|                 const bytesRead = await read.read(buffer); | ||||
|                 if(bytesRead) | ||||
|                 { | ||||
|                     if(new TextDecoder().decode(buffer.subarray(0, bytesRead)).indexOf("@able-types") != -1) | ||||
|                     { | ||||
|                         tripleSlash =`/// <reference types=".${pathDTS.substring(pathDTS.lastIndexOf("/"))}" />\n`; | ||||
|                     } | ||||
|                 } | ||||
|             } finally { | ||||
|                 read.close(); | ||||
|             } | ||||
|          | ||||
|             await ensureFile(pathBake); | ||||
|             await Deno.writeTextFile(pathBake, tripleSlash+code); | ||||
| 
 | ||||
|             if(tripleSlash) | ||||
|             { | ||||
|                 console.log("making types") | ||||
|                 await ensureFile(pathDTS); | ||||
|                 await Deno.writeTextFile(pathDTS, tstypes("."+pathRel));    | ||||
|             } | ||||
|           | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             await Deno.copyFile("."+pathRel, pathBake); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -3,32 +3,10 @@ import * as TW from   "@twind/core"; | ||||
| import TWPreTail from "https://esm.sh/v126/@twind/preset-tailwind@1.1.3/es2022/preset-tailwind.mjs"; | ||||
| import TWPreAuto from "https://esm.sh/v126/@twind/preset-autoprefix@1.0.7/es2022/preset-autoprefix.mjs"; | ||||
| 
 | ||||
| const Configure = | ||||
| { | ||||
|   theme: {}, | ||||
|   presets: [TWPreTail(), TWPreAuto()], | ||||
|   hash: false | ||||
| } as TW.TwindUserConfig; | ||||
| 
 | ||||
| export const Shadow =(inElement:HTMLElement, inConfig:TW.TwindUserConfig)=> | ||||
| { | ||||
|     const ShadowDOM = inElement.attachShadow({ mode: "open" }); | ||||
|     const ShadowDiv = document.createElement("div"); | ||||
|     const ShadowCSS = document.createElement("style"); | ||||
| 
 | ||||
|     ShadowDOM.append(ShadowCSS); | ||||
|     ShadowDOM.append(ShadowDiv); | ||||
|     TW.observe(TW.twind(inConfig, TW.cssom(ShadowCSS)), ShadowDiv); | ||||
|     return ShadowDiv; | ||||
| }; | ||||
| const Configure = { theme: {}, presets: [TWPreTail(), TWPreAuto()], hash: false} as TW.TwindUserConfig; | ||||
| 
 | ||||
| export default async(inSelector:string, inModulePath:string, inMemberApp="default", inMemberCSS="CSS", inShadow=false):Promise<(()=>void)|false>=> | ||||
| { | ||||
|   if(!inModulePath) | ||||
|   { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   let dom = document.querySelector(inSelector); | ||||
|   if(!dom) | ||||
|   { | ||||
| @ -37,12 +15,18 @@ export default async(inSelector:string, inModulePath:string, inMemberApp="defaul | ||||
|   } | ||||
| 
 | ||||
|   const module = await import(inModulePath); | ||||
| 
 | ||||
|   const merge = inMemberCSS ? {...Configure, ...module[inMemberCSS]} : Configure; | ||||
| 
 | ||||
|   if(inShadow) | ||||
|   { | ||||
|     dom = Shadow(dom as HTMLElement, merge); | ||||
|     const ShadowDOM = dom.attachShadow({ mode: "open" }); | ||||
|     const ShadowDiv = document.createElement("div"); | ||||
|     const ShadowCSS = document.createElement("style"); | ||||
| 
 | ||||
|     ShadowDOM.append(ShadowCSS); | ||||
|     ShadowDOM.append(ShadowDiv); | ||||
|     TW.observe(TW.twind(merge, TW.cssom(ShadowCSS)), ShadowDiv); | ||||
|     dom = ShadowDiv; | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|  | ||||
							
								
								
									
										106
									
								
								run-deploy.tsx
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								run-deploy.tsx
									
									
									
									
									
								
							| @ -1,106 +0,0 @@ | ||||
| import * as Env from "https://deno.land/std@0.194.0/dotenv/mod.ts"; | ||||
| import { parse } from "https://deno.land/std@0.194.0/flags/mod.ts"; | ||||
| 
 | ||||
| 
 | ||||
| const collect =async(inKey:string, inArg:Record<string, string>, inEnv:Record<string, string>):Promise<string|undefined>=> | ||||
| { | ||||
|     const scanArg = inArg[inKey]; | ||||
|     const scanEnvFile = inEnv[inKey]; | ||||
|     const scanEnvDeno = Deno.env.get(inKey); | ||||
| 
 | ||||
|     if(scanArg) | ||||
|     { | ||||
|         console.log(`Using "${inKey}" from passed argument.`); | ||||
|         return scanArg; | ||||
|     } | ||||
|     if(scanEnvFile) | ||||
|     { | ||||
|         console.log(`Using "${inKey}" from .env file.`); | ||||
|         return scanEnvFile; | ||||
|     } | ||||
|     if(scanEnvDeno) | ||||
|     { | ||||
|         console.log(`Using "${inKey}" from environment variable.`); | ||||
|         return scanEnvDeno; | ||||
|     } | ||||
| 
 | ||||
|     const scanUser = await prompt(`No "${inKey}" found. Enter one here:`); | ||||
|     if(!scanUser || scanUser?.length < 3) | ||||
|     { | ||||
|         console.log("Exiting..."); | ||||
|         Deno.exit(); | ||||
|     } | ||||
|     return scanUser; | ||||
| }; | ||||
| 
 | ||||
| const prompt =async(question: string):Promise<string>=> | ||||
| { | ||||
|     const buf = new Uint8Array(1024); | ||||
|     await Deno.stdout.write(new TextEncoder().encode(question)); | ||||
|     const bytes = await Deno.stdin.read(buf); | ||||
|     if (bytes) { | ||||
|         return new TextDecoder().decode(buf.subarray(0, bytes)).trim(); | ||||
|     } | ||||
|     throw new Error("Unexpected end of input"); | ||||
| }; | ||||
| 
 | ||||
| try | ||||
| { | ||||
|     console.log("Runing deploy!", Deno.mainModule); | ||||
| 
 | ||||
|     let arg = parse(Deno.args); | ||||
|     let env = await Env.load(); | ||||
| 
 | ||||
|     let useToken = await collect("DENO_DEPLOY_TOKEN", arg, env); | ||||
|     let useProject = await collect("DENO_DEPLOY_PROJECT", arg, env); | ||||
|      | ||||
|     let scanProd:string|string[] = await prompt(`Do you want to deploy to *production*? [y/n]`); | ||||
|     if(scanProd == "y") | ||||
|     { | ||||
|         scanProd = await prompt(`This will update the live project at ${useProject} are you sure you want to continue? [y/n]`); | ||||
|         scanProd = scanProd=="y" ? ["--prod"] : []; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         scanProd = []; | ||||
|     } | ||||
| 
 | ||||
|     const command = new Deno.Command( | ||||
|         `deno`, | ||||
|         { | ||||
|             args:[ | ||||
|                 "run", | ||||
|                 "-A", | ||||
|                 "--no-lock", | ||||
|                 "https://deno.land/x/deploy/deployctl.ts", | ||||
|                 "deploy", | ||||
|                 `--project=${useProject}`, | ||||
|                 `--import-map=./deno.json`, | ||||
|                 `--token=${useToken}`, | ||||
|                 ...scanProd, | ||||
|                 Deno.mainModule | ||||
|             ], | ||||
|             stdin: "piped", | ||||
|             stdout: "piped" | ||||
|         } | ||||
|     ); | ||||
| 
 | ||||
|     const child = command.spawn(); | ||||
|      | ||||
|     // open a file and pipe the subprocess output to it.
 | ||||
|     const writableStream = new WritableStream({ | ||||
|         write(chunk: Uint8Array): Promise<void> { | ||||
|             Deno.stdout.write(chunk); | ||||
|             return Promise.resolve(); | ||||
|         }, | ||||
|     }); | ||||
|     child.stdout.pipeTo(writableStream); | ||||
| 
 | ||||
|     // manually close stdin
 | ||||
|     child.stdin.close(); | ||||
|     const status = await child.status; | ||||
| } | ||||
| catch(e) | ||||
| { | ||||
|     console.error(e); | ||||
| } | ||||
| @ -1,5 +1,4 @@ | ||||
| import {Configure, Transpile, Extension} from "./run-serve.tsx"; | ||||
| import { Root } from "./checker.tsx"; | ||||
| import {Configure, Transpile, Extension, Root} from "./run-serve.tsx"; | ||||
| import * as Collect from "./hmr-static.tsx"; | ||||
| 
 | ||||
| const SocketsLive:Set<WebSocket> = new Set(); | ||||
|  | ||||
| @ -1,34 +1,55 @@ | ||||
| import * as MIME from "https://deno.land/std@0.180.0/media_types/mod.ts"; | ||||
| import * as SWCW from "https://esm.sh/@swc/wasm-web@1.3.62"; | ||||
| import { HuntConfig, Root } from "./checker.tsx"; | ||||
| import * as SWCW from "https://esm.sh/@swc/wasm-web@1.4.17"; | ||||
| import { HuntConfig } from "./checker.tsx"; | ||||
| import CustomServe from ">able/api.tsx";  | ||||
| 
 | ||||
| export const Root = new URL(`file://${Deno.cwd().replaceAll("\\", "/")}`).toString(); | ||||
| 
 | ||||
| type DenoConfig = {imports:Record<string, string>}; | ||||
| const ImportMap:DenoConfig = {imports:{}}; | ||||
| let ImportMapProxies:Record<string, string> = {}; | ||||
| 
 | ||||
| // (re)scan the project directory looking for the config
 | ||||
| // process the found import map:
 | ||||
| // - make a copy of the import map
 | ||||
| // - change root relative imports that deno needs (starts with "./") to "/" for use in the browser
 | ||||
| // - change 
 | ||||
| 
 | ||||
| const ImportMapReload =async()=> | ||||
| { | ||||
|     const [, {json}] = await HuntConfig(); | ||||
|     const [, {json, path}] = await HuntConfig(); | ||||
|     const imports = (json as DenoConfig).imports; | ||||
| 
 | ||||
|     if(imports) | ||||
|     { | ||||
|         ImportMapProxies = {}; | ||||
|         Object.entries(imports).forEach(([key, value])=> | ||||
|         { | ||||
|             // re-write deno project-relative paths (e.g. "./app.tsx") to root-relative for the browser ("/app.tsx"); 
 | ||||
|             if(value.startsWith("./")) | ||||
|             { | ||||
|                 imports[key] = value.substring(1); | ||||
|             } | ||||
| 
 | ||||
|             if(key.startsWith(">") && key.endsWith("/")) | ||||
|             if(key.startsWith(">")) | ||||
|             { | ||||
|                 if(value.startsWith("./")) | ||||
|                 { | ||||
|                     ImportMapProxies[encodeURI(key)] = value.substring(1); | ||||
|                     imports[key] = value.substring(1);  | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     ImportMapProxies["/"+encodeURI(key)] = value; | ||||
|                     imports[key] = "/"+key;     | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         ImportMap.imports = Configuration.Remap(imports, Configuration); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| @ -76,7 +97,7 @@ let Configuration:Configuration = | ||||
|             minify: | ||||
|             { | ||||
|                 compress: { unused: true }, | ||||
|                 mangle: true | ||||
|                 mangle: false | ||||
|             }, | ||||
|             parser: | ||||
|             { | ||||
| @ -146,6 +167,7 @@ export const Configure =(config:ConfigurationArgs)=> | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| let running = false; | ||||
| export default async()=> | ||||
| { | ||||
| @ -169,6 +191,7 @@ export default async()=> | ||||
|         const headers = {"content-type":"application/json", "Access-Control-Allow-Origin": Configuration.Allow, "charset":"UTF-8"}; | ||||
|         let proxy = Root + url.pathname; | ||||
|          | ||||
|         // dont serve hidden files (end file or folder names with "__" to hide)
 | ||||
|         if(url.pathname.includes("__/") || url.pathname.lastIndexOf("__.") > -1) | ||||
|         { | ||||
|             return new Response(`{"error":"unmatched route", "path":"${url.pathname}"}`, {status:404, headers}); | ||||
| @ -177,9 +200,24 @@ export default async()=> | ||||
|         // proxy imports
 | ||||
|         if(url.pathname.startsWith(encodeURI("/>"))) | ||||
|         { | ||||
|             /** pathname with no leading slash */ | ||||
|             const clippedPath = decodeURI(url.pathname.substring(1)); | ||||
|             proxy = import.meta.resolve(clippedPath); | ||||
|             console.log(ImportMapProxies); | ||||
|             console.log("checking for", url.pathname) | ||||
|             let bestMatch=""; | ||||
|             for(const key in ImportMapProxies) | ||||
|             { | ||||
|                 const match = url.pathname.startsWith(key) && key.length > bestMatch.length; | ||||
|                 console.log(`key:${key} match:${match}`); | ||||
|                 if(match) | ||||
|                 { | ||||
|                     bestMatch = key; | ||||
|                 } | ||||
|             } | ||||
|             if(bestMatch.length) | ||||
|             { | ||||
|                 const value = ImportMapProxies[bestMatch]; | ||||
|                 const path = url.pathname.substring(bestMatch.length); | ||||
|                 proxy = path ? value + path : Root + value; | ||||
|             } | ||||
|         } | ||||
|      | ||||
|         // allow for custom handlers
 | ||||
| @ -197,6 +235,7 @@ export default async()=> | ||||
|         // transpileable files
 | ||||
|         if(Transpile.Check(ext)) | ||||
|         { | ||||
|             console.log("transpiling:", proxy); | ||||
|             const code = await Transpile.Fetch(proxy, url.pathname);     | ||||
|             if(code) | ||||
|             { | ||||
|  | ||||
							
								
								
									
										7
									
								
								run.tsx
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								run.tsx
									
									
									
									
									
								
							| @ -20,15 +20,8 @@ export default function(config:Serve.ConfigurationArgs) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| if(isDeploy) | ||||
| { | ||||
|     import("./run-deploy.tsx"); | ||||
| } | ||||
| else | ||||
| { | ||||
| if(isDevelop) | ||||
| { | ||||
|     await import("./run-local.tsx"); | ||||
| } | ||||
| Serve.default(); | ||||
| } | ||||
							
								
								
									
										56
									
								
								things.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								things.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | ||||
| # Outpost | ||||
| 
 | ||||
| ## Deno Deploy | ||||
| ``` | ||||
| accept:  */* | ||||
| accept-encoding:  gzip, br | ||||
| accept-language:  * | ||||
| cdn-loop:  deno;s=deno;d=ah40t9m8n54g | ||||
| host:  bad-goat-66.deno.dev | ||||
| user-agent:  Deno/1.34.1 | ||||
| ``` | ||||
| 
 | ||||
| ## Deno | ||||
| ``` | ||||
| accept:  */* | ||||
| accept-encoding:  gzip, br | ||||
| accept-language:  * | ||||
| host:  bad-goat-66.deno.dev | ||||
| user-agent:  Deno/1.34.3 | ||||
| ``` | ||||
| 
 | ||||
| ## Edge | ||||
| ``` | ||||
| accept:  text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 | ||||
| accept-encoding:  gzip, deflate, br | ||||
| accept-language:  en-US,en;q=0.9 | ||||
| host:  bad-goat-66.deno.dev | ||||
| referer:  https://dash.deno.com/ | ||||
| sec-ch-ua:  "Microsoft Edge";v="117", "Not;A=Brand";v="8", "Chromium";v="117" | ||||
| sec-ch-ua-mobile:  ?0 | ||||
| sec-ch-ua-platform:  "Windows" | ||||
| sec-fetch-dest:  iframe | ||||
| sec-fetch-mode:  navigate | ||||
| sec-fetch-site:  cross-site | ||||
| upgrade-insecure-requests:  1 | ||||
| user-agent:  Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.0.0 | ||||
| ``` | ||||
| 
 | ||||
| ## Firefox | ||||
| ``` | ||||
| accept:  text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 | ||||
| accept-encoding:  gzip, deflate, br | ||||
| accept-language:  en-US,en;q=0.5 | ||||
| host:  bad-goat-66.deno.dev | ||||
| sec-fetch-dest:  document | ||||
| sec-fetch-mode:  navigate | ||||
| sec-fetch-site:  cross-site | ||||
| te:  trailers | ||||
| upgrade-insecure-requests:  1 | ||||
| user-agent:  Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0 | ||||
| ``` | ||||
| 
 | ||||
| When a requet comes in: | ||||
| - if its for a transpile-able document: | ||||
|   - if its a request from deno: | ||||
|     -  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user