@florent-uzio/custody 2.4.0 → 2.6.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 (181) hide show
  1. package/README.md +1 -6
  2. package/dist/constants/urls.d.ts +52 -0
  3. package/dist/constants/urls.d.ts.map +1 -1
  4. package/dist/constants/urls.js +58 -0
  5. package/dist/constants/urls.js.map +1 -1
  6. package/dist/index.d.ts +12 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +1 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/models/capabilities.generated.d.ts +51 -0
  11. package/dist/models/capabilities.generated.d.ts.map +1 -0
  12. package/dist/models/capabilities.generated.js +9770 -0
  13. package/dist/models/capabilities.generated.js.map +1 -0
  14. package/dist/models/custody-types.d.ts +7314 -3341
  15. package/dist/models/custody-types.d.ts.map +1 -1
  16. package/dist/models/custody-types.js +2 -2
  17. package/dist/namespaces/accounts.d.ts.map +1 -1
  18. package/dist/namespaces/accounts.js +2 -1
  19. package/dist/namespaces/accounts.js.map +1 -1
  20. package/dist/namespaces/backups.d.ts +8 -0
  21. package/dist/namespaces/backups.d.ts.map +1 -0
  22. package/dist/namespaces/backups.js +9 -0
  23. package/dist/namespaces/backups.js.map +1 -0
  24. package/dist/namespaces/compliance/analysis.d.ts +8 -0
  25. package/dist/namespaces/compliance/analysis.d.ts.map +1 -0
  26. package/dist/namespaces/compliance/analysis.js +9 -0
  27. package/dist/namespaces/compliance/analysis.js.map +1 -0
  28. package/dist/namespaces/compliance/domain.d.ts +9 -0
  29. package/dist/namespaces/compliance/domain.d.ts.map +1 -0
  30. package/dist/namespaces/compliance/domain.js +10 -0
  31. package/dist/namespaces/compliance/domain.js.map +1 -0
  32. package/dist/namespaces/compliance/index.d.ts +43 -0
  33. package/dist/namespaces/compliance/index.d.ts.map +1 -0
  34. package/dist/namespaces/compliance/index.js +20 -0
  35. package/dist/namespaces/compliance/index.js.map +1 -0
  36. package/dist/namespaces/compliance/policy.d.ts +9 -0
  37. package/dist/namespaces/compliance/policy.d.ts.map +1 -0
  38. package/dist/namespaces/compliance/policy.js +10 -0
  39. package/dist/namespaces/compliance/policy.js.map +1 -0
  40. package/dist/namespaces/compliance/providers.d.ts +18 -0
  41. package/dist/namespaces/compliance/providers.d.ts.map +1 -0
  42. package/dist/namespaces/compliance/providers.js +19 -0
  43. package/dist/namespaces/compliance/providers.js.map +1 -0
  44. package/dist/namespaces/compliance/travel-rule.d.ts +18 -0
  45. package/dist/namespaces/compliance/travel-rule.d.ts.map +1 -0
  46. package/dist/namespaces/compliance/travel-rule.js +21 -0
  47. package/dist/namespaces/compliance/travel-rule.js.map +1 -0
  48. package/dist/namespaces/domains.d.ts +34 -0
  49. package/dist/namespaces/domains.d.ts.map +1 -1
  50. package/dist/namespaces/domains.js +34 -0
  51. package/dist/namespaces/domains.js.map +1 -1
  52. package/dist/namespaces/health.d.ts +21 -0
  53. package/dist/namespaces/health.d.ts.map +1 -0
  54. package/dist/namespaces/health.js +22 -0
  55. package/dist/namespaces/health.js.map +1 -0
  56. package/dist/namespaces/index.d.ts +6 -0
  57. package/dist/namespaces/index.d.ts.map +1 -1
  58. package/dist/namespaces/index.js +6 -0
  59. package/dist/namespaces/index.js.map +1 -1
  60. package/dist/namespaces/providers.d.ts +8 -0
  61. package/dist/namespaces/providers.d.ts.map +1 -0
  62. package/dist/namespaces/providers.js +9 -0
  63. package/dist/namespaces/providers.js.map +1 -0
  64. package/dist/namespaces/system-properties.d.ts +6 -0
  65. package/dist/namespaces/system-properties.d.ts.map +1 -0
  66. package/dist/namespaces/system-properties.js +7 -0
  67. package/dist/namespaces/system-properties.js.map +1 -0
  68. package/dist/namespaces/trusted-public-keys.d.ts +8 -0
  69. package/dist/namespaces/trusted-public-keys.d.ts.map +1 -0
  70. package/dist/namespaces/trusted-public-keys.js +9 -0
  71. package/dist/namespaces/trusted-public-keys.js.map +1 -0
  72. package/dist/ripple-custody.d.ts +16 -1
  73. package/dist/ripple-custody.d.ts.map +1 -1
  74. package/dist/ripple-custody.js +50 -4
  75. package/dist/ripple-custody.js.map +1 -1
  76. package/dist/ripple-custody.types.d.ts +33 -0
  77. package/dist/ripple-custody.types.d.ts.map +1 -1
  78. package/dist/services/apis/api.service.d.ts.map +1 -1
  79. package/dist/services/apis/api.service.js +0 -1
  80. package/dist/services/apis/api.service.js.map +1 -1
  81. package/dist/services/backups/backups.types.d.ts +8 -0
  82. package/dist/services/backups/backups.types.d.ts.map +1 -0
  83. package/dist/services/backups/backups.types.js +2 -0
  84. package/dist/services/backups/backups.types.js.map +1 -0
  85. package/dist/services/backups/index.d.ts +2 -0
  86. package/dist/services/backups/index.d.ts.map +1 -0
  87. package/dist/services/backups/index.js +2 -0
  88. package/dist/services/backups/index.js.map +1 -0
  89. package/dist/services/compliance/analysis.types.d.ts +7 -0
  90. package/dist/services/compliance/analysis.types.d.ts.map +1 -0
  91. package/dist/services/compliance/analysis.types.js +2 -0
  92. package/dist/services/compliance/analysis.types.js.map +1 -0
  93. package/dist/services/compliance/domain.types.d.ts +5 -0
  94. package/dist/services/compliance/domain.types.d.ts.map +1 -0
  95. package/dist/services/compliance/domain.types.js +2 -0
  96. package/dist/services/compliance/domain.types.js.map +1 -0
  97. package/dist/services/compliance/index.d.ts +6 -0
  98. package/dist/services/compliance/index.d.ts.map +1 -0
  99. package/dist/services/compliance/index.js +6 -0
  100. package/dist/services/compliance/index.js.map +1 -0
  101. package/dist/services/compliance/policy.types.d.ts +8 -0
  102. package/dist/services/compliance/policy.types.d.ts.map +1 -0
  103. package/dist/services/compliance/policy.types.js +2 -0
  104. package/dist/services/compliance/policy.types.js.map +1 -0
  105. package/dist/services/compliance/providers.types.d.ts +12 -0
  106. package/dist/services/compliance/providers.types.d.ts.map +1 -0
  107. package/dist/services/compliance/providers.types.js +2 -0
  108. package/dist/services/compliance/providers.types.js.map +1 -0
  109. package/dist/services/compliance/travel-rule.types.d.ts +20 -0
  110. package/dist/services/compliance/travel-rule.types.d.ts.map +1 -0
  111. package/dist/services/compliance/travel-rule.types.js +2 -0
  112. package/dist/services/compliance/travel-rule.types.js.map +1 -0
  113. package/dist/services/health/health.types.d.ts +4 -0
  114. package/dist/services/health/health.types.d.ts.map +1 -0
  115. package/dist/services/health/health.types.js +2 -0
  116. package/dist/services/health/health.types.js.map +1 -0
  117. package/dist/services/health/index.d.ts +2 -0
  118. package/dist/services/health/index.d.ts.map +1 -0
  119. package/dist/services/health/index.js +2 -0
  120. package/dist/services/health/index.js.map +1 -0
  121. package/dist/services/index.d.ts +8 -0
  122. package/dist/services/index.d.ts.map +1 -1
  123. package/dist/services/index.js +8 -0
  124. package/dist/services/index.js.map +1 -1
  125. package/dist/services/omnibus/index.d.ts +2 -0
  126. package/dist/services/omnibus/index.d.ts.map +1 -0
  127. package/dist/services/omnibus/index.js +2 -0
  128. package/dist/services/omnibus/index.js.map +1 -0
  129. package/dist/services/omnibus/omnibus.types.d.ts +37 -0
  130. package/dist/services/omnibus/omnibus.types.d.ts.map +1 -0
  131. package/dist/services/omnibus/omnibus.types.js +2 -0
  132. package/dist/services/omnibus/omnibus.types.js.map +1 -0
  133. package/dist/services/providers/index.d.ts +2 -0
  134. package/dist/services/providers/index.d.ts.map +1 -0
  135. package/dist/services/providers/index.js +2 -0
  136. package/dist/services/providers/index.js.map +1 -0
  137. package/dist/services/providers/providers.types.d.ts +9 -0
  138. package/dist/services/providers/providers.types.d.ts.map +1 -0
  139. package/dist/services/providers/providers.types.js +2 -0
  140. package/dist/services/providers/providers.types.js.map +1 -0
  141. package/dist/services/sponsors/index.d.ts +2 -0
  142. package/dist/services/sponsors/index.d.ts.map +1 -0
  143. package/dist/services/sponsors/index.js +2 -0
  144. package/dist/services/sponsors/index.js.map +1 -0
  145. package/dist/services/sponsors/sponsors.types.d.ts +36 -0
  146. package/dist/services/sponsors/sponsors.types.d.ts.map +1 -0
  147. package/dist/services/sponsors/sponsors.types.js +2 -0
  148. package/dist/services/sponsors/sponsors.types.js.map +1 -0
  149. package/dist/services/system-properties/index.d.ts +2 -0
  150. package/dist/services/system-properties/index.d.ts.map +1 -0
  151. package/dist/services/system-properties/index.js +2 -0
  152. package/dist/services/system-properties/index.js.map +1 -0
  153. package/dist/services/system-properties/system-properties.types.d.ts +7 -0
  154. package/dist/services/system-properties/system-properties.types.d.ts.map +1 -0
  155. package/dist/services/system-properties/system-properties.types.js +2 -0
  156. package/dist/services/system-properties/system-properties.types.js.map +1 -0
  157. package/dist/services/trusted-public-keys/index.d.ts +2 -0
  158. package/dist/services/trusted-public-keys/index.d.ts.map +1 -0
  159. package/dist/services/trusted-public-keys/index.js +2 -0
  160. package/dist/services/trusted-public-keys/index.js.map +1 -0
  161. package/dist/services/trusted-public-keys/trusted-public-keys.types.d.ts +4 -0
  162. package/dist/services/trusted-public-keys/trusted-public-keys.types.d.ts.map +1 -0
  163. package/dist/services/trusted-public-keys/trusted-public-keys.types.js +2 -0
  164. package/dist/services/trusted-public-keys/trusted-public-keys.types.js.map +1 -0
  165. package/dist/services/xrpl/xrpl.service.d.ts +3 -1
  166. package/dist/services/xrpl/xrpl.service.d.ts.map +1 -1
  167. package/dist/services/xrpl/xrpl.service.js +7 -1
  168. package/dist/services/xrpl/xrpl.service.js.map +1 -1
  169. package/dist/transport/typed-transport.d.ts +5 -3
  170. package/dist/transport/typed-transport.d.ts.map +1 -1
  171. package/dist/transport/typed-transport.js +36 -6
  172. package/dist/transport/typed-transport.js.map +1 -1
  173. package/dist/versioning/detect.d.ts +25 -0
  174. package/dist/versioning/detect.d.ts.map +1 -0
  175. package/dist/versioning/detect.js +45 -0
  176. package/dist/versioning/detect.js.map +1 -0
  177. package/dist/versioning/version-guard.d.ts +101 -0
  178. package/dist/versioning/version-guard.d.ts.map +1 -0
  179. package/dist/versioning/version-guard.js +181 -0
  180. package/dist/versioning/version-guard.js.map +1 -0
  181. package/package.json +20 -20
@@ -1,3 +1,4 @@
1
+ import { VersionGuard } from "../versioning/version-guard.js";
1
2
  import { splitParams } from "./split-params.js";
2
3
  /**
3
4
  * A typed transport layer that wraps ApiService, handling URL template
@@ -7,14 +8,17 @@ import { splitParams } from "./split-params.js";
7
8
  */
8
9
  export class TypedTransport {
9
10
  api;
10
- constructor(api) {
11
+ guard;
12
+ constructor(api, guard = new VersionGuard(undefined)) {
11
13
  this.api = api;
14
+ this.guard = guard;
12
15
  }
13
16
  /**
14
17
  * Makes a typed GET request.
15
18
  * Splits flat params into path and query params based on the URL template.
16
19
  */
17
20
  async get(url, pathParams, query, _config) {
21
+ await this.guard.checkEndpoint("GET", url);
18
22
  let resolvedUrl = url;
19
23
  if (pathParams && Object.keys(pathParams).length > 0) {
20
24
  const result = splitParams(url, pathParams);
@@ -31,30 +35,49 @@ export class TypedTransport {
31
35
  * Resolves path params from the URL template before posting.
32
36
  */
33
37
  async post(url, body, pathParams, config) {
38
+ await this.guard.checkEndpoint("POST", url);
34
39
  let resolvedUrl = url;
40
+ let mergedConfig = config;
35
41
  if (pathParams && Object.keys(pathParams).length > 0) {
36
42
  const result = splitParams(url, pathParams);
37
43
  resolvedUrl = result.url;
44
+ // Non-path keys become query params, mirroring get()/delete().
45
+ if (result.query) {
46
+ mergedConfig = {
47
+ ...(mergedConfig ?? {}),
48
+ params: { ...(mergedConfig?.params ?? {}), ...result.query },
49
+ };
50
+ }
38
51
  }
39
- return this.api.post(resolvedUrl, body, config);
52
+ return this.api.post(resolvedUrl, body, mergedConfig);
40
53
  }
41
54
  /**
42
55
  * Makes a typed PUT request.
43
56
  * Resolves path params from the URL template before sending.
44
57
  */
45
58
  async put(url, body, pathParams, config) {
59
+ await this.guard.checkEndpoint("PUT", url);
46
60
  let resolvedUrl = url;
61
+ let mergedConfig = config;
47
62
  if (pathParams && Object.keys(pathParams).length > 0) {
48
63
  const result = splitParams(url, pathParams);
49
64
  resolvedUrl = result.url;
65
+ // Non-path keys become query params, mirroring get()/delete().
66
+ if (result.query) {
67
+ mergedConfig = {
68
+ ...(mergedConfig ?? {}),
69
+ params: { ...(mergedConfig?.params ?? {}), ...result.query },
70
+ };
71
+ }
50
72
  }
51
- return this.api.put(resolvedUrl, body, config);
73
+ return this.api.put(resolvedUrl, body, mergedConfig);
52
74
  }
53
75
  /**
54
76
  * Makes a typed PATCH request.
55
77
  * Resolves path params from the URL template before sending.
56
78
  */
57
79
  async patch(url, body, pathParams, config) {
80
+ await this.guard.checkEndpoint("PATCH", url);
58
81
  let resolvedUrl = url;
59
82
  if (pathParams && Object.keys(pathParams).length > 0) {
60
83
  const result = splitParams(url, pathParams);
@@ -64,15 +87,22 @@ export class TypedTransport {
64
87
  }
65
88
  /**
66
89
  * Makes a typed DELETE request.
67
- * Resolves path params from the URL template before sending.
90
+ * Splits flat params into path and query params based on the URL template.
68
91
  */
69
- async delete(url, pathParams, config) {
92
+ async delete(url, pathParams, query, config) {
93
+ await this.guard.checkEndpoint("DELETE", url);
70
94
  let resolvedUrl = url;
71
95
  if (pathParams && Object.keys(pathParams).length > 0) {
72
96
  const result = splitParams(url, pathParams);
73
97
  resolvedUrl = result.url;
98
+ if (result.query) {
99
+ query = { ...(query ?? {}), ...result.query };
100
+ }
74
101
  }
75
- return this.api.delete(resolvedUrl, config);
102
+ return this.api.delete(resolvedUrl, {
103
+ ...config,
104
+ params: query,
105
+ });
76
106
  }
77
107
  }
78
108
  //# sourceMappingURL=typed-transport.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"typed-transport.js","sourceRoot":"","sources":["../../src/transport/typed-transport.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAG/C;;;;;GAKG;AACH,MAAM,OAAO,cAAc;IACI;IAA7B,YAA6B,GAAe;QAAf,QAAG,GAAH,GAAG,CAAY;IAAG,CAAC;IAEhD;;;OAGG;IACH,KAAK,CAAC,GAAG,CACP,GAAW,EACX,UAAoC,EACpC,KAAe,EACf,OAAuB;QAEvB,IAAI,WAAW,GAAG,GAAG,CAAA;QACrB,IAAI,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;YAC3C,WAAW,GAAG,MAAM,CAAC,GAAG,CAAA;YACxB,uDAAuD;YACvD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBACjB,KAAK,GAAG,EAAE,GAAG,CAAE,KAAiC,IAAI,EAAE,CAAC,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,CAAA;YAC5E,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAI,WAAW,EAAE,KAAqC,CAAC,CAAA;IAC5E,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI,CACR,GAAW,EACX,IAAa,EACb,UAAoC,EACpC,MAAsB;QAEtB,IAAI,WAAW,GAAG,GAAG,CAAA;QACrB,IAAI,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;YAC3C,WAAW,GAAG,MAAM,CAAC,GAAG,CAAA;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAI,WAAW,EAAE,IAAI,EAAE,MAAiD,CAAC,CAAA;IAC/F,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,GAAG,CACP,GAAW,EACX,IAAa,EACb,UAAoC,EACpC,MAAsB;QAEtB,IAAI,WAAW,GAAG,GAAG,CAAA;QACrB,IAAI,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;YAC3C,WAAW,GAAG,MAAM,CAAC,GAAG,CAAA;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAI,WAAW,EAAE,IAAI,EAAE,MAA4B,CAAC,CAAA;IACzE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK,CACT,GAAW,EACX,IAAa,EACb,UAAoC,EACpC,MAAsB;QAEtB,IAAI,WAAW,GAAG,GAAG,CAAA;QACrB,IAAI,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;YAC3C,WAAW,GAAG,MAAM,CAAC,GAAG,CAAA;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAI,WAAW,EAAE,IAAI,EAAE,MAA4B,CAAC,CAAA;IAC3E,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CACV,GAAW,EACX,UAAoC,EACpC,MAAsB;QAEtB,IAAI,WAAW,GAAG,GAAG,CAAA;QACrB,IAAI,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;YAC3C,WAAW,GAAG,MAAM,CAAC,GAAG,CAAA;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAI,WAAW,EAAE,MAA4B,CAAC,CAAA;IACtE,CAAC;CACF"}
1
+ {"version":3,"file":"typed-transport.js","sourceRoot":"","sources":["../../src/transport/typed-transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { ResolvedCapabilities } from "./version-guard.js";
2
+ /**
3
+ * Fetches the target instance's live OpenAPI document. Production is backed by
4
+ * an HTTP GET; tests supply an in-memory implementation.
5
+ */
6
+ export interface SpecSource {
7
+ /** Fetch and return the parsed live OpenAPI document. */
8
+ fetchSpec(): Promise<unknown>;
9
+ }
10
+ /**
11
+ * Builds the OpenAPI document URL for an instance from its API base URL.
12
+ * The endpoint is unauthenticated (the same one the `rc-version` skill reads).
13
+ */
14
+ export declare function buildOpenApiUrl(apiUrl: string): string;
15
+ /** Default HTTP-backed spec source (plain, unauthenticated GET). */
16
+ export declare function createHttpSpecSource(openApiUrl: string, timeout?: number): SpecSource;
17
+ /**
18
+ * Derives a runtime capability set from a live OpenAPI document: every
19
+ * `METHOD /path` it serves and every component schema name it defines.
20
+ * Accurate for any version, including ones the SDK has never bundled.
21
+ */
22
+ export declare function extractCapabilitiesFromSpec(spec: unknown): ResolvedCapabilities;
23
+ /** Fetches the live spec via `source` and derives its capability set. */
24
+ export declare function detectCapabilities(source: SpecSource): Promise<ResolvedCapabilities>;
25
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/versioning/detect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAE9D;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,yDAAyD;IACzD,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAC9B;AAKD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,oEAAoE;AACpE,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU,CAOrF;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,OAAO,GAAG,oBAAoB,CAoB/E;AAED,yEAAyE;AACzE,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAG1F"}
@@ -0,0 +1,45 @@
1
+ import axios from "axios";
2
+ /** OpenAPI path-item keys that denote an operation. */
3
+ const HTTP_METHODS = ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
4
+ /**
5
+ * Builds the OpenAPI document URL for an instance from its API base URL.
6
+ * The endpoint is unauthenticated (the same one the `rc-version` skill reads).
7
+ */
8
+ export function buildOpenApiUrl(apiUrl) {
9
+ return `${apiUrl.replace(/\/+$/, "")}/api/OpenAPI?scope=&layout=`;
10
+ }
11
+ /** Default HTTP-backed spec source (plain, unauthenticated GET). */
12
+ export function createHttpSpecSource(openApiUrl, timeout) {
13
+ return {
14
+ async fetchSpec() {
15
+ const response = await axios.get(openApiUrl, { timeout });
16
+ return response.data;
17
+ },
18
+ };
19
+ }
20
+ /**
21
+ * Derives a runtime capability set from a live OpenAPI document: every
22
+ * `METHOD /path` it serves and every component schema name it defines.
23
+ * Accurate for any version, including ones the SDK has never bundled.
24
+ */
25
+ export function extractCapabilitiesFromSpec(spec) {
26
+ const doc = (spec ?? {});
27
+ const appVersion = doc.info?.["x-app-version"] ?? "unknown";
28
+ const endpoints = new Set();
29
+ for (const [path, item] of Object.entries(doc.paths ?? {})) {
30
+ if (!item || typeof item !== "object")
31
+ continue;
32
+ for (const method of HTTP_METHODS) {
33
+ if (item[method])
34
+ endpoints.add(`${method.toUpperCase()} ${path}`);
35
+ }
36
+ }
37
+ const schemas = new Set(Object.keys(doc.components?.schemas ?? {}));
38
+ return { appVersion, endpoints, schemas };
39
+ }
40
+ /** Fetches the live spec via `source` and derives its capability set. */
41
+ export async function detectCapabilities(source) {
42
+ const spec = await source.fetchSpec();
43
+ return extractCapabilitiesFromSpec(spec);
44
+ }
45
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/versioning/detect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAYzB,uDAAuD;AACvD,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;AAE1F;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,6BAA6B,CAAA;AACnE,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,oBAAoB,CAAC,UAAkB,EAAE,OAAgB;IACvE,OAAO;QACL,KAAK,CAAC,SAAS;YACb,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;YACzD,OAAO,QAAQ,CAAC,IAAI,CAAA;QACtB,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAAa;IACvD,MAAM,GAAG,GAAG,CAAC,IAAI,IAAI,EAAE,CAItB,CAAA;IAED,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,SAAS,CAAA;IAE3D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;IACnC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,SAAQ;QAC/C,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,MAAM,CAAC;gBAAE,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,CAAA;QACpE,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,CAAA;IAE3E,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,CAAA;AAC3C,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAkB;IACzD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,SAAS,EAAE,CAAA;IACrC,OAAO,2BAA2B,CAAC,IAAI,CAAC,CAAA;AAC1C,CAAC"}
@@ -0,0 +1,101 @@
1
+ import { CustodyError } from "../models/index.js";
2
+ /** Whether a capability is a whole endpoint or a feature carried inside one. */
3
+ export type CapabilityKind = "endpoint" | "feature";
4
+ /**
5
+ * The capability set the guard checks against: the endpoints and component
6
+ * schemas a single resolved backend version exposes.
7
+ */
8
+ export type ResolvedCapabilities = {
9
+ /** The resolved app version (`x-app-version`), used for messaging. */
10
+ appVersion: string;
11
+ /** Endpoint capabilities, each formatted `METHOD /path-template`. */
12
+ endpoints: ReadonlySet<string>;
13
+ /** Feature capabilities: the names of component schemas the version defines. */
14
+ schemas: ReadonlySet<string>;
15
+ };
16
+ /**
17
+ * Thrown when a call needs a capability the resolved backend version does not
18
+ * support. Extends {@link CustodyError} so existing `catch (CustodyError)`
19
+ * handlers still catch it.
20
+ */
21
+ export declare class UnsupportedInVersionError extends CustodyError {
22
+ readonly capability: string;
23
+ readonly kind: CapabilityKind;
24
+ readonly appVersion: string;
25
+ readonly sdkMethod: string;
26
+ constructor(args: {
27
+ capability: string;
28
+ kind: CapabilityKind;
29
+ appVersion: string;
30
+ sdkMethod: string;
31
+ });
32
+ }
33
+ /**
34
+ * Maps an XRPL operation `type` (the discriminator of `Core_XrplOperation`) to
35
+ * its component-schema name. The generated union members are named
36
+ * `Core_XrplOperation_<type>` exactly, so no lookup table is needed.
37
+ */
38
+ export declare function xrplOperationSchema(operationType: string): string;
39
+ /**
40
+ * Builds the capability set for an explicitly-requested app version from the
41
+ * bundled capability data. Throws when the version is not bundled.
42
+ */
43
+ export declare function resolveExplicitCapabilities(apiVersion: string): ResolvedCapabilities;
44
+ /**
45
+ * Runtime guard that blocks calls the resolved backend version cannot serve.
46
+ *
47
+ * When constructed with no resolved capabilities it is a **pass-through**: every
48
+ * check is a no-op (fail-open). The backend remains the ultimate authority.
49
+ */
50
+ export declare class VersionGuard {
51
+ private resolved;
52
+ private settled;
53
+ private pending?;
54
+ private failedOpen;
55
+ private warned;
56
+ private readonly resolver?;
57
+ private readonly onFailOpen?;
58
+ /**
59
+ * Construct a guard with capabilities already resolved (or `undefined` for a
60
+ * pass-through guard). Pass a `resolver` for lazy resolution, or use
61
+ * {@link VersionGuard.deferred}. `onFailOpen` runs once the first time the
62
+ * guard passes a call through because no version could be resolved.
63
+ */
64
+ constructor(resolved: ResolvedCapabilities | undefined, resolver?: () => Promise<ResolvedCapabilities | undefined>, onFailOpen?: () => void);
65
+ /**
66
+ * Construct a guard whose capabilities are resolved lazily on first use (e.g.
67
+ * by fetching the live instance spec). The resolver runs at most once per
68
+ * successful resolution; concurrent triggers share a single invocation.
69
+ */
70
+ static deferred(resolver: () => Promise<ResolvedCapabilities | undefined>, onFailOpen?: () => void): VersionGuard;
71
+ /** Whether the guard has a resolved version and is actively gating. */
72
+ get isActive(): boolean;
73
+ /**
74
+ * Resolve the capability set if not already resolved. Idempotent and
75
+ * concurrency-safe: parallel calls share one in-flight resolution. On failure
76
+ * the error propagates and a later call retries.
77
+ */
78
+ ensureResolved(): Promise<void>;
79
+ /** Resolves (detecting if needed) then asserts the endpoint capability. */
80
+ checkEndpoint(httpMethod: string, pathTemplate: string, sdkMethod?: string): Promise<void>;
81
+ /** Resolves (detecting if needed) then asserts the feature capability. */
82
+ checkFeature(schemaName: string, sdkMethod: string): Promise<void>;
83
+ /**
84
+ * Whether gating is active for the call path. Resolves the version on first
85
+ * use; if no version can be resolved — detection failed, or the guard is a
86
+ * pass-through — it **fails open**: returns `false` (call passes through) and
87
+ * fires `onFailOpen` once. The unresolved state is cached, so detection is
88
+ * not re-attempted on every call. `ensureResolved`/`ready()` keep surfacing
89
+ * detection errors independently.
90
+ */
91
+ private gatingActive;
92
+ private enterFailOpen;
93
+ /**
94
+ * Asserts the resolved version serves `METHOD /pathTemplate`.
95
+ * @param sdkMethod - Label for the error (defaults to the HTTP descriptor).
96
+ */
97
+ assertEndpoint(httpMethod: string, pathTemplate: string, sdkMethod?: string): void;
98
+ /** Asserts the resolved version defines the component schema `schemaName`. */
99
+ assertFeature(schemaName: string, sdkMethod: string): void;
100
+ }
101
+ //# sourceMappingURL=version-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-guard.d.ts","sourceRoot":"","sources":["../../src/versioning/version-guard.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,gFAAgF;AAChF,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,SAAS,CAAA;AAEnD;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAA;IAClB,qEAAqE;IACrE,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC9B,gFAAgF;IAChF,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAC7B,CAAA;AAED;;;;GAIG;AACH,qBAAa,yBAA0B,SAAQ,YAAY;IACzD,SAAgB,UAAU,EAAE,MAAM,CAAA;IAClC,SAAgB,IAAI,EAAE,cAAc,CAAA;IACpC,SAAgB,UAAU,EAAE,MAAM,CAAA;IAClC,SAAgB,SAAS,EAAE,MAAM,CAAA;gBAErB,IAAI,EAAE;QAChB,UAAU,EAAE,MAAM,CAAA;QAClB,IAAI,EAAE,cAAc,CAAA;QACpB,UAAU,EAAE,MAAM,CAAA;QAClB,SAAS,EAAE,MAAM,CAAA;KAClB;CAYF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,CAapF;AAED;;;;;GAKG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAe;IAC/B,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAiD;IAC3E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAY;IAExC;;;;;OAKG;gBAED,QAAQ,EAAE,oBAAoB,GAAG,SAAS,EAC1C,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,EAC1D,UAAU,CAAC,EAAE,MAAM,IAAI;IAQzB;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CACb,QAAQ,EAAE,MAAM,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,EACzD,UAAU,CAAC,EAAE,MAAM,IAAI,GACtB,YAAY;IAIf,uEAAuE;IACvE,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;;OAIG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBrC,2EAA2E;IACrE,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhG,0EAA0E;IACpE,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxE;;;;;;;OAOG;YACW,YAAY;IAW1B,OAAO,CAAC,aAAa;IASrB;;;OAGG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAalF,8EAA8E;IAC9E,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;CAW3D"}
@@ -0,0 +1,181 @@
1
+ import { CAPABILITIES } from "../models/capabilities.generated.js";
2
+ import { CustodyError } from "../models/index.js";
3
+ /**
4
+ * Thrown when a call needs a capability the resolved backend version does not
5
+ * support. Extends {@link CustodyError} so existing `catch (CustodyError)`
6
+ * handlers still catch it.
7
+ */
8
+ export class UnsupportedInVersionError extends CustodyError {
9
+ capability;
10
+ kind;
11
+ appVersion;
12
+ sdkMethod;
13
+ constructor(args) {
14
+ super({
15
+ reason: `${args.sdkMethod} requires ${args.kind} "${args.capability}", which is not ` +
16
+ `available on the resolved backend version ${args.appVersion}.`,
17
+ });
18
+ this.name = "UnsupportedInVersionError";
19
+ this.capability = args.capability;
20
+ this.kind = args.kind;
21
+ this.appVersion = args.appVersion;
22
+ this.sdkMethod = args.sdkMethod;
23
+ }
24
+ }
25
+ /**
26
+ * Maps an XRPL operation `type` (the discriminator of `Core_XrplOperation`) to
27
+ * its component-schema name. The generated union members are named
28
+ * `Core_XrplOperation_<type>` exactly, so no lookup table is needed.
29
+ */
30
+ export function xrplOperationSchema(operationType) {
31
+ return `Core_XrplOperation_${operationType}`;
32
+ }
33
+ /**
34
+ * Builds the capability set for an explicitly-requested app version from the
35
+ * bundled capability data. Throws when the version is not bundled.
36
+ */
37
+ export function resolveExplicitCapabilities(apiVersion) {
38
+ const entry = CAPABILITIES[apiVersion];
39
+ if (!entry) {
40
+ const known = Object.keys(CAPABILITIES).join(", ");
41
+ throw new CustodyError({
42
+ reason: `Unknown apiVersion "${apiVersion}". Known versions: ${known}.`,
43
+ });
44
+ }
45
+ return {
46
+ appVersion: apiVersion,
47
+ endpoints: new Set(entry.endpoints),
48
+ schemas: new Set(entry.schemas),
49
+ };
50
+ }
51
+ /**
52
+ * Runtime guard that blocks calls the resolved backend version cannot serve.
53
+ *
54
+ * When constructed with no resolved capabilities it is a **pass-through**: every
55
+ * check is a no-op (fail-open). The backend remains the ultimate authority.
56
+ */
57
+ export class VersionGuard {
58
+ resolved;
59
+ settled;
60
+ pending;
61
+ failedOpen = false;
62
+ warned = false;
63
+ resolver;
64
+ onFailOpen;
65
+ /**
66
+ * Construct a guard with capabilities already resolved (or `undefined` for a
67
+ * pass-through guard). Pass a `resolver` for lazy resolution, or use
68
+ * {@link VersionGuard.deferred}. `onFailOpen` runs once the first time the
69
+ * guard passes a call through because no version could be resolved.
70
+ */
71
+ constructor(resolved, resolver, onFailOpen) {
72
+ this.resolved = resolved;
73
+ this.resolver = resolver;
74
+ this.onFailOpen = onFailOpen;
75
+ this.settled = resolver === undefined;
76
+ }
77
+ /**
78
+ * Construct a guard whose capabilities are resolved lazily on first use (e.g.
79
+ * by fetching the live instance spec). The resolver runs at most once per
80
+ * successful resolution; concurrent triggers share a single invocation.
81
+ */
82
+ static deferred(resolver, onFailOpen) {
83
+ return new VersionGuard(undefined, resolver, onFailOpen);
84
+ }
85
+ /** Whether the guard has a resolved version and is actively gating. */
86
+ get isActive() {
87
+ return this.resolved !== undefined;
88
+ }
89
+ /**
90
+ * Resolve the capability set if not already resolved. Idempotent and
91
+ * concurrency-safe: parallel calls share one in-flight resolution. On failure
92
+ * the error propagates and a later call retries.
93
+ */
94
+ async ensureResolved() {
95
+ if (this.settled)
96
+ return;
97
+ if (!this.pending) {
98
+ const resolver = this.resolver;
99
+ this.pending = resolver().then((caps) => {
100
+ this.resolved = caps;
101
+ this.settled = true;
102
+ }, (error) => {
103
+ this.pending = undefined;
104
+ throw error;
105
+ });
106
+ }
107
+ return this.pending;
108
+ }
109
+ /** Resolves (detecting if needed) then asserts the endpoint capability. */
110
+ async checkEndpoint(httpMethod, pathTemplate, sdkMethod) {
111
+ if (await this.gatingActive()) {
112
+ this.assertEndpoint(httpMethod, pathTemplate, sdkMethod);
113
+ }
114
+ }
115
+ /** Resolves (detecting if needed) then asserts the feature capability. */
116
+ async checkFeature(schemaName, sdkMethod) {
117
+ if (await this.gatingActive()) {
118
+ this.assertFeature(schemaName, sdkMethod);
119
+ }
120
+ }
121
+ /**
122
+ * Whether gating is active for the call path. Resolves the version on first
123
+ * use; if no version can be resolved — detection failed, or the guard is a
124
+ * pass-through — it **fails open**: returns `false` (call passes through) and
125
+ * fires `onFailOpen` once. The unresolved state is cached, so detection is
126
+ * not re-attempted on every call. `ensureResolved`/`ready()` keep surfacing
127
+ * detection errors independently.
128
+ */
129
+ async gatingActive() {
130
+ if (this.failedOpen)
131
+ return false;
132
+ try {
133
+ await this.ensureResolved();
134
+ }
135
+ catch {
136
+ return this.enterFailOpen();
137
+ }
138
+ if (!this.resolved)
139
+ return this.enterFailOpen();
140
+ return true;
141
+ }
142
+ enterFailOpen() {
143
+ this.failedOpen = true;
144
+ if (!this.warned) {
145
+ this.warned = true;
146
+ this.onFailOpen?.();
147
+ }
148
+ return false;
149
+ }
150
+ /**
151
+ * Asserts the resolved version serves `METHOD /pathTemplate`.
152
+ * @param sdkMethod - Label for the error (defaults to the HTTP descriptor).
153
+ */
154
+ assertEndpoint(httpMethod, pathTemplate, sdkMethod) {
155
+ if (!this.resolved)
156
+ return;
157
+ const capability = `${httpMethod.toUpperCase()} ${pathTemplate}`;
158
+ if (!this.resolved.endpoints.has(capability)) {
159
+ throw new UnsupportedInVersionError({
160
+ capability,
161
+ kind: "endpoint",
162
+ appVersion: this.resolved.appVersion,
163
+ sdkMethod: sdkMethod ?? capability,
164
+ });
165
+ }
166
+ }
167
+ /** Asserts the resolved version defines the component schema `schemaName`. */
168
+ assertFeature(schemaName, sdkMethod) {
169
+ if (!this.resolved)
170
+ return;
171
+ if (!this.resolved.schemas.has(schemaName)) {
172
+ throw new UnsupportedInVersionError({
173
+ capability: schemaName,
174
+ kind: "feature",
175
+ appVersion: this.resolved.appVersion,
176
+ sdkMethod,
177
+ });
178
+ }
179
+ }
180
+ }
181
+ //# sourceMappingURL=version-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-guard.js","sourceRoot":"","sources":["../../src/versioning/version-guard.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@florent-uzio/custody",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "description": "An SDK to interact with the Ripple Custody API",
5
5
  "keywords": [
6
6
  "Ripple Custody",
@@ -36,8 +36,9 @@
36
36
  "check-format": "prettier --check .",
37
37
  "ci": "npm run build && npm run check-format && npm run test",
38
38
  "dev": "vitest",
39
+ "fetch:openapi-spec": "node ./scripts/fetch-openapi-release.mjs",
39
40
  "format": "prettier --write .",
40
- "generate:custody-types": "npx openapi-typescript ./openapi/Ripple-Custody-v1-OpenAPI.json -o ./src/models/custody-types.ts && prettier --write ./src/models/custody-types.ts",
41
+ "generate:custody-types": "node ./scripts/generate-custody-types/generate.mjs && prettier --write ./src/models/custody-types.ts ./src/models/capabilities.generated.ts",
41
42
  "local-release": "changeset version && changeset publish",
42
43
  "prepare": "npm run build",
43
44
  "release": "changeset publish",
@@ -49,25 +50,24 @@
49
50
  "test:coverage:ui": "vitest --coverage --ui"
50
51
  },
51
52
  "dependencies": {
52
- "axios": "^1.8.4",
53
- "canonicalize": "^2.1.0",
54
- "dayjs": "^1.11.19",
55
- "qs": "^6.14.1",
56
- "uuid": "^11.1.0",
57
- "xrpl": "^4.6.0"
53
+ "axios": "^1.18.1",
54
+ "canonicalize": "^3.0.0",
55
+ "dayjs": "^1.11.21",
56
+ "qs": "^6.15.3",
57
+ "uuid": "^14.0.1",
58
+ "xrpl": "^5.0.0"
58
59
  },
59
60
  "devDependencies": {
60
- "@arethetypeswrong/cli": "^0.18.2",
61
- "@changesets/cli": "^2.29.6",
62
- "@types/qs": "^6.14.0",
63
- "@vitest/coverage-v8": "^3.1.4",
64
- "@vitest/ui": "^3.1.4",
65
- "dotenv": "^16.4.7",
66
- "openapi-typescript": "^7.9.1",
67
- "prettier": "^3.5.3",
68
- "prettier-plugin-organize-imports": "^4.1.0",
69
- "ts-node": "^10.9.2",
70
- "typescript": "^5.8.2",
71
- "vitest": "^3.1.4"
61
+ "@arethetypeswrong/cli": "^0.18.5",
62
+ "@changesets/cli": "^2.31.0",
63
+ "@types/qs": "^6.15.1",
64
+ "@vitest/coverage-v8": "^4.1.10",
65
+ "@vitest/ui": "^4.1.10",
66
+ "dotenv": "^17.4.2",
67
+ "openapi-typescript": "^7.13.0",
68
+ "prettier": "^3.9.5",
69
+ "prettier-plugin-organize-imports": "^4.3.0",
70
+ "typescript": "^5.9.3",
71
+ "vitest": "^4.1.10"
72
72
  }
73
73
  }