@se-studio/contentful-rest-api 1.0.46 → 1.0.48

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 (298) hide show
  1. package/CHANGELOG.md +424 -0
  2. package/dist/api/article-type.d.ts +37 -0
  3. package/dist/api/article-type.d.ts.map +1 -0
  4. package/dist/api/article-type.js +134 -0
  5. package/dist/api/article-type.js.map +1 -0
  6. package/dist/api/article.d.ts +32 -0
  7. package/dist/api/article.d.ts.map +1 -0
  8. package/dist/api/article.js +43 -0
  9. package/dist/api/article.js.map +1 -0
  10. package/dist/api/asset.d.ts +28 -0
  11. package/dist/api/asset.d.ts.map +1 -0
  12. package/dist/api/asset.js +55 -0
  13. package/dist/api/asset.js.map +1 -0
  14. package/dist/api/context.d.ts +24 -0
  15. package/dist/api/context.d.ts.map +1 -0
  16. package/dist/api/context.js +62 -0
  17. package/dist/api/context.js.map +1 -0
  18. package/dist/api/custom-type.d.ts +37 -0
  19. package/dist/api/custom-type.d.ts.map +1 -0
  20. package/dist/api/custom-type.js +44 -0
  21. package/dist/api/custom-type.js.map +1 -0
  22. package/dist/api/helpers.d.ts +73 -0
  23. package/dist/api/helpers.d.ts.map +1 -0
  24. package/dist/api/helpers.js +296 -0
  25. package/dist/api/helpers.js.map +1 -0
  26. package/dist/api/index.d.ts +22 -0
  27. package/dist/api/index.d.ts.map +1 -0
  28. package/dist/api/index.js +28 -0
  29. package/dist/api/index.js.map +1 -0
  30. package/dist/api/links.d.ts +109 -0
  31. package/dist/api/links.d.ts.map +1 -0
  32. package/dist/api/links.js +199 -0
  33. package/dist/api/links.js.map +1 -0
  34. package/dist/api/page.d.ts +33 -0
  35. package/dist/api/page.d.ts.map +1 -0
  36. package/dist/api/page.js +40 -0
  37. package/dist/api/page.js.map +1 -0
  38. package/dist/api/person.d.ts +37 -0
  39. package/dist/api/person.d.ts.map +1 -0
  40. package/dist/api/person.js +134 -0
  41. package/dist/api/person.js.map +1 -0
  42. package/dist/api/preview.d.ts +55 -0
  43. package/dist/api/preview.d.ts.map +1 -0
  44. package/dist/api/preview.js +160 -0
  45. package/dist/api/preview.js.map +1 -0
  46. package/dist/api/related-articles.d.ts +22 -0
  47. package/dist/api/related-articles.d.ts.map +1 -0
  48. package/dist/api/related-articles.js +82 -0
  49. package/dist/api/related-articles.js.map +1 -0
  50. package/dist/api/server-asset.d.ts +40 -0
  51. package/dist/api/server-asset.d.ts.map +1 -0
  52. package/dist/api/server-asset.js +65 -0
  53. package/dist/api/server-asset.js.map +1 -0
  54. package/dist/api/sitemap.d.ts +131 -0
  55. package/dist/api/sitemap.d.ts.map +1 -0
  56. package/dist/api/sitemap.js +199 -0
  57. package/dist/api/sitemap.js.map +1 -0
  58. package/dist/api/tag.d.ts +37 -0
  59. package/dist/api/tag.d.ts.map +1 -0
  60. package/dist/api/tag.js +131 -0
  61. package/dist/api/tag.js.map +1 -0
  62. package/dist/api/template.d.ts +49 -0
  63. package/dist/api/template.d.ts.map +1 -0
  64. package/dist/api/template.js +88 -0
  65. package/dist/api/template.js.map +1 -0
  66. package/dist/api/types.d.ts +98 -0
  67. package/dist/api/types.d.ts.map +1 -0
  68. package/dist/api/types.js +2 -0
  69. package/dist/api/types.js.map +1 -0
  70. package/dist/baseTypes/baseAlternatePageContent.d.ts +24 -0
  71. package/dist/baseTypes/baseAlternatePageContent.d.ts.map +1 -0
  72. package/dist/baseTypes/baseAlternatePageContent.js +2 -0
  73. package/dist/baseTypes/baseAlternatePageContent.js.map +1 -0
  74. package/dist/baseTypes/baseArticle.d.ts +179 -0
  75. package/dist/baseTypes/baseArticle.d.ts.map +1 -0
  76. package/dist/baseTypes/baseArticle.js +2 -0
  77. package/dist/baseTypes/baseArticle.js.map +1 -0
  78. package/dist/baseTypes/baseArticleType.d.ts +156 -0
  79. package/dist/baseTypes/baseArticleType.d.ts.map +1 -0
  80. package/dist/baseTypes/baseArticleType.js +2 -0
  81. package/dist/baseTypes/baseArticleType.js.map +1 -0
  82. package/dist/baseTypes/baseBanner.d.ts +76 -0
  83. package/dist/baseTypes/baseBanner.d.ts.map +1 -0
  84. package/dist/baseTypes/baseBanner.js +2 -0
  85. package/dist/baseTypes/baseBanner.js.map +1 -0
  86. package/dist/baseTypes/baseCollection.d.ts +132 -0
  87. package/dist/baseTypes/baseCollection.d.ts.map +1 -0
  88. package/dist/baseTypes/baseCollection.js +2 -0
  89. package/dist/baseTypes/baseCollection.js.map +1 -0
  90. package/dist/baseTypes/baseComponent.d.ts +130 -0
  91. package/dist/baseTypes/baseComponent.d.ts.map +1 -0
  92. package/dist/baseTypes/baseComponent.js +2 -0
  93. package/dist/baseTypes/baseComponent.js.map +1 -0
  94. package/dist/baseTypes/baseCustomType.d.ts +126 -0
  95. package/dist/baseTypes/baseCustomType.d.ts.map +1 -0
  96. package/dist/baseTypes/baseCustomType.js +2 -0
  97. package/dist/baseTypes/baseCustomType.js.map +1 -0
  98. package/dist/baseTypes/baseExternalComponent.d.ts +66 -0
  99. package/dist/baseTypes/baseExternalComponent.d.ts.map +1 -0
  100. package/dist/baseTypes/baseExternalComponent.js +2 -0
  101. package/dist/baseTypes/baseExternalComponent.js.map +1 -0
  102. package/dist/baseTypes/baseExternalVideo.d.ts +85 -0
  103. package/dist/baseTypes/baseExternalVideo.d.ts.map +1 -0
  104. package/dist/baseTypes/baseExternalVideo.js +2 -0
  105. package/dist/baseTypes/baseExternalVideo.js.map +1 -0
  106. package/dist/baseTypes/baseLink.d.ts +90 -0
  107. package/dist/baseTypes/baseLink.d.ts.map +1 -0
  108. package/dist/baseTypes/baseLink.js +2 -0
  109. package/dist/baseTypes/baseLink.js.map +1 -0
  110. package/dist/baseTypes/baseMedia.d.ts +92 -0
  111. package/dist/baseTypes/baseMedia.d.ts.map +1 -0
  112. package/dist/baseTypes/baseMedia.js +2 -0
  113. package/dist/baseTypes/baseMedia.js.map +1 -0
  114. package/dist/baseTypes/baseNavigation.d.ts +36 -0
  115. package/dist/baseTypes/baseNavigation.d.ts.map +1 -0
  116. package/dist/baseTypes/baseNavigation.js +2 -0
  117. package/dist/baseTypes/baseNavigation.js.map +1 -0
  118. package/dist/baseTypes/baseNavigationItem.d.ts +96 -0
  119. package/dist/baseTypes/baseNavigationItem.d.ts.map +1 -0
  120. package/dist/baseTypes/baseNavigationItem.js +2 -0
  121. package/dist/baseTypes/baseNavigationItem.js.map +1 -0
  122. package/dist/baseTypes/basePage.d.ts +120 -0
  123. package/dist/baseTypes/basePage.d.ts.map +1 -0
  124. package/dist/baseTypes/basePage.js +2 -0
  125. package/dist/baseTypes/basePage.js.map +1 -0
  126. package/dist/baseTypes/basePageTest.d.ts +66 -0
  127. package/dist/baseTypes/basePageTest.d.ts.map +1 -0
  128. package/dist/baseTypes/basePageTest.js +2 -0
  129. package/dist/baseTypes/basePageTest.js.map +1 -0
  130. package/dist/baseTypes/basePageVariant.d.ts +123 -0
  131. package/dist/baseTypes/basePageVariant.d.ts.map +1 -0
  132. package/dist/baseTypes/basePageVariant.js +2 -0
  133. package/dist/baseTypes/basePageVariant.js.map +1 -0
  134. package/dist/baseTypes/basePerson.d.ts +111 -0
  135. package/dist/baseTypes/basePerson.d.ts.map +1 -0
  136. package/dist/baseTypes/basePerson.js +2 -0
  137. package/dist/baseTypes/basePerson.js.map +1 -0
  138. package/dist/baseTypes/baseSchema.d.ts +18 -0
  139. package/dist/baseTypes/baseSchema.d.ts.map +1 -0
  140. package/dist/baseTypes/baseSchema.js +2 -0
  141. package/dist/baseTypes/baseSchema.js.map +1 -0
  142. package/dist/baseTypes/baseShared.d.ts +30 -0
  143. package/dist/baseTypes/baseShared.d.ts.map +1 -0
  144. package/dist/baseTypes/baseShared.js +2 -0
  145. package/dist/baseTypes/baseShared.js.map +1 -0
  146. package/dist/baseTypes/baseTag.d.ts +108 -0
  147. package/dist/baseTypes/baseTag.d.ts.map +1 -0
  148. package/dist/baseTypes/baseTag.js +2 -0
  149. package/dist/baseTypes/baseTag.js.map +1 -0
  150. package/dist/baseTypes/baseTagType.d.ts +11 -0
  151. package/dist/baseTypes/baseTagType.d.ts.map +1 -0
  152. package/dist/baseTypes/baseTagType.js +2 -0
  153. package/dist/baseTypes/baseTagType.js.map +1 -0
  154. package/dist/baseTypes/baseTemplate.d.ts +55 -0
  155. package/dist/baseTypes/baseTemplate.d.ts.map +1 -0
  156. package/dist/baseTypes/baseTemplate.js +2 -0
  157. package/dist/baseTypes/baseTemplate.js.map +1 -0
  158. package/dist/client.d.ts +143 -0
  159. package/dist/client.d.ts.map +1 -0
  160. package/dist/client.js +268 -0
  161. package/dist/client.js.map +1 -0
  162. package/dist/converters/article.d.ts +42 -0
  163. package/dist/converters/article.d.ts.map +1 -0
  164. package/dist/converters/article.js +220 -0
  165. package/dist/converters/article.js.map +1 -0
  166. package/dist/converters/asset.d.ts +22 -0
  167. package/dist/converters/asset.d.ts.map +1 -0
  168. package/dist/converters/asset.js +282 -0
  169. package/dist/converters/asset.js.map +1 -0
  170. package/dist/converters/collection.d.ts +26 -0
  171. package/dist/converters/collection.d.ts.map +1 -0
  172. package/dist/converters/collection.js +50 -0
  173. package/dist/converters/collection.js.map +1 -0
  174. package/dist/converters/component.d.ts +26 -0
  175. package/dist/converters/component.d.ts.map +1 -0
  176. package/dist/converters/component.js +54 -0
  177. package/dist/converters/component.js.map +1 -0
  178. package/dist/converters/customType.d.ts +24 -0
  179. package/dist/converters/customType.d.ts.map +1 -0
  180. package/dist/converters/customType.js +71 -0
  181. package/dist/converters/customType.js.map +1 -0
  182. package/dist/converters/externalComponent.d.ts +22 -0
  183. package/dist/converters/externalComponent.d.ts.map +1 -0
  184. package/dist/converters/externalComponent.js +34 -0
  185. package/dist/converters/externalComponent.js.map +1 -0
  186. package/dist/converters/helpers.d.ts +116 -0
  187. package/dist/converters/helpers.d.ts.map +1 -0
  188. package/dist/converters/helpers.js +128 -0
  189. package/dist/converters/helpers.js.map +1 -0
  190. package/dist/converters/iconCollector.d.ts +65 -0
  191. package/dist/converters/iconCollector.d.ts.map +1 -0
  192. package/dist/converters/iconCollector.js +282 -0
  193. package/dist/converters/iconCollector.js.map +1 -0
  194. package/dist/converters/index.d.ts +18 -0
  195. package/dist/converters/index.d.ts.map +1 -0
  196. package/dist/converters/index.js +18 -0
  197. package/dist/converters/index.js.map +1 -0
  198. package/dist/converters/link.d.ts +11 -0
  199. package/dist/converters/link.d.ts.map +1 -0
  200. package/dist/converters/link.js +96 -0
  201. package/dist/converters/link.js.map +1 -0
  202. package/dist/converters/navigationItem.d.ts +11 -0
  203. package/dist/converters/navigationItem.d.ts.map +1 -0
  204. package/dist/converters/navigationItem.js +73 -0
  205. package/dist/converters/navigationItem.js.map +1 -0
  206. package/dist/converters/page.d.ts +44 -0
  207. package/dist/converters/page.d.ts.map +1 -0
  208. package/dist/converters/page.js +121 -0
  209. package/dist/converters/page.js.map +1 -0
  210. package/dist/converters/person.d.ts +40 -0
  211. package/dist/converters/person.d.ts.map +1 -0
  212. package/dist/converters/person.js +109 -0
  213. package/dist/converters/person.js.map +1 -0
  214. package/dist/converters/resolver.d.ts +29 -0
  215. package/dist/converters/resolver.d.ts.map +1 -0
  216. package/dist/converters/resolver.js +317 -0
  217. package/dist/converters/resolver.js.map +1 -0
  218. package/dist/converters/schema.d.ts +14 -0
  219. package/dist/converters/schema.d.ts.map +1 -0
  220. package/dist/converters/schema.js +18 -0
  221. package/dist/converters/schema.js.map +1 -0
  222. package/dist/converters/svgProcessor.d.ts +23 -0
  223. package/dist/converters/svgProcessor.d.ts.map +1 -0
  224. package/dist/converters/svgProcessor.js +47 -0
  225. package/dist/converters/svgProcessor.js.map +1 -0
  226. package/dist/converters/tag.d.ts +25 -0
  227. package/dist/converters/tag.d.ts.map +1 -0
  228. package/dist/converters/tag.js +98 -0
  229. package/dist/converters/tag.js.map +1 -0
  230. package/dist/converters/template.d.ts +26 -0
  231. package/dist/converters/template.d.ts.map +1 -0
  232. package/dist/converters/template.js +44 -0
  233. package/dist/converters/template.js.map +1 -0
  234. package/dist/index.d.ts +28 -721
  235. package/dist/index.d.ts.map +1 -0
  236. package/dist/index.js +37 -3634
  237. package/dist/index.js.map +1 -1
  238. package/dist/revalidation/handlers.d.ts +52 -0
  239. package/dist/revalidation/handlers.d.ts.map +1 -0
  240. package/dist/revalidation/handlers.js +130 -0
  241. package/dist/revalidation/handlers.js.map +1 -0
  242. package/dist/revalidation/index.d.ts +3 -0
  243. package/dist/revalidation/index.d.ts.map +1 -0
  244. package/dist/revalidation/index.js +4 -0
  245. package/dist/revalidation/index.js.map +1 -0
  246. package/dist/revalidation/nextjs-route.d.ts +31 -0
  247. package/dist/revalidation/nextjs-route.d.ts.map +1 -0
  248. package/dist/revalidation/nextjs-route.js +34 -0
  249. package/dist/revalidation/nextjs-route.js.map +1 -0
  250. package/dist/revalidation/route.d.ts +3 -0
  251. package/dist/revalidation/route.d.ts.map +1 -0
  252. package/dist/revalidation/route.js +97 -0
  253. package/dist/revalidation/route.js.map +1 -0
  254. package/dist/revalidation/server-utils.d.ts +22 -0
  255. package/dist/revalidation/server-utils.d.ts.map +1 -0
  256. package/dist/revalidation/server-utils.js +41 -0
  257. package/dist/revalidation/server-utils.js.map +1 -0
  258. package/dist/revalidation/tags.d.ts +81 -0
  259. package/dist/revalidation/tags.d.ts.map +1 -0
  260. package/dist/revalidation/tags.js +117 -0
  261. package/dist/revalidation/tags.js.map +1 -0
  262. package/dist/revalidation/utils.d.ts +21 -0
  263. package/dist/revalidation/utils.d.ts.map +1 -0
  264. package/dist/revalidation/utils.js +51 -0
  265. package/dist/revalidation/utils.js.map +1 -0
  266. package/dist/server.d.ts +7 -0
  267. package/dist/server.d.ts.map +1 -0
  268. package/dist/server.js +10 -0
  269. package/dist/server.js.map +1 -0
  270. package/dist/types.d.ts +67 -0
  271. package/dist/types.d.ts.map +1 -0
  272. package/dist/types.js +2 -0
  273. package/dist/types.js.map +1 -0
  274. package/dist/utils/arrayUtils.d.ts +3 -0
  275. package/dist/utils/arrayUtils.d.ts.map +1 -0
  276. package/dist/utils/arrayUtils.js +12 -0
  277. package/dist/utils/arrayUtils.js.map +1 -0
  278. package/dist/utils/dateUtils.d.ts +9 -0
  279. package/dist/utils/dateUtils.d.ts.map +1 -0
  280. package/dist/utils/dateUtils.js +26 -0
  281. package/dist/utils/dateUtils.js.map +1 -0
  282. package/dist/utils/errors.d.ts +56 -0
  283. package/dist/utils/errors.d.ts.map +1 -0
  284. package/dist/utils/errors.js +100 -0
  285. package/dist/utils/errors.js.map +1 -0
  286. package/dist/utils/index.d.ts +8 -0
  287. package/dist/utils/index.d.ts.map +1 -0
  288. package/dist/utils/index.js +8 -0
  289. package/dist/utils/index.js.map +1 -0
  290. package/dist/utils/json-utils.d.ts +17 -0
  291. package/dist/utils/json-utils.d.ts.map +1 -0
  292. package/dist/utils/json-utils.js +43 -0
  293. package/dist/utils/json-utils.js.map +1 -0
  294. package/dist/utils/retry.d.ts +112 -0
  295. package/dist/utils/retry.d.ts.map +1 -0
  296. package/dist/utils/retry.js +221 -0
  297. package/dist/utils/retry.js.map +1 -0
  298. package/package.json +12 -6
@@ -0,0 +1,112 @@
1
+ import type { RetryConfig } from '../types';
2
+ /**
3
+ * Calculates the delay for the next retry attempt using exponential backoff
4
+ *
5
+ * @param attempt - Current retry attempt (0-based)
6
+ * @param config - Retry configuration
7
+ * @param retryAfter - Optional retry-after value from rate limit response
8
+ * @returns Delay in milliseconds
9
+ */
10
+ export declare function calculateBackoffDelay(attempt: number, config: Required<RetryConfig>, retryAfter?: number): number;
11
+ /**
12
+ * Executes a function with retry logic
13
+ *
14
+ * @param fn - Async function to execute
15
+ * @param config - Retry configuration
16
+ * @returns Promise resolving to the function result
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const result = await withRetry(
21
+ * async () => await client.getEntry('id'),
22
+ * { maxRetries: 3, initialDelay: 1000 }
23
+ * );
24
+ * ```
25
+ */
26
+ export declare function withRetry<T>(fn: () => Promise<T>, config?: RetryConfig): Promise<T>;
27
+ /**
28
+ * Interval-based rate limiter that enforces minimum time between requests.
29
+ * Unlike token bucket, this prevents bursts entirely by spacing requests evenly.
30
+ * Requests are processed in FIFO order with guaranteed minimum intervals.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * const limiter = new RateLimiter(14); // 14 req/s = ~71ms between requests
35
+ * await limiter.acquire(); // Wait for permission to make request
36
+ * await fetch(...);
37
+ * ```
38
+ */
39
+ export declare class RateLimiter {
40
+ /** Minimum interval between requests in milliseconds */
41
+ private readonly intervalMs;
42
+ /** Timestamp when the next request can be made */
43
+ private nextAvailableTime;
44
+ /** Queue of pending requests */
45
+ private readonly queue;
46
+ /** Whether the queue processor is running */
47
+ private processing;
48
+ /** Additional pause time from 429 responses (ms) */
49
+ private pauseUntil;
50
+ constructor(requestsPerSecond: number,
51
+ /** @deprecated Use single parameter - kept for backward compatibility */
52
+ _refillRate?: number);
53
+ /**
54
+ * Calculates how long to wait before the next request can be made
55
+ */
56
+ private getWaitTime;
57
+ /**
58
+ * Processes the queue, releasing requests one at a time with proper spacing
59
+ */
60
+ private processQueue;
61
+ /**
62
+ * Acquires permission to make a request.
63
+ * Returns a promise that resolves when the request can proceed.
64
+ * Requests are processed in FIFO order with minimum interval spacing.
65
+ *
66
+ * @returns Promise that resolves when rate limit allows the request
67
+ */
68
+ acquire(): Promise<void>;
69
+ /**
70
+ * Gets the number of requests currently waiting in the queue
71
+ */
72
+ getQueueLength(): number;
73
+ /**
74
+ * Pauses the rate limiter for a specified duration.
75
+ * All requests (current and queued) will wait until pause expires.
76
+ * Does NOT block - just sets the pause time and returns.
77
+ *
78
+ * @param seconds - Duration to pause in seconds
79
+ */
80
+ pause(seconds: number): void;
81
+ /**
82
+ * Gets the current interval between requests in milliseconds
83
+ */
84
+ getIntervalMs(): number;
85
+ }
86
+ /**
87
+ * Rate limits for Contentful APIs (requests per second)
88
+ */
89
+ export declare const CONTENTFUL_RATE_LIMITS: {
90
+ /** Content Delivery API: 55 requests/second */
91
+ readonly delivery: 55;
92
+ /** Content Preview API: 14 requests/second */
93
+ readonly preview: 14;
94
+ };
95
+ /**
96
+ * Shared rate limiter for Contentful Delivery API (55 req/s)
97
+ * Module-level singleton shared across all client instances
98
+ */
99
+ export declare const deliveryRateLimiter: RateLimiter;
100
+ /**
101
+ * Shared rate limiter for Contentful Preview API (14 req/s)
102
+ * Module-level singleton shared across all client instances
103
+ */
104
+ export declare const previewRateLimiter: RateLimiter;
105
+ /**
106
+ * Gets the appropriate rate limiter based on preview mode
107
+ *
108
+ * @param preview - Whether using preview API
109
+ * @returns The appropriate rate limiter instance
110
+ */
111
+ export declare function getRateLimiter(preview: boolean): RateLimiter;
112
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAoB5C;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC7B,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAaR;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAyCzF;AASD;;;;;;;;;;;GAWG;AACH,qBAAa,WAAW;IACtB,wDAAwD;IACxD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,kDAAkD;IAClD,OAAO,CAAC,iBAAiB,CAAa;IACtC,gCAAgC;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,6CAA6C;IAC7C,OAAO,CAAC,UAAU,CAAS;IAC3B,oDAAoD;IACpD,OAAO,CAAC,UAAU,CAAa;gBAG7B,iBAAiB,EAAE,MAAM;IACzB,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM;IAOtB;;OAEG;IACH,OAAO,CAAC,WAAW;IAOnB;;OAEG;YACW,YAAY;IAyB1B;;;;;;OAMG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB9B;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;;;;;OAMG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQ5B;;OAEG;IACH,aAAa,IAAI,MAAM;CAGxB;AAMD;;GAEG;AACH,eAAO,MAAM,sBAAsB;IACjC,+CAA+C;;IAE/C,8CAA8C;;CAEtC,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,mBAAmB,aAAmD,CAAC;AAEpF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,aAAkD,CAAC;AAElF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAE5D"}
@@ -0,0 +1,221 @@
1
+ import { getRetryAfter, isRetryableError } from './errors';
2
+ /**
3
+ * Default retry configuration
4
+ */
5
+ const DEFAULT_RETRY_CONFIG = {
6
+ maxRetries: 3,
7
+ initialDelay: 1000, // 1 second
8
+ maxDelay: 30000, // 30 seconds
9
+ backoffMultiplier: 2,
10
+ };
11
+ /**
12
+ * Sleep utility for async delays
13
+ */
14
+ function sleep(ms) {
15
+ return new Promise((resolve) => setTimeout(resolve, ms));
16
+ }
17
+ /**
18
+ * Calculates the delay for the next retry attempt using exponential backoff
19
+ *
20
+ * @param attempt - Current retry attempt (0-based)
21
+ * @param config - Retry configuration
22
+ * @param retryAfter - Optional retry-after value from rate limit response
23
+ * @returns Delay in milliseconds
24
+ */
25
+ export function calculateBackoffDelay(attempt, config, retryAfter) {
26
+ // If server specified retry-after, use that
27
+ if (retryAfter !== undefined) {
28
+ return Math.min(retryAfter * 1000, config.maxDelay);
29
+ }
30
+ // Calculate exponential backoff
31
+ const exponentialDelay = config.initialDelay * config.backoffMultiplier ** attempt;
32
+ // Add jitter (random value between 0 and delay) to prevent thundering herd
33
+ const jitter = Math.random() * exponentialDelay;
34
+ return Math.min(exponentialDelay + jitter, config.maxDelay);
35
+ }
36
+ /**
37
+ * Executes a function with retry logic
38
+ *
39
+ * @param fn - Async function to execute
40
+ * @param config - Retry configuration
41
+ * @returns Promise resolving to the function result
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * const result = await withRetry(
46
+ * async () => await client.getEntry('id'),
47
+ * { maxRetries: 3, initialDelay: 1000 }
48
+ * );
49
+ * ```
50
+ */
51
+ export async function withRetry(fn, config) {
52
+ const retryConfig = {
53
+ ...DEFAULT_RETRY_CONFIG,
54
+ ...config,
55
+ };
56
+ let lastError;
57
+ for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {
58
+ try {
59
+ return await fn();
60
+ }
61
+ catch (error) {
62
+ lastError = error;
63
+ // Don't retry if it's the last attempt
64
+ if (attempt === retryConfig.maxRetries) {
65
+ break;
66
+ }
67
+ // Only retry if the error is retryable
68
+ if (!isRetryableError(error)) {
69
+ throw error;
70
+ }
71
+ const retryAfter = getRetryAfter(error);
72
+ const delay = calculateBackoffDelay(attempt, retryConfig, retryAfter);
73
+ // Only log in development mode
74
+ if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {
75
+ console.warn(`Retry attempt ${attempt + 1}/${retryConfig.maxRetries} after ${delay}ms`, error);
76
+ }
77
+ await sleep(delay);
78
+ }
79
+ }
80
+ // If we get here, all retries failed
81
+ throw lastError;
82
+ }
83
+ /**
84
+ * Interval-based rate limiter that enforces minimum time between requests.
85
+ * Unlike token bucket, this prevents bursts entirely by spacing requests evenly.
86
+ * Requests are processed in FIFO order with guaranteed minimum intervals.
87
+ *
88
+ * @example
89
+ * ```ts
90
+ * const limiter = new RateLimiter(14); // 14 req/s = ~71ms between requests
91
+ * await limiter.acquire(); // Wait for permission to make request
92
+ * await fetch(...);
93
+ * ```
94
+ */
95
+ export class RateLimiter {
96
+ /** Minimum interval between requests in milliseconds */
97
+ intervalMs;
98
+ /** Timestamp when the next request can be made */
99
+ nextAvailableTime = 0;
100
+ /** Queue of pending requests */
101
+ queue = [];
102
+ /** Whether the queue processor is running */
103
+ processing = false;
104
+ /** Additional pause time from 429 responses (ms) */
105
+ pauseUntil = 0;
106
+ constructor(requestsPerSecond,
107
+ /** @deprecated Use single parameter - kept for backward compatibility */
108
+ _refillRate) {
109
+ // Calculate minimum interval between requests
110
+ // Use 80% of theoretical max to leave headroom
111
+ this.intervalMs = Math.ceil(1000 / (requestsPerSecond * 0.8));
112
+ }
113
+ /**
114
+ * Calculates how long to wait before the next request can be made
115
+ */
116
+ getWaitTime() {
117
+ const now = Date.now();
118
+ const waitForInterval = Math.max(0, this.nextAvailableTime - now);
119
+ const waitForPause = Math.max(0, this.pauseUntil - now);
120
+ return Math.max(waitForInterval, waitForPause);
121
+ }
122
+ /**
123
+ * Processes the queue, releasing requests one at a time with proper spacing
124
+ */
125
+ async processQueue() {
126
+ if (this.processing) {
127
+ return;
128
+ }
129
+ this.processing = true;
130
+ while (this.queue.length > 0) {
131
+ const waitTime = this.getWaitTime();
132
+ if (waitTime > 0) {
133
+ await sleep(waitTime);
134
+ }
135
+ // Update next available time BEFORE releasing the request
136
+ this.nextAvailableTime = Date.now() + this.intervalMs;
137
+ // Release the next queued request
138
+ const entry = this.queue.shift();
139
+ entry?.resolve();
140
+ }
141
+ this.processing = false;
142
+ }
143
+ /**
144
+ * Acquires permission to make a request.
145
+ * Returns a promise that resolves when the request can proceed.
146
+ * Requests are processed in FIFO order with minimum interval spacing.
147
+ *
148
+ * @returns Promise that resolves when rate limit allows the request
149
+ */
150
+ async acquire() {
151
+ const waitTime = this.getWaitTime();
152
+ // If no wait needed and no queue, proceed immediately
153
+ if (waitTime === 0 && this.queue.length === 0) {
154
+ this.nextAvailableTime = Date.now() + this.intervalMs;
155
+ return;
156
+ }
157
+ // Otherwise, queue the request
158
+ return new Promise((resolve) => {
159
+ this.queue.push({ resolve });
160
+ this.processQueue();
161
+ });
162
+ }
163
+ /**
164
+ * Gets the number of requests currently waiting in the queue
165
+ */
166
+ getQueueLength() {
167
+ return this.queue.length;
168
+ }
169
+ /**
170
+ * Pauses the rate limiter for a specified duration.
171
+ * All requests (current and queued) will wait until pause expires.
172
+ * Does NOT block - just sets the pause time and returns.
173
+ *
174
+ * @param seconds - Duration to pause in seconds
175
+ */
176
+ pause(seconds) {
177
+ const pauseUntil = Date.now() + seconds * 1000;
178
+ // Only extend pause, never shorten it
179
+ if (pauseUntil > this.pauseUntil) {
180
+ this.pauseUntil = pauseUntil;
181
+ }
182
+ }
183
+ /**
184
+ * Gets the current interval between requests in milliseconds
185
+ */
186
+ getIntervalMs() {
187
+ return this.intervalMs;
188
+ }
189
+ }
190
+ // ============================================================================
191
+ // Shared Rate Limiter Instances
192
+ // ============================================================================
193
+ /**
194
+ * Rate limits for Contentful APIs (requests per second)
195
+ */
196
+ export const CONTENTFUL_RATE_LIMITS = {
197
+ /** Content Delivery API: 55 requests/second */
198
+ delivery: 55,
199
+ /** Content Preview API: 14 requests/second */
200
+ preview: 14,
201
+ };
202
+ /**
203
+ * Shared rate limiter for Contentful Delivery API (55 req/s)
204
+ * Module-level singleton shared across all client instances
205
+ */
206
+ export const deliveryRateLimiter = new RateLimiter(CONTENTFUL_RATE_LIMITS.delivery);
207
+ /**
208
+ * Shared rate limiter for Contentful Preview API (14 req/s)
209
+ * Module-level singleton shared across all client instances
210
+ */
211
+ export const previewRateLimiter = new RateLimiter(CONTENTFUL_RATE_LIMITS.preview);
212
+ /**
213
+ * Gets the appropriate rate limiter based on preview mode
214
+ *
215
+ * @param preview - Whether using preview API
216
+ * @returns The appropriate rate limiter instance
217
+ */
218
+ export function getRateLimiter(preview) {
219
+ return preview ? previewRateLimiter : deliveryRateLimiter;
220
+ }
221
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@se-studio/contentful-rest-api",
3
- "version": "1.0.46",
3
+ "version": "1.0.48",
4
4
  "description": "Type-safe Contentful REST API client with caching and rate limiting for Next.js applications",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,10 +15,15 @@
15
15
  ".": {
16
16
  "types": "./dist/index.d.ts",
17
17
  "import": "./dist/index.js"
18
+ },
19
+ "./server": {
20
+ "types": "./dist/server.d.ts",
21
+ "import": "./dist/server.js"
18
22
  }
19
23
  },
20
24
  "files": [
21
- "dist"
25
+ "dist",
26
+ "*.md"
22
27
  ],
23
28
  "keywords": [
24
29
  "contentful",
@@ -44,14 +49,15 @@
44
49
  "dependencies": {
45
50
  "@contentful/rich-text-types": "^17.2.5",
46
51
  "contentful": "^11.10.1",
47
- "@se-studio/core-data-types": "1.0.46"
52
+ "server-only": "0.0.1",
53
+ "@se-studio/core-data-types": "1.0.48"
48
54
  },
49
55
  "peerDependencies": {
50
56
  "next": ">=15.5.0"
51
57
  },
52
58
  "devDependencies": {
53
59
  "@biomejs/biome": "^2.3.10",
54
- "@types/node": "^24.10.4",
60
+ "@types/node": "^22.19.3",
55
61
  "next": "^15.5.9",
56
62
  "tsup": "^8.5.1",
57
63
  "tsx": "^4.21.0",
@@ -59,8 +65,8 @@
59
65
  "vitest": "^4.0.16"
60
66
  },
61
67
  "scripts": {
62
- "build": "tsup",
63
- "dev": "tsup --watch --no-clean",
68
+ "build": "tsc --project tsconfig.build.json",
69
+ "dev": "tsc --project tsconfig.build.json --watch",
64
70
  "test": "vitest run",
65
71
  "test:watch": "vitest",
66
72
  "type-check": "tsc --noEmit",