@valancex/cli 0.0.0-stage → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +334 -2
- package/bin/vlx.js +4 -0
- package/dist/add.d.ts +20 -0
- package/dist/add.js +143 -0
- package/dist/args.d.ts +20 -0
- package/dist/args.js +78 -0
- package/dist/author.d.ts +4 -0
- package/dist/author.js +30 -0
- package/dist/build.d.ts +14 -0
- package/dist/build.js +75 -0
- package/dist/check.d.ts +8 -0
- package/dist/check.js +37 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +280 -0
- package/dist/compile.d.ts +52 -0
- package/dist/compile.js +217 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.js +142 -0
- package/dist/content.d.ts +12 -0
- package/dist/content.js +194 -0
- package/dist/contract.d.ts +31 -0
- package/dist/contract.js +45 -0
- package/dist/delegate.d.ts +2 -0
- package/dist/delegate.js +23 -0
- package/dist/dev.d.ts +21 -0
- package/dist/dev.js +257 -0
- package/dist/diagnostics.d.ts +16 -0
- package/dist/diagnostics.js +16 -0
- package/dist/emit.d.ts +13 -0
- package/dist/emit.js +107 -0
- package/dist/init.d.ts +69 -0
- package/dist/init.js +185 -0
- package/dist/markdown.d.ts +20 -0
- package/dist/markdown.js +186 -0
- package/dist/node.d.ts +10 -0
- package/dist/node.js +6 -0
- package/dist/outline.d.ts +17 -0
- package/dist/outline.js +88 -0
- package/dist/project.d.ts +8 -0
- package/dist/project.js +20 -0
- package/dist/security.d.ts +4 -0
- package/dist/security.js +35 -0
- package/dist/targets.d.ts +12 -0
- package/dist/targets.js +7 -0
- package/dist/tree.d.ts +47 -0
- package/dist/tree.js +149 -0
- package/dist/tty.d.ts +13 -0
- package/dist/tty.js +4 -0
- package/dist/ui/Spinner.d.ts +3 -0
- package/dist/ui/Spinner.js +16 -0
- package/dist/ui/init.d.ts +22 -0
- package/dist/ui/init.js +137 -0
- package/dist/ui/prompts.d.ts +39 -0
- package/dist/ui/prompts.js +98 -0
- package/dist/ui/report.d.ts +31 -0
- package/dist/ui/report.js +30 -0
- package/dist/ui/run.d.ts +15 -0
- package/dist/ui/run.js +75 -0
- package/dist/vite.d.ts +7 -0
- package/dist/vite.js +49 -0
- package/dist/wiring.d.ts +108 -0
- package/dist/wiring.js +330 -0
- package/package.json +70 -3
- package/schemas/valance.schema.json +32 -0
- package/schemas/valance.web.schema.json +56 -0
- package/templates/web/README.md +14 -0
- package/templates/web/content/404.md +7 -0
- package/templates/web/content/guide/getting-started.md +33 -0
- package/templates/web/content/guide/writing-pages.md +21 -0
- package/templates/web/content/index.md +16 -0
- package/templates/web/gitignore +4 -0
- package/templates/web/public/logo.svg +1 -0
- package/templates/web/src/layout.mprx +27 -0
- package/templates/web/src/main.ts +20 -0
- package/templates/web/src/styles.css +28 -0
- package/templates/web/src/theme-toggle.mprx +1 -0
- package/templates/web/src/theme-toggle.ts +10 -0
- package/templates/web/tsconfig.json +18 -0
- package/views/block.mprx +3 -0
- package/views/blocks.mprx +3 -0
- package/views/heading.mprx +3 -0
- package/views/inline.mprx +3 -0
- package/views/layout.mprx +26 -0
- package/views/list-block.mprx +5 -0
- package/views/list-items.mprx +3 -0
- package/views/runs.mprx +3 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://valancex.dev/schemas/valance.schema.json",
|
|
4
|
+
"title": "valance.json",
|
|
5
|
+
"description": "The project: what the application is called. Settings for a target are in valance.<target>.json (valance.web.json for the web).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"name"
|
|
10
|
+
],
|
|
11
|
+
"properties": {
|
|
12
|
+
"$schema": {
|
|
13
|
+
"type": "string"
|
|
14
|
+
},
|
|
15
|
+
"version": {
|
|
16
|
+
"const": 1,
|
|
17
|
+
"description": "The version of this file's format."
|
|
18
|
+
},
|
|
19
|
+
"name": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"minLength": 1,
|
|
22
|
+
"description": "The application's name: the site's title in navigation and in every page's <title>."
|
|
23
|
+
},
|
|
24
|
+
"title": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"default": "{page} \u00b7 {site}",
|
|
27
|
+
"pattern": "^[^{}]*(\\{page\\}|\\{site\\})[^{}]*(\\{page\\}|\\{site\\}|[^{}])*$",
|
|
28
|
+
"maxLength": 120,
|
|
29
|
+
"description": "How a document's title is written: \"{page}\" is the page's title and \"{site}\" the name above. Must contain \"{page}\". A page whose title is the site's name is that name alone."
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://valancex.dev/schemas/valance.web.schema.json",
|
|
4
|
+
"title": "valance.web.json",
|
|
5
|
+
"description": "Settings for the web target: where the built site is served.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": {
|
|
10
|
+
"type": "string"
|
|
11
|
+
},
|
|
12
|
+
"version": {
|
|
13
|
+
"const": 1,
|
|
14
|
+
"description": "The version of this file's format."
|
|
15
|
+
},
|
|
16
|
+
"base": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"pattern": "^/([\\w.~-]+/)*$",
|
|
19
|
+
"default": "/",
|
|
20
|
+
"description": "The path the site is served under: \"/\" or \"/docs/\". Every address the build writes is under it."
|
|
21
|
+
},
|
|
22
|
+
"url": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"pattern": "^https?://.*[^/]$",
|
|
25
|
+
"description": "Where the site is published, without a trailing slash. With it, pages get canonical links and the build writes sitemap.xml."
|
|
26
|
+
},
|
|
27
|
+
"headers": {
|
|
28
|
+
"type": "boolean",
|
|
29
|
+
"default": true,
|
|
30
|
+
"description": "Write the recommended security headers (a strict Content-Security-Policy and others) as _headers beside the built site."
|
|
31
|
+
},
|
|
32
|
+
"announce": {
|
|
33
|
+
"type": "boolean",
|
|
34
|
+
"default": true,
|
|
35
|
+
"description": "After the application changes page in place, tell assistive technology: say the new title in a live region and focus the main content."
|
|
36
|
+
},
|
|
37
|
+
"api": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"additionalProperties": false,
|
|
40
|
+
"required": [
|
|
41
|
+
"base"
|
|
42
|
+
],
|
|
43
|
+
"description": "The application's backend.",
|
|
44
|
+
"properties": {
|
|
45
|
+
"base": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"description": "Where its requests go: a path on the site's own origin (\"/api\") or an absolute https address (\"https://api.example.com\", which the Content-Security-Policy then allows)."
|
|
48
|
+
},
|
|
49
|
+
"proxy": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"description": "For vlx dev: forward requests under a path \"base\" to this address (\"http://localhost:3000\"), so the browser sees one origin and no CORS settings are needed."
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# {{name}}
|
|
2
|
+
|
|
3
|
+
A VALANCE application for the web, made with `vlx init`.
|
|
4
|
+
|
|
5
|
+
```console
|
|
6
|
+
$ {{run}} dev # serve it, and rebuild as you edit
|
|
7
|
+
$ {{run}} build # write the site to dist/
|
|
8
|
+
$ {{run}} check # find mistakes in your files without building
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
- `content/` is Markdown: a page's path is its address.
|
|
12
|
+
- `src/layout.mprx` is the page around it; `src/main.ts` declares the components it uses (start reading there).
|
|
13
|
+
- `src/styles.css` is the look. `public/` is served as it is.
|
|
14
|
+
- `valance.json` names the application{{web_note}}.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Getting started
|
|
3
|
+
description: Create the project, run it, change a page.
|
|
4
|
+
order: 1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Getting started
|
|
8
|
+
|
|
9
|
+
## Run it
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
pnpm install
|
|
13
|
+
pnpm dev
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Open the address `vlx dev` prints. Edit this file and save: the page reloads with your change.
|
|
17
|
+
|
|
18
|
+
## Build it
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
pnpm build
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The finished site is in `dist/`. Anything that serves files can host it.
|
|
25
|
+
|
|
26
|
+
## Where things are
|
|
27
|
+
|
|
28
|
+
1. `content/` holds the pages.
|
|
29
|
+
2. `src/layout.mprx` is the shell around every page.
|
|
30
|
+
3. `src/styles.css` is the look.
|
|
31
|
+
4. `public/` holds files that are served as they are, like the logo.
|
|
32
|
+
|
|
33
|
+
Next: [writing pages](./writing-pages.md).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Writing pages
|
|
3
|
+
description: Front matter, headings, links and images.
|
|
4
|
+
order: 2
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Writing pages
|
|
8
|
+
|
|
9
|
+
A page starts with an optional block of settings, then Markdown.
|
|
10
|
+
|
|
11
|
+
## Front matter
|
|
12
|
+
|
|
13
|
+
`title`, `description` and `order` are the three settings. Without a `title`, the first `#` heading is used.
|
|
14
|
+
|
|
15
|
+
> Anything else in the front matter is an error, so a typo never goes unnoticed.
|
|
16
|
+
|
|
17
|
+
## Links and images
|
|
18
|
+
|
|
19
|
+
Link to another page by its address, like [Getting started](/guide/getting-started), or by its file, like [the first page](./getting-started.md). A link that leads nowhere fails the build and names the line.
|
|
20
|
+
|
|
21
|
+
Images live in `public/` and are named from the site's root: ``.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: {{name}}
|
|
3
|
+
description: A small documentation site, written the way a VALANCE application is written.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# {{name}}
|
|
7
|
+
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
This site is a **VALANCE application**. Everything you are reading is a Markdown file in `content/`; the page around it is `src/layout.mprx`; the look is `src/styles.css`.
|
|
11
|
+
|
|
12
|
+
- Pages are Markdown files. Their path is their address.
|
|
13
|
+
- The layout and the components are templates.
|
|
14
|
+
- `vlx dev` serves the site and updates it as you edit.
|
|
15
|
+
|
|
16
|
+
Start with [Getting started](/guide/getting-started), or see [how a page is written](/guide/writing-pages#front-matter).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="{{name}}"><rect width="64" height="64" rx="14" fill="#5b3fd6"/><path d="M18 20h28M18 32h28M18 44h18" stroke="#fff" stroke-width="5" stroke-linecap="round"/></svg>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<shell class="layout" theme={theme}>
|
|
2
|
+
<header class="bar">
|
|
3
|
+
<link class="brand" href={home} current="false">{site}</link>
|
|
4
|
+
<theme-toggle theme={theme} on.toggle={toggleTheme()} />
|
|
5
|
+
</header>
|
|
6
|
+
<div class="frame">
|
|
7
|
+
<nav class="sidebar" label="Pages">
|
|
8
|
+
{#each sections as s (s.id)}
|
|
9
|
+
<section>
|
|
10
|
+
{#if s.title != ""}<para class="nav-title">{s.title}</para>{/if}
|
|
11
|
+
<list class="nav-list">
|
|
12
|
+
{#each s.items as n (n.id)}
|
|
13
|
+
<item><link class="nav-link" href={n.href} current={n.current}>{n.label}</link></item>
|
|
14
|
+
{/each}
|
|
15
|
+
</list>
|
|
16
|
+
</section>
|
|
17
|
+
{/each}
|
|
18
|
+
</nav>
|
|
19
|
+
<main id="content" tabindex="-1">
|
|
20
|
+
<blocks items={blocks} />
|
|
21
|
+
<nav class="pager" label="Previous and next page">
|
|
22
|
+
{#if prev.href != ""}<link class="pager-link" href={prev.href} current="false">{prev.label}</link>{/if}
|
|
23
|
+
{#if next.href != ""}<link class="pager-link" href={next.href} current="false">{next.label}</link>{/if}
|
|
24
|
+
</nav>
|
|
25
|
+
</main>
|
|
26
|
+
</div>
|
|
27
|
+
</shell>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { component, defineApp, field } from "@valancex/common";
|
|
2
|
+
import { Schema } from "effect";
|
|
3
|
+
import layout from "./layout.mprx";
|
|
4
|
+
import themeToggle from "./theme-toggle.js";
|
|
5
|
+
|
|
6
|
+
// The application, from the top. `layout` is the page's shell; `components` lists the components your templates use, once each: a template uses one by writing its tag. Nothing under src/ is part of
|
|
7
|
+
// the application unless it is imported here and listed. A component states its own interface where it is defined (see theme-toggle.ts).
|
|
8
|
+
export default defineApp({
|
|
9
|
+
layout: component(layout),
|
|
10
|
+
components: [themeToggle],
|
|
11
|
+
|
|
12
|
+
// The application's own state, beyond "which page is shown": each field is its type and its default, together. A field is a name the layout can read (`theme`), and the commands below are
|
|
13
|
+
// names it can run (`toggleTheme()`).
|
|
14
|
+
state: {
|
|
15
|
+
theme: field(Schema.Literal("light", "dark"), "light"),
|
|
16
|
+
},
|
|
17
|
+
commands: (command) => ({
|
|
18
|
+
toggleTheme: command((state) => ({ ...state, theme: state.theme === "light" ? "dark" : "light" })),
|
|
19
|
+
}),
|
|
20
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
:root { --bg: #fff; --fg: #1d2330; --muted: #5c6578; --line: #e3e6ee; --accent: #5b3fd6; --code: #f4f5f9; }
|
|
2
|
+
[data-theme="dark"] { --bg: #12141b; --fg: #e8eaf1; --muted: #9aa3b8; --line: #272b38; --accent: #a78bfa; --code: #1b1e29; }
|
|
3
|
+
|
|
4
|
+
* { box-sizing: border-box; }
|
|
5
|
+
body { margin: 0; font: 16px/1.6 system-ui, sans-serif; background: var(--bg); color: var(--fg); }
|
|
6
|
+
.layout { min-height: 100vh; background: var(--bg); color: var(--fg); }
|
|
7
|
+
|
|
8
|
+
.bar { display: flex; align-items: center; justify-content: space-between; padding: 0.75rem 1.5rem; border-bottom: 1px solid var(--line); }
|
|
9
|
+
.brand { font-weight: 700; color: var(--fg); text-decoration: none; }
|
|
10
|
+
.theme-toggle { font: inherit; padding: 0.25rem 0.75rem; border: 1px solid var(--line); border-radius: 999px; background: transparent; color: var(--fg); cursor: pointer; }
|
|
11
|
+
|
|
12
|
+
.frame { display: grid; grid-template-columns: 14rem 1fr; gap: 2rem; max-width: 60rem; margin: 0 auto; padding: 1.5rem; }
|
|
13
|
+
.sidebar { font-size: 0.95rem; }
|
|
14
|
+
.nav-title { margin: 1rem 0 0.25rem; font-weight: 600; color: var(--muted); text-transform: uppercase; font-size: 0.75rem; letter-spacing: 0.05em; }
|
|
15
|
+
.nav-list { list-style: none; margin: 0; padding: 0; }
|
|
16
|
+
.nav-link { display: block; padding: 0.15rem 0; color: var(--fg); text-decoration: none; }
|
|
17
|
+
.nav-link[aria-current="page"] { color: var(--accent); font-weight: 600; }
|
|
18
|
+
|
|
19
|
+
main { min-width: 0; }
|
|
20
|
+
main h1 { margin-top: 0; }
|
|
21
|
+
a { color: var(--accent); }
|
|
22
|
+
.code { padding: 1rem; overflow-x: auto; background: var(--code); border-radius: 0.5rem; }
|
|
23
|
+
code { font-family: ui-monospace, monospace; font-size: 0.9em; }
|
|
24
|
+
.quote { margin: 1rem 0; padding-left: 1rem; border-left: 3px solid var(--accent); color: var(--muted); }
|
|
25
|
+
.picture { max-width: 100%; }
|
|
26
|
+
.pager { display: flex; justify-content: space-between; margin-top: 3rem; padding-top: 1rem; border-top: 1px solid var(--line); }
|
|
27
|
+
|
|
28
|
+
@media (max-width: 40rem) { .frame { grid-template-columns: 1fr; } }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<button class="theme-toggle" pressed={theme == "dark" ? "true" : "false"} on.click={toggle()}>{theme == "dark" ? "Light" : "Dark"}</button>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { component } from "@valancex/common";
|
|
2
|
+
import { Schema } from "effect";
|
|
3
|
+
import template from "./theme-toggle.mprx";
|
|
4
|
+
|
|
5
|
+
// The interface of `<theme-toggle>`, stated once, where it is defined: what the template reads (`theme`) and what it raises (`toggle`, which carries nothing). Whoever uses it names only that
|
|
6
|
+
// they use it. `.valance/templates.d.ts` gives the template its keys as a type, so a contract that disagrees with the template is an error in the editor.
|
|
7
|
+
export default component(template, {
|
|
8
|
+
props: { theme: Schema.Literal("light", "dark") },
|
|
9
|
+
events: { toggle: Schema.Void },
|
|
10
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"types": ["node"],
|
|
4
|
+
"target": "ES2022",
|
|
5
|
+
"module": "NodeNext",
|
|
6
|
+
"moduleResolution": "NodeNext",
|
|
7
|
+
"lib": ["ES2022", "DOM"],
|
|
8
|
+
"strict": true,
|
|
9
|
+
"noUncheckedIndexedAccess": true,
|
|
10
|
+
"exactOptionalPropertyTypes": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"allowArbitraryExtensions": true,
|
|
15
|
+
"rootDirs": ["src", ".valance/types"]
|
|
16
|
+
},
|
|
17
|
+
"include": ["src"]
|
|
18
|
+
}
|
package/views/block.mprx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<mesh-fragment>
|
|
2
|
+
{#if b.kind == "heading"}<heading level={b.level} anchor={b.anchor} spans={b.spans} />{:else if b.kind == "list"}<list-block ordered={b.ordered} items={b.items} />{:else if b.kind == "code"}<pre class="code" tabindex="0"><code>{b.text}</code></pre>{:else if b.kind == "quote"}<quote class="quote"><runs spans={b.spans} /></quote>{:else if b.kind == "image"}<image class="picture" src={b.src} alt={b.alt} loading="lazy" />{:else}<para class="prose"><runs spans={b.spans} /></para>{/if}
|
|
3
|
+
</mesh-fragment>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<shell class="layout" theme="light">
|
|
2
|
+
<header class="bar">
|
|
3
|
+
<link class="brand" href={home} current="false">{site}</link>
|
|
4
|
+
</header>
|
|
5
|
+
<div class="frame">
|
|
6
|
+
<nav class="sidebar" label="Pages">
|
|
7
|
+
{#each sections as s (s.id)}
|
|
8
|
+
<section>
|
|
9
|
+
{#if s.title != ""}<para class="nav-title">{s.title}</para>{/if}
|
|
10
|
+
<list class="nav-list">
|
|
11
|
+
{#each s.items as n (n.id)}
|
|
12
|
+
<item><link class="nav-link" href={n.href} current={n.current}>{n.label}</link></item>
|
|
13
|
+
{/each}
|
|
14
|
+
</list>
|
|
15
|
+
</section>
|
|
16
|
+
{/each}
|
|
17
|
+
</nav>
|
|
18
|
+
<main id="content" tabindex="-1">
|
|
19
|
+
<blocks items={blocks} />
|
|
20
|
+
<nav class="pager" label="Previous and next page">
|
|
21
|
+
{#if prev.href != ""}<link class="pager-link" href={prev.href} current="false">{prev.label}</link>{/if}
|
|
22
|
+
{#if next.href != ""}<link class="pager-link" href={next.href} current="false">{next.label}</link>{/if}
|
|
23
|
+
</nav>
|
|
24
|
+
</main>
|
|
25
|
+
</div>
|
|
26
|
+
</shell>
|
package/views/runs.mprx
ADDED