opencode-qwen-oauth 1.1.0 → 2.1.0

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,8 +1,13 @@
1
1
  # opencode-qwen-oauth
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/opencode-qwen-oauth.svg)](https://www.npmjs.com/package/opencode-qwen-oauth)
4
- [![npm downloads](https://img.shields.io/npm/dm/opencode-qwen-oauth.svg)](https://www.npmjs.com/package/opencode-qwen-oauth)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
3
+ [![npm version](https://img.shields.io/npm/v/opencode-qwen-oauth.svg?style=flat-square)](https://www.npmjs.com/package/opencode-qwen-oauth)
4
+ [![npm downloads](https://img.shields.io/npm/dm/opencode-qwen-oauth.svg?style=flat-square)](https://www.npmjs.com/package/opencode-qwen-oauth)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](LICENSE)
6
+ [![CI Status](https://img.shields.io/github/actions/workflow/status/dreygur/opencode-qwen-oauth/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/dreygur/opencode-qwen-oauth/actions)
7
+ [![Security Audit](https://img.shields.io/badge/security-audited-success?style=flat-square)](AUDIT.md)
8
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
9
+ [![OpenCode](https://img.shields.io/badge/OpenCode-Plugin-purple?style=flat-square)](https://opencode.ai)
10
+ [![Qwen](https://img.shields.io/badge/Qwen.ai-OAuth-red?style=flat-square)](https://qwen.ai)
6
11
 
7
12
  Qwen OAuth authentication plugin for [OpenCode](https://opencode.ai) - authenticate with Qwen.ai using OAuth device flow (PKCE).
8
13
 
@@ -14,6 +19,10 @@ Qwen OAuth authentication plugin for [OpenCode](https://opencode.ai) - authentic
14
19
  - 📝 **File Logging** - All OAuth activity logged to `~/.config/opencode/logs/qwen-oauth.log`
15
20
  - 🐛 **Debug Mode** - Enable verbose output with `QWEN_OAUTH_DEBUG=true`
16
21
  - 🚀 **Easy Install** - One-command installation with CLI tool
22
+ - 🎯 **Custom Headers** - Automatically adds Qwen-specific headers to API requests
23
+ - ⚙️ **Optimized Parameters** - Pre-configured temperature and topP settings for Qwen models
24
+ - 🌍 **Environment Variables** - Exposes Qwen credentials to shell environments
25
+ - 📊 **Event Monitoring** - Tracks authentication and session events for debugging
17
26
 
18
27
  ## Quick Start
19
28
 
@@ -139,6 +148,25 @@ Use the CLI directly:
139
148
  opencode auth login qwen
140
149
  ```
141
150
 
151
+ ### Browser doesn't open automatically (Linux)
152
+ The plugin tries multiple methods to open your browser:
153
+ 1. First tries `xdg-open` (standard Linux)
154
+ 2. Falls back to: `google-chrome`, `firefox`, `chromium`, `brave-browser`, `microsoft-edge`
155
+
156
+ If none work, manually copy the URL shown in the terminal and open it in your browser.
157
+
158
+ To ensure browser opening works, install `xdg-utils`:
159
+ ```bash
160
+ # Ubuntu/Debian
161
+ sudo apt install xdg-utils
162
+
163
+ # Fedora/RHEL
164
+ sudo dnf install xdg-utils
165
+
166
+ # Arch Linux
167
+ sudo pacman -S xdg-utils
168
+ ```
169
+
142
170
  ### Check logs
143
171
  ```bash
144
172
  cat ~/.config/opencode/logs/qwen-oauth.log
@@ -181,12 +209,47 @@ cd /path/to/project
181
209
  opencode-qwen-oauth install
182
210
  ```
183
211
 
212
+ ## Plugin Architecture
213
+
214
+ This plugin implements multiple OpenCode plugin hooks:
215
+
216
+ ### Hooks Implemented
217
+
218
+ #### `auth` Hook
219
+ Provides OAuth device flow authentication with automatic browser opening and token polling.
220
+
221
+ #### `config` Hook
222
+ Dynamically registers the Qwen provider and available models with OpenCode.
223
+
224
+ #### `event` Hook
225
+ Monitors session events (creation, errors) for debugging and logging.
226
+
227
+ #### `chat.headers` Hook
228
+ Injects custom headers for Qwen API requests:
229
+ - `X-Qwen-Client: OpenCode`
230
+ - `X-Qwen-Plugin-Version: 1.1.0`
231
+
232
+ #### `chat.params` Hook
233
+ Optimizes model parameters for Qwen:
234
+ - Temperature: `0.7` (default)
235
+ - Top P: `0.95` (default)
236
+
237
+ #### `shell.env` Hook
238
+ Exposes environment variables to shell commands:
239
+ - `QWEN_API_BASE_URL` - Qwen API endpoint
240
+ - `QWEN_PROVIDER` - Provider identifier
241
+
184
242
  ## Project Structure
185
243
 
186
244
  ```
187
245
  opencode-qwen-oauth/
188
246
  ├── src/ # TypeScript source files
189
- └── index.ts # Main plugin implementation
247
+ ├── index.ts # Main plugin with hooks
248
+ │ ├── oauth.ts # OAuth device flow logic
249
+ │ ├── pkce.ts # PKCE implementation
250
+ │ ├── browser.ts # Browser opening utility
251
+ │ ├── logger.ts # Logging utilities
252
+ │ └── constants.ts # API constants
190
253
  ├── bin/ # CLI scripts
191
254
  │ └── install.js # Installer script
192
255
  ├── dist/ # Compiled JavaScript (generated)
package/dist/browser.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  /**
2
2
  * Browser utilities for opening URLs
3
3
  */
4
+ /**
5
+ * Opens a URL in the default browser
6
+ * Supports macOS, Windows, and Linux with fallback mechanisms
7
+ * Debounced to prevent multiple rapid calls
8
+ */
4
9
  export declare function openBrowser(url: string): void;
5
10
  //# sourceMappingURL=browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAmB7C"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE7C"}
package/dist/browser.js CHANGED
@@ -2,23 +2,86 @@
2
2
  * Browser utilities for opening URLs
3
3
  */
4
4
  import { spawn } from "node:child_process";
5
+ import { Debouncer } from "./mutex.js";
6
+ // Debouncer to prevent multiple rapid browser opens
7
+ const browserDebouncer = new Debouncer();
8
+ /**
9
+ * Opens a URL in the default browser
10
+ * Supports macOS, Windows, and Linux with fallback mechanisms
11
+ * Debounced to prevent multiple rapid calls
12
+ */
5
13
  export function openBrowser(url) {
14
+ openBrowserDebounced(url);
15
+ }
16
+ /**
17
+ * Internal debounced browser opening function
18
+ */
19
+ const openBrowserDebounced = browserDebouncer.debounce(async (url) => {
20
+ openBrowserInternal(url);
21
+ }, 1000);
22
+ /**
23
+ * Internal function that actually opens the browser
24
+ */
25
+ function openBrowserInternal(url) {
6
26
  try {
7
27
  const platform = process.platform;
8
- const command = platform === "darwin"
9
- ? "open"
10
- : platform === "win32"
11
- ? "rundll32"
12
- : "xdg-open";
13
- const args = platform === "win32" ? ["url.dll,FileProtocolHandler", url] : [url];
28
+ let command;
29
+ let args;
30
+ if (platform === "darwin") {
31
+ // macOS
32
+ command = "open";
33
+ args = [url];
34
+ }
35
+ else if (platform === "win32") {
36
+ // Windows
37
+ command = "rundll32";
38
+ args = ["url.dll,FileProtocolHandler", url];
39
+ }
40
+ else {
41
+ // Linux and other Unix-like systems
42
+ // Try xdg-open first, with fallbacks
43
+ command = "xdg-open";
44
+ args = [url];
45
+ // Check if xdg-open exists, if not try common browsers
46
+ const child = spawn(command, args, {
47
+ stdio: "ignore",
48
+ detached: true,
49
+ });
50
+ child.on("error", (error) => {
51
+ // xdg-open failed, try common Linux browsers
52
+ const browsers = [
53
+ "google-chrome",
54
+ "firefox",
55
+ "chromium",
56
+ "brave-browser",
57
+ "microsoft-edge",
58
+ ];
59
+ for (const browser of browsers) {
60
+ try {
61
+ const browserChild = spawn(browser, [url], {
62
+ stdio: "ignore",
63
+ detached: true,
64
+ });
65
+ browserChild.unref?.();
66
+ return; // Success, exit
67
+ }
68
+ catch {
69
+ // Try next browser
70
+ continue;
71
+ }
72
+ }
73
+ });
74
+ child.unref?.();
75
+ return;
76
+ }
14
77
  const child = spawn(command, args, {
15
78
  stdio: "ignore",
16
79
  detached: true,
17
80
  });
18
81
  child.unref?.();
19
82
  }
20
- catch {
21
- // Ignore errors
83
+ catch (error) {
84
+ // Silently fail - user can manually open the URL
22
85
  }
23
86
  }
24
87
  //# sourceMappingURL=browser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAClC,MAAM,OAAO,GACX,QAAQ,KAAK,QAAQ;YACnB,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,QAAQ,KAAK,OAAO;gBACpB,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,UAAU,CAAC;QACnB,MAAM,IAAI,GACR,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACtE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,oDAAoD;AACpD,MAAM,gBAAgB,GAAG,IAAI,SAAS,EAAE,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,oBAAoB,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,QAAQ,CACpD,KAAK,EAAE,GAAW,EAAiB,EAAE;IACnC,mBAAmB,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC,EACD,IAAI,CACL,CAAC;AAEF;;GAEG;AACH,SAAS,mBAAmB,CAAC,GAAW;IACtC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAElC,IAAI,OAAe,CAAC;QACpB,IAAI,IAAc,CAAC;QAEnB,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,QAAQ;YACR,OAAO,GAAG,MAAM,CAAC;YACjB,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACf,CAAC;aAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YAChC,UAAU;YACV,OAAO,GAAG,UAAU,CAAC;YACrB,IAAI,GAAG,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,oCAAoC;YACpC,qCAAqC;YACrC,OAAO,GAAG,UAAU,CAAC;YACrB,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;YAEb,uDAAuD;YACvD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;gBACjC,KAAK,EAAE,QAAQ;gBACf,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1B,6CAA6C;gBAC7C,MAAM,QAAQ,GAAG;oBACf,eAAe;oBACf,SAAS;oBACT,UAAU;oBACV,eAAe;oBACf,gBAAgB;iBACjB,CAAC;gBAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;oBAC/B,IAAI,CAAC;wBACH,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE;4BACzC,KAAK,EAAE,QAAQ;4BACf,QAAQ,EAAE,IAAI;yBACf,CAAC,CAAC;wBACH,YAAY,CAAC,KAAK,EAAE,EAAE,CAAC;wBACvB,OAAO,CAAC,gBAAgB;oBAC1B,CAAC;oBAAC,MAAM,CAAC;wBACP,mBAAmB;wBACnB,SAAS;oBACX,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,iDAAiD;IACnD,CAAC;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Configuration system for Qwen OAuth Plugin
3
+ */
4
+ export interface QwenConfig {
5
+ /** Request timeout in milliseconds */
6
+ timeout: number;
7
+ /** Maximum number of retries for failed requests */
8
+ maxRetries: number;
9
+ /** Time before token expiry to trigger refresh (milliseconds) */
10
+ refreshThreshold: number;
11
+ /** Logging level */
12
+ logLevel: "debug" | "info" | "warn" | "error";
13
+ /** Base delay for exponential backoff (milliseconds) */
14
+ baseRetryDelay: number;
15
+ /** Maximum delay for exponential backoff (milliseconds) */
16
+ maxRetryDelay: number;
17
+ }
18
+ export declare const defaultConfig: QwenConfig;
19
+ /**
20
+ * Get configuration with environment variable overrides
21
+ */
22
+ export declare function getConfig(): QwenConfig;
23
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB;IACpB,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC9C,wDAAwD;IACxD,cAAc,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,aAAa,EAAE,UAO3B,CAAC;AAEF;;GAEG;AACH,wBAAgB,SAAS,IAAI,UAAU,CAStC"}
package/dist/config.js ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Configuration system for Qwen OAuth Plugin
3
+ */
4
+ export const defaultConfig = {
5
+ timeout: 30000, // 30 seconds
6
+ maxRetries: 3,
7
+ refreshThreshold: 300000, // 5 minutes
8
+ logLevel: process.env.QWEN_OAUTH_DEBUG === "true" ? "debug" : "info",
9
+ baseRetryDelay: 1000, // 1 second
10
+ maxRetryDelay: 30000, // 30 seconds
11
+ };
12
+ /**
13
+ * Get configuration with environment variable overrides
14
+ */
15
+ export function getConfig() {
16
+ return {
17
+ timeout: parseInt(process.env.QWEN_OAUTH_TIMEOUT || String(defaultConfig.timeout)),
18
+ maxRetries: parseInt(process.env.QWEN_OAUTH_MAX_RETRIES || String(defaultConfig.maxRetries)),
19
+ refreshThreshold: parseInt(process.env.QWEN_OAUTH_REFRESH_THRESHOLD || String(defaultConfig.refreshThreshold)),
20
+ logLevel: process.env.QWEN_OAUTH_LOG_LEVEL || defaultConfig.logLevel,
21
+ baseRetryDelay: defaultConfig.baseRetryDelay,
22
+ maxRetryDelay: defaultConfig.maxRetryDelay,
23
+ };
24
+ }
25
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiBH,MAAM,CAAC,MAAM,aAAa,GAAe;IACvC,OAAO,EAAE,KAAK,EAAE,aAAa;IAC7B,UAAU,EAAE,CAAC;IACb,gBAAgB,EAAE,MAAM,EAAE,YAAY;IACtC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;IACpE,cAAc,EAAE,IAAI,EAAE,WAAW;IACjC,aAAa,EAAE,KAAK,EAAE,aAAa;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO;QACL,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAClF,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAC5F,gBAAgB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,MAAM,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAC9G,QAAQ,EAAG,OAAO,CAAC,GAAG,CAAC,oBAA4B,IAAI,aAAa,CAAC,QAAQ;QAC7E,cAAc,EAAE,aAAa,CAAC,cAAc;QAC5C,aAAa,EAAE,aAAa,CAAC,aAAa;KAC3C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Custom error types for Qwen OAuth Plugin
3
+ */
4
+ export declare class QwenAuthError extends Error {
5
+ code: string;
6
+ recoverable: boolean;
7
+ userMessage?: string | undefined;
8
+ constructor(message: string, code: string, recoverable?: boolean, userMessage?: string | undefined);
9
+ }
10
+ export declare class NetworkError extends QwenAuthError {
11
+ constructor(message: string, userMessage?: string);
12
+ }
13
+ export declare class TokenExpiredError extends QwenAuthError {
14
+ constructor(message?: string);
15
+ }
16
+ export declare class RateLimitError extends QwenAuthError {
17
+ constructor(message: string, waitTimeMs?: number);
18
+ }
19
+ export declare class AuthorizationError extends QwenAuthError {
20
+ constructor(message: string);
21
+ }
22
+ export declare class ValidationError extends QwenAuthError {
23
+ constructor(message: string, field?: string);
24
+ }
25
+ export declare class DeviceFlowError extends QwenAuthError {
26
+ errorType?: string | undefined;
27
+ constructor(message: string, errorType?: string | undefined);
28
+ }
29
+ export declare class QwenTokenRefreshError extends QwenAuthError {
30
+ constructor(message: string);
31
+ }
32
+ /**
33
+ * Type guard to check if error is recoverable
34
+ */
35
+ export declare function isRecoverableError(error: unknown): boolean;
36
+ /**
37
+ * Get user-friendly error message
38
+ */
39
+ export declare function getUserMessage(error: unknown): string;
40
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,aAAc,SAAQ,KAAK;IAG7B,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,OAAO;IACpB,WAAW,CAAC,EAAE,MAAM;gBAH3B,OAAO,EAAE,MAAM,EACR,IAAI,EAAE,MAAM,EACZ,WAAW,GAAE,OAAc,EAC3B,WAAW,CAAC,EAAE,MAAM,YAAA;CAM9B;AAED,qBAAa,YAAa,SAAQ,aAAa;gBACjC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM;CASlD;AAED,qBAAa,iBAAkB,SAAQ,aAAa;gBACtC,OAAO,GAAE,MAA4B;CASlD;AAED,qBAAa,cAAe,SAAQ,aAAa;gBACnC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;CAOjD;AAED,qBAAa,kBAAmB,SAAQ,aAAa;gBACvC,OAAO,EAAE,MAAM;CAS5B;AAED,qBAAa,eAAgB,SAAQ,aAAa;gBACpC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAS5C;AAED,qBAAa,eAAgB,SAAQ,aAAa;IACZ,SAAS,CAAC,EAAE,MAAM;gBAA1C,OAAO,EAAE,MAAM,EAAS,SAAS,CAAC,EAAE,MAAM,YAAA;CAIvD;AAED,qBAAa,qBAAsB,SAAQ,aAAa;gBAC1C,OAAO,EAAE,MAAM;CAS5B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAK1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQrD"}
package/dist/errors.js ADDED
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Custom error types for Qwen OAuth Plugin
3
+ */
4
+ export class QwenAuthError extends Error {
5
+ code;
6
+ recoverable;
7
+ userMessage;
8
+ constructor(message, code, recoverable = true, userMessage) {
9
+ super(message);
10
+ this.code = code;
11
+ this.recoverable = recoverable;
12
+ this.userMessage = userMessage;
13
+ this.name = "QwenAuthError";
14
+ Error.captureStackTrace(this, this.constructor);
15
+ }
16
+ }
17
+ export class NetworkError extends QwenAuthError {
18
+ constructor(message, userMessage) {
19
+ super(message, "NETWORK_ERROR", true, userMessage || "Network request failed. Please check your connection.");
20
+ this.name = "NetworkError";
21
+ }
22
+ }
23
+ export class TokenExpiredError extends QwenAuthError {
24
+ constructor(message = "Token has expired") {
25
+ super(message, "TOKEN_EXPIRED", true, "Your authentication token has expired. Please re-authenticate.");
26
+ this.name = "TokenExpiredError";
27
+ }
28
+ }
29
+ export class RateLimitError extends QwenAuthError {
30
+ constructor(message, waitTimeMs) {
31
+ const userMsg = waitTimeMs
32
+ ? `Rate limit exceeded. Please wait ${Math.ceil(waitTimeMs / 1000)} seconds.`
33
+ : "Rate limit exceeded. Please try again later.";
34
+ super(message, "RATE_LIMIT_EXCEEDED", true, userMsg);
35
+ this.name = "RateLimitError";
36
+ }
37
+ }
38
+ export class AuthorizationError extends QwenAuthError {
39
+ constructor(message) {
40
+ super(message, "AUTHORIZATION_ERROR", false, "Authorization failed. Please check your credentials.");
41
+ this.name = "AuthorizationError";
42
+ }
43
+ }
44
+ export class ValidationError extends QwenAuthError {
45
+ constructor(message, field) {
46
+ super(message, "VALIDATION_ERROR", false, field ? `Invalid ${field}: ${message}` : message);
47
+ this.name = "ValidationError";
48
+ }
49
+ }
50
+ export class DeviceFlowError extends QwenAuthError {
51
+ errorType;
52
+ constructor(message, errorType) {
53
+ super(message, "DEVICE_FLOW_ERROR", true, message);
54
+ this.errorType = errorType;
55
+ this.name = "DeviceFlowError";
56
+ }
57
+ }
58
+ export class QwenTokenRefreshError extends QwenAuthError {
59
+ constructor(message) {
60
+ super(message, "TOKEN_REFRESH_ERROR", false, "Failed to refresh access token. Please re-authenticate.");
61
+ this.name = "QwenTokenRefreshError";
62
+ }
63
+ }
64
+ /**
65
+ * Type guard to check if error is recoverable
66
+ */
67
+ export function isRecoverableError(error) {
68
+ if (error instanceof QwenAuthError) {
69
+ return error.recoverable;
70
+ }
71
+ return false;
72
+ }
73
+ /**
74
+ * Get user-friendly error message
75
+ */
76
+ export function getUserMessage(error) {
77
+ if (error instanceof QwenAuthError && error.userMessage) {
78
+ return error.userMessage;
79
+ }
80
+ if (error instanceof Error) {
81
+ return error.message;
82
+ }
83
+ return "An unexpected error occurred";
84
+ }
85
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAM/D,eAAO,MAAM,eAAe,EAAE,MAiG7B,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAW/D,eAAO,MAAM,eAAe,EAAE,MAoM7B,CAAC;AAEF,eAAe,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -5,9 +5,13 @@
5
5
  * @packageDocumentation
6
6
  */
7
7
  import { QWEN_API_BASE_URL } from "./constants.js";
8
- import { debugLog } from "./logger.js";
8
+ import { debugLog, warnLog } from "./logger.js";
9
9
  import { openBrowser } from "./browser.js";
10
- import { authorizeDevice, pollForToken } from "./oauth.js";
10
+ import { authorizeDevice, pollForToken, refreshAccessToken } from "./oauth.js";
11
+ import { Mutex } from "./mutex.js";
12
+ import { QwenTokenRefreshError } from "./errors.js";
13
+ // Mutex to prevent multiple concurrent authorization flows
14
+ const authorizationMutex = new Mutex();
11
15
  export const QwenOAuthPlugin = async ({ project, client, $, directory, worktree, }) => {
12
16
  debugLog("Plugin initialized", {
13
17
  directory,
@@ -22,40 +26,65 @@ export const QwenOAuthPlugin = async ({ project, client, $, directory, worktree,
22
26
  type: "oauth",
23
27
  label: "Qwen Code (qwen.ai OAuth)",
24
28
  authorize: async () => {
25
- debugLog("Starting Qwen OAuth device flow...");
26
- const device = await authorizeDevice();
27
- const url = device.verification_uri_complete || device.verification_uri;
28
- // Try to open browser automatically
29
- openBrowser(url);
30
- debugLog("Device authorization received", {
31
- user_code: device.user_code,
32
- verification_uri: device.verification_uri,
33
- expires_in: device.expires_in,
34
- interval: device.interval,
35
- });
36
- return {
37
- url,
38
- instructions: `Enter code: ${device.user_code}`,
39
- method: "auto",
40
- callback: async () => {
41
- debugLog("Polling for OAuth token...");
42
- const result = await pollForToken(device.device_code, device.verifier, device.interval, device.expires_in);
43
- if (result.success) {
44
- debugLog("Qwen authentication successful!", {
45
- expires_in: result.expires_in,
46
- has_refresh: !!result.refresh_token,
47
- });
48
- return {
49
- type: "success",
50
- access: result.access_token,
51
- refresh: result.refresh_token,
52
- expires: Date.now() + result.expires_in * 1000,
53
- };
54
- }
55
- debugLog(`Authentication failed: ${result.error}`);
56
- return { type: "failed", error: result.error };
57
- },
58
- };
29
+ // Check if authorization is already in progress
30
+ if (authorizationMutex.isLocked()) {
31
+ warnLog("Authorization already in progress");
32
+ throw new Error("Authorization already in progress. Please wait for the current flow to complete.");
33
+ }
34
+ return authorizationMutex.runExclusive(async () => {
35
+ debugLog("Starting Qwen OAuth device flow...");
36
+ const device = await authorizeDevice();
37
+ const url = device.verification_uri_complete || device.verification_uri;
38
+ // Try to open browser automatically
39
+ openBrowser(url);
40
+ debugLog("Device authorization received", {
41
+ user_code: device.user_code,
42
+ verification_uri: device.verification_uri,
43
+ expires_in: device.expires_in,
44
+ interval: device.interval,
45
+ });
46
+ return {
47
+ url,
48
+ instructions: `Enter code: ${device.user_code}`,
49
+ method: "auto",
50
+ callback: async () => {
51
+ debugLog("Polling for OAuth token...");
52
+ const result = await pollForToken(device.device_code, device.verifier, device.interval, device.expires_in);
53
+ if (result.success) {
54
+ debugLog("Qwen authentication successful!", {
55
+ expires_in: result.expires_in,
56
+ has_refresh: !!result.refresh_token,
57
+ });
58
+ return {
59
+ type: "success",
60
+ access: result.access_token,
61
+ refresh: result.refresh_token,
62
+ expires: Date.now() + result.expires_in * 1000,
63
+ };
64
+ }
65
+ debugLog(`Authentication failed: ${result.error}`);
66
+ return { type: "failed", error: result.error };
67
+ },
68
+ };
69
+ }); // End runExclusive
70
+ },
71
+ refresh: async (refreshToken) => {
72
+ debugLog("Refreshing Qwen access token...");
73
+ const result = await refreshAccessToken(refreshToken);
74
+ if (result.success) {
75
+ debugLog("Token refresh successful", {
76
+ expires_in: result.expires_in,
77
+ has_refresh: !!result.refresh_token,
78
+ });
79
+ return {
80
+ type: "success",
81
+ access: result.access_token,
82
+ refresh: result.refresh_token,
83
+ expires: Date.now() + result.expires_in * 1000,
84
+ };
85
+ }
86
+ debugLog(`Token refresh failed: ${result.error}`);
87
+ throw new QwenTokenRefreshError(result.error || "Invalid refresh token or client_id");
59
88
  },
60
89
  },
61
90
  ],
@@ -82,6 +111,63 @@ export const QwenOAuthPlugin = async ({ project, client, $, directory, worktree,
82
111
  },
83
112
  };
84
113
  },
114
+ // Event monitoring hook
115
+ event: async ({ event }) => {
116
+ // Log important events for debugging
117
+ if (event.type === "session.error") {
118
+ debugLog("Session error occurred", {
119
+ type: event.type,
120
+ timestamp: new Date().toISOString(),
121
+ });
122
+ }
123
+ if (event.type === "session.created") {
124
+ debugLog("New session created", {
125
+ type: event.type,
126
+ timestamp: new Date().toISOString(),
127
+ });
128
+ }
129
+ },
130
+ // Inject custom headers for Qwen API requests
131
+ "chat.headers": async (input, output) => {
132
+ // Only add headers for Qwen provider
133
+ if (input.provider.info.id === "qwen") {
134
+ debugLog("Adding custom headers for Qwen request", {
135
+ model: input.model.id,
136
+ session: input.sessionID,
137
+ });
138
+ // Add any custom headers needed for Qwen
139
+ // OpenCode will automatically handle the Authorization header
140
+ output.headers["X-Qwen-Client"] = "OpenCode";
141
+ output.headers["X-Qwen-Plugin-Version"] = "1.1.0";
142
+ }
143
+ },
144
+ // Customize model parameters for Qwen
145
+ "chat.params": async (input, output) => {
146
+ if (input.provider.info.id === "qwen") {
147
+ debugLog("Customizing parameters for Qwen model", {
148
+ model: input.model.id,
149
+ current_temp: output.temperature,
150
+ });
151
+ // Qwen models work well with these defaults
152
+ // Users can override these in their config
153
+ if (output.temperature === undefined) {
154
+ output.temperature = 0.7;
155
+ }
156
+ if (output.topP === undefined) {
157
+ output.topP = 0.95;
158
+ }
159
+ }
160
+ },
161
+ // Expose Qwen credentials as environment variables if needed
162
+ "shell.env": async (input, output) => {
163
+ debugLog("Setting up shell environment", {
164
+ cwd: input.cwd,
165
+ hasSession: !!input.sessionID,
166
+ });
167
+ // Add Qwen-specific environment variables
168
+ output.env.QWEN_API_BASE_URL = QWEN_API_BASE_URL;
169
+ output.env.QWEN_PROVIDER = "qwen";
170
+ },
85
171
  };
86
172
  };
87
173
  export default QwenOAuthPlugin;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,2DAA2D;AAC3D,MAAM,kBAAkB,GAAG,IAAI,KAAK,EAAE,CAAC;AAEvC,MAAM,CAAC,MAAM,eAAe,GAAW,KAAK,EAAE,EAC5C,OAAO,EACP,MAAM,EACN,CAAC,EACD,SAAS,EACT,QAAQ,GACI,EAAE,EAAE;IAChB,QAAQ,CAAC,oBAAoB,EAAE;QAC7B,SAAS;QACT,QAAQ;QACR,OAAO,EAAG,OAAe,EAAE,IAAI,IAAI,KAAK;KACzC,CAAC,CAAC;IAEH,OAAO;QACL,IAAI,EAAE;YACJ,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,2BAA2B;oBAClC,SAAS,EAAE,KAAK,IAAI,EAAE;wBACpB,gDAAgD;wBAChD,IAAI,kBAAkB,CAAC,QAAQ,EAAE,EAAE,CAAC;4BAClC,OAAO,CAAC,mCAAmC,CAAC,CAAC;4BAC7C,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;wBACJ,CAAC;wBAED,OAAO,kBAAkB,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;4BAChD,QAAQ,CAAC,oCAAoC,CAAC,CAAC;4BAE/C,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;4BACvC,MAAM,GAAG,GACP,MAAM,CAAC,yBAAyB,IAAI,MAAM,CAAC,gBAAgB,CAAC;4BAE9D,oCAAoC;4BACpC,WAAW,CAAC,GAAG,CAAC,CAAC;4BAEjB,QAAQ,CAAC,+BAA+B,EAAE;gCACxC,SAAS,EAAE,MAAM,CAAC,SAAS;gCAC3B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;gCACzC,UAAU,EAAE,MAAM,CAAC,UAAU;gCAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;6BAC1B,CAAC,CAAC;4BAEH,OAAO;gCACL,GAAG;gCACH,YAAY,EAAE,eAAe,MAAM,CAAC,SAAS,EAAE;gCAC/C,MAAM,EAAE,MAAM;gCACd,QAAQ,EAAE,KAAK,IAAI,EAAE;oCACrB,QAAQ,CAAC,4BAA4B,CAAC,CAAC;oCACvC,MAAM,MAAM,GAAG,MAAM,YAAY,CAC/B,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,UAAU,CAClB,CAAC;oCAEF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;wCACnB,QAAQ,CAAC,iCAAiC,EAAE;4CAC1C,UAAU,EAAE,MAAM,CAAC,UAAU;4CAC7B,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa;yCACpC,CAAC,CAAC;wCACH,OAAO;4CACL,IAAI,EAAE,SAAS;4CACf,MAAM,EAAE,MAAM,CAAC,YAAa;4CAC5B,OAAO,EAAE,MAAM,CAAC,aAAc;4CAC9B,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAW,GAAG,IAAI;yCAChD,CAAC;oCACJ,CAAC;oCAED,QAAQ,CAAC,0BAA0B,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;oCACnD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,KAAM,EAAE,CAAC;gCAClD,CAAC;6BACF,CAAC;wBACF,CAAC,CAAC,CAAC,CAAC,mBAAmB;oBACzB,CAAC;oBACD,OAAO,EAAE,KAAK,EAAE,YAAoB,EAAE,EAAE;wBACtC,QAAQ,CAAC,iCAAiC,CAAC,CAAC;wBAE5C,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,YAAY,CAAC,CAAC;wBAEtD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;4BACnB,QAAQ,CAAC,0BAA0B,EAAE;gCACnC,UAAU,EAAE,MAAM,CAAC,UAAU;gCAC7B,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa;6BACpC,CAAC,CAAC;4BAEH,OAAO;gCACL,IAAI,EAAE,SAAS;gCACf,MAAM,EAAE,MAAM,CAAC,YAAa;gCAC5B,OAAO,EAAE,MAAM,CAAC,aAAc;gCAC9B,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAW,GAAG,IAAI;6BAChD,CAAC;wBACJ,CAAC;wBAED,QAAQ,CAAC,yBAAyB,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;wBAClD,MAAM,IAAI,qBAAqB,CAC7B,MAAM,CAAC,KAAK,IAAI,oCAAoC,CACrD,CAAC;oBACJ,CAAC;iBACF;aACF;SACF;QACD,MAAM,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE;YAChD,MAAM,SAAS,GACZ,MAAM,CAAC,QAEN,IAAI,EAAE,CAAC;YACX,MAAM,CAAC,QAAQ,GAAG,SAAS,CAAC;YAC5B,SAAS,CAAC,MAAM,CAAC,GAAG;gBAClB,GAAG,EAAE,2BAA2B;gBAChC,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE;oBACP,OAAO,EAAE,iBAAiB;iBAC3B;gBACD,MAAM,EAAE;oBACN,kBAAkB,EAAE;wBAClB,EAAE,EAAE,kBAAkB;wBACtB,IAAI,EAAE,kBAAkB;qBACzB;oBACD,eAAe,EAAE;wBACf,EAAE,EAAE,eAAe;wBACnB,IAAI,EAAE,eAAe;wBACrB,UAAU,EAAE,IAAI;qBACjB;iBACF;aACF,CAAC;QACJ,CAAC;QAED,wBAAwB;QACxB,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;YACzB,qCAAqC;YACrC,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;gBACnC,QAAQ,CAAC,wBAAwB,EAAE;oBACjC,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBACrC,QAAQ,CAAC,qBAAqB,EAAE;oBAC9B,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACtC,qCAAqC;YACrC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;gBACtC,QAAQ,CAAC,wCAAwC,EAAE;oBACjD,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;oBACrB,OAAO,EAAE,KAAK,CAAC,SAAS;iBACzB,CAAC,CAAC;gBAEH,yCAAyC;gBACzC,8DAA8D;gBAC9D,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,CAAC;gBAC7C,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC;YACpD,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;gBACtC,QAAQ,CAAC,uCAAuC,EAAE;oBAChD,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;oBACrB,YAAY,EAAE,MAAM,CAAC,WAAW;iBACjC,CAAC,CAAC;gBAEH,4CAA4C;gBAC5C,2CAA2C;gBAC3C,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;oBACrC,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC;gBAC3B,CAAC;gBACD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC9B,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;QAED,6DAA6D;QAC7D,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACnC,QAAQ,CAAC,8BAA8B,EAAE;gBACvC,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS;aAC9B,CAAC,CAAC;YAEH,0CAA0C;YAC1C,MAAM,CAAC,GAAG,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;YACjD,MAAM,CAAC,GAAG,CAAC,aAAa,GAAG,MAAM,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,eAAe,CAAC"}
package/dist/logger.d.ts CHANGED
@@ -1,6 +1,15 @@
1
1
  /**
2
2
  * Logging utilities for Qwen OAuth Plugin
3
3
  */
4
+ export declare enum LogLevel {
5
+ DEBUG = 0,
6
+ INFO = 1,
7
+ WARN = 2,
8
+ ERROR = 3
9
+ }
4
10
  export declare const DEBUG: boolean;
5
11
  export declare function debugLog(message: string, data?: Record<string, unknown>): void;
12
+ export declare function infoLog(message: string, data?: Record<string, unknown>): void;
13
+ export declare function warnLog(message: string, data?: Record<string, unknown>): void;
14
+ export declare function errorLog(message: string, data?: Record<string, unknown>): void;
6
15
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiCH,eAAO,MAAM,KAAK,SAEoB,CAAC;AAEvC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAG9E"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AA2DD,eAAO,MAAM,KAAK,SAEoB,CAAC;AAEvC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAE9E;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAE7E;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAE7E;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAE9E"}