From 9dfb8d65d33c839cdadea39168f3d760c7b0cab7 Mon Sep 17 00:00:00 2001 From: Fabian Stamm Date: Fri, 15 Jan 2021 02:32:51 +0100 Subject: [PATCH] Add support for intellisense imports for the vscode extension --- jsx/mod.ts | 6 ++-- registry/src/config.ts | 7 ++++ registry/src/http.ts | 4 ++- registry/src/http/api.ts | 60 ++++++++++++++++++++++++++++++- registry/src/http/intellisense.ts | 43 ++++++++++++++++++++++ registry/src/renderer.tsx | 25 ++++++++----- registry/src/utils.ts | 2 +- 7 files changed, 134 insertions(+), 13 deletions(-) create mode 100644 registry/src/http/intellisense.ts diff --git a/jsx/mod.ts b/jsx/mod.ts index 9d51274..e98af22 100644 --- a/jsx/mod.ts +++ b/jsx/mod.ts @@ -9,8 +9,6 @@ declare namespace JSX { } } -export { Fragment }; - export type Element = { component: Component | string | typeof Fragment; props: any; @@ -34,6 +32,10 @@ export function h( }; } +const createElement = h; + +export { Fragment, createElement }; + export async function renderSSR(element: Element | string): Promise { if (typeof element === "string") return element; else if (typeof element.component === "string") diff --git a/registry/src/config.ts b/registry/src/config.ts index afae7e9..527d4a2 100644 --- a/registry/src/config.ts +++ b/registry/src/config.ts @@ -45,6 +45,9 @@ for (const key in env) { case "S3_REGION": config.s3 = { ...(config.s3 || {}), region: env[key] }; break; + case "WEB_URL": + config.web.url = env[key]; + break; case "WEB_TRACKING": config.web.tracking = env[key]; break; @@ -59,6 +62,10 @@ if (config.general.dev) { console.warn("Dev mode active!!!"); } +if (!config.web.url) { + console.error("The web.url configuration has to be set!"); +} + console.log("Known users:", Object.keys(config.user)); export default config; diff --git a/registry/src/http.ts b/registry/src/http.ts index d0ce9ac..7116cdc 100644 --- a/registry/src/http.ts +++ b/registry/src/http.ts @@ -38,9 +38,11 @@ api(app.group("/api")); import raw from "./http/raw.ts"; raw(app.group("/raw")); +import intellisense from "./http/intellisense.ts"; +intellisense(app.group("/.well-known")); + import view from "./http/views.ts"; view(app); - // function logNode(router: Node, indent = 0) { // trees.map((tree) => { // console.log("Path:", tree.path); diff --git a/registry/src/http/api.ts b/registry/src/http/api.ts index d230ad5..152d37c 100644 --- a/registry/src/http/api.ts +++ b/registry/src/http/api.ts @@ -1,7 +1,13 @@ import { ABC, Path, Compress, FS, Colors, S3Error } from "../deps.ts"; import bucket from "../s3.ts"; -import { isValidPackageName, basicauth, isValidFullVersion } from "../utils.ts"; +import { + isValidPackageName, + basicauth, + isValidFullVersion, + getAbsolutePackageVersion, + getBucketFilePath, +} from "../utils.ts"; import db, { IPackage } from "../db.ts"; @@ -21,8 +27,60 @@ export default function api(g: ABC.Group) { cacheControl ); + g.get("/module", async (ctx) => { + return db.package.find({}).then((res) => res.map((e) => e.name)); + }); + + g.get("/module/:module", async (ctx) => { + const module = await db.package.findOne({ name: ctx.params.module }); + if (!module) { + ctx.response.status = 404; + return "// Not found"; + } else { + return module.versions; + } + }); + + g.get("/module/:module/v/:version", async (ctx) => { + const module = await db.package.findOne({ name: ctx.params.module }); + if (!module) { + ctx.response.status = 404; + return "// Not found"; + } else { + let version = getAbsolutePackageVersion( + module, + ctx.params.version + ) as string; + + if (!version) { + ctx.response.status = 404; + return "// Not found"; + } + + const bucketPath = await getBucketFilePath(module.name, version, "/"); + + const filesItr = bucket.listAllObjects({ + batchSize: 100, + prefix: bucketPath, + }); + const allowedExts = new Set( + (ctx.queryParams.ext || "js|ts").split("|").map((e) => "." + e) + ); + + let files: string[] = []; + for await (let file of filesItr) { + const relPath = Path.posix.relative(bucketPath, file.key || ""); + const ext = Path.extname(relPath); + if (allowedExts.has(ext)) files.push(relPath); + } + + return files; + } + }); + // g.post("/getapikey", getApiKey, basicauth("api")); g.post("/package/:name", uploadPackage, cacheControl, basicauth("api")); + g.post("/module/:name", uploadPackage, cacheControl, basicauth("api")); //Switch no module instead of package } // async function getApiKey(ctx: ABC.Context) { diff --git a/registry/src/http/intellisense.ts b/registry/src/http/intellisense.ts new file mode 100644 index 0000000..6e4fdb0 --- /dev/null +++ b/registry/src/http/intellisense.ts @@ -0,0 +1,43 @@ +import { ABC } from "../deps.ts"; + +import config from "../config.ts"; + +export default function raw(g: ABC.Group) { + g.get("/deno-import-intellisense.json", (ctx) => { + return { + version: 1, + registries: [ + { + schema: "/raw/:module([@]*[a-z0-9\\-\\_]*)@:version?/:path*", + variables: [ + { + key: "module", + url: `${config.web.url}/api/module`, + }, + { + key: "version", + url: `${config.web.url}/api/module/\${module}`, + }, + { + key: "path", + url: `${config.web.url}/api/module/\${module}/v/\${{version}}`, + }, + ], + }, + { + schema: "/raw/:module([@]*[a-z0-9\\-\\_]*)/:path*", + variables: [ + { + key: "module", + url: `${config.web.url}/api/module`, + }, + { + key: "path", + url: `${config.web.url}/api/module/\${module}/v/latest`, + }, + ], + }, + ], + }; + }); +} diff --git a/registry/src/renderer.tsx b/registry/src/renderer.tsx index 7d27647..072ad81 100644 --- a/registry/src/renderer.tsx +++ b/registry/src/renderer.tsx @@ -46,14 +46,23 @@ async function loadComponent(name: string) { return mod; } -import index from "./views/index.tsx"; -componentCache.set("index", index as Component); -import pkg from "./views/package.tsx"; -componentCache.set("package", pkg as Component); -import browse_folder from "./views/browse_folder.tsx"; -componentCache.set("browse_folder", browse_folder as Component); -import browse_file from "./views/browse_file.tsx"; -componentCache.set("browse_file", browse_file as Component); +Promise.resolve().then(async () => { + console.log("[PRECACHE] Start loading pages"); + await loadComponent("index"); + await loadComponent("package"); + await loadComponent("browse_folder"); + await loadComponent("browse_file"); + console.log("[PRECACHE] Finished loading pages"); +}); + +// import index from "./views/index.tsx"; +// componentCache.set("index", index as Component); +// import pkg from "./views/package.tsx"; +// componentCache.set("package", pkg as Component); +// import browse_folder from "./views/browse_folder.tsx"; +// componentCache.set("browse_folder", browse_folder as Component); +// import browse_file from "./views/browse_file.tsx"; +// componentCache.set("browse_file", browse_file as Component); export default async function render( name: string, diff --git a/registry/src/utils.ts b/registry/src/utils.ts index 4bce07c..4773bca 100644 --- a/registry/src/utils.ts +++ b/registry/src/utils.ts @@ -99,7 +99,7 @@ export function getAbsolutePackageVersion( const versions = pkg.versions.sort(sortVersions).reverse(); - if (!version) { + if (!version || version === "latest") { version = versions[0]; } else { const v = versions.filter((e) => e.startsWith(version as string));