vrchat 2.20.5 → 2.20.7-nightly.16

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 ADDED
@@ -0,0 +1,8 @@
1
+ # VRChat.js
2
+
3
+ VRChat.js is a JavaScript SDK for interacting with the VRChat API, allowing developers to create applications that can access and manipulate VRChat data.
4
+
5
+ * https://vrchat.community/javascript
6
+ * https://npm.im/vrchat
7
+
8
+ Join the [Discord Server](https://discord.gg/Ge2APMhPfD) for support & to start a discussion.
@@ -0,0 +1,6 @@
1
+ // src/types.ts
2
+ var TwoFactorMethods = ["totp", "otp", "emailOtp"];
3
+
4
+ export { TwoFactorMethods };
5
+ //# sourceMappingURL=chunk-353CBA4S.mjs.map
6
+ //# sourceMappingURL=chunk-353CBA4S.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";AA6CO,IAAM,gBAAmB,GAAA,CAAC,MAAQ,EAAA,KAAA,EAAO,UAAU","file":"chunk-353CBA4S.mjs","sourcesContent":["import type { KeyvStoreAdapter } from \"keyv\";\nimport type Keyv from \"keyv\";\n\nimport type { VRChatApplication } from \"./application\";\nimport type { createConfig, Options, RequestResult } from \"./generated/client\";\nimport type { Lazy } from \"./lib/lazy\";\nimport type { GetCurrentUser, GetCurrentUserErrors, GetCurrentUserResponses } from \"./types\";\nimport type { VRChatWebsocketOptions } from \"./websocket\";\n\nexport interface VRChatAuthentication {\n\t/**\n\t * The credentials to use for the VRChat API.\n\t *\n\t * If not provided, the user must be logged in using the `login` method.\n\t * If provided, this will be used to authenticate the user automatically.\n\t */\n\tcredentials?: Lazy<LoginCredentials>;\n\t/**\n\t * If set to `true`, the client will attempt to authenticate immediately after being created.\n\t * If set to `false`, the client will only re-authenticate on request failure (e.g. 401 Unauthorized).\n\t * @default true\n\t */\n\toptimistic?: boolean;\n}\n\nexport interface VRChatOptions extends Omit<NonNullable<Parameters<typeof createConfig>[0]>, \"body\" | \"bodySerializer\" | \"credentials\" | \"global\" | \"method\" | \"mode\" | \"parseAs\" | \"querySerializer\"> {\n\t/**\n\t * When using the VRChat API, you must provide an application name, version, and contact information.\n\t * This is used to identify your application to VRChat, and to provide support if needed.\n\t */\n\tapplication: VRChatApplication;\n\tauthentication?: VRChatAuthentication;\n\tpipeline?: VRChatWebsocketOptions;\n\t/**\n\t * A [Keyv-compatible adapter](https://npm.im/keyv#official-storage-adapters) for caching & persistent sessions.\n\t */\n\tkeyv?: Keyv<unknown> | KeyvStoreAdapter | Map<unknown, unknown>;\n\t/**\n\t * If set to `true`, this client will log debug information to the console.\n\t * This is useful for debugging, but **will expose sensitive information**.\n\t * @default false\n\t */\n\tverbose?: boolean;\n}\n\nexport const TwoFactorMethods = [\"totp\", \"otp\", \"emailOtp\"] as const;\nexport type TwoFactorMethods = (typeof TwoFactorMethods)[number];\n\nexport interface LoginCredentials {\n\t/**\n\t * The username or email of the VRChat account.\n\t */\n\tusername: string;\n\t/**\n\t * The password of the VRChat account.\n\t */\n\tpassword: string;\n\t/**\n\t * The secret key for two-factor authentication, useful for service accounts & automated workflows.\n\t * If this is a user-initiated login, don't use this.\n\t *\n\t * Equivalent to ``twoFactorCode: TOTP.generate(totpSecret).otp``.\n\t */\n\ttotpSecret?: string;\n\t/**\n\t * If provided, this function will be called to generate the two-factor authentication code.\n\t * It overrides ``totpSecret`` if both are provided, ``totpSecret`` will be ignored.\n\t *\n\t * @returns The two-factor authentication code.\n\t */\n\ttwoFactorCode?: Lazy<string>;\n}\n\nexport type LoginOptions<ThrowOnError extends boolean> = { meta?: Record<PropertyKey, unknown> } & LoginCredentials & Omit<Options<GetCurrentUser, ThrowOnError>, \"credentials\" | \"responseTransformer\">;\nexport type LoginResult<ThrowOnError extends boolean = false> = Awaited<RequestResult<GetCurrentUserResponses, GetCurrentUserErrors, ThrowOnError>>;\n\nexport * from \"./generated/types.gen\";\n"]}
@@ -0,0 +1,65 @@
1
+ import EventEmitter from 'events';
2
+ import WebSocket from 'isomorphic-ws';
3
+ import debug from 'debug';
4
+
5
+ // src/websocket.ts
6
+ var log = debug("vrchat");
7
+
8
+ // src/websocket.ts
9
+ var logWebsocket = log.extend("websocket");
10
+ var baseUrl = "wss://pipeline.vrchat.cloud";
11
+ var VRChatWebsocket = class extends EventEmitter {
12
+ constructor(options = {}, vrchat) {
13
+ super();
14
+ this.options = options;
15
+ this.vrchat = vrchat;
16
+ this.url = new URL(this.options.baseUrl ?? baseUrl);
17
+ if (options.authToken)
18
+ this.authenticate(options.authToken);
19
+ process.on("beforeExit", () => this.close());
20
+ process.on("SIGINT", () => this.close());
21
+ }
22
+ url;
23
+ websocket;
24
+ get connected() {
25
+ return this.websocket?.readyState === WebSocket.OPEN;
26
+ }
27
+ close() {
28
+ if (!this.websocket || this.websocket.readyState === WebSocket.CLOSED)
29
+ return;
30
+ logWebsocket("%s()", this.close.name);
31
+ this.websocket.close();
32
+ }
33
+ async authenticate(authToken) {
34
+ logWebsocket('%s(authToken: "%s")', this.authenticate.name, authToken);
35
+ this.close();
36
+ this.url.searchParams.set("authToken", authToken);
37
+ this.websocket = new WebSocket(this.url, {
38
+ headers: Object.fromEntries(this.options.headers?.entries() ?? [])
39
+ });
40
+ this.websocket.addEventListener("open", (event) => {
41
+ logWebsocket("%s", event.type);
42
+ });
43
+ this.websocket.addEventListener("close", (event) => {
44
+ logWebsocket("%s: %s", event.type, event.reason);
45
+ });
46
+ this.websocket.addEventListener("error", (event) => {
47
+ logWebsocket("%s: %O", event.type, event.error);
48
+ });
49
+ this.websocket.addEventListener("message", (event) => {
50
+ try {
51
+ const { type, content: _content } = JSON.parse(event.data.toString());
52
+ const content = JSON.parse(_content);
53
+ logWebsocket("%s: %O", type, content);
54
+ this.emit(type, content);
55
+ } catch (reason) {
56
+ logWebsocket("Malformed message: %O", event.data);
57
+ logWebsocket(reason);
58
+ }
59
+ });
60
+ }
61
+ };
62
+
63
+ export { VRChatWebsocket, log };
64
+ //# sourceMappingURL=chunk-63N2PY2X.mjs.map
65
+ //# sourceMappingURL=chunk-63N2PY2X.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/log.ts","../src/websocket.ts"],"names":[],"mappings":"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","file":"chunk-63N2PY2X.mjs","sourcesContent":["import debug from \"debug\";\n\nexport const log = debug(\"vrchat\");\n","import EventEmitter from \"node:events\";\n\nimport WebSocket from \"isomorphic-ws\";\nimport type TypedEventEmitter from \"typed-emitter\";\n\nimport type { VRChat } from \"./client\";\nimport type { Events } from \"./events\";\nimport { log } from \"./lib/log\";\n\nconst logWebsocket = log.extend(\"websocket\");\nconst baseUrl = \"wss://pipeline.vrchat.cloud\";\n\nexport interface VRChatWebsocketOptions {\n\tbaseUrl?: string;\n\theaders?: Headers;\n\tauthToken?: string;\n}\n\nexport class VRChatWebsocket extends (EventEmitter as new () => TypedEventEmitter<Events>) {\n\tprivate url!: URL;\n\tprivate websocket?: WebSocket;\n\n\tpublic constructor(\n\t\tpublic readonly options: VRChatWebsocketOptions = {},\n\t\tprivate readonly vrchat?: VRChat\n\t) {\n\t\tsuper();\n\n\t\tthis.url = new URL(this.options.baseUrl ?? baseUrl);\n\n\t\tif (options.authToken)\n\t\t\tthis.authenticate(options.authToken);\n\n\t\tprocess.on(\"beforeExit\", () => this.close());\n\t\tprocess.on(\"SIGINT\", () => this.close());\n\t}\n\n\tpublic get connected(): boolean {\n\t\treturn this.websocket?.readyState === WebSocket.OPEN;\n\t}\n\n\tpublic close(): void {\n\t\tif (!this.websocket || this.websocket.readyState === WebSocket.CLOSED)\n\t\t\treturn;\n\n\t\tlogWebsocket(\"%s()\", this.close.name);\n\t\tthis.websocket.close();\n\t}\n\n\tpublic async authenticate(authToken: string): Promise<void> {\n\t\tlogWebsocket(\"%s(authToken: \\\"%s\\\")\", this.authenticate.name, authToken);\n\n\t\tthis.close();\n\t\tthis.url.searchParams.set(\"authToken\", authToken);\n\n\t\tthis.websocket = new WebSocket(this.url, {\n\t\t\theaders: Object.fromEntries(this.options.headers?.entries() ?? [])\n\t\t});\n\n\t\tthis.websocket.addEventListener(\"open\", (event: WebSocket.Event) => {\n\t\t\tlogWebsocket(\"%s\", event.type);\n\t\t});\n\n\t\tthis.websocket.addEventListener(\"close\", (event: WebSocket.CloseEvent) => {\n\t\t\tlogWebsocket(\"%s: %s\", event.type, event.reason);\n\t\t});\n\n\t\tthis.websocket.addEventListener(\"error\", (event: WebSocket.ErrorEvent) => {\n\t\t\tlogWebsocket(\"%s: %O\", event.type, event.error);\n\t\t});\n\n\t\tthis.websocket.addEventListener(\"message\", (event: WebSocket.MessageEvent) => {\n\t\t\ttry {\n\t\t\t\tconst { type, content: _content } = JSON.parse(event.data.toString());\n\t\t\t\tconst content = JSON.parse(_content);\n\n\t\t\t\tlogWebsocket(\"%s: %O\", type, content);\n\n\t\t\t\tthis.emit(type, content);\n\t\t\t}\n\t\t\tcatch (reason) {\n\t\t\t\tlogWebsocket(\"Malformed message: %O\", event.data);\n\t\t\t\tlogWebsocket(reason);\n\t\t\t}\n\t\t});\n\t}\n}\n"]}
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ // src/types.ts
4
+ var TwoFactorMethods = ["totp", "otp", "emailOtp"];
5
+
6
+ exports.TwoFactorMethods = TwoFactorMethods;
7
+ //# sourceMappingURL=chunk-EWNWJRNP.js.map
8
+ //# sourceMappingURL=chunk-EWNWJRNP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";;;AA6CO,IAAM,gBAAmB,GAAA,CAAC,MAAQ,EAAA,KAAA,EAAO,UAAU","file":"chunk-EWNWJRNP.js","sourcesContent":["import type { KeyvStoreAdapter } from \"keyv\";\nimport type Keyv from \"keyv\";\n\nimport type { VRChatApplication } from \"./application\";\nimport type { createConfig, Options, RequestResult } from \"./generated/client\";\nimport type { Lazy } from \"./lib/lazy\";\nimport type { GetCurrentUser, GetCurrentUserErrors, GetCurrentUserResponses } from \"./types\";\nimport type { VRChatWebsocketOptions } from \"./websocket\";\n\nexport interface VRChatAuthentication {\n\t/**\n\t * The credentials to use for the VRChat API.\n\t *\n\t * If not provided, the user must be logged in using the `login` method.\n\t * If provided, this will be used to authenticate the user automatically.\n\t */\n\tcredentials?: Lazy<LoginCredentials>;\n\t/**\n\t * If set to `true`, the client will attempt to authenticate immediately after being created.\n\t * If set to `false`, the client will only re-authenticate on request failure (e.g. 401 Unauthorized).\n\t * @default true\n\t */\n\toptimistic?: boolean;\n}\n\nexport interface VRChatOptions extends Omit<NonNullable<Parameters<typeof createConfig>[0]>, \"body\" | \"bodySerializer\" | \"credentials\" | \"global\" | \"method\" | \"mode\" | \"parseAs\" | \"querySerializer\"> {\n\t/**\n\t * When using the VRChat API, you must provide an application name, version, and contact information.\n\t * This is used to identify your application to VRChat, and to provide support if needed.\n\t */\n\tapplication: VRChatApplication;\n\tauthentication?: VRChatAuthentication;\n\tpipeline?: VRChatWebsocketOptions;\n\t/**\n\t * A [Keyv-compatible adapter](https://npm.im/keyv#official-storage-adapters) for caching & persistent sessions.\n\t */\n\tkeyv?: Keyv<unknown> | KeyvStoreAdapter | Map<unknown, unknown>;\n\t/**\n\t * If set to `true`, this client will log debug information to the console.\n\t * This is useful for debugging, but **will expose sensitive information**.\n\t * @default false\n\t */\n\tverbose?: boolean;\n}\n\nexport const TwoFactorMethods = [\"totp\", \"otp\", \"emailOtp\"] as const;\nexport type TwoFactorMethods = (typeof TwoFactorMethods)[number];\n\nexport interface LoginCredentials {\n\t/**\n\t * The username or email of the VRChat account.\n\t */\n\tusername: string;\n\t/**\n\t * The password of the VRChat account.\n\t */\n\tpassword: string;\n\t/**\n\t * The secret key for two-factor authentication, useful for service accounts & automated workflows.\n\t * If this is a user-initiated login, don't use this.\n\t *\n\t * Equivalent to ``twoFactorCode: TOTP.generate(totpSecret).otp``.\n\t */\n\ttotpSecret?: string;\n\t/**\n\t * If provided, this function will be called to generate the two-factor authentication code.\n\t * It overrides ``totpSecret`` if both are provided, ``totpSecret`` will be ignored.\n\t *\n\t * @returns The two-factor authentication code.\n\t */\n\ttwoFactorCode?: Lazy<string>;\n}\n\nexport type LoginOptions<ThrowOnError extends boolean> = { meta?: Record<PropertyKey, unknown> } & LoginCredentials & Omit<Options<GetCurrentUser, ThrowOnError>, \"credentials\" | \"responseTransformer\">;\nexport type LoginResult<ThrowOnError extends boolean = false> = Awaited<RequestResult<GetCurrentUserResponses, GetCurrentUserErrors, ThrowOnError>>;\n\nexport * from \"./generated/types.gen\";\n"]}
@@ -0,0 +1,74 @@
1
+ 'use strict';
2
+
3
+ var EventEmitter = require('events');
4
+ var WebSocket = require('isomorphic-ws');
5
+ var debug = require('debug');
6
+
7
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
+
9
+ var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter);
10
+ var WebSocket__default = /*#__PURE__*/_interopDefault(WebSocket);
11
+ var debug__default = /*#__PURE__*/_interopDefault(debug);
12
+
13
+ // src/websocket.ts
14
+ var log = debug__default.default("vrchat");
15
+
16
+ // src/websocket.ts
17
+ var logWebsocket = log.extend("websocket");
18
+ var baseUrl = "wss://pipeline.vrchat.cloud";
19
+ var VRChatWebsocket = class extends EventEmitter__default.default {
20
+ constructor(options = {}, vrchat) {
21
+ super();
22
+ this.options = options;
23
+ this.vrchat = vrchat;
24
+ this.url = new URL(this.options.baseUrl ?? baseUrl);
25
+ if (options.authToken)
26
+ this.authenticate(options.authToken);
27
+ process.on("beforeExit", () => this.close());
28
+ process.on("SIGINT", () => this.close());
29
+ }
30
+ url;
31
+ websocket;
32
+ get connected() {
33
+ return this.websocket?.readyState === WebSocket__default.default.OPEN;
34
+ }
35
+ close() {
36
+ if (!this.websocket || this.websocket.readyState === WebSocket__default.default.CLOSED)
37
+ return;
38
+ logWebsocket("%s()", this.close.name);
39
+ this.websocket.close();
40
+ }
41
+ async authenticate(authToken) {
42
+ logWebsocket('%s(authToken: "%s")', this.authenticate.name, authToken);
43
+ this.close();
44
+ this.url.searchParams.set("authToken", authToken);
45
+ this.websocket = new WebSocket__default.default(this.url, {
46
+ headers: Object.fromEntries(this.options.headers?.entries() ?? [])
47
+ });
48
+ this.websocket.addEventListener("open", (event) => {
49
+ logWebsocket("%s", event.type);
50
+ });
51
+ this.websocket.addEventListener("close", (event) => {
52
+ logWebsocket("%s: %s", event.type, event.reason);
53
+ });
54
+ this.websocket.addEventListener("error", (event) => {
55
+ logWebsocket("%s: %O", event.type, event.error);
56
+ });
57
+ this.websocket.addEventListener("message", (event) => {
58
+ try {
59
+ const { type, content: _content } = JSON.parse(event.data.toString());
60
+ const content = JSON.parse(_content);
61
+ logWebsocket("%s: %O", type, content);
62
+ this.emit(type, content);
63
+ } catch (reason) {
64
+ logWebsocket("Malformed message: %O", event.data);
65
+ logWebsocket(reason);
66
+ }
67
+ });
68
+ }
69
+ };
70
+
71
+ exports.VRChatWebsocket = VRChatWebsocket;
72
+ exports.log = log;
73
+ //# sourceMappingURL=chunk-OCTHAJNR.js.map
74
+ //# sourceMappingURL=chunk-OCTHAJNR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/log.ts","../src/websocket.ts"],"names":["debug","EventEmitter","WebSocket"],"mappings":"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","file":"chunk-OCTHAJNR.js","sourcesContent":["import debug from \"debug\";\n\nexport const log = debug(\"vrchat\");\n","import EventEmitter from \"node:events\";\n\nimport WebSocket from \"isomorphic-ws\";\nimport type TypedEventEmitter from \"typed-emitter\";\n\nimport type { VRChat } from \"./client\";\nimport type { Events } from \"./events\";\nimport { log } from \"./lib/log\";\n\nconst logWebsocket = log.extend(\"websocket\");\nconst baseUrl = \"wss://pipeline.vrchat.cloud\";\n\nexport interface VRChatWebsocketOptions {\n\tbaseUrl?: string;\n\theaders?: Headers;\n\tauthToken?: string;\n}\n\nexport class VRChatWebsocket extends (EventEmitter as new () => TypedEventEmitter<Events>) {\n\tprivate url!: URL;\n\tprivate websocket?: WebSocket;\n\n\tpublic constructor(\n\t\tpublic readonly options: VRChatWebsocketOptions = {},\n\t\tprivate readonly vrchat?: VRChat\n\t) {\n\t\tsuper();\n\n\t\tthis.url = new URL(this.options.baseUrl ?? baseUrl);\n\n\t\tif (options.authToken)\n\t\t\tthis.authenticate(options.authToken);\n\n\t\tprocess.on(\"beforeExit\", () => this.close());\n\t\tprocess.on(\"SIGINT\", () => this.close());\n\t}\n\n\tpublic get connected(): boolean {\n\t\treturn this.websocket?.readyState === WebSocket.OPEN;\n\t}\n\n\tpublic close(): void {\n\t\tif (!this.websocket || this.websocket.readyState === WebSocket.CLOSED)\n\t\t\treturn;\n\n\t\tlogWebsocket(\"%s()\", this.close.name);\n\t\tthis.websocket.close();\n\t}\n\n\tpublic async authenticate(authToken: string): Promise<void> {\n\t\tlogWebsocket(\"%s(authToken: \\\"%s\\\")\", this.authenticate.name, authToken);\n\n\t\tthis.close();\n\t\tthis.url.searchParams.set(\"authToken\", authToken);\n\n\t\tthis.websocket = new WebSocket(this.url, {\n\t\t\theaders: Object.fromEntries(this.options.headers?.entries() ?? [])\n\t\t});\n\n\t\tthis.websocket.addEventListener(\"open\", (event: WebSocket.Event) => {\n\t\t\tlogWebsocket(\"%s\", event.type);\n\t\t});\n\n\t\tthis.websocket.addEventListener(\"close\", (event: WebSocket.CloseEvent) => {\n\t\t\tlogWebsocket(\"%s: %s\", event.type, event.reason);\n\t\t});\n\n\t\tthis.websocket.addEventListener(\"error\", (event: WebSocket.ErrorEvent) => {\n\t\t\tlogWebsocket(\"%s: %O\", event.type, event.error);\n\t\t});\n\n\t\tthis.websocket.addEventListener(\"message\", (event: WebSocket.MessageEvent) => {\n\t\t\ttry {\n\t\t\t\tconst { type, content: _content } = JSON.parse(event.data.toString());\n\t\t\t\tconst content = JSON.parse(_content);\n\n\t\t\t\tlogWebsocket(\"%s: %O\", type, content);\n\n\t\t\t\tthis.emit(type, content);\n\t\t\t}\n\t\t\tcatch (reason) {\n\t\t\t\tlogWebsocket(\"Malformed message: %O\", event.data);\n\t\t\t\tlogWebsocket(reason);\n\t\t\t}\n\t\t});\n\t}\n}\n"]}