بنقرة واحدة
deno-script
// Write or modify Cataclysm-BN Deno/TypeScript scripts. Use for scripts, tools, migrations, generators, git hooks, and CLI utilities.
// Write or modify Cataclysm-BN Deno/TypeScript scripts. Use for scripts, tools, migrations, generators, git hooks, and CLI utilities.
| name | deno-script |
| description | Write or modify Cataclysm-BN Deno/TypeScript scripts. Use for scripts, tools, migrations, generators, git hooks, and CLI utilities. |
Write Deno/TypeScript scripts following Cataclysm: Bright Nights conventions.
Start scripts with the proper shebang and required permissions:
#!/usr/bin/env -S deno run --allow-read --allow-write --allow-run --allow-env
Common permission flags:
--allow-read - File system read access--allow-write - File system write access--allow-run - Run subprocesses--allow-env - Access environment variables--allow-net - Network access (only if needed)Add a module-level JSDoc comment explaining the script's purpose:
/**
* @module
*
* Brief description of what this script does
*
* Longer explanation if needed with examples or usage notes.
*/
This pattern is used in existing scripts like:
scripts/gen_cli_docs.tsscripts/utils.tsscripts/affected_files.tsUse JSR imports for standard library and well-known packages:
import { Command } from "@cliffy/command"
import { exists } from "@std/fs"
import { join } from "@std/path"
import { partition } from "@std/collections"
import * as v from "@valibot/valibot"
DO NOT use npm or http imports unless absolutely necessary. Prefer JSR.
For data validation, use Valibot (NOT Zod):
import * as v from "@valibot/valibot"
const MySchema = v.object({
name: v.string(),
count: v.pipe(v.number(), v.minValue(0)),
tags: v.array(v.string()),
})
type MyType = v.InferOutput<typeof MySchema>
const parser = v.safeParser(MySchema)
const result = parser(data)
if (result.success) {
const validated = result.output
}
For command-line interfaces, use Cliffy:
import { Command } from "@cliffy/command"
const main = new Command()
.name("script-name")
.version("1.0.0")
.description("What this script does")
.option("-o, --output <file>", "Output file path")
.arguments("<input:string>")
.action(async ({ output }, input) => {
// Implementation
})
if (import.meta.main) {
await main.parse(Deno.args)
}
Use @std/fs for file system operations:
import { exists, walk } from "@std/fs"
import { basename, join } from "@std/path"
if (await exists("path/to/file")) {
const content = await Deno.readTextFile("path/to/file")
}
for await (const entry of walk("src", { exts: [".ts"] })) {
console.log(entry.path)
}
Use Deno.Command for subprocesses:
const cmd = new Deno.Command("git", {
args: ["status"],
stdout: "piped",
stderr: "piped",
})
const { success, stdout, stderr } = await cmd.output()
if (success) {
const output = new TextDecoder().decode(stdout)
}
Handle errors with proper types:
try {
await someOperation()
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
console.error(`Error: ${message}`)
Deno.exit(1)
}
Define colors as utility functions:
const colors = {
red: (text: string) => `\x1b[31m${text}\x1b[0m`,
yellow: (text: string) => `\x1b[33m${text}\x1b[0m`,
green: (text: string) => `\x1b[32m${text}\x1b[0m`,
dim: (text: string) => `\x1b[2m${text}\x1b[0m`,
}
console.log(colors.green("Success!"))
console.warn(colors.yellow("[WARNING] Something happened"))
console.error(colors.red("[ERROR] Failed"))
Look at these existing scripts for patterns:
scripts/gen_cli_docs.ts
scripts/utils.ts
scripts/affected_files.ts
tools/hooks/pre-commit.ts
tools/hooks/install-hooks.ts
Scripts location:
scripts/tools/tools/hooks/Before submitting:
deno check your-script.ts
deno fmt your-script.ts
deno lint your-script.ts
Make the script executable:
chmod +x your-script.ts
Add to deno.jsonc tasks if the script should be easily runnable:
{
"tasks": {
"your-task": "deno run --allow-... scripts/your-script.ts"
}
}
#!/usr/bin/env -S deno run [permissions]@module JSDoc commentdeno check before considering completechmod +x)if (import.meta.main) guard for executable scriptsdeno check and deno fmt@ts-ignore or @ts-expect-errorconst commandExists = async (cmd: string): Promise<boolean> => {
try {
const process = new Deno.Command("command", {
args: ["-v", cmd],
stdout: "piped",
stderr: "piped",
})
const { success } = await process.output()
return success
} catch {
return false
}
}
const getRepoRoot = async (): Promise<string> => {
const cmd = new Deno.Command("git", {
args: ["rev-parse", "--show-toplevel"],
stdout: "piped",
})
const { stdout } = await cmd.output()
return new TextDecoder().decode(stdout).trim()
}
import { walk } from "@std/fs"
for await (const entry of walk("data", { exts: [".json"] })) {
const content = await Deno.readTextFile(entry.path)
const data = JSON.parse(content)
// Process data
}
const results = await Promise.all([
operation1(),
operation2(),
operation3(),
])
Use Deno scripts for:
Don't use Deno scripts for:
Rewrite every `docs/*/game/changelog/{order}.stable-{semver}.md` from a ref range. Default `--limit=20`.
Add Cataclysm-BN Lua API bindings for global game functions, utility libraries, constants, callbacks, and domain-specific Lua namespaces.
Add comprehensive Cataclysm-BN Lua bindings for complex C++ classes with methods, inheritance, constructors, properties, operators, and ownership rules.
Add simple Cataclysm-BN Lua bindings for string_id types, enums, and basic read-only C++ types. Use when exposing straightforward C++ types to Lua.
Quick reference for Cataclysm-BN Lua binding macros, Luna usertypes, libraries, documentation, type patterns, build steps, and common errors.
Add gettext context for ambiguous user-facing strings and repair affected PO translations.