Make the final breaking change with net json and update changelog

This commit is contained in:
Filip Tibell 2025-04-25 12:43:40 +02:00
parent 1119f0d46b
commit 387080cf45
No known key found for this signature in database
11 changed files with 86 additions and 69 deletions

View file

@ -1,6 +1,7 @@
local fs = require("@lune/fs")
local net = require("@lune/net")
local process = require("@lune/process")
local serde = require("@lune/serde")
local stdio = require("@lune/stdio")
local task = require("@lune/task")
@ -145,10 +146,8 @@ local result = process.exec("ping", {
if result.ok then
assert(#result.stdout > 0, "Result output was empty")
local min, avg, max, stddev = string.match(
result.stdout,
"min/avg/max/stddev = ([%d%.]+)/([%d%.]+)/([%d%.]+)/([%d%.]+) ms"
)
local min, avg, max, stddev =
string.match(result.stdout, "min/avg/max/stddev = ([%d%.]+)/([%d%.]+)/([%d%.]+)/([%d%.]+) ms")
print(string.format("Minimum ping time: %.3fms", assert(tonumber(min))))
print(string.format("Maximum ping time: %.3fms", assert(tonumber(max))))
print(string.format("Average ping time: %.3fms", assert(tonumber(avg))))
@ -172,7 +171,7 @@ local apiResult = net.request({
headers = {
["Content-Type"] = "application/json",
} :: { [string]: string },
body = net.jsonEncode({
body = serde.encode("json", {
title = "foo",
body = "bar",
}),
@ -192,7 +191,7 @@ type ApiResponse = {
userId: number,
}
local apiResponse: ApiResponse = net.jsonDecode(apiResult.body)
local apiResponse: ApiResponse = serde.decode("json", apiResult.body)
assert(apiResponse.title == "foo", "Invalid json response")
assert(apiResponse.body == "bar", "Invalid json response")
print("Got valid JSON response with changes applied")

View file

@ -10,43 +10,96 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## `0.9.0`
### Breaking changes
This release has been a long time coming, and many breaking changes have been deferred until this version.
If you are an existing Lune user upgrading to this version, you will **most likely** be affected - please read the full list of breaking changes below.
- Added two new process spawning functions - `process.create` and `process.exec`, removing the previous `process.spawn` API completely. ([#211])
### Breaking changes & additions
To migrate from `process.spawn`, use the new `process.exec` API which retains the same behavior as the old function.
- The behavior of `require` has changed, according to the latest Luau RFCs and specifications.
For the full details, feel free to read documentation [here](https://github.com/luau-lang/rfcs), otherwise, the most notable changes here are:
- Paths passed to require must start with either `./`, `../` or `@` - require statements such as `require("foo")` **will now error** and must be changed to `require("./foo")`.
- The behavior of require from within `init.luau` and `init.lua` files has changed - previously `require("./foo")` would resolve
to the file or directory `foo` _as a **sibling** of the init file_, but will now resolve to the file or directory `foo` _which is a sibling of the **parent directory** of the init file_.
To require files inside of the same directory as the init file, the new `@self` alias must be used - like `require("@self/foo")`.
- The main `lune run` subcommand will no longer sink flags passed to it - `lune run --` will now *literally* pass the string `--` as the first
value in `process.args`, and `--` is no longer necessary to be able to pass flag arguments such as `--foo` and `-b` properly to your Lune programs.
- Two new process spawning functions - `process.create` and `process.exec` - replace the previous `process.spawn` API. ([#211])
To migrate from `process.spawn`, use the new `process.exec` API which retains the same behavior as the old function, with slight changes in how the `stdin` option is passed.
The new `process.create` function is a non-blocking process creation API and can be used to interactively
read and write stdio of the process.
read and write to standard input and output streams of the child process.
```lua
local child = process.create("program", {
"cli-argument",
"other-cli-argument"
"first-argument",
"second-argument"
})
-- Writing to stdin
child.stdin:write("Hello from Lune!")
-- Reading from stdout
-- Reading partial data from stdout
local data = child.stdout:read()
print(buffer.tostring(data))
print(data)
-- Reading the full stdout
local full = child.stdout:readToEnd()
print(full)
```
- Removed `net.jsonEncode` and `net.jsonDecode` - please use the equivalent `serde.encode("json", ...)` and `serde.decode("json", ...)` instead
- WebSocket methods in `net.socket` and `net.serve` now use standard Lua method calling convention and colon syntax.
This means `socket.send(...)` is now `socket:send(...)`, `socket.close(...)` is now `socket:close(...)`, and so on.
- Various changes have been made to the Lune Rust crates:
- `Runtime::run` now returns a more useful value instead of an `ExitCode` ([#178])
- All Lune standard library crates now export a `typedefs` function that returns the source code for the respective standard library module type definitions
- All Lune crates now depend on `mlua` version `0.10` or above
- Most Lune crates have been migrated to the `smol` and `async-*` ecosystem instead of `tokio`, with a full migration expected soon (this will not break public types)
- The `roblox` crate re-export has been removed from the main `lune` crate - please depend on `lune-roblox` crate directly instead
### Added
- Added functions for getting Roblox Studio locations to the `roblox` standard library ([#284])
- Added support for the `Content` datatype in the `roblox` standard library ([#305])
- Added support for `EnumItem` instance attributes in the `roblox` standard library ([#306])
- Added support for RFC 2822 dates in the `datetime` standard library using `fromRfc2822` ([#285]) - the `fromIsoDate`
function has also been deprecated (not removed yet) and `fromRfc3339` should instead be preferred for any new work.
- Added a `readLine` function to the `stdio` standard library for reading line-by-line from stdin.
- Added a way to disable JIT by setting the `LUNE_LUAU_JIT` environment variable to `false` before running Lune.
- Added `process.endianness` constant ([#267])
### Changed
- Documentation comments for several standard library properties have been improved ([#248], [#250])
- Error messages no longer contain redundant or duplicate stack trace information
- Updated to Luau version `0.663`
- Updated to rbx-dom database version `0.670`
### Fixed
- Fixed deadlock in `stdio.format` calls in `__tostring` metamethods ([#288])
- Fixed `task.wait` and `task.delay` not being guaranteed to yield when duration is set to zero or very small values
- Fixed `__tostring` metamethods sometimes not being respected in `print` and `stdio.format` calls
[#178]: https://github.com/lune-org/lune/pull/178
[#211]: https://github.com/lune-org/lune/pull/211
[#248]: https://github.com/lune-org/lune/pull/248
[#250]: https://github.com/lune-org/lune/pull/250
[#265]: https://github.com/lune-org/lune/pull/265
[#267]: https://github.com/lune-org/lune/pull/267
[#284]: https://github.com/lune-org/lune/pull/284
[#285]: https://github.com/lune-org/lune/pull/285
[#288]: https://github.com/lune-org/lune/pull/288
[#305]: https://github.com/lune-org/lune/pull/305
[#306]: https://github.com/lune-org/lune/pull/306
## `0.8.9` - October 7th, 2024

4
Cargo.lock generated
View file

@ -473,9 +473,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.2.19"
version = "1.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362"
checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a"
dependencies = [
"jobserver",
"libc",

View file

@ -1,6 +1,5 @@
#![allow(clippy::cargo_common_metadata)]
use bstr::BString;
use mlua::prelude::*;
use mlua_luau_scheduler::LuaSpawnExt;
@ -20,8 +19,6 @@ use self::{
websocket::NetWebSocket,
};
use lune_std_serde::{decode, encode, EncodeDecodeConfig, EncodeDecodeFormat};
const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/types.d.luau"));
/**
@ -45,8 +42,6 @@ pub fn module(lua: Lua) -> LuaResult<LuaTable> {
.build()?
.into_registry(&lua);
TableBuilder::new(lua)?
.with_function("jsonEncode", net_json_encode)?
.with_function("jsonDecode", net_json_decode)?
.with_async_function("request", net_request)?
.with_async_function("socket", net_socket)?
.with_async_function("serve", net_serve)?
@ -55,16 +50,6 @@ pub fn module(lua: Lua) -> LuaResult<LuaTable> {
.build_readonly()
}
fn net_json_encode(lua: &Lua, (val, pretty): (LuaValue, Option<bool>)) -> LuaResult<LuaString> {
let config = EncodeDecodeConfig::from((EncodeDecodeFormat::Json, pretty.unwrap_or_default()));
encode(val, lua, config)
}
fn net_json_decode(lua: &Lua, json: BString) -> LuaResult<LuaValue> {
let config = EncodeDecodeConfig::from(EncodeDecodeFormat::Json);
decode(json, lua, config)
}
async fn net_request(lua: Lua, config: RequestConfig) -> LuaResult<LuaTable> {
let client = NetClient::from_registry(&lua);
// NOTE: We spawn the request as a background task to free up resources in lua

View file

@ -188,6 +188,7 @@ export type WebSocket = {
```lua
local net = require("@lune/net")
local serde = require("@lune/serde")
-- Sending a web request
local response = net.request("https://www.google.com")
@ -200,14 +201,14 @@ export type WebSocket = {
url = "https://dummyjson.com/products/add",
method = "POST",
headers = { ["Content-Type"] = "application/json" },
body = net.jsonEncode({
body = serde.encode("json", {
title = "Cool Pencil",
})
})
local product = net.jsonDecode(response.body)
local product = serde.decode("json", response.body)
print(product.id, "-", product.title)
-- Starting up a webserver
-- Starting up an http server
net.serve(8080, function(request)
return {
status = 200,
@ -263,33 +264,6 @@ function net.serve(port: number, handlerOrConfig: ServeHttpHandler | ServeConfig
return nil :: any
end
--[=[
@within Net
@tag must_use
Encodes the given value as JSON.
@param value The value to encode as JSON
@param pretty If the encoded JSON string should include newlines and spaces. Defaults to false
@return The encoded JSON string
]=]
function net.jsonEncode(value: any, pretty: boolean?): string
return nil :: any
end
--[=[
@within Net
@tag must_use
Decodes the given JSON string into a lua value.
@param encoded The JSON string to decode
@return The decoded lua value
]=]
function net.jsonDecode(encoded: string): any
return nil :: any
end
--[=[
@within Net
@tag must_use

View file

@ -330,6 +330,7 @@ end
```lua
local roblox = require("@lune/roblox")
local serde = require("@lune/serde")
local net = require("@lune/net")
local cookie = roblox.getAuthCookie()
@ -344,7 +345,7 @@ end
},
})
local responseTable = net.jsonDecode(response.body)
local responseTable = serde.decode("json", response.body)
local responseLocation = responseTable.locations[1].location
print("Download link to place: " .. responseLocation)
```

View file

@ -1,10 +1,11 @@
local fs = require("@lune/fs")
local net = require("@lune/net")
local serde = require("@lune/serde")
local URL =
"https://gist.githubusercontent.com/Anaminus/49ac255a68e7a7bc3cdd72b602d5071f/raw/f1534dcae312dbfda716b7677f8ac338b565afc3/BrickColor.json"
local json = net.jsonDecode(net.request(URL).body)
local json = serde.decode("json", net.request(URL).body)
local contents = ""

View file

@ -1,4 +1,5 @@
local net = require("@lune/net")
local serde = require("@lune/serde")
-- Should decompress automatically by default
@ -17,7 +18,7 @@ assert(
.. tostring(response.statusMessage)
)
local success, json = pcall(net.jsonDecode, response.body)
local success, json = pcall(serde.decode, "json" :: "json", response.body)
assert(success, "Failed to decode json response\n" .. tostring(json))
-- Content encoding header should no longer exist when automatically decompressed
@ -45,7 +46,7 @@ assert(
.. tostring(response2.statusMessage)
)
local success2 = pcall(net.jsonDecode, response2.body)
local success2 = pcall(serde.decode, "json" :: "json", response2.body)
assert(not success2, "Decompression disabled still returned json response")
-- Content encoding header should still exist when not automatically decompressed

View file

@ -1,4 +1,5 @@
local net = require("@lune/net")
local serde = require("@lune/serde")
local QUERY: { [string]: string } = {
Key = "Value",
@ -24,7 +25,7 @@ assert(
-- We should get a json response here with an "args" table which is our query
local success, json = pcall(net.jsonDecode, response.body)
local success, json = pcall(serde.decode, "json" :: "json", response.body)
assert(success, "Failed to decode json response\n" .. tostring(json))
local args = if type(json.args) == "table" then json.args else nil

View file

@ -1,9 +1,10 @@
local net = require("@lune/net")
local serde = require("@lune/serde")
local runtime, version = table.unpack(_VERSION:split(" "))
local expectedUserAgent = runtime:lower() .. "/" .. version
local userAgent: string =
net.jsonDecode(net.request("https://www.whatsmyua.info/api/v1/ua").body)[1].ua.rawUa
serde.decode("json", net.request("https://www.whatsmyua.info/api/v1/ua").body)[1].ua.rawUa
assert(userAgent == expectedUserAgent, "Expected user agent to be " .. expectedUserAgent)

View file

@ -1,5 +1,6 @@
local net = require("@lune/net")
local roblox = require("@lune/roblox")
local serde = require("@lune/serde")
roblox.implementMethod("HttpService", "GetAsync", function(_, url: string)
local response = net.request({
@ -10,7 +11,7 @@ roblox.implementMethod("HttpService", "GetAsync", function(_, url: string)
end)
roblox.implementMethod("HttpService", "JSONDecode", function(_, value)
return net.jsonDecode(value)
return serde.decode("json", value)
end)
-- Reference: https://create.roblox.com/docs/reference/engine/classes/HttpService#GetAsync