├── tests ├── require │ ├── tests │ │ ├── multi_ext.luau │ │ ├── modules │ │ │ ├── nested.luau │ │ │ ├── init.luau │ │ │ ├── module.luau │ │ │ ├── modules │ │ │ │ ├── init.luau │ │ │ │ └── module.luau │ │ │ ├── self_alias │ │ │ │ ├── module.luau │ │ │ │ └── init.luau │ │ │ └── async.luau │ │ ├── module.luau │ │ ├── multi.ext.file.luau │ │ ├── state_second.luau │ │ ├── state_module.luau │ │ ├── parents.luau │ │ ├── siblings.luau │ │ ├── async.luau │ │ ├── nested.luau │ │ ├── children.luau │ │ ├── state.luau │ │ ├── aliases.luau │ │ ├── invalid.luau │ │ ├── builtins.luau │ │ ├── async_sequential.luau │ │ ├── async_concurrent.luau │ │ └── init_files.luau │ └── modules │ │ ├── init.luau │ │ └── module.luau ├── stdio │ ├── write.luau │ ├── ewrite.luau │ ├── style.luau │ ├── color.luau │ └── prompt.luau ├── serde │ ├── test-files │ │ ├── loremipsum.txt.z │ │ ├── loremipsum.txt.br │ │ ├── loremipsum.txt.gz │ │ ├── loremipsum.txt.lz4 │ │ ├── loremipsum.txt.zst │ │ ├── uncompressed.csv │ │ ├── uncompressed.yaml │ │ ├── uncompressed.json │ │ └── loremipsum.txt │ ├── toml │ │ ├── encode.luau │ │ ├── decode.luau │ │ └── source.luau │ ├── jsonc │ │ ├── source.luau │ │ ├── encode.luau │ │ └── decode.luau │ └── json │ │ ├── source.luau │ │ ├── encode.luau │ │ └── decode.luau ├── net │ ├── request │ │ ├── redirect.luau │ │ ├── codes.luau │ │ ├── user_agent.luau │ │ ├── methods.luau │ │ ├── https.luau │ │ └── util.luau │ ├── url │ │ ├── decode.luau │ │ └── encode.luau │ ├── tcp │ │ ├── info.luau │ │ ├── basic.luau │ │ └── tls.luau │ ├── serve │ │ ├── non_blocking.luau │ │ ├── addresses.luau │ │ └── requests.luau │ └── socket │ │ ├── wss.luau │ │ ├── wss_rw.luau │ │ └── basic.luau ├── globals │ ├── warn.luau │ ├── error.luau │ ├── type.luau │ ├── _G.luau │ ├── pcall.luau │ └── typeof.luau ├── datetime │ ├── now.luau │ ├── fromRfc3339.luau │ ├── fromRfc2822.luau │ ├── formatUniversalTime.luau │ ├── fromUniversalTime.luau │ ├── fromUnixTimestamp.luau │ ├── toLocalTime.luau │ ├── toUniversalTime.luau │ └── fromLocalTime.luau ├── process │ ├── exec │ │ ├── no_panic.luau │ │ ├── stdio.luau │ │ ├── shell.luau │ │ ├── basic.luau │ │ └── async.luau │ ├── create │ │ ├── non_blocking.luau │ │ ├── kill.luau │ │ ├── status.luau │ │ └── stream.luau │ ├── cwd.luau │ ├── env.luau │ ├── exit.luau │ └── args.luau ├── task │ ├── fcheck.luau │ └── cancel.luau ├── roblox │ ├── instance │ │ ├── methods │ │ │ ├── GetDebugId.luau │ │ │ ├── FindFirstAncestor.luau │ │ │ ├── GetFullName.luau │ │ │ ├── FindFirstAncestorOfClass.luau │ │ │ ├── FindFirstAncestorWhichIsA.luau │ │ │ ├── FindFirstChild.luau │ │ │ ├── Destroy.luau │ │ │ ├── GetChildren.luau │ │ │ ├── FindFirstChildOfClass.luau │ │ │ ├── GetDescendants.luau │ │ │ ├── FindFirstChildWhichIsA.luau │ │ │ ├── IsAncestorOf.luau │ │ │ ├── ClearAllChildren.luau │ │ │ ├── IsDescendantOf.luau │ │ │ ├── IsA.luau │ │ │ └── Clone.luau │ │ ├── classes │ │ │ ├── Terrain.luau │ │ │ ├── Workspace.luau │ │ │ └── DataModel.luau │ │ ├── tags.luau │ │ ├── custom │ │ │ ├── async.luau │ │ │ └── methods.luau │ │ └── new.luau │ ├── datatypes │ │ ├── UDim.luau │ │ ├── NumberRange.luau │ │ ├── Enum.luau │ │ ├── NumberSequenceKeypoint.luau │ │ ├── BrickColor.luau │ │ ├── NumberSequence.luau │ │ ├── ColorSequenceKeypoint.luau │ │ ├── Region3int16.luau │ │ ├── Vector2int16.luau │ │ ├── ColorSequence.luau │ │ ├── Vector3int16.luau │ │ ├── Axes.luau │ │ ├── Faces.luau │ │ ├── Rect.luau │ │ ├── Region3.luau │ │ ├── Ray.luau │ │ ├── UniqueId.luau │ │ ├── UDim2.luau │ │ └── Font.luau │ ├── reflection │ │ ├── property.luau │ │ ├── enums.luau │ │ └── class.luau │ ├── files │ │ ├── deserializeModel.luau │ │ └── deserializePlace.luau │ └── misc │ │ └── typeof.luau ├── fs │ ├── utils.luau │ └── dirs.luau ├── regex │ ├── metamethods.luau │ └── general.luau └── luau │ ├── compile.luau │ └── options.luau ├── crates ├── lune │ └── src │ │ ├── cli │ │ ├── utils │ │ │ └── mod.rs │ │ └── build │ │ │ ├── result.rs │ │ │ └── files.rs │ │ ├── rt │ │ └── mod.rs │ │ ├── lib.rs │ │ ├── standalone │ │ ├── tracer.rs │ │ └── mod.rs │ │ └── main.rs ├── lune-std │ └── src │ │ ├── require │ │ └── mod.rs │ │ ├── globals │ │ ├── mod.rs │ │ ├── g_table.rs │ │ ├── require.rs │ │ ├── print.rs │ │ ├── warn.rs │ │ └── version.rs │ │ └── lib.rs ├── mlua-luau-scheduler │ ├── src │ │ ├── threads │ │ │ ├── mod.rs │ │ │ └── id.rs │ │ ├── events │ │ │ └── mod.rs │ │ ├── queue │ │ │ ├── mod.rs │ │ │ ├── spawned.rs │ │ │ ├── deferred.rs │ │ │ └── futures.rs │ │ ├── lib.rs │ │ ├── exit.rs │ │ ├── status.rs │ │ └── error_callback.rs │ ├── examples │ │ ├── lua │ │ │ ├── callbacks.luau │ │ │ ├── exit_code.luau │ │ │ ├── basic_sleep.luau │ │ │ ├── basic_spawn.luau │ │ │ ├── lots_of_threads.luau │ │ │ └── scheduler_ordering.luau │ │ ├── exit_code.rs │ │ ├── callbacks.rs │ │ └── basic_sleep.rs │ └── Cargo.toml ├── lune-std-net │ ├── src │ │ ├── url │ │ │ ├── mod.rs │ │ │ ├── encode.rs │ │ │ └── decode.rs │ │ ├── shared │ │ │ ├── mod.rs │ │ │ ├── futures.rs │ │ │ └── lua.rs │ │ ├── body │ │ │ ├── mod.rs │ │ │ ├── incoming.rs │ │ │ └── cursor.rs │ │ └── client │ │ │ ├── rustls.rs │ │ │ └── tcp.rs │ └── Cargo.toml ├── lune-roblox │ ├── src │ │ ├── shared │ │ │ └── mod.rs │ │ ├── datatypes │ │ │ ├── mod.rs │ │ │ ├── util.rs │ │ │ └── types │ │ │ │ ├── mod.rs │ │ │ │ └── enums.rs │ │ ├── document │ │ │ ├── error.rs │ │ │ └── postprocessing.rs │ │ └── instance │ │ │ └── workspace.rs │ └── Cargo.toml ├── lune-std-process │ ├── src │ │ ├── create │ │ │ └── mod.rs │ │ └── exec │ │ │ ├── mod.rs │ │ │ └── tee_writer.rs │ └── Cargo.toml ├── lune-utils │ ├── src │ │ ├── fmt │ │ │ ├── error │ │ │ │ └── mod.rs │ │ │ ├── mod.rs │ │ │ ├── value │ │ │ │ ├── style.rs │ │ │ │ ├── config.rs │ │ │ │ └── metamethods.rs │ │ │ └── label.rs │ │ ├── path │ │ │ ├── constants.rs │ │ │ └── mod.rs │ │ ├── lib.rs │ │ └── process │ │ │ └── jit.rs │ └── Cargo.toml ├── lune-std-luau │ └── Cargo.toml ├── lune-std-regex │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── lune-std-datetime │ ├── Cargo.toml │ └── src │ │ ├── result.rs │ │ └── lib.rs ├── lune-std-task │ └── Cargo.toml ├── lune-std-fs │ ├── Cargo.toml │ └── src │ │ └── options.rs ├── lune-std-stdio │ └── Cargo.toml ├── lune-std-roblox │ └── Cargo.toml └── lune-std-serde │ └── Cargo.toml ├── .lune ├── data │ └── test.csv ├── websocket_server.luau ├── websocket_client.luau └── http_server.luau ├── assets └── logo │ ├── tilt.ico │ ├── tilt.png │ ├── no-tilt.ico │ ├── no-tilt.png │ ├── tilt-grid.ico │ ├── tilt-grid.png │ ├── no-tilt-grid.ico │ └── no-tilt-grid.png ├── rokit.toml ├── .gitmodules ├── .gitattributes ├── scripts ├── format.sh ├── format-check.sh ├── analyze.sh ├── get-version.sh ├── analyze_copy_typedefs.luau ├── physical_properties_enum_map.luau ├── brick_color.luau ├── unpack-releases.sh └── zip-release.sh ├── .vscode ├── extensions.json └── settings.json ├── stylua.toml ├── .editorconfig ├── .luaurc ├── .gitignore └── .cargo └── config.toml /tests/require/tests/multi_ext.luau: -------------------------------------------------------------------------------- 1 | require("./multi.ext.file") 2 | -------------------------------------------------------------------------------- /crates/lune/src/cli/utils/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod files; 2 | pub mod listing; 3 | -------------------------------------------------------------------------------- /tests/require/tests/modules/nested.luau: -------------------------------------------------------------------------------- 1 | return require("./modules/module") 2 | -------------------------------------------------------------------------------- /.lune/data/test.csv: -------------------------------------------------------------------------------- 1 | Header1,Header2,Header3 2 | Hello,World,! 3 | 1,2,3 4 | Foo,Bar,Baz 5 | -------------------------------------------------------------------------------- /assets/logo/tilt.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/assets/logo/tilt.ico -------------------------------------------------------------------------------- /assets/logo/tilt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/assets/logo/tilt.png -------------------------------------------------------------------------------- /tests/require/modules/init.luau: -------------------------------------------------------------------------------- 1 | return { 2 | Foo = "Bar", 3 | Hello = "World", 4 | } 5 | -------------------------------------------------------------------------------- /tests/require/modules/module.luau: -------------------------------------------------------------------------------- 1 | return { 2 | Foo = "Bar", 3 | Hello = "World", 4 | } 5 | -------------------------------------------------------------------------------- /tests/require/tests/module.luau: -------------------------------------------------------------------------------- 1 | return { 2 | Foo = "Bar", 3 | Hello = "World", 4 | } 5 | -------------------------------------------------------------------------------- /assets/logo/no-tilt.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/assets/logo/no-tilt.ico -------------------------------------------------------------------------------- /assets/logo/no-tilt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/assets/logo/no-tilt.png -------------------------------------------------------------------------------- /tests/require/tests/modules/init.luau: -------------------------------------------------------------------------------- 1 | return { 2 | Foo = "Bar", 3 | Hello = "World", 4 | } 5 | -------------------------------------------------------------------------------- /tests/require/tests/modules/module.luau: -------------------------------------------------------------------------------- 1 | return { 2 | Foo = "Bar", 3 | Hello = "World", 4 | } 5 | -------------------------------------------------------------------------------- /tests/require/tests/multi.ext.file.luau: -------------------------------------------------------------------------------- 1 | return { 2 | Foo = "Bar", 3 | Hello = "World", 4 | } 5 | -------------------------------------------------------------------------------- /assets/logo/tilt-grid.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/assets/logo/tilt-grid.ico -------------------------------------------------------------------------------- /assets/logo/tilt-grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/assets/logo/tilt-grid.png -------------------------------------------------------------------------------- /tests/stdio/write.luau: -------------------------------------------------------------------------------- 1 | local stdio = require("@lune/stdio") 2 | 3 | stdio.write("Hello, stdout!") 4 | -------------------------------------------------------------------------------- /assets/logo/no-tilt-grid.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/assets/logo/no-tilt-grid.ico -------------------------------------------------------------------------------- /assets/logo/no-tilt-grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/assets/logo/no-tilt-grid.png -------------------------------------------------------------------------------- /tests/require/tests/modules/modules/init.luau: -------------------------------------------------------------------------------- 1 | return { 2 | Foo = "Bar", 3 | Hello = "World", 4 | } 5 | -------------------------------------------------------------------------------- /tests/require/tests/modules/modules/module.luau: -------------------------------------------------------------------------------- 1 | return { 2 | Foo = "Bar", 3 | Hello = "World", 4 | } 5 | -------------------------------------------------------------------------------- /tests/require/tests/modules/self_alias/module.luau: -------------------------------------------------------------------------------- 1 | return { 2 | Foo = "Bar", 3 | Hello = "World", 4 | } 5 | -------------------------------------------------------------------------------- /crates/lune-std/src/require/mod.rs: -------------------------------------------------------------------------------- 1 | mod loader; 2 | mod resolver; 3 | 4 | pub(crate) use self::resolver::RequireResolver; 5 | -------------------------------------------------------------------------------- /tests/serde/test-files/loremipsum.txt.z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/tests/serde/test-files/loremipsum.txt.z -------------------------------------------------------------------------------- /tests/serde/test-files/loremipsum.txt.br: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/tests/serde/test-files/loremipsum.txt.br -------------------------------------------------------------------------------- /tests/serde/test-files/loremipsum.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/tests/serde/test-files/loremipsum.txt.gz -------------------------------------------------------------------------------- /tests/serde/test-files/loremipsum.txt.lz4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/tests/serde/test-files/loremipsum.txt.lz4 -------------------------------------------------------------------------------- /tests/serde/test-files/loremipsum.txt.zst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lune-org/lune/HEAD/tests/serde/test-files/loremipsum.txt.zst -------------------------------------------------------------------------------- /crates/lune-std/src/globals/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod g_table; 2 | pub mod print; 3 | pub mod require; 4 | pub mod version; 5 | pub mod warn; 6 | -------------------------------------------------------------------------------- /crates/mlua-luau-scheduler/src/threads/mod.rs: -------------------------------------------------------------------------------- 1 | mod id; 2 | mod map; 3 | 4 | pub use id::ThreadId; 5 | pub(crate) use map::ThreadMap; 6 | -------------------------------------------------------------------------------- /crates/lune-std-net/src/url/mod.rs: -------------------------------------------------------------------------------- 1 | mod decode; 2 | mod encode; 3 | 4 | pub use self::decode::decode; 5 | pub use self::encode::encode; 6 | -------------------------------------------------------------------------------- /tests/require/tests/state_second.luau: -------------------------------------------------------------------------------- 1 | local state_module = require("./state_module") 2 | 3 | state_module.set_state(11) 4 | 5 | return {} 6 | -------------------------------------------------------------------------------- /rokit.toml: -------------------------------------------------------------------------------- 1 | [tools] 2 | luau-lsp = "JohnnyMorganz/luau-lsp@1.54.0" 3 | lune = "lune-org/lune@0.10.4" 4 | stylua = "JohnnyMorganz/StyLua@2.3.0" 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tests/roblox/rbx-test-files"] 2 | path = tests/roblox/rbx-test-files 3 | url = https://github.com/rojo-rbx/rbx-test-files 4 | -------------------------------------------------------------------------------- /crates/mlua-luau-scheduler/examples/lua/callbacks.luau: -------------------------------------------------------------------------------- 1 | --!nocheck 2 | --!nolint UnknownGlobal 3 | 4 | error("Oh no! Something went very very wrong!") 5 | -------------------------------------------------------------------------------- /tests/require/tests/modules/async.luau: -------------------------------------------------------------------------------- 1 | local task = require("@lune/task") 2 | 3 | task.wait(0.25) 4 | 5 | return { 6 | Foo = "Bar", 7 | Hello = "World", 8 | } 9 | -------------------------------------------------------------------------------- /crates/lune-std/src/globals/g_table.rs: -------------------------------------------------------------------------------- 1 | use mlua::prelude::*; 2 | 3 | pub fn create(lua: Lua) -> LuaResult { 4 | lua.create_table()?.into_lua(&lua) 5 | } 6 | -------------------------------------------------------------------------------- /tests/require/tests/state_module.luau: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.state = 10 4 | 5 | function M.set_state(n: number) 6 | M.state = n 7 | end 8 | 9 | return M 10 | -------------------------------------------------------------------------------- /tests/stdio/ewrite.luau: -------------------------------------------------------------------------------- 1 | local process = require("@lune/process") 2 | local stdio = require("@lune/stdio") 3 | 4 | stdio.ewrite("Hello, stderr!") 5 | 6 | process.exit(0) 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | 3 | # Ensure all lua files use LF 4 | *.lua eol=lf 5 | *.luau eol=lf 6 | 7 | # Ensure all txt files within tests use LF 8 | tests/**/*.txt eol=lf 9 | -------------------------------------------------------------------------------- /crates/lune/src/rt/mod.rs: -------------------------------------------------------------------------------- 1 | mod result; 2 | mod runtime; 3 | 4 | pub use self::result::{RuntimeError, RuntimeResult}; 5 | pub use self::runtime::{Runtime, RuntimeReturnValues}; 6 | -------------------------------------------------------------------------------- /tests/net/request/redirect.luau: -------------------------------------------------------------------------------- 1 | local util = require("./util") 2 | local pass = util.pass 3 | 4 | pass("GET", "https://httpbingo.org/absolute-redirect/3", "Redirect 3 times") 5 | -------------------------------------------------------------------------------- /crates/lune-roblox/src/shared/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod instance; 2 | 3 | #[cfg(feature = "mlua")] 4 | pub(crate) mod classes; 5 | 6 | #[cfg(feature = "mlua")] 7 | pub(crate) mod userdata; 8 | -------------------------------------------------------------------------------- /crates/mlua-luau-scheduler/examples/lua/exit_code.luau: -------------------------------------------------------------------------------- 1 | --!nocheck 2 | --!nolint UnknownGlobal 3 | 4 | print("Setting exit code manually") 5 | 6 | exit(1) 7 | 8 | error("unreachable") 9 | -------------------------------------------------------------------------------- /crates/lune-std-net/src/shared/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod futures; 2 | pub mod headers; 3 | pub mod hyper; 4 | pub mod lua; 5 | pub mod request; 6 | pub mod response; 7 | pub mod tcp; 8 | pub mod websocket; 9 | -------------------------------------------------------------------------------- /tests/serde/test-files/uncompressed.csv: -------------------------------------------------------------------------------- 1 | name,age,hobbies,friends 2 | John,30,"reading, writing, coding, 👽","Ξθής, Bob" 3 | Ξθής,28,"painting, hiking, 🦛","" 4 | Bob,35,"fishing, gardening, 🌿","" 5 | -------------------------------------------------------------------------------- /tests/serde/toml/encode.luau: -------------------------------------------------------------------------------- 1 | local serde = require("@lune/serde") 2 | local source = require("./source") 3 | 4 | local str = serde.encode("toml", source.decoded) 5 | assert(str == source.encoded) 6 | -------------------------------------------------------------------------------- /crates/lune/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::cargo_common_metadata)] 2 | 3 | mod rt; 4 | 5 | #[cfg(test)] 6 | mod tests; 7 | 8 | pub use crate::rt::{Runtime, RuntimeError, RuntimeResult, RuntimeReturnValues}; 9 | -------------------------------------------------------------------------------- /tests/globals/warn.luau: -------------------------------------------------------------------------------- 1 | assert(warn ~= nil, "Missing 'warn' global") 2 | assert( 3 | type(warn) == "function", 4 | string.format("Global 'warn' should be a function, got '%s'", tostring(type(warn))) 5 | ) 6 | -------------------------------------------------------------------------------- /tests/net/url/decode.luau: -------------------------------------------------------------------------------- 1 | local net = require("@lune/net") 2 | 3 | local decoded = net.urlDecode("%F0%9F%9A%80%20This%20string%20will%20be%20decoded.") 4 | assert(decoded == "🚀 This string will be decoded.") 5 | -------------------------------------------------------------------------------- /tests/net/url/encode.luau: -------------------------------------------------------------------------------- 1 | local net = require("@lune/net") 2 | 3 | local encoded = net.urlEncode("🚀 This string will be encoded.") 4 | assert(encoded == "%F0%9F%9A%80%20This%20string%20will%20be%20encoded.") 5 | -------------------------------------------------------------------------------- /scripts/format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | stylua .lune crates scripts tests \ 6 | --glob "tests/**/*.luau" \ 7 | --glob "!tests/roblox/rbx-test-files/**" 8 | 9 | cargo fmt 10 | -------------------------------------------------------------------------------- /crates/lune-std-process/src/create/mod.rs: -------------------------------------------------------------------------------- 1 | mod child; 2 | mod child_reader; 3 | mod child_writer; 4 | 5 | pub use self::child::Child; 6 | pub use self::child_reader::ChildReader; 7 | pub use self::child_writer::ChildWriter; 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "rust-lang.rust-analyzer", 4 | "esbenp.prettier-vscode", 5 | "JohnnyMorganz.stylua", 6 | "DavidAnson.vscode-markdownlint" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /crates/mlua-luau-scheduler/src/events/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_imports)] 2 | 3 | mod multi; 4 | mod once; 5 | 6 | pub(crate) use self::multi::{MultiEvent, MultiListener}; 7 | pub(crate) use self::once::{OnceEvent, OnceListener}; 8 | -------------------------------------------------------------------------------- /stylua.toml: -------------------------------------------------------------------------------- 1 | column_width = 100 2 | line_endings = "Unix" 3 | indent_type = "Tabs" 4 | indent_width = 4 5 | quote_style = "AutoPreferDouble" 6 | call_parentheses = "Always" 7 | 8 | [sort_requires] 9 | enabled = true 10 | -------------------------------------------------------------------------------- /tests/datetime/now.luau: -------------------------------------------------------------------------------- 1 | local DateTime = require("@lune/datetime") 2 | 3 | local TYPE = "DateTime" 4 | 5 | local now = DateTime.now() 6 | 7 | assert(typeof(now) == TYPE, `dateTime.now() should return a {TYPE}, returned {typeof(now)}`) 8 | -------------------------------------------------------------------------------- /crates/lune-utils/src/fmt/error/mod.rs: -------------------------------------------------------------------------------- 1 | mod components; 2 | mod stack_trace; 3 | 4 | #[cfg(test)] 5 | mod tests; 6 | 7 | pub use self::components::ErrorComponents; 8 | pub use self::stack_trace::{StackTrace, StackTraceLine, StackTraceSource}; 9 | -------------------------------------------------------------------------------- /scripts/format-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | stylua .lune crates scripts tests \ 6 | --glob "tests/**/*.luau" \ 7 | --glob "!tests/roblox/rbx-test-files/**" \ 8 | --check 9 | 10 | cargo fmt --check 11 | -------------------------------------------------------------------------------- /crates/lune-std/src/globals/require.rs: -------------------------------------------------------------------------------- 1 | use mlua::prelude::*; 2 | 3 | use crate::require::RequireResolver; 4 | 5 | pub fn create(lua: Lua) -> LuaResult { 6 | lua.create_require_function(RequireResolver::new()) 7 | .map(LuaValue::Function) 8 | } 9 | -------------------------------------------------------------------------------- /crates/mlua-luau-scheduler/src/queue/mod.rs: -------------------------------------------------------------------------------- 1 | mod deferred; 2 | mod futures; 3 | mod spawned; 4 | mod threads; 5 | 6 | pub(crate) use self::deferred::DeferredThreadQueue; 7 | pub(crate) use self::futures::FuturesQueue; 8 | pub(crate) use self::spawned::SpawnedThreadQueue; 9 | -------------------------------------------------------------------------------- /tests/serde/jsonc/source.luau: -------------------------------------------------------------------------------- 1 | local JSON_STRING = [[{ 2 | "Foo": "Bar", // Baz ?!? 3 | "Hello": "World", 4 | "Inner": { 5 | "Array": [ 6 | 1, 7 | 3, 8 | 2 9 | ] 10 | } 11 | }]] 12 | 13 | return { 14 | encoded = JSON_STRING, 15 | } 16 | -------------------------------------------------------------------------------- /crates/lune-utils/src/fmt/mod.rs: -------------------------------------------------------------------------------- 1 | mod error; 2 | mod label; 3 | mod value; 4 | 5 | pub use self::error::{ErrorComponents, StackTrace, StackTraceLine, StackTraceSource}; 6 | pub use self::label::Label; 7 | pub use self::value::{ValueFormatConfig, pretty_format_multi_value, pretty_format_value}; 8 | -------------------------------------------------------------------------------- /crates/mlua-luau-scheduler/examples/lua/basic_sleep.luau: -------------------------------------------------------------------------------- 1 | --!nocheck 2 | --!nolint UnknownGlobal 3 | 4 | print("Sleeping for 3 seconds...") 5 | 6 | sleep(1) 7 | print("1 second passed") 8 | 9 | sleep(1) 10 | print("2 seconds passed") 11 | 12 | sleep(1) 13 | print("3 seconds passed") 14 | -------------------------------------------------------------------------------- /scripts/analyze.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | lune run scripts/analyze_copy_typedefs 6 | 7 | luau-lsp analyze \ 8 | --platform=standard \ 9 | --settings=".vscode/settings.json" \ 10 | --ignore="tests/roblox/rbx-test-files/**" \ 11 | .lune crates scripts tests 12 | -------------------------------------------------------------------------------- /crates/lune-utils/src/path/constants.rs: -------------------------------------------------------------------------------- 1 | /*! 2 | Constants for working with Luau module paths. 3 | */ 4 | 5 | pub const FILE_CHUNK_PREFIX: char = '@'; 6 | pub const FILE_NAME_INIT: &str = "init"; 7 | pub const FILE_NAME_CONFIG: &str = ".luaurc"; 8 | pub const FILE_EXTENSIONS: [&str; 2] = ["luau", "lua"]; 9 | -------------------------------------------------------------------------------- /tests/serde/toml/decode.luau: -------------------------------------------------------------------------------- 1 | local serde = require("@lune/serde") 2 | local source = require("./source") 3 | 4 | local toml = serde.decode("toml", source.encoded) 5 | 6 | assert(toml.package.name == "my-cool-toml-package") 7 | assert(toml.package.version == "0.1.0") 8 | assert(toml.values.epic == true) 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | 9 | [*.{json,jsonc,json5}] 10 | indent_style = space 11 | indent_size = 4 12 | 13 | [*.{yml,yaml,md}] 14 | indent_style = space 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /tests/process/exec/no_panic.luau: -------------------------------------------------------------------------------- 1 | local process = require("@lune/process") 2 | 3 | -- Executing a non existent command as a child process 4 | -- should not panic, but should error 5 | 6 | local success = pcall(process.exec, "someProgramThatDoesNotExist") 7 | assert(not success, "Spawned a non-existent program") 8 | -------------------------------------------------------------------------------- /crates/lune-std-net/src/body/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_imports)] 2 | 3 | mod cursor; 4 | mod incoming; 5 | mod inner; 6 | mod readable; 7 | 8 | pub use self::cursor::ReadableBodyCursor; 9 | pub use self::incoming::handle_incoming_body; 10 | pub use self::inner::ReadableBodyInner; 11 | pub use self::readable::ReadableBody; 12 | -------------------------------------------------------------------------------- /.luaurc: -------------------------------------------------------------------------------- 1 | { 2 | "languageMode": "strict", 3 | "lint": { 4 | "*": true 5 | }, 6 | "lintErrors": false, 7 | "typeErrors": true, 8 | "globals": [ 9 | "warn" 10 | ], 11 | "aliases": { 12 | "lune": "./types/", 13 | "tests": "./tests", 14 | "require-tests": "./tests/require/tests" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/require/tests/parents.luau: -------------------------------------------------------------------------------- 1 | local module = require("../modules/module") 2 | 3 | assert(type(module) == "table", "Required module did not return a table") 4 | assert(module.Foo == "Bar", "Required module did not contain correct values") 5 | assert(module.Hello == "World", "Required module did not contain correct values") 6 | 7 | return true 8 | -------------------------------------------------------------------------------- /crates/lune-utils/src/path/mod.rs: -------------------------------------------------------------------------------- 1 | mod luau; 2 | mod std; 3 | 4 | pub mod constants; 5 | 6 | pub use self::std::{ 7 | append_extension, clean_path, clean_path_and_make_absolute, get_current_dir, get_current_exe, 8 | relative_path_normalize, relative_path_parent, 9 | }; 10 | 11 | pub use self::luau::{LuauFilePath, LuauModulePath}; 12 | -------------------------------------------------------------------------------- /tests/net/request/codes.luau: -------------------------------------------------------------------------------- 1 | local util = require("./util") 2 | local pass, fail = util.pass, util.fail 3 | 4 | pass("GET", "https://httpbingo.org/status/200", "Request status code - 200") 5 | fail("GET", "https://httpbingo.org/status/400", "Request status code - 400") 6 | fail("GET", "https://httpbingo.org/status/500", "Request status code - 500") 7 | -------------------------------------------------------------------------------- /tests/task/fcheck.luau: -------------------------------------------------------------------------------- 1 | local stdio = require("@lune/stdio") 2 | 3 | return function(index: number, type: string, value: any) 4 | if typeof(value) ~= type then 5 | error( 6 | string.format( 7 | "Expected argument #%d to be of type %s, got %s", 8 | index, 9 | type, 10 | stdio.format(value) 11 | ) 12 | ) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /tests/datetime/fromRfc3339.luau: -------------------------------------------------------------------------------- 1 | local DateTime = require("@lune/datetime") 2 | 3 | assert( 4 | DateTime.fromRfc3339("2023-08-26T16:56:28Z") ~= nil, 5 | "expected DateTime.fromRfc3339() to return DateTime, got nil" 6 | ) 7 | 8 | assert( 9 | DateTime.fromRfc3339("1929-12-05T23:18:23Z") ~= nil, 10 | "expected DateTime.fromRfc3339() to return DateTime, got nil" 11 | ) 12 | -------------------------------------------------------------------------------- /tests/process/create/non_blocking.luau: -------------------------------------------------------------------------------- 1 | local process = require("@lune/process") 2 | 3 | local childThread = coroutine.create(process.create) 4 | 5 | local ok, err = coroutine.resume(childThread, "echo", { "hello, world" }) 6 | assert(ok, err) 7 | 8 | assert( 9 | coroutine.status(childThread) == "dead", 10 | "Child process should not yield the thread it is created on" 11 | ) 12 | -------------------------------------------------------------------------------- /scripts/get-version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Since we are using cargo workspaces, reading the actual version 4 | # of the CLI is slightly more complicated - which is why this exists 5 | 6 | set -euo pipefail 7 | 8 | CLI_MANIFEST=$(cargo read-manifest --manifest-path crates/lune/Cargo.toml) 9 | CLI_VERSION=$(echo $CLI_MANIFEST | jq -r .version) 10 | 11 | echo $CLI_VERSION 12 | -------------------------------------------------------------------------------- /tests/serde/json/source.luau: -------------------------------------------------------------------------------- 1 | local JSON_STRING = [[{"Foo":"Bar","Hello":"World","Inner":{"Array":[1,3,2]}}]] 2 | 3 | local JSON_STRING_PRETTY = [[{ 4 | "Foo": "Bar", 5 | "Hello": "World", 6 | "Inner": { 7 | "Array": [ 8 | 1, 9 | 3, 10 | 2 11 | ] 12 | } 13 | }]] 14 | 15 | return { 16 | encoded = JSON_STRING, 17 | pretty = JSON_STRING_PRETTY, 18 | } 19 | -------------------------------------------------------------------------------- /tests/datetime/fromRfc2822.luau: -------------------------------------------------------------------------------- 1 | local DateTime = require("@lune/datetime") 2 | 3 | assert( 4 | DateTime.fromRfc2822("Fri, 21 Nov 1997 09:55:06 -0600") ~= nil, 5 | "expected DateTime.fromRfcDate() to return DateTime, got nil" 6 | ) 7 | 8 | assert( 9 | DateTime.fromRfc2822("Tue, 1 Jul 2003 10:52:37 +0200") ~= nil, 10 | "expected DateTime.fromRfcDate() to return DateTime, got nil" 11 | ) 12 | -------------------------------------------------------------------------------- /scripts/analyze_copy_typedefs.luau: -------------------------------------------------------------------------------- 1 | local fs = require("@lune/fs") 2 | 3 | fs.writeDir("./types") 4 | 5 | for _, dir in fs.readDir("./crates") do 6 | local std = string.match(dir, "^lune%-std%-(%w+)$") 7 | if std ~= nil then 8 | local from = `./crates/{dir}/types.d.luau` 9 | if fs.isFile(from) then 10 | local to = `./types/{std}.luau` 11 | fs.copy(from, to, true) 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /tests/serde/test-files/uncompressed.yaml: -------------------------------------------------------------------------------- 1 | - name: John 2 | age: 30 3 | hobbies: 4 | - reading 5 | - writing 6 | - coding 7 | - 👽 8 | friends: 9 | - name: Ξθής 10 | age: 28 11 | hobbies: 12 | - painting 13 | - hiking 14 | - 🦛 15 | - name: Bob 16 | age: 35 17 | hobbies: 18 | - fishing 19 | - gardening 20 | - 🌿 21 | -------------------------------------------------------------------------------- /tests/require/tests/siblings.luau: -------------------------------------------------------------------------------- 1 | local module = require("./module") 2 | 3 | assert(type(module) == "table", "Required module did not return a table") 4 | assert(module.Foo == "Bar", "Required module did not contain correct values") 5 | assert(module.Hello == "World", "Required module did not contain correct values") 6 | 7 | require("./children") 8 | require("./parents") 9 | 10 | require("./children") 11 | require("./parents") 12 | -------------------------------------------------------------------------------- /crates/mlua-luau-scheduler/examples/lua/basic_spawn.luau: -------------------------------------------------------------------------------- 1 | --!nocheck 2 | --!nolint UnknownGlobal 3 | 4 | local _, err = pcall(function() 5 | local file = readFile("Cargo.toml") 6 | if file ~= nil then 7 | print("Cargo.toml found!") 8 | print("Contents:") 9 | print(file) 10 | else 11 | print("Cargo.toml not found!") 12 | end 13 | end) 14 | 15 | if err ~= nil then 16 | print("Error while reading file: " .. err) 17 | end 18 | -------------------------------------------------------------------------------- /crates/lune-utils/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::cargo_common_metadata)] 2 | 3 | mod table_builder; 4 | mod version_string; 5 | 6 | pub mod fmt; 7 | pub mod path; 8 | pub mod process; 9 | 10 | pub use self::table_builder::TableBuilder; 11 | pub use self::version_string::get_version_string; 12 | 13 | // TODO: Remove this in the next major semver 14 | pub mod jit { 15 | pub use super::process::ProcessJitEnablement as JitEnablement; 16 | } 17 | -------------------------------------------------------------------------------- /crates/lune-std-net/src/url/encode.rs: -------------------------------------------------------------------------------- 1 | use mlua::prelude::*; 2 | 3 | pub fn encode(lua_string: LuaString, as_binary: bool) -> LuaResult> { 4 | if as_binary { 5 | Ok(urlencoding::encode_binary(&lua_string.as_bytes()) 6 | .into_owned() 7 | .into_bytes()) 8 | } else { 9 | Ok(urlencoding::encode(&lua_string.to_str()?) 10 | .into_owned() 11 | .into_bytes()) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/roblox/instance/methods/GetDebugId.luau: -------------------------------------------------------------------------------- 1 | local roblox = require("@lune/roblox") 2 | 3 | local part = roblox.Instance.new("Part") 4 | 5 | local id = part:GetDebugId() 6 | assert(type(id) == "string", "GetDebugId should return a string") 7 | assert(#id == 32, "GetDebugId should return a string with length 32") 8 | assert( 9 | string.match(id, "^[0-9A-Fa-f]+$"), 10 | "GetDebugId should return a string with only hexadecimal characters" 11 | ) 12 | -------------------------------------------------------------------------------- /crates/mlua-luau-scheduler/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::cargo_common_metadata)] 2 | 3 | mod error_callback; 4 | mod events; 5 | mod exit; 6 | mod functions; 7 | mod queue; 8 | mod scheduler; 9 | mod status; 10 | mod threads; 11 | mod traits; 12 | mod util; 13 | 14 | pub use functions::Functions; 15 | pub use scheduler::Scheduler; 16 | pub use status::Status; 17 | pub use threads::ThreadId; 18 | pub use traits::{IntoLuaThread, LuaSchedulerExt, LuaSpawnExt}; 19 | -------------------------------------------------------------------------------- /tests/net/request/user_agent.luau: -------------------------------------------------------------------------------- 1 | local net = require("@lune/net") 2 | local serde = require("@lune/serde") 3 | 4 | local runtime, version = table.unpack(_VERSION:split(" ")) 5 | local expectedUserAgent = runtime:lower() .. "/" .. version 6 | 7 | local userAgent: string = 8 | serde.decode("json", net.request("https://www.whatsmyua.info/api/v1/ua").body)[1].ua.rawUa 9 | 10 | assert(userAgent == expectedUserAgent, "Expected user agent to be " .. expectedUserAgent) 11 | -------------------------------------------------------------------------------- /tests/require/tests/modules/self_alias/init.luau: -------------------------------------------------------------------------------- 1 | local inner = require("@self/module") 2 | local outer = require("./module") 3 | 4 | assert(type(outer) == "table", "Outer module is not a table") 5 | assert(type(inner) == "table", "Inner module is not a table") 6 | 7 | assert(outer.Foo == inner.Foo, "Outer and inner modules have different Foo values") 8 | assert(inner.Hello == outer.Hello, "Outer and inner modules have different Hello values") 9 | 10 | return inner 11 | -------------------------------------------------------------------------------- /tests/serde/test-files/uncompressed.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "John", 3 | "age": 30, 4 | "hobbies": ["reading", "writing", "coding", "👽"], 5 | "friends": [ 6 | { 7 | "name": "Ξθής", 8 | "age": 28, 9 | "hobbies": ["painting", "hiking", "🦛"] 10 | }, 11 | { 12 | "name": "Bob", 13 | "age": 35, 14 | "hobbies": ["fishing", "gardening", "🌿"] 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /crates/lune-std-luau/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lune-std-luau" 3 | version = "0.3.4" 4 | edition = "2024" 5 | license = "MPL-2.0" 6 | repository = "https://github.com/lune-org/lune" 7 | description = "Lune standard library - Luau" 8 | 9 | [lib] 10 | path = "src/lib.rs" 11 | 12 | [lints] 13 | workspace = true 14 | 15 | [dependencies] 16 | mlua = { version = "0.11.4", features = ["luau", "luau-jit"] } 17 | 18 | lune-utils = { version = "0.3.4", path = "../lune-utils" } 19 | -------------------------------------------------------------------------------- /tests/serde/json/encode.luau: -------------------------------------------------------------------------------- 1 | local serde = require("@lune/serde") 2 | local source = require("./source") 3 | 4 | local decoded = serde.decode("json", source.pretty) 5 | local encoded = serde.encode("json", decoded, false) 6 | assert(encoded == source.encoded, "JSON round-trip did not produce the same result") 7 | 8 | local encodedPretty = serde.encode("json", decoded, true) 9 | assert(encodedPretty == source.pretty, "JSON round-trip did not produce the same result (pretty)") 10 | -------------------------------------------------------------------------------- /tests/fs/utils.luau: -------------------------------------------------------------------------------- 1 | local serde = require("@lune/serde") 2 | 3 | -- Generate testing data 4 | 5 | local binaryBlob = "" 6 | for _ = 1, 1024 do 7 | binaryBlob ..= string.char(math.random(1, 127)) 8 | end 9 | 10 | local jsonBlob = serde.encode("json", { 11 | Foo = "Bar", 12 | Hello = "World", 13 | Inner = { Array = { 1, 2, 3 } }, 14 | }, true) 15 | 16 | -- Return testing data and utils 17 | 18 | return { 19 | binaryBlob = buffer.fromstring(binaryBlob), 20 | jsonBlob = jsonBlob, 21 | } 22 | -------------------------------------------------------------------------------- /tests/net/request/methods.luau: -------------------------------------------------------------------------------- 1 | local util = require("./util") 2 | local pass = util.pass 3 | 4 | -- stylua: ignore start 5 | pass("GET", "https://httpbingo.org/get", "Request method - GET") 6 | pass("POST", "https://httpbingo.org/post", "Request method - POST") 7 | pass("PATCH", "https://httpbingo.org/patch", "Request method - PATCH") 8 | pass("PUT", "https://httpbingo.org/put", "Request method - PUT") 9 | pass("DELETE", "https://httpbingo.org/delete", "Request method - DELETE") 10 | -------------------------------------------------------------------------------- /crates/lune-std-net/src/url/decode.rs: -------------------------------------------------------------------------------- 1 | use mlua::prelude::*; 2 | 3 | pub fn decode(lua_string: LuaString, as_binary: bool) -> LuaResult> { 4 | if as_binary { 5 | Ok(urlencoding::decode_binary(&lua_string.as_bytes()).into_owned()) 6 | } else { 7 | Ok(urlencoding::decode(&lua_string.to_str()?) 8 | .map_err(|e| LuaError::RuntimeError(format!("Encountered invalid encoding - {e}")))? 9 | .into_owned() 10 | .into_bytes()) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/process/cwd.luau: -------------------------------------------------------------------------------- 1 | local process = require("@lune/process") 2 | 3 | assert(process.cwd ~= nil, "Process cwd is missing") 4 | 5 | assert(type(process.cwd) == "string", "Process cwd is not a string") 6 | 7 | assert(#process.cwd > 0, "Process cwd is an empty string") 8 | 9 | if process.os == "windows" then 10 | assert(string.sub(process.cwd, -1) == "\\", "Process cwd does not end with '\\'") 11 | else 12 | assert(string.sub(process.cwd, -1) == "/", "Process cwd does not end with '/'") 13 | end 14 | -------------------------------------------------------------------------------- /tests/serde/toml/source.luau: -------------------------------------------------------------------------------- 1 | local TOML_LINES = { 2 | "[package]", 3 | 'name = "my-cool-toml-package"', 4 | 'version = "0.1.0"', 5 | "", 6 | "[values]", 7 | "epic = true", 8 | "", 9 | } 10 | 11 | local TOML_STRING = table.concat(TOML_LINES, "\n") 12 | 13 | local TOML_TABLE = { 14 | package = { 15 | name = "my-cool-toml-package", 16 | version = "0.1.0", 17 | }, 18 | values = { 19 | epic = true, 20 | }, 21 | } 22 | 23 | return { 24 | encoded = TOML_STRING, 25 | decoded = TOML_TABLE, 26 | } 27 | -------------------------------------------------------------------------------- /crates/lune-std-regex/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lune-std-regex" 3 | version = "0.3.4" 4 | edition = "2024" 5 | license = "MPL-2.0" 6 | repository = "https://github.com/lune-org/lune" 7 | description = "Lune standard library - RegEx" 8 | 9 | [lib] 10 | path = "src/lib.rs" 11 | 12 | [lints] 13 | workspace = true 14 | 15 | [dependencies] 16 | mlua = { version = "0.11.4", features = ["luau"] } 17 | 18 | regex = "1.10" 19 | self_cell = "1.0" 20 | 21 | lune-utils = { version = "0.3.4", path = "../lune-utils" } 22 | -------------------------------------------------------------------------------- /tests/serde/jsonc/encode.luau: -------------------------------------------------------------------------------- 1 | local serde = require("@lune/serde") 2 | local source = require("./source") 3 | 4 | -- NOTE: Our json format (intentionally) does not round-trip or keep 5 | -- comments, so we will strip those for the purposes of this test 6 | local original = string.gsub(source.encoded, "%s*//[^\n]+", "") 7 | 8 | local decoded = serde.decode("jsonc", original) 9 | local encoded = serde.encode("jsonc", decoded, true) 10 | assert(encoded == original, "JSONC round-trip did not produce the same result") 11 | -------------------------------------------------------------------------------- /crates/lune-utils/src/fmt/value/style.rs: -------------------------------------------------------------------------------- 1 | use std::sync::LazyLock; 2 | 3 | use console::Style; 4 | 5 | pub static COLOR_GREEN: LazyLock