feat: release Dever 0.1.4 with enforceable project guidance

This commit is contained in:
Antigravity committed 2026-10-09 05:33:57 +00:00
1 parent 201bdee372
commit 89629c2197
86 files changed
+2798 -338

No files matched your search

@@ -0,0 +1 @@
{}
@@ -0,0 +1 @@
cmd summarize = app.summarize
@@ -0,0 +1,18 @@
type Article {
title: Text
published: Bool
}
type Summary {
titles: List<Text>
title_length: Int
}
summarize(articles: List<Article>) (summary: Summary) {
published = filter(domain.is_published, articles)
titles = each(domain.published_title, published)
summary = Summary {
titles = titles
title_length = reduce(domain.add_title_length, titles, 0)
}
}
@@ -0,0 +1,11 @@
is_published(article: app.Article) (selected: Bool) pure {
selected = article.published and text.trim(article.title) != ""
}
published_title(article: app.Article) (title: Text) pure {
title = text.trim(article.title)
}
add_title_length(title: Text, total: Int) (next: Int) pure {
next = total + length(title)
}
@@ -0,0 +1,43 @@
type State {
Draft
Published
Rejected(reason: Text)
}
clauses() () {
assert_eq(label(State.Draft), "draft")
assert_eq(label(State.Published), "published")
assert_eq(label(State.Rejected("needs revision")), "needs revision")
assert_eq(display(null), "missing")
assert_eq(display("present"), "present")
assert_eq(grade(59), "fail")
assert_eq(grade(60), "pass")
}
label(state: State.Published) (text: Text) {
text = "published"
}
label(state: State.Rejected(reason)) (text: Text) {
text = reason
}
label(state: other) (text: Text) {
text = "draft"
}
display(value: Text) (text: Text) {
text = value
}
display(value: null) (text: Text) {
text = "missing"
}
grade(score: Int < 60) (text: Text) {
text = "fail"
}
grade(score: Int >= 60) (text: Text) {
text = "pass"
}
@@ -0,0 +1,32 @@
summary() () {
articles = [
app.Article {
title = " First "
published = true
},
app.Article {
title = "Hidden"
published = false
},
app.Article {
title = " "
published = true
},
app.Article {
title = "Second"
published = true
}
]
actual = app.summarize(articles)
assert_eq(actual.titles, ["First", "Second"])
assert_eq(actual.title_length, 11)
each(assert_clean_title, actual.titles)
empty = app.summarize([])
assert_eq(empty.titles, [])
assert_eq(empty.title_length, 0)
}
assert_clean_title(title: Text) () {
assert(title != "")
assert_eq(title, text.trim(title))
}
@@ -0,0 +1 @@
{}
@@ -0,0 +1 @@
external command "bin/tool" {}
@@ -0,0 +1 @@
cmd version = app.version
@@ -0,0 +1,14 @@
type Version {
code: Int
stdout: Text
stderr: Text
}
version() (version: Version) {
output = port.execute(["--version"], null)
version = Version {
code = output.code
stdout = dever.bytes.to_text(output.stdout)
stderr = dever.bytes.to_text(output.stderr)
}
}
@@ -0,0 +1 @@
execute(args: List<Text>, stdin: Bytes?) (output: dever.process.Output) fails dever.process.Error
@@ -0,0 +1,16 @@
version() () {
output = app.version()
assert_eq(output.code, 0)
assert_eq(output.stdout, "tool 1.0\n")
assert_eq(output.stderr, "")
}
port.execute(args: List<Text>, stdin: Bytes?) (output: dever.process.Output) {
assert_eq(args, ["--version"])
assert_eq(stdin, null)
output = dever.process.Output {
code = 0
stdout = dever.bytes.from_text("tool 1.0\n")
stderr = dever.bytes.from_text("")
}
}
@@ -0,0 +1,4 @@
{
"lib": ["pip:markdown@3.8.2"],
"log": { "level": "info" }
}
@@ -0,0 +1,3 @@
external pip "python/render.py" {
lib "markdown@3.8.2"
}
@@ -0,0 +1 @@
cmd render = app.render
@@ -0,0 +1,8 @@
type RenderResult {
Rendered(html: Text)
error Rejected(message: Text)
}
render(source: Text) (html: Text) {
html = port.render(source)
}
@@ -0,0 +1,17 @@
package main
import (
"bytes"
"context"
"github.com/yuin/goldmark"
)
func Render(ctx context.Context, payload any, setting any) (any, error) {
var output bytes.Buffer
source := payload.(map[string]any)["source"].(string)
if err := goldmark.Convert([]byte(source), &output); err != nil {
return nil, err
}
return map[string]any{"html": output.String()}, nil
}
@@ -0,0 +1,5 @@
import { marked } from 'marked';
export async function render(payload, setting, signal) {
return { html: await marked.parse(payload.source) };
}
@@ -0,0 +1 @@
render(source: Text) (html: Text) fails app.RenderResult
@@ -0,0 +1,5 @@
import markdown
async def render(payload, setting):
return {"html": markdown.markdown(payload["source"])}
@@ -0,0 +1,16 @@
rejected() () {
verify(result(app.render("rejected input")))
}
port.render(source: Text) (html: Text) {
assert_eq(source, "rejected input")
fail(app.RenderResult.Rejected("invalid document"))
}
verify(value: app.RenderResult.Rejected(message)) () recover("test verifies declared rejection") {
assert_eq(message, "invalid document")
}
verify(value: app.RenderResult.Rendered(html)) () recover("test verifies declared rejection") {
assert(false)
}
@@ -0,0 +1,8 @@
rendered() () {
assert_eq(app.render("# Report"), "<h1>Report</h1>")
}
port.render(source: Text) (html: Text) {
assert_eq(source, "# Report")
html = "<h1>Report</h1>"
}
@@ -0,0 +1,22 @@
{
"database": {
"default": {
"type": "sqlite",
"path": "data/db/platform.db",
"tenant_directory": "data/tenants"
}
},
"tenant": { "database": "default" },
"auth": {
"providers": {
"session": {
"verify": "access.session.verify",
"jwtSecret": "replace-this-example-secret-before-deployment",
"ttlSeconds": 3600
}
}
},
"sites": { "admin": { "path": "admin", "auth": "session" } },
"http": { "host": "127.0.0.1", "port": 8080 },
"log": { "level": "info" }
}
@@ -0,0 +1,60 @@
type Identity {
id: Text
user_id: access.user.model.id?
tenant_id: access.tenant.model.id?
}
verify(claims: dever.auth.Claims) (identity: Identity) {
identity = find_session(uuid.parse(claims.session), claims.tenant, claims)
}
find_session(session_id: Uuid, selected_key: Text, claims: dever.auth.Claims) (
identity: Identity
) {
stored = model.first(
{
where = uuid == session_id and subject == claims.subject and site == claims.site and tenant_key == selected_key and revoked == false and expires_at > dever.time.now(
)
}
)
identity = verified(stored)
}
find_session(session_id: null, selected_key: Text?, claims: dever.auth.Claims) (
identity: Identity
) {
fail(dever.api.Error.Unauthorized)
}
find_session(session_id: Uuid, selected_key: null, claims: dever.auth.Claims) (
identity: Identity
) {
fail(dever.api.Error.Unauthorized)
}
verified(stored: model.Session) (identity: Identity) {
access.user.require_active(stored.user_id)
access.tenant.require_active(stored.tenant_id, stored.tenant_key)
require_membership(
model.membership.exists(
{
where = user_id == stored.user_id and tenant_id == stored.tenant_id and active == true
}
)
)
identity = Identity {
id = stored.subject
user_id = stored.user_id
tenant_id = stored.tenant_id
}
}
verified(stored: null) (identity: Identity) {
fail(dever.api.Error.Unauthorized)
}
require_membership(active: true) () {}
require_membership(active: false) () {
fail(dever.api.Error.Unauthorized)
}
@@ -0,0 +1,10 @@
global type Session {
uuid: Uuid generated unique
subject: Text
user_id: access.user.model.id
tenant_id: access.tenant.model.id
tenant_key: Text
site: Text
expires_at: DateTime
revoked: Bool default false
}
@@ -0,0 +1,7 @@
global type Membership {
user_id: access.user.model.id
tenant_id: access.tenant.model.id
active: Bool default true
}
unique(user_id, tenant_id)
@@ -0,0 +1,9 @@
require_active(tenant_id: model.id, tenant_key: Text) () {
domain.require_active(
model.exists(
{
where = id == tenant_id and key == tenant_key and active == true
}
)
)
}
@@ -0,0 +1,5 @@
require_active(active: true) () {}
require_active(active: false) () {
fail(dever.api.Error.Unauthorized)
}
@@ -0,0 +1,4 @@
global type Tenant {
key: Text unique
active: Bool default true
}
@@ -0,0 +1,9 @@
require_active(user_id: model.id) () {
domain.require_active(
model.exists(
{
where = id == user_id and active == true
}
)
)
}
@@ -0,0 +1,5 @@
require_active(active: true) () {}
require_active(active: false) () {
fail(dever.api.Error.Unauthorized)
}
@@ -0,0 +1,4 @@
global type User {
uuid: Uuid generated unique
active: Bool default true
}
@@ -0,0 +1,3 @@
normalize(value: Text) (title: Text) pure {
title = text.trim(value)
}
@@ -0,0 +1,4 @@
type Article {
title: Text(1, 200) create = domain.normalize(input) replace = domain.normalize(input)
body: Text
}
@@ -0,0 +1 @@
public get ready = app.status
@@ -0,0 +1,3 @@
status() (healthy: Bool) {
healthy = true
}
@@ -0,0 +1,3 @@
title() () {
assert_eq(domain.normalize(" Draft "), "Draft")
}
@@ -0,0 +1,12 @@
{
"database": { "default": { "type": "sqlite", "path": "data/jobs.db" } },
"runtime": { "mode": "worker", "shutdown_ms": 30000 },
"job": {
"workers": 1,
"poll_ms": 1000,
"lease_ms": 60000,
"retry_base_ms": 1000,
"retry_max_ms": 300000
},
"log": { "level": "info" }
}
@@ -0,0 +1,3 @@
cmd submit = app.submit
cmd total = app.total
@@ -0,0 +1,29 @@
type Request {
key: Text
title: Text
}
submit(input: Request) (id: Id) {
id = dever.job.enqueue(job.store, input, input.key)
}
store(input: Request) () {
stored = model.create(
{
request_key = input.key
title = input.title
}
)
blocking(
dever.log.info(
"Report archived",
{
"request_key" = stored.request_key
}
)
)
}
total() (count: Int) {
count = model.count()
}
@@ -0,0 +1,5 @@
database default
job store(input: app.Request) () retry(3) timeout(30000) {
app.store(input)
}
@@ -0,0 +1,4 @@
type Archive {
request_key: Text unique
title: Text
}
@@ -0,0 +1,12 @@
queued() () {
request = app.Request {
key = "test-report"
title = "Report"
}
first_id = app.submit(request)
assert_eq(app.submit(request), first_id)
assert_eq(dever.test.drain_jobs(5), 1)
assert_eq(app.total(), 1)
dever.test.advance_clock(1000)
assert_eq(dever.test.drain_jobs(5), 0)
}