@f3liz/rescript-misskey-api 0.6.9 → 0.7.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.
Files changed (113) hide show
  1. package/lib/es6/src/Misskey.mjs +133 -156
  2. package/lib/es6/src/bindings/Ofetch.mjs +2 -0
  3. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkAccount.mjs +70 -48
  4. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkAdmin.mjs +133 -98
  5. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkAntennas.mjs +9 -6
  6. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkApp.mjs +6 -4
  7. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkAuth.mjs +6 -4
  8. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkChannels.mjs +18 -12
  9. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkCharts.mjs +6 -4
  10. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkChat.mjs +70 -54
  11. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkClips.mjs +12 -8
  12. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkDefault.mjs +27 -20
  13. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkDrive.mjs +35 -24
  14. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkFederation.mjs +18 -12
  15. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkFlash.mjs +9 -6
  16. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkFlashs.mjs +3 -2
  17. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkFollowing.mjs +21 -14
  18. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkGallery.mjs +12 -8
  19. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkGroups.mjs +30 -24
  20. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkHashtags.mjs +6 -4
  21. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkLists.mjs +9 -6
  22. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkMeta.mjs +27 -18
  23. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkNotes.mjs +85 -58
  24. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkNotifications.mjs +2 -2
  25. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkPages.mjs +8 -6
  26. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkRole.mjs +9 -6
  27. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkUsers.mjs +35 -24
  28. package/lib/es6/src/generated/kokonect-link/api/KokonectLinkWebhooks.mjs +7 -6
  29. package/lib/es6/src/generated/misskey-io/api/MisskeyIoAccount.mjs +92 -68
  30. package/lib/es6/src/generated/misskey-io/api/MisskeyIoAdmin.mjs +266 -214
  31. package/lib/es6/src/generated/misskey-io/api/MisskeyIoAntennas.mjs +17 -12
  32. package/lib/es6/src/generated/misskey-io/api/MisskeyIoApp.mjs +6 -4
  33. package/lib/es6/src/generated/misskey-io/api/MisskeyIoAuth.mjs +14 -10
  34. package/lib/es6/src/generated/misskey-io/api/MisskeyIoChannels.mjs +35 -26
  35. package/lib/es6/src/generated/misskey-io/api/MisskeyIoCharts.mjs +72 -48
  36. package/lib/es6/src/generated/misskey-io/api/MisskeyIoClip.mjs +4 -4
  37. package/lib/es6/src/generated/misskey-io/api/MisskeyIoClips.mjs +17 -12
  38. package/lib/es6/src/generated/misskey-io/api/MisskeyIoDefault.mjs +133 -110
  39. package/lib/es6/src/generated/misskey-io/api/MisskeyIoDrive.mjs +51 -36
  40. package/lib/es6/src/generated/misskey-io/api/MisskeyIoFederation.mjs +32 -22
  41. package/lib/es6/src/generated/misskey-io/api/MisskeyIoFlash.mjs +12 -10
  42. package/lib/es6/src/generated/misskey-io/api/MisskeyIoFlashs.mjs +5 -4
  43. package/lib/es6/src/generated/misskey-io/api/MisskeyIoFollowing.mjs +27 -20
  44. package/lib/es6/src/generated/misskey-io/api/MisskeyIoGallery.mjs +24 -18
  45. package/lib/es6/src/generated/misskey-io/api/MisskeyIoHashtags.mjs +18 -12
  46. package/lib/es6/src/generated/misskey-io/api/MisskeyIoLists.mjs +23 -18
  47. package/lib/es6/src/generated/misskey-io/api/MisskeyIoMeta.mjs +71 -48
  48. package/lib/es6/src/generated/misskey-io/api/MisskeyIoNonProductive.mjs +5 -4
  49. package/lib/es6/src/generated/misskey-io/api/MisskeyIoNotes.mjs +96 -70
  50. package/lib/es6/src/generated/misskey-io/api/MisskeyIoNotifications.mjs +8 -8
  51. package/lib/es6/src/generated/misskey-io/api/MisskeyIoPages.mjs +17 -14
  52. package/lib/es6/src/generated/misskey-io/api/MisskeyIoReactions.mjs +4 -4
  53. package/lib/es6/src/generated/misskey-io/api/MisskeyIoResetPassword.mjs +4 -4
  54. package/lib/es6/src/generated/misskey-io/api/MisskeyIoRole.mjs +12 -8
  55. package/lib/es6/src/generated/misskey-io/api/MisskeyIoUsers.mjs +83 -56
  56. package/lib/es6/src/generated/misskey-io/api/MisskeyIoWebhooks.mjs +17 -14
  57. package/package.json +3 -2
  58. package/src/Misskey.res +92 -149
  59. package/src/bindings/Ofetch.res +14 -0
  60. package/src/generated/kokonect-link/api/KokonectLinkAccount.res +94 -166
  61. package/src/generated/kokonect-link/api/KokonectLinkAdmin.res +182 -329
  62. package/src/generated/kokonect-link/api/KokonectLinkAntennas.res +12 -21
  63. package/src/generated/kokonect-link/api/KokonectLinkApp.res +8 -14
  64. package/src/generated/kokonect-link/api/KokonectLinkAuth.res +8 -14
  65. package/src/generated/kokonect-link/api/KokonectLinkChannels.res +24 -42
  66. package/src/generated/kokonect-link/api/KokonectLinkCharts.res +8 -14
  67. package/src/generated/kokonect-link/api/KokonectLinkChat.res +97 -178
  68. package/src/generated/kokonect-link/api/KokonectLinkClips.res +16 -28
  69. package/src/generated/kokonect-link/api/KokonectLinkDefault.res +37 -67
  70. package/src/generated/kokonect-link/api/KokonectLinkDrive.res +47 -83
  71. package/src/generated/kokonect-link/api/KokonectLinkFederation.res +24 -42
  72. package/src/generated/kokonect-link/api/KokonectLinkFlash.res +12 -21
  73. package/src/generated/kokonect-link/api/KokonectLinkFlashs.res +4 -7
  74. package/src/generated/kokonect-link/api/KokonectLinkFollowing.res +28 -49
  75. package/src/generated/kokonect-link/api/KokonectLinkGallery.res +16 -28
  76. package/src/generated/kokonect-link/api/KokonectLinkGroups.res +42 -78
  77. package/src/generated/kokonect-link/api/KokonectLinkHashtags.res +8 -14
  78. package/src/generated/kokonect-link/api/KokonectLinkLists.res +12 -21
  79. package/src/generated/kokonect-link/api/KokonectLinkMeta.res +36 -63
  80. package/src/generated/kokonect-link/api/KokonectLinkNotes.res +114 -201
  81. package/src/generated/kokonect-link/api/KokonectLinkNotifications.res +3 -6
  82. package/src/generated/kokonect-link/api/KokonectLinkPages.res +11 -20
  83. package/src/generated/kokonect-link/api/KokonectLinkRole.res +12 -21
  84. package/src/generated/kokonect-link/api/KokonectLinkUsers.res +47 -83
  85. package/src/generated/kokonect-link/api/KokonectLinkWebhooks.res +10 -19
  86. package/src/generated/misskey-io/api/MisskeyIoAccount.res +126 -228
  87. package/src/generated/misskey-io/api/MisskeyIoAdmin.res +373 -694
  88. package/src/generated/misskey-io/api/MisskeyIoAntennas.res +23 -41
  89. package/src/generated/misskey-io/api/MisskeyIoApp.res +8 -14
  90. package/src/generated/misskey-io/api/MisskeyIoAuth.res +19 -34
  91. package/src/generated/misskey-io/api/MisskeyIoChannels.res +48 -87
  92. package/src/generated/misskey-io/api/MisskeyIoCharts.res +96 -168
  93. package/src/generated/misskey-io/api/MisskeyIoClip.res +6 -12
  94. package/src/generated/misskey-io/api/MisskeyIoClips.res +23 -41
  95. package/src/generated/misskey-io/api/MisskeyIoDefault.res +188 -353
  96. package/src/generated/misskey-io/api/MisskeyIoDrive.res +69 -123
  97. package/src/generated/misskey-io/api/MisskeyIoFederation.res +43 -76
  98. package/src/generated/misskey-io/api/MisskeyIoFlash.res +17 -32
  99. package/src/generated/misskey-io/api/MisskeyIoFlashs.res +7 -13
  100. package/src/generated/misskey-io/api/MisskeyIoFollowing.res +37 -67
  101. package/src/generated/misskey-io/api/MisskeyIoGallery.res +33 -60
  102. package/src/generated/misskey-io/api/MisskeyIoHashtags.res +24 -42
  103. package/src/generated/misskey-io/api/MisskeyIoLists.res +32 -59
  104. package/src/generated/misskey-io/api/MisskeyIoMeta.res +95 -167
  105. package/src/generated/misskey-io/api/MisskeyIoNonProductive.res +7 -13
  106. package/src/generated/misskey-io/api/MisskeyIoNotes.res +131 -236
  107. package/src/generated/misskey-io/api/MisskeyIoNotifications.res +12 -24
  108. package/src/generated/misskey-io/api/MisskeyIoPages.res +24 -45
  109. package/src/generated/misskey-io/api/MisskeyIoReactions.res +6 -12
  110. package/src/generated/misskey-io/api/MisskeyIoResetPassword.res +6 -12
  111. package/src/generated/misskey-io/api/MisskeyIoRole.res +16 -28
  112. package/src/generated/misskey-io/api/MisskeyIoUsers.res +111 -195
  113. package/src/generated/misskey-io/api/MisskeyIoWebhooks.res +24 -45
package/src/Misskey.res CHANGED
@@ -18,30 +18,9 @@
18
18
  // You can override it by passing ~fetch to connect() for custom behavior
19
19
  // (e.g., adding performance metrics, retries, logging, etc.).
20
20
 
21
- // ============================================================================
22
- // Fetch Bindings
23
- // ============================================================================
24
-
25
21
  // Enable JSON schema for Sury
26
22
  S.enableJson()
27
23
 
28
- module FetchBindings = {
29
- type response
30
-
31
- type requestInit = {
32
- method: string,
33
- headers: dict<string>,
34
- body: option<string>,
35
- }
36
-
37
- @val external fetch: (string, requestInit) => promise<response> = "fetch"
38
-
39
- @send external json: response => promise<JSON.t> = "json"
40
- @get external ok: response => bool = "ok"
41
- @get external status: response => int = "status"
42
- @get external statusText: response => string = "statusText"
43
- }
44
-
45
24
  // ============================================================================
46
25
  // Client & Configuration
47
26
  // ============================================================================
@@ -56,50 +35,34 @@ type t = {
56
35
  mutable streamClient: option<StreamClient.t>,
57
36
  }
58
37
 
59
- // Default fetch implementation using the browser's Fetch API.
60
- // Constructs full URL from origin + endpoint path, sets JSON headers,
61
- // and injects the auth token into the request body (Misskey API convention).
62
- let defaultFetch = (~origin: string, ~token: option<string>) => {
63
- (~url: string, ~method_: string, ~body: option<JSON.t>): Promise.t<JSON.t> => {
64
- let fullUrl = `${origin}/api/${url}`
65
-
66
- // Misskey injects the token into the request body
67
- let bodyWithToken = switch (body, token) {
68
- | (Some(jsonBody), Some(t)) =>
69
- switch jsonBody->JSON.Decode.object {
70
- | Some(obj) =>
71
- obj->Dict.set("i", t->JSON.Encode.string)
72
- Some(obj->JSON.Encode.object)
73
- | None => body
74
- }
75
- | (None, Some(t)) =>
76
- let obj = Dict.make()
38
+ // Inject auth token into request body (Misskey API convention)
39
+ let injectToken = (body: option<JSON.t>, token: option<string>): option<JSON.t> => {
40
+ switch (body, token) {
41
+ | (Some(jsonBody), Some(t)) =>
42
+ switch jsonBody->JSON.Decode.object {
43
+ | Some(obj) =>
77
44
  obj->Dict.set("i", t->JSON.Encode.string)
78
45
  Some(obj->JSON.Encode.object)
79
- | _ => body
46
+ | None => body
80
47
  }
48
+ | (None, Some(t)) =>
49
+ let obj = Dict.make()
50
+ obj->Dict.set("i", t->JSON.Encode.string)
51
+ Some(obj->JSON.Encode.object)
52
+ | _ => body
53
+ }
54
+ }
81
55
 
82
- let bodyStr = bodyWithToken->Option.map(json => JSON.stringify(json))
83
-
84
- let headers = Dict.make()
85
- headers->Dict.set("Content-Type", "application/json")
86
-
87
- FetchBindings.fetch(
88
- fullUrl,
89
- {
90
- method: method_,
91
- headers,
92
- body: bodyStr,
93
- },
94
- )->Promise.then(response => {
95
- if FetchBindings.ok(response) {
96
- response->FetchBindings.json
97
- } else {
98
- let msg = `API error: ${FetchBindings.status(
99
- response,
100
- )->Int.toString} ${FetchBindings.statusText(response)}`
101
- Promise.reject(JsExn(JsError.make(msg)->Obj.magic))
102
- }
56
+ // Default fetch implementation using ofetch.
57
+ // Uses baseURL for origin, auto JSON parsing, and token injection.
58
+ let defaultFetch = (~origin: string, ~token: option<string>) => {
59
+ (~url: string, ~method_: string, ~body: option<JSON.t>): Promise.t<JSON.t> => {
60
+ let bodyWithToken = injectToken(body, token)
61
+ Ofetch.ofetch(url, {
62
+ baseURL: `${origin}/api`,
63
+ method: method_,
64
+ body: ?bodyWithToken,
65
+ retry: 0,
103
66
  })
104
67
  }
105
68
  }
@@ -143,21 +106,23 @@ let wrapperConnect = (client: t): MisskeyIoWrapper.client => {
143
106
  ///
144
107
  /// Example:
145
108
  /// let user = await client->Misskey.request("i", ())
146
- let request = (
109
+ let request = async (
147
110
  client: t,
148
111
  endpoint: string,
149
112
  ~params: JSON.t=JSON.Encode.object(Dict.make()),
150
113
  (),
151
- ): promise<result<JSON.t, string>> => {
152
- client.fetchFn(~url=endpoint, ~method_="POST", ~body=Some(params))
153
- ->Promise.then(json => Ok(json)->Promise.resolve)
154
- ->Promise.catch(err => {
114
+ ): result<JSON.t, string> => {
115
+ try {
116
+ let json = await client.fetchFn(~url=endpoint, ~method_="POST", ~body=Some(params))
117
+ Ok(json)
118
+ } catch {
119
+ | err =>
155
120
  let msg = switch err->JsExn.fromException {
156
121
  | Some(jsExn) => JsExn.message(jsExn)->Option.getOr("Unknown error")
157
122
  | None => "Unknown error"
158
123
  }
159
- Error(msg)->Promise.resolve
160
- })
124
+ Error(msg)
125
+ }
161
126
  }
162
127
 
163
128
  /// Get current user info.
@@ -413,21 +378,20 @@ module Emojis = {
413
378
  }
414
379
 
415
380
  /// Get list of custom emojis from instance.
416
- let list = (client: t): promise<result<array<customEmoji>, string>> => {
417
- request(client, "emojis", ())->Promise.then(result => {
418
- switch result {
419
- | Ok(json) =>
420
- switch json->JSON.Decode.object {
421
- | Some(obj) =>
422
- switch obj->Dict.get("emojis")->Option.flatMap(JSON.Decode.array) {
423
- | Some(emojisArray) => Ok(emojisArray->Array.filterMap(decodeCustomEmoji))
424
- | None => Ok([])
425
- }
381
+ let list = async (client: t): result<array<customEmoji>, string> => {
382
+ let result = await request(client, "emojis", ())
383
+ switch result {
384
+ | Ok(json) =>
385
+ switch json->JSON.Decode.object {
386
+ | Some(obj) =>
387
+ switch obj->Dict.get("emojis")->Option.flatMap(JSON.Decode.array) {
388
+ | Some(emojisArray) => Ok(emojisArray->Array.filterMap(decodeCustomEmoji))
426
389
  | None => Ok([])
427
390
  }
428
- | Error(e) => Error(e)
429
- }->Promise.resolve
430
- })
391
+ | None => Ok([])
392
+ }
393
+ | Error(e) => Error(e)
394
+ }
431
395
  }
432
396
  }
433
397
 
@@ -437,45 +401,42 @@ module Emojis = {
437
401
 
438
402
  module CustomTimelines = {
439
403
  /// Fetch user's antennas.
440
- let antennas = (client: t): promise<result<array<JSON.t>, string>> => {
441
- request(client, "antennas/list", ())->Promise.then(result => {
442
- switch result {
443
- | Ok(json) =>
444
- switch json->JSON.Decode.array {
445
- | Some(arr) => Ok(arr)
446
- | None => Ok([])
447
- }
448
- | Error(e) => Error(e)
449
- }->Promise.resolve
450
- })
404
+ let antennas = async (client: t): result<array<JSON.t>, string> => {
405
+ let result = await request(client, "antennas/list", ())
406
+ switch result {
407
+ | Ok(json) =>
408
+ switch json->JSON.Decode.array {
409
+ | Some(arr) => Ok(arr)
410
+ | None => Ok([])
411
+ }
412
+ | Error(e) => Error(e)
413
+ }
451
414
  }
452
415
 
453
416
  /// Fetch user's lists.
454
- let lists = (client: t): promise<result<array<JSON.t>, string>> => {
455
- request(client, "users/lists/list", ())->Promise.then(result => {
456
- switch result {
457
- | Ok(json) =>
458
- switch json->JSON.Decode.array {
459
- | Some(arr) => Ok(arr)
460
- | None => Ok([])
461
- }
462
- | Error(e) => Error(e)
463
- }->Promise.resolve
464
- })
417
+ let lists = async (client: t): result<array<JSON.t>, string> => {
418
+ let result = await request(client, "users/lists/list", ())
419
+ switch result {
420
+ | Ok(json) =>
421
+ switch json->JSON.Decode.array {
422
+ | Some(arr) => Ok(arr)
423
+ | None => Ok([])
424
+ }
425
+ | Error(e) => Error(e)
426
+ }
465
427
  }
466
428
 
467
429
  /// Fetch user's followed channels.
468
- let channels = (client: t): promise<result<array<JSON.t>, string>> => {
469
- request(client, "channels/followed", ())->Promise.then(result => {
470
- switch result {
471
- | Ok(json) =>
472
- switch json->JSON.Decode.array {
473
- | Some(arr) => Ok(arr)
474
- | None => Ok([])
475
- }
476
- | Error(e) => Error(e)
477
- }->Promise.resolve
478
- })
430
+ let channels = async (client: t): result<array<JSON.t>, string> => {
431
+ let result = await request(client, "channels/followed", ())
432
+ switch result {
433
+ | Ok(json) =>
434
+ switch json->JSON.Decode.array {
435
+ | Some(arr) => Ok(arr)
436
+ | None => Ok([])
437
+ }
438
+ | Error(e) => Error(e)
439
+ }
479
440
  }
480
441
 
481
442
  /// Extract ID and name from a timeline item JSON.
@@ -589,15 +550,10 @@ module MiAuth = {
589
550
  }
590
551
 
591
552
  @val external encodeURIComponent: string => string = "encodeURIComponent"
553
+ @val @scope("crypto") external randomUUID: unit => string = "randomUUID"
592
554
 
593
555
  let generateSessionId = (): string => {
594
- %raw(`
595
- function() {
596
- var a = new Uint8Array(16);
597
- crypto.getRandomValues(a);
598
- return Array.from(a, function(b) { return b.toString(16).padStart(2, '0'); }).join('');
599
- }()
600
- `)
556
+ randomUUID()->String.replaceAll("-", "")
601
557
  }
602
558
 
603
559
  /// Generate MiAuth URL for user authorization.
@@ -637,35 +593,22 @@ module MiAuth = {
637
593
  /// authorization is complete, and `{ok: false}` when still pending.
638
594
  let check = async (~origin: string, ~sessionId: string): result<checkResult, string> => {
639
595
  try {
640
- let url = `${origin}/api/miauth/${sessionId}/check`
641
-
642
- let headers = Dict.make()
643
- headers->Dict.set("Content-Type", "application/json")
644
-
645
- let response = await FetchBindings.fetch(url, {method: "POST", headers, body: Some("{}")})
646
-
647
- if !FetchBindings.ok(response) {
648
- Error(
649
- `HTTP error: ${FetchBindings.status(response)->Int.toString} ${FetchBindings.statusText(
650
- response,
651
- )}`,
652
- )
653
- } else {
654
- let json = await response->FetchBindings.json
655
- switch json->JSON.Decode.object {
656
- | Some(obj) =>
657
- // Check the "ok" field in the response body
658
- let isOk = obj->Dict.get("ok")->Option.flatMap(JSON.Decode.bool)->Option.getOr(false)
659
- if isOk {
660
- let token = obj->Dict.get("token")->Option.flatMap(JSON.Decode.string)
661
- let user = obj->Dict.get("user")
662
- Ok({token, user})
663
- } else {
664
- // Server explicitly says not authorized yet
665
- Ok({token: None, user: None})
666
- }
667
- | None => Error("Unexpected response format")
596
+ let json = await Ofetch.ofetch(`${origin}/api/miauth/${sessionId}/check`, {
597
+ method: "POST",
598
+ body: JSON.Encode.object(Dict.make()),
599
+ retry: 0,
600
+ })
601
+ switch json->JSON.Decode.object {
602
+ | Some(obj) =>
603
+ let isOk = obj->Dict.get("ok")->Option.flatMap(JSON.Decode.bool)->Option.getOr(false)
604
+ if isOk {
605
+ let token = obj->Dict.get("token")->Option.flatMap(JSON.Decode.string)
606
+ let user = obj->Dict.get("user")
607
+ Ok({token, user})
608
+ } else {
609
+ Ok({token: None, user: None})
668
610
  }
611
+ | None => Error("Unexpected response format")
669
612
  }
670
613
  } catch {
671
614
  | err =>
@@ -0,0 +1,14 @@
1
+ // Ofetch.res - ReScript bindings for ofetch
2
+ // Auto JSON parsing, error handling, baseURL, retries, timeouts
3
+
4
+ type fetchOptions = {
5
+ baseURL?: string,
6
+ method?: string,
7
+ body?: JSON.t,
8
+ headers?: dict<string>,
9
+ retry?: int,
10
+ retryDelay?: int,
11
+ timeout?: int,
12
+ }
13
+
14
+ @module("ofetch") external ofetch: (string, fetchOptions) => promise<JSON.t> = "ofetch"