wuira 0.0.0-stage → 0.1.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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +254 -2
  3. package/cli/wuira.mjs +67 -0
  4. package/config/tsconfig.json +25 -0
  5. package/lib/Console.d.ts +5 -0
  6. package/lib/Console.lua +20 -0
  7. package/lib/console-polyfill.d.ts +9 -0
  8. package/lib/console-polyfill.lua +39 -0
  9. package/lib/datasources/DataSource.d.ts +17 -0
  10. package/lib/datasources/DataSource.lua +199 -0
  11. package/lib/datasources/NativeNumberSource.d.ts +7 -0
  12. package/lib/datasources/NativeNumberSource.lua +50 -0
  13. package/lib/datasources/ProgressSource.d.ts +23 -0
  14. package/lib/datasources/ProgressSource.lua +79 -0
  15. package/lib/datasources/Resources.d.ts +27 -0
  16. package/lib/datasources/Resources.lua +102 -0
  17. package/lib/datasources/index.d.ts +4 -0
  18. package/lib/datasources/index.lua +18 -0
  19. package/lib/index.d.ts +4 -0
  20. package/lib/index.lua +11 -0
  21. package/lib/platform/forever.d.ts +62 -0
  22. package/lib/types/Anchor.d.ts +6 -0
  23. package/lib/types/Anchor.lua +8 -0
  24. package/lib/types/Color.d.ts +6 -0
  25. package/lib/types/Color.lua +3 -0
  26. package/lib/types/Position.d.ts +21 -0
  27. package/lib/types/Position.lua +3 -0
  28. package/lib/types/Spacing.d.ts +14 -0
  29. package/lib/types/Spacing.lua +20 -0
  30. package/lib/types/Texture.d.ts +11 -0
  31. package/lib/types/Texture.lua +3 -0
  32. package/lib/ui/Cell.d.ts +21 -0
  33. package/lib/ui/Cell.lua +8 -0
  34. package/lib/ui/FlowLayout.d.ts +18 -0
  35. package/lib/ui/FlowLayout.lua +8 -0
  36. package/lib/ui/GridLayout.d.ts +19 -0
  37. package/lib/ui/GridLayout.lua +8 -0
  38. package/lib/ui/Layout.d.ts +10 -0
  39. package/lib/ui/Layout.lua +3 -0
  40. package/lib/ui/ProgressBar.d.ts +32 -0
  41. package/lib/ui/ProgressBar.lua +8 -0
  42. package/lib/ui/decorations/Background.d.ts +10 -0
  43. package/lib/ui/decorations/Background.lua +76 -0
  44. package/lib/ui/decorations/Border.d.ts +18 -0
  45. package/lib/ui/decorations/Border.lua +188 -0
  46. package/lib/ui/decorations/Decoration.d.ts +13 -0
  47. package/lib/ui/decorations/Decoration.lua +81 -0
  48. package/lib/ui/decorations/Decorations.d.ts +8 -0
  49. package/lib/ui/decorations/Decorations.lua +3 -0
  50. package/lib/ui/decorations/Glow.d.ts +14 -0
  51. package/lib/ui/decorations/Glow.lua +63 -0
  52. package/lib/ui/decorations/backgroundTextures.d.ts +25 -0
  53. package/lib/ui/decorations/backgroundTextures.lua +10 -0
  54. package/lib/ui/decorations/borderTextures.d.ts +41 -0
  55. package/lib/ui/decorations/borderTextures.lua +12 -0
  56. package/lib/ui/decorations/statusBarTextures.d.ts +12 -0
  57. package/lib/ui/decorations/statusBarTextures.lua +9 -0
  58. package/lib/ui/index.d.ts +11 -0
  59. package/lib/ui/index.lua +35 -0
  60. package/lib/ui/layout/calculateFlow.d.ts +12 -0
  61. package/lib/ui/layout/calculateFlow.lua +36 -0
  62. package/lib/ui/layout/calculateGrid.d.ts +9 -0
  63. package/lib/ui/layout/calculateGrid.lua +47 -0
  64. package/lib/ui/layout/measureLayout.d.ts +19 -0
  65. package/lib/ui/layout/measureLayout.lua +215 -0
  66. package/lib/ui/mount.d.ts +5 -0
  67. package/lib/ui/mount.lua +486 -0
  68. package/lib/ui/primitives/jsx.d.ts +38 -0
  69. package/lib/ui/primitives/jsx.lua +66 -0
  70. package/lib/wuira.d.ts +8 -0
  71. package/lib/wuira.lua +30 -0
  72. package/package.json +74 -4
  73. package/templates/addon/README.md +13 -0
  74. package/templates/addon/addon.toc.in +4 -0
  75. package/templates/addon/gitignore +3 -0
  76. package/templates/addon/package.json +11 -0
  77. package/templates/addon/src/index.tsx +9 -0
  78. package/templates/addon/tsconfig.json +8 -0
  79. package/templates/addon/wuira.config.mjs +4 -0
  80. package/tools/build-library.mjs +15 -0
  81. package/tools/module-loader.lua +16 -0
  82. package/tools/wow-modules.mjs +56 -0
  83. package/tsconfig.json +22 -0
  84. package/tsconfig.lib.json +8 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Uira contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,255 @@
1
- # Temporary Holding Version
1
+ # wuira
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Build WoW Forever interfaces with TypeScript and JSX.
4
+
5
+ wuira is a UI framework and addon toolchain for developers who want to describe their interface in code, compose reusable components, and keep game data separate from presentation. Write TypeScript, arrange native widgets with JSX, and compile your addon to Lua.
6
+
7
+ ## Why wuira?
8
+
9
+ An interface should be easy to understand by reading its source. A health display can be a progress bar inside a layout; a player display can be a composition of bars, labels, and icons rather than a special unit-frame class. wuira provides the foundations for that approach, with TypeScript checking your component props before the addon reaches the game.
10
+
11
+ The snippets below use the lowercase JSX primitives. In a generated project, import `{ UI, wuira }` from `wuira` before mounting a view. Each view example is independent.
12
+
13
+ ### JSX composition
14
+
15
+ <!-- Screenshot: a reusable ResourceBar component inside a Cell. -->
16
+
17
+ Describe UI trees with components and reusable functions. No separate XML view files are required.
18
+
19
+ ```tsx
20
+ function ResourceBar({ current }: { current: number }) {
21
+ return <progress width="inherit" height={24} min={0} max={100} current={current} />;
22
+ }
23
+
24
+ function App() {
25
+ return (
26
+ <cell width={200} height={40} padding={8}>
27
+ <ResourceBar current={75} />
28
+ </cell>
29
+ );
30
+ }
31
+
32
+ wuira.Mount(App);
33
+ ```
34
+
35
+ ### Native widgets
36
+
37
+ <!-- Screenshot: a native StatusBar with a dark background. -->
38
+
39
+ Cells mount to WoW frames, and progress bars use the game's native StatusBar widget.
40
+
41
+ ```tsx
42
+ const view = (
43
+ <progress
44
+ width={200} height={24}
45
+ min={0} max={100} current={65}
46
+ foreground={{ color: { r: 0.1, g: 0.75, b: 0.4 } }}
47
+ background={{ color: { r: 0.08, g: 0.08, b: 0.08 } }}
48
+ />
49
+ );
50
+
51
+ wuira.Mount(view);
52
+ ```
53
+
54
+ ### Layout primitives
55
+
56
+ <!-- Screenshot: two vertically stacked progress bars with a gap. -->
57
+
58
+ Flow and grid layouts arrange children, with spacing and sizing options shared across components.
59
+
60
+ ```tsx
61
+ const view = (
62
+ <flow width={200} height={56} direction="vertical" gap={8}>
63
+ <progress height={24} min={0} max={100} current={80} />
64
+ <progress height={24} min={0} max={100} current={45} />
65
+ </flow>
66
+ );
67
+
68
+ wuira.Mount(view);
69
+ ```
70
+
71
+ For rows and columns, use `<grid columns={2} gap={8}>` with an explicit width and height.
72
+
73
+ ### Data sources
74
+
75
+ <!-- Screenshot: live player health and mana bars. -->
76
+
77
+ Connect health and mana values to progress bars without writing a separate resource-specific container class.
78
+
79
+ ```tsx
80
+ import { HP, Mana, Unit } from "wuira/datasources";
81
+
82
+ function App() {
83
+ const hp = new HP(Unit.Player);
84
+ const mana = new Mana(Unit.Player);
85
+
86
+ return (
87
+ <flow width={200} height={52} direction="vertical" gap={4}>
88
+ <progress height={24} source={hp} />
89
+ <progress height={24} source={mana} />
90
+ </flow>
91
+ );
92
+ }
93
+
94
+ wuira.Mount(App);
95
+ ```
96
+
97
+ ### Visual styling
98
+
99
+ <!-- Screenshot: a dark Cell with a thin colored border. -->
100
+
101
+ Configure backgrounds, borders, textures, and glow through reusable decoration objects.
102
+
103
+ ```tsx
104
+ import { Background, Border } from "wuira/ui";
105
+
106
+
107
+ const view = (
108
+ <cell width={200} height={64} decorations={{
109
+ background: new Background({ color: { r: 0.06, g: 0.08, b: 0.1 } }),
110
+ border: new Border({ thickness: 1, color: { r: 0.3, g: 0.8, b: 0.7 } }),
111
+ }} />
112
+ );
113
+
114
+ wuira.Mount(view);
115
+ ```
116
+
117
+ ### Addon tooling
118
+
119
+ <!-- Screenshot: creating and building an addon in the terminal. -->
120
+
121
+ Create a project, compile TypeScriptToLua, and generate the TOC and module-loading files through one CLI.
122
+
123
+ ```sh
124
+ npx wuira@latest create MyAddon
125
+ cd MyAddon
126
+ npm install
127
+ npm run build
128
+ ```
129
+
130
+ ### Readable Lua output
131
+
132
+ <!-- Screenshot: source files alongside their emitted Lua modules. -->
133
+
134
+ Emitted modules remain split across files following the source structure.
135
+
136
+ ```text
137
+ src/index.tsx → dist/index.lua
138
+ src/components/Panel.tsx → dist/components/Panel.lua
139
+ wuira/ui dependency → dist/lua_modules/wuira/lib/ui/index.lua
140
+
141
+ MyAddon.toc loads the module registry, emitted files, and startup entry.
142
+ ```
143
+
144
+ Use wuira when you want to build and distribute an addon UI in TypeScript, share visual components, and let the toolchain handle Lua module loading. Node.js runs during development; the game loads the generated Lua files without a JavaScript runtime.
145
+
146
+ ## Scope and current status
147
+
148
+ wuira is an early framework for addon authors. It is not a complete UI replacement, an in-game visual editor, or a WeakAuras replacement. JSX describes widgets; there is no React runtime or automatic reactive rendering layer.
149
+
150
+ The current core includes Cells, flow and grid layouts, progress bars, decorations, health and mana sources, a local console polyfill, and project tooling. A complete WoW API surface, secure action and click-cast abstractions, nameplate adapters, and preset management are not implemented yet. Combat restrictions and secret-value rules still apply; framework abstractions cannot bypass them.
151
+
152
+ The target client is WoW Forever. Compatibility with Retail or other Classic clients is not promised without verification. Expect API changes while the framework takes shape.
153
+
154
+ ## Getting started
155
+
156
+ The framework, npm package, CLI command, and public API are named `wuira`. Future extension packages can use the `@wuira/` organization scope once that organization is registered.
157
+
158
+ Available on npm as [`wuira`](https://www.npmjs.com/package/wuira):
159
+
160
+ ```sh
161
+ npx wuira create MyAddon
162
+ ```
163
+
164
+ A TypeScript and JSX UI framework for WoW Forever. TypeScriptToLua emits separate Lua files following the source directory structure. No Rollup or single-file Lua bundle is required.
165
+
166
+ ## CLI
167
+
168
+ Create an addon with Node.js 22.13 or newer:
169
+
170
+ ```sh
171
+ npx wuira@latest create MyAddon
172
+ cd MyAddon
173
+ npm install
174
+ npm run build
175
+ ```
176
+
177
+ Alternatively, install globally with `npm install -g wuira`, then use `wuira create MyAddon`. To test unpublished changes, run `npm install` and `npm link` in this repository, or invoke `node /path/to/wuira/cli/wuira.mjs create MyAddon` directly. Templates reflect the installed CLI version; repository changes become available through npm after the next release.
178
+
179
+ `create` refuses to overwrite an existing directory. It generates TypeScriptToLua configuration, addon metadata, a module loader, an MIT license, and this minimal `src/index.tsx`:
180
+
181
+ ```tsx
182
+ import "wuira/console-polyfill";
183
+ import { UI, wuira } from "wuira";
184
+
185
+
186
+ function App() {
187
+ console.log("MyAddon loaded");
188
+ return <></>;
189
+ }
190
+
191
+ wuira.Mount(App);
192
+ ```
193
+
194
+ An empty fragment creates no native frame. Only empty fragments are currently supported; use a layout for multiple visual elements.
195
+
196
+ `console.log/info/warn/error` use a global WoW console polyfill. Output goes to the local chat window, never to other players. The addon uses no Node.js runtime or stdin/stdout. `console.error` does not throw. Arguments are formatted with Lua `tostring`; objects are not deeply inspected. The CLI uses its own Node.js terminal console.
197
+
198
+ ## Build and distribution
199
+
200
+ `wuira build` transpiles through `tsconfig.json`. It writes a standalone addon directory containing individual Lua modules, a loader, a startup file, and `<addonName>.toc`. The default output directory is `dist/`. The addon name lives in `wuira.config.mjs`; Interface version and other metadata live in `addon.toc.in`. The default Interface version, 16001, targets the Forever playground.
201
+
202
+ Copy the contents of `dist/` to `Interface/AddOns/<addonName>/`, or configure the build to output there directly. No Node.js runtime or separate wuira addon is required in game. Module registries are isolated by addon name.
203
+
204
+ Framework code and generated `.d.ts` declarations come from the installed npm package. Import UI components from `wuira/ui`, data sources from `wuira/datasources`, and the mounting API from `wuira`. No framework source files or build scripts are copied into addon projects. This repository contains only the framework and CLI; addon entry points and TOC metadata are generated in consumer projects.
205
+
206
+ Project templates live in `templates/addon/`. Generated projects depend on `wuira` and extend `wuira/config/tsconfig.json`. Shared settings and the TSTL module plugin stay in the installed package; build scripts are not copied into projects. Project-local `rootDir`, `outDir`, and source includes remain in the generated `tsconfig.json`.
207
+
208
+ `npm run build` resolves the locally installed `wuira` command automatically. Use `npx wuira build` when invoking the CLI directly.
209
+
210
+ Configure the addon output in `wuira.config.mjs`:
211
+
212
+ ```js
213
+ export default {
214
+ name: "MyAddon",
215
+ outDir: "./dist",
216
+ // Or: outDir: "G:/Games/WoW/Interface/AddOns/MyAddon",
217
+ };
218
+ ```
219
+
220
+ Relative output paths resolve from the project directory. Absolute paths can target the game's addon directory, keeping the development project elsewhere. Builds compile into a temporary staging directory before copying successful output to the destination. Existing files with matching names are overwritten; unrelated files are retained. The emitted TOC uses paths relative to the output folder, so the entire folder can be moved independently.
221
+
222
+ The CLI, configuration, and build plugin use ESM (`.mjs`). Only Lua and TOC files are needed in game. `npm run build` in the framework repository generates distributable Lua modules and TypeScript declarations in `lib/`; addon builds include the framework modules they import.
223
+
224
+ ## Development
225
+
226
+ ```sh
227
+ npm ci
228
+ npm run build
229
+ npm run check
230
+ npm test
231
+ ```
232
+
233
+ `.github/workflows/ci.yml` runs type checks, builds, tests, and a package dry run on pushes and pull requests, on both Linux and Windows with Node.js 22. CI does not publish packages and requires no npm token.
234
+
235
+ Cell is the basic visual box. FlowLayout and GridLayout arrange children. ProgressBar uses a native StatusBar, while data sources connect values to presentation. Behavior from other WoW versions must be verified against the Forever API before use.
236
+
237
+ Licensed under MIT; see [LICENSE](LICENSE).
238
+
239
+ ## Releases
240
+
241
+ The first version is published. To publish the next version locally, validate the project, increment the patch version, and publish:
242
+
243
+ ```sh
244
+ npm run check
245
+ npm run build
246
+ npm test
247
+ npm version patch --no-git-tag-version
248
+ npm publish --access public
249
+ ```
250
+
251
+ Publishing requires npm authentication and 2FA, or a granular access token with write access and Bypass 2FA enabled. Commit both `package.json` and `package-lock.json` after changing the version. npm versions cannot be published twice.
252
+
253
+ For future automated releases, every pushed Git tag triggers `.github/workflows/publish.yml`. It checks types, builds, tests, and publishes to npm. Tags must match `package.json` version, optionally prefixed with `v`. Do not push a release tag for a version already published locally; the workflow would attempt to publish it again.
254
+
255
+ To enable automated publishing, configure the GitHub repository secret `NPM_TOKEN` with an npm granular access token authorized to publish `wuira` and bypass 2FA. Never commit the token. GitHub Actions must be enabled. Local setup does not publish a package or push a tag.
package/cli/wuira.mjs ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import os from "node:os";
5
+ import { spawnSync } from "node:child_process";
6
+ import { createRequire } from "node:module";
7
+ import { fileURLToPath, pathToFileURL } from "node:url";
8
+ const require = createRequire(import.meta.url);
9
+ const root = path.resolve(import.meta.dirname, "..");
10
+
11
+ export function create(name, cwd = process.cwd()) {
12
+ if (!name || !/^[A-Za-z][A-Za-z0-9_-]*$/.test(name)) throw new Error("Use an addon name containing letters, numbers, underscores or hyphens, starting with a letter.");
13
+ const target = path.join(cwd, name);
14
+ if (fs.existsSync(target)) throw new Error(`Destination already exists: ${target}`);
15
+ fs.mkdirSync(target, { recursive: true });
16
+ const version = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8")).version;
17
+ const variables = { addonName: name, packageName: name.toLowerCase(), frameworkVersion: version };
18
+ const template = path.join(root, "templates/addon");
19
+ for (const entry of fs.readdirSync(template, { recursive: true, withFileTypes: true })) {
20
+ if (!entry.isFile()) continue;
21
+ const source = path.join(entry.parentPath, entry.name);
22
+ const relative = path.relative(template, source);
23
+ const destination = path.join(target, relative === "gitignore" ? ".gitignore" : relative);
24
+ fs.mkdirSync(path.dirname(destination), { recursive: true });
25
+ const content = fs.readFileSync(source, "utf8").replace(/\{\{(\w+)\}\}/g, (_, key) => {
26
+ if (!(key in variables)) throw new Error(`Unknown template variable: ${key}`);
27
+ return variables[key];
28
+ });
29
+ fs.writeFileSync(destination, content);
30
+ }
31
+ fs.copyFileSync(path.join(root, "LICENSE"), path.join(target, "LICENSE"));
32
+ return target;
33
+ }
34
+
35
+ export async function build(cwd = process.cwd()) {
36
+ if (!fs.existsSync(path.join(cwd, "tsconfig.json"))) throw new Error("Run wuira build inside an addon project.");
37
+ const configFile = path.join(cwd, "wuira.config.mjs");
38
+ const config = fs.existsSync(configFile) ? (await import(pathToFileURL(configFile).href + `?updated=${fs.statSync(configFile).mtimeMs}`)).default : {};
39
+ if (config === null || typeof config !== "object") throw new Error("wuira.config.mjs must export a configuration object.");
40
+ if (config.outDir !== undefined && (typeof config.outDir !== "string" || config.outDir.trim() === "")) throw new Error("outDir must be a nonempty path.");
41
+ const output = path.resolve(cwd, config.outDir ?? "dist");
42
+ if (output === path.parse(output).root || output === path.resolve(cwd)) throw new Error("Choose a dedicated addon output directory.");
43
+ const stage = fs.mkdtempSync(path.join(os.tmpdir(), "wuira-build-"));
44
+ const compiler = require.resolve("typescript-to-lua/dist/tstl.js", { paths: [cwd, root] });
45
+ try {
46
+ const result = spawnSync(process.execPath, [compiler, "-p", "tsconfig.json", "--outDir", stage], {
47
+ cwd, stdio: "inherit", env: { ...process.env, WUIRA_STANDALONE: "1", ...(config.name ? { WUIRA_ADDON_NAME: config.name } : {}) },
48
+ });
49
+ if (result.error) throw result.error;
50
+ if (result.status !== 0) throw new Error("Addon build failed.");
51
+ fs.mkdirSync(output, { recursive: true });
52
+ fs.cpSync(stage, output, { recursive: true });
53
+ console.log(`Built addon: ${output}`);
54
+ } finally {
55
+ fs.rmSync(stage, { recursive: true, force: true });
56
+ }
57
+ }
58
+
59
+ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
60
+ try {
61
+ const [command, name] = process.argv.slice(2);
62
+ if (command === "create") console.log(`Created ${create(name)}\nNext: cd ${name}, npm install, wuira build`);
63
+ else if (command === "build") await build();
64
+ else if (!command || command === "--help") console.log("wuira create <addonName>\nwuira build");
65
+ else throw new Error(`Unknown command: ${command}`);
66
+ } catch (error) { console.error(error.message); process.exitCode = 1; }
67
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/TypeScriptToLua/master/tsconfig-schema.json",
3
+ "compilerOptions": {
4
+ "target": "ESNext",
5
+ "lib": [
6
+ "ESNext"
7
+ ],
8
+ "types": [],
9
+ "jsx": "react",
10
+ "jsxFactory": "UI.createElement",
11
+ "jsxFragmentFactory": "UI.Fragment",
12
+ "strict": true,
13
+ "noEmitOnError": true
14
+ },
15
+ "tstl": {
16
+ "luaTarget": "universal",
17
+ "luaLibImport": "inline",
18
+ "noImplicitGlobalVariables": true,
19
+ "luaPlugins": [
20
+ {
21
+ "name": "wuira/tools/wow-modules.mjs"
22
+ }
23
+ ]
24
+ }
25
+ }
@@ -0,0 +1,5 @@
1
+ /** Local client output only; never sends chat messages to other players. */
2
+ export declare class Console {
3
+ private constructor();
4
+ static Echo(message: string): void;
5
+ }
@@ -0,0 +1,20 @@
1
+ --[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
2
+ -- Lua Library inline imports
3
+ local function __TS__Class(self)
4
+ local c = {prototype = {}}
5
+ c.prototype.__index = c.prototype
6
+ c.prototype.constructor = c
7
+ return c
8
+ end
9
+ -- End of Lua Library inline imports
10
+ local ____exports = {}
11
+ --- Local client output only; never sends chat messages to other players.
12
+ ____exports.Console = __TS__Class()
13
+ local Console = ____exports.Console
14
+ Console.name = "Console"
15
+ function Console.prototype.____constructor(self)
16
+ end
17
+ function Console.Echo(self, message)
18
+ print("|cff60d9c5[wuira]|r " .. message)
19
+ end
20
+ return ____exports
@@ -0,0 +1,9 @@
1
+ declare global {
2
+ const console: {
3
+ log(this: void, ...values: unknown[]): void;
4
+ info(this: void, ...values: unknown[]): void;
5
+ warn(this: void, ...values: unknown[]): void;
6
+ error(this: void, ...values: unknown[]): void;
7
+ };
8
+ }
9
+ export {};
@@ -0,0 +1,39 @@
1
+ --[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
2
+ -- Lua Library inline imports
3
+ local function __TS__ArrayMap(self, callbackfn, thisArg)
4
+ local result = {}
5
+ for i = 1, #self do
6
+ result[i] = callbackfn(thisArg, self[i], i - 1, self)
7
+ end
8
+ return result
9
+ end
10
+ -- End of Lua Library inline imports
11
+ local ____exports = {}
12
+ local function write(self, color, values)
13
+ print((color .. table.concat(
14
+ __TS__ArrayMap(
15
+ values,
16
+ function(____, value) return tostring(value) end
17
+ ),
18
+ " "
19
+ )) .. "|r")
20
+ end
21
+ _G.console = {
22
+ log = function(...)
23
+ local values = {...}
24
+ write(nil, "|cffffffff", values)
25
+ end,
26
+ info = function(...)
27
+ local values = {...}
28
+ write(nil, "|cff60d9c5", values)
29
+ end,
30
+ warn = function(...)
31
+ local values = {...}
32
+ write(nil, "|cffffcc00", values)
33
+ end,
34
+ error = function(...)
35
+ local values = {...}
36
+ write(nil, "|cffff5555", values)
37
+ end
38
+ }
39
+ return ____exports
@@ -0,0 +1,17 @@
1
+ /** A value-producing source. Secrecy describes data, not native frame protection. */
2
+ export declare abstract class DataSource<T> {
3
+ private value;
4
+ private secret;
5
+ protected constructor(value: T, secret?: boolean);
6
+ /** Checked when consumed, rather than inferred from combat state. */
7
+ IsSecret(): boolean;
8
+ get Value(): T;
9
+ Compute<TResult>(compute: (value: T) => TResult): TResult;
10
+ protected GetValue(): T;
11
+ private IsValueSecret;
12
+ /** Replace the value and its explicit restriction together, clearing stale flags. */
13
+ protected SetValue(value: T, secret?: boolean): void;
14
+ /** Aggregate sources override this to check known fields without comparing them. */
15
+ protected HasSecretFields(_value: T): boolean;
16
+ private AssertReadable;
17
+ }
@@ -0,0 +1,199 @@
1
+ --[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
2
+ -- Lua Library inline imports
3
+ local function __TS__Class(self)
4
+ local c = {prototype = {}}
5
+ c.prototype.__index = c.prototype
6
+ c.prototype.constructor = c
7
+ return c
8
+ end
9
+
10
+ local function __TS__CloneDescriptor(____bindingPattern0)
11
+ local value
12
+ local writable
13
+ local set
14
+ local get
15
+ local configurable
16
+ local enumerable
17
+ enumerable = ____bindingPattern0.enumerable
18
+ configurable = ____bindingPattern0.configurable
19
+ get = ____bindingPattern0.get
20
+ set = ____bindingPattern0.set
21
+ writable = ____bindingPattern0.writable
22
+ value = ____bindingPattern0.value
23
+ local descriptor = {enumerable = enumerable == true, configurable = configurable == true}
24
+ local hasGetterOrSetter = get ~= nil or set ~= nil
25
+ local hasValueOrWritableAttribute = writable ~= nil or value ~= nil
26
+ if hasGetterOrSetter and hasValueOrWritableAttribute then
27
+ error("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute.", 0)
28
+ end
29
+ if get or set then
30
+ descriptor.get = get
31
+ descriptor.set = set
32
+ else
33
+ descriptor.value = value
34
+ descriptor.writable = writable == true
35
+ end
36
+ return descriptor
37
+ end
38
+
39
+ local __TS__DescriptorGet
40
+ do
41
+ local getmetatable = _G.getmetatable
42
+ local ____rawget = _G.rawget
43
+ function __TS__DescriptorGet(self, metatable, key)
44
+ while metatable do
45
+ local rawResult = ____rawget(metatable, key)
46
+ if rawResult ~= nil then
47
+ return rawResult
48
+ end
49
+ local descriptors = ____rawget(metatable, "_descriptors")
50
+ if descriptors then
51
+ local descriptor = descriptors[key]
52
+ if descriptor ~= nil then
53
+ if descriptor.get then
54
+ return descriptor.get(self)
55
+ end
56
+ return descriptor.value
57
+ end
58
+ end
59
+ metatable = getmetatable(metatable)
60
+ end
61
+ end
62
+ end
63
+
64
+ local __TS__DescriptorSet
65
+ do
66
+ local getmetatable = _G.getmetatable
67
+ local ____rawget = _G.rawget
68
+ local rawset = _G.rawset
69
+ function __TS__DescriptorSet(self, metatable, key, value)
70
+ while metatable do
71
+ local descriptors = ____rawget(metatable, "_descriptors")
72
+ if descriptors then
73
+ local descriptor = descriptors[key]
74
+ if descriptor ~= nil then
75
+ if descriptor.set then
76
+ descriptor.set(self, value)
77
+ else
78
+ if descriptor.writable == false then
79
+ error(
80
+ ((("Cannot assign to read only property '" .. key) .. "' of object '") .. tostring(self)) .. "'",
81
+ 0
82
+ )
83
+ end
84
+ descriptor.value = value
85
+ end
86
+ return
87
+ end
88
+ end
89
+ metatable = getmetatable(metatable)
90
+ end
91
+ rawset(self, key, value)
92
+ end
93
+ end
94
+
95
+ local __TS__SetDescriptor
96
+ do
97
+ local getmetatable = _G.getmetatable
98
+ local function descriptorIndex(self, key)
99
+ return __TS__DescriptorGet(
100
+ self,
101
+ getmetatable(self),
102
+ key
103
+ )
104
+ end
105
+ local function descriptorNewIndex(self, key, value)
106
+ return __TS__DescriptorSet(
107
+ self,
108
+ getmetatable(self),
109
+ key,
110
+ value
111
+ )
112
+ end
113
+ function __TS__SetDescriptor(target, key, desc, isPrototype)
114
+ if isPrototype == nil then
115
+ isPrototype = false
116
+ end
117
+ local ____isPrototype_0
118
+ if isPrototype then
119
+ ____isPrototype_0 = target
120
+ else
121
+ ____isPrototype_0 = getmetatable(target)
122
+ end
123
+ local metatable = ____isPrototype_0
124
+ if not metatable then
125
+ metatable = {}
126
+ setmetatable(target, metatable)
127
+ end
128
+ if not isPrototype and not rawget(metatable, "_isOwnDescriptorMetatable") then
129
+ local instanceMetatable = {}
130
+ instanceMetatable._isOwnDescriptorMetatable = true
131
+ setmetatable(instanceMetatable, metatable)
132
+ setmetatable(target, instanceMetatable)
133
+ metatable = instanceMetatable
134
+ end
135
+ local value = rawget(target, key)
136
+ if value ~= nil then
137
+ rawset(target, key, nil)
138
+ end
139
+ if not rawget(metatable, "_descriptors") then
140
+ metatable._descriptors = {}
141
+ end
142
+ metatable._descriptors[key] = __TS__CloneDescriptor(desc)
143
+ metatable.__index = descriptorIndex
144
+ metatable.__newindex = descriptorNewIndex
145
+ end
146
+ end
147
+ -- End of Lua Library inline imports
148
+ local ____exports = {}
149
+ --- A value-producing source. Secrecy describes data, not native frame protection.
150
+ ____exports.DataSource = __TS__Class()
151
+ local DataSource = ____exports.DataSource
152
+ DataSource.name = "DataSource"
153
+ function DataSource.prototype.____constructor(self, value, secret)
154
+ if secret == nil then
155
+ secret = false
156
+ end
157
+ self.value = value
158
+ self.secret = secret
159
+ end
160
+ function DataSource.prototype.IsSecret(self)
161
+ return self:IsValueSecret(self:GetValue())
162
+ end
163
+ function DataSource.prototype.Compute(self, compute)
164
+ local value = self:GetValue()
165
+ self:AssertReadable(value)
166
+ return compute(nil, value)
167
+ end
168
+ function DataSource.prototype.GetValue(self)
169
+ return self.value
170
+ end
171
+ function DataSource.prototype.IsValueSecret(self, value)
172
+ return issecretvalue(value) or self.secret or self:HasSecretFields(value)
173
+ end
174
+ function DataSource.prototype.SetValue(self, value, secret)
175
+ if secret == nil then
176
+ secret = false
177
+ end
178
+ self.value = value
179
+ self.secret = secret
180
+ end
181
+ function DataSource.prototype.HasSecretFields(self, _value)
182
+ return false
183
+ end
184
+ function DataSource.prototype.AssertReadable(self, value)
185
+ if self:IsValueSecret(value) then
186
+ error("DataSource: secret data cannot be read or used in computations")
187
+ end
188
+ end
189
+ __TS__SetDescriptor(
190
+ DataSource.prototype,
191
+ "Value",
192
+ {get = function(self)
193
+ local value = self:GetValue()
194
+ self:AssertReadable(value)
195
+ return value
196
+ end},
197
+ true
198
+ )
199
+ return ____exports
@@ -0,0 +1,7 @@
1
+ import { DataSource } from "./DataSource";
2
+ /** Read-only API value; no cached assignment or game-state mutation. */
3
+ export declare class NativeNumberSource extends DataSource<number> {
4
+ private readonly read;
5
+ constructor(read: () => number);
6
+ protected GetValue(): number;
7
+ }