@velarscript/cli 0.17.0 → 0.18.1
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/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +8 -8
- package/skill/ai-skill-node.md +39 -17
- package/skill/ai-skill-server.md +10 -8
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@velarscript/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"description": "The VelarScript command-line compiler, dev server, test runner, and language server.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
"velar": "./dist/cli.js"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@velarscript/compiler": "0.
|
|
34
|
-
"@velarscript/core": "0.
|
|
35
|
-
"@velarscript/desktop": "0.
|
|
36
|
-
"@velarscript/node": "0.
|
|
37
|
-
"@velarscript/server": "0.
|
|
38
|
-
"@velarscript/web": "0.
|
|
39
|
-
"create-velar": "0.
|
|
33
|
+
"@velarscript/compiler": "0.18.1",
|
|
34
|
+
"@velarscript/core": "0.18.1",
|
|
35
|
+
"@velarscript/desktop": "0.18.1",
|
|
36
|
+
"@velarscript/node": "0.18.1",
|
|
37
|
+
"@velarscript/server": "0.18.1",
|
|
38
|
+
"@velarscript/web": "0.18.1",
|
|
39
|
+
"create-velar": "0.18.1",
|
|
40
40
|
"esbuild": "^0.28.1",
|
|
41
41
|
"playwright": "^1.58.2"
|
|
42
42
|
}
|
package/skill/ai-skill-node.md
CHANGED
|
@@ -52,7 +52,6 @@ export async def start():
|
|
|
52
52
|
host: "127.0.0.1",
|
|
53
53
|
port: 3000,
|
|
54
54
|
http: routes,
|
|
55
|
-
path: "/api/events",
|
|
56
55
|
origins: ["https://app.example.com"],
|
|
57
56
|
maxBodyBytes: 16777216,
|
|
58
57
|
})
|
|
@@ -69,7 +68,7 @@ second runtime configuration source.
|
|
|
69
68
|
`@` remains the language-wide annotation introducer, and `@name` is a context
|
|
70
69
|
annotation with a compiler-owned compile-time role. In a `server` block, the
|
|
71
70
|
available annotations are `@get`, `@post`, `@put`, `@patch`, `@delete`,
|
|
72
|
-
`@notFound`, and `@response`. They are not decorators, functions, imports, user-defined
|
|
71
|
+
`@websocket`, `@notFound`, and `@response`. They are not decorators, functions, imports, user-defined
|
|
73
72
|
annotations, first-class values, or user extension points.
|
|
74
73
|
|
|
75
74
|
## Routes and checked inputs
|
|
@@ -84,23 +83,24 @@ type CreateArticle:
|
|
|
84
83
|
|
|
85
84
|
export server articles:
|
|
86
85
|
/// Reports whether this service is ready.
|
|
87
|
-
@get(
|
|
86
|
+
@get(p"/health") => {ok: true}
|
|
88
87
|
|
|
89
|
-
@get(
|
|
90
|
-
const id = path.params.id
|
|
88
|
+
@get(p"/articles/{id:number}?{details:bool?}"):
|
|
91
89
|
if id < 1:
|
|
92
90
|
throw HttpProblem({status: 404, code: "article.not_found", title: "Article not found"})
|
|
93
|
-
return {id, details:
|
|
91
|
+
return {id, details: details ?? false}
|
|
94
92
|
|
|
95
|
-
@post(
|
|
93
|
+
@post(p"/articles", input: CreateArticle):
|
|
96
94
|
return created({id: 1, title: input.title})
|
|
97
95
|
|
|
98
96
|
```
|
|
99
97
|
|
|
100
|
-
`p"..."` is a first-class `RoutePattern`.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
`p"..."` is a first-class `RoutePattern`. An inline pattern projects its typed
|
|
99
|
+
path captures and query fields directly as immutable handler locals. A pattern
|
|
100
|
+
stored elsewhere must use an explicit binding such as `@get(articlePath as
|
|
101
|
+
route)`; its `RouteMatch` contains `pattern`, `pathname`, `params`, and `query`,
|
|
102
|
+
and `str(route)` or `str(route.pattern)` returns the complete declaration. Query shorthand
|
|
103
|
+
`?{details:bool?}` uses the field name on the
|
|
104
104
|
wire; `?details={details:bool?}` spells it explicitly, and
|
|
105
105
|
`?include-details={details:bool?}` maps a different wire name. The trailing
|
|
106
106
|
`?` makes a query field optional; without it the framework rejects a missing
|
|
@@ -109,8 +109,10 @@ an ASCII half-width `:` and accept `string`, `number`, `bool`, or a named enum.
|
|
|
109
109
|
The explicit same-name form remains valid but reports advisory `A11`; its
|
|
110
110
|
mechanical fix removes the redundant `details=` prefix. Different-name aliases
|
|
111
111
|
do not report it.
|
|
112
|
-
Route catalogs may keep patterns in exported `const` objects
|
|
113
|
-
|
|
112
|
+
Route catalogs may keep patterns in exported `const` objects. Referenced
|
|
113
|
+
patterns require `as name` so the compiler never injects identifiers that are
|
|
114
|
+
hidden inside another declaration. The old `path=` spelling is an error with a
|
|
115
|
+
mechanical fix to the positional form and `as path`.
|
|
114
116
|
|
|
115
117
|
On `POST`, `PUT`, or `PATCH`, one concrete Data parameter is the
|
|
116
118
|
checked JSON body. A `Request` parameter explicitly requests the complete
|
|
@@ -184,13 +186,13 @@ const currentUser = provide(
|
|
|
184
186
|
)
|
|
185
187
|
|
|
186
188
|
server account:
|
|
187
|
-
@get(
|
|
189
|
+
@get(p"/me",
|
|
188
190
|
user=input.dependency(currentUser),
|
|
189
191
|
tenant=input.header("x-tenant"),
|
|
190
192
|
session=input.cookie("session", default=null),
|
|
191
193
|
) => {id: user.id, tenant, session}
|
|
192
194
|
|
|
193
|
-
@post(
|
|
195
|
+
@post(p"/images",
|
|
194
196
|
metadata=input.form(UploadMetadata),
|
|
195
197
|
image=input.upload("image", maxBytes=8_388_608),
|
|
196
198
|
) => {title: metadata.title, filename: image.filename}
|
|
@@ -308,13 +310,33 @@ total stream are bounded. SSE accepts text or checked
|
|
|
308
310
|
root-contained, streamed reads with validators and one byte range.
|
|
309
311
|
|
|
310
312
|
`velar/websocket.listen({http: app, ...})` serves a `ServeApp` and WebSocket
|
|
311
|
-
upgrades on one native server and owns the application lifecycle.
|
|
313
|
+
upgrades on one native server and owns the application lifecycle. A declarative
|
|
314
|
+
session belongs in the route table:
|
|
315
|
+
|
|
316
|
+
```velar
|
|
317
|
+
import {WebSocketConnection} from "velar/websocket"
|
|
318
|
+
|
|
319
|
+
server realtime:
|
|
320
|
+
@websocket(p"/worlds/{worldId:string}/realtime", connection: WebSocketConnection):
|
|
321
|
+
async for message in connection:
|
|
322
|
+
await connection.send(message)
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Matching, path/query decoding, dependencies, security, headers, cookies, and
|
|
326
|
+
the optional `Request` are resolved before upgrade. Exactly one
|
|
327
|
+
`WebSocketConnection` is supplied by the framework, the handler must finish
|
|
328
|
+
with `null`, and its lifetime is joined with shutdown. Inline patterns project
|
|
329
|
+
captures directly; referenced patterns require `as route`. A listener whose app
|
|
330
|
+
contains these routes rejects its legacy single `path` option and does not offer
|
|
331
|
+
accepted sessions through `WebSocketServer.next()`.
|
|
332
|
+
|
|
333
|
+
Set
|
|
312
334
|
`maxBodyBytes` to the supplied application value. `origins` contains exact
|
|
313
335
|
canonical HTTP/HTTPS origins. The default rejects any upgrade carrying
|
|
314
336
|
`Origin`; no-Origin non-browser clients remain allowed. Use `["*"]` only for an
|
|
315
337
|
intentional unrestricted policy. A rejected browser origin receives 403 before
|
|
316
338
|
it consumes connection-queue capacity. Connections are pull-based. Always
|
|
317
|
-
consume `next()`, handle backpressure, and stop the server.
|
|
339
|
+
consume each connection's `next()`, handle backpressure, and stop the server.
|
|
318
340
|
|
|
319
341
|
## Tests
|
|
320
342
|
|
package/skill/ai-skill-server.md
CHANGED
|
@@ -13,7 +13,7 @@ browser application activates `@velarscript/web`:
|
|
|
13
13
|
```json
|
|
14
14
|
{
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@velarscript/server": "0.
|
|
16
|
+
"@velarscript/server": "0.18.1"
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
```
|
|
@@ -62,7 +62,7 @@ All three fields are optional. Their defaults are `127.0.0.1`, `3000`, and
|
|
|
62
62
|
import {application} from "velar/server"
|
|
63
63
|
|
|
64
64
|
export server routes:
|
|
65
|
-
@get(
|
|
65
|
+
@get(p"/health") => {status: "ready"}
|
|
66
66
|
|
|
67
67
|
export const start = application(routes)
|
|
68
68
|
```
|
|
@@ -127,7 +127,7 @@ async def verifyAccessToken(token: string) -> Principal?:
|
|
|
127
127
|
const currentPrincipal = authenticate(security.bearer(), verifyAccessToken)
|
|
128
128
|
|
|
129
129
|
export server accountRoutes:
|
|
130
|
-
@get(
|
|
130
|
+
@get(p"/me", principal=input.dependency(currentPrincipal)) => {
|
|
131
131
|
subject: principal.subject,
|
|
132
132
|
}
|
|
133
133
|
```
|
|
@@ -168,7 +168,7 @@ const connection = database(
|
|
|
168
168
|
)
|
|
169
169
|
|
|
170
170
|
export server databaseRoutes:
|
|
171
|
-
@get(
|
|
171
|
+
@get(p"/database", value=input.dependency(connection)) => {name: value.name}
|
|
172
172
|
```
|
|
173
173
|
|
|
174
174
|
The framework owns only this connect/inject/disconnect lifecycle. Concrete
|
|
@@ -179,8 +179,9 @@ syntax to `@velarscript/server` or `@velarscript/node`.
|
|
|
179
179
|
|
|
180
180
|
## Custom shared HTTP/WebSocket startup
|
|
181
181
|
|
|
182
|
-
A service
|
|
183
|
-
typed configuration and export an exact zero-argument async startup
|
|
182
|
+
A service whose route table contains `@websocket` declarations may load the
|
|
183
|
+
same typed configuration and export an exact zero-argument async startup
|
|
184
|
+
function for the shared HTTP/WebSocket listener:
|
|
184
185
|
|
|
185
186
|
```velar fragment
|
|
186
187
|
import {configuration} from "velar/server"
|
|
@@ -201,7 +202,6 @@ export async def start():
|
|
|
201
202
|
host: settings.server.host,
|
|
202
203
|
port: settings.server.port,
|
|
203
204
|
http: routes,
|
|
204
|
-
path: "/events",
|
|
205
205
|
origins: ["https://app.example.com"],
|
|
206
206
|
maxBodyBytes: settings.server.maxBodyBytes,
|
|
207
207
|
})
|
|
@@ -209,7 +209,9 @@ export async def start():
|
|
|
209
209
|
|
|
210
210
|
The result must be exactly `Promise<WebSocketServer>`. The launcher supplies no
|
|
211
211
|
host, port, or body-limit arguments; the root application configuration remains
|
|
212
|
-
the single runtime authority.
|
|
212
|
+
the single runtime authority. Each `@websocket` RoutePattern owns its own path,
|
|
213
|
+
typed captures, admission inputs, and session handler, so this declarative mode
|
|
214
|
+
does not accept the listener's legacy single `path` option.
|
|
213
215
|
|
|
214
216
|
Use direct `serve(app, port=0)` in tests or embedded low-level adapters. Use
|
|
215
217
|
`velar/server-test` only from `*.test.vel`. Route, provider, transport,
|