Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: serve versioned matcha #32

Merged
merged 1 commit into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ To utilize **matcha.css**, just include the following line in the `<head>` secti
```

Assets are hosted on [Vercel](https://vercel.com) but _matcha.css_ is also available on
[![npm](https://img.shields.io/npm/v/@lowlighter%2Fmatcha?logo=npm&labelColor=cb0000&color=black)](https://www.npmjs.com/package/@lowlighter/matcha) and CDN services that distributes npm packages.
[![npm](https://img.shields.io/npm/v/@lowlighter%2Fmatcha?logo=npm&labelColor=cb0000&color=black)](https://www.npmjs.com/package/@lowlighter/matcha) and CDN services that distributes npm packages such
as [JSdelivr](https://www.jsdelivr.com/package/npm/@lowlighter/matcha).

All published versions are available in the [`/v/`](https://matcha.mizu.sh/v/) directory. By default, the `main` branch is served.

### 🍴 À la carte

Expand Down
71 changes: 70 additions & 1 deletion app/build/ssg.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Imports
import { copy, emptyDir, ensureDir, expandGlob } from "jsr:@std/fs@0.229.1"
import { dirname, fromFileUrl } from "jsr:@std/path@0.225.1"
import { basename, dirname, fromFileUrl } from "jsr:@std/path@0.225.1"
import { root } from "./root.ts"
import { html, html_builder, html_builder_demo } from "./html.ts"
import { compatibility } from "jsr:@libs/bundle@5/css"
import { DOMParser } from " https://deno.land/x/deno_dom@v0.1.45/deno-dom-wasm.ts"

/** Highlight.js CDN */
export const highlight = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"
Expand All @@ -24,9 +25,13 @@ export async function ssg() {
console.log("Created .pages/mod.css")
// Generate CSS
const dist = fromFileUrl(new URL("dist", root)).replaceAll("\\", "/")
await ensureDir(new URL(".pages/v/main", root))
console.log("Created .pages/v/main")
for await (const { path, name } of expandGlob("**/*.css", { root: dist })) {
await copy(path, new URL(`.pages/${name}`, root))
console.log(`Created .pages/${name}`)
await copy(path, new URL(`.pages/v/main/${name}`, root))
console.log(`Created .pages/v/main/${name}`)
}
// Generate compatibility table
const table = await compatibility(new URL(".pages/matcha.css", root), { output: "html", style: false, verbose: true })
Expand All @@ -53,10 +58,74 @@ export async function ssg() {
const alias = `${dirname(subpath)}.css`
await copy(path, new URL(`.pages/${alias}`, root))
console.log(`Created .pages/${alias}`)
await copy(path, new URL(`.pages/v/main/${alias}`, root))
console.log(`Created .pages/v/main/${alias}`)
}
}
await copy(new URL(".pages/styles", root), new URL(".pages/v/main/styles", root))
console.log("Created .pages/v/main/styles")
// Download highlight.js
await Deno.writeTextFile(new URL(".pages/highlight.js", root), await fetch(highlight).then((response) => response.text()))
console.log("Created .pages/highlight.js")
// Download previous versions
const { tags: { latest }, versions } = await fetch("https://data.jsdelivr.com/v1/package/npm/@lowlighter/matcha").then((response) => response.json())
for (const version of versions.reverse()) {
await ensureDir(new URL(`.pages/v/${version}`, root))
console.log(`Created .pages/v/${version}`)
const url = `https://cdn.jsdelivr.net/npm/@lowlighter/matcha@${version}`
const dist = Array.from(
new DOMParser().parseFromString(await fetch(`${url}/dist/`).then((response) => response.text()), "text/html")!.querySelectorAll(`.listing a[href^="/npm/@lowlighter/matcha@${version}"]`),
)
await Promise.all(dist.map(async (_file) => {
const file = _file as unknown as HTMLAnchorElement
const href = file.getAttribute("href")!
await Deno.writeTextFile(new URL(`.pages/v/${version}/${basename(href)}`, root), await fetch(new URL(href, url)).then((response) => response.text()))
console.log(`Created .pages/v/${version}/${basename(href)}`)
}))
const styles = Array.from(
new DOMParser().parseFromString(await fetch(`${url}/styles/`).then((response) => response.text()), "text/html")!.querySelectorAll(`.listing a[href^="/npm/@lowlighter/matcha@${version}"]`),
)
await Promise.all(styles.map(async (_directory) => {
const directory = _directory as unknown as HTMLAnchorElement
const href = directory.getAttribute("href")!
const files = Array.from(
new DOMParser().parseFromString(await fetch(new URL(href, url)).then((response) => response.text()), "text/html")!.querySelectorAll(`.listing a[href^="/npm/@lowlighter/matcha@${version}"]`),
)
await Promise.all(Array.from(files.map(async (_file) => {
const file = _file as unknown as HTMLAnchorElement
const href = file.getAttribute("href")!
if (!href.endsWith(".css")) {
return
}
const subpath = `styles/${basename(directory.getAttribute("href")!)}/${basename(href)}`
const content = await fetch(new URL(href, url)).then((response) => response.text())
await ensureDir(new URL(`.pages/v/${version}/${dirname(subpath)}`, root))
await Deno.writeTextFile(new URL(`.pages/v/${version}/${subpath}`, root), content)
console.log(`Created .pages/v/${version}/${subpath}`)
if (basename(href) === "mod.css") {
await Deno.writeTextFile(new URL(`.pages/v/${version}/${basename(dirname(subpath))}.css`, root), content)
console.log(`Created .pages/v/${version}/${basename(dirname(subpath))}.css`)
}
})))
}))
}
await copy(new URL(`.pages/v/${latest}`, root), new URL(".pages/v/latest", root))
console.log(`Created .pages/v/latest from version ${latest}`)
for (const major of new Set<string>(versions.map((version: string) => version.split(".")[0]))) {
if (major === "0") {
continue
}
const version = versions.reverse().filter((version: string) => version.startsWith(`${major}.`))[0]
await copy(new URL(`.pages/v/${version}`, root), new URL(`.pages/v/${major}`, root))
console.log(`Created .pages/v/${major} from version ${version}`)
}
for (const minor of new Set<string>(versions.map((version: string) => `${version.split(".")[0]}.${version.split(".")[1]}`))) {
if (minor.startsWith("0.")) {
continue
}
const version = versions.reverse().filter((version: string) => version.startsWith(`${minor}.`))[0]
await copy(new URL(`.pages/v/${version}`, root), new URL(`.pages/v/${minor}`, root))
console.log(`Created .pages/v/${minor} from version ${version}`)
}
console.log("Done!")
}
6 changes: 5 additions & 1 deletion app/mod.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ <h2 id="usage"><a href="#usage">Usage</a></h2>
<pre class="usage-snippet"><code data-hl="html">&lt;link rel="stylesheet" href="https://matcha.mizu.sh/matcha.css"&gt;</code></pre>
<p>
Assets are hosted on <a href="https://vercel.com">Vercel</a> but <em>matcha.css</em> is also available on <a href="https://www.npmjs.com/package/@lowlighter/matcha"><img alt="npm" src="https://img.shields.io/npm/v/@lowlighter%2Fmatcha?logo=npm&labelColor=cb0000&color=black"></a>
and <abbr data-title="Content Delivery Network">CDN</abbr> services that distributes npm packages.
and <abbr data-title="Content Delivery Network">CDN</abbr> services that distributes npm packages such as <a href="https://www.jsdelivr.com/package/npm/@lowlighter/matcha">JSdelivr</a>.
</p>
<p>
All published versions are available in the <a href="/v/" target="_blank"><code>/v/</code></a> directory.
By default, the <code>main</code> branch is served.
</p>
<section>
<h3 id="a-la-carte"><a href="#a-la-carte">À la carte</a></h3>
Expand Down
5 changes: 4 additions & 1 deletion app/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { css } from "./build/css.ts"
import { html, html_builder, html_builder_demo } from "./build/html.ts"
import { highlight, ssg } from "./build/ssg.ts"
import { dist } from "./build/dist.ts"
import { STATUS_CODE, STATUS_TEXT } from "jsr:@std/http@0.224.1"
import { serveDir, STATUS_CODE, STATUS_TEXT } from "jsr:@std/http@0.224.1"
import { root } from "./build/root.ts"
import api_minify from "../api/brew.ts"
import api_preview from "../api/preview.ts"
import { fromFileUrl } from "jsr:@std/path"

// Serve files
switch (Deno.args[0]) {
Expand Down Expand Up @@ -40,6 +41,8 @@ switch (Deno.args[0]) {
return api_preview(request)
case new URLPattern("/highlight.js", url.origin).test(url.href):
return fetch(highlight)
case new URLPattern("/v/*", url.origin).test(url.href):
return serveDir(request, { fsRoot: fromFileUrl(new URL(".pages/v", root)), urlRoot: "v", showDirListing: true, quiet: true })
default:
return new Response(STATUS_TEXT[STATUS_CODE.NotFound], { status: STATUS_CODE.NotFound })
}
Expand Down