@hasagi/cli 0.9.9 → 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 CHANGED
@@ -1,4 +1,84 @@
1
- # @hasagi/cli
2
-
3
- # Disclaimer
4
- Hasagi is not endorsed by Riot Games and does not reflect the views or opinions of Riot Games or anyone officially involved in producing or managing Riot Games properties. Riot Games and all associated properties are trademarks or registered trademarks of Riot Games, Inc
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
- await fs.writeFile(isDirectory ? _path.join(out, `${method}-${path.substring(1).replaceAll("/", "_")}-${Date.now()}.json`) : out, JSON.stringify(result, null, 4));
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.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": "^0.6.7",
21
- "@hasagi/schema": "^0.6.8",
22
- "yargs": "^17.7.2"
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
+ }