@zhin.js/plugin-calendar 0.1.5 → 0.1.7

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.
Files changed (70) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +6 -0
  3. package/commands/calendar/auth/index.js +7 -6
  4. package/commands/calendar/auth/index.ts +8 -6
  5. package/commands/calendar/logout/index.js +6 -5
  6. package/commands/calendar/logout/index.ts +6 -5
  7. package/commands/calendar/status/index.js +4 -3
  8. package/commands/calendar/status/index.ts +4 -3
  9. package/lib/caldav.d.ts.map +1 -1
  10. package/lib/caldav.js +4 -3
  11. package/lib/caldav.js.map +1 -1
  12. package/lib/chat-auth.d.ts +7 -5
  13. package/lib/chat-auth.d.ts.map +1 -1
  14. package/lib/chat-auth.js +48 -45
  15. package/lib/chat-auth.js.map +1 -1
  16. package/lib/config.d.ts +2 -2
  17. package/lib/config.js +9 -9
  18. package/lib/config.js.map +1 -1
  19. package/lib/credential-store.d.ts +3 -0
  20. package/lib/credential-store.d.ts.map +1 -1
  21. package/lib/credential-store.js.map +1 -1
  22. package/lib/errors.d.ts +72 -0
  23. package/lib/errors.d.ts.map +1 -0
  24. package/lib/errors.js +32 -0
  25. package/lib/errors.js.map +1 -0
  26. package/lib/free-time.d.ts.map +1 -1
  27. package/lib/free-time.js +3 -2
  28. package/lib/free-time.js.map +1 -1
  29. package/lib/i18n.d.ts +2 -0
  30. package/lib/i18n.d.ts.map +1 -0
  31. package/lib/i18n.js +133 -0
  32. package/lib/i18n.js.map +1 -0
  33. package/lib/oauth-auth.d.ts.map +1 -1
  34. package/lib/oauth-auth.js +4 -3
  35. package/lib/oauth-auth.js.map +1 -1
  36. package/lib/oauth.d.ts.map +1 -1
  37. package/lib/oauth.js +7 -6
  38. package/lib/oauth.js.map +1 -1
  39. package/lib/time.d.ts.map +1 -1
  40. package/lib/time.js +5 -7
  41. package/lib/time.js.map +1 -1
  42. package/lib/token-manager.d.ts +4 -2
  43. package/lib/token-manager.d.ts.map +1 -1
  44. package/lib/token-manager.js +12 -9
  45. package/lib/token-manager.js.map +1 -1
  46. package/lib/tool-errors.d.ts +2 -1
  47. package/lib/tool-errors.d.ts.map +1 -1
  48. package/lib/tool-errors.js +8 -2
  49. package/lib/tool-errors.js.map +1 -1
  50. package/package.json +9 -9
  51. package/plugin.js +4 -2
  52. package/schema.json +45 -0
  53. package/skills/calendar-scheduling/tools/create_event/index.js +4 -3
  54. package/skills/calendar-scheduling/tools/create_event/index.ts +4 -3
  55. package/skills/calendar-scheduling/tools/find_free_time/index.js +4 -3
  56. package/skills/calendar-scheduling/tools/find_free_time/index.ts +4 -3
  57. package/skills/calendar-scheduling/tools/list_events/index.js +5 -4
  58. package/skills/calendar-scheduling/tools/list_events/index.ts +5 -4
  59. package/src/caldav.ts +4 -3
  60. package/src/chat-auth.ts +55 -50
  61. package/src/config.ts +9 -9
  62. package/src/credential-store.ts +3 -0
  63. package/src/errors.ts +34 -0
  64. package/src/free-time.ts +3 -2
  65. package/src/i18n.ts +133 -0
  66. package/src/oauth-auth.ts +4 -5
  67. package/src/oauth.ts +7 -10
  68. package/src/time.ts +5 -4
  69. package/src/token-manager.ts +16 -13
  70. package/src/tool-errors.ts +8 -2
@@ -1,3 +1,4 @@
1
+ import { CalendarError } from './errors.js';
1
2
  /**
2
3
  * In-memory OAuth access-token cache with proactive refresh, single-flight,
3
4
  * refresh-token rotation handling, and clear invalid_grant errors.
@@ -30,8 +31,8 @@ export type AuthorizationLostListener = (
30
31
  ) => void | Promise<void>;
31
32
 
32
33
  /** Chat command that (re-)authorizes a provider; shown in user-facing errors. */
33
- export function authCommandFor(provider: OAuthProviderKind): string {
34
- return `calendar auth ${provider}`;
34
+ export function authCommandFor(provider: OAuthProviderKind, commandHead?: string): string | undefined {
35
+ return commandHead ? `${commandHead} ${provider}` : undefined;
35
36
  }
36
37
 
37
38
  export interface TokenManagerOptions {
@@ -60,10 +61,13 @@ export interface TokenManagerOptions {
60
61
 
61
62
  export class OAuthTokenError extends Error {
62
63
  readonly code: string;
63
- constructor(code: string, message: string) {
64
+ readonly presentation?: CalendarError;
65
+
66
+ constructor(code: string, message: string, presentation?: CalendarError) {
64
67
  super(message);
65
68
  this.name = "OAuthTokenError";
66
69
  this.code = code;
70
+ this.presentation = presentation;
67
71
  }
68
72
  }
69
73
 
@@ -97,11 +101,12 @@ export class OAuthTokenManager {
97
101
  if (!options.clientId.trim()) {
98
102
  throw new OAuthTokenError(
99
103
  "config",
100
- `${options.provider}: 缺少 client_id`
104
+ `${options.provider}: 缺少 client_id`,
105
+ new CalendarError('clientMissing', { provider: options.provider, field: 'client_id' })
101
106
  );
102
107
  }
103
108
  if (options.provider === "google" && !options.clientSecret?.trim()) {
104
- throw new OAuthTokenError("config", "google: 缺少 client_secret");
109
+ throw new OAuthTokenError("config", "google: 缺少 client_secret", new CalendarError('clientMissing', { provider: 'google', field: 'client_secret' }));
105
110
  }
106
111
  this.#provider = options.provider;
107
112
  this.#clientId = options.clientId.trim();
@@ -230,9 +235,7 @@ export class OAuthTokenManager {
230
235
  "not_authorized",
231
236
  `${
232
237
  this.#provider
233
- }: 日历尚未授权。请 master 在聊天中发送「${authCommandFor(
234
- this.#provider
235
- )}」完成授权。`
238
+ }: 日历尚未授权。请 master 通过日历授权入口完成授权。`
236
239
  );
237
240
  }
238
241
  const body = new URLSearchParams({
@@ -269,9 +272,7 @@ export class OAuthTokenManager {
269
272
  if (errCode === "invalid_grant" || /invalid_grant/i.test(errDesc)) {
270
273
  const message = `${
271
274
  this.#provider
272
- }: 日历授权已失效或被撤销(invalid_grant)。请 master 在聊天中发送「${authCommandFor(
273
- this.#provider
274
- )}」重新授权。详情:${errDesc}`;
275
+ }: 日历授权已失效或被撤销(invalid_grant)。请 master 通过日历授权入口重新授权。详情:${errDesc}`;
275
276
  this.#authorizationLostMessage = message;
276
277
  await this.#notifyAuthorizationLost(message);
277
278
  throw new OAuthTokenError("invalid_grant", message);
@@ -280,7 +281,8 @@ export class OAuthTokenManager {
280
281
  errCode || "http_error",
281
282
  `${this.#provider}: token 刷新失败 HTTP ${response.status}:${
282
283
  errDesc || response.statusText
283
- }`
284
+ }`,
285
+ new CalendarError('refreshHttp', { provider: this.#provider, status: response.status, detail: errDesc || response.statusText })
284
286
  );
285
287
  }
286
288
 
@@ -288,7 +290,8 @@ export class OAuthTokenManager {
288
290
  if (!accessToken) {
289
291
  throw new OAuthTokenError(
290
292
  "response",
291
- `${this.#provider}: 刷新响应缺少 access_token`
293
+ `${this.#provider}: 刷新响应缺少 access_token`,
294
+ new CalendarError('refreshAccessMissing', { provider: this.#provider })
292
295
  );
293
296
  }
294
297
  const expiresIn = Number(data.expires_in ?? 3600);
@@ -1,3 +1,6 @@
1
+ import { CalendarError } from './errors.js';
2
+ import type { Locale } from 'zhin.js/i18n';
3
+ import { messages as t } from './i18n.js';
1
4
  import { OAuthTokenError } from "./token-manager.js";
2
5
 
3
6
  /**
@@ -5,13 +8,16 @@ import { OAuthTokenError } from "./token-manager.js";
5
8
  * readable reply (e.g. "请 master 发送 calendar auth google") instead of a crash.
6
9
  */
7
10
  export async function runCalendarTool(
8
- operation: () => Promise<string>
11
+ operation: () => Promise<string>,
12
+ locale?: Locale
9
13
  ): Promise<string> {
10
14
  try {
11
15
  return await operation();
12
16
  } catch (error) {
17
+ if (error instanceof CalendarError) throw new CalendarError(error.code, error.params, locale);
13
18
  if (error instanceof OAuthTokenError) {
14
- return error.message;
19
+ if (error.code === 'invalid_grant' || error.code === 'not_authorized') return t(locale, error.code === 'invalid_grant' ? 'lost' : 'notAuthorized', { provider: 'Calendar' });
20
+ return error.presentation?.format(locale) ?? error.message;
15
21
  }
16
22
  throw error;
17
23
  }