@hasagi/cli 0.9.8 → 0.9.10
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.
- package/README.md +84 -4
- package/bin/format.js +22 -0
- package/bin/index.js +12 -5
- package/package.json +6 -16
package/README.md
CHANGED
|
@@ -1,4 +1,84 @@
|
|
|
1
|
-
# @hasagi/cli
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
# @hasagi/cli
|
|
2
|
+
|
|
3
|
+
A command-line interface for the League of Legends client API (LCU). Send requests, listen to
|
|
4
|
+
WebSocket events, read credentials, and generate the LCU schema / TypeScript types — all against a
|
|
5
|
+
running League client, with credentials discovered automatically.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @hasagi/cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This exposes the `hasagi` command. (Or run without installing via `npx @hasagi/cli <command>`.)
|
|
14
|
+
|
|
15
|
+
## Commands
|
|
16
|
+
|
|
17
|
+
### `request <method> <path>`
|
|
18
|
+
|
|
19
|
+
Send an HTTP request to the LCU.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
hasagi request get /lol-summoner/v1/current-summoner
|
|
23
|
+
hasagi request post /lol-lobby/v2/lobby --body '{ "queueId": 430 }'
|
|
24
|
+
hasagi request get /lol-summoner/v1/summoners --query '{ "name": "Faker" }'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| Option | Alias | Description |
|
|
28
|
+
| --- | --- | --- |
|
|
29
|
+
| `--body` | `-b` | JSON request body |
|
|
30
|
+
| `--query` | `-q` | JSON query parameters |
|
|
31
|
+
| `--out` | `-o` | Write the response to a file (or a directory to auto-name it) |
|
|
32
|
+
|
|
33
|
+
### `listen`
|
|
34
|
+
|
|
35
|
+
Subscribe to LCU WebSocket events and print them. With neither `--name` nor `--path`, subscribes to
|
|
36
|
+
the `OnJsonApiEvent` catch-all.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
hasagi listen
|
|
40
|
+
hasagi listen --path /lol-gameflow/v1/gameflow-phase --type Update
|
|
41
|
+
hasagi listen --name OnJsonApiEvent_lol-champ-select_v1_session --out ./events
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
| Option | Alias | Description |
|
|
45
|
+
| --- | --- | --- |
|
|
46
|
+
| `--path` | `-p` | Filter by URI path (conflicts with `--name`) |
|
|
47
|
+
| `--name` | `-n` | Subscribe to a specific event name (conflicts with `--path`) |
|
|
48
|
+
| `--type` | `-t` | Filter by event type(s): `Create`, `Update`, `Delete` |
|
|
49
|
+
| `--out` | `-o` | Append events to a file (or a directory for the default file name) |
|
|
50
|
+
|
|
51
|
+
### `credentials`
|
|
52
|
+
|
|
53
|
+
Print the LCU base URL and `Authorization` header for the running client.
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
hasagi credentials
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### `schema`
|
|
60
|
+
|
|
61
|
+
Generate the LCU schema and/or TypeScript types from the running client (powered by
|
|
62
|
+
[`@hasagi/schema`](https://www.npmjs.com/package/@hasagi/schema)).
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Emit the generated TypeScript types into ./src/types
|
|
66
|
+
hasagi schema --typescript ./src/types
|
|
67
|
+
|
|
68
|
+
# Emit the OpenAPI (swagger) document
|
|
69
|
+
hasagi schema --swagger ./
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
| Option | Alias | Description |
|
|
73
|
+
| --- | --- | --- |
|
|
74
|
+
| `--typescript` | `-t` | Output directory for the generated `.d.ts` files |
|
|
75
|
+
| `--tsnamespace` | | Wrap the generated types in a namespace |
|
|
76
|
+
| `--swagger` | `-s` | Output directory for `swagger.json` |
|
|
77
|
+
| `--raw` | `-r` | Output directory for the raw/extended schema JSON |
|
|
78
|
+
| `--index` / `--no-index` | | Emit (default) or skip an `index.d.ts` barrel re-export |
|
|
79
|
+
|
|
80
|
+
## Disclaimer
|
|
81
|
+
|
|
82
|
+
Hasagi is not endorsed by Riot Games and does not reflect the views or opinions of Riot Games or
|
|
83
|
+
anyone officially involved in producing or managing Riot Games properties. Riot Games and all
|
|
84
|
+
associated properties are trademarks or registered trademarks of Riot Games, Inc.
|
package/bin/format.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { LCUError, RequestError } from "@hasagi/core";
|
|
2
|
+
/**
|
|
3
|
+
* Serializes a `request` command result for writing to disk. `LCUError`/`RequestError` instances
|
|
4
|
+
* aren't JSON-enumerable (`JSON.stringify(error)` yields `"{}"`), so their fields are mapped
|
|
5
|
+
* explicitly; any other (successful) result passes through unchanged.
|
|
6
|
+
*/
|
|
7
|
+
export function serializeRequestResult(result) {
|
|
8
|
+
if (result instanceof LCUError)
|
|
9
|
+
return { error: "LCUError", statusCode: result.statusCode, errorCode: result.errorCode, message: result.message, implementationDetails: result.implementationDetails };
|
|
10
|
+
if (result instanceof RequestError)
|
|
11
|
+
return { error: "RequestError", errorCode: result.errorCode, message: result.message };
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Resolves the LCU event name the `listen` command should subscribe to. With neither a name nor a
|
|
16
|
+
* path, core subscribes to nothing, so default to the `OnJsonApiEvent` catch-all so a bare
|
|
17
|
+
* `hasagi listen` still receives events. An explicit name always wins; a path-only filter keeps the
|
|
18
|
+
* name unset (core defaults it to `OnJsonApiEvent` itself).
|
|
19
|
+
*/
|
|
20
|
+
export function resolveListenEventName(name, path) {
|
|
21
|
+
return name ?? (path ? undefined : "OnJsonApiEvent");
|
|
22
|
+
}
|
package/bin/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { HasagiClient, LCUError, RequestError } from "@hasagi/core";
|
|
|
4
4
|
import fs from "fs/promises";
|
|
5
5
|
import _path from "path";
|
|
6
6
|
import { getExtendedHelp, getSwagger, getTypeScript } from "@hasagi/schema";
|
|
7
|
+
import { resolveListenEventName, serializeRequestResult } from "./format.js";
|
|
7
8
|
export const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
8
9
|
function log(text) {
|
|
9
10
|
console.log(`[hasagi] ${text}`);
|
|
@@ -24,7 +25,8 @@ const options = await yargs().scriptName("hasagi")
|
|
|
24
25
|
.option("typescript", { alias: "t", string: true })
|
|
25
26
|
.option("tsnamespace", { string: true })
|
|
26
27
|
.option("swagger", { alias: "s", string: true })
|
|
27
|
-
.option("raw", { alias: "r", string: true })
|
|
28
|
+
.option("raw", { alias: "r", string: true })
|
|
29
|
+
.option("index", { boolean: true, default: true, description: "Also emit an index.d.ts barrel re-exporting the generated types (use --no-index to disable)" }))
|
|
28
30
|
.command("credentials", "prints the lcu port and auth token")
|
|
29
31
|
.demandCommand()
|
|
30
32
|
.help("help")
|
|
@@ -46,13 +48,14 @@ if (cmd === "request") {
|
|
|
46
48
|
url: path,
|
|
47
49
|
returnAxiosResponse: true,
|
|
48
50
|
data: body,
|
|
49
|
-
params: query
|
|
51
|
+
params: query,
|
|
50
52
|
}).then(res => ({
|
|
51
53
|
statusCode: res.status,
|
|
52
|
-
body: res.data
|
|
54
|
+
body: res.data,
|
|
53
55
|
}), (err) => err);
|
|
54
56
|
if (out) {
|
|
55
|
-
|
|
57
|
+
const fileContent = serializeRequestResult(result);
|
|
58
|
+
await fs.writeFile(isDirectory ? _path.join(out, `${method}-${path.substring(1).replaceAll("/", "_")}-${Date.now()}.json`) : out, JSON.stringify(fileContent, null, 4));
|
|
56
59
|
}
|
|
57
60
|
if (result instanceof LCUError) {
|
|
58
61
|
log(`Received response with non-success status code '${result.statusCode}'.`);
|
|
@@ -79,7 +82,7 @@ else if (cmd === "listen") {
|
|
|
79
82
|
const out = (options.out === undefined ? undefined : options.out !== "" ? options.out : "./");
|
|
80
83
|
const isDirectory = out !== undefined ? await fs.stat(out).then(stat => stat.isDirectory(), () => false) : false;
|
|
81
84
|
client.addLCUEventListener({
|
|
82
|
-
name,
|
|
85
|
+
name: resolveListenEventName(name, path),
|
|
83
86
|
path,
|
|
84
87
|
types,
|
|
85
88
|
callback: async (event) => {
|
|
@@ -120,6 +123,10 @@ else if (cmd === "schema") {
|
|
|
120
123
|
await fs.writeFile(_path.join(out, "lcu-types.d.ts"), lcuTypes);
|
|
121
124
|
await fs.writeFile(_path.join(out, "lcu-endpoints.d.ts"), lcuEndpoints);
|
|
122
125
|
await fs.writeFile(_path.join(out, "lcu-events.d.ts"), lcuEvents);
|
|
126
|
+
// Barrel so the generated types can be imported by name from a single entry point (disable with --no-index).
|
|
127
|
+
// The `LCUTypes` namespace re-export preserves backwards compatibility with older @hasagi/types versions.
|
|
128
|
+
if (options.index !== false)
|
|
129
|
+
await fs.writeFile(_path.join(out, "index.d.ts"), "export * from \"./lcu-types\";\nexport * from \"./lcu-endpoints\";\nexport * from \"./lcu-events\";\nexport * as LCUTypes from \"./lcu-types\";\n");
|
|
123
130
|
}
|
|
124
131
|
}
|
|
125
132
|
}
|
package/package.json
CHANGED
|
@@ -1,33 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasagi/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.10",
|
|
4
4
|
"description": "This package provides the 'hasagi' command-line interface",
|
|
5
5
|
"bin": {
|
|
6
6
|
"hasagi": "bin/index.js"
|
|
7
7
|
},
|
|
8
|
-
"main": "bin/index.js",
|
|
9
|
-
"scripts": {
|
|
10
|
-
"build": "tsc",
|
|
11
|
-
"pub": "npm run build && npm publish --access public",
|
|
12
|
-
"update": "npm i @hasagi/core@latest @hasagi/schema@latest"
|
|
13
|
-
},
|
|
14
8
|
"keywords": [
|
|
15
9
|
"hasagi"
|
|
16
10
|
],
|
|
17
11
|
"author": "dysolix",
|
|
18
12
|
"license": "MIT",
|
|
19
13
|
"dependencies": {
|
|
20
|
-
"@hasagi/core": "
|
|
21
|
-
"@hasagi/schema": "
|
|
22
|
-
"yargs": "
|
|
14
|
+
"@hasagi/core": "0.7.0",
|
|
15
|
+
"@hasagi/schema": "0.7.1",
|
|
16
|
+
"yargs": "17.7.2"
|
|
23
17
|
},
|
|
24
18
|
"type": "module",
|
|
25
|
-
"devDependencies": {
|
|
26
|
-
"@types/node": "^20.6.2",
|
|
27
|
-
"@types/yargs": "^17.0.24"
|
|
28
|
-
},
|
|
29
19
|
"repository": {
|
|
30
20
|
"type": "git",
|
|
31
|
-
"url": "https://github.com/dysolix/hasagi-cli.git"
|
|
21
|
+
"url": "git+https://github.com/dysolix/hasagi-cli.git"
|
|
32
22
|
}
|
|
33
|
-
}
|
|
23
|
+
}
|