Compare commits
40 Commits
6bfcb3642d
...
1.0.2
Author | SHA1 | Date | |
---|---|---|---|
ae69bcd48e | |||
675a73e551 | |||
310c8e12fa | |||
a14a5b9462 | |||
a0fef1ef76 | |||
3cda4ee8c8 | |||
e5829d9a4f | |||
3efe4fc34e | |||
22a447604b | |||
9dfb8d65d3 | |||
6bc090e51b | |||
965ca33d33 | |||
0202946813 | |||
53a11eccf6 | |||
325c1a4d7d | |||
c718e8898d | |||
6fe3ddbd37 | |||
79bcef0698 | |||
2af5d4f823 | |||
7c1166bf87 | |||
639287663d | |||
fbbb66d5af | |||
df1f4965ad | |||
10930db13d | |||
6b88be1b18 | |||
c9bd5c7d18 | |||
d1244ac0a7 | |||
e56d8b4548 | |||
ed1ce0cc0f | |||
252bf4aac3 | |||
a3a7370be0 | |||
10a7c26642 | |||
7e821f9771 | |||
1b7c4847dc | |||
2194bf199e | |||
f3f6f0d7bc | |||
13bc1b07cd | |||
1b2d85eeef | |||
46d8f8b289 | |||
78c40e4819 |
@ -12,7 +12,7 @@ steps:
|
||||
from_secret: docker_password
|
||||
auto_tag: true
|
||||
context: registry
|
||||
repo: hibas123.azurecr.io/denreg
|
||||
registry: hibas123.azurecr.io
|
||||
repo: docker.hibas123.de/denreg
|
||||
registry: docker.hibas123.de
|
||||
dockerfile: registry/Dockerfile
|
||||
debug: false
|
||||
|
36
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
# .github/workflows/ci.yml
|
||||
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
MY_DOCKER_USERNAME: ${{ secrets.MY_DOCKER_USERNAME }}
|
||||
MY_DOCKER_PASSWORD: ${{ secrets.MY_DOCKER_PASSWORD }}
|
||||
FORCE_COLOR: 1
|
||||
steps:
|
||||
- uses: https://github.com/earthly/actions-setup@v1
|
||||
with:
|
||||
version: v0.7.0
|
||||
- uses: actions/checkout@v2
|
||||
- name: Put back the git branch into git (Earthly uses it for tagging)
|
||||
run: |
|
||||
branch=""
|
||||
if [ -n "$GITHUB_HEAD_REF" ]; then
|
||||
branch="$GITHUB_HEAD_REF"
|
||||
else
|
||||
branch="${GITHUB_REF##*/}"
|
||||
fi
|
||||
git checkout -b "$branch" || true
|
||||
- name: Docker Login
|
||||
run: docker login git.hibas.dev --username "$MY_DOCKER_USERNAME" --password "$MY_DOCKER_PASSWORD"
|
||||
- name: Earthly version
|
||||
run: earthly --version
|
||||
- name: Run build
|
||||
run: cd registry && earthly --push +docker-multi
|
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
test.ini
|
9
.vscode/settings.json
vendored
@ -1,5 +1,12 @@
|
||||
{
|
||||
"deno.enable": true,
|
||||
"deno.unstable": true,
|
||||
"debug.javascript.usePreview": false
|
||||
"debug.javascript.usePreview": false,
|
||||
"deno.import_intellisense_origins": {
|
||||
"https://deno.land": true
|
||||
},
|
||||
"deno.suggest.imports.hosts": {
|
||||
"https://deno.land": true,
|
||||
"https://deno.hibas123.de": false
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Colors, Cliffy } from "../deps.ts";
|
||||
import { Colors, CliffyPrompt } from "../deps.ts";
|
||||
|
||||
import { getMeta, setMeta, log } from "../global.ts";
|
||||
|
||||
export default async function deprecate(options: any) {
|
||||
const meta = await getMeta();
|
||||
|
||||
const res = await Cliffy.Confirm.prompt(
|
||||
const res = await CliffyPrompt.Confirm.prompt(
|
||||
"Are you sure you want to deprecat this package?"
|
||||
);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Cliffy, Path, FS } from "../deps.ts";
|
||||
import { CliffyPrompt, Path, FS } from "../deps.ts";
|
||||
import {
|
||||
getMeta,
|
||||
setMeta,
|
||||
@ -11,7 +11,7 @@ export default async function init() {
|
||||
let existing = {};
|
||||
try {
|
||||
existing = await getMeta();
|
||||
} catch (err) {}
|
||||
} catch (err) { }
|
||||
let meta: IMeta = {
|
||||
name: Path.basename(Deno.cwd()).toLowerCase().replace(/\s+/g, "-"),
|
||||
version: "0.0.1",
|
||||
@ -23,21 +23,21 @@ export default async function init() {
|
||||
};
|
||||
|
||||
if (isInteractive()) {
|
||||
meta.name = await Cliffy.Input.prompt({
|
||||
meta.name = await CliffyPrompt.Input.prompt({
|
||||
message: "What's the name of your package?",
|
||||
default: meta.name,
|
||||
});
|
||||
meta.description = await Cliffy.Input.prompt({
|
||||
meta.description = await CliffyPrompt.Input.prompt({
|
||||
message: "What's the description of your package?",
|
||||
default: meta.description,
|
||||
});
|
||||
meta.author = await Cliffy.Input.prompt({
|
||||
meta.author = await CliffyPrompt.Input.prompt({
|
||||
message: "Who's the author of your package?",
|
||||
default: meta.author,
|
||||
});
|
||||
|
||||
if (!(await FS.exists("README.md"))) {
|
||||
const res = await Cliffy.Confirm.prompt({
|
||||
const res = await CliffyPrompt.Confirm.prompt({
|
||||
message: "Autogenerate README?",
|
||||
default: true,
|
||||
});
|
||||
|
@ -1,64 +1,31 @@
|
||||
import { Colors, Path, FS, Compress, Base64 } from "../deps.ts";
|
||||
import { getMeta, IMeta, log, getConfig } from "../global.ts";
|
||||
import { runHooks } from "../helper/run_script.ts";
|
||||
import { ServerError } from "../helper/server_error.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);
|
||||
}
|
||||
}
|
||||
import { checkPermOrExit } from "../helper/permission.ts";
|
||||
|
||||
export default async function publish(options: { dry: boolean }) {
|
||||
const meta: IMeta = await getMeta();
|
||||
const originalMeta = await getMeta();
|
||||
|
||||
if (originalMeta.hooks) {
|
||||
log("Running prepublish hooks");
|
||||
await runHooks(originalMeta.hooks.prepublish);
|
||||
}
|
||||
|
||||
const meta = await getMeta();
|
||||
|
||||
//TODO: Output Diff between original and result meta
|
||||
|
||||
if (!meta.name) throw new Error("name is not set in meta.json");
|
||||
if (!meta.version) throw new Error("version is not set in meta.json");
|
||||
if (!meta.files || !Array.isArray(meta.files) || meta.files.length <= 0)
|
||||
throw new Error("files is not set or empty in meta.json");
|
||||
|
||||
if (meta.hooks) {
|
||||
log("Running prepublish hooks");
|
||||
await runHooks(meta.hooks.prepublish);
|
||||
}
|
||||
|
||||
const tmpDir = await Deno.makeTempDir();
|
||||
const packedFile = (await Deno.makeTempFile()) + ".tar";
|
||||
|
||||
try {
|
||||
const walker = FS.walk(".", {
|
||||
const walker = FS.walk(meta.root || ".", {
|
||||
includeDirs: false,
|
||||
includeFiles: true,
|
||||
match: meta.files.map((file) => Path.globToRegExp(file)),
|
||||
@ -66,17 +33,18 @@ export default async function publish(options: { dry: boolean }) {
|
||||
|
||||
log("Copying files to package to", tmpDir);
|
||||
|
||||
const copy = async (path: string) => {
|
||||
const dest = Path.join(tmpDir, path);
|
||||
const copy = async (path: string, abs?: boolean) => {
|
||||
const relative = abs ? path : Path.relative(meta.root || ".", path);
|
||||
log("Adding file:", path, "as", relative);
|
||||
const dest = Path.join(tmpDir, relative);
|
||||
await FS.ensureDir(Path.dirname(dest));
|
||||
await FS.copy(path, dest);
|
||||
};
|
||||
|
||||
await copy("meta.json");
|
||||
await copy("meta.json", true);
|
||||
|
||||
for await (const file of walker) {
|
||||
await copy(file.path);
|
||||
log("Adding file:", file.path);
|
||||
}
|
||||
|
||||
log("Compressing files into", packedFile);
|
||||
@ -88,9 +56,16 @@ export default async function publish(options: { dry: boolean }) {
|
||||
const url = new URL(getConfig("registry"));
|
||||
url.pathname = "/api/package/" + meta.name;
|
||||
|
||||
if (!options.dry) {
|
||||
log("Uploading new package version");
|
||||
console.log(
|
||||
"Pushing version",
|
||||
Colors.blue(meta.version),
|
||||
"to repository"
|
||||
);
|
||||
|
||||
if (!options.dry) {
|
||||
await checkPermOrExit("net", "Net permission required for publishing");
|
||||
|
||||
log("Uploading new package version");
|
||||
await fetch(url, {
|
||||
method: "POST",
|
||||
body: await Deno.readFile(packedFile),
|
||||
|
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,23 +1,23 @@
|
||||
import { Cliffy } from "../deps.ts";
|
||||
import { CliffyPrompt } from "../deps.ts";
|
||||
|
||||
import { getConfig, setConfig } from "../global.ts";
|
||||
|
||||
export default async function setup() {
|
||||
const registry = await Cliffy.Input.prompt({
|
||||
const registry = await CliffyPrompt.Input.prompt({
|
||||
message: "What's your registry?",
|
||||
default: getConfig("registry"),
|
||||
});
|
||||
const username = await Cliffy.Input.prompt({
|
||||
const username = await CliffyPrompt.Input.prompt({
|
||||
message: "What's your username?",
|
||||
default: getConfig("username"),
|
||||
});
|
||||
const password = await Cliffy.Secret.prompt({
|
||||
const password = await CliffyPrompt.Secret.prompt({
|
||||
message: "What's your password?",
|
||||
hidden: true,
|
||||
default: getConfig("password"),
|
||||
});
|
||||
|
||||
const author = await Cliffy.Input.prompt({
|
||||
const author = await CliffyPrompt.Input.prompt({
|
||||
message: "Who are you? (optional) Name <email@example.com>",
|
||||
default: getConfig("author"),
|
||||
});
|
||||
|
@ -1,25 +1,63 @@
|
||||
import { Cliffy, Colors } from "../deps.ts";
|
||||
import { CliffyPrompt, Colors } from "../deps.ts";
|
||||
import { version } from "../version.ts";
|
||||
import { requestPermOrExit } from "../helper/permission.ts";
|
||||
|
||||
export default async function upgrade() {
|
||||
const res = await Cliffy.Confirm.prompt({
|
||||
message: "Are you sure you want to upgrade the denreg cli?",
|
||||
await requestPermOrExit(
|
||||
"net",
|
||||
"Net permission required to fetch new version"
|
||||
);
|
||||
const meta = await fetch(
|
||||
"https://deno.hibas123.de/raw/@denreg-cli/meta.json"
|
||||
).then((e) => e.json());
|
||||
|
||||
if (meta.version === version) {
|
||||
const res = await CliffyPrompt.Confirm.prompt({
|
||||
message: Colors.yellow("No update available!") + " Continue?",
|
||||
default: false,
|
||||
});
|
||||
if (!res) return;
|
||||
}
|
||||
|
||||
const res = await CliffyPrompt.Confirm.prompt({
|
||||
message: "Are you sure you want to upgrade?",
|
||||
default: true,
|
||||
});
|
||||
|
||||
if (res) {
|
||||
const process = Deno.run({
|
||||
cmd: [
|
||||
"deno",
|
||||
"install",
|
||||
"-A",
|
||||
"--unstable",
|
||||
"-f",
|
||||
"https://deno.hibas123.de/raw/@denreg-cli/denreg.ts",
|
||||
],
|
||||
const cmd_base = ["deno", "install", "-A", "--unstable", "-f"];
|
||||
|
||||
const cmd1 = [
|
||||
...cmd_base,
|
||||
`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();
|
||||
if (!s) {
|
||||
const s1 = await process1.status();
|
||||
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!"));
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,20 @@
|
||||
import { Cliffy, Path, Colors } from "./deps.ts";
|
||||
import { CliffyCommand, 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 { version } from "./version.ts";
|
||||
|
||||
import setupCMD from "./commands/setup.ts";
|
||||
import initCMD from "./commands/init.ts";
|
||||
import bumpCMD from "./commands/bump.ts";
|
||||
import publishCMD from "./commands/publish.ts";
|
||||
import deprecateCMD from "./commands/deprecate.ts";
|
||||
import upgradeCMD from "./commands/upgrade.ts";
|
||||
import runCMD from "./commands/run.ts";
|
||||
|
||||
const HOME_FOLDER = Deno.env.get("HOME") || Deno.env.get("USERPROFILE") || "";
|
||||
|
||||
@ -26,7 +32,7 @@ const commandWrapper = (cmd: CommandHandler) => {
|
||||
opts = params;
|
||||
};
|
||||
};
|
||||
const flags = await new Cliffy.Command()
|
||||
const flags = await new CliffyCommand.Command()
|
||||
.name("denreg")
|
||||
.version(version)
|
||||
.description("CLI for the Open Source DenReg package registry")
|
||||
@ -44,13 +50,13 @@ const flags = await new Cliffy.Command()
|
||||
})
|
||||
.command(
|
||||
"setup",
|
||||
new Cliffy.Command()
|
||||
new CliffyCommand.Command()
|
||||
.description("Configure cli")
|
||||
.action(commandWrapper(setupCMD))
|
||||
)
|
||||
.command(
|
||||
"publish",
|
||||
new Cliffy.Command()
|
||||
new CliffyCommand.Command()
|
||||
.description("Upload package")
|
||||
.action(commandWrapper(publishCMD))
|
||||
.option("-d, --dry [dry:boolean]", "Dry run", {
|
||||
@ -59,13 +65,13 @@ const flags = await new Cliffy.Command()
|
||||
)
|
||||
.command(
|
||||
"init",
|
||||
new Cliffy.Command()
|
||||
new CliffyCommand.Command()
|
||||
.description("Create meta.json")
|
||||
.action(commandWrapper(initCMD))
|
||||
)
|
||||
.command(
|
||||
"bump",
|
||||
new Cliffy.Command()
|
||||
new CliffyCommand.Command()
|
||||
.complete("major|minor|patch", () => ["major", "minor", "patch"])
|
||||
.arguments("<major|minor|patch>")
|
||||
.description("Change package version")
|
||||
@ -73,17 +79,26 @@ const flags = await new Cliffy.Command()
|
||||
)
|
||||
.command(
|
||||
"deprecate",
|
||||
new Cliffy.Command()
|
||||
new CliffyCommand.Command()
|
||||
.description("Deprecate package")
|
||||
.action(commandWrapper(deprecateCMD))
|
||||
)
|
||||
.command(
|
||||
"upgrade",
|
||||
new Cliffy.Command()
|
||||
new CliffyCommand.Command()
|
||||
.description("Upgrade to latest version of denreg cli")
|
||||
.action(commandWrapper(upgradeCMD))
|
||||
)
|
||||
.command("completions", new Cliffy.CompletionsCommand())
|
||||
.command(
|
||||
"run",
|
||||
new CliffyCommand.Command()
|
||||
.arguments("<name>")
|
||||
// .complete("name", ()=>) //TODO: add autocomplete?
|
||||
.description("Run script from meta.json")
|
||||
.action(commandWrapper(runCMD))
|
||||
)
|
||||
.command("completions", new CliffyCommand.CompletionsCommand())
|
||||
.command("help", new CliffyCommand.HelpCommand().global())
|
||||
.parse(Deno.args);
|
||||
|
||||
await init(flags.options);
|
||||
@ -94,4 +109,6 @@ if (command) {
|
||||
} catch (err) {
|
||||
console.log(Colors.bold(Colors.red("An error occured:")), err.message);
|
||||
}
|
||||
} else {
|
||||
flags.cmd.showHelp();
|
||||
}
|
||||
|
14
cli/deps.ts
@ -1,7 +1,11 @@
|
||||
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 Cliffy from "https://deno.land/x/cliffy@v0.14.1/mod.ts";
|
||||
export * as Base64 from "https://deno.land/std@0.65.0/encoding/base64.ts";
|
||||
export * as FS from "https://deno.land/std@0.65.0/fs/mod.ts";
|
||||
export * as Colors from "https://deno.land/std@0.65.0/fmt/colors.ts";
|
||||
export * as Path from "https://deno.land/std@0.65.0/path/mod.ts";
|
||||
export * as CliffyPrompt from "https://deno.land/x/cliffy@v1.0.0-rc.3/prompt/mod.ts";
|
||||
export * as CliffyCommand from "https://deno.land/x/cliffy@v1.0.0-rc.3/command/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.95.0/encoding/base64.ts";
|
||||
export * as FS from "https://deno.land/std@0.95.0/fs/mod.ts";
|
||||
export * as Colors from "https://deno.land/std@0.95.0/fmt/colors.ts";
|
||||
export * as Path from "https://deno.land/std@0.95.0/path/mod.ts";
|
1
cli/dpm.ts
Normal file
@ -0,0 +1 @@
|
||||
import "./denreg.ts";
|
@ -9,10 +9,14 @@ export interface IMeta {
|
||||
contributors?: string[];
|
||||
deprecated?: boolean;
|
||||
files: string[];
|
||||
root?: string;
|
||||
hooks?: {
|
||||
prepublish?: string | string[];
|
||||
postpublish?: string | string[];
|
||||
};
|
||||
scripts?: {
|
||||
[key: string]: string | string[];
|
||||
};
|
||||
}
|
||||
|
||||
let verbose = false;
|
||||
@ -41,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() {
|
||||
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> {
|
||||
log("Saving meta.json");
|
||||
return FS.writeJson("meta.json", meta, {
|
||||
spaces: " ",
|
||||
});
|
||||
return writeJson("meta.json", meta, " ");
|
||||
}
|
||||
|
||||
let interactive = true;
|
||||
|
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
@ -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,11 +1,18 @@
|
||||
{
|
||||
"name": "@denreg-cli",
|
||||
"version": "0.2.5",
|
||||
"version": "1.0.0",
|
||||
"description": "CLI for the DenReg package registry",
|
||||
"author": "Fabian Stamm <dev@fabianstamm.de>",
|
||||
"contributors": [],
|
||||
"files": ["**/*.ts", "**/*.js", "README.md"],
|
||||
"files": [
|
||||
"**/*.ts",
|
||||
"**/*.js",
|
||||
"README.md"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "version.ts"
|
||||
},
|
||||
"hooks": {
|
||||
"prepublish": "pre.ts"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
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(
|
||||
"version.ts",
|
||||
|
0
cli/test.ts
Normal file
@ -1 +1 @@
|
||||
export const version = "0.2.5"
|
||||
export const version = "1.0.0"
|
||||
|
@ -1,5 +0,0 @@
|
||||
Denreg JSX renderer
|
||||
|
||||
**deprecated**
|
||||
|
||||
**DO NOT USE**
|
@ -1,13 +1,14 @@
|
||||
{
|
||||
"name": "@denreg-jsx",
|
||||
"version": "0.0.3",
|
||||
"version": "0.1.4",
|
||||
"description": "Denreg JSX renderer",
|
||||
"author": "Fabian Stamm <dev@fabianstamm.de>",
|
||||
"contributors": [],
|
||||
"deprecated": true,
|
||||
"deprecated": false,
|
||||
"files": [
|
||||
"**/*.ts",
|
||||
"**/*.js",
|
||||
"tsconfig.json",
|
||||
"README.md"
|
||||
]
|
||||
}
|
145
jsx/mod.ts
Normal file
@ -0,0 +1,145 @@
|
||||
import "./types.ts";
|
||||
|
||||
const Fragment = Symbol("fragment");
|
||||
|
||||
declare namespace JSX {
|
||||
interface Element {}
|
||||
interface IntrinsicElements {
|
||||
div: any;
|
||||
}
|
||||
}
|
||||
|
||||
export type Element = {
|
||||
component: Component | string | typeof Fragment;
|
||||
props: any;
|
||||
children: any[];
|
||||
};
|
||||
export type ComponentRetElm = Element | Element[];
|
||||
export type Component = (
|
||||
props: any,
|
||||
children: any
|
||||
) => ComponentRetElm | Promise<ComponentRetElm>;
|
||||
|
||||
export function h(
|
||||
component: string | Component,
|
||||
props: any,
|
||||
...children: Element[]
|
||||
): Element {
|
||||
return {
|
||||
component,
|
||||
props,
|
||||
children,
|
||||
};
|
||||
}
|
||||
|
||||
const createElement = h;
|
||||
|
||||
export { Fragment, createElement };
|
||||
|
||||
export async function renderSSR(element: Element | string): Promise<string> {
|
||||
if (typeof element === "string") return element;
|
||||
else if (typeof element.component === "string")
|
||||
return await renderHTML(element as Element);
|
||||
else if (
|
||||
typeof element.component === "function" ||
|
||||
element.component === Fragment
|
||||
)
|
||||
return await renderCustom(element as Element);
|
||||
|
||||
console.warn("renderSSR: invalid element", element);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
const selfClosing = new Set([
|
||||
"area",
|
||||
"base",
|
||||
"br",
|
||||
"col",
|
||||
"embed",
|
||||
"hr",
|
||||
"img",
|
||||
"input",
|
||||
"link",
|
||||
"meta",
|
||||
"param",
|
||||
"source",
|
||||
"track",
|
||||
"wbr",
|
||||
]);
|
||||
|
||||
function flatDeep(arr: any, d = Infinity): any[] {
|
||||
if (Array.isArray(arr) && d >= 0) {
|
||||
let res = [];
|
||||
for (const val of arr) {
|
||||
const v = flatDeep(val, d - 1);
|
||||
res.push(...v);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return [arr];
|
||||
}
|
||||
|
||||
function cleanChildren(children: any) {
|
||||
return flatDeep(children).filter((e) => !!e);
|
||||
}
|
||||
|
||||
async function renderHTML(element: Element) {
|
||||
if (typeof element.component !== "string")
|
||||
throw new Error("Internal consistency error");
|
||||
|
||||
let props = "";
|
||||
|
||||
for (const key in element.props) {
|
||||
if (key == "innerHTML") continue;
|
||||
props += `${key}="${element.props[key] || ""}" `;
|
||||
}
|
||||
|
||||
const tag = element.component;
|
||||
|
||||
if (selfClosing.has(element.component)) {
|
||||
return `<${tag} ${props}/>`;
|
||||
} else {
|
||||
let inner = "";
|
||||
if (element.props && element.props["innerHTML"]) {
|
||||
inner = element.props["innerHTML"];
|
||||
} else {
|
||||
const children = cleanChildren(element.children);
|
||||
inner = (
|
||||
await Promise.all(children.map((child) => renderSSR(child)))
|
||||
).join("");
|
||||
}
|
||||
return `<${tag} ${props}>${inner || ""}</${tag}>`;
|
||||
}
|
||||
}
|
||||
|
||||
async function renderCustom(element: Element) {
|
||||
if (typeof element.component === "string")
|
||||
throw new Error("Internal consistency error");
|
||||
|
||||
if (element.component === Fragment) {
|
||||
const ch = (
|
||||
await Promise.all(
|
||||
cleanChildren(element.children).map((child) => renderSSR(child))
|
||||
)
|
||||
).join("");
|
||||
|
||||
return ch;
|
||||
} else {
|
||||
const res = await Promise.resolve(
|
||||
element.component(
|
||||
{
|
||||
...element.props,
|
||||
children: element.children,
|
||||
},
|
||||
element.children
|
||||
)
|
||||
);
|
||||
|
||||
const ch = (
|
||||
await Promise.all(cleanChildren(res).map((child) => renderSSR(child)))
|
||||
).join("");
|
||||
|
||||
return ch;
|
||||
}
|
||||
}
|
7
jsx/tsconfig.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["dom", "dom.iterable", "esnext", "deno.ns", "deno.unstable"],
|
||||
"jsxFactory": "h",
|
||||
"strictPropertyInitialization": false
|
||||
}
|
||||
}
|
11
jsx/types.ts
Normal file
@ -0,0 +1,11 @@
|
||||
declare namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
[elemName: string]: any;
|
||||
}
|
||||
}
|
||||
|
||||
declare namespace JSX {
|
||||
interface ElementClass {
|
||||
render: any;
|
||||
}
|
||||
}
|
14
markdown/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Deno",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"runtimeExecutable": "deno",
|
||||
"runtimeArgs": ["run", "--inspect", "-A", "app.ts"],
|
||||
"port": 9229
|
||||
}
|
||||
]
|
||||
}
|
9
markdown/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"deno.enable": true,
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "axetroy.vscode-deno"
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "axetroy.vscode-deno"
|
||||
}
|
||||
}
|
21
markdown/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Eivind Furuberg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
62
markdown/README.md
Normal file
@ -0,0 +1,62 @@
|
||||
# markdown
|
||||
|
||||
Deno Markdown module forked from https://github.com/ts-stack/markdown/tree/bb47aa8e625e89e6aa84f49a98536a3089dee831
|
||||
|
||||
### Example usage
|
||||
|
||||
Simple md2html.ts script:
|
||||
|
||||
```typescript
|
||||
import { Marked } from "./mod.ts";
|
||||
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
const filename = Deno.args[0];
|
||||
const markdown = decoder.decode(await Deno.readFile(filename));
|
||||
const markup = Marked.parse(markdown);
|
||||
console.log(markup.content);
|
||||
console.log(JSON.stringify(markup.meta))
|
||||
```
|
||||
|
||||
Now running:
|
||||
|
||||
```bash
|
||||
deno run --allow-read md2html.ts example.md > example.html
|
||||
```
|
||||
|
||||
Will output:
|
||||
|
||||
```html
|
||||
<h1 id="hello-world">Hello World</h1>
|
||||
<h2 id="this-an-example-for-md2html-ts-">
|
||||
This an example for <code>md2html.ts</code>
|
||||
</h2>
|
||||
<p>A small paragraph that will become a <code><p></code> tag</p>
|
||||
<hr />
|
||||
<p>Code Block (md2html.ts)</p>
|
||||
|
||||
<pre><code class="lang-typescript">import { Marked } from "./mod.ts";
|
||||
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
const filename = Deno.args[0];
|
||||
const markdown = decoder.decode(await Deno.readFile(filename));
|
||||
const markup = Marked.parse(markdown);
|
||||
console.log(markup.content);
|
||||
console.log(JSON.stringify(markup.meta))
|
||||
</code></pre>
|
||||
<p>
|
||||
This module is forked from
|
||||
<a
|
||||
href="https://github.com/ts-stack/markdown/tree/bb47aa8e625e89e6aa84f49a98536a3089dee831"
|
||||
>ts-stack/markdown</a
|
||||
>
|
||||
</p>
|
||||
<p>Made for Deno <img src="https://deno.land/logo.svg" alt="deno-logo" /></p>
|
||||
|
||||
{"title":"Hello world!","subtitle":"Front-matter is supported!","boolean":true,"list-example":["this","is",{"a":"list"}]}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Notes
|
||||
|
||||
I had to do some changes to the source code to make the compiler happy, mostly fixes for things that were uninitialized and possibly null or undefined
|
BIN
markdown/example.html
Normal file
34
markdown/example.md
Normal file
@ -0,0 +1,34 @@
|
||||
---
|
||||
title : Hello world!
|
||||
subtitle : Front-matter is supported!
|
||||
boolean: true
|
||||
list-example:
|
||||
- this
|
||||
- is
|
||||
- a: list
|
||||
---
|
||||
# Hello World
|
||||
|
||||
## This an example for `md2html.ts`
|
||||
|
||||
A small paragraph that will become a `<p>` tag
|
||||
|
||||
---
|
||||
|
||||
Code Block (md2html.ts)
|
||||
|
||||
```typescript
|
||||
import { Marked } from "./mod.ts";
|
||||
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
const filename = Deno.args[0];
|
||||
const markdown = decoder.decode(await Deno.readFile(filename));
|
||||
const markup = Marked.parse(markdown);
|
||||
console.log(markup.content);
|
||||
console.log(JSON.stringify(markup.meta));
|
||||
```
|
||||
|
||||
This module is forked from [ts-stack/markdown](https://github.com/ts-stack/markdown/tree/bb47aa8e625e89e6aa84f49a98536a3089dee831)
|
||||
|
||||
Made for Deno
|
||||

|
8
markdown/md2html.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { Marked } from "./mod.ts";
|
||||
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
const filename = Deno.args[0];
|
||||
const markdown = decoder.decode(await Deno.readFile(filename));
|
||||
const markup = Marked.parse(markdown);
|
||||
console.log(markup.content);
|
||||
console.log(JSON.stringify(markup.meta))
|
12
markdown/meta.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "markdown",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"author": "Fabian Stamm <dev@fabianstamm.de>",
|
||||
"contributors": [],
|
||||
"files": [
|
||||
"**/*.ts",
|
||||
"**/*.js",
|
||||
"README.md"
|
||||
]
|
||||
}
|
8
markdown/mod.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export * from "./src/block-lexer.ts";
|
||||
export * from "./src/helpers.ts";
|
||||
export * from "./src/inline-lexer.ts";
|
||||
export * from "./src/interfaces.ts";
|
||||
export * from "./src/marked.ts";
|
||||
export * from "./src/parser.ts";
|
||||
export * from "./src/renderer.ts";
|
||||
export * from "./src/extend-regexp.ts";
|
522
markdown/src/block-lexer.ts
Normal file
@ -0,0 +1,522 @@
|
||||
/**
|
||||
* @license
|
||||
*
|
||||
* Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
|
||||
* https://github.com/chjj/marked
|
||||
*
|
||||
* Copyright (c) 2018, Костя Третяк. (MIT Licensed)
|
||||
* https://github.com/ts-stack/markdown
|
||||
*/
|
||||
|
||||
import { ExtendRegexp } from "./extend-regexp.ts";
|
||||
import {
|
||||
Align,
|
||||
LexerReturns,
|
||||
Links,
|
||||
MarkedOptions,
|
||||
RulesBlockBase,
|
||||
RulesBlockGfm,
|
||||
RulesBlockTables,
|
||||
Token,
|
||||
TokenType,
|
||||
Obj
|
||||
} from "./interfaces.ts";
|
||||
import { Marked } from "./marked.ts";
|
||||
import { parse } from "https://deno.land/std@0.208.0/yaml/mod.ts";
|
||||
|
||||
|
||||
|
||||
export class BlockLexer<T extends typeof BlockLexer> {
|
||||
static simpleRules: RegExp[] = [];
|
||||
protected static rulesBase: RulesBlockBase;
|
||||
/**
|
||||
* GFM Block Grammar.
|
||||
*/
|
||||
protected static rulesGfm: RulesBlockGfm;
|
||||
/**
|
||||
* GFM + Tables Block Grammar.
|
||||
*/
|
||||
protected static rulesTables: RulesBlockTables;
|
||||
protected rules!: RulesBlockBase | RulesBlockGfm | RulesBlockTables;
|
||||
protected options: MarkedOptions;
|
||||
protected links: Links = {};
|
||||
protected tokens: Token[] = [];
|
||||
protected frontmatter: Obj = {};
|
||||
protected hasRulesGfm!: boolean;
|
||||
protected hasRulesTables!: boolean;
|
||||
|
||||
constructor(protected staticThis: typeof BlockLexer, options?: object) {
|
||||
this.options = options || Marked.options;
|
||||
this.setRules();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts Markdown text and returns object with tokens and links.
|
||||
*
|
||||
* @param src String of markdown source to be compiled.
|
||||
* @param options Hash of options.
|
||||
*/
|
||||
static lex(
|
||||
src: string,
|
||||
options?: MarkedOptions,
|
||||
top?: boolean,
|
||||
isBlockQuote?: boolean,
|
||||
): LexerReturns {
|
||||
const lexer = new this(this, options);
|
||||
return lexer.getTokens(src, top, isBlockQuote);
|
||||
}
|
||||
|
||||
protected static getRulesBase(): RulesBlockBase {
|
||||
if (this.rulesBase) {
|
||||
return this.rulesBase;
|
||||
}
|
||||
|
||||
const base: RulesBlockBase = {
|
||||
newline: /^\n+/,
|
||||
code: /^( {4}[^\n]+\n*)+/,
|
||||
hr: /^( *[-*_]){3,} *(?:\n+|$)/,
|
||||
heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
|
||||
lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
|
||||
blockquote: /^( *>[^\n]+(\n[^\n]+)*\n*)+/,
|
||||
list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
|
||||
html:
|
||||
/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
|
||||
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
|
||||
paragraph:
|
||||
/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
|
||||
text: /^[^\n]+/,
|
||||
bullet: /(?:[*+-]|\d+\.)/,
|
||||
item: /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,
|
||||
};
|
||||
|
||||
base.item = new ExtendRegexp(base.item, "gm").setGroup(/bull/g, base.bullet)
|
||||
.getRegexp();
|
||||
|
||||
base.list = new ExtendRegexp(base.list)
|
||||
.setGroup(/bull/g, base.bullet)
|
||||
.setGroup("hr", "\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")
|
||||
.setGroup("def", "\\n+(?=" + base.def.source + ")")
|
||||
.getRegexp();
|
||||
|
||||
const tag = "(?!(?:" +
|
||||
"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code" +
|
||||
"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo" +
|
||||
"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b";
|
||||
|
||||
base.html = new ExtendRegexp(base.html)
|
||||
.setGroup("comment", /<!--[\s\S]*?-->/)
|
||||
.setGroup("closed", /<(tag)[\s\S]+?<\/\1>/)
|
||||
.setGroup("closing", /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
|
||||
.setGroup(/tag/g, tag)
|
||||
.getRegexp();
|
||||
|
||||
base.paragraph = new ExtendRegexp(base.paragraph)
|
||||
.setGroup("hr", base.hr)
|
||||
.setGroup("heading", base.heading)
|
||||
.setGroup("lheading", base.lheading)
|
||||
.setGroup("blockquote", base.blockquote)
|
||||
.setGroup("tag", "<" + tag)
|
||||
.setGroup("def", base.def)
|
||||
.getRegexp();
|
||||
|
||||
return (this.rulesBase = base);
|
||||
}
|
||||
|
||||
protected static getRulesGfm(): RulesBlockGfm {
|
||||
if (this.rulesGfm) {
|
||||
return this.rulesGfm;
|
||||
}
|
||||
|
||||
const base = this.getRulesBase();
|
||||
|
||||
const gfm: RulesBlockGfm = {
|
||||
...base,
|
||||
...{
|
||||
fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
|
||||
paragraph: /^/,
|
||||
heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/,
|
||||
},
|
||||
};
|
||||
|
||||
const group1 = gfm.fences.source.replace("\\1", "\\2");
|
||||
const group2 = base.list.source.replace("\\1", "\\3");
|
||||
|
||||
gfm.paragraph = new ExtendRegexp(base.paragraph).setGroup(
|
||||
"(?!",
|
||||
`(?!${group1}|${group2}|`,
|
||||
).getRegexp();
|
||||
|
||||
return (this.rulesGfm = gfm);
|
||||
}
|
||||
|
||||
protected static getRulesTable(): RulesBlockTables {
|
||||
if (this.rulesTables) {
|
||||
return this.rulesTables;
|
||||
}
|
||||
|
||||
return (this.rulesTables = {
|
||||
...this.getRulesGfm(),
|
||||
...{
|
||||
nptable:
|
||||
/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
|
||||
table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
protected setRules() {
|
||||
if (this.options.gfm) {
|
||||
if (this.options.tables) {
|
||||
this.rules = this.staticThis.getRulesTable();
|
||||
} else {
|
||||
this.rules = this.staticThis.getRulesGfm();
|
||||
}
|
||||
} else {
|
||||
this.rules = this.staticThis.getRulesBase();
|
||||
}
|
||||
|
||||
this.hasRulesGfm = (this.rules as RulesBlockGfm).fences !== undefined;
|
||||
this.hasRulesTables = (this.rules as RulesBlockTables).table !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lexing.
|
||||
*/
|
||||
protected getTokens(
|
||||
src: string,
|
||||
top?: boolean,
|
||||
isBlockQuote?: boolean,
|
||||
): LexerReturns {
|
||||
let nextPart = src;
|
||||
let execArr, fmArr: RegExpExecArray | null;
|
||||
|
||||
mainLoop:
|
||||
while (nextPart) {
|
||||
// newline
|
||||
if ((execArr = this.rules.newline.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
|
||||
if (execArr[0].length > 1) {
|
||||
this.tokens.push({ type: TokenType.space });
|
||||
}
|
||||
}
|
||||
|
||||
// code
|
||||
if ((execArr = this.rules.code.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
const code = execArr[0].replace(/^ {4}/gm, "");
|
||||
|
||||
this.tokens.push({
|
||||
type: TokenType.code,
|
||||
text: !this.options.pedantic ? code.replace(/\n+$/, "") : code,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// fences code (gfm)
|
||||
if (
|
||||
this.hasRulesGfm &&
|
||||
(execArr = (this.rules as RulesBlockGfm).fences.exec(nextPart))
|
||||
) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
|
||||
this.tokens.push({
|
||||
type: TokenType.code,
|
||||
lang: execArr[2],
|
||||
text: execArr[3] || "",
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// heading
|
||||
if ((execArr = this.rules.heading.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
this.tokens.push({
|
||||
type: TokenType.heading,
|
||||
depth: execArr[1].length,
|
||||
text: execArr[2],
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// table no leading pipe (gfm)
|
||||
if (
|
||||
top && this.hasRulesTables &&
|
||||
(execArr = (this.rules as RulesBlockTables).nptable.exec(nextPart))
|
||||
) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
|
||||
const item: Token = {
|
||||
type: TokenType.table,
|
||||
header: execArr[1].replace(/^ *| *\| *$/g, "").split(/ *\| */),
|
||||
align: execArr[2].replace(/^ *|\| *$/g, "").split(
|
||||
/ *\| */,
|
||||
) as Align[],
|
||||
cells: [],
|
||||
};
|
||||
|
||||
if (!item.align) throw ReferenceError;
|
||||
|
||||
for (let i = 0; i < item.align.length; i++) {
|
||||
if (/^ *-+: *$/.test(item.align[i])) {
|
||||
item.align[i] = "right";
|
||||
} else if (/^ *:-+: *$/.test(item.align[i])) {
|
||||
item.align[i] = "center";
|
||||
} else if (/^ *:-+ *$/.test(item.align[i])) {
|
||||
item.align[i] = "left";
|
||||
} else {
|
||||
item.align[i] = "";
|
||||
}
|
||||
}
|
||||
|
||||
const td: string[] = execArr[3].replace(/\n$/, "").split("\n");
|
||||
|
||||
if (!item.cells) throw ReferenceError;
|
||||
|
||||
for (let i = 0; i < td.length; i++) {
|
||||
item.cells[i] = td[i].split(/ *\| */);
|
||||
}
|
||||
|
||||
this.tokens.push(item);
|
||||
continue;
|
||||
}
|
||||
|
||||
// lheading
|
||||
if ((execArr = this.rules.lheading.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
|
||||
this.tokens.push({
|
||||
type: TokenType.heading,
|
||||
depth: execArr[2] === "=" ? 1 : 2,
|
||||
text: execArr[1],
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// hr
|
||||
if ((execArr = this.rules.hr.exec(nextPart))) {
|
||||
|
||||
// Checks if the previous string contains a content.
|
||||
if ((this.tokens.length == 0) || (this.tokens.every(object => object.type == TokenType.space))) {
|
||||
|
||||
// Grabs front-matter data and parse it into Javascript object.
|
||||
if (fmArr = /^(?:\-\-\-)(.*?)(?:\-\-\-|\.\.\.)/s.exec(nextPart)) {
|
||||
nextPart = nextPart.substring(fmArr[0].length);
|
||||
this.frontmatter = <Obj>parse(fmArr[1]);
|
||||
}
|
||||
continue;
|
||||
|
||||
} else {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
this.tokens.push({ type: TokenType.hr });
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// blockquote
|
||||
if ((execArr = this.rules.blockquote.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
this.tokens.push({ type: TokenType.blockquoteStart });
|
||||
const str = execArr[0].replace(/^ *> ?/gm, "");
|
||||
|
||||
// Pass `top` to keep the current
|
||||
// "toplevel" state. This is exactly
|
||||
// how markdown.pl works.
|
||||
this.getTokens(str);
|
||||
this.tokens.push({ type: TokenType.blockquoteEnd });
|
||||
continue;
|
||||
}
|
||||
|
||||
// list
|
||||
if ((execArr = this.rules.list.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
const bull: string = execArr[2];
|
||||
|
||||
this.tokens.push(
|
||||
{ type: TokenType.listStart, ordered: bull.length > 1 },
|
||||
);
|
||||
|
||||
// Get each top-level item.
|
||||
const str = execArr[0].match(this.rules.item) || "";
|
||||
const length = str.length;
|
||||
|
||||
let next = false;
|
||||
let space: number;
|
||||
let blockBullet: string;
|
||||
let loose: boolean;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
let item = str[i];
|
||||
|
||||
// Remove the list item's bullet so it is seen as the next token.
|
||||
space = item.length;
|
||||
item = item.replace(/^ *([*+-]|\d+\.) +/, "");
|
||||
|
||||
// Outdent whatever the list item contains. Hacky.
|
||||
if (item.indexOf("\n ") !== -1) {
|
||||
space -= item.length;
|
||||
item = !this.options.pedantic
|
||||
? item.replace(new RegExp("^ {1," + space + "}", "gm"), "")
|
||||
: item.replace(/^ {1,4}/gm, "");
|
||||
}
|
||||
|
||||
// Determine whether the next list item belongs here.
|
||||
// Backpedal if it does not belong in this list.
|
||||
if (this.options.smartLists && i !== length - 1) {
|
||||
const bb = this.staticThis.getRulesBase().bullet.exec(str[i + 1]);
|
||||
blockBullet = bb ? bb[0] : "";
|
||||
|
||||
if (
|
||||
bull !== blockBullet &&
|
||||
!(bull.length > 1 && blockBullet.length > 1)
|
||||
) {
|
||||
nextPart = (str.slice(i + 1) as string[]).join("\n") + nextPart;
|
||||
i = length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine whether item is loose or not.
|
||||
// Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
|
||||
// for discount behavior.
|
||||
loose = next || /\n\n(?!\s*$)/.test(item);
|
||||
|
||||
if (i !== length - 1) {
|
||||
next = item.charAt(item.length - 1) === "\n";
|
||||
|
||||
if (!loose) {
|
||||
loose = next;
|
||||
}
|
||||
}
|
||||
|
||||
this.tokens.push(
|
||||
{
|
||||
type: loose ? TokenType.looseItemStart : TokenType.listItemStart,
|
||||
},
|
||||
);
|
||||
|
||||
// Recurse.
|
||||
this.getTokens(item, false, isBlockQuote);
|
||||
this.tokens.push({ type: TokenType.listItemEnd });
|
||||
}
|
||||
|
||||
this.tokens.push({ type: TokenType.listEnd });
|
||||
continue;
|
||||
}
|
||||
|
||||
// html
|
||||
if ((execArr = this.rules.html.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
const attr = execArr[1];
|
||||
const isPre = attr === "pre" || attr === "script" || attr === "style";
|
||||
|
||||
this.tokens.push({
|
||||
type: this.options.sanitize ? TokenType.paragraph : TokenType.html,
|
||||
pre: !this.options.sanitizer && isPre,
|
||||
text: execArr[0],
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// def
|
||||
if (top && (execArr = this.rules.def.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
|
||||
this.links[execArr[1].toLowerCase()] = {
|
||||
href: execArr[2],
|
||||
title: execArr[3],
|
||||
};
|
||||
continue;
|
||||
}
|
||||
|
||||
// table (gfm)
|
||||
if (
|
||||
top && this.hasRulesTables &&
|
||||
(execArr = (this.rules as RulesBlockTables).table.exec(nextPart))
|
||||
) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
|
||||
const item: Token = {
|
||||
type: TokenType.table,
|
||||
header: execArr[1].replace(/^ *| *\| *$/g, "").split(/ *\| */),
|
||||
align: execArr[2].replace(/^ *|\| *$/g, "").split(
|
||||
/ *\| */,
|
||||
) as Align[],
|
||||
cells: [],
|
||||
};
|
||||
|
||||
if (!item.align) throw ReferenceError;
|
||||
|
||||
for (let i = 0; i < item.align.length; i++) {
|
||||
if (/^ *-+: *$/.test(item.align[i])) {
|
||||
item.align[i] = "right";
|
||||
} else if (/^ *:-+: *$/.test(item.align[i])) {
|
||||
item.align[i] = "center";
|
||||
} else if (/^ *:-+ *$/.test(item.align[i])) {
|
||||
item.align[i] = "left";
|
||||
} else {
|
||||
item.align[i] = "";
|
||||
}
|
||||
}
|
||||
|
||||
const td = execArr[3].replace(/(?: *\| *)?\n$/, "").split("\n");
|
||||
|
||||
if (!item.cells) throw ReferenceError;
|
||||
|
||||
for (let i = 0; i < td.length; i++) {
|
||||
item.cells[i] = td[i].replace(/^ *\| *| *\| *$/g, "").split(/ *\| */);
|
||||
}
|
||||
|
||||
this.tokens.push(item);
|
||||
continue;
|
||||
}
|
||||
|
||||
// simple rules
|
||||
if (this.staticThis.simpleRules.length) {
|
||||
const simpleRules = this.staticThis.simpleRules;
|
||||
for (let i = 0; i < simpleRules.length; i++) {
|
||||
if ((execArr = simpleRules[i].exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
const type = "simpleRule" + (i + 1);
|
||||
this.tokens.push({ type, execArr });
|
||||
continue mainLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// top-level paragraph
|
||||
if (top && (execArr = this.rules.paragraph.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
|
||||
if (execArr[1].slice(-1) === "\n") {
|
||||
this.tokens.push({
|
||||
type: TokenType.paragraph,
|
||||
text: execArr[1].slice(0, -1),
|
||||
});
|
||||
} else {
|
||||
this.tokens.push({
|
||||
type: this.tokens.length > 0 ? TokenType.paragraph : TokenType.text,
|
||||
text: execArr[1],
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// text
|
||||
// Top-level should never reach here.
|
||||
if ((execArr = this.rules.text.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
this.tokens.push({ type: TokenType.text, text: execArr[0] });
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nextPart) {
|
||||
throw new Error(
|
||||
"Infinite loop on byte: " + nextPart.charCodeAt(0) +
|
||||
`, near text '${nextPart.slice(0, 30)}...'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return { tokens: this.tokens, links: this.links, meta: this.frontmatter };
|
||||
}
|
||||
}
|
43
markdown/src/extend-regexp.ts
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* @license
|
||||
*
|
||||
* Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
|
||||
* https://github.com/chjj/marked
|
||||
*
|
||||
* Copyright (c) 2018, Костя Третяк. (MIT Licensed)
|
||||
* https://github.com/ts-stack/markdown
|
||||
*/
|
||||
|
||||
export class ExtendRegexp {
|
||||
private source: string;
|
||||
private flags: string;
|
||||
|
||||
constructor(regex: RegExp, flags: string = "") {
|
||||
this.source = regex.source;
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend regular expression.
|
||||
*
|
||||
* @param groupName Regular expression for search a group name.
|
||||
* @param groupRegexp Regular expression of named group.
|
||||
*/
|
||||
setGroup(groupName: RegExp | string, groupRegexp: RegExp | string): this {
|
||||
let newRegexp: string = typeof groupRegexp == "string"
|
||||
? groupRegexp
|
||||
: groupRegexp.source;
|
||||
newRegexp = newRegexp.replace(/(^|[^\[])\^/g, "$1");
|
||||
|
||||
// Extend regexp.
|
||||
this.source = this.source.replace(groupName, newRegexp);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a result of extending a regular expression.
|
||||
*/
|
||||
getRegexp(): RegExp {
|
||||
return new RegExp(this.source, this.flags);
|
||||
}
|
||||
}
|
64
markdown/src/helpers.ts
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @license
|
||||
*
|
||||
* Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
|
||||
* https://github.com/chjj/marked
|
||||
*
|
||||
* Copyright (c) 2018, Костя Третяк. (MIT Licensed)
|
||||
* https://github.com/ts-stack/markdown
|
||||
*/
|
||||
|
||||
import type { Replacements } from "./interfaces.ts";
|
||||
|
||||
const escapeTest = /[&<>"']/;
|
||||
const escapeReplace = /[&<>"']/g;
|
||||
const replacements: Replacements = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
'"': """,
|
||||
// tslint:disable-next-line:quotemark
|
||||
"'": "'",
|
||||
};
|
||||
|
||||
const escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/;
|
||||
const escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g;
|
||||
|
||||
export function escape(html: string, encode?: boolean) {
|
||||
if (encode) {
|
||||
if (escapeTest.test(html)) {
|
||||
return html.replace(escapeReplace, (ch: string) => replacements[ch]);
|
||||
}
|
||||
} else {
|
||||
if (escapeTestNoEncode.test(html)) {
|
||||
return html.replace(
|
||||
escapeReplaceNoEncode,
|
||||
(ch: string) => replacements[ch]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
export function unescape(html: string) {
|
||||
// Explicitly match decimal, hex, and named HTML entities
|
||||
return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi, function (
|
||||
_,
|
||||
n
|
||||
) {
|
||||
n = n.toLowerCase();
|
||||
|
||||
if (n === "colon") {
|
||||
return ":";
|
||||
}
|
||||
|
||||
if (n.charAt(0) === "#") {
|
||||
return n.charAt(1) === "x"
|
||||
? String.fromCharCode(parseInt(n.substring(2), 16))
|
||||
: String.fromCharCode(+n.substring(1));
|
||||
}
|
||||
|
||||
return "";
|
||||
});
|
||||
}
|
419
markdown/src/inline-lexer.ts
Normal file
@ -0,0 +1,419 @@
|
||||
/**
|
||||
* @license
|
||||
*
|
||||
* Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
|
||||
* https://github.com/chjj/marked
|
||||
*
|
||||
* Copyright (c) 2018, Костя Третяк. (MIT Licensed)
|
||||
* https://github.com/ts-stack/markdown
|
||||
*/
|
||||
|
||||
import { ExtendRegexp } from "./extend-regexp.ts";
|
||||
import type {
|
||||
Link,
|
||||
Links,
|
||||
MarkedOptions,
|
||||
RulesInlineBase,
|
||||
RulesInlineBreaks,
|
||||
RulesInlineCallback,
|
||||
RulesInlineGfm,
|
||||
RulesInlinePedantic,
|
||||
} from "./interfaces.ts";
|
||||
import { Marked } from "./marked.ts";
|
||||
import { Renderer } from "./renderer.ts";
|
||||
|
||||
/**
|
||||
* Inline Lexer & Compiler.
|
||||
*/
|
||||
export class InlineLexer {
|
||||
protected static rulesBase: RulesInlineBase;
|
||||
/**
|
||||
* Pedantic Inline Grammar.
|
||||
*/
|
||||
protected static rulesPedantic: RulesInlinePedantic;
|
||||
/**
|
||||
* GFM Inline Grammar
|
||||
*/
|
||||
protected static rulesGfm: RulesInlineGfm;
|
||||
/**
|
||||
* GFM + Line Breaks Inline Grammar.
|
||||
*/
|
||||
protected static rulesBreaks: RulesInlineBreaks;
|
||||
protected rules!:
|
||||
| RulesInlineBase
|
||||
| RulesInlinePedantic
|
||||
| RulesInlineGfm
|
||||
| RulesInlineBreaks;
|
||||
protected renderer: Renderer;
|
||||
protected inLink!: boolean;
|
||||
protected hasRulesGfm!: boolean;
|
||||
protected ruleCallbacks!: RulesInlineCallback[];
|
||||
|
||||
constructor(
|
||||
protected staticThis: typeof InlineLexer,
|
||||
protected links: Links,
|
||||
protected options: MarkedOptions = Marked.options,
|
||||
renderer?: Renderer
|
||||
) {
|
||||
this.renderer =
|
||||
renderer || this.options.renderer || new Renderer(this.options);
|
||||
|
||||
if (!this.links) {
|
||||
throw new Error(`InlineLexer requires 'links' parameter.`);
|
||||
}
|
||||
|
||||
this.setRules();
|
||||
}
|
||||
|
||||
/**
|
||||
* Static Lexing/Compiling Method.
|
||||
*/
|
||||
static output(src: string, links: Links, options: MarkedOptions): string {
|
||||
const inlineLexer = new this(this, links, options);
|
||||
return inlineLexer.output(src);
|
||||
}
|
||||
|
||||
protected static getRulesBase(): RulesInlineBase {
|
||||
if (this.rulesBase) {
|
||||
return this.rulesBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline-Level Grammar.
|
||||
*/
|
||||
const base: RulesInlineBase = {
|
||||
escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
|
||||
autolink: /^<([^ <>]+(@|:\/)[^ <>]+)>/,
|
||||
tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^<'">])*?>/,
|
||||
link: /^!?\[(inside)\]\(href\)/,
|
||||
reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
|
||||
nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
|
||||
strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
|
||||
em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
|
||||
code: /^(`+)([\s\S]*?[^`])\1(?!`)/,
|
||||
br: /^ {2,}\n(?!\s*$)/,
|
||||
text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/,
|
||||
_inside: /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/,
|
||||
_href: /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/,
|
||||
};
|
||||
|
||||
base.link = new ExtendRegexp(base.link)
|
||||
.setGroup("inside", base._inside)
|
||||
.setGroup("href", base._href)
|
||||
.getRegexp();
|
||||
|
||||
base.reflink = new ExtendRegexp(base.reflink)
|
||||
.setGroup("inside", base._inside)
|
||||
.getRegexp();
|
||||
|
||||
return (this.rulesBase = base);
|
||||
}
|
||||
|
||||
protected static getRulesPedantic(): RulesInlinePedantic {
|
||||
if (this.rulesPedantic) {
|
||||
return this.rulesPedantic;
|
||||
}
|
||||
|
||||
return (this.rulesPedantic = {
|
||||
...this.getRulesBase(),
|
||||
...{
|
||||
strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
|
||||
em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
protected static getRulesGfm(): RulesInlineGfm {
|
||||
if (this.rulesGfm) {
|
||||
return this.rulesGfm;
|
||||
}
|
||||
|
||||
const base = this.getRulesBase();
|
||||
|
||||
const escape = new ExtendRegexp(base.escape)
|
||||
.setGroup("])", "~|])")
|
||||
.getRegexp();
|
||||
|
||||
const text = new ExtendRegexp(base.text)
|
||||
.setGroup("]|", "~]|")
|
||||
.setGroup("|", "|https?://|")
|
||||
.getRegexp();
|
||||
|
||||
return (this.rulesGfm = {
|
||||
...base,
|
||||
...{
|
||||
escape,
|
||||
url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
|
||||
del: /^~~(?=\S)([\s\S]*?\S)~~/,
|
||||
text,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
protected static getRulesBreaks(): RulesInlineBreaks {
|
||||
if (this.rulesBreaks) {
|
||||
return this.rulesBreaks;
|
||||
}
|
||||
|
||||
const inline = this.getRulesGfm();
|
||||
const gfm = this.getRulesGfm();
|
||||
|
||||
return (this.rulesBreaks = {
|
||||
...gfm,
|
||||
...{
|
||||
br: new ExtendRegexp(inline.br).setGroup("{2,}", "*").getRegexp(),
|
||||
text: new ExtendRegexp(gfm.text).setGroup("{2,}", "*").getRegexp(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
protected setRules() {
|
||||
if (this.options.gfm) {
|
||||
if (this.options.breaks) {
|
||||
this.rules = this.staticThis.getRulesBreaks();
|
||||
} else {
|
||||
this.rules = this.staticThis.getRulesGfm();
|
||||
}
|
||||
} else if (this.options.pedantic) {
|
||||
this.rules = this.staticThis.getRulesPedantic();
|
||||
} else {
|
||||
this.rules = this.staticThis.getRulesBase();
|
||||
}
|
||||
|
||||
this.hasRulesGfm = (this.rules as RulesInlineGfm).url !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lexing/Compiling.
|
||||
*/
|
||||
output(nextPart: string): string {
|
||||
nextPart = nextPart;
|
||||
let execArr: RegExpExecArray | null;
|
||||
let out = "";
|
||||
|
||||
while (nextPart) {
|
||||
// escape
|
||||
if ((execArr = this.rules.escape.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
out += execArr[1];
|
||||
continue;
|
||||
}
|
||||
|
||||
// autolink
|
||||
if ((execArr = this.rules.autolink.exec(nextPart))) {
|
||||
let text: string;
|
||||
let href: string;
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
|
||||
if (!this.options.escape) throw ReferenceError;
|
||||
|
||||
if (execArr[2] === "@") {
|
||||
text = this.options.escape(
|
||||
execArr[1].charAt(6) === ":"
|
||||
? this.mangle(execArr[1].substring(7))
|
||||
: this.mangle(execArr[1])
|
||||
);
|
||||
href = this.mangle("mailto:") + text;
|
||||
} else {
|
||||
text = this.options.escape(execArr[1]);
|
||||
href = text;
|
||||
}
|
||||
|
||||
out += this.renderer.link(href, "", text);
|
||||
continue;
|
||||
}
|
||||
|
||||
// url (gfm)
|
||||
if (
|
||||
!this.inLink &&
|
||||
this.hasRulesGfm &&
|
||||
(execArr = (this.rules as RulesInlineGfm).url.exec(nextPart))
|
||||
) {
|
||||
if (!this.options.escape) throw ReferenceError;
|
||||
let text: string;
|
||||
let href: string;
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
text = this.options.escape(execArr[1]);
|
||||
href = text;
|
||||
out += this.renderer.link(href, "", text);
|
||||
continue;
|
||||
}
|
||||
|
||||
// tag
|
||||
if ((execArr = this.rules.tag.exec(nextPart))) {
|
||||
if (!this.inLink && /^<a /i.test(execArr[0])) {
|
||||
this.inLink = true;
|
||||
} else if (this.inLink && /^<\/a>/i.test(execArr[0])) {
|
||||
this.inLink = false;
|
||||
}
|
||||
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
|
||||
if (!this.options.escape) throw ReferenceError;
|
||||
|
||||
out += this.options.sanitize
|
||||
? this.options.sanitizer
|
||||
? this.options.sanitizer(execArr[0])
|
||||
: this.options.escape(execArr[0])
|
||||
: execArr[0];
|
||||
continue;
|
||||
}
|
||||
|
||||
// link
|
||||
if ((execArr = this.rules.link.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
this.inLink = true;
|
||||
|
||||
out += this.outputLink(execArr, {
|
||||
href: execArr[2],
|
||||
title: execArr[3],
|
||||
});
|
||||
|
||||
this.inLink = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// reflink, nolink
|
||||
if (
|
||||
(execArr = this.rules.reflink.exec(nextPart)) ||
|
||||
(execArr = this.rules.nolink.exec(nextPart))
|
||||
) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
const keyLink = (execArr[2] || execArr[1]).replace(/\s+/g, " ");
|
||||
const link = this.links[keyLink.toLowerCase()];
|
||||
|
||||
if (!link || !link.href) {
|
||||
out += execArr[0].charAt(0);
|
||||
nextPart = execArr[0].substring(1) + nextPart;
|
||||
continue;
|
||||
}
|
||||
|
||||
this.inLink = true;
|
||||
out += this.outputLink(execArr, link);
|
||||
this.inLink = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// strong
|
||||
if ((execArr = this.rules.strong.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
out += this.renderer.strong(this.output(execArr[2] || execArr[1]));
|
||||
continue;
|
||||
}
|
||||
|
||||
// em
|
||||
if ((execArr = this.rules.em.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
out += this.renderer.em(this.output(execArr[2] || execArr[1]));
|
||||
continue;
|
||||
}
|
||||
|
||||
// code
|
||||
if ((execArr = this.rules.code.exec(nextPart))) {
|
||||
if (!this.options.escape) throw ReferenceError;
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
out += this.renderer.codespan(
|
||||
this.options.escape(execArr[2].trim(), true)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// br
|
||||
if ((execArr = this.rules.br.exec(nextPart))) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
out += this.renderer.br();
|
||||
continue;
|
||||
}
|
||||
|
||||
// del (gfm)
|
||||
if (
|
||||
this.hasRulesGfm &&
|
||||
(execArr = (this.rules as RulesInlineGfm).del.exec(nextPart))
|
||||
) {
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
out += this.renderer.del(this.output(execArr[1]));
|
||||
continue;
|
||||
}
|
||||
|
||||
// text
|
||||
if ((execArr = this.rules.text.exec(nextPart))) {
|
||||
if (!this.options.escape) throw ReferenceError;
|
||||
nextPart = nextPart.substring(execArr[0].length);
|
||||
out += this.renderer.text(
|
||||
this.options.escape(this.smartypants(execArr[0]))
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nextPart) {
|
||||
throw new Error("Infinite loop on byte: " + nextPart.charCodeAt(0));
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile Link.
|
||||
*/
|
||||
protected outputLink(execArr: RegExpExecArray, link: Link) {
|
||||
if (!this.options.escape) throw ReferenceError;
|
||||
const href = this.options.escape(link.href);
|
||||
const title = link.title ? this.options.escape(link.title) : null;
|
||||
|
||||
return execArr[0].charAt(0) !== "!"
|
||||
? this.renderer.link(href, title || "", this.output(execArr[1]))
|
||||
: this.renderer.image(href, title || "", this.options.escape(execArr[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Smartypants Transformations.
|
||||
*/
|
||||
protected smartypants(text: string) {
|
||||
if (!this.options.smartypants) {
|
||||
return text;
|
||||
}
|
||||
|
||||
return (
|
||||
text
|
||||
// em-dashes
|
||||
.replace(/---/g, "\u2014")
|
||||
// en-dashes
|
||||
.replace(/--/g, "\u2013")
|
||||
// opening singles
|
||||
.replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018")
|
||||
// closing singles & apostrophes
|
||||
.replace(/'/g, "\u2019")
|
||||
// opening doubles
|
||||
.replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201c")
|
||||
// closing doubles
|
||||
.replace(/"/g, "\u201d")
|
||||
// ellipses
|
||||
.replace(/\.{3}/g, "\u2026")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mangle Links.
|
||||
*/
|
||||
protected mangle(text: string) {
|
||||
if (!this.options.mangle) {
|
||||
return text;
|
||||
}
|
||||
|
||||
let out = "";
|
||||
const length = text.length;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
let str: string = "";
|
||||
|
||||
if (Math.random() > 0.5) {
|
||||
str = "x" + text.charCodeAt(i).toString(16);
|
||||
}
|
||||
|
||||
out += "&#" + str + ";";
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
196
markdown/src/interfaces.ts
Normal file
@ -0,0 +1,196 @@
|
||||
/**
|
||||
* @license
|
||||
*
|
||||
* Copyright (c) 2018, Костя Третяк. (MIT Licensed)
|
||||
* https://github.com/ts-stack/markdown
|
||||
*/
|
||||
|
||||
import { escape, unescape } from "./helpers.ts";
|
||||
import type { Renderer } from "./renderer.ts";
|
||||
|
||||
export interface Obj {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface RulesBlockBase {
|
||||
newline: RegExp;
|
||||
code: RegExp;
|
||||
hr: RegExp;
|
||||
heading: RegExp;
|
||||
lheading: RegExp;
|
||||
blockquote: RegExp;
|
||||
list: RegExp;
|
||||
html: RegExp;
|
||||
def: RegExp;
|
||||
paragraph: RegExp;
|
||||
text: RegExp;
|
||||
bullet: RegExp;
|
||||
/**
|
||||
* List item (<li>).
|
||||
*/
|
||||
item: RegExp;
|
||||
}
|
||||
|
||||
export interface RulesBlockGfm extends RulesBlockBase {
|
||||
fences: RegExp;
|
||||
}
|
||||
|
||||
export interface RulesBlockTables extends RulesBlockGfm {
|
||||
nptable: RegExp;
|
||||
table: RegExp;
|
||||
}
|
||||
|
||||
export interface Link {
|
||||
href: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface Links {
|
||||
[key: string]: Link;
|
||||
}
|
||||
|
||||
export enum TokenType {
|
||||
space = 1,
|
||||
text,
|
||||
paragraph,
|
||||
heading,
|
||||
listStart,
|
||||
listEnd,
|
||||
looseItemStart,
|
||||
looseItemEnd,
|
||||
listItemStart,
|
||||
listItemEnd,
|
||||
blockquoteStart,
|
||||
blockquoteEnd,
|
||||
code,
|
||||
table,
|
||||
html,
|
||||
hr,
|
||||
}
|
||||
|
||||
export type Align = "center" | "left" | "right" | "";
|
||||
|
||||
export interface Token {
|
||||
type: number | string;
|
||||
text?: string;
|
||||
lang?: string;
|
||||
depth?: number;
|
||||
header?: string[];
|
||||
align?: Align[];
|
||||
cells?: string[][];
|
||||
ordered?: boolean;
|
||||
pre?: boolean;
|
||||
escaped?: boolean;
|
||||
execArr?: RegExpExecArray;
|
||||
/**
|
||||
* Used for debugging. Identifies the line number in the resulting HTML file.
|
||||
*/
|
||||
line?: number;
|
||||
}
|
||||
|
||||
export interface RulesInlineBase {
|
||||
escape: RegExp;
|
||||
autolink: RegExp;
|
||||
tag: RegExp;
|
||||
link: RegExp;
|
||||
reflink: RegExp;
|
||||
nolink: RegExp;
|
||||
strong: RegExp;
|
||||
em: RegExp;
|
||||
code: RegExp;
|
||||
br: RegExp;
|
||||
text: RegExp;
|
||||
_inside: RegExp;
|
||||
_href: RegExp;
|
||||
}
|
||||
|
||||
export interface RulesInlinePedantic extends RulesInlineBase {}
|
||||
|
||||
/**
|
||||
* GFM Inline Grammar
|
||||
*/
|
||||
export interface RulesInlineGfm extends RulesInlineBase {
|
||||
url: RegExp;
|
||||
del: RegExp;
|
||||
}
|
||||
|
||||
export interface RulesInlineBreaks extends RulesInlineGfm {}
|
||||
|
||||
export class MarkedOptions {
|
||||
gfm?: boolean = true;
|
||||
tables?: boolean = true;
|
||||
breaks?: boolean = false;
|
||||
pedantic?: boolean = false;
|
||||
sanitize?: boolean = false;
|
||||
sanitizer?: (text: string) => string;
|
||||
mangle?: boolean = false;
|
||||
smartLists?: boolean = false;
|
||||
silent?: boolean = false;
|
||||
/**
|
||||
* @param code The section of code to pass to the highlighter.
|
||||
* @param lang The programming language specified in the code block.
|
||||
*/
|
||||
highlight?: (code: string, lang?: string) => string;
|
||||
langPrefix?: string = "lang-";
|
||||
smartypants?: boolean = false;
|
||||
headerPrefix?: string = "";
|
||||
/**
|
||||
* An object containing functions to render tokens to HTML. Default: `new Renderer()`
|
||||
*/
|
||||
renderer?: Renderer;
|
||||
/**
|
||||
* Self-close the tags for void elements (<br/>, <img/>, etc.)
|
||||
* with a "/" as required by XHTML.
|
||||
*/
|
||||
xhtml?: boolean = false;
|
||||
/**
|
||||
* The function that will be using to escape HTML entities.
|
||||
* By default using inner helper.
|
||||
*/
|
||||
escape?: (html: string, encode?: boolean) => string = escape;
|
||||
/**
|
||||
* The function that will be using to unescape HTML entities.
|
||||
* By default using inner helper.
|
||||
*/
|
||||
unescape?: (html: string) => string = unescape;
|
||||
/**
|
||||
* If set to `true`, an inline text will not be taken in paragraph.
|
||||
*
|
||||
* ```ts
|
||||
* // isNoP == false
|
||||
* Marked.parse('some text'); // returns '<p>some text</p>'
|
||||
*
|
||||
* Marked.setOptions({isNoP: true});
|
||||
*
|
||||
* Marked.parse('some text'); // returns 'some text'
|
||||
* ```
|
||||
*/
|
||||
isNoP?: boolean;
|
||||
}
|
||||
|
||||
export interface LexerReturns {
|
||||
tokens: Token[];
|
||||
links: Links;
|
||||
meta: Obj;
|
||||
}
|
||||
|
||||
export interface Parsed {
|
||||
content: string;
|
||||
meta: Obj;
|
||||
}
|
||||
|
||||
export interface DebugReturns extends LexerReturns {
|
||||
result: string;
|
||||
}
|
||||
|
||||
export interface Replacements {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface RulesInlineCallback {
|
||||
regexp?: RegExp;
|
||||
condition(): RegExp;
|
||||
tokenize(execArr: RegExpExecArray): void;
|
||||
}
|
||||
|
||||
export type SimpleRenderer = (execArr?: RegExpExecArray) => string;
|
154
markdown/src/marked.ts
Normal file
@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license
|
||||
*
|
||||
* Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
|
||||
* https://github.com/chjj/marked
|
||||
*
|
||||
* Copyright (c) 2018, Костя Третяк. (MIT Licensed)
|
||||
* https://github.com/ts-stack/markdown
|
||||
*/
|
||||
|
||||
import { BlockLexer } from "./block-lexer.ts";
|
||||
import {
|
||||
DebugReturns,
|
||||
LexerReturns,
|
||||
Links,
|
||||
MarkedOptions,
|
||||
SimpleRenderer,
|
||||
Token,
|
||||
TokenType,
|
||||
Parsed
|
||||
} from "./interfaces.ts";
|
||||
import { Parser } from "./parser.ts";
|
||||
|
||||
export class Marked {
|
||||
static options = new MarkedOptions();
|
||||
protected static simpleRenderers: SimpleRenderer[] = [];
|
||||
protected static parsed: Parsed = {
|
||||
content: "",
|
||||
meta: {},
|
||||
};
|
||||
|
||||
/**
|
||||
* Merges the default options with options that will be set.
|
||||
*
|
||||
* @param options Hash of options.
|
||||
*/
|
||||
static setOptions(options: MarkedOptions) {
|
||||
Object.assign(this.options, options);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setting simple block rule.
|
||||
*/
|
||||
static setBlockRule(regexp: RegExp, renderer: SimpleRenderer = () => "") {
|
||||
BlockLexer.simpleRules.push(regexp);
|
||||
this.simpleRenderers.push(renderer);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts Markdown text and returns an object containing HTML and metadata.
|
||||
*
|
||||
* @param src String of markdown source to be compiled.
|
||||
* @param options Hash of options. They replace, but do not merge with the default options.
|
||||
* If you want the merging, you can to do this via `Marked.setOptions()`.
|
||||
*/
|
||||
static parse(src: string, options: MarkedOptions = this.options): Parsed {
|
||||
try {
|
||||
const { tokens, links, meta } = this.callBlockLexer(src, options);
|
||||
this.parsed.content = this.callParser(tokens, links, options);
|
||||
this.parsed.meta = meta;
|
||||
return this.parsed;
|
||||
} catch (e) {
|
||||
this.parsed.content = this.callMe(e);
|
||||
return this.parsed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts Markdown text and returns object with text in HTML format,
|
||||
* tokens and links from `BlockLexer.parser()`.
|
||||
*
|
||||
* @param src String of markdown source to be compiled.
|
||||
* @param options Hash of options. They replace, but do not merge with the default options.
|
||||
* If you want the merging, you can to do this via `Marked.setOptions()`.
|
||||
*/
|
||||
static debug(
|
||||
src: string,
|
||||
options: MarkedOptions = this.options,
|
||||
): DebugReturns {
|
||||
const { tokens, links, meta } = this.callBlockLexer(src, options);
|
||||
let origin = tokens.slice();
|
||||
const parser = new Parser(options);
|
||||
parser.simpleRenderers = this.simpleRenderers;
|
||||
const result = parser.debug(links, tokens);
|
||||
|
||||
/**
|
||||
* Translates a token type into a readable form,
|
||||
* and moves `line` field to a first place in a token object.
|
||||
*/
|
||||
origin = origin.map((token) => {
|
||||
token.type = (TokenType as any)[token.type] || token.type;
|
||||
|
||||
const line = token.line;
|
||||
delete token.line;
|
||||
if (line) {
|
||||
return { ...{ line }, ...token };
|
||||
} else {
|
||||
return token;
|
||||
}
|
||||
});
|
||||
|
||||
return { tokens: origin, links, meta, result};
|
||||
}
|
||||
|
||||
protected static callBlockLexer(
|
||||
src: string = "",
|
||||
options?: MarkedOptions,
|
||||
): LexerReturns {
|
||||
if (typeof src != "string") {
|
||||
throw new Error(
|
||||
`Expected that the 'src' parameter would have a 'string' type, got '${typeof src}'`,
|
||||
);
|
||||
}
|
||||
|
||||
// Preprocessing.
|
||||
src = src
|
||||
.replace(/\r\n|\r/g, "\n")
|
||||
.replace(/\t/g, " ")
|
||||
.replace(/\u00a0/g, " ")
|
||||
.replace(/\u2424/g, "\n")
|
||||
.replace(/^ +$/gm, "");
|
||||
|
||||
return BlockLexer.lex(src, options, true);
|
||||
}
|
||||
|
||||
protected static callParser(
|
||||
tokens: Token[],
|
||||
links: Links,
|
||||
options?: MarkedOptions,
|
||||
): string {
|
||||
if (this.simpleRenderers.length) {
|
||||
const parser = new Parser(options);
|
||||
parser.simpleRenderers = this.simpleRenderers;
|
||||
return parser.parse(links, tokens);
|
||||
} else {
|
||||
return Parser.parse(tokens, links, options);
|
||||
}
|
||||
}
|
||||
|
||||
protected static callMe(err: Error) {
|
||||
err.message +=
|
||||
"\nPlease report this to https://github.com/ts-stack/markdown";
|
||||
|
||||
if (this.options.silent && this.options.escape) {
|
||||
return "<p>An error occured:</p><pre>" +
|
||||
this.options.escape(err.message + "", true) + "</pre>";
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
247
markdown/src/parser.ts
Normal file
@ -0,0 +1,247 @@
|
||||
/**
|
||||
* @license
|
||||
*
|
||||
* Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
|
||||
* https://github.com/chjj/marked
|
||||
*
|
||||
* Copyright (c) 2018, Костя Третяк. (MIT Licensed)
|
||||
* https://github.com/ts-stack/markdown
|
||||
*/
|
||||
|
||||
import { InlineLexer } from "./inline-lexer.ts";
|
||||
import {
|
||||
Links,
|
||||
MarkedOptions,
|
||||
SimpleRenderer,
|
||||
Token,
|
||||
TokenType,
|
||||
} from "./interfaces.ts";
|
||||
import { Marked } from "./marked.ts";
|
||||
import { Renderer } from "./renderer.ts";
|
||||
|
||||
/**
|
||||
* Parsing & Compiling.
|
||||
*/
|
||||
export class Parser {
|
||||
simpleRenderers: SimpleRenderer[] = [];
|
||||
protected tokens: Token[];
|
||||
protected token: Token | undefined;
|
||||
protected inlineLexer!: InlineLexer;
|
||||
protected options: MarkedOptions;
|
||||
protected renderer: Renderer;
|
||||
protected line: number = 0;
|
||||
|
||||
constructor(options?: MarkedOptions) {
|
||||
this.tokens = [];
|
||||
this.token = undefined;
|
||||
this.options = options || Marked.options;
|
||||
this.renderer = this.options.renderer || new Renderer(this.options);
|
||||
}
|
||||
|
||||
static parse(tokens: Token[], links: Links, options?: MarkedOptions): string {
|
||||
const parser = new this(options);
|
||||
return parser.parse(links, tokens);
|
||||
}
|
||||
|
||||
parse(links: Links, tokens: Token[]) {
|
||||
this.inlineLexer = new InlineLexer(
|
||||
InlineLexer,
|
||||
links,
|
||||
this.options,
|
||||
this.renderer,
|
||||
);
|
||||
this.tokens = tokens.reverse();
|
||||
|
||||
let out = "";
|
||||
|
||||
while (this.next()) {
|
||||
out += this.tok();
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
debug(links: Links, tokens: Token[]) {
|
||||
this.inlineLexer = new InlineLexer(
|
||||
InlineLexer,
|
||||
links,
|
||||
this.options,
|
||||
this.renderer,
|
||||
);
|
||||
this.tokens = tokens.reverse();
|
||||
|
||||
let out = "";
|
||||
|
||||
while (this.next()) {
|
||||
const outToken: string = this.tok() || "";
|
||||
if (!this.token) throw ReferenceError;
|
||||
this.token.line = this.line += outToken.split("\n").length - 1;
|
||||
out += outToken;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
protected next() {
|
||||
return (this.token = this.tokens.pop());
|
||||
}
|
||||
|
||||
protected getNextElement() {
|
||||
return this.tokens[this.tokens.length - 1];
|
||||
}
|
||||
|
||||
protected parseText() {
|
||||
if (!this.token) throw ReferenceError;
|
||||
let body = this.token.text;
|
||||
let nextElement: Token;
|
||||
|
||||
while (
|
||||
(nextElement = this.getNextElement()) &&
|
||||
nextElement.type == TokenType.text
|
||||
) {
|
||||
body += "\n" + this.next()?.text;
|
||||
}
|
||||
|
||||
return this.inlineLexer.output(body || "");
|
||||
}
|
||||
|
||||
protected tok() {
|
||||
if (!this.token) throw ReferenceError;
|
||||
switch (this.token.type) {
|
||||
case TokenType.space: {
|
||||
return "";
|
||||
}
|
||||
case TokenType.paragraph: {
|
||||
return this.renderer.paragraph(
|
||||
this.inlineLexer.output(this.token.text || ""),
|
||||
);
|
||||
}
|
||||
case TokenType.text: {
|
||||
if (this.options.isNoP) {
|
||||
return this.parseText();
|
||||
} else {
|
||||
return this.renderer.paragraph(this.parseText());
|
||||
}
|
||||
}
|
||||
case TokenType.heading: {
|
||||
return this.renderer.heading(
|
||||
this.inlineLexer.output(this.token.text || ""),
|
||||
this.token.depth || 0,
|
||||
this.token.text || "",
|
||||
);
|
||||
}
|
||||
case TokenType.listStart: {
|
||||
let body = "";
|
||||
const ordered = this.token.ordered;
|
||||
|
||||
while (this.next()?.type != TokenType.listEnd) {
|
||||
body += this.tok();
|
||||
}
|
||||
|
||||
return this.renderer.list(body, ordered);
|
||||
}
|
||||
case TokenType.listItemStart: {
|
||||
let body = "";
|
||||
|
||||
while (this.next()?.type != TokenType.listItemEnd) {
|
||||
body += this.token.type == (TokenType.text as any)
|
||||
? this.parseText()
|
||||
: this.tok();
|
||||
}
|
||||
|
||||
return this.renderer.listitem(body);
|
||||
}
|
||||
case TokenType.looseItemStart: {
|
||||
let body = "";
|
||||
|
||||
while (this.next()?.type != TokenType.listItemEnd) {
|
||||
body += this.tok();
|
||||
}
|
||||
|
||||
return this.renderer.listitem(body);
|
||||
}
|
||||
case TokenType.code: {
|
||||
return this.renderer.code(
|
||||
this.token.text || "",
|
||||
this.token.lang,
|
||||
this.token.escaped,
|
||||
);
|
||||
}
|
||||
case TokenType.table: {
|
||||
let header = "";
|
||||
let body = "";
|
||||
let cell;
|
||||
|
||||
if (
|
||||
!this.token || !this.token.header || !this.token.align ||
|
||||
!this.token.cells
|
||||
) {
|
||||
throw ReferenceError;
|
||||
}
|
||||
// header
|
||||
cell = "";
|
||||
for (let i = 0; i < this.token.header.length; i++) {
|
||||
const flags = { header: true, align: this.token.align[i] };
|
||||
const out = this.inlineLexer.output(this.token.header[i]);
|
||||
|
||||
cell += this.renderer.tablecell(out, flags);
|
||||
}
|
||||
|
||||
header += this.renderer.tablerow(cell);
|
||||
|
||||
for (const row of this.token.cells) {
|
||||
cell = "";
|
||||
|
||||
for (let j = 0; j < row.length; j++) {
|
||||
cell += this.renderer.tablecell(this.inlineLexer.output(row[j]), {
|
||||
header: false,
|
||||
align: this.token.align[j],
|
||||
});
|
||||
}
|
||||
|
||||
body += this.renderer.tablerow(cell);
|
||||
}
|
||||
|
||||
return this.renderer.table(header, body);
|
||||
}
|
||||
case TokenType.blockquoteStart: {
|
||||
let body = "";
|
||||
|
||||
while (this.next()?.type != TokenType.blockquoteEnd) {
|
||||
body += this.tok();
|
||||
}
|
||||
|
||||
return this.renderer.blockquote(body);
|
||||
}
|
||||
case TokenType.hr: {
|
||||
return this.renderer.hr();
|
||||
}
|
||||
case TokenType.html: {
|
||||
const html = !this.token.pre && !this.options.pedantic
|
||||
? this.inlineLexer.output(this.token.text || "")
|
||||
: this.token.text;
|
||||
return this.renderer.html(html || "");
|
||||
}
|
||||
default: {
|
||||
if (this.simpleRenderers.length) {
|
||||
for (let i = 0; i < this.simpleRenderers.length; i++) {
|
||||
if (this.token.type == "simpleRule" + (i + 1)) {
|
||||
return this.simpleRenderers[i].call(
|
||||
this.renderer,
|
||||
this.token.execArr,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const errMsg = `Token with "${this.token.type}" type was not found.`;
|
||||
|
||||
if (this.options.silent) {
|
||||
console.log(errMsg);
|
||||
} else {
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
179
markdown/src/renderer.ts
Normal file
@ -0,0 +1,179 @@
|
||||
/**
|
||||
* @license
|
||||
*
|
||||
* Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
|
||||
* https://github.com/chjj/marked
|
||||
*
|
||||
* Copyright (c) 2018, Костя Третяк. (MIT Licensed)
|
||||
* https://github.com/ts-stack/markdown
|
||||
*/
|
||||
|
||||
import type { Align, MarkedOptions } from "./interfaces.ts";
|
||||
import { Marked } from "./marked.ts";
|
||||
|
||||
export class Renderer {
|
||||
protected options: MarkedOptions;
|
||||
|
||||
constructor(options?: MarkedOptions) {
|
||||
this.options = options || Marked.options;
|
||||
}
|
||||
|
||||
code(code: string, lang?: string, escaped?: boolean): string {
|
||||
if (this.options.highlight) {
|
||||
const out = this.options.highlight(code, lang);
|
||||
|
||||
if (out != null && out !== code) {
|
||||
escaped = true;
|
||||
code = out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.options.escape) throw ReferenceError;
|
||||
|
||||
if (!lang) {
|
||||
return (
|
||||
"\n<pre><code>" +
|
||||
(escaped ? code : this.options.escape(code, true)) +
|
||||
"\n</code></pre>\n"
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
'\n<pre><code class="' +
|
||||
this.options.langPrefix +
|
||||
this.options.escape(lang, true) +
|
||||
'">' +
|
||||
(escaped ? code : this.options.escape(code, true)) +
|
||||
"\n</code></pre>\n"
|
||||
);
|
||||
}
|
||||
|
||||
blockquote(quote: string): string {
|
||||
return "<blockquote>\n" + quote + "</blockquote>\n";
|
||||
}
|
||||
|
||||
html(html: string): string {
|
||||
return html;
|
||||
}
|
||||
|
||||
heading(text: string, level: number, raw: string): string {
|
||||
const id: string =
|
||||
this.options.headerPrefix + raw.toLowerCase().replace(/[^\w]+/g, "-");
|
||||
|
||||
return `<h${level} id="${id}">${text}</h${level}>\n`;
|
||||
}
|
||||
|
||||
hr(): string {
|
||||
return this.options.xhtml ? "<hr/>\n" : "<hr>\n";
|
||||
}
|
||||
|
||||
list(body: string, ordered?: boolean): string {
|
||||
const type = ordered ? "ol" : "ul";
|
||||
|
||||
return `\n<${type}>\n${body}</${type}>\n`;
|
||||
}
|
||||
|
||||
listitem(text: string): string {
|
||||
return "<li>" + text + "</li>\n";
|
||||
}
|
||||
|
||||
paragraph(text: string): string {
|
||||
return "<p>" + text + "</p>\n";
|
||||
}
|
||||
|
||||
table(header: string, body: string): string {
|
||||
return `
|
||||
<table>
|
||||
<thead>
|
||||
${header}</thead>
|
||||
<tbody>
|
||||
${body}</tbody>
|
||||
</table>
|
||||
`;
|
||||
}
|
||||
|
||||
tablerow(content: string): string {
|
||||
return "<tr>\n" + content + "</tr>\n";
|
||||
}
|
||||
|
||||
tablecell(
|
||||
content: string,
|
||||
flags: { header?: boolean; align?: Align }
|
||||
): string {
|
||||
const type = flags.header ? "th" : "td";
|
||||
const tag = flags.align
|
||||
? "<" + type + ' style="text-align:' + flags.align + '">'
|
||||
: "<" + type + ">";
|
||||
return tag + content + "</" + type + ">\n";
|
||||
}
|
||||
|
||||
// *** Inline level renderer methods. ***
|
||||
|
||||
strong(text: string): string {
|
||||
return "<strong>" + text + "</strong>";
|
||||
}
|
||||
|
||||
em(text: string): string {
|
||||
return "<em>" + text + "</em>";
|
||||
}
|
||||
|
||||
codespan(text: string): string {
|
||||
return "<code>" + text + "</code>";
|
||||
}
|
||||
|
||||
br(): string {
|
||||
return this.options.xhtml ? "<br/>" : "<br>";
|
||||
}
|
||||
|
||||
del(text: string): string {
|
||||
return "<del>" + text + "</del>";
|
||||
}
|
||||
|
||||
link(href: string, title: string, text: string): string {
|
||||
if (this.options.sanitize) {
|
||||
let prot: string;
|
||||
if (!this.options.unescape) throw ReferenceError;
|
||||
try {
|
||||
prot = decodeURIComponent(this.options.unescape(href))
|
||||
.replace(/[^\w:]/g, "")
|
||||
.toLowerCase();
|
||||
} catch (e) {
|
||||
return text;
|
||||
}
|
||||
|
||||
if (
|
||||
prot.indexOf("javascript:") === 0 ||
|
||||
prot.indexOf("vbscript:") === 0 ||
|
||||
prot.indexOf("data:") === 0
|
||||
) {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
let out = '<a href="' + href + '"';
|
||||
|
||||
if (title) {
|
||||
out += ' title="' + title + '"';
|
||||
}
|
||||
|
||||
out += ">" + text + "</a>";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
image(href: string, title: string, text: string): string {
|
||||
let out = '<img src="' + href + '" alt="' + text + '"';
|
||||
|
||||
if (title) {
|
||||
out += ' title="' + title + '"';
|
||||
}
|
||||
|
||||
out += this.options.xhtml ? "/>" : ">";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
text(text: string): string {
|
||||
return text;
|
||||
}
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
FROM hibas123.azurecr.io/deno
|
||||
FROM docker.io/denoland/deno:alpine-1.38.3
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ADD src /app/src
|
||||
|
||||
RUN /usr/bin/deno cache --unstable src/registry.ts
|
||||
ADD public /app/public
|
||||
ADD deno.json /app/
|
||||
RUN deno cache --unstable src/registry.ts
|
||||
|
||||
VOLUME [ "/app/data" ]
|
||||
ENTRYPOINT [ "/usr/bin/deno", "run", "-A", "--unstable", "/app/src/registry.ts" ]
|
||||
CMD [ "run", "-A", "--unstable", "/app/src/registry.ts" ]
|
||||
|
19
registry/Earthfile
Normal file
@ -0,0 +1,19 @@
|
||||
VERSION 0.7
|
||||
FROM docker.io/runcitadel/deno:v1.29.3
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
docker-multi:
|
||||
BUILD --platform linux/amd64 --platform linux/arm64 +docker
|
||||
|
||||
docker:
|
||||
COPY src /app/src
|
||||
COPY public /app/public
|
||||
COPY deno.json /app/
|
||||
|
||||
RUN deno cache --unstable src/registry.ts
|
||||
CMD [ "run", "-A", "--unstable", "/app/src/registry.ts" ]
|
||||
|
||||
ARG EARTHLY_TARGET_TAG
|
||||
ARG TAG=$EARTHLY_TARGET_TAG
|
||||
SAVE IMAGE --push git.hibas.dev/deno/denreg:$TAG
|
19
registry/deno.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"tasks": {
|
||||
"start": "deno run --allow-net --allow-read index.tsx"
|
||||
},
|
||||
"imports": {
|
||||
"nano-jsx": "https://deno.land/x/nano_jsx@v0.0.34/mod.ts",
|
||||
"oak": "https://deno.land/x/oak@v10.6.0/mod.ts"
|
||||
},
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"dom.asynciterable",
|
||||
"deno.ns"
|
||||
],
|
||||
"jsxFactory": "h",
|
||||
"jsxFragmentFactory": "Fragment"
|
||||
}
|
||||
}
|
388
registry/deno.lock
generated
Normal file
@ -0,0 +1,388 @@
|
||||
{
|
||||
"version": "3",
|
||||
"redirects": {
|
||||
"https://deno.land/std/fs/mod.ts": "https://deno.land/std@0.208.0/fs/mod.ts",
|
||||
"https://deno.land/std/path/mod.ts": "https://deno.land/std@0.208.0/path/mod.ts",
|
||||
"https://deno.land/std/uuid/mod.ts": "https://deno.land/std@0.208.0/uuid/mod.ts",
|
||||
"https://deno.land/x/base64/base64url.ts": "https://deno.land/x/base64@v0.2.1/base64url.ts",
|
||||
"https://deno.land/x/nano_jsx/mod.ts": "https://deno.land/x/nano_jsx@v0.1.0/mod.ts",
|
||||
"https://git.stamm.me/Deno/DenReg/raw/branch/master/tar/mod.ts": "https://git.hibas.dev/Deno/DenReg/raw/branch/master/tar/mod.ts"
|
||||
},
|
||||
"remote": {
|
||||
"https://cdn.skypack.dev/-/@jsreport/mingo@v2.4.1-ZVYVnAnRedyuAPBNb9NZ/dist=es2019,mode=imports/optimized/@jsreport/mingo.js": "75213f47970810db2eaed8a551167ba85d301eeec879b21b8fce9faf61a68b33",
|
||||
"https://cdn.skypack.dev/-/prismjs@v1.29.0-tsFxawAKDjgdZ80OeL0T/dist=es2019,mode=imports/optimized/prismjs.js": "4aa116c4194f957b8500bd5fbcec3b2cf9c9132dad3d1fcebebe634b9ef8603e",
|
||||
"https://cdn.skypack.dev/@jsreport/mingo": "a2acca816e6078b3080e80b717fa09a9e0c7a805017d514536b0655b7dad79a7",
|
||||
"https://cdn.skypack.dev/prismjs": "2f31eecf3dea3232b302fbc57b7d0383d8f27d4ce1b14c72b77989d33de16bd5",
|
||||
"https://deno.hibas123.de/raw/ini@0.0.3/ini.ts": "436fba4744160024f02844ea255778c5009e65ececdccee65ff846e0edf5f829",
|
||||
"https://deno.hibas123.de/raw/ini@0.0.3/mod.ts": "c04a10c3a9e7849149caaf7a9101dce60919345149797ac463f5a6778f3e062f",
|
||||
"https://deno.hibas123.de/raw/markdown@0.1.0/mod.ts": "495ee5abb28bff8e6e4027819ece57f61342ef7715419675c1b1be24c47fc624",
|
||||
"https://deno.hibas123.de/raw/markdown@0.1.0/src/block-lexer.ts": "8bb407abb7dc0cdf99eef9610c67812057749a36f7ffddc87aa6ce30ece3df71",
|
||||
"https://deno.hibas123.de/raw/markdown@0.1.0/src/extend-regexp.ts": "187bbc8527a00add37f05790af39e0a242dd2064270ab52a536f104d76634ab7",
|
||||
"https://deno.hibas123.de/raw/markdown@0.1.0/src/helpers.ts": "5cfea4e14aed4dc1964c006bab11f83444f51db5cfdeeb9d94e0463f5fa3f369",
|
||||
"https://deno.hibas123.de/raw/markdown@0.1.0/src/inline-lexer.ts": "8e665c6540dd2dac5a71e4b0e67546b32315e7e2593ed076d4b5aecc03715df0",
|
||||
"https://deno.hibas123.de/raw/markdown@0.1.0/src/interfaces.ts": "fe985b08281f5e00e658aed72b16d1c890f465683f27e357b4aa34b26ff4e748",
|
||||
"https://deno.hibas123.de/raw/markdown@0.1.0/src/marked.ts": "36cacb1b13527429bf48935d0fed1f715e71238375ba5163054d57cb6ebbe732",
|
||||
"https://deno.hibas123.de/raw/markdown@0.1.0/src/parser.ts": "3b200dc5ca451f7309d794da517c8b80cfe333c3636e5beb168b29b952f10f9a",
|
||||
"https://deno.hibas123.de/raw/markdown@0.1.0/src/renderer.ts": "5437d447a90e6bdff628dde6c5e56d2210bc979661c47850576dc9ed9372334b",
|
||||
"https://deno.land/std@0.208.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee",
|
||||
"https://deno.land/std@0.208.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56",
|
||||
"https://deno.land/std@0.208.0/bytes/concat.ts": "d3d420badeb4f26a0f2f3ce343725f937326aff1b4634b25341b12b27353aac4",
|
||||
"https://deno.land/std@0.208.0/bytes/copy.ts": "939d89e302a9761dcf1d9c937c7711174ed74c59eef40a1e4569a05c9de88219",
|
||||
"https://deno.land/std@0.208.0/crypto/_fnv/fnv32.ts": "e4649dfdefc5c987ed53c3c25db62db771a06d9d1b9c36d2b5cf0853b8e82153",
|
||||
"https://deno.land/std@0.208.0/crypto/_fnv/fnv64.ts": "bfa0e4702061fdb490a14e6bf5f9168a22fb022b307c5723499469bfefca555e",
|
||||
"https://deno.land/std@0.208.0/crypto/_fnv/mod.ts": "f956a95f58910f223e420340b7404702ecd429603acd4491fa77af84f746040c",
|
||||
"https://deno.land/std@0.208.0/crypto/_fnv/util.ts": "accba12bfd80a352e32a872f87df2a195e75561f1b1304a4cb4f5a4648d288f9",
|
||||
"https://deno.land/std@0.208.0/crypto/_wasm/lib/deno_std_wasm_crypto.generated.mjs": "c41c4676a3ea2a92e8fdff55434533474131e4dfac2262a6a6c81631069808d8",
|
||||
"https://deno.land/std@0.208.0/crypto/_wasm/mod.ts": "d7b7dc54bbd6b02c16cd08e8e3d30fa9aa9692efb112a7ab5d8595827b9a0234",
|
||||
"https://deno.land/std@0.208.0/crypto/crypto.ts": "91c67764abb640b3e2a0b46867704d02077c0b1f978f5c711e4408e5d856717d",
|
||||
"https://deno.land/std@0.208.0/encoding/_util.ts": "f368920189c4fe6592ab2e93bd7ded8f3065b84f95cd3e036a4a10a75649dcba",
|
||||
"https://deno.land/std@0.208.0/encoding/base64.ts": "81c0ecff5ccb402def58ca03d8bd245bd01da15a077d3362b568e991aa10f4d9",
|
||||
"https://deno.land/std@0.208.0/fs/_util.ts": "fbf57dcdc9f7bc8128d60301eece608246971a7836a3bb1e78da75314f08b978",
|
||||
"https://deno.land/std@0.208.0/fs/copy.ts": "ca19e4837965914471df38fbd61e16f9e8adfe89f9cffb0c83615c83ea3fc2bf",
|
||||
"https://deno.land/std@0.208.0/fs/empty_dir.ts": "7fba29ef2d03f3503cd512616efc0535984cf1bbe7ca9d098e8b4d0d88910120",
|
||||
"https://deno.land/std@0.208.0/fs/ensure_dir.ts": "dc64c4c75c64721d4e3fb681f1382f803ff3d2868f08563ff923fdd20d071c40",
|
||||
"https://deno.land/std@0.208.0/fs/ensure_file.ts": "39ac83cc283a20ec2735e956adf5de3e8a3334e0b6820547b5772f71c49ae083",
|
||||
"https://deno.land/std@0.208.0/fs/ensure_link.ts": "c15e69c48556d78aae31b83e0c0ece04b7b8bc0951412f5b759aceb6fde7f0ac",
|
||||
"https://deno.land/std@0.208.0/fs/ensure_symlink.ts": "b389c8568f0656d145ac7ece472afe710815cccbb2ebfd19da7978379ae143fe",
|
||||
"https://deno.land/std@0.208.0/fs/eol.ts": "8565e1e076c5baced170236617150a7833668658e000205d896fc54084309ce1",
|
||||
"https://deno.land/std@0.208.0/fs/exists.ts": "cb59a853d84871d87acab0e7936a4dac11282957f8e195102c5a7acb42546bb8",
|
||||
"https://deno.land/std@0.208.0/fs/expand_glob.ts": "4f98c508fc9e40d6311d2f7fd88aaad05235cc506388c22dda315e095305811d",
|
||||
"https://deno.land/std@0.208.0/fs/mod.ts": "bc3d0acd488cc7b42627044caf47d72019846d459279544e1934418955ba4898",
|
||||
"https://deno.land/std@0.208.0/fs/move.ts": "b4f8f46730b40c32ea3c0bc8eb0fd0e8139249a698883c7b3756424cf19785c9",
|
||||
"https://deno.land/std@0.208.0/fs/walk.ts": "c1e6b43f72a46e89b630140308bd51a4795d416a416b4cfb7cd4bd1e25946723",
|
||||
"https://deno.land/std@0.208.0/io/buffer.ts": "11acaeae3dc0e491a335d82915e09e9f8afd53ecb82562515e5951e78f69b076",
|
||||
"https://deno.land/std@0.208.0/path/_common/assert_path.ts": "061e4d093d4ba5aebceb2c4da3318bfe3289e868570e9d3a8e327d91c2958946",
|
||||
"https://deno.land/std@0.208.0/path/_common/basename.ts": "0d978ff818f339cd3b1d09dc914881f4d15617432ae519c1b8fdc09ff8d3789a",
|
||||
"https://deno.land/std@0.208.0/path/_common/common.ts": "9e4233b2eeb50f8b2ae10ecc2108f58583aea6fd3e8907827020282dc2b76143",
|
||||
"https://deno.land/std@0.208.0/path/_common/constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
|
||||
"https://deno.land/std@0.208.0/path/_common/dirname.ts": "2ba7fb4cc9fafb0f38028f434179579ce61d4d9e51296fad22b701c3d3cd7397",
|
||||
"https://deno.land/std@0.208.0/path/_common/format.ts": "11aa62e316dfbf22c126917f5e03ea5fe2ee707386555a8f513d27ad5756cf96",
|
||||
"https://deno.land/std@0.208.0/path/_common/from_file_url.ts": "ef1bf3197d2efbf0297a2bdbf3a61d804b18f2bcce45548ae112313ec5be3c22",
|
||||
"https://deno.land/std@0.208.0/path/_common/glob_to_reg_exp.ts": "5c3c2b79fc2294ec803d102bd9855c451c150021f452046312819fbb6d4dc156",
|
||||
"https://deno.land/std@0.208.0/path/_common/normalize.ts": "2ba7fb4cc9fafb0f38028f434179579ce61d4d9e51296fad22b701c3d3cd7397",
|
||||
"https://deno.land/std@0.208.0/path/_common/normalize_string.ts": "88c472f28ae49525f9fe82de8c8816d93442d46a30d6bb5063b07ff8a89ff589",
|
||||
"https://deno.land/std@0.208.0/path/_common/relative.ts": "1af19d787a2a84b8c534cc487424fe101f614982ae4851382c978ab2216186b4",
|
||||
"https://deno.land/std@0.208.0/path/_common/strip_trailing_separators.ts": "7ffc7c287e97bdeeee31b155828686967f222cd73f9e5780bfe7dfb1b58c6c65",
|
||||
"https://deno.land/std@0.208.0/path/_common/to_file_url.ts": "a8cdd1633bc9175b7eebd3613266d7c0b6ae0fb0cff24120b6092ac31662f9ae",
|
||||
"https://deno.land/std@0.208.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b",
|
||||
"https://deno.land/std@0.208.0/path/_os.ts": "30b0c2875f360c9296dbe6b7f2d528f0f9c741cecad2e97f803f5219e91b40a2",
|
||||
"https://deno.land/std@0.208.0/path/basename.ts": "04bb5ef3e86bba8a35603b8f3b69537112cdd19ce64b77f2522006da2977a5f3",
|
||||
"https://deno.land/std@0.208.0/path/common.ts": "f4d061c7d0b95a65c2a1a52439edec393e906b40f1caf4604c389fae7caa80f5",
|
||||
"https://deno.land/std@0.208.0/path/dirname.ts": "88a0a71c21debafc4da7a4cd44fd32e899462df458fbca152390887d41c40361",
|
||||
"https://deno.land/std@0.208.0/path/extname.ts": "2da4e2490f3b48b7121d19fb4c91681a5e11bd6bd99df4f6f47d7a71bb6ecdf2",
|
||||
"https://deno.land/std@0.208.0/path/format.ts": "3457530cc85d1b4bab175f9ae73998b34fd456c830d01883169af0681b8894fb",
|
||||
"https://deno.land/std@0.208.0/path/from_file_url.ts": "e7fa233ea1dff9641e8d566153a24d95010110185a6f418dd2e32320926043f8",
|
||||
"https://deno.land/std@0.208.0/path/glob.ts": "a00a81a55c02bbe074ab21a50b6495c6f7795f54cd718c824adaa92c6c9b7419",
|
||||
"https://deno.land/std@0.208.0/path/glob_to_regexp.ts": "74d7448c471e293d03f05ccb968df4365fed6aaa508506b6325a8efdc01d8271",
|
||||
"https://deno.land/std@0.208.0/path/is_absolute.ts": "67232b41b860571c5b7537f4954c88d86ae2ba45e883ee37d3dec27b74909d13",
|
||||
"https://deno.land/std@0.208.0/path/is_glob.ts": "567dce5c6656bdedfc6b3ee6c0833e1e4db2b8dff6e62148e94a917f289c06ad",
|
||||
"https://deno.land/std@0.208.0/path/join.ts": "98d3d76c819af4a11a81d5ba2dbb319f1ce9d63fc2b615597d4bcfddd4a89a09",
|
||||
"https://deno.land/std@0.208.0/path/join_globs.ts": "9b84d5103b63d3dbed4b2cf8b12477b2ad415c7d343f1488505162dc0e5f4db8",
|
||||
"https://deno.land/std@0.208.0/path/mod.ts": "3defabebc98279e62b392fee7a6937adc932a8f4dcd2471441e36c15b97b00e0",
|
||||
"https://deno.land/std@0.208.0/path/normalize.ts": "aa95be9a92c7bd4f9dc0ba51e942a1973e2b93d266cd74f5ca751c136d520b66",
|
||||
"https://deno.land/std@0.208.0/path/normalize_glob.ts": "674baa82e1c00b6cb153bbca36e06f8e0337cb8062db6d905ab5de16076ca46b",
|
||||
"https://deno.land/std@0.208.0/path/parse.ts": "d87ff0deef3fb495bc0d862278ff96da5a06acf0625ca27769fc52ac0d3d6ece",
|
||||
"https://deno.land/std@0.208.0/path/posix/_util.ts": "ecf49560fedd7dd376c6156cc5565cad97c1abe9824f4417adebc7acc36c93e5",
|
||||
"https://deno.land/std@0.208.0/path/posix/basename.ts": "a630aeb8fd8e27356b1823b9dedd505e30085015407caa3396332752f6b8406a",
|
||||
"https://deno.land/std@0.208.0/path/posix/common.ts": "e781d395dc76f6282e3f7dd8de13194abb8b04a82d109593141abc6e95755c8b",
|
||||
"https://deno.land/std@0.208.0/path/posix/dirname.ts": "f48c9c42cc670803b505478b7ef162c7cfa9d8e751b59d278b2ec59470531472",
|
||||
"https://deno.land/std@0.208.0/path/posix/extname.ts": "ee7f6571a9c0a37f9218fbf510c440d1685a7c13082c348d701396cc795e0be0",
|
||||
"https://deno.land/std@0.208.0/path/posix/format.ts": "b94876f77e61bfe1f147d5ccb46a920636cd3cef8be43df330f0052b03875968",
|
||||
"https://deno.land/std@0.208.0/path/posix/from_file_url.ts": "b97287a83e6407ac27bdf3ab621db3fccbf1c27df0a1b1f20e1e1b5acf38a379",
|
||||
"https://deno.land/std@0.208.0/path/posix/glob_to_regexp.ts": "6ed00c71fbfe0ccc35977c35444f94e82200b721905a60bd1278b1b768d68b1a",
|
||||
"https://deno.land/std@0.208.0/path/posix/is_absolute.ts": "159900a3422d11069d48395568217eb7fc105ceda2683d03d9b7c0f0769e01b8",
|
||||
"https://deno.land/std@0.208.0/path/posix/is_glob.ts": "ec4fbc604b9db8487f7b56ab0e759b24a971ab6a45f7b0b698bc39b8b9f9680f",
|
||||
"https://deno.land/std@0.208.0/path/posix/join.ts": "0c0d84bdc344876930126640011ec1b888e6facf74153ffad9ef26813aa2a076",
|
||||
"https://deno.land/std@0.208.0/path/posix/join_globs.ts": "f4838d54b1f60a34a40625a3293f6e583135348be1b2974341ac04743cb26121",
|
||||
"https://deno.land/std@0.208.0/path/posix/mod.ts": "f1b08a7f64294b7de87fc37190d63b6ce5b02889af9290c9703afe01951360ae",
|
||||
"https://deno.land/std@0.208.0/path/posix/normalize.ts": "11de90a94ab7148cc46e5a288f7d732aade1d616bc8c862f5560fa18ff987b4b",
|
||||
"https://deno.land/std@0.208.0/path/posix/normalize_glob.ts": "10a1840c628ebbab679254d5fa1c20e59106102354fb648a1765aed72eb9f3f9",
|
||||
"https://deno.land/std@0.208.0/path/posix/parse.ts": "199208f373dd93a792e9c585352bfc73a6293411bed6da6d3bc4f4ef90b04c8e",
|
||||
"https://deno.land/std@0.208.0/path/posix/relative.ts": "e2f230608b0f083e6deaa06e063943e5accb3320c28aef8d87528fbb7fe6504c",
|
||||
"https://deno.land/std@0.208.0/path/posix/resolve.ts": "51579d83159d5c719518c9ae50812a63959bbcb7561d79acbdb2c3682236e285",
|
||||
"https://deno.land/std@0.208.0/path/posix/separator.ts": "0b6573b5f3269a3164d8edc9cefc33a02dd51003731c561008c8bb60220ebac1",
|
||||
"https://deno.land/std@0.208.0/path/posix/to_file_url.ts": "08d43ea839ee75e9b8b1538376cfe95911070a655cd312bc9a00f88ef14967b6",
|
||||
"https://deno.land/std@0.208.0/path/posix/to_namespaced_path.ts": "c9228a0e74fd37e76622cd7b142b8416663a9b87db643302fa0926b5a5c83bdc",
|
||||
"https://deno.land/std@0.208.0/path/relative.ts": "23d45ede8b7ac464a8299663a43488aad6b561414e7cbbe4790775590db6349c",
|
||||
"https://deno.land/std@0.208.0/path/resolve.ts": "5b184efc87155a0af9fa305ff68a109e28de9aee81fc3e77cd01380f19daf867",
|
||||
"https://deno.land/std@0.208.0/path/separator.ts": "40a3e9a4ad10bef23bc2cd6c610291b6c502a06237c2c4cd034a15ca78dedc1f",
|
||||
"https://deno.land/std@0.208.0/path/to_file_url.ts": "edaafa089e0bce386e1b2d47afe7c72e379ff93b28a5829a5885e4b6c626d864",
|
||||
"https://deno.land/std@0.208.0/path/to_namespaced_path.ts": "cf8734848aac3c7527d1689d2adf82132b1618eff3cc523a775068847416b22a",
|
||||
"https://deno.land/std@0.208.0/path/windows/_util.ts": "f32b9444554c8863b9b4814025c700492a2b57ff2369d015360970a1b1099d54",
|
||||
"https://deno.land/std@0.208.0/path/windows/basename.ts": "8a9dbf7353d50afbc5b221af36c02a72c2d1b2b5b9f7c65bf6a5a2a0baf88ad3",
|
||||
"https://deno.land/std@0.208.0/path/windows/common.ts": "e781d395dc76f6282e3f7dd8de13194abb8b04a82d109593141abc6e95755c8b",
|
||||
"https://deno.land/std@0.208.0/path/windows/dirname.ts": "5c2aa541384bf0bd9aca821275d2a8690e8238fa846198ef5c7515ce31a01a94",
|
||||
"https://deno.land/std@0.208.0/path/windows/extname.ts": "07f4fa1b40d06a827446b3e3bcc8d619c5546b079b8ed0c77040bbef716c7614",
|
||||
"https://deno.land/std@0.208.0/path/windows/format.ts": "343019130d78f172a5c49fdc7e64686a7faf41553268961e7b6c92a6d6548edf",
|
||||
"https://deno.land/std@0.208.0/path/windows/from_file_url.ts": "d53335c12b0725893d768be3ac6bf0112cc5b639d2deb0171b35988493b46199",
|
||||
"https://deno.land/std@0.208.0/path/windows/glob_to_regexp.ts": "290755e18ec6c1a4f4d711c3390537358e8e3179581e66261a0cf348b1a13395",
|
||||
"https://deno.land/std@0.208.0/path/windows/is_absolute.ts": "245b56b5f355ede8664bd7f080c910a97e2169972d23075554ae14d73722c53c",
|
||||
"https://deno.land/std@0.208.0/path/windows/is_glob.ts": "ec4fbc604b9db8487f7b56ab0e759b24a971ab6a45f7b0b698bc39b8b9f9680f",
|
||||
"https://deno.land/std@0.208.0/path/windows/join.ts": "e6600bf88edeeef4e2276e155b8de1d5dec0435fd526ba2dc4d37986b2882f16",
|
||||
"https://deno.land/std@0.208.0/path/windows/join_globs.ts": "f4838d54b1f60a34a40625a3293f6e583135348be1b2974341ac04743cb26121",
|
||||
"https://deno.land/std@0.208.0/path/windows/mod.ts": "d7040f461465c2c21c1c68fc988ef0bdddd499912138cde3abf6ad60c7fb3814",
|
||||
"https://deno.land/std@0.208.0/path/windows/normalize.ts": "9deebbf40c81ef540b7b945d4ccd7a6a2c5a5992f791e6d3377043031e164e69",
|
||||
"https://deno.land/std@0.208.0/path/windows/normalize_glob.ts": "344ff5ed45430495b9a3d695567291e50e00b1b3b04ea56712a2acf07ab5c128",
|
||||
"https://deno.land/std@0.208.0/path/windows/parse.ts": "120faf778fe1f22056f33ded069b68e12447668fcfa19540c0129561428d3ae5",
|
||||
"https://deno.land/std@0.208.0/path/windows/relative.ts": "026855cd2c36c8f28f1df3c6fbd8f2449a2aa21f48797a74700c5d872b86d649",
|
||||
"https://deno.land/std@0.208.0/path/windows/resolve.ts": "5ff441ab18a2346abadf778121128ee71bda4d0898513d4639a6ca04edca366b",
|
||||
"https://deno.land/std@0.208.0/path/windows/separator.ts": "ae21f27015f10510ed1ac4a0ba9c4c9c967cbdd9d9e776a3e4967553c397bd5d",
|
||||
"https://deno.land/std@0.208.0/path/windows/to_file_url.ts": "8e9ea9e1ff364aa06fa72999204229952d0a279dbb876b7b838b2b2fea55cce3",
|
||||
"https://deno.land/std@0.208.0/path/windows/to_namespaced_path.ts": "e0f4d4a5e77f28a5708c1a33ff24360f35637ba6d8f103d19661255ef7bfd50d",
|
||||
"https://deno.land/std@0.208.0/streams/_common.ts": "3b2c1f0287ce2ad51fff4091a7d0f48375c85b0ec341468e76d5ac13bb0014dd",
|
||||
"https://deno.land/std@0.208.0/streams/buffer.ts": "6cd773d22cf21bb988a98cc551b5abfc4c3b03516f93eaa3fb6f2f6e16032deb",
|
||||
"https://deno.land/std@0.208.0/streams/byte_slice_stream.ts": "c46d7c74836fc8c1a9acd9fe211cbe1bbaaee1b36087c834fb03af4991135c3a",
|
||||
"https://deno.land/std@0.208.0/streams/copy.ts": "faa201291ce9116fb1fae9d16b4f033e259fdea437b77404ff5cf742507844e6",
|
||||
"https://deno.land/std@0.208.0/streams/delimiter_stream.ts": "af7aab15d830636265c998ca330576edb6a50959fec1949d2fa57ef8dda299d2",
|
||||
"https://deno.land/std@0.208.0/streams/early_zip_readable_streams.ts": "4005fa74162b943f79899e5d7cb96adcbc0a6b867f9144974ed12d30e0a556e1",
|
||||
"https://deno.land/std@0.208.0/streams/iterate_reader.ts": "d6b2770f8ee27fb1c1e2c5a3c66451647f6fb5371534c78bef2ce614d60568d8",
|
||||
"https://deno.land/std@0.208.0/streams/limited_bytes_transform_stream.ts": "05dc592ffaab83257494d22dd53917e56243c26e5e3129b3f13ddbbbc4785048",
|
||||
"https://deno.land/std@0.208.0/streams/limited_transform_stream.ts": "d69ab790232c1b86f53621ad41ef03c235f2abb4b7a1cd51960ad6e12ee55e38",
|
||||
"https://deno.land/std@0.208.0/streams/merge_readable_streams.ts": "22963b9bbec8d000d9613db859002768e013fd731cafd55942dc0120d03e7b5d",
|
||||
"https://deno.land/std@0.208.0/streams/mod.ts": "e133c271474f1e9dc19f5c4959406f5c2101540c56a3e7d7abc6bdb7bcef807e",
|
||||
"https://deno.land/std@0.208.0/streams/read_all.ts": "64bfb842f4047f81d977dead27b6e5a9faaba17c8f1c30066284553dcfc13171",
|
||||
"https://deno.land/std@0.208.0/streams/readable_stream_from_reader.ts": "c28abb70a35c683f522b6bd43d39c272db33d86d874c59e728e26f270956b773",
|
||||
"https://deno.land/std@0.208.0/streams/reader_from_iterable.ts": "4fd184770b3756987b97c7718df3f5c4a2828b50e1cdc33111827d640dca6366",
|
||||
"https://deno.land/std@0.208.0/streams/reader_from_stream_reader.ts": "6fb8852fdd9775ce940a4facf6e265f1f233cc3b90f6d064b1556f6b0ef3d18b",
|
||||
"https://deno.land/std@0.208.0/streams/text_delimiter_stream.ts": "f0dc8ff953a8a77f0d1fa8db1fee62de817f36e20d79b00b1362847e30fbdd90",
|
||||
"https://deno.land/std@0.208.0/streams/text_line_stream.ts": "4958525688593d20c1c439a006dabd64881736bff642744ca060b2c34b40c240",
|
||||
"https://deno.land/std@0.208.0/streams/to_array_buffer.ts": "31b0729f6527054760a3758e84d6d646eac0f7f586204a81824c3eb7728ce836",
|
||||
"https://deno.land/std@0.208.0/streams/to_blob.ts": "4cf929b3ffe5d4dbe445d572246159ee2eebf69e998a0ba867b9048fb6e92797",
|
||||
"https://deno.land/std@0.208.0/streams/to_json.ts": "10635fac9826392bb8e70bc8354d3beb1058fa1676aa9b6f98257a0d5575f520",
|
||||
"https://deno.land/std@0.208.0/streams/to_text.ts": "4018b5f7a0e7ab28d6957c239e401f8b534ef326b7ebd282ca76b3cd55380aab",
|
||||
"https://deno.land/std@0.208.0/streams/to_transform_stream.ts": "50af06140c414090df8c3879f46bed4043a5d73caa60352c0c9682a88ec7a8c9",
|
||||
"https://deno.land/std@0.208.0/streams/writable_stream_from_writer.ts": "057bdfc6c08e34a8a86e2d61efe7354a8a0976260cd1437de8b7e64bcefaa9b9",
|
||||
"https://deno.land/std@0.208.0/streams/write_all.ts": "8fc9525c16eb60eb851274d4693ecd35c2177620239fbdfa8f5aacb32702f2cb",
|
||||
"https://deno.land/std@0.208.0/streams/writer_from_stream_writer.ts": "71d7a26f2a2b955794a7318856ad64d9eade36467d930b40698d3d5bfb0ce3b4",
|
||||
"https://deno.land/std@0.208.0/streams/zip_readable_streams.ts": "721c5bce8862c8225e60995b2d61c7b1b1d5b5178b60d303a01f453d5c26bb62",
|
||||
"https://deno.land/std@0.208.0/uuid/_common.ts": "cb1441f4df460571fc0919e1c5c217f3e7006189b703caf946604b3f791ae34d",
|
||||
"https://deno.land/std@0.208.0/uuid/constants.ts": "0d0e95561343da44adb4a4edbc1f04cef48b0d75288c4d1704f58743f4a50d88",
|
||||
"https://deno.land/std@0.208.0/uuid/mod.ts": "5c7ca252dddba1ddf0bca2dc1124328245272650c98251d71996bb9cd8f5a386",
|
||||
"https://deno.land/std@0.208.0/uuid/v1.ts": "fe36009afce7ced96e1b5928565e12c5a8eb0df1a2b5063c0a72bda6b75c0de5",
|
||||
"https://deno.land/std@0.208.0/uuid/v3.ts": "397ad58daec8b5ef6ba7e94fe86c9bc56b194adcbe2f70ec40a1fb005203c870",
|
||||
"https://deno.land/std@0.208.0/uuid/v4.ts": "0f081880c156fd59b9e44e2f84ea0f94a3627e89c224eaf6cc982b53d849f37e",
|
||||
"https://deno.land/std@0.208.0/uuid/v5.ts": "9daaf769e487b512d25adf8e137e05ff2e3392d27f66d5b273ee28030ff7cd58",
|
||||
"https://deno.land/std@0.208.0/yaml/_dumper/dumper.ts": "717403d0e700de783f2ef5c906b3d7245383e1509fc050e7ff5d4a53a03dbf40",
|
||||
"https://deno.land/std@0.208.0/yaml/_dumper/dumper_state.ts": "f0d0673ceea288334061ca34b63954c2bb5feb5bf6de5e4cfe9a942cdf6e5efe",
|
||||
"https://deno.land/std@0.208.0/yaml/_error.ts": "b59e2c76ce5a47b1b9fa0ff9f96c1dd92ea1e1b17ce4347ece5944a95c3c1a84",
|
||||
"https://deno.land/std@0.208.0/yaml/_loader/loader.ts": "63ec7f0a265dbbabc54b25a4beefff7650e205160a2d75c7d8f8363b5f84851a",
|
||||
"https://deno.land/std@0.208.0/yaml/_loader/loader_state.ts": "0841870b467169269d7c2dfa75cd288c319bc06f65edd9e42c29e5fced91c7a4",
|
||||
"https://deno.land/std@0.208.0/yaml/_mark.ts": "dcd8585dee585e024475e9f3fe27d29740670fb64ebb970388094cad0fc11d5d",
|
||||
"https://deno.land/std@0.208.0/yaml/_state.ts": "ef03d55ec235d48dcfbecc0ab3ade90bfae69a61094846e08003421c2cf5cfc6",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/binary.ts": "24d49614463a7339a8a16d894919c2ec18a10588ae360ec352093b60e2cc8b0d",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/bool.ts": "5bfa75da84343d45347b521ba4e5aeace9fe6f53447405290d53315a3fc20e66",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/float.ts": "056bd3cb9c5586238b20517511014fb24b0e36f98f9f6073e12da308b6b9808a",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/function.ts": "ff574fe84a750695302864e1c31b93f12d14ada4bde79a5f93197fc33ad17471",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/int.ts": "563ad074f0fa7aecf6b6c3d84135bcc95a8269dcc15de878de20ce868fd773fa",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/map.ts": "7b105e4ab03a361c61e7e335a0baf4d40f06460b13920e5af3fb2783a1464000",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/merge.ts": "8192bf3e4d637f32567917f48bb276043da9cf729cf594e5ec191f7cd229337e",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/mod.ts": "060e2b3d38725094b77ea3a3f05fc7e671fced8e67ca18e525be98c4aa8f4bbb",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/nil.ts": "606e8f0c44d73117c81abec822f89ef81e40f712258c74f186baa1af659b8887",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/omap.ts": "cfe59a294726f5cea705c39a61fd2b08199cf48f4ccd6b040cb550ec0f38d0a1",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/pairs.ts": "0032fdfe57558d21696a4f8cf5b5cfd1f698743177080affc18629685c905666",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/regexp.ts": "1ce118de15b2da43b4bd8e4395f42d448b731acf3bdaf7c888f40789f9a95f8b",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/seq.ts": "95333abeec8a7e4d967b8c8328b269e342a4bbdd2585395549b9c4f58c8533a2",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/set.ts": "f28ba44e632ef2a6eb580486fd47a460445eeddbdf1dbc739c3e62486f566092",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/str.ts": "a67a3c6e429d95041399e964015511779b1130ea5889fa257c48457bd3446e31",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/timestamp.ts": "706ea80a76a73e48efaeb400ace087da1f927647b53ad6f754f4e06d51af087f",
|
||||
"https://deno.land/std@0.208.0/yaml/_type/undefined.ts": "94a316ca450597ccbc6750cbd79097ad0d5f3a019797eed3c841a040c29540ba",
|
||||
"https://deno.land/std@0.208.0/yaml/_utils.ts": "26b311f0d42a7ce025060bd6320a68b50e52fd24a839581eb31734cd48e20393",
|
||||
"https://deno.land/std@0.208.0/yaml/mod.ts": "28ecda6652f3e7a7735ee29c247bfbd32a2e2fc5724068e9fd173ec4e59f66f7",
|
||||
"https://deno.land/std@0.208.0/yaml/parse.ts": "1fbbda572bf3fff578b6482c0d8b85097a38de3176bf3ab2ca70c25fb0c960ef",
|
||||
"https://deno.land/std@0.208.0/yaml/schema.ts": "96908b78dc50c340074b93fc1598d5e7e2fe59103f89ff81e5a49b2dedf77a67",
|
||||
"https://deno.land/std@0.208.0/yaml/schema/core.ts": "fa406f18ceedc87a50e28bb90ec7a4c09eebb337f94ef17468349794fa828639",
|
||||
"https://deno.land/std@0.208.0/yaml/schema/default.ts": "0047e80ae8a4a93293bc4c557ae8a546aabd46bb7165b9d9b940d57b4d88bde9",
|
||||
"https://deno.land/std@0.208.0/yaml/schema/extended.ts": "0784416bf062d20a1626b53c03380e265b3e39b9409afb9f4cb7d659fd71e60d",
|
||||
"https://deno.land/std@0.208.0/yaml/schema/failsafe.ts": "d219ab5febc43f770917d8ec37735a4b1ad671149846cbdcade767832b42b92b",
|
||||
"https://deno.land/std@0.208.0/yaml/schema/json.ts": "5f41dd7c2f1ad545ef6238633ce9ee3d444dfc5a18101e1768bd5504bf90e5e5",
|
||||
"https://deno.land/std@0.208.0/yaml/schema/mod.ts": "4472e827bab5025e92bc2eb2eeefa70ecbefc64b2799b765c69af84822efef32",
|
||||
"https://deno.land/std@0.208.0/yaml/stringify.ts": "fffc09c65c68d3d63f8159e8cbaa3f489bc20a8e55b4fbb61a8c2e9f914d1d02",
|
||||
"https://deno.land/std@0.208.0/yaml/type.ts": "65553da3da3c029b6589c6e4903f0afbea6768be8fca61580711457151f2b30f",
|
||||
"https://deno.land/std@0.63.0/_util/assert.ts": "e1f76e77c5ccb5a8e0dbbbe6cce3a56d2556c8cb5a9a8802fc9565af72462149",
|
||||
"https://deno.land/std@0.63.0/archive/tar.ts": "5a0a7465d57fec2684239b07da0f5ec884c6c71a768297f73c348f22e04acd92",
|
||||
"https://deno.land/std@0.63.0/bytes/mod.ts": "b1a149ac741728db00bda9ce1a2d044f248edd5ac95e708a6cc501bfd3adb4a7",
|
||||
"https://deno.land/std@0.63.0/encoding/utf8.ts": "8654fa820aa69a37ec5eb11908e20b39d056c9bf1c23ab294303ff467f3d50a1",
|
||||
"https://deno.land/std@0.63.0/fs/_util.ts": "68508c05d5a02678179a02beabf2b3eac5b16c5a9cbd1c272686d8101bb2679d",
|
||||
"https://deno.land/std@0.63.0/fs/copy.ts": "b562e8f482cb8459bb011cbd769769bbdb4f6bc966effd277c06edbdbe41b72e",
|
||||
"https://deno.land/std@0.63.0/fs/empty_dir.ts": "4d706eb01e5d08d862c673200d1978526e485368559fc7fb0f297add68f9cc43",
|
||||
"https://deno.land/std@0.63.0/fs/ensure_dir.ts": "54cf0cfb16160857116d1bdff98214ad0189275fe2f089607fdc06c52ac79cc4",
|
||||
"https://deno.land/std@0.63.0/fs/ensure_file.ts": "b70eccaee6f41ae226d399ad9c8ebc29beb5dd86fe179d30ab7e681976352baf",
|
||||
"https://deno.land/std@0.63.0/fs/ensure_link.ts": "f647cea5c3b65f4a6618444546e9ca891d38f54f7fd4c718fb1fd575b4232213",
|
||||
"https://deno.land/std@0.63.0/fs/ensure_symlink.ts": "d472af1507fb920db214f6816522ddc89eefd5800735243873053b2523882ec1",
|
||||
"https://deno.land/std@0.63.0/fs/eol.ts": "4a0b2a612e0639b76d9c5fab0392e7bf1a158a7dab191ff7b7564870a1173812",
|
||||
"https://deno.land/std@0.63.0/fs/exists.ts": "5429dce6587bfcdde06a7a2a1fd5ad932c17d74ca082e67934fa646cff1d2e57",
|
||||
"https://deno.land/std@0.63.0/fs/expand_glob.ts": "415a109faaf50f8bf3e116bac534928a72373d0a981784e6130d91d11ce543a6",
|
||||
"https://deno.land/std@0.63.0/fs/mod.ts": "88bb982130bb86df1cb350619fed4118c4cc439eeced6484330b7255e3a16568",
|
||||
"https://deno.land/std@0.63.0/fs/move.ts": "020f56063c66288facbebc7d3c8dd3f309b0949fcaea49e463ccd5217fc82e2c",
|
||||
"https://deno.land/std@0.63.0/fs/read_json.ts": "6922a9adc50cd2a7233298fd7b7ad9062d8602a55d4abb2b72d23ef0268b1306",
|
||||
"https://deno.land/std@0.63.0/fs/walk.ts": "1715028b1646648b1239b9f93ff42beaf38f8e77424f8f9c2ffab9ee1594a54f",
|
||||
"https://deno.land/std@0.63.0/fs/write_json.ts": "89a6231f51a6759dfff8f1f5534d030c2239c22fc9f3c0b3305d424f4f1d5604",
|
||||
"https://deno.land/std@0.63.0/io/bufio.ts": "e76c5b7bf978a638aae6f62b87efde3ab7203b85902ce9b84ac8388c8c2bb104",
|
||||
"https://deno.land/std@0.63.0/io/readers.ts": "4c2e98abf2a2a1d5e2adaf460479a1c69f742951c1bc141b26654d2f5248b663",
|
||||
"https://deno.land/std@0.63.0/path/_constants.ts": "e11f32a36644e04dce243f3c1f30c02cc5d149827f48a755628176f0707cfc70",
|
||||
"https://deno.land/std@0.63.0/path/_globrex.ts": "cfd1af99fb5ed2eff9b49aef994cdf7a14a5d26cd32b14c60b27bfff49839c82",
|
||||
"https://deno.land/std@0.63.0/path/_interface.ts": "5876f91d35fd42624893a4aaddaee352144e1f46e719f1dde6511bab7c3c1029",
|
||||
"https://deno.land/std@0.63.0/path/_util.ts": "f0fa012d40ae9b6acbef03908e534eb11e694de6470fb4d78ea4f38829e735ab",
|
||||
"https://deno.land/std@0.63.0/path/common.ts": "e4ec66a7416d56f60331b66e27a8a4f08c7b1cf48e350271cb69754a01cf5c04",
|
||||
"https://deno.land/std@0.63.0/path/glob.ts": "dbcda011329b5ba0f955823e578af19a8bf8d01586a07925b42affe885544e62",
|
||||
"https://deno.land/std@0.63.0/path/mod.ts": "6de8885c2534757097818e302becd1cefcbc4c28ac022cc279e612ee04e8cfd1",
|
||||
"https://deno.land/std@0.63.0/path/posix.ts": "1a6e53e1c90dde43750f38134ace0f6300f7330f5456b60d4979a4564fcf5f7a",
|
||||
"https://deno.land/std@0.63.0/path/separator.ts": "9dd15d46ff84a16e13554f56af7fee1f85f8d0f379efbbe60ac066a60561f036",
|
||||
"https://deno.land/std@0.63.0/path/win32.ts": "b530878b0f3f281c7f06fa73dc8e89a15106ab06e88ca1dea27394d09a1b0514",
|
||||
"https://deno.land/std@0.79.0/async/pool.ts": "a499691231d8c249f044f69d204b479ad3af7f115e0b37342829eff076bc2450",
|
||||
"https://deno.land/std@0.79.0/encoding/base64.ts": "b1d8f99b778981548457ec74bc6273ad785ffd6f61b2233bd5b30925345b565d",
|
||||
"https://deno.land/std@0.79.0/encoding/hex.ts": "07a03ba41c96060a4ed4ba272e50b9e23f3c5b3839f4b069cdebc24d57434386",
|
||||
"https://deno.land/std@0.79.0/hash/_wasm/hash.ts": "005f64c4d9343ecbc91e0da9ae5e800f146c20930ad829bbb872c5c06bd89c5f",
|
||||
"https://deno.land/std@0.79.0/hash/_wasm/wasm.js": "fa27095b91e6268682100997577f1d3478beab5b045777e27ff7b2b5d19c8fdc",
|
||||
"https://deno.land/std@0.79.0/hash/mod.ts": "e764a6a9ab2f5519a97f928e17cc13d984e3dd5c7f742ff9c1c8fb3114790f0c",
|
||||
"https://deno.land/std@0.80.0/fs/eol.ts": "e133163510b683fc26a8285c4fa81e259a398ca592ab49edc3fdc9b2cc71e99a",
|
||||
"https://deno.land/std@0.81.0/_util/assert.ts": "e1f76e77c5ccb5a8e0dbbbe6cce3a56d2556c8cb5a9a8802fc9565af72462149",
|
||||
"https://deno.land/std@0.81.0/_util/has_own_property.ts": "91a2ef2fae5d941643a6472b97cac7ed8060a96deb66f4fafb4a2750c8af18e5",
|
||||
"https://deno.land/std@0.81.0/_util/os.ts": "e2be3e25f96e4b5a233a08fd03aba80819bcaee66ac53c11c9b5aaa64799b475",
|
||||
"https://deno.land/std@0.81.0/async/deferred.ts": "ecdb71319e164ec4ace5a44e3ee991b52c21bfc19e498acdf8eccdc0b1184f70",
|
||||
"https://deno.land/std@0.81.0/async/delay.ts": "35957d585a6e3dd87706858fb1d6b551cb278271b03f52c5a2cb70e65e00c26a",
|
||||
"https://deno.land/std@0.81.0/async/mod.ts": "39f2602a005805dd1e6b9da4ee5391b14d15e8fec4fa5494a6165c599911d746",
|
||||
"https://deno.land/std@0.81.0/async/mux_async_iterator.ts": "2532c6f448fda34db7ab9504746db671c32425dd4ffa96eeb9df744c3038c106",
|
||||
"https://deno.land/std@0.81.0/async/pool.ts": "a499691231d8c249f044f69d204b479ad3af7f115e0b37342829eff076bc2450",
|
||||
"https://deno.land/std@0.81.0/bytes/mod.ts": "e4f91c6473fe13e3cf1a23649137f87f49135c10bc08fc0f83382a0fb0b03744",
|
||||
"https://deno.land/std@0.81.0/datetime/formatter.ts": "0db8ca0d476bd80151b3557eb8f1bb2b6d5ba0713c8fc98f3526c2ce8c01649e",
|
||||
"https://deno.land/std@0.81.0/datetime/mod.ts": "38ecaf7da9f81da63a18c7e6d4602ba70f563e99ab786c179393c7984fbf6006",
|
||||
"https://deno.land/std@0.81.0/datetime/tokenizer.ts": "ae21a459f2f017ac81b1b49caa81174b6b8ab8a4d8d82195dcf25bb67b565c71",
|
||||
"https://deno.land/std@0.81.0/encoding/utf8.ts": "1b7e77db9a12363c67872f8a208886ca1329f160c1ca9133b13d2ed399688b99",
|
||||
"https://deno.land/std@0.81.0/fmt/colors.ts": "c5665c66f1a67228f21c5989bbb04b36d369b98dd7ceac06f5e26856c81c2531",
|
||||
"https://deno.land/std@0.81.0/http/_io.ts": "8e1ed7effe99446535a98ac0cdcfd544265c78c46e4cef5a8c5f8e31037711d9",
|
||||
"https://deno.land/std@0.81.0/http/cookie.ts": "8b54d578e1b72df92b30ec65c0e0d89142fec8700bff18a8cfe3ce87e60edeb6",
|
||||
"https://deno.land/std@0.81.0/http/http_status.ts": "0ecc0799a208f49452023b1b927106ba5a2c13cc6cf6666345db028239d554ab",
|
||||
"https://deno.land/std@0.81.0/http/server.ts": "282bb3b13da077a760083b465843fc2b8bf8936c3e22c514f6ae695db0721866",
|
||||
"https://deno.land/std@0.81.0/io/bufio.ts": "3cbbe1f761c1c636d1e7128ed4e7fdca6bf21d9199aa3cae71e69972a6ae8f93",
|
||||
"https://deno.land/std@0.81.0/io/ioutil.ts": "b781afd113a7d29c88c3d88efec391a0446c3e6537b74f795dd8579339ae8a5f",
|
||||
"https://deno.land/std@0.81.0/io/readers.ts": "4c2e98abf2a2a1d5e2adaf460479a1c69f742951c1bc141b26654d2f5248b663",
|
||||
"https://deno.land/std@0.81.0/mime/multipart.ts": "fa3c5ea5374ecae99e02543506a6ef4dc43ed5f3e26f406e8f4fea20f184cca6",
|
||||
"https://deno.land/std@0.81.0/path/_constants.ts": "3a19d04e5d6de4620df22ab40c2e8c9d87002b56702d2b4669c14dfa2765e368",
|
||||
"https://deno.land/std@0.81.0/path/_interface.ts": "67b276380d297a7cedc3c17f7a0bf122edcfc96a3e1f69de06f379d85ba0e2c0",
|
||||
"https://deno.land/std@0.81.0/path/_util.ts": "7820a788b35c26dfc27ff329df12507fc0553ae92727009597046f6cf856b4fa",
|
||||
"https://deno.land/std@0.81.0/path/common.ts": "e4ec66a7416d56f60331b66e27a8a4f08c7b1cf48e350271cb69754a01cf5c04",
|
||||
"https://deno.land/std@0.81.0/path/glob.ts": "c36be777b82346a3fac02ef0ffef7d6c9bfe4da50f4599c798d7ded072f88d22",
|
||||
"https://deno.land/std@0.81.0/path/mod.ts": "ef6a91aed4bc417eb56f8d5947f117f35ed3ca76c24d19dc482d3d6514218d5f",
|
||||
"https://deno.land/std@0.81.0/path/posix.ts": "0f635537634111caa17a944b7405cf0a50ed6d6dd1a847c65323bebeccec5718",
|
||||
"https://deno.land/std@0.81.0/path/separator.ts": "696812939d47fbe095002e92d595e3a1cdf03157222029a39c68dce9995f38c4",
|
||||
"https://deno.land/std@0.81.0/path/win32.ts": "c5efe2a88d2351adddb53c22439ef32dc1081bc0d4205ae54a2ce388bcc600fb",
|
||||
"https://deno.land/std@0.81.0/textproto/mod.ts": "4c378eda3cb6216608bb4c3a34201761c65f6980c4669455ca224c330cd5b790",
|
||||
"https://deno.land/std@0.83.0/_util/assert.ts": "e1f76e77c5ccb5a8e0dbbbe6cce3a56d2556c8cb5a9a8802fc9565af72462149",
|
||||
"https://deno.land/std@0.83.0/_util/os.ts": "e2be3e25f96e4b5a233a08fd03aba80819bcaee66ac53c11c9b5aaa64799b475",
|
||||
"https://deno.land/std@0.83.0/encoding/base64.ts": "b1d8f99b778981548457ec74bc6273ad785ffd6f61b2233bd5b30925345b565d",
|
||||
"https://deno.land/std@0.83.0/encoding/hex.ts": "fa01b16414c8e04caa0055f2d8c4610a3ec714a04315d0afe6956e07d501e11d",
|
||||
"https://deno.land/std@0.83.0/fmt/colors.ts": "c5665c66f1a67228f21c5989bbb04b36d369b98dd7ceac06f5e26856c81c2531",
|
||||
"https://deno.land/std@0.83.0/fs/_util.ts": "9318f5253cb09177280bdce64b6af97012707cdb458c02864811c2bae1dd1dbd",
|
||||
"https://deno.land/std@0.83.0/fs/copy.ts": "94a9035388fb197e5d61db360bbf77497dbddd66bce56a42b7b6e0c39d5f7a2e",
|
||||
"https://deno.land/std@0.83.0/fs/empty_dir.ts": "4d706eb01e5d08d862c673200d1978526e485368559fc7fb0f297add68f9cc43",
|
||||
"https://deno.land/std@0.83.0/fs/ensure_dir.ts": "54cf0cfb16160857116d1bdff98214ad0189275fe2f089607fdc06c52ac79cc4",
|
||||
"https://deno.land/std@0.83.0/fs/ensure_file.ts": "b70eccaee6f41ae226d399ad9c8ebc29beb5dd86fe179d30ab7e681976352baf",
|
||||
"https://deno.land/std@0.83.0/fs/ensure_link.ts": "f647cea5c3b65f4a6618444546e9ca891d38f54f7fd4c718fb1fd575b4232213",
|
||||
"https://deno.land/std@0.83.0/fs/ensure_symlink.ts": "88e14896b2cf069ac6342cf929c1ca57a681eb90f48e5af658c05fbb100c6097",
|
||||
"https://deno.land/std@0.83.0/fs/eol.ts": "e133163510b683fc26a8285c4fa81e259a398ca592ab49edc3fdc9b2cc71e99a",
|
||||
"https://deno.land/std@0.83.0/fs/exists.ts": "5429dce6587bfcdde06a7a2a1fd5ad932c17d74ca082e67934fa646cff1d2e57",
|
||||
"https://deno.land/std@0.83.0/fs/expand_glob.ts": "1b43b860bd0834f2d79db4b88bb3ae97b4aed6c91e377bb843cc9d2f024bb117",
|
||||
"https://deno.land/std@0.83.0/fs/mod.ts": "54ba0d1dac6de21ac32e3b60b83930e7febb4a2148ed735013b8d911c889d172",
|
||||
"https://deno.land/std@0.83.0/fs/move.ts": "63803372793b85edfb8da586145fa5d33f4836caf4cea919f5b172b06bcab08a",
|
||||
"https://deno.land/std@0.83.0/fs/walk.ts": "8d37f2164a7397668842a7cb5d53b9e7bcd216462623b1b96abe519f76d7f8b9",
|
||||
"https://deno.land/std@0.83.0/hash/_wasm/hash.ts": "005f64c4d9343ecbc91e0da9ae5e800f146c20930ad829bbb872c5c06bd89c5f",
|
||||
"https://deno.land/std@0.83.0/hash/_wasm/wasm.js": "fa27095b91e6268682100997577f1d3478beab5b045777e27ff7b2b5d19c8fdc",
|
||||
"https://deno.land/std@0.83.0/hash/mod.ts": "e764a6a9ab2f5519a97f928e17cc13d984e3dd5c7f742ff9c1c8fb3114790f0c",
|
||||
"https://deno.land/std@0.83.0/path/_constants.ts": "3a19d04e5d6de4620df22ab40c2e8c9d87002b56702d2b4669c14dfa2765e368",
|
||||
"https://deno.land/std@0.83.0/path/_interface.ts": "67b276380d297a7cedc3c17f7a0bf122edcfc96a3e1f69de06f379d85ba0e2c0",
|
||||
"https://deno.land/std@0.83.0/path/_util.ts": "7820a788b35c26dfc27ff329df12507fc0553ae92727009597046f6cf856b4fa",
|
||||
"https://deno.land/std@0.83.0/path/common.ts": "e4ec66a7416d56f60331b66e27a8a4f08c7b1cf48e350271cb69754a01cf5c04",
|
||||
"https://deno.land/std@0.83.0/path/glob.ts": "c36be777b82346a3fac02ef0ffef7d6c9bfe4da50f4599c798d7ded072f88d22",
|
||||
"https://deno.land/std@0.83.0/path/mod.ts": "ef6a91aed4bc417eb56f8d5947f117f35ed3ca76c24d19dc482d3d6514218d5f",
|
||||
"https://deno.land/std@0.83.0/path/posix.ts": "0f635537634111caa17a944b7405cf0a50ed6d6dd1a847c65323bebeccec5718",
|
||||
"https://deno.land/std@0.83.0/path/separator.ts": "696812939d47fbe095002e92d595e3a1cdf03157222029a39c68dce9995f38c4",
|
||||
"https://deno.land/std@0.83.0/path/win32.ts": "c5efe2a88d2351adddb53c22439ef32dc1081bc0d4205ae54a2ce388bcc600fb",
|
||||
"https://deno.land/x/abc@v1.2.4/_header.ts": "111617a83e956c74f2bb2c3ccbb0cc39801b13365c11c050e74d0b74d31546ac",
|
||||
"https://deno.land/x/abc@v1.2.4/_http_method.ts": "407c04d24eaee5ce9a1b00a9f1ef0d5b0b0cacfec080a98ece15ed8471ee9ef8",
|
||||
"https://deno.land/x/abc@v1.2.4/_mime.ts": "32d91f49a4477ec4901830b12c22ce77c5ade18bc22f83ce6e3f803c47cbfdd3",
|
||||
"https://deno.land/x/abc@v1.2.4/app.ts": "88c0ff086e82cabf7a72276a263cc4d51de6db2e9d8f947dff3f8370a9488b7c",
|
||||
"https://deno.land/x/abc@v1.2.4/constants.ts": "1c04ea5873f9540a1c227c70ebbf97f3f3c2751a88b98f035f7eccf6b3ae4201",
|
||||
"https://deno.land/x/abc@v1.2.4/context.ts": "e919516d5b9b21bbb70cd59409174b98a72f05f8fbb1f41ed30ca7a75170b806",
|
||||
"https://deno.land/x/abc@v1.2.4/group.ts": "cadbb1476b06b828494bf1fc049c1184cd5fc8bf519c1eb9e59e5b4409c8eba6",
|
||||
"https://deno.land/x/abc@v1.2.4/http_exception.ts": "45cd2e85f3f63f011af35064459d5180257766ebc4af981aef6c3a7fc9955ca3",
|
||||
"https://deno.land/x/abc@v1.2.4/middleware/cors.ts": "c274cfb67d71a97e3648a299aad5a7eed428a20ee02914bb3428c044d66edd3c",
|
||||
"https://deno.land/x/abc@v1.2.4/middleware/logger.ts": "18aaf687a365050c8cffa133019bf2af13c4fdf755ea75ab6f8c194059f40a5c",
|
||||
"https://deno.land/x/abc@v1.2.4/middleware/skipper.ts": "a8f299c116b6f68e6c3f387cb871b2e7d6f4418ecee927f0fc0ca1794be53662",
|
||||
"https://deno.land/x/abc@v1.2.4/mod.ts": "861cbdf90446f40afc7ddcaacbcb69e432e0970e6c6ea830ea80fd988de3a2e8",
|
||||
"https://deno.land/x/abc@v1.2.4/router.ts": "45be01701031eda4c95f9a68c6248014a4e939c2e9e0679d920867fe327a7da0",
|
||||
"https://deno.land/x/abc@v1.2.4/types.ts": "2e8a6ebbacf3c814b3b1f40d9b38a8833d8e41b55b67a23e5bbedf4edb51212a",
|
||||
"https://deno.land/x/abc@v1.2.4/util.ts": "8eb6a894461a1875132b4d380cf6e52396a5fbcc7e1cde4aa7d523183cadf51b",
|
||||
"https://deno.land/x/abc@v1.2.4/vendor/https/deno.land/std/encoding/utf8.ts": "7e1736536d5c8c9c5a541eff0515ab1fbb068c7d3ee2064264c87adcb540c7b7",
|
||||
"https://deno.land/x/abc@v1.2.4/vendor/https/deno.land/std/fmt/colors.ts": "4ccb3297215fff946df10a6e8f844cf582534562f1c36d8a66addc3681be907f",
|
||||
"https://deno.land/x/abc@v1.2.4/vendor/https/deno.land/std/http/cookie.ts": "8a62a5a7a9f7231e4045f176e45ace7a54b39f90019771a6308c383591ca04d2",
|
||||
"https://deno.land/x/abc@v1.2.4/vendor/https/deno.land/std/http/http_status.ts": "f517061c2ff552bf04414a00b77b57aff6c1f8493fb9ecc06c966e082e7c0e45",
|
||||
"https://deno.land/x/abc@v1.2.4/vendor/https/deno.land/std/http/server.ts": "7c1511c064a883e2f34aaa19a6f4a7403364447c6f95f7cdb238f7aa50e9e49c",
|
||||
"https://deno.land/x/abc@v1.2.4/vendor/https/deno.land/std/mime/multipart.ts": "f5e978a047df388190a59d9ddb5905ae75048e129b14c9b8ca567f1322699672",
|
||||
"https://deno.land/x/abc@v1.2.4/vendor/https/deno.land/std/path/mod.ts": "a095ff43f5219bbe6ebee2e4038106b0cb6509499cee5d650e63749c802ffb6a",
|
||||
"https://deno.land/x/abc@v1.2.4/vendor/https/deno.land/x/router/mod.ts": "a12a329c0b5d04e409fc7ad9f202fd3f78ed494e0236c04eba98a02e69731707",
|
||||
"https://deno.land/x/aws_sign_v4@0.1.5/deps.ts": "83822a3274e4e2fa51d62f099fde58500a842c1ebd220d407cc2c9428296b7f3",
|
||||
"https://deno.land/x/aws_sign_v4@0.1.5/mod.ts": "133d10a9073f1550795bdea025a398a5b2e64bb0276af6c4e76d963fec0eac84",
|
||||
"https://deno.land/x/aws_sign_v4@0.1.5/src/date.ts": "96d156206dceadbede0e8cd709dd2b0f8c8aef858359dbe187b78c50bdc73353",
|
||||
"https://deno.land/x/aws_sign_v4@0.1.5/src/signing.ts": "20188270e96390320b776d6b00596a02140106fabb5cb61e0a3263252fd0c8ba",
|
||||
"https://deno.land/x/base64@v0.2.1/base.ts": "47dc8d68f07dc91524bdd6db36eccbe59cf4d935b5fc09f27357a3944bb3ff7b",
|
||||
"https://deno.land/x/base64@v0.2.1/base64url.ts": "18bbf879b31f1f32cca8adaa2b6885ae325c2cec6a66c5817b684ca12c46ad5e",
|
||||
"https://deno.land/x/html_entities@v1.0/lib/xml-entities.js": "cbbc40f7b6fd1f925508ff7d43a52d2383a57a64d0aaa3a7a1eca9d4155e4bde",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/component.ts": "6bd3dab67754e91308df863e11e2b7945bbe0bf575b4bc529e8a9e02087eb732",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/components/helmet.ts": "59e598dc79c7b18620de175c61eb26f4aeb6905a6654cd63359208a26471541e",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/components/img.ts": "82a9f830394a7d6cd9b789b48fe1e70bc64eb151c4b410a3da74347c06acdae0",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/components/index.ts": "8855ee8302a9a19f38202d4a7ff5b17e22942600da02356bdfbc80c99c5c55f5",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/components/link.ts": "0f0b1c57dc8c466203105062335e0d9ded89a34e75d08b1bbeece198d42021cb",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/components/router.ts": "186e77064a96c31cb66ff1935c93d91904347647fcb13b56b5875ea64905397d",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/components/suspense.ts": "0711b7cdcd42b0b085972eca796d3ba7c436a736e1d2ce17db7e0cd1d3b928f5",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/components/visible.ts": "f19487f7faff0bad38a5549f1efac1df351e83ee4a77ca5886412b439f4b6b53",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/context.ts": "a65018beedf3e1863b96f9d99cf2d471c231a6ae0c77877a77754a398105f9fc",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/core.ts": "9346346ba7ddc52057131953a333c3ffa12e2a93aaceb25dabbab4bf8f1a171c",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/customElementsMode.ts": "61b9688ae89bfcc6109b72eaab4d82a69a8482d89770f3e2c1359b79bf57bb91",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/fragment.ts": "9cfb0dcdcb02d5cc53f027b4b55609e4f9d6d9322b665292e572856f4b688569",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/helpers.ts": "d904aa646534f1c0cf7c05a6c8e02231f906d962acb725c964aedbcf50216d85",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/htm.ts": "d8d9cd4fb4ad4645bff3698c7eb96e7798022c5519d04e709ebde236edde156b",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/htm/build.ts": "9d6b6eb407c0db2d1213a3f9c82efc66a2bec34c89976132ff13e3e095dcaaaf",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/htm/constants.ts": "3f296f87f03bd0ba8d7673884a1f6c4c927a2774648eaa4fd3ca9e3c46c3f7b8",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/htm/index.ts": "29912b9f7a760884fce79caca82649b9772cfa3c3272e0426a4ce377b67d70d5",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/index.ts": "0f39c911a39c61cb39f9bd8a2481500126dcb1b2a826d5b4523dd47a08b6938d",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/jsx.ts": "7d5b4d4a249fba1a42f2016f54f71ca049d96ff490e098db4a19b2a9b197b952",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/lazy.ts": "f8b8a2b915daff1fb70704ffad5171c805f1e28778b5cd0f8c827780762776c4",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/mod.ts": "3dda2bc0dbee9abd01c03acf43ab55a7854952afe0450245fc2ad12eb9bd9598",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/regexDom.ts": "de82fd3110c5a367e3d4ba9b774cfef3baf995deff455edc7363551d79089c90",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/ssr.ts": "1ab6c17f41f612fe409d29d81ce1f17692ff02e5abea6ef4080cabecafc246dd",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/state.ts": "cfc6ca6eb5e65f4cd60717a0a96ce604053bacf6e0b8835afbe22327e9979a1b",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/store.ts": "bf075833a656fc87b2a24c486bb3f77e13f19d6d9efcc42e31ffb6f24ec8eb93",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/types.ts": "fb338d7fa4422a92c442d14e073a2deb01d42b017fcd36013a1f6554e17c5449",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/version.ts": "d7f3813a3b1c490f16e77047483b0dc52cc0cec6cb1b73d6926cf9ad96129a59",
|
||||
"https://deno.land/x/nano_jsx@v0.1.0/withStyles.ts": "8aae4c8e79319fe991d49dd8ccc927c221786dfe58de640dba9d9885ce0dd4b7",
|
||||
"https://deno.land/x/router@v2.0.0/mod.ts": "8792d3c390e0446d89eb94ee8030dd20de18f2aba649e263d2832f3f150ea2ce",
|
||||
"https://deno.land/x/s3@0.3.0/deps.ts": "590be3be45b218c91979d4d70db22cc25d16aa2f0ea6d4c414508f87bb3525e7",
|
||||
"https://deno.land/x/s3@0.3.0/mod.ts": "2f2bee45abe1c1197bba5d251ea49b3a342ed474c829119f315202011195f649",
|
||||
"https://deno.land/x/s3@0.3.0/src/bucket.ts": "85fd6d3a4f633ef70509d60397aa4dbf4cc7b6cfb155dedc70a22794a49984ff",
|
||||
"https://deno.land/x/s3@0.3.0/src/error.ts": "a7857ca64eedbaf5c4daad5e83fdef5c4acd61534bffdab784b4e17e008e6aae",
|
||||
"https://denopkg.com/chiefbiiko/hmac@v1.0.2/deps.ts": "fb061e6fa0fd96f455ef647c57e9e6309a86fb0bf484447fc6cb38e57262192f",
|
||||
"https://denopkg.com/chiefbiiko/hmac@v1.0.2/mod.ts": "83590b95de468d0cf5398b7631b4fb62a64226786247fe265482045d799e8f97",
|
||||
"https://denopkg.com/chiefbiiko/sha1@v1.0.3/deps.ts": "2e1af51a48c8507017fdb057b950366601b177fb7e73d5de54c1b3e0e115d72e",
|
||||
"https://denopkg.com/chiefbiiko/sha1@v1.0.3/mod.ts": "146a101c9776cc9c807053c93f23e4b321ade5251f65745df418f4a75d5fd27b",
|
||||
"https://denopkg.com/chiefbiiko/sha256@v1.0.2/deps.ts": "2e1af51a48c8507017fdb057b950366601b177fb7e73d5de54c1b3e0e115d72e",
|
||||
"https://denopkg.com/chiefbiiko/sha256@v1.0.2/mod.ts": "f109aa5eeb201a0cbfaf44950b70a429838b187e8a84c5b810c1ac84953427cc",
|
||||
"https://denopkg.com/chiefbiiko/sha512@v1.0.3/deps.ts": "2e1af51a48c8507017fdb057b950366601b177fb7e73d5de54c1b3e0e115d72e",
|
||||
"https://denopkg.com/chiefbiiko/sha512@v1.0.3/mod.ts": "33190babd4c0e748bb2568fd003444487c8798c8c3a618f6593098c12805fe15",
|
||||
"https://denopkg.com/chiefbiiko/std-encoding@v1.0.0/mod.ts": "4a927e5cd1d9b080d72881eb285b3b94edb6dadc1828aeb194117645f4481ac0",
|
||||
"https://git.hibas.dev/Deno/DenReg/raw/branch/master/tar/mod.ts": "472497c6ef7ed0f45e11c6ad9a3d7ff9caf3ea9da377e53b73a9466d089f1beb",
|
||||
"https://git.hibas.dev/Deno/DenReg/raw/branch/master/tar/src/deps.ts": "d8066e3bcd0a1885ce6b352f71845ec639e9392f7b84f517d1ff6d70e39498ec",
|
||||
"https://git.hibas.dev/Deno/DenReg/raw/branch/master/tar/src/mod.ts": "438a487ea4a8ef4f2767cd2399a569fd0ef59524b4863b68568775a2bca76416",
|
||||
"https://raw.githubusercontent.com/hibas123/dndb/master/deps.ts": "02b61f3ce1d74cf2f0c723b4e43240a6c6da39166391b1adec5b139c06e8e010",
|
||||
"https://raw.githubusercontent.com/hibas123/dndb/master/mod.ts": "3890f580d22e97bacf44050661b74a2c4a3dcbf75e4d8e0f56fd2cbce9305f2a",
|
||||
"https://raw.githubusercontent.com/hibas123/dndb/master/src/methods/find.js": "59b664c58cc986a2639b3a5ca0a158ddbc6cf812345f65c0b2bd3533c058dc41",
|
||||
"https://raw.githubusercontent.com/hibas123/dndb/master/src/methods/findOne.js": "3230785e45781324b421c47b7e9ef1f5bd058691d75d2eae9ab2242815159792",
|
||||
"https://raw.githubusercontent.com/hibas123/dndb/master/src/methods/insert.js": "8df8a869bf97c16eb5ee696157b59cf8d2b0238b427b08a92b6e4e63ce2ffadd",
|
||||
"https://raw.githubusercontent.com/hibas123/dndb/master/src/methods/mod.js": "fe009c4a55bad2ad84a0d3ad7ee0ab0d3166f91f2f706fe0550df92a90171b7e",
|
||||
"https://raw.githubusercontent.com/hibas123/dndb/master/src/methods/remove.js": "5f623dea009ec34831ba8362175a090b1055f28fe9576e9f929ce7df888a6467",
|
||||
"https://raw.githubusercontent.com/hibas123/dndb/master/src/methods/update.js": "9e8c9ec9cfebe3c46cfe68ef6fd98e452c24cb93c858f58e03d1d81b87c62da6",
|
||||
"https://raw.githubusercontent.com/hibas123/dndb/master/src/mod.ts": "476b9d0069b60443b3e9684fa086374bffbc45f02a083b7608c28dfd5733f702",
|
||||
"https://raw.githubusercontent.com/hibas123/dndb/master/src/storage.js": "fa06befe5609fda4dfc6fc2ddc0cfdc4765ddf0b9cccf106fc14435f83ef975c",
|
||||
"https://raw.githubusercontent.com/nekobato/deno-xml-parser/0bc4c2bd2f5fad36d274279978ca57eec57c680c/index.ts": "05d093028c005706e37b46bfe2bb7e2488f42fdc74d2196ac818902336927c01"
|
||||
}
|
||||
}
|
BIN
registry/favicon.png
Normal file
After Width: | Height: | Size: 44 KiB |
11
registry/favicon.svg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
registry/public/android-icon-192x192.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
registry/public/apple-icon-114x114.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
registry/public/apple-icon-120x120.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
registry/public/apple-icon-144x144.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
registry/public/apple-icon-152x152.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
registry/public/apple-icon-180x180.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
registry/public/apple-icon-57x57.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
registry/public/apple-icon-60x60.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
registry/public/apple-icon-72x72.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
registry/public/apple-icon-76x76.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
2
registry/public/browserconfig.xml
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig><msapplication><tile><square70x70logo src="/public/ms-icon-70x70.png"/><square150x150logo src="/public/ms-icon-150x150.png"/><square310x310logo src="/public/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
|
BIN
registry/public/favicon-16x16.png
Normal file
After Width: | Height: | Size: 930 B |
BIN
registry/public/favicon-256x256.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
registry/public/favicon-32x32.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
registry/public/favicon-96x96.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
registry/public/favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
1
registry/public/file.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline></svg>
|
After Width: | Height: | Size: 337 B |
1
registry/public/folder.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-folder"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path></svg>
|
After Width: | Height: | Size: 311 B |
41
registry/public/manifest.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "Deno package Registry",
|
||||
"short_name": "DenReg",
|
||||
"description": "A deno package registry, that can be self hosted easily",
|
||||
"start_url": "/",
|
||||
"scope": "/",
|
||||
"theme_color": "#ffffff",
|
||||
"display": "standalone",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/public/favicon-32x32.png",
|
||||
"sizes": "32x32",
|
||||
"type": "image/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "/public/apple-icon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "/public/favicon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "/public/apple-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "/public/android-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
}
|
BIN
registry/public/ms-icon-144x144.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
registry/public/ms-icon-150x150.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
registry/public/ms-icon-310x310.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
registry/public/ms-icon-70x70.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
2
registry/public/paper.min.css
vendored
Normal file
218
registry/public/prism.css
Normal file
@ -0,0 +1,218 @@
|
||||
/* PrismJS 1.22.0
|
||||
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apl+applescript+aql+arduino+arff+asciidoc+aspnet+asm6502+autohotkey+autoit+bash+basic+batch+bbcode+birb+bison+bnf+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cil+clojure+cmake+coffeescript+concurnas+csp+crystal+css-extras+cypher+d+dart+dax+dhall+diff+django+dns-zone-file+docker+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+firestore-security-rules+flow+fortran+ftl+gml+gcode+gdscript+gedcom+gherkin+git+glsl+go+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+http+hpkp+hsts+ichigojam+icon+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keyman+kotlin+latex+latte+less+lilypond+liquid+lisp+livescript+llvm+lolcode+lua+makefile+markdown+markup-templating+matlab+mel+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nginx+nim+nix+nsis+objectivec+ocaml+opencl+oz+parigp+parser+pascal+pascaligo+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plsql+powerquery+powershell+processing+prolog+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+q+qml+qore+r+racket+jsx+tsx+reason+regex+renpy+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+stan+iecst+stylus+swift+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+turtle+twig+typescript+typoscript+unrealscript+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+wiki+xeora+xml-doc+xojo+xquery+yaml+yang+zig&plugins=line-numbers+inline-color */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
font-size: 1em;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.token.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
/* This background color was intended by the author of this theme. */
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
pre[class*="language-"].line-numbers {
|
||||
position: relative;
|
||||
padding-left: 3.8em;
|
||||
counter-reset: linenumber;
|
||||
}
|
||||
|
||||
pre[class*="language-"].line-numbers > code {
|
||||
position: relative;
|
||||
white-space: inherit;
|
||||
}
|
||||
|
||||
.line-numbers .line-numbers-rows {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
top: 0;
|
||||
font-size: 100%;
|
||||
left: -3.8em;
|
||||
width: 3em; /* works for line-numbers below 1000 lines */
|
||||
letter-spacing: -1px;
|
||||
border-right: 1px solid #999;
|
||||
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
}
|
||||
|
||||
.line-numbers-rows > span {
|
||||
display: block;
|
||||
counter-increment: linenumber;
|
||||
}
|
||||
|
||||
.line-numbers-rows > span:before {
|
||||
content: counter(linenumber);
|
||||
color: #999;
|
||||
display: block;
|
||||
padding-right: 0.8em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
span.inline-color-wrapper {
|
||||
/*
|
||||
* The background image is the following SVG inline in base 64:
|
||||
*
|
||||
* <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2 2">
|
||||
* <path fill="gray" d="M0 0h2v2H0z"/>
|
||||
* <path fill="white" d="M0 0h1v1H0zM1 1h1v1H1z"/>
|
||||
* </svg>
|
||||
*
|
||||
* SVG-inlining explained:
|
||||
* https://stackoverflow.com/a/21626701/7595472
|
||||
*/
|
||||
background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyIDIiPjxwYXRoIGZpbGw9ImdyYXkiIGQ9Ik0wIDBoMnYySDB6Ii8+PHBhdGggZmlsbD0id2hpdGUiIGQ9Ik0wIDBoMXYxSDB6TTEgMWgxdjFIMXoiLz48L3N2Zz4=");
|
||||
/* This is to prevent visual glitches where one pixel from the repeating pattern could be seen. */
|
||||
background-position: center;
|
||||
background-size: 110%;
|
||||
|
||||
display: inline-block;
|
||||
height: 1.333ch;
|
||||
width: 1.333ch;
|
||||
margin: 0 .333ch;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid white;
|
||||
outline: 1px solid rgba(0,0,0,.5);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
span.inline-color {
|
||||
display: block;
|
||||
/* To prevent visual glitches again */
|
||||
height: 120%;
|
||||
width: 120%;
|
||||
}
|
||||
|
6
registry/scripts/getPaperCSS.ts
Normal file
@ -0,0 +1,6 @@
|
||||
await fetch("https://unpkg.com/papercss/dist/paper.min.css")
|
||||
.then((res) => res.arrayBuffer())
|
||||
.then((data) =>
|
||||
Deno.writeFile("./public/paper.min.css", new Uint8Array(data))
|
||||
)
|
||||
.catch(console.error);
|
@ -14,6 +14,8 @@ const config =
|
||||
) || {};
|
||||
|
||||
if (!config.user) config.user = {};
|
||||
if (!config.web) config.web = {};
|
||||
if (!config.general) config.general = {};
|
||||
|
||||
const env = Deno.env.toObject();
|
||||
|
||||
@ -40,11 +42,30 @@ for (const key in env) {
|
||||
case "S3_SECRET":
|
||||
config.s3 = { ...(config.s3 || {}), secretKey: env[key] };
|
||||
break;
|
||||
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;
|
||||
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));
|
||||
|
||||
export default config;
|
||||
|
@ -8,6 +8,7 @@ export interface IPackage {
|
||||
description: string;
|
||||
versions: string[];
|
||||
deprecated: boolean;
|
||||
readme: string;
|
||||
}
|
||||
|
||||
export interface IApiKey {
|
||||
|
@ -1,29 +1,26 @@
|
||||
// export { MongoClient, ObjectId } from "https://deno.land/x/mongo@v0.9.1/mod.ts";
|
||||
// @deno-types="./types/hotfix.d.ts"
|
||||
export * as Ini from "https://deno.hibas123.de/raw/ini@0.0.3/mod.ts";
|
||||
|
||||
export * as S3 from "https://deno.land/x/s3/mod.ts";
|
||||
export * as ABC from "https://deno.land/x/abc@v1.2.4/mod.ts";
|
||||
export * as CorsMW from "https://deno.land/x/abc@v1.2.4/middleware/cors.ts";
|
||||
export * as LoggerMW from "https://deno.land/x/abc@v1.2.4/middleware/logger.ts";
|
||||
|
||||
export * as Ini from "https://deno.land/x/ini/mod.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.208.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 Streams from "https://deno.land/std@0.208.0/streams/mod.ts";
|
||||
|
||||
export * as ABC from "https://deno.land/x/abc@v1/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.63.0/path/mod.ts";
|
||||
export * as FS from "https://deno.land/std@0.63.0/fs/mod.ts";
|
||||
export * as Base64 from "https://deno.land/std@0.63.0/encoding/base64.ts";
|
||||
export * as Hash from "https://deno.land/std@0.63.0/hash/mod.ts";
|
||||
export * as Compress from "https://git.hibas.dev/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 { Marked } from "https://deno.land/x/markdown/mod.ts";
|
||||
export { Marked } from "https://deno.hibas123.de/raw/markdown@0.1.0/mod.ts";
|
||||
|
||||
import DS from "https://raw.githubusercontent.com/hibas123/dndb/master/mod.ts";
|
||||
|
||||
/// <reference path="./types/jsx.d.ts" />
|
||||
export {
|
||||
React,
|
||||
jsx,
|
||||
Fragment,
|
||||
} from "https://raw.githubusercontent.com/apiel/jsx-html/master/mod.ts";
|
||||
export * as Nano from "https://deno.land/x/nano_jsx@v0.1.0/mod.ts";
|
||||
|
||||
export const Datastore = DS;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/// <reference path="./types/jsx.d.ts" />
|
||||
import { ABC, CorsMW, LoggerMW } from "./deps.ts";
|
||||
// /// <reference path="./types/jsx.d.ts" />
|
||||
import { ABC, CorsMW, LoggerMW, Path } from "./deps.ts";
|
||||
import config from "./config.ts";
|
||||
|
||||
const port = config?.api?.port || 8000;
|
||||
@ -8,16 +8,50 @@ const app = new ABC.Application();
|
||||
app.use(LoggerMW.logger({}));
|
||||
app.use(CorsMW.cors({}));
|
||||
|
||||
// app.static("/public", "./public");
|
||||
|
||||
const MIMEDB = {
|
||||
".css": "text/css",
|
||||
".json": "application/json",
|
||||
".js": "application/javascript",
|
||||
".gz": "applcation/gzip",
|
||||
".ico": "image/x-icon",
|
||||
".png": "image/png",
|
||||
".svg": "image/svg+xml",
|
||||
".xml": "application/xml",
|
||||
};
|
||||
|
||||
app.get("/public/*path", async (ctx) => {
|
||||
const filePath = Path.join("./public", ctx.params.path);
|
||||
|
||||
console.log(filePath);
|
||||
|
||||
ctx.blob(
|
||||
await Deno.open(filePath, { read: true }),
|
||||
(MIMEDB as any)[Path.extname(filePath)]
|
||||
);
|
||||
});
|
||||
|
||||
import api from "./http/api.ts";
|
||||
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);
|
||||
// tree.children?.forEach((node) => logNode(node, indent + 3));
|
||||
// });
|
||||
// }
|
||||
|
||||
console.log(app.router.trees.GET);
|
||||
// const trees = Object.values(app.router) as Node[];
|
||||
// trees.forEach(logNode);
|
||||
|
||||
import render from "./renderer.tsx";
|
||||
app.renderer = {
|
||||
|
@ -1,11 +1,16 @@
|
||||
import { ABC, Path, Compress, FS } from "../deps.ts";
|
||||
import { ABC, Path, Compress, FS, Colors } from "../deps.ts";
|
||||
|
||||
import bucket from "../s3.ts";
|
||||
import { isValidPackageName, basicauth, isValidFullVersion } from "../utils.ts";
|
||||
import {
|
||||
isValidPackageName,
|
||||
basicauth,
|
||||
isValidFullVersion,
|
||||
getAbsolutePackageVersion,
|
||||
getFilePath,
|
||||
} from "../utils.ts";
|
||||
|
||||
import db, { IPackage } from "../db.ts";
|
||||
import * as Storage from "../storage.ts";
|
||||
|
||||
import { v4 } from "https://deno.land/std/uuid/mod.ts";
|
||||
import db from "../db.ts";
|
||||
|
||||
export default function api(g: ABC.Group) {
|
||||
const cacheControl = (next: ABC.HandlerFunc) => (ctx: ABC.Context) => {
|
||||
@ -15,14 +20,65 @@ export default function api(g: ABC.Group) {
|
||||
|
||||
g.get(
|
||||
"/",
|
||||
(ctx) => {
|
||||
(_ctx) => {
|
||||
return { version: "1" };
|
||||
},
|
||||
cacheControl
|
||||
);
|
||||
|
||||
g.get("/module", async (_ctx) => {
|
||||
const res = await db.package.find({});
|
||||
return 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 {
|
||||
const version = getAbsolutePackageVersion(
|
||||
module,
|
||||
ctx.params.version
|
||||
) as string;
|
||||
|
||||
if (!version) {
|
||||
ctx.response.status = 404;
|
||||
return "// Not found";
|
||||
}
|
||||
|
||||
const bucketPath = await getFilePath(module.name, version, "/");
|
||||
|
||||
const filesItr = Storage.walkFiles(module.name + "/" + version + "/");
|
||||
|
||||
const allowedExts = new Set(
|
||||
(ctx.queryParams.ext || "js|ts").split("|").map((e) => "." + e)
|
||||
);
|
||||
|
||||
const files: string[] = [];
|
||||
for await (const file of filesItr) {
|
||||
const relPath = Path.posix.relative(bucketPath, file.path || "");
|
||||
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) {
|
||||
@ -42,7 +98,7 @@ export default function api(g: ABC.Group) {
|
||||
// }
|
||||
|
||||
async function uploadPackage(ctx: ABC.Context) {
|
||||
const reqId = v4.generate();
|
||||
const reqId = crypto.randomUUID();
|
||||
const filename = "./tmp/" + reqId + ".tar";
|
||||
const folder = "./tmp/" + reqId;
|
||||
|
||||
@ -61,6 +117,7 @@ async function uploadPackage(ctx: ABC.Context) {
|
||||
write: true,
|
||||
create: true,
|
||||
});
|
||||
// ctx.request.body.pipeTo(file); //TODO: Do this, once web framework is updated
|
||||
await Deno.copy(ctx.request.body, file);
|
||||
file.close();
|
||||
|
||||
@ -98,7 +155,6 @@ async function uploadPackage(ctx: ABC.Context) {
|
||||
success: false,
|
||||
message: "Invalid version. Version must be in format: 0.0.0",
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Checking for previous uploads");
|
||||
@ -113,6 +169,7 @@ async function uploadPackage(ctx: ABC.Context) {
|
||||
owner: ctx.customContext.user,
|
||||
description: meta.description,
|
||||
deprecated: false,
|
||||
readme: meta.readme,
|
||||
versions: [],
|
||||
};
|
||||
|
||||
@ -128,7 +185,7 @@ async function uploadPackage(ctx: ABC.Context) {
|
||||
};
|
||||
}
|
||||
|
||||
const bucketBase = "packages/" + packageName + "/" + packageVersion + "/";
|
||||
const storageBase = packageName + "/" + packageVersion + "/";
|
||||
|
||||
console.log("Uploading files to S3");
|
||||
|
||||
@ -138,16 +195,16 @@ async function uploadPackage(ctx: ABC.Context) {
|
||||
});
|
||||
|
||||
for await (const file of walker) {
|
||||
const relative = Path.relative(folder, file.path);
|
||||
const relative = Path.relative(folder, file.path).replace("\\", "/");
|
||||
|
||||
const bucketPath = (bucketBase + relative).replace(/@/g, "§");
|
||||
console.log("Normalised path:", relative.replace("\\", "/"));
|
||||
|
||||
console.log("Uploading file:", file.path, bucketPath, bucketBase);
|
||||
await bucket.putObject(
|
||||
bucketPath,
|
||||
await Deno.readAll(await Deno.open(file.path)),
|
||||
{}
|
||||
);
|
||||
const bucketPath = (storageBase + relative).replace(/@/g, "§");
|
||||
|
||||
const body = await Deno.readAll(await Deno.open(file.path));
|
||||
console.log("Put Object", bucketPath, body.byteLength);
|
||||
|
||||
await Storage.writeFile(bucketPath, body);
|
||||
}
|
||||
console.log("Setting new live version");
|
||||
|
||||
@ -168,7 +225,9 @@ async function uploadPackage(ctx: ABC.Context) {
|
||||
success: true,
|
||||
};
|
||||
} catch (err) {
|
||||
console.error("Error while processing newly uploaded package");
|
||||
console.error(
|
||||
Colors.red("Error while processing newly uploaded package")
|
||||
);
|
||||
console.error(err);
|
||||
return {
|
||||
success: false,
|
||||
|
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,5 +1,12 @@
|
||||
import { ABC } from "../deps.ts";
|
||||
import { extractPackagePath, getFile } from "../utils.ts";
|
||||
import { Path } from "../deps.ts";
|
||||
import type { ABC } from "../deps.ts";
|
||||
import {
|
||||
extractPackagePath,
|
||||
getAbsolutePackageVersion,
|
||||
getFile,
|
||||
getContentType,
|
||||
} from "../utils.ts";
|
||||
import db from "../db.ts";
|
||||
|
||||
const MAX_FIXED_CACHE_AGE = 60 * 60 * 24 * 365;
|
||||
const MAX_FLOATING_CACHE_AGE = 60 * 30;
|
||||
@ -11,16 +18,27 @@ export default function raw(g: ABC.Group) {
|
||||
ctx.params.package
|
||||
);
|
||||
|
||||
const pkg = await db.package.findOne({ name: packageName });
|
||||
packageVersion = getAbsolutePackageVersion(pkg, packageVersion);
|
||||
|
||||
const E404 = () => {
|
||||
ctx.response.status = 404;
|
||||
ctx.response.body = "// Not found!";
|
||||
};
|
||||
|
||||
const result = await getFile(
|
||||
packageName,
|
||||
packageVersion,
|
||||
ctx.params.path
|
||||
);
|
||||
const filepath = ctx.params.path;
|
||||
const result = await getFile(packageName, packageVersion, filepath);
|
||||
|
||||
if (filepath.endsWith(".js")) {
|
||||
const tsFile = filepath.slice(0, filepath.length - 3) + ".d.ts";
|
||||
const tsResult = await getFile(packageName, packageVersion, tsFile);
|
||||
if (tsResult) {
|
||||
ctx.response.headers.set(
|
||||
"X-TypeScript-Types",
|
||||
"./" + Path.posix.basename(tsFile)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (packageVersion && result) {
|
||||
ctx.response.headers.set(
|
||||
@ -37,6 +55,8 @@ export default function raw(g: ABC.Group) {
|
||||
if (!result) return E404();
|
||||
|
||||
ctx.response.headers.set("e-tag", result.etag);
|
||||
let contentType = getContentType(filepath);
|
||||
if (contentType) ctx.response.headers.set("Content-Type", contentType);
|
||||
return result.data;
|
||||
});
|
||||
}
|
||||
|
@ -1,8 +1,16 @@
|
||||
import { ABC } from "../deps.ts";
|
||||
import { basicauth, extractPackagePath, sortVersions } from "../utils.ts";
|
||||
import type { ABC } from "../deps.ts";
|
||||
import {
|
||||
extractPackagePath,
|
||||
getFilePath,
|
||||
getFile,
|
||||
getOneOf,
|
||||
getAbsolutePackageVersion,
|
||||
sortVersions,
|
||||
} from "../utils.ts";
|
||||
|
||||
import { Hash } from "../deps.ts";
|
||||
import { Hash, Path } from "../deps.ts";
|
||||
import db, { IPackage } from "../db.ts";
|
||||
import * as Storage from "../storage.ts";
|
||||
|
||||
const MAX_CACHE_AGE = 60 * 30; // 30 Minutes
|
||||
|
||||
@ -23,6 +31,7 @@ export default function views(g: ABC.Application) {
|
||||
packages = await db.package.find({});
|
||||
}
|
||||
|
||||
|
||||
await ctx.render("index", {
|
||||
packages: packages.reverse(),
|
||||
search,
|
||||
@ -44,21 +53,116 @@ export default function views(g: ABC.Application) {
|
||||
ctx.response.headers.set("cache-control", CACHE_CONTROL);
|
||||
ctx.response.headers.set("E-Tag", etag);
|
||||
});
|
||||
|
||||
g.get("/package/:package", async (ctx) => {
|
||||
let [packageName, packageVersion] = extractPackagePath(
|
||||
const [packageName, packageVersion] = extractPackagePath(
|
||||
ctx.params.package
|
||||
);
|
||||
|
||||
const pkg = await db.package.findOne({ name: packageName });
|
||||
|
||||
if (!pkg) {
|
||||
ctx.response.status = 404;
|
||||
ctx.response.body = "// Package not found!";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const readmeContentRaw = (await getOneOf(
|
||||
pkg.name,
|
||||
packageVersion || pkg.versions.sort(sortVersions).reverse()[0],
|
||||
[pkg.readme, "README.md", "readme.md", "Readme.md"]
|
||||
))?.data;
|
||||
|
||||
const readmeContent = readmeContentRaw
|
||||
? new TextDecoder().decode(readmeContentRaw)
|
||||
: "";
|
||||
|
||||
const etag =
|
||||
"W/" +
|
||||
Hash.createHash("sha3-256")
|
||||
.update(`${packageName}:${packageVersion}`)
|
||||
.toString("base64");
|
||||
|
||||
await ctx.render("package", { pkg, version: packageVersion });
|
||||
await ctx.render("package", { pkg, version: packageVersion, readmeContent });
|
||||
ctx.response.headers.set("cache-control", CACHE_CONTROL);
|
||||
ctx.response.headers.set("E-Tag", etag);
|
||||
});
|
||||
|
||||
async function handleBrowse(ctx: ABC.Context) {
|
||||
const E404 = () => {
|
||||
ctx.response.status = 404;
|
||||
ctx.response.body = "// Not found!";
|
||||
};
|
||||
|
||||
let [packageName, packageVersion] = extractPackagePath(
|
||||
ctx.params.package
|
||||
);
|
||||
|
||||
const pkg = await db.package.findOne({ name: packageName });
|
||||
packageVersion = getAbsolutePackageVersion(pkg, packageVersion);
|
||||
|
||||
if (!packageVersion) return E404();
|
||||
|
||||
const path = ctx.params.path || "";
|
||||
|
||||
const fileContent = await getFile(packageName, packageVersion, path);
|
||||
if (fileContent) {
|
||||
await ctx.render("browse_file", {
|
||||
pkg,
|
||||
version: packageVersion,
|
||||
content: new TextDecoder().decode(fileContent.data),
|
||||
ext: Path.extname(path),
|
||||
path: `${packageName}@${packageVersion}/${path}`,
|
||||
});
|
||||
} else {
|
||||
const filesPath = getFilePath(
|
||||
packageName,
|
||||
packageVersion,
|
||||
path
|
||||
);
|
||||
if (!filesPath) return E404();
|
||||
|
||||
console.log(filesPath);
|
||||
|
||||
const filesItr = Storage.walkFiles(filesPath);
|
||||
|
||||
const files: { name: string; size: number }[] = [];
|
||||
const directories: Set<string> = new Set();
|
||||
let readme: string | null = null;
|
||||
for await (const file of filesItr) {
|
||||
const relPath = Path.posix.relative(filesPath, file.path || "");
|
||||
console.log({ file, relPath, filesPath });
|
||||
if (relPath.indexOf("/") >= 0) {
|
||||
directories.add(relPath.split("/")[0]);
|
||||
} else {
|
||||
files.push({ name: relPath, size: -1 }); //TODO: Size is not implemented yet
|
||||
if (relPath.toLowerCase() === "readme.md") {
|
||||
const readmeCont = await getFile(
|
||||
packageName,
|
||||
packageVersion,
|
||||
Path.posix.join(path, relPath)
|
||||
);
|
||||
if (readmeCont) {
|
||||
readme = new TextDecoder().decode(readmeCont?.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await ctx.render("browse_folder", {
|
||||
pkg,
|
||||
version: packageVersion,
|
||||
readme,
|
||||
files,
|
||||
directories: Array.from(directories.values()).map((e) => ({
|
||||
name: e,
|
||||
})),
|
||||
path: `${packageName}@${packageVersion}/${path}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
g.get("/browse/:package", handleBrowse);
|
||||
g.get("/browse/:package/*path", handleBrowse);
|
||||
}
|
||||
|
0
registry/src/react.ts
Normal file
@ -1,8 +1,10 @@
|
||||
/// <reference path="./types/jsx.d.ts" />
|
||||
import { React, jsx } from "./deps.ts";
|
||||
import { Nano } from "./deps.ts";
|
||||
const { h, renderSSR } = Nano;
|
||||
|
||||
import config from "./config.ts";
|
||||
|
||||
|
||||
|
||||
class StringReader implements Deno.Reader {
|
||||
private data: Uint8Array;
|
||||
private offset = 0;
|
||||
@ -25,15 +27,50 @@ 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(
|
||||
name: string,
|
||||
data: any
|
||||
): Promise<Deno.Reader> {
|
||||
const component: {
|
||||
default: () => JSX.IntrinsicElements | Promise<JSX.IntrinsicElements>;
|
||||
} = await import(`./views/${name}.tsx`);
|
||||
const Component = await loadComponent(name);
|
||||
|
||||
const res = await (<component.default {...data} />).render();
|
||||
// // @ts-ignore
|
||||
// const res = await Pico.renderSSR(<Component {...data} />);
|
||||
const res = await renderSSR(<Component {...data} />);
|
||||
|
||||
return new StringReader(res as string);
|
||||
return new StringReader("<!DOCTYPE html>\n" + res);
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
import { S3 } from "./deps.ts";
|
||||
import config from "./config.ts";
|
||||
|
||||
if (!config.s3) {
|
||||
throw new Error("Config is missing [s3] section!");
|
||||
}
|
||||
|
||||
const bucket = new S3.S3Bucket({
|
||||
bucket: config.s3.bucket || "deno-registry",
|
||||
endpointURL: config.s3.endpoint,
|
||||
accessKeyID: config.s3.accessKey,
|
||||
secretKey: config.s3.secretKey,
|
||||
region: config?.s3?.region || "us-east-1",
|
||||
});
|
||||
|
||||
export default bucket;
|
40
registry/src/storage.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { FS, Path } from "./deps.ts";
|
||||
|
||||
const STORAGE_ROOT = Path.resolve("./data/files");
|
||||
|
||||
|
||||
|
||||
export function walkFiles(path: string) {
|
||||
const norm = Path.normalize(path);
|
||||
const p = Path.join(STORAGE_ROOT, norm);
|
||||
|
||||
const walker = FS.walk(p, { includeFiles: true, includeDirs: false })
|
||||
|
||||
// Make path of entry relative to the root and return an async iterator
|
||||
return (async function* () {
|
||||
for await (const entry of walker) {
|
||||
const rel = Path.relative(STORAGE_ROOT, entry.path);
|
||||
yield { ...entry, path: rel };
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
export async function writeFile(path: string, content: Uint8Array) {
|
||||
const norm = Path.normalize(path);
|
||||
const p = Path.join(STORAGE_ROOT, norm);
|
||||
|
||||
await FS.ensureFile(p);
|
||||
await Deno.writeFile(p, content);
|
||||
}
|
||||
|
||||
export async function readFile(path: string) {
|
||||
const norm = Path.normalize(path);
|
||||
const p = Path.join(STORAGE_ROOT, norm);
|
||||
|
||||
if (!await FS.exists(p)) return undefined;
|
||||
|
||||
const s = await Deno.stat(p);
|
||||
if (!s.isFile) return undefined;
|
||||
|
||||
return await Deno.readFile(p);
|
||||
}
|
3
registry/src/test.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import * as Prism from "./vendor/prism/prism.js";
|
||||
|
||||
console.log((window as any).Prism);
|
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
@ -1,5 +0,0 @@
|
||||
declare namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
[elemName: string]: any;
|
||||
}
|
||||
}
|
@ -1,15 +1,13 @@
|
||||
import { ABC, Base64 } from "./deps.ts";
|
||||
import { ABC, Base64, Path } from "./deps.ts";
|
||||
import config from "./config.ts";
|
||||
import * as Storage from "./storage.ts";
|
||||
|
||||
const packageNameRegex = /^[@]?[a-zA-Z][\d\w\-\_]*$/g.compile();
|
||||
const packageVersionRegex = /^\d(\.\d)?(\.\d)?$/g.compile();
|
||||
const packageFullVersionRegex = /^\d(\.\d)(\.\d)$/g.compile();
|
||||
|
||||
export const isValidPackageName = (name: string) => packageNameRegex.test(name);
|
||||
export const isValidPackageName = (name: string) => /^[@]?[a-zA-Z][\d\w\-\_]*$/g.test(name);
|
||||
export const isValidVersion = (version: string) =>
|
||||
packageVersionRegex.test(version);
|
||||
/^\d+(\.\d+)?(\.\d+)?$/g.test(version);
|
||||
export const isValidFullVersion = (version: string) =>
|
||||
packageFullVersionRegex.test(version);
|
||||
/^\d+(\.\d+)(\.\d+)$/g.test(version);
|
||||
|
||||
const ALg = 1;
|
||||
const ASm = -ALg;
|
||||
@ -70,16 +68,18 @@ export function extractPackagePath(path: string): [string, string | undefined] {
|
||||
path = path.slice(1);
|
||||
}
|
||||
|
||||
let parts = path.split("@");
|
||||
|
||||
const parts = path.split("@");
|
||||
if (parts.length > 2) throw new Error("Invalid package name!");
|
||||
|
||||
packageName += parts[0];
|
||||
let packageVersion: string | undefined = parts[1];
|
||||
const packageVersion: string | undefined = parts[1];
|
||||
console.log({ path, parts, packageName, packageVersion });
|
||||
|
||||
if (!isValidPackageName(packageName))
|
||||
throw new Error("Invalid package name!");
|
||||
|
||||
if (packageVersion !== "") {
|
||||
if (packageVersion && packageVersion !== "") {
|
||||
if (!isValidVersion(packageVersion))
|
||||
throw new Error("Invalid package version!");
|
||||
}
|
||||
@ -87,32 +87,37 @@ export function extractPackagePath(path: string): [string, string | undefined] {
|
||||
return [packageName, packageVersion];
|
||||
}
|
||||
|
||||
import db from "./db.ts";
|
||||
import type { IPackage } from "./db.ts";
|
||||
|
||||
import bucket from "./s3.ts";
|
||||
export function getAbsolutePackageVersion(
|
||||
pkg?: IPackage | null,
|
||||
version?: string
|
||||
) {
|
||||
if (!pkg || pkg.versions.length < 1) return undefined;
|
||||
|
||||
export async function getFile(
|
||||
pkgName: string,
|
||||
version: string | null | undefined,
|
||||
file: string
|
||||
): Promise<{ etag: string; data: Uint8Array } | null | undefined> {
|
||||
console.log("Searching for file: %s/%s@%s", pkgName, file, version);
|
||||
const meta = await db.package.findOne({ name: pkgName });
|
||||
const versions = pkg.versions.sort(sortVersions).reverse();
|
||||
|
||||
if (!meta || meta.versions.length < 1) return null;
|
||||
|
||||
const versions = meta.versions.sort(sortVersions).reverse();
|
||||
|
||||
if (!version) {
|
||||
if (!version || version === "latest") {
|
||||
version = versions[0];
|
||||
} else {
|
||||
const v = versions.filter((e) => e.startsWith(version as string));
|
||||
if (v.length < 1) return null;
|
||||
if (v.length < 1) return undefined;
|
||||
version = v[0];
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
export function getFilePath(
|
||||
pkgName: string,
|
||||
version: string,
|
||||
file: string
|
||||
) {
|
||||
if (file.startsWith("/")) {
|
||||
file = file.substr(1);
|
||||
}
|
||||
|
||||
const bucketPath = (
|
||||
"packages/" +
|
||||
pkgName +
|
||||
"/" +
|
||||
version +
|
||||
@ -120,14 +125,36 @@ export async function getFile(
|
||||
file
|
||||
).replace(/@/g, "§");
|
||||
|
||||
return bucketPath;
|
||||
}
|
||||
|
||||
export async function getOneOf(pkgName: string, version: string, files: (string | undefined)[]) {
|
||||
for (const file of files) {
|
||||
if (!file) continue;
|
||||
const res = await getFile(pkgName, version, file);
|
||||
if (res) return res;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export async function getFile(
|
||||
pkgName: string,
|
||||
version: string | undefined,
|
||||
file: string
|
||||
): Promise<{ etag: string; data: Uint8Array } | null | undefined> {
|
||||
if (!version) return undefined;
|
||||
const bucketPath = await getFilePath(pkgName, version, file);
|
||||
if (!bucketPath) return null;
|
||||
|
||||
console.log("Getting file from:", bucketPath);
|
||||
|
||||
try {
|
||||
const res = await bucket.getObject(bucketPath);
|
||||
const res = await Storage.readFile(bucketPath);
|
||||
if (!res) return undefined;
|
||||
|
||||
return {
|
||||
etag: res.etag,
|
||||
data: res.body,
|
||||
etag: Base64.encodeBase64(await crypto.subtle.digest("sha-1", res)),
|
||||
data: res,
|
||||
};
|
||||
} catch (err) {
|
||||
const msg = err.message as string;
|
||||
@ -135,3 +162,18 @@ export async function getFile(
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const exts = new Map<string, string>();
|
||||
|
||||
exts.set(".js", "text/javascript");
|
||||
exts.set(".mjs", "text/javascript");
|
||||
exts.set(".json", "application/json");
|
||||
exts.set(".jsonld", "application/ld+json");
|
||||
exts.set(".css", "text/css");
|
||||
exts.set(".html", "text/html");
|
||||
exts.set(".htm", "text/html");
|
||||
|
||||
export function getContentType(filename: string) {
|
||||
const ext = Path.extname(filename);
|
||||
return exts.get(ext);
|
||||
}
|
||||
|
7
registry/src/vendor/prism.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import "./prism/prism.js";
|
||||
|
||||
const Prism = (window as any).Prism;
|
||||
|
||||
delete (window as any).Prism;
|
||||
|
||||
export default Prism;
|
239
registry/src/vendor/prism/prism.js
vendored
Normal file
@ -1,24 +1,103 @@
|
||||
/// <reference path="../types/jsx.d.ts" />
|
||||
import { React } from "../deps.ts";
|
||||
import { Nano } from "../deps.ts";
|
||||
const { h } = Nano;
|
||||
|
||||
import config from "../config.ts";
|
||||
|
||||
const styles = new TextDecoder().decode(
|
||||
Deno.readFileSync("src/views/styles.css")
|
||||
);
|
||||
|
||||
export default function Base(p: any, children: any[]) {
|
||||
// href="https://unpkg.com/papercss@1.6.1/dist/paper.min.css"
|
||||
export default function Base(p: any) {
|
||||
const title = p.title || "DenReg";
|
||||
return (
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"></meta>
|
||||
<style dangerouslySetInnerHTML={{ __html: ".clean {all:revert;}" }} />
|
||||
{/* <link
|
||||
rel="stylesheet"
|
||||
href="https://deno.hibas123.de/raw/@hibas123-theme@2.0.2/out/base.css"
|
||||
/> */}
|
||||
<link rel="stylesheet" href="/public/paper.min.css" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://unpkg.com/papercss@1.6.1/dist/paper.min.css"
|
||||
rel="apple-touch-icon"
|
||||
sizes="57x57"
|
||||
href="/public/apple-icon-57x57.png"
|
||||
/>
|
||||
<style innerHTML={styles}></style>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="60x60"
|
||||
href="/public/apple-icon-60x60.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="72x72"
|
||||
href="/public/apple-icon-72x72.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="76x76"
|
||||
href="/public/apple-icon-76x76.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="114x114"
|
||||
href="/public/apple-icon-114x114.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="120x120"
|
||||
href="/public/apple-icon-120x120.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="144x144"
|
||||
href="/public/apple-icon-144x144.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="152x152"
|
||||
href="/public/apple-icon-152x152.png"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="/public/apple-icon-180x180.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="192x192"
|
||||
href="/public/android-icon-192x192.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="32x32"
|
||||
href="/public/favicon-32x32.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="96x96"
|
||||
href="/public/favicon-96x96.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="16x16"
|
||||
href="/public/favicon-16x16.png"
|
||||
/>
|
||||
<link rel="manifest" href="/public/manifest.json" />
|
||||
<meta name="msapplication-TileColor" content="#ffffff" />
|
||||
<meta
|
||||
name="msapplication-TileImage"
|
||||
content="/public/ms-icon-144x144.png"
|
||||
/>
|
||||
<meta name="theme-color" content="#ffffff"></meta>
|
||||
<link href="/public/prism.css" rel="stylesheet" />
|
||||
<style dangerouslySetInnerHTML={{ __html: styles }}></style>
|
||||
<title>{title}</title>
|
||||
<meta
|
||||
name="Description"
|
||||
@ -29,7 +108,12 @@ export default function Base(p: any, children: any[]) {
|
||||
content="width=device-width,initial-scale=1"
|
||||
/>
|
||||
</head>
|
||||
<body class="site">{children}</body>
|
||||
<body class="site">
|
||||
{config.web.tracking && (
|
||||
<tracking dangerouslySetInnerHTML={{ __html: config.web.tracking }}></tracking>
|
||||
)}
|
||||
{p.children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
114
registry/src/views/_browse.tsx
Normal file
@ -0,0 +1,114 @@
|
||||
import { Marked } from "../deps.ts";
|
||||
import { Nano } from "../deps.ts";
|
||||
const { h, Fragment } = Nano;
|
||||
import type { IPackage } from "../db.ts";
|
||||
import { sortVersions } from "../utils.ts";
|
||||
|
||||
import Prism from "../vendor/prism.ts";
|
||||
|
||||
interface IEntryParams {
|
||||
name: string;
|
||||
size?: number;
|
||||
directory?: true;
|
||||
}
|
||||
|
||||
export function Entry({ name, size, directory }: IEntryParams) {
|
||||
return (
|
||||
<a class="browse-list-item" href={"./" + name + (directory ? "/" : "")}>
|
||||
<img src={directory ? "/public/folder.svg" : "/public/file.svg"} />
|
||||
<span>{name}</span>
|
||||
{size && <span class="browse-list-item-size">{size}</span>}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
interface IEntryListParams {
|
||||
files: { name: string; size: number }[];
|
||||
directories: { name: string }[];
|
||||
}
|
||||
|
||||
export function EntryList({ directories, files }: IEntryListParams) {
|
||||
return (
|
||||
<div class="card" style="padding: 1rem;">
|
||||
<div>
|
||||
{directories.map((e) => (
|
||||
<Entry name={e.name} directory />
|
||||
))}
|
||||
{files.map((e) => (
|
||||
<Entry name={e.name} size={e.size} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface IRenderFileInterface {
|
||||
content: string;
|
||||
ext: string;
|
||||
}
|
||||
|
||||
const languages: { [key: string]: string } = {
|
||||
js: "javascript",
|
||||
cjs: "javascript",
|
||||
mjs: "javascript",
|
||||
ts: "typescript",
|
||||
c: "clike",
|
||||
svelte: "html",
|
||||
cs: "csharp",
|
||||
hb: "handlebars",
|
||||
ps: "powershell",
|
||||
sh: "bash",
|
||||
bat: "batch",
|
||||
yml: "yaml",
|
||||
};
|
||||
|
||||
export function RenderFile({ content, ext }: IRenderFileInterface) {
|
||||
if (ext === ".md") {
|
||||
content = Marked.parse(content).content;
|
||||
return (
|
||||
<div
|
||||
class="card browse-code-block"
|
||||
style="margin-top: 1rem; padding: 1rem;"
|
||||
dangerouslySetInnerHTML={{ __html: content }}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
let lang = languages[ext.replace(".", "")] || ext.replace(".", "");
|
||||
|
||||
if (Prism.languages[lang]) {
|
||||
content = Prism.highlight(content, Prism.languages[lang], lang);
|
||||
}
|
||||
|
||||
return <pre><code dangerouslySetInnerHTML={{ __html: content }}> </code></pre>;
|
||||
}
|
||||
}
|
||||
|
||||
interface IBrowseHeaderParams {
|
||||
pkg: IPackage;
|
||||
version?: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
export function BrowseHeader({ pkg, version, path }: IBrowseHeaderParams) {
|
||||
return (
|
||||
<>
|
||||
<div style="display: flex;">
|
||||
<div>
|
||||
<h2 style="margin-bottom: 0">Browse: {pkg.name}</h2>
|
||||
<h4 class="text-muted" style="margin-top: 0; margin-left: .5rem">
|
||||
By {pkg.owner}
|
||||
</h4>
|
||||
</div>
|
||||
<div>
|
||||
Version:
|
||||
<select>
|
||||
{pkg.versions.sort(sortVersions).map((v) => (
|
||||
<option selected={version === v}>{v}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="browse-path">{path}</div>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,15 +1,15 @@
|
||||
/// <reference path="../types/jsx.d.ts" />
|
||||
import { React, Fragment } from "../deps.ts";
|
||||
import { Nano } from "../deps.ts";
|
||||
const { h } = Nano;
|
||||
|
||||
export function Main(a: any, children: any) {
|
||||
export function Main(a: any) {
|
||||
return (
|
||||
<div style="grid-area: main">
|
||||
<div class="paper">{children}</div>
|
||||
<div class="paper">{a.children}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function Menu({}: any, children: any) {
|
||||
export function Menu(a: any) {
|
||||
return (
|
||||
<div style="grid-area: menu">
|
||||
<div class="paper">
|
||||
@ -23,7 +23,7 @@ export function Menu({}: any, children: any) {
|
||||
</a>
|
||||
</h3>
|
||||
|
||||
{children}
|
||||
{a.children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
22
registry/src/views/_pkgheader.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
// /// <reference path="../types/jsx.d.ts" />
|
||||
import { Nano } from "../deps.ts";
|
||||
const { h, Fragment } = Nano;
|
||||
|
||||
import type { IPackage } from "../db.ts";
|
||||
|
||||
export default function index({
|
||||
pkg,
|
||||
version,
|
||||
}: {
|
||||
pkg: IPackage;
|
||||
version?: string;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<h2 style="margin-bottom: 0">Package: {pkg.name}</h2>
|
||||
<h4 class="text-muted" style="margin-top: 0; margin-left: .5rem">
|
||||
By {pkg.owner}
|
||||
</h4>
|
||||
</>
|
||||
);
|
||||
}
|
38
registry/src/views/browse_file.tsx
Normal file
@ -0,0 +1,38 @@
|
||||
import { Nano } from "../deps.ts";
|
||||
const { h } = Nano;
|
||||
import Base from "./_base.tsx";
|
||||
import type { IPackage } from "../db.ts";
|
||||
|
||||
import { Main, Menu } from "./_default.tsx";
|
||||
import { RenderFile, EntryList, BrowseHeader } from "./_browse.tsx";
|
||||
|
||||
export default function index({
|
||||
pkg,
|
||||
version,
|
||||
content,
|
||||
ext,
|
||||
path,
|
||||
}: {
|
||||
pkg: IPackage;
|
||||
version?: string;
|
||||
content: string;
|
||||
ext: string;
|
||||
path: string;
|
||||
}) {
|
||||
if (!pkg)
|
||||
return (
|
||||
<Base>
|
||||
<h1>Not found</h1>
|
||||
</Base>
|
||||
);
|
||||
|
||||
return (
|
||||
<Base title={"DenReg - " + pkg.name}>
|
||||
<Main>
|
||||
<BrowseHeader pkg={pkg} version={version} path={path} />
|
||||
<RenderFile content={content} ext={ext} />
|
||||
</Main>
|
||||
<Menu></Menu>
|
||||
</Base>
|
||||
);
|
||||
}
|
43
registry/src/views/browse_folder.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import { Nano } from "../deps.ts";
|
||||
const { h } = Nano;
|
||||
import Base from "./_base.tsx";
|
||||
import type { IPackage } from "../db.ts";
|
||||
|
||||
import { Main, Menu } from "./_default.tsx";
|
||||
import { RenderFile, EntryList, BrowseHeader } from "./_browse.tsx";
|
||||
|
||||
export default function index({
|
||||
pkg,
|
||||
version,
|
||||
files,
|
||||
directories,
|
||||
readme,
|
||||
path,
|
||||
}: {
|
||||
pkg: IPackage;
|
||||
version?: string;
|
||||
files: { name: string; size: number }[];
|
||||
directories: { name: string }[];
|
||||
readme?: string;
|
||||
path: string;
|
||||
}) {
|
||||
if (!pkg)
|
||||
return (
|
||||
<Base>
|
||||
<h1>Not found</h1>
|
||||
</Base>
|
||||
);
|
||||
|
||||
return (
|
||||
<Base title={"DenReg - " + pkg.name}>
|
||||
<Main>
|
||||
<BrowseHeader pkg={pkg} version={version} path={path} />
|
||||
|
||||
<EntryList directories={directories} files={files} />
|
||||
|
||||
{readme && <RenderFile content={readme} ext={".md"} />}
|
||||
</Main>
|
||||
<Menu></Menu>
|
||||
</Base>
|
||||
);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/// <reference path="../types/jsx.d.ts" />
|
||||
import { React, Fragment } from "../deps.ts";
|
||||
import { Nano } from "../deps.ts";
|
||||
const { h } = Nano;
|
||||
import Base from "./_base.tsx";
|
||||
import DB, { IPackage } from "../db.ts";
|
||||
import type { IPackage } from "../db.ts";
|
||||
import { sortVersions } from "../utils.ts";
|
||||
|
||||
function Package({ pkg }: { pkg: IPackage }) {
|
||||
@ -10,9 +10,11 @@ function Package({ pkg }: { pkg: IPackage }) {
|
||||
const sorted = versions.sort(sortVersions).reverse();
|
||||
|
||||
return (
|
||||
<div
|
||||
class="card package-list-margin"
|
||||
onClick={"window.location.href = '/package/" + name + "'"}
|
||||
<a
|
||||
style="text-decoration:none; color: black"
|
||||
class="clean card package-list-margin"
|
||||
href={"/package/" + name}
|
||||
// onClick={"window.location.href = '/package/" + name + "'"}
|
||||
>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">
|
||||
@ -27,13 +29,13 @@ function Package({ pkg }: { pkg: IPackage }) {
|
||||
{description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
import { Main, Menu } from "./_default.tsx";
|
||||
|
||||
export default async function index({
|
||||
export default function index({
|
||||
packages,
|
||||
search,
|
||||
}: {
|
||||
|
@ -1,9 +1,9 @@
|
||||
/// <reference path="../types/jsx.d.ts" />
|
||||
import { React, Fragment, Marked } from "../deps.ts";
|
||||
import { Nano, Marked } from "../deps.ts";
|
||||
const { h, Suspense } = Nano;
|
||||
import Base from "./_base.tsx";
|
||||
import DB, { IPackage } from "../db.ts";
|
||||
import { sortVersions, getFile } from "../utils.ts";
|
||||
|
||||
import type { IPackage } from "../db.ts";
|
||||
import { sortVersions, getFile, getAbsolutePackageVersion } from "../utils.ts";
|
||||
import PkgHeader from "./_pkgheader.tsx";
|
||||
// function Package({ pkg }: { pkg: IPackage }) {
|
||||
// const { name, versions, author } = pkg;
|
||||
|
||||
@ -30,12 +30,14 @@ import { sortVersions, getFile } from "../utils.ts";
|
||||
|
||||
import { Main, Menu } from "./_default.tsx";
|
||||
|
||||
export default async function index({
|
||||
export default function index({
|
||||
pkg,
|
||||
version,
|
||||
readmeContent
|
||||
}: {
|
||||
pkg: IPackage;
|
||||
version?: string;
|
||||
readmeContent: string | undefined;
|
||||
}) {
|
||||
if (!pkg)
|
||||
return (
|
||||
@ -44,40 +46,23 @@ export default async function index({
|
||||
</Base>
|
||||
);
|
||||
|
||||
const readmeContent = await getFile(pkg.name, version, "README.md").then(
|
||||
(res) => {
|
||||
if (res)
|
||||
return Marked.parse(new TextDecoder().decode(res.data))
|
||||
.content as string;
|
||||
else return undefined;
|
||||
}
|
||||
);
|
||||
version = getAbsolutePackageVersion(pkg, version);
|
||||
|
||||
return (
|
||||
<Base title={"DenReg - " + pkg.name}>
|
||||
<Main>
|
||||
<h2 style="margin-bottom: 0">Package: {pkg.name}</h2>
|
||||
<h4 class="text-muted" style="margin-top: 0; margin-left: .5rem">
|
||||
By {pkg.owner}
|
||||
</h4>
|
||||
|
||||
<PkgHeader pkg={pkg} version={version} />
|
||||
<div class="tabs">
|
||||
<input id="tab1" type="radio" name="tabs" checked />
|
||||
<label for="tab1">Readme</label>
|
||||
|
||||
<input id="tab2" type="radio" name="tabs" />
|
||||
<label for="tab2">Versions</label>
|
||||
{/*
|
||||
<input id="tab3" type="radio" name="tabs" />
|
||||
<label for="tab3">Tab 3</label>
|
||||
|
||||
<input id="tab4" type="radio" name="tabs" />
|
||||
<label for="tab4">Tab 4</label> */}
|
||||
<div class="content" id="content1">
|
||||
{readmeContent !== undefined ? (
|
||||
<div
|
||||
style="overflow-x: hidden"
|
||||
innerHTML={readmeContent}
|
||||
dangerouslySetInnerHTML={{ __html: Marked.parse(readmeContent).content }}
|
||||
/>
|
||||
) : (
|
||||
<div class="alert alert-warning">No README.md found!</div>
|
||||
@ -95,7 +80,11 @@ export default async function index({
|
||||
</div>
|
||||
</div>
|
||||
</Main>
|
||||
<Menu></Menu>
|
||||
<Menu>
|
||||
<a href={`/browse/${pkg.name}${version ? "@" + version : ""}/`}>
|
||||
Browse Files
|
||||
</a>
|
||||
</Menu>
|
||||
</Base>
|
||||
);
|
||||
}
|
||||
}
|