@xquik/tweetclaw 1.6.18 → 1.6.19

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/dist/request.js CHANGED
@@ -6,6 +6,7 @@ const BEARER_PREFIX = 'Bearer ';
6
6
  const API_KEY_PREFIX = 'xq_';
7
7
  const API_V1_PREFIX = '/api/v1/';
8
8
  const SUPPORT_TICKETS_PREFIX = '/api/v1/support/tickets';
9
+ const MAX_SAFE_ERROR_CODE_LENGTH = 80;
9
10
  function buildAuthHeader(credential) {
10
11
  if (credential.startsWith(API_KEY_PREFIX)) {
11
12
  return { [API_KEY_HEADER]: credential };
@@ -84,6 +85,68 @@ function validateRequestPath(method, path) {
84
85
  throw new Error('Agent-prohibited endpoint. Account connection and re-authentication must be done through the Xquik dashboard at dashboard.xquik.com, not through the agent.');
85
86
  }
86
87
  }
88
+ async function readResponseJson(response) {
89
+ try {
90
+ return await response.json();
91
+ }
92
+ catch {
93
+ return undefined;
94
+ }
95
+ }
96
+ function isAsciiLetter(character) {
97
+ const lower = character.toLowerCase();
98
+ return lower >= 'a' && lower <= 'z';
99
+ }
100
+ function isAsciiDigit(character) {
101
+ return character >= '0' && character <= '9';
102
+ }
103
+ function isSafeErrorCodeCharacter(character) {
104
+ return isAsciiLetter(character)
105
+ || isAsciiDigit(character)
106
+ || character === '_'
107
+ || character === '.'
108
+ || character === ':'
109
+ || character === '-';
110
+ }
111
+ function isSafeErrorCode(value) {
112
+ if (value.length === 0
113
+ || value.length > MAX_SAFE_ERROR_CODE_LENGTH
114
+ || !isAsciiLetter(value.slice(0, 1))) {
115
+ return false;
116
+ }
117
+ for (const character of value) {
118
+ if (!isSafeErrorCodeCharacter(character)) {
119
+ return false;
120
+ }
121
+ }
122
+ return true;
123
+ }
124
+ function stringErrorCode(value) {
125
+ if (typeof value !== 'object' || value === null) {
126
+ return undefined;
127
+ }
128
+ if ('error' in value && typeof value.error === 'string') {
129
+ return value.error;
130
+ }
131
+ if ('code' in value && typeof value.code === 'string') {
132
+ return value.code;
133
+ }
134
+ return undefined;
135
+ }
136
+ function safeErrorCode(value) {
137
+ const code = stringErrorCode(value);
138
+ return code !== undefined && isSafeErrorCode(code) ? code : undefined;
139
+ }
140
+ function formatApiError(response, payload) {
141
+ const status = response.statusText.length > 0
142
+ ? `${String(response.status)} ${response.statusText}`
143
+ : String(response.status);
144
+ const code = safeErrorCode(payload);
145
+ if (code === undefined) {
146
+ return `API request failed: ${status}`;
147
+ }
148
+ return `API request failed: ${status} (${code})`;
149
+ }
87
150
  function createProxiedRequest(baseUrl, credential, fetchFunction = fetch) {
88
151
  return async (path, options) => {
89
152
  const method = options?.method ?? 'GET';
@@ -95,9 +158,9 @@ function createProxiedRequest(baseUrl, credential, fetchFunction = fetch) {
95
158
  method,
96
159
  signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
97
160
  });
98
- const json = await response.json();
161
+ const json = await readResponseJson(response);
99
162
  if (!response.ok) {
100
- throw new Error(`API request failed: ${String(response.status)} ${response.statusText} - ${JSON.stringify(json)}`);
163
+ throw new Error(formatApiError(response, json));
101
164
  }
102
165
  return json;
103
166
  };
@@ -1 +1 @@
1
- {"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "tweetclaw",
3
3
  "name": "TweetClaw",
4
- "version": "1.6.18",
4
+ "version": "1.6.19",
5
5
  "description": "Post tweets, reply, like, retweet, follow, DM, search, and monitor X/Twitter through structured Xquik endpoints.",
6
6
  "activation": {
7
7
  "onStartup": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xquik/tweetclaw",
3
- "version": "1.6.18",
3
+ "version": "1.6.19",
4
4
  "description": "Post tweets, reply, like, retweet, follow, DM & more from OpenClaw through structured Xquik endpoints.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "install": {
34
34
  "defaultChoice": "npm",
35
- "npmSpec": "@xquik/tweetclaw@1.6.18",
35
+ "npmSpec": "@xquik/tweetclaw@1.6.19",
36
36
  "minHostVersion": ">=2026.5.4"
37
37
  }
38
38
  },
package/src/request.ts CHANGED
@@ -8,6 +8,7 @@ const BEARER_PREFIX = 'Bearer ';
8
8
  const API_KEY_PREFIX = 'xq_';
9
9
  const API_V1_PREFIX = '/api/v1/';
10
10
  const SUPPORT_TICKETS_PREFIX = '/api/v1/support/tickets';
11
+ const MAX_SAFE_ERROR_CODE_LENGTH = 80;
11
12
 
12
13
  function buildAuthHeader(credential: string): Record<string, string> {
13
14
  if (credential.startsWith(API_KEY_PREFIX)) {
@@ -103,6 +104,77 @@ function validateRequestPath(method: string, path: string): void {
103
104
  }
104
105
  }
105
106
 
107
+ async function readResponseJson(response: Response): Promise<unknown> {
108
+ try {
109
+ return await response.json();
110
+ } catch {
111
+ return undefined;
112
+ }
113
+ }
114
+
115
+ function isAsciiLetter(character: string): boolean {
116
+ const lower = character.toLowerCase();
117
+ return lower >= 'a' && lower <= 'z';
118
+ }
119
+
120
+ function isAsciiDigit(character: string): boolean {
121
+ return character >= '0' && character <= '9';
122
+ }
123
+
124
+ function isSafeErrorCodeCharacter(character: string): boolean {
125
+ return isAsciiLetter(character)
126
+ || isAsciiDigit(character)
127
+ || character === '_'
128
+ || character === '.'
129
+ || character === ':'
130
+ || character === '-';
131
+ }
132
+
133
+ function isSafeErrorCode(value: string): boolean {
134
+ if (
135
+ value.length === 0
136
+ || value.length > MAX_SAFE_ERROR_CODE_LENGTH
137
+ || !isAsciiLetter(value.slice(0, 1))
138
+ ) {
139
+ return false;
140
+ }
141
+ for (const character of value) {
142
+ if (!isSafeErrorCodeCharacter(character)) {
143
+ return false;
144
+ }
145
+ }
146
+ return true;
147
+ }
148
+
149
+ function stringErrorCode(value: unknown): string | undefined {
150
+ if (typeof value !== 'object' || value === null) {
151
+ return undefined;
152
+ }
153
+ if ('error' in value && typeof value.error === 'string') {
154
+ return value.error;
155
+ }
156
+ if ('code' in value && typeof value.code === 'string') {
157
+ return value.code;
158
+ }
159
+ return undefined;
160
+ }
161
+
162
+ function safeErrorCode(value: unknown): string | undefined {
163
+ const code = stringErrorCode(value);
164
+ return code !== undefined && isSafeErrorCode(code) ? code : undefined;
165
+ }
166
+
167
+ function formatApiError(response: Response, payload: unknown): string {
168
+ const status = response.statusText.length > 0
169
+ ? `${String(response.status)} ${response.statusText}`
170
+ : String(response.status);
171
+ const code = safeErrorCode(payload);
172
+ if (code === undefined) {
173
+ return `API request failed: ${status}`;
174
+ }
175
+ return `API request failed: ${status} (${code})`;
176
+ }
177
+
106
178
  function createProxiedRequest(
107
179
  baseUrl: string,
108
180
  credential: string,
@@ -118,11 +190,9 @@ function createProxiedRequest(
118
190
  method,
119
191
  signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
120
192
  });
121
- const json: unknown = await response.json();
193
+ const json: unknown = await readResponseJson(response);
122
194
  if (!response.ok) {
123
- throw new Error(
124
- `API request failed: ${String(response.status)} ${response.statusText} - ${JSON.stringify(json)}`,
125
- );
195
+ throw new Error(formatApiError(response, json));
126
196
  }
127
197
  return json;
128
198
  };