Compare commits
14 Commits
2af5d4f823
...
master
Author | SHA1 | Date | |
---|---|---|---|
a0fef1ef76 | |||
3cda4ee8c8 | |||
e5829d9a4f | |||
3efe4fc34e | |||
22a447604b | |||
9dfb8d65d3 | |||
6bc090e51b | |||
965ca33d33 | |||
0202946813 | |||
53a11eccf6 | |||
325c1a4d7d | |||
c718e8898d | |||
6fe3ddbd37 | |||
79bcef0698 |
@ -1,45 +1,8 @@
|
|||||||
import { Colors, Path, FS, Compress, Base64 } from "../deps.ts";
|
import { Colors, Path, FS, Compress, Base64 } from "../deps.ts";
|
||||||
import { getMeta, IMeta, log, getConfig } from "../global.ts";
|
import { getMeta, IMeta, log, getConfig } from "../global.ts";
|
||||||
|
import { runHooks } from "../helper/run_script.ts";
|
||||||
import { ServerError } from "../helper/server_error.ts";
|
import { ServerError } from "../helper/server_error.ts";
|
||||||
|
import { checkPermOrExit } from "../helper/permission.ts";
|
||||||
async function runScript(script: string) {
|
|
||||||
console.log(Colors.bold(Colors.blue("Running script:")), script);
|
|
||||||
const runPerm = await Deno.permissions.query({
|
|
||||||
name: "run",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (runPerm.state !== "granted") {
|
|
||||||
console.log(
|
|
||||||
Colors.red("Missing --allow-run permission. Cannot run hooks!")
|
|
||||||
);
|
|
||||||
throw new Error("Missing --allow-run permission. Cannot run hooks!");
|
|
||||||
}
|
|
||||||
|
|
||||||
const process = Deno.run({
|
|
||||||
cmd: ["deno", "run", "-A", "--unstable", script],
|
|
||||||
});
|
|
||||||
|
|
||||||
const status = await process.status();
|
|
||||||
|
|
||||||
console.log(Colors.bold(Colors.blue("Finished script:")), script);
|
|
||||||
|
|
||||||
if (!status.success) {
|
|
||||||
throw new Error(
|
|
||||||
"A hook did not complete sucessfully. This is not a issue of denreg!"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function runHooks(hooks: undefined | string | string[]) {
|
|
||||||
if (!hooks) return;
|
|
||||||
if (typeof hooks === "string") {
|
|
||||||
hooks = [hooks];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const hook of hooks) {
|
|
||||||
await runScript(hook);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function publish(options: { dry: boolean }) {
|
export default async function publish(options: { dry: boolean }) {
|
||||||
const originalMeta = await getMeta();
|
const originalMeta = await getMeta();
|
||||||
@ -100,6 +63,8 @@ export default async function publish(options: { dry: boolean }) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!options.dry) {
|
if (!options.dry) {
|
||||||
|
await checkPermOrExit("net", "Net permission required for publishing");
|
||||||
|
|
||||||
log("Uploading new package version");
|
log("Uploading new package version");
|
||||||
await fetch(url, {
|
await fetch(url, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
18
cli/commands/run.ts
Normal file
18
cli/commands/run.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Colors, Path, FS, Compress, Base64 } from "../deps.ts";
|
||||||
|
import { getMeta, IMeta, log, getConfig } from "../global.ts";
|
||||||
|
import { ServerError } from "../helper/server_error.ts";
|
||||||
|
|
||||||
|
import { runScript } from "../helper/run_script.ts";
|
||||||
|
|
||||||
|
export default async function run(options: {}, name: string) {
|
||||||
|
const { scripts } = await getMeta();
|
||||||
|
if (!scripts || !scripts[name]) {
|
||||||
|
console.log(Colors.bold(Colors.red("Script not found:")), name);
|
||||||
|
} else {
|
||||||
|
let script = scripts[name];
|
||||||
|
if (!Array.isArray(script)) script = [script];
|
||||||
|
for (const s of script) {
|
||||||
|
await runScript(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,12 @@
|
|||||||
import { Cliffy, Colors } from "../deps.ts";
|
import { Cliffy, Colors } from "../deps.ts";
|
||||||
import { version } from "../version.ts";
|
import { version } from "../version.ts";
|
||||||
|
import { requestPermOrExit } from "../helper/permission.ts";
|
||||||
|
|
||||||
export default async function upgrade() {
|
export default async function upgrade() {
|
||||||
|
await requestPermOrExit(
|
||||||
|
"net",
|
||||||
|
"Net permission required to fetch new version"
|
||||||
|
);
|
||||||
const meta = await fetch(
|
const meta = await fetch(
|
||||||
"https://deno.hibas123.de/raw/@denreg-cli/meta.json"
|
"https://deno.hibas123.de/raw/@denreg-cli/meta.json"
|
||||||
).then((e) => e.json());
|
).then((e) => e.json());
|
||||||
@ -20,19 +25,39 @@ export default async function upgrade() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
const process = Deno.run({
|
const cmd_base = ["deno", "install", "-A", "--unstable", "-f"];
|
||||||
cmd: [
|
|
||||||
"deno",
|
const cmd1 = [
|
||||||
"install",
|
...cmd_base,
|
||||||
"-A",
|
`https://deno.hibas123.de/raw/@denreg-cli@${meta.version}/denreg.ts`,
|
||||||
"--unstable",
|
];
|
||||||
"-f",
|
|
||||||
`https://deno.hibas123.de/raw/@denreg-cli@${meta.version}/denreg.ts`,
|
const cmd2 = [
|
||||||
],
|
...cmd_base,
|
||||||
|
`https://deno.hibas123.de/raw/@denreg-cli@${meta.version}/dpm.ts`,
|
||||||
|
];
|
||||||
|
|
||||||
|
await requestPermOrExit(
|
||||||
|
"run",
|
||||||
|
"Run permission required to install new version. Or run it manually: " +
|
||||||
|
cmd1.join(" ")
|
||||||
|
);
|
||||||
|
|
||||||
|
const process1 = Deno.run({
|
||||||
|
cmd: cmd1,
|
||||||
});
|
});
|
||||||
|
|
||||||
const s = await process.status();
|
const s1 = await process1.status();
|
||||||
if (!s) {
|
if (!s1) {
|
||||||
|
console.log(Colors.red("Upgrade failed!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const process2 = Deno.run({
|
||||||
|
cmd: cmd2,
|
||||||
|
});
|
||||||
|
|
||||||
|
const s2 = await process2.status();
|
||||||
|
if (!s2) {
|
||||||
console.log(Colors.red("Upgrade failed!"));
|
console.log(Colors.red("Upgrade failed!"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
import { Cliffy, Path, Colors } from "./deps.ts";
|
import { Cliffy, Path, Colors } from "./deps.ts";
|
||||||
|
|
||||||
|
import { checkPermOrExit } from "./helper/permission.ts";
|
||||||
|
|
||||||
|
await checkPermOrExit("env", "Requires --allow-env");
|
||||||
|
await checkPermOrExit("read", "Requires --allow-read");
|
||||||
|
await checkPermOrExit("write", "Requires --allow-write");
|
||||||
|
|
||||||
import { init } from "./global.ts";
|
import { init } from "./global.ts";
|
||||||
|
|
||||||
import { version } from "./version.ts";
|
import { version } from "./version.ts";
|
||||||
|
|
||||||
import setupCMD from "./commands/setup.ts";
|
import setupCMD from "./commands/setup.ts";
|
||||||
import initCMD from "./commands/init.ts";
|
import initCMD from "./commands/init.ts";
|
||||||
import bumpCMD from "./commands/bump.ts";
|
import bumpCMD from "./commands/bump.ts";
|
||||||
import publishCMD from "./commands/publish.ts";
|
import publishCMD from "./commands/publish.ts";
|
||||||
import deprecateCMD from "./commands/deprecate.ts";
|
import deprecateCMD from "./commands/deprecate.ts";
|
||||||
import upgradeCMD from "./commands/upgrade.ts";
|
import upgradeCMD from "./commands/upgrade.ts";
|
||||||
|
import runCMD from "./commands/run.ts";
|
||||||
|
|
||||||
const HOME_FOLDER = Deno.env.get("HOME") || Deno.env.get("USERPROFILE") || "";
|
const HOME_FOLDER = Deno.env.get("HOME") || Deno.env.get("USERPROFILE") || "";
|
||||||
|
|
||||||
@ -83,7 +89,16 @@ const flags = await new Cliffy.Command()
|
|||||||
.description("Upgrade to latest version of denreg cli")
|
.description("Upgrade to latest version of denreg cli")
|
||||||
.action(commandWrapper(upgradeCMD))
|
.action(commandWrapper(upgradeCMD))
|
||||||
)
|
)
|
||||||
|
.command(
|
||||||
|
"run",
|
||||||
|
new Cliffy.Command()
|
||||||
|
.arguments("<name>")
|
||||||
|
// .complete("name", ()=>) //TODO: add autocomplete?
|
||||||
|
.description("Run script from meta.json")
|
||||||
|
.action(commandWrapper(runCMD))
|
||||||
|
)
|
||||||
.command("completions", new Cliffy.CompletionsCommand())
|
.command("completions", new Cliffy.CompletionsCommand())
|
||||||
|
.command("help", new Cliffy.HelpCommand().global())
|
||||||
.parse(Deno.args);
|
.parse(Deno.args);
|
||||||
|
|
||||||
await init(flags.options);
|
await init(flags.options);
|
||||||
@ -95,5 +110,5 @@ if (command) {
|
|||||||
console.log(Colors.bold(Colors.red("An error occured:")), err.message);
|
console.log(Colors.bold(Colors.red("An error occured:")), err.message);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
flags.cmd.help();
|
flags.cmd.showHelp();
|
||||||
}
|
}
|
||||||
|
10
cli/deps.ts
10
cli/deps.ts
@ -1,7 +1,7 @@
|
|||||||
export * as Compress from "https://deno.hibas123.de/raw/@denreg-tar/mod.ts";
|
export * as Compress from "https://deno.hibas123.de/raw/@denreg-tar/mod.ts";
|
||||||
export * as Ini from "https://deno.land/x/ini@v2.1.0/mod.ts";
|
export * as Ini from "https://deno.land/x/ini@v2.1.0/mod.ts";
|
||||||
export * as Cliffy from "https://deno.land/x/cliffy@v0.16.0/mod.ts";
|
export * as Cliffy from "https://deno.land/x/cliffy@v0.18.2/mod.ts";
|
||||||
export * as Base64 from "https://deno.land/std@0.65.0/encoding/base64.ts";
|
export * as Base64 from "https://deno.land/std@0.95.0/encoding/base64.ts";
|
||||||
export * as FS from "https://deno.land/std@0.65.0/fs/mod.ts";
|
export * as FS from "https://deno.land/std@0.95.0/fs/mod.ts";
|
||||||
export * as Colors from "https://deno.land/std@0.65.0/fmt/colors.ts";
|
export * as Colors from "https://deno.land/std@0.95.0/fmt/colors.ts";
|
||||||
export * as Path from "https://deno.land/std@0.65.0/path/mod.ts";
|
export * as Path from "https://deno.land/std@0.95.0/path/mod.ts";
|
||||||
|
1
cli/dpm.ts
Normal file
1
cli/dpm.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
import "./denreg.ts";
|
@ -14,6 +14,9 @@ export interface IMeta {
|
|||||||
prepublish?: string | string[];
|
prepublish?: string | string[];
|
||||||
postpublish?: string | string[];
|
postpublish?: string | string[];
|
||||||
};
|
};
|
||||||
|
scripts?: {
|
||||||
|
[key: string]: string | string[];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let verbose = false;
|
let verbose = false;
|
||||||
@ -42,16 +45,18 @@ export async function setConfig(name: string, value: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const readJson = (name: string) => Deno.readTextFile(name).then(JSON.parse);
|
||||||
|
const writeJson = (name: string, value: any, spaces?: string) =>
|
||||||
|
Deno.writeTextFile(name, JSON.stringify(value, null, spaces));
|
||||||
|
|
||||||
export async function getMeta() {
|
export async function getMeta() {
|
||||||
log("Reading meta.json");
|
log("Reading meta.json");
|
||||||
return (await FS.readJson("meta.json")) as IMeta;
|
return (await readJson("meta.json")) as IMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setMeta(meta: IMeta): Promise<void> {
|
export async function setMeta(meta: IMeta): Promise<void> {
|
||||||
log("Saving meta.json");
|
log("Saving meta.json");
|
||||||
return FS.writeJson("meta.json", meta, {
|
return writeJson("meta.json", meta, " ");
|
||||||
spaces: " ",
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let interactive = true;
|
let interactive = true;
|
||||||
|
26
cli/helper/permission.ts
Normal file
26
cli/helper/permission.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { Colors } from "../deps.ts";
|
||||||
|
|
||||||
|
export const checkPermOrExit = (name: string, err: string) =>
|
||||||
|
Deno.permissions.query({ name: name as any }).then((res) => {
|
||||||
|
if (res.state !== "granted") {
|
||||||
|
console.log(Colors.bold(Colors.red(err)));
|
||||||
|
Deno.exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const requestPermOrExit = (name: string, err: string) => {
|
||||||
|
Deno.permissions
|
||||||
|
.query({ name: name as any })
|
||||||
|
.then((res) => {
|
||||||
|
if (res.state === "prompt") {
|
||||||
|
return Deno.permissions.request({ name: name as any });
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.state !== "granted") {
|
||||||
|
console.log(Colors.bold(Colors.red(err)));
|
||||||
|
Deno.exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
51
cli/helper/run_script.ts
Normal file
51
cli/helper/run_script.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { Colors } from "../deps.ts";
|
||||||
|
import { checkPermOrExit } from "../helper/permission.ts";
|
||||||
|
|
||||||
|
export async function runScript(script: string) {
|
||||||
|
await checkPermOrExit(
|
||||||
|
"run",
|
||||||
|
"Requires --allow-run to run scripts and hooks"
|
||||||
|
);
|
||||||
|
console.log(Colors.bold(Colors.blue("Running script:")), script);
|
||||||
|
const runPerm = await Deno.permissions.query({
|
||||||
|
name: "run",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (runPerm.state !== "granted") {
|
||||||
|
console.log(
|
||||||
|
Colors.red("Missing --allow-run permission. Cannot run hooks!")
|
||||||
|
);
|
||||||
|
throw new Error("Missing --allow-run permission. Cannot run hooks!");
|
||||||
|
}
|
||||||
|
|
||||||
|
const process = Deno.run({
|
||||||
|
cmd: ["deno", "run", "-A", "--unstable", script],
|
||||||
|
});
|
||||||
|
|
||||||
|
const status = await process.status();
|
||||||
|
|
||||||
|
console.log(Colors.bold(Colors.blue("Finished script:")), script);
|
||||||
|
|
||||||
|
if (!status.success) {
|
||||||
|
throw new Error(
|
||||||
|
"A script did not complete sucessfully. This is not a issue of denreg!"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function runHooks(hooks: undefined | string | string[]) {
|
||||||
|
if (!hooks) return;
|
||||||
|
if (typeof hooks === "string") {
|
||||||
|
hooks = [hooks];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const hook of hooks) {
|
||||||
|
try {
|
||||||
|
await runScript(hook);
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(
|
||||||
|
"A hook did not complete sucessfully. This is not a issue of denreg!"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@denreg-cli",
|
"name": "@denreg-cli",
|
||||||
"version": "0.2.10",
|
"version": "0.3.3",
|
||||||
"description": "CLI for the DenReg package registry",
|
"description": "CLI for the DenReg package registry",
|
||||||
"author": "Fabian Stamm <dev@fabianstamm.de>",
|
"author": "Fabian Stamm <dev@fabianstamm.de>",
|
||||||
"contributors": [],
|
"contributors": [],
|
||||||
@ -9,7 +9,10 @@
|
|||||||
"**/*.js",
|
"**/*.js",
|
||||||
"README.md"
|
"README.md"
|
||||||
],
|
],
|
||||||
|
"scripts": {
|
||||||
|
"test": "version.ts"
|
||||||
|
},
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"prepublish": "pre.ts"
|
"prepublish": "pre.ts"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import { FS } from "./deps.ts";
|
import { FS } from "./deps.ts";
|
||||||
|
|
||||||
const meta = (await FS.readJson("./meta.json")) as any;
|
const meta = (await Deno.readTextFile("./meta.json").then(JSON.parse)) as any;
|
||||||
|
|
||||||
await Deno.writeTextFile(
|
await Deno.writeTextFile(
|
||||||
"version.ts",
|
"version.ts",
|
||||||
|
0
cli/test.ts
Normal file
0
cli/test.ts
Normal file
@ -1 +1 @@
|
|||||||
export const version = "0.2.10"
|
export const version = "0.3.3"
|
@ -1,9 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "@denreg-jsx",
|
"name": "@denreg-jsx",
|
||||||
"version": "0.1.0",
|
"version": "0.1.2",
|
||||||
"description": "Denreg JSX renderer",
|
"description": "Denreg JSX renderer",
|
||||||
"author": "Fabian Stamm <dev@fabianstamm.de>",
|
"author": "Fabian Stamm <dev@fabianstamm.de>",
|
||||||
"contributors": [],
|
"contributors": [],
|
||||||
"deprecated": false,
|
"deprecated": false,
|
||||||
"files": ["**/*.ts", "**/*.js", "tsconfig.json", "README.md"]
|
"files": [
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.js",
|
||||||
|
"tsconfig.json",
|
||||||
|
"README.md"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
52
jsx/mod.ts
52
jsx/mod.ts
@ -9,10 +9,8 @@ declare namespace JSX {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Fragment };
|
|
||||||
|
|
||||||
export type Element = {
|
export type Element = {
|
||||||
component: Component | string;
|
component: Component | string | typeof Fragment;
|
||||||
props: any;
|
props: any;
|
||||||
children: any[];
|
children: any[];
|
||||||
};
|
};
|
||||||
@ -34,11 +32,18 @@ export function h(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const createElement = h;
|
||||||
|
|
||||||
|
export { Fragment, createElement };
|
||||||
|
|
||||||
export async function renderSSR(element: Element | string): Promise<string> {
|
export async function renderSSR(element: Element | string): Promise<string> {
|
||||||
if (typeof element === "string") return element;
|
if (typeof element === "string") return element;
|
||||||
else if (typeof element.component === "string")
|
else if (typeof element.component === "string")
|
||||||
return await renderHTML(element as Element);
|
return await renderHTML(element as Element);
|
||||||
else if (typeof element.component === "function")
|
else if (
|
||||||
|
typeof element.component === "function" ||
|
||||||
|
element.component === Fragment
|
||||||
|
)
|
||||||
return await renderCustom(element as Element);
|
return await renderCustom(element as Element);
|
||||||
|
|
||||||
console.warn("renderSSR: invalid element", element);
|
console.warn("renderSSR: invalid element", element);
|
||||||
@ -83,7 +88,6 @@ async function renderHTML(element: Element) {
|
|||||||
if (typeof element.component !== "string")
|
if (typeof element.component !== "string")
|
||||||
throw new Error("Internal consistency error");
|
throw new Error("Internal consistency error");
|
||||||
|
|
||||||
console.log("Element:", element.component);
|
|
||||||
let props = "";
|
let props = "";
|
||||||
|
|
||||||
for (const key in element.props) {
|
for (const key in element.props) {
|
||||||
@ -101,7 +105,6 @@ async function renderHTML(element: Element) {
|
|||||||
inner = element.props["innerHTML"];
|
inner = element.props["innerHTML"];
|
||||||
} else {
|
} else {
|
||||||
const children = cleanChildren(element.children);
|
const children = cleanChildren(element.children);
|
||||||
if (tag == "body") console.log(element.children, children);
|
|
||||||
inner = (
|
inner = (
|
||||||
await Promise.all(children.map((child) => renderSSR(child)))
|
await Promise.all(children.map((child) => renderSSR(child)))
|
||||||
).join("");
|
).join("");
|
||||||
@ -114,20 +117,29 @@ async function renderCustom(element: Element) {
|
|||||||
if (typeof element.component === "string")
|
if (typeof element.component === "string")
|
||||||
throw new Error("Internal consistency error");
|
throw new Error("Internal consistency error");
|
||||||
|
|
||||||
console.log("Component:", element.component);
|
if (element.component === Fragment) {
|
||||||
const res = await Promise.resolve(
|
const ch = (
|
||||||
element.component(
|
await Promise.all(
|
||||||
{
|
cleanChildren(element.children).map((child) => renderSSR(child))
|
||||||
...element.props,
|
)
|
||||||
children: element.children,
|
).join("");
|
||||||
},
|
|
||||||
element.children
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const ch = (
|
return ch;
|
||||||
await Promise.all(cleanChildren(res).map((child) => renderSSR(child)))
|
} else {
|
||||||
).join("");
|
const res = await Promise.resolve(
|
||||||
|
element.component(
|
||||||
|
{
|
||||||
|
...element.props,
|
||||||
|
children: element.children,
|
||||||
|
},
|
||||||
|
element.children
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return ch;
|
const ch = (
|
||||||
|
await Promise.all(cleanChildren(res).map((child) => renderSSR(child)))
|
||||||
|
).join("");
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ WORKDIR /app
|
|||||||
|
|
||||||
ADD src /app/src
|
ADD src /app/src
|
||||||
ADD public /app/public
|
ADD public /app/public
|
||||||
|
ADD tsconfig.json /app/
|
||||||
RUN /usr/bin/deno cache --unstable src/registry.ts
|
RUN /usr/bin/deno cache --unstable --config /app/tsconfig.json src/registry.ts
|
||||||
|
|
||||||
VOLUME [ "/app/data" ]
|
VOLUME [ "/app/data" ]
|
||||||
ENTRYPOINT [ "/usr/bin/deno", "run", "-A", "--unstable", "/app/src/registry.ts" ]
|
ENTRYPOINT [ "/usr/bin/deno", "run", "-A", "--unstable", "--config", "/app/tsconfig.json", "/app/src/registry.ts" ]
|
||||||
|
@ -15,6 +15,7 @@ const config =
|
|||||||
|
|
||||||
if (!config.user) config.user = {};
|
if (!config.user) config.user = {};
|
||||||
if (!config.web) config.web = {};
|
if (!config.web) config.web = {};
|
||||||
|
if (!config.general) config.general = {};
|
||||||
|
|
||||||
const env = Deno.env.toObject();
|
const env = Deno.env.toObject();
|
||||||
|
|
||||||
@ -44,14 +45,27 @@ for (const key in env) {
|
|||||||
case "S3_REGION":
|
case "S3_REGION":
|
||||||
config.s3 = { ...(config.s3 || {}), region: env[key] };
|
config.s3 = { ...(config.s3 || {}), region: env[key] };
|
||||||
break;
|
break;
|
||||||
|
case "WEB_URL":
|
||||||
|
config.web.url = env[key];
|
||||||
|
break;
|
||||||
case "WEB_TRACKING":
|
case "WEB_TRACKING":
|
||||||
config.web.tracking = env[key];
|
config.web.tracking = env[key];
|
||||||
break;
|
break;
|
||||||
|
case "GENERAL_DEV":
|
||||||
|
config.general.dev = env[key] === "true";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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));
|
console.log("Known users:", Object.keys(config.user));
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
@ -1,40 +1,30 @@
|
|||||||
export * as S3 from "https://deno.land/x/s3@0.2.0/mod.ts";
|
// @deno-types="./types/hotfix.d.ts"
|
||||||
export { S3Error } from "https://deno.land/x/s3@0.2.0/src/error.ts";
|
|
||||||
|
|
||||||
export * as Ini from "https://deno.hibas123.de/raw/ini@0.0.1/mod.ts";
|
export * as S3 from "https://deno.land/x/s3@0.3.0/mod.ts";
|
||||||
|
export { S3Error } from "https://deno.land/x/s3@0.3.0/src/error.ts";
|
||||||
|
|
||||||
export * as ABC from "https://deno.land/x/abc@v1/mod.ts";
|
export * as Ini from "https://deno.hibas123.de/raw/ini@0.0.3/mod.ts";
|
||||||
export * as CorsMW from "https://deno.land/x/abc@v1/middleware/cors.ts";
|
|
||||||
export * as LoggerMW from "https://deno.land/x/abc@v1/middleware/logger.ts";
|
|
||||||
|
|
||||||
export * as Path from "https://deno.land/std@0.74.0/path/mod.ts";
|
export * as ABC from "https://deno.land/x/abc@v1.2.4/mod.ts";
|
||||||
export * as FS from "https://deno.land/std@0.74.0/fs/mod.ts";
|
export * as CorsMW from "https://deno.land/x/abc@v1.2.4/middleware/cors.ts";
|
||||||
export * as Base64 from "https://deno.land/std@0.74.0/encoding/base64.ts";
|
export * as LoggerMW from "https://deno.land/x/abc@v1.2.4/middleware/logger.ts";
|
||||||
export * as Hash from "https://deno.land/std@0.74.0/hash/mod.ts";
|
|
||||||
export * as Colors from "https://deno.land/std@0.74.0/fmt/colors.ts";
|
export * as Path from "https://deno.land/std@0.83.0/path/mod.ts";
|
||||||
|
export * as FS from "https://deno.land/std@0.83.0/fs/mod.ts";
|
||||||
|
export * as Base64 from "https://deno.land/std@0.83.0/encoding/base64.ts";
|
||||||
|
export * as Hash from "https://deno.land/std@0.83.0/hash/mod.ts";
|
||||||
|
export * as Colors from "https://deno.land/std@0.83.0/fmt/colors.ts";
|
||||||
|
|
||||||
export * as Compress from "https://git.stamm.me/Deno/DenReg/raw/branch/master/tar/mod.ts";
|
export * as Compress from "https://git.stamm.me/Deno/DenReg/raw/branch/master/tar/mod.ts";
|
||||||
|
|
||||||
export { default as Prism } from "https://cdn.skypack.dev/prismjs";
|
export { default as Prism } from "https://cdn.skypack.dev/prismjs";
|
||||||
|
|
||||||
// export { Marked } from "https://deno.land/x/markdown/mod.ts";
|
|
||||||
|
|
||||||
// export { Marked } from "../../markdown/mod.ts";
|
|
||||||
export { Marked } from "https://deno.hibas123.de/raw/markdown/mod.ts";
|
export { Marked } from "https://deno.hibas123.de/raw/markdown/mod.ts";
|
||||||
|
|
||||||
import DS from "https://raw.githubusercontent.com/hibas123/dndb/master/mod.ts";
|
import DS from "https://raw.githubusercontent.com/hibas123/dndb/master/mod.ts";
|
||||||
|
|
||||||
/// <reference path="./types/jsx.d.ts" />
|
import * as Pico from "https://deno.hibas123.de/raw/@denreg-jsx@0.1.2/mod.ts";
|
||||||
export {
|
|
||||||
React,
|
|
||||||
jsx,
|
|
||||||
Fragment,
|
|
||||||
} from "https://deno.hibas123.de/raw/jsx-html/mod.ts";
|
|
||||||
|
|
||||||
// export {
|
export { Pico };
|
||||||
// React,
|
|
||||||
// jsx,
|
|
||||||
// Fragment,
|
|
||||||
// } from "https://raw.githubusercontent.com/apiel/jsx-html/master/mod.ts";
|
|
||||||
|
|
||||||
export const Datastore = DS;
|
export const Datastore = DS;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/// <reference path="./types/jsx.d.ts" />
|
// /// <reference path="./types/jsx.d.ts" />
|
||||||
import { ABC, CorsMW, LoggerMW, Path } from "./deps.ts";
|
import { ABC, CorsMW, LoggerMW, Path } from "./deps.ts";
|
||||||
import config from "./config.ts";
|
import config from "./config.ts";
|
||||||
|
|
||||||
@ -38,9 +38,11 @@ api(app.group("/api"));
|
|||||||
import raw from "./http/raw.ts";
|
import raw from "./http/raw.ts";
|
||||||
raw(app.group("/raw"));
|
raw(app.group("/raw"));
|
||||||
|
|
||||||
|
import intellisense from "./http/intellisense.ts";
|
||||||
|
intellisense(app.group("/.well-known"));
|
||||||
|
|
||||||
import view from "./http/views.ts";
|
import view from "./http/views.ts";
|
||||||
view(app);
|
view(app);
|
||||||
|
|
||||||
// function logNode(router: Node, indent = 0) {
|
// function logNode(router: Node, indent = 0) {
|
||||||
// trees.map((tree) => {
|
// trees.map((tree) => {
|
||||||
// console.log("Path:", tree.path);
|
// console.log("Path:", tree.path);
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
import { ABC, Path, Compress, FS, Colors, S3Error } from "../deps.ts";
|
import { ABC, Path, Compress, FS, Colors, S3Error } from "../deps.ts";
|
||||||
|
|
||||||
import bucket from "../s3.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";
|
import db, { IPackage } from "../db.ts";
|
||||||
|
|
||||||
@ -21,8 +27,60 @@ export default function api(g: ABC.Group) {
|
|||||||
cacheControl
|
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("/getapikey", getApiKey, basicauth("api"));
|
||||||
g.post("/package/:name", uploadPackage, cacheControl, 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) {
|
// async function getApiKey(ctx: ABC.Context) {
|
||||||
|
43
registry/src/http/intellisense.ts
Normal file
43
registry/src/http/intellisense.ts
Normal file
@ -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`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
@ -1,8 +1,12 @@
|
|||||||
/// <reference path="./types/jsx.d.ts" />
|
// / <reference path="./types/jsx.d.ts" />
|
||||||
import { React, jsx } from "./deps.ts";
|
import { Pico } from "./deps.ts";
|
||||||
|
|
||||||
import config from "./config.ts";
|
import config from "./config.ts";
|
||||||
|
|
||||||
|
const React = {
|
||||||
|
createElement: Pico.h.bind(Pico),
|
||||||
|
};
|
||||||
|
|
||||||
class StringReader implements Deno.Reader {
|
class StringReader implements Deno.Reader {
|
||||||
private data: Uint8Array;
|
private data: Uint8Array;
|
||||||
private offset = 0;
|
private offset = 0;
|
||||||
@ -25,15 +29,49 @@ class StringReader implements Deno.Reader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ELM = any;
|
||||||
|
|
||||||
|
type Component = () => ELM;
|
||||||
|
|
||||||
|
const componentCache = new Map<string, Component>();
|
||||||
|
|
||||||
|
async function loadComponent(name: string) {
|
||||||
|
let mod = componentCache.get(name);
|
||||||
|
if (!mod || config.general.dev) {
|
||||||
|
mod = (await import(`./views/${name}.tsx`)).default;
|
||||||
|
if (!mod) throw new Error("Invalid component " + name);
|
||||||
|
componentCache.set(name, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(
|
export default async function render(
|
||||||
name: string,
|
name: string,
|
||||||
data: any
|
data: any
|
||||||
): Promise<Deno.Reader> {
|
): Promise<Deno.Reader> {
|
||||||
const component: {
|
const Component = await loadComponent(name);
|
||||||
default: () => JSX.IntrinsicElements | Promise<JSX.IntrinsicElements>;
|
|
||||||
} = await import(`./views/${name}.tsx`);
|
|
||||||
|
|
||||||
const res = await (<component.default {...data} />).render();
|
//@ts-ignore
|
||||||
|
const res = await Pico.renderSSR(<Component {...data} />);
|
||||||
|
|
||||||
return new StringReader("<!DOCTYPE html>\n" + (res as string));
|
return new StringReader("<!DOCTYPE html>\n" + res);
|
||||||
}
|
}
|
||||||
|
4
registry/src/types/hotfix.d.ts
vendored
Normal file
4
registry/src/types/hotfix.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// fixes an issue in std@0.80.0
|
||||||
|
interface ReadableStream<R> {
|
||||||
|
getIterator(): any;
|
||||||
|
}
|
5
registry/src/types/jsx.d.ts
vendored
5
registry/src/types/jsx.d.ts
vendored
@ -1,5 +0,0 @@
|
|||||||
declare namespace JSX {
|
|
||||||
interface IntrinsicElements {
|
|
||||||
[elemName: string]: any;
|
|
||||||
}
|
|
||||||
}
|
|
@ -99,7 +99,7 @@ export function getAbsolutePackageVersion(
|
|||||||
|
|
||||||
const versions = pkg.versions.sort(sortVersions).reverse();
|
const versions = pkg.versions.sort(sortVersions).reverse();
|
||||||
|
|
||||||
if (!version) {
|
if (!version || version === "latest") {
|
||||||
version = versions[0];
|
version = versions[0];
|
||||||
} else {
|
} else {
|
||||||
const v = versions.filter((e) => e.startsWith(version as string));
|
const v = versions.filter((e) => e.startsWith(version as string));
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/// <reference path="../types/jsx.d.ts" />
|
import { Pico } from "../deps.ts";
|
||||||
import { React } from "../deps.ts";
|
|
||||||
import config from "../config.ts";
|
import config from "../config.ts";
|
||||||
|
|
||||||
const styles = new TextDecoder().decode(
|
const styles = new TextDecoder().decode(
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/// <reference path="../types/jsx.d.ts" />
|
import { Pico, Marked } from "../deps.ts";
|
||||||
import { React, Marked } from "../deps.ts";
|
|
||||||
import type { IPackage } from "../db.ts";
|
import type { IPackage } from "../db.ts";
|
||||||
import { sortVersions } from "../utils.ts";
|
import { sortVersions } from "../utils.ts";
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/// <reference path="../types/jsx.d.ts" />
|
import { Pico } from "../deps.ts";
|
||||||
import { React, Fragment } from "../deps.ts";
|
|
||||||
|
|
||||||
export function Main(a: any, children: any) {
|
export function Main(a: any, children: any) {
|
||||||
return (
|
return (
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/// <reference path="../types/jsx.d.ts" />
|
// /// <reference path="../types/jsx.d.ts" />
|
||||||
import { React, Fragment, Marked } from "../deps.ts";
|
import { Pico, Marked } from "../deps.ts";
|
||||||
import type { IPackage } from "../db.ts";
|
import type { IPackage } from "../db.ts";
|
||||||
|
|
||||||
export default async function index({
|
export default async function index({
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/// <reference path="../types/jsx.d.ts" />
|
import { Pico } from "../deps.ts";
|
||||||
import { React } from "../deps.ts";
|
|
||||||
import Base from "./_base.tsx";
|
import Base from "./_base.tsx";
|
||||||
import type { IPackage } from "../db.ts";
|
import type { IPackage } from "../db.ts";
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/// <reference path="../types/jsx.d.ts" />
|
import { Pico } from "../deps.ts";
|
||||||
import { React } from "../deps.ts";
|
|
||||||
import Base from "./_base.tsx";
|
import Base from "./_base.tsx";
|
||||||
import type { IPackage } from "../db.ts";
|
import type { IPackage } from "../db.ts";
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/// <reference path="../types/jsx.d.ts" />
|
import { Pico } from "../deps.ts";
|
||||||
import { React, Fragment } from "../deps.ts";
|
|
||||||
import Base from "./_base.tsx";
|
import Base from "./_base.tsx";
|
||||||
import type { IPackage } from "../db.ts";
|
import type { IPackage } from "../db.ts";
|
||||||
import { sortVersions } from "../utils.ts";
|
import { sortVersions } from "../utils.ts";
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/// <reference path="../types/jsx.d.ts" />
|
import { Pico, Marked } from "../deps.ts";
|
||||||
import { React, Fragment, Marked } from "../deps.ts";
|
|
||||||
import Base from "./_base.tsx";
|
import Base from "./_base.tsx";
|
||||||
import type { IPackage } from "../db.ts";
|
import type { IPackage } from "../db.ts";
|
||||||
import { sortVersions, getFile, getAbsolutePackageVersion } from "../utils.ts";
|
import { sortVersions, getFile, getAbsolutePackageVersion } from "../utils.ts";
|
||||||
|
10
registry/tsconfig.json
Normal file
10
registry/tsconfig.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext", "deno.ns", "deno.unstable"],
|
||||||
|
"jsx": "react",
|
||||||
|
"jsxFactory": "Pico.h",
|
||||||
|
"jsxFragmentFactory": "Pico.Fragment",
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"strictPropertyInitialization": false
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user