Standard Library
The @metascript/core package provides cross-platform utilities that work on all backends.
Installation
npm install @metascript/coreModules
fs (File System)
Cross-platform file system operations.
import { fs } from "@metascript/core"
// Read file
const content = await fs.readFile("config.json", "utf-8")
// Write file
await fs.writeFile("output.txt", "Hello, World!")
// Check existence
if (await fs.exists("file.txt")) {
// ...
}
// Read directory
const entries = await fs.readdir("src/")
for (const entry of entries) {
console.log(entry.name, entry.isFile())
}
// Walk directory recursively
for await (const entry of fs.walk("src/")) {
console.log(entry.path)
}
// Create directory
await fs.mkdir("dist/", { recursive: true })
// Remove file/directory
await fs.remove("temp/")
// Copy
await fs.copy("src/", "backup/")
// Move/rename
await fs.move("old.txt", "new.txt")
// File stats
const stats = await fs.stat("file.txt")
console.log(stats.size, stats.mtime)path
Path manipulation utilities.
import { path } from "@metascript/core"
// Join paths
const full = path.join("src", "components", "Button.ms")
// => "src/components/Button.ms"
// Resolve absolute path
const abs = path.resolve("./src/main.ms")
// => "/Users/me/project/src/main.ms"
// Get parts
path.basename("/src/file.ms") // "file.ms"
path.dirname("/src/file.ms") // "/src"
path.extname("/src/file.ms") // ".ms"
// Parse path
const parsed = path.parse("/src/file.ms")
// { root: "/", dir: "/src", base: "file.ms", ext: ".ms", name: "file" }
// Normalize
path.normalize("/src/../lib/./utils")
// => "/lib/utils"
// Relative path
path.relative("/src/components", "/src/utils")
// => "../utils"http
HTTP client for making requests.
import { http } from "@metascript/core"
// GET request
const response = await http.get("https://api.example.com/users")
const users = await response.json()
// POST request
const created = await http.post("https://api.example.com/users", {
body: JSON.stringify({ name: "Alice" }),
headers: {
"Content-Type": "application/json",
},
})
// With options
const response = await http.request("https://api.example.com/data", {
method: "PUT",
body: data,
headers: { Authorization: `Bearer ${token}` },
timeout: 5000,
})
// Streaming response
const stream = await http.get("https://example.com/large-file", {
stream: true,
})
for await (const chunk of stream.body) {
process.stdout.write(chunk)
}env
Environment variable access.
import { env } from "@metascript/core"
// Get variable
const port = env.get("PORT", "3000")
// Required variable (throws if missing)
const secret = env.require("API_SECRET")
// Check existence
if (env.has("DEBUG")) {
// ...
}
// All variables
const all = env.all()
// Set variable (for current process)
env.set("MY_VAR", "value")process
Process utilities.
import { process } from "@metascript/core"
// Command line arguments
const args = process.argv
// Current working directory
const cwd = process.cwd()
// Exit
process.exit(0)
// Environment info
console.log(process.platform) // "darwin" | "linux" | "win32"
console.log(process.arch) // "x64" | "arm64"
// Standard streams
process.stdout.write("Hello")
process.stderr.write("Error")
const input = await process.stdin.read()
// Signals
process.on("SIGINT", () => {
console.log("Interrupted")
process.exit(0)
})crypto
Cryptographic utilities.
import { crypto } from "@metascript/core"
// Hash
const hash = crypto.hash("sha256", "hello")
// => "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
// HMAC
const hmac = crypto.hmac("sha256", "secret", "message")
// Random bytes
const bytes = crypto.randomBytes(32)
// Random UUID
const id = crypto.randomUUID()
// => "550e8400-e29b-41d4-a716-446655440000"
// Encrypt/Decrypt
const encrypted = crypto.encrypt("aes-256-gcm", key, plaintext)
const decrypted = crypto.decrypt("aes-256-gcm", key, encrypted)json
JSON utilities with type safety.
import { json } from "@metascript/core"
// Parse with type
const user = json.parse<User>(text)
// Returns Result<User, ParseError>
// Parse with validation
@derive(Serialize, Deserialize)
class User {
name: string
email: string
}
const result = json.parse(text, User)
if (result.ok) {
console.log(result.value.name)
} else {
console.error(result.error)
}
// Stringify with options
const text = json.stringify(data, {
indent: 2,
sortKeys: true,
})time
Time and date utilities.
import { time } from "@metascript/core"
// Current time
const now = time.now()
// Timestamps
const unix = time.unix() // seconds
const millis = time.millis() // milliseconds
// Sleep
await time.sleep(1000) // 1 second
// Measure duration
const start = time.now()
await doWork()
const elapsed = time.since(start)
console.log(`Took ${elapsed}ms`)
// Formatting
const formatted = time.format(now, "YYYY-MM-DD HH:mm:ss")
// Parsing
const date = time.parse("2024-01-15", "YYYY-MM-DD")Result and Option
Functional error handling.
import { Result, Option, Ok, Err, Some, None } from "@metascript/core"
// Result type
function divide(a: number, b: number): Result<number, string> {
if (b === 0) {
return Err("Division by zero")
}
return Ok(a / b)
}
const result = divide(10, 2)
if (result.ok) {
console.log(result.value)
} else {
console.error(result.error)
}
// Chaining
const doubled = divide(10, 2)
.map(x => x * 2)
.mapErr(e => `Error: ${e}`)
// Option type
function find(arr: number[], pred: (n: number) => boolean): Option<number> {
for (const item of arr) {
if (pred(item)) return Some(item)
}
return None
}
const found = find([1, 2, 3], x => x > 2)
if (found.some) {
console.log(found.value)
}
// Unwrap with default
const value = found.unwrapOr(0)collections
Advanced data structures.
import { Vec, HashMap, HashSet, Queue, Stack } from "@metascript/core"
// Vec (resizable array)
const vec = new Vec<number>()
vec.push(1, 2, 3)
vec.pop()
console.log(vec.get(0))
// HashMap with custom hash
const map = new HashMap<User, number>()
map.set(user, 42)
console.log(map.get(user))
// HashSet
const set = new HashSet<string>()
set.add("a")
set.add("b")
console.log(set.has("a"))
// Queue (FIFO)
const queue = new Queue<string>()
queue.enqueue("first")
queue.enqueue("second")
console.log(queue.dequeue()) // "first"
// Stack (LIFO)
const stack = new Stack<string>()
stack.push("first")
stack.push("second")
console.log(stack.pop()) // "second"testing
Test utilities.
import { test, expect, describe, beforeEach, mock } from "@metascript/core"
describe("Calculator", () => {
let calc: Calculator
beforeEach(() => {
calc = new Calculator()
})
test("adds numbers", () => {
expect(calc.add(1, 2)).toBe(3)
})
test("handles async", async () => {
const result = await calc.fetchAndAdd(1)
expect(result).toBeGreaterThan(0)
})
})
// Mocking
const mockFetch = mock.fn(() => Promise.resolve({ data: [] }))
mock.module("./api", { fetch: mockFetch })
// Assertions
expect(value).toBe(expected)
expect(value).toEqual(expected)
expect(value).toBeTruthy()
expect(value).toBeFalsy()
expect(fn).toThrow(Error)
expect(array).toContain(item)
expect(object).toHaveProperty("key")Next Steps
- Language Reference - Syntax guide
- Configuration - Project settings
- CLI Commands - Compiler commands