@fastpix/fastpix-node 2.0.4 → 2.0.6

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 (542) hide show
  1. package/FUNCTIONS.md +1 -1
  2. package/README.md +11 -11
  3. package/dist/commonjs/funcs/aiFeaturesGenerateNamedEntities.d.ts +2 -2
  4. package/dist/commonjs/funcs/aiFeaturesGenerateNamedEntities.js +2 -2
  5. package/dist/commonjs/funcs/aiFeaturesUpdateSummary.d.ts +2 -2
  6. package/dist/commonjs/funcs/aiFeaturesUpdateSummary.js +2 -2
  7. package/dist/commonjs/funcs/dimensionsList.d.ts +2 -2
  8. package/dist/commonjs/funcs/dimensionsList.js +2 -2
  9. package/dist/commonjs/funcs/dimensionsListFilterValues.d.ts +2 -2
  10. package/dist/commonjs/funcs/dimensionsListFilterValues.js +2 -2
  11. package/dist/commonjs/funcs/drmConfigurationsGet.d.ts +1 -1
  12. package/dist/commonjs/funcs/drmConfigurationsGet.js +1 -1
  13. package/dist/commonjs/funcs/drmConfigurationsList.d.ts +1 -1
  14. package/dist/commonjs/funcs/drmConfigurationsList.js +1 -1
  15. package/dist/commonjs/funcs/errorsList.d.ts +1 -1
  16. package/dist/commonjs/funcs/errorsList.js +1 -1
  17. package/dist/commonjs/funcs/inVideoAIUpdateModeration.d.ts +2 -2
  18. package/dist/commonjs/funcs/inVideoAIUpdateModeration.js +2 -2
  19. package/dist/commonjs/funcs/inVideoAIfeaturesGenerateChapters.d.ts +2 -2
  20. package/dist/commonjs/funcs/inVideoAIfeaturesGenerateChapters.js +2 -2
  21. package/dist/commonjs/funcs/inputVideoCreate.d.ts +4 -4
  22. package/dist/commonjs/funcs/inputVideoCreate.js +4 -4
  23. package/dist/commonjs/funcs/inputVideoUpload.d.ts +5 -5
  24. package/dist/commonjs/funcs/inputVideoUpload.js +5 -5
  25. package/dist/commonjs/funcs/liveStreamsCreate.d.ts +3 -3
  26. package/dist/commonjs/funcs/liveStreamsCreate.js +3 -3
  27. package/dist/commonjs/funcs/liveStreamsDelete.d.ts +2 -2
  28. package/dist/commonjs/funcs/liveStreamsDelete.js +2 -2
  29. package/dist/commonjs/funcs/liveStreamsEnable.d.ts +1 -1
  30. package/dist/commonjs/funcs/liveStreamsEnable.js +1 -1
  31. package/dist/commonjs/funcs/liveStreamsListClips.d.ts +1 -1
  32. package/dist/commonjs/funcs/liveStreamsListClips.js +1 -1
  33. package/dist/commonjs/funcs/manageLiveStreamComplete.d.ts +1 -1
  34. package/dist/commonjs/funcs/manageLiveStreamComplete.js +1 -1
  35. package/dist/commonjs/funcs/manageLiveStreamDisable.d.ts +1 -1
  36. package/dist/commonjs/funcs/manageLiveStreamDisable.js +1 -1
  37. package/dist/commonjs/funcs/manageLiveStreamGet.d.ts +1 -1
  38. package/dist/commonjs/funcs/manageLiveStreamGet.js +1 -1
  39. package/dist/commonjs/funcs/manageLiveStreamGetViewerCount.d.ts +1 -1
  40. package/dist/commonjs/funcs/manageLiveStreamGetViewerCount.js +1 -1
  41. package/dist/commonjs/funcs/manageLiveStreamUpdate.d.ts +2 -2
  42. package/dist/commonjs/funcs/manageLiveStreamUpdate.js +2 -2
  43. package/dist/commonjs/funcs/manageVideosAddTrack.d.ts +5 -5
  44. package/dist/commonjs/funcs/manageVideosAddTrack.js +5 -5
  45. package/dist/commonjs/funcs/manageVideosCancelUpload.d.ts +1 -1
  46. package/dist/commonjs/funcs/manageVideosCancelUpload.js +1 -1
  47. package/dist/commonjs/funcs/manageVideosDelete.d.ts +1 -1
  48. package/dist/commonjs/funcs/manageVideosDelete.js +1 -1
  49. package/dist/commonjs/funcs/manageVideosGenerateSubtitleTrack.d.ts +3 -3
  50. package/dist/commonjs/funcs/manageVideosGenerateSubtitleTrack.js +3 -3
  51. package/dist/commonjs/funcs/manageVideosGet.d.ts +1 -1
  52. package/dist/commonjs/funcs/manageVideosGet.js +1 -1
  53. package/dist/commonjs/funcs/manageVideosUpdate.d.ts +1 -1
  54. package/dist/commonjs/funcs/manageVideosUpdate.js +1 -1
  55. package/dist/commonjs/funcs/manageVideosUpdateMp4Support.d.ts +3 -3
  56. package/dist/commonjs/funcs/manageVideosUpdateMp4Support.js +3 -3
  57. package/dist/commonjs/funcs/manageVideosUpdateTrack.d.ts +4 -4
  58. package/dist/commonjs/funcs/manageVideosUpdateTrack.js +4 -4
  59. package/dist/commonjs/funcs/mediaDeleteTrack.d.ts +2 -2
  60. package/dist/commonjs/funcs/mediaDeleteTrack.js +2 -2
  61. package/dist/commonjs/funcs/mediaGetClips.d.ts +1 -1
  62. package/dist/commonjs/funcs/mediaGetClips.js +1 -1
  63. package/dist/commonjs/funcs/mediaUpdateSourceAccess.d.ts +1 -1
  64. package/dist/commonjs/funcs/mediaUpdateSourceAccess.js +1 -1
  65. package/dist/commonjs/funcs/metricsListBreakdownValues.d.ts +2 -2
  66. package/dist/commonjs/funcs/metricsListBreakdownValues.js +2 -2
  67. package/dist/commonjs/funcs/metricsListCompares.d.ts +2 -2
  68. package/dist/commonjs/funcs/metricsListCompares.js +2 -2
  69. package/dist/commonjs/funcs/metricsListOverallValues.d.ts +2 -2
  70. package/dist/commonjs/funcs/metricsListOverallValues.js +2 -2
  71. package/dist/commonjs/funcs/playbackCreate.d.ts +1 -1
  72. package/dist/commonjs/funcs/playbackCreate.js +1 -1
  73. package/dist/commonjs/funcs/playlistCreate.d.ts +1 -1
  74. package/dist/commonjs/funcs/playlistCreate.js +1 -1
  75. package/dist/commonjs/funcs/signingKeysCreate.d.ts +1 -1
  76. package/dist/commonjs/funcs/signingKeysCreate.js +1 -1
  77. package/dist/commonjs/funcs/signingKeysGetById.d.ts +2 -2
  78. package/dist/commonjs/funcs/signingKeysGetById.js +2 -2
  79. package/dist/commonjs/funcs/simulcastStreamsDelete.d.ts +1 -1
  80. package/dist/commonjs/funcs/simulcastStreamsDelete.js +1 -1
  81. package/dist/commonjs/funcs/simulcastsCreate.d.ts +2 -2
  82. package/dist/commonjs/funcs/simulcastsCreate.js +2 -2
  83. package/dist/commonjs/funcs/simulcastsUpdate.d.ts +1 -1
  84. package/dist/commonjs/funcs/simulcastsUpdate.js +1 -1
  85. package/dist/commonjs/funcs/viewsGetDetails.d.ts +1 -1
  86. package/dist/commonjs/funcs/viewsGetDetails.js +1 -1
  87. package/dist/commonjs/funcs/viewsList.d.ts +3 -3
  88. package/dist/commonjs/funcs/viewsList.js +3 -3
  89. package/dist/commonjs/funcs/viewsListTopContent.d.ts +1 -1
  90. package/dist/commonjs/funcs/viewsListTopContent.js +1 -1
  91. package/dist/commonjs/hooks/eventsFieldRemapHook.d.ts +5 -0
  92. package/dist/commonjs/hooks/eventsFieldRemapHook.d.ts.map +1 -0
  93. package/dist/commonjs/hooks/eventsFieldRemapHook.js +84 -0
  94. package/dist/commonjs/hooks/eventsFieldRemapHook.js.map +1 -0
  95. package/dist/commonjs/hooks/registration.d.ts.map +1 -1
  96. package/dist/commonjs/hooks/registration.js +2 -4
  97. package/dist/commonjs/hooks/registration.js.map +1 -1
  98. package/dist/commonjs/lib/config.d.ts +3 -3
  99. package/dist/commonjs/lib/config.d.ts.map +1 -1
  100. package/dist/commonjs/lib/config.js +3 -3
  101. package/dist/commonjs/lib/config.js.map +1 -1
  102. package/dist/commonjs/models/addtrackrequest.js +1 -1
  103. package/dist/commonjs/models/addtrackrequest.js.map +1 -1
  104. package/dist/commonjs/models/createmediarequest.d.ts +1 -1
  105. package/dist/commonjs/models/deletesigningkeyresponse.d.ts +10 -0
  106. package/dist/commonjs/models/deletesigningkeyresponse.d.ts.map +1 -1
  107. package/dist/commonjs/models/deletesigningkeyresponse.js +1 -0
  108. package/dist/commonjs/models/deletesigningkeyresponse.js.map +1 -1
  109. package/dist/commonjs/models/operations/directuploadvideomedia.d.ts +2 -2
  110. package/dist/commonjs/models/pullvideoinput.js +1 -1
  111. package/dist/commonjs/models/pullvideoinput.js.map +1 -1
  112. package/dist/commonjs/models/videotrackforgetall.d.ts +4 -0
  113. package/dist/commonjs/models/videotrackforgetall.d.ts.map +1 -1
  114. package/dist/commonjs/models/videotrackforgetall.js +1 -0
  115. package/dist/commonjs/models/videotrackforgetall.js.map +1 -1
  116. package/dist/commonjs/models/views.d.ts +3 -3
  117. package/dist/commonjs/models/views.d.ts.map +1 -1
  118. package/dist/commonjs/models/views.js +4 -9
  119. package/dist/commonjs/models/views.js.map +1 -1
  120. package/dist/commonjs/models/viewslist.d.ts +7 -1
  121. package/dist/commonjs/models/viewslist.d.ts.map +1 -1
  122. package/dist/commonjs/models/viewslist.js +3 -7
  123. package/dist/commonjs/models/viewslist.js.map +1 -1
  124. package/dist/commonjs/models/watermarkinput.d.ts +1 -1
  125. package/dist/commonjs/sdk/aifeatures.d.ts +4 -4
  126. package/dist/commonjs/sdk/aifeatures.js +4 -4
  127. package/dist/commonjs/sdk/dimensions.d.ts +4 -4
  128. package/dist/commonjs/sdk/dimensions.js +4 -4
  129. package/dist/commonjs/sdk/drmconfigurations.d.ts +2 -2
  130. package/dist/commonjs/sdk/drmconfigurations.js +2 -2
  131. package/dist/commonjs/sdk/errors.d.ts +1 -1
  132. package/dist/commonjs/sdk/errors.js +1 -1
  133. package/dist/commonjs/sdk/inputvideo.d.ts +9 -9
  134. package/dist/commonjs/sdk/inputvideo.js +9 -9
  135. package/dist/commonjs/sdk/invideoai.d.ts +2 -2
  136. package/dist/commonjs/sdk/invideoai.js +2 -2
  137. package/dist/commonjs/sdk/invideoaifeatures.d.ts +2 -2
  138. package/dist/commonjs/sdk/invideoaifeatures.js +2 -2
  139. package/dist/commonjs/sdk/livestreams.d.ts +7 -7
  140. package/dist/commonjs/sdk/livestreams.js +7 -7
  141. package/dist/commonjs/sdk/managelivestream.d.ts +6 -6
  142. package/dist/commonjs/sdk/managelivestream.js +6 -6
  143. package/dist/commonjs/sdk/managevideos.d.ts +19 -19
  144. package/dist/commonjs/sdk/managevideos.js +19 -19
  145. package/dist/commonjs/sdk/media.d.ts +4 -4
  146. package/dist/commonjs/sdk/media.js +4 -4
  147. package/dist/commonjs/sdk/metrics.d.ts +6 -6
  148. package/dist/commonjs/sdk/metrics.js +6 -6
  149. package/dist/commonjs/sdk/playback.d.ts +1 -1
  150. package/dist/commonjs/sdk/playback.js +1 -1
  151. package/dist/commonjs/sdk/playlist.d.ts +1 -1
  152. package/dist/commonjs/sdk/playlist.js +1 -1
  153. package/dist/commonjs/sdk/signingkeys.d.ts +3 -3
  154. package/dist/commonjs/sdk/signingkeys.js +3 -3
  155. package/dist/commonjs/sdk/simulcasts.d.ts +3 -3
  156. package/dist/commonjs/sdk/simulcasts.js +3 -3
  157. package/dist/commonjs/sdk/simulcaststreams.d.ts +1 -1
  158. package/dist/commonjs/sdk/simulcaststreams.js +1 -1
  159. package/dist/commonjs/sdk/views.d.ts +5 -5
  160. package/dist/commonjs/sdk/views.js +5 -5
  161. package/dist/esm/funcs/aiFeaturesGenerateNamedEntities.d.ts +2 -2
  162. package/dist/esm/funcs/aiFeaturesGenerateNamedEntities.js +2 -2
  163. package/dist/esm/funcs/aiFeaturesUpdateSummary.d.ts +2 -2
  164. package/dist/esm/funcs/aiFeaturesUpdateSummary.js +2 -2
  165. package/dist/esm/funcs/dimensionsList.d.ts +2 -2
  166. package/dist/esm/funcs/dimensionsList.js +2 -2
  167. package/dist/esm/funcs/dimensionsListFilterValues.d.ts +2 -2
  168. package/dist/esm/funcs/dimensionsListFilterValues.js +2 -2
  169. package/dist/esm/funcs/drmConfigurationsGet.d.ts +1 -1
  170. package/dist/esm/funcs/drmConfigurationsGet.js +1 -1
  171. package/dist/esm/funcs/drmConfigurationsList.d.ts +1 -1
  172. package/dist/esm/funcs/drmConfigurationsList.js +1 -1
  173. package/dist/esm/funcs/errorsList.d.ts +1 -1
  174. package/dist/esm/funcs/errorsList.js +1 -1
  175. package/dist/esm/funcs/inVideoAIUpdateModeration.d.ts +2 -2
  176. package/dist/esm/funcs/inVideoAIUpdateModeration.js +2 -2
  177. package/dist/esm/funcs/inVideoAIfeaturesGenerateChapters.d.ts +2 -2
  178. package/dist/esm/funcs/inVideoAIfeaturesGenerateChapters.js +2 -2
  179. package/dist/esm/funcs/inputVideoCreate.d.ts +4 -4
  180. package/dist/esm/funcs/inputVideoCreate.js +4 -4
  181. package/dist/esm/funcs/inputVideoUpload.d.ts +5 -5
  182. package/dist/esm/funcs/inputVideoUpload.js +5 -5
  183. package/dist/esm/funcs/liveStreamsCreate.d.ts +3 -3
  184. package/dist/esm/funcs/liveStreamsCreate.js +3 -3
  185. package/dist/esm/funcs/liveStreamsDelete.d.ts +2 -2
  186. package/dist/esm/funcs/liveStreamsDelete.js +2 -2
  187. package/dist/esm/funcs/liveStreamsEnable.d.ts +1 -1
  188. package/dist/esm/funcs/liveStreamsEnable.js +1 -1
  189. package/dist/esm/funcs/liveStreamsListClips.d.ts +1 -1
  190. package/dist/esm/funcs/liveStreamsListClips.js +1 -1
  191. package/dist/esm/funcs/manageLiveStreamComplete.d.ts +1 -1
  192. package/dist/esm/funcs/manageLiveStreamComplete.js +1 -1
  193. package/dist/esm/funcs/manageLiveStreamDisable.d.ts +1 -1
  194. package/dist/esm/funcs/manageLiveStreamDisable.js +1 -1
  195. package/dist/esm/funcs/manageLiveStreamGet.d.ts +1 -1
  196. package/dist/esm/funcs/manageLiveStreamGet.js +1 -1
  197. package/dist/esm/funcs/manageLiveStreamGetViewerCount.d.ts +1 -1
  198. package/dist/esm/funcs/manageLiveStreamGetViewerCount.js +1 -1
  199. package/dist/esm/funcs/manageLiveStreamUpdate.d.ts +2 -2
  200. package/dist/esm/funcs/manageLiveStreamUpdate.js +2 -2
  201. package/dist/esm/funcs/manageVideosAddTrack.d.ts +5 -5
  202. package/dist/esm/funcs/manageVideosAddTrack.js +5 -5
  203. package/dist/esm/funcs/manageVideosCancelUpload.d.ts +1 -1
  204. package/dist/esm/funcs/manageVideosCancelUpload.js +1 -1
  205. package/dist/esm/funcs/manageVideosDelete.d.ts +1 -1
  206. package/dist/esm/funcs/manageVideosDelete.js +1 -1
  207. package/dist/esm/funcs/manageVideosGenerateSubtitleTrack.d.ts +3 -3
  208. package/dist/esm/funcs/manageVideosGenerateSubtitleTrack.js +3 -3
  209. package/dist/esm/funcs/manageVideosGet.d.ts +1 -1
  210. package/dist/esm/funcs/manageVideosGet.js +1 -1
  211. package/dist/esm/funcs/manageVideosUpdate.d.ts +1 -1
  212. package/dist/esm/funcs/manageVideosUpdate.js +1 -1
  213. package/dist/esm/funcs/manageVideosUpdateMp4Support.d.ts +3 -3
  214. package/dist/esm/funcs/manageVideosUpdateMp4Support.js +3 -3
  215. package/dist/esm/funcs/manageVideosUpdateTrack.d.ts +4 -4
  216. package/dist/esm/funcs/manageVideosUpdateTrack.js +4 -4
  217. package/dist/esm/funcs/mediaDeleteTrack.d.ts +2 -2
  218. package/dist/esm/funcs/mediaDeleteTrack.js +2 -2
  219. package/dist/esm/funcs/mediaGetClips.d.ts +1 -1
  220. package/dist/esm/funcs/mediaGetClips.js +1 -1
  221. package/dist/esm/funcs/mediaUpdateSourceAccess.d.ts +1 -1
  222. package/dist/esm/funcs/mediaUpdateSourceAccess.js +1 -1
  223. package/dist/esm/funcs/metricsListBreakdownValues.d.ts +2 -2
  224. package/dist/esm/funcs/metricsListBreakdownValues.js +2 -2
  225. package/dist/esm/funcs/metricsListCompares.d.ts +2 -2
  226. package/dist/esm/funcs/metricsListCompares.js +2 -2
  227. package/dist/esm/funcs/metricsListOverallValues.d.ts +2 -2
  228. package/dist/esm/funcs/metricsListOverallValues.js +2 -2
  229. package/dist/esm/funcs/playbackCreate.d.ts +1 -1
  230. package/dist/esm/funcs/playbackCreate.js +1 -1
  231. package/dist/esm/funcs/playlistCreate.d.ts +1 -1
  232. package/dist/esm/funcs/playlistCreate.js +1 -1
  233. package/dist/esm/funcs/signingKeysCreate.d.ts +1 -1
  234. package/dist/esm/funcs/signingKeysCreate.js +1 -1
  235. package/dist/esm/funcs/signingKeysGetById.d.ts +2 -2
  236. package/dist/esm/funcs/signingKeysGetById.js +2 -2
  237. package/dist/esm/funcs/simulcastStreamsDelete.d.ts +1 -1
  238. package/dist/esm/funcs/simulcastStreamsDelete.js +1 -1
  239. package/dist/esm/funcs/simulcastsCreate.d.ts +2 -2
  240. package/dist/esm/funcs/simulcastsCreate.js +2 -2
  241. package/dist/esm/funcs/simulcastsUpdate.d.ts +1 -1
  242. package/dist/esm/funcs/simulcastsUpdate.js +1 -1
  243. package/dist/esm/funcs/viewsGetDetails.d.ts +1 -1
  244. package/dist/esm/funcs/viewsGetDetails.js +1 -1
  245. package/dist/esm/funcs/viewsList.d.ts +3 -3
  246. package/dist/esm/funcs/viewsList.js +3 -3
  247. package/dist/esm/funcs/viewsListTopContent.d.ts +1 -1
  248. package/dist/esm/funcs/viewsListTopContent.js +1 -1
  249. package/dist/esm/hooks/eventsFieldRemapHook.d.ts +5 -0
  250. package/dist/esm/hooks/eventsFieldRemapHook.d.ts.map +1 -0
  251. package/dist/esm/hooks/eventsFieldRemapHook.js +80 -0
  252. package/dist/esm/hooks/eventsFieldRemapHook.js.map +1 -0
  253. package/dist/esm/hooks/registration.d.ts.map +1 -1
  254. package/dist/esm/hooks/registration.js +2 -4
  255. package/dist/esm/hooks/registration.js.map +1 -1
  256. package/dist/esm/lib/config.d.ts +3 -3
  257. package/dist/esm/lib/config.d.ts.map +1 -1
  258. package/dist/esm/lib/config.js +3 -3
  259. package/dist/esm/lib/config.js.map +1 -1
  260. package/dist/esm/models/addtrackrequest.js +1 -1
  261. package/dist/esm/models/addtrackrequest.js.map +1 -1
  262. package/dist/esm/models/createmediarequest.d.ts +1 -1
  263. package/dist/esm/models/deletesigningkeyresponse.d.ts +10 -0
  264. package/dist/esm/models/deletesigningkeyresponse.d.ts.map +1 -1
  265. package/dist/esm/models/deletesigningkeyresponse.js +1 -0
  266. package/dist/esm/models/deletesigningkeyresponse.js.map +1 -1
  267. package/dist/esm/models/operations/directuploadvideomedia.d.ts +2 -2
  268. package/dist/esm/models/pullvideoinput.js +1 -1
  269. package/dist/esm/models/pullvideoinput.js.map +1 -1
  270. package/dist/esm/models/videotrackforgetall.d.ts +4 -0
  271. package/dist/esm/models/videotrackforgetall.d.ts.map +1 -1
  272. package/dist/esm/models/videotrackforgetall.js +1 -0
  273. package/dist/esm/models/videotrackforgetall.js.map +1 -1
  274. package/dist/esm/models/views.d.ts +3 -3
  275. package/dist/esm/models/views.d.ts.map +1 -1
  276. package/dist/esm/models/views.js +4 -9
  277. package/dist/esm/models/views.js.map +1 -1
  278. package/dist/esm/models/viewslist.d.ts +7 -1
  279. package/dist/esm/models/viewslist.d.ts.map +1 -1
  280. package/dist/esm/models/viewslist.js +3 -7
  281. package/dist/esm/models/viewslist.js.map +1 -1
  282. package/dist/esm/models/watermarkinput.d.ts +1 -1
  283. package/dist/esm/sdk/aifeatures.d.ts +4 -4
  284. package/dist/esm/sdk/aifeatures.js +4 -4
  285. package/dist/esm/sdk/dimensions.d.ts +4 -4
  286. package/dist/esm/sdk/dimensions.js +4 -4
  287. package/dist/esm/sdk/drmconfigurations.d.ts +2 -2
  288. package/dist/esm/sdk/drmconfigurations.js +2 -2
  289. package/dist/esm/sdk/errors.d.ts +1 -1
  290. package/dist/esm/sdk/errors.js +1 -1
  291. package/dist/esm/sdk/inputvideo.d.ts +9 -9
  292. package/dist/esm/sdk/inputvideo.js +9 -9
  293. package/dist/esm/sdk/invideoai.d.ts +2 -2
  294. package/dist/esm/sdk/invideoai.js +2 -2
  295. package/dist/esm/sdk/invideoaifeatures.d.ts +2 -2
  296. package/dist/esm/sdk/invideoaifeatures.js +2 -2
  297. package/dist/esm/sdk/livestreams.d.ts +7 -7
  298. package/dist/esm/sdk/livestreams.js +7 -7
  299. package/dist/esm/sdk/managelivestream.d.ts +6 -6
  300. package/dist/esm/sdk/managelivestream.js +6 -6
  301. package/dist/esm/sdk/managevideos.d.ts +19 -19
  302. package/dist/esm/sdk/managevideos.js +19 -19
  303. package/dist/esm/sdk/media.d.ts +4 -4
  304. package/dist/esm/sdk/media.js +4 -4
  305. package/dist/esm/sdk/metrics.d.ts +6 -6
  306. package/dist/esm/sdk/metrics.js +6 -6
  307. package/dist/esm/sdk/playback.d.ts +1 -1
  308. package/dist/esm/sdk/playback.js +1 -1
  309. package/dist/esm/sdk/playlist.d.ts +1 -1
  310. package/dist/esm/sdk/playlist.js +1 -1
  311. package/dist/esm/sdk/signingkeys.d.ts +3 -3
  312. package/dist/esm/sdk/signingkeys.js +3 -3
  313. package/dist/esm/sdk/simulcasts.d.ts +3 -3
  314. package/dist/esm/sdk/simulcasts.js +3 -3
  315. package/dist/esm/sdk/simulcaststreams.d.ts +1 -1
  316. package/dist/esm/sdk/simulcaststreams.js +1 -1
  317. package/dist/esm/sdk/views.d.ts +5 -5
  318. package/dist/esm/sdk/views.js +5 -5
  319. package/examples/inputVideoCreate.example.ts +1 -1
  320. package/examples/package-lock.json +1 -1
  321. package/jsr.json +1 -1
  322. package/package.json +10 -4
  323. package/src/funcs/aiFeaturesGenerateNamedEntities.ts +2 -2
  324. package/src/funcs/aiFeaturesUpdateSummary.ts +2 -2
  325. package/src/funcs/dimensionsList.ts +2 -2
  326. package/src/funcs/dimensionsListFilterValues.ts +2 -2
  327. package/src/funcs/drmConfigurationsGet.ts +1 -1
  328. package/src/funcs/drmConfigurationsList.ts +1 -1
  329. package/src/funcs/errorsList.ts +1 -1
  330. package/src/funcs/inVideoAIUpdateModeration.ts +2 -2
  331. package/src/funcs/inVideoAIfeaturesGenerateChapters.ts +2 -2
  332. package/src/funcs/inputVideoCreate.ts +4 -4
  333. package/src/funcs/inputVideoUpload.ts +5 -5
  334. package/src/funcs/liveStreamsCreate.ts +3 -3
  335. package/src/funcs/liveStreamsDelete.ts +2 -2
  336. package/src/funcs/liveStreamsEnable.ts +1 -1
  337. package/src/funcs/liveStreamsListClips.ts +1 -1
  338. package/src/funcs/manageLiveStreamComplete.ts +1 -1
  339. package/src/funcs/manageLiveStreamDisable.ts +1 -1
  340. package/src/funcs/manageLiveStreamGet.ts +1 -1
  341. package/src/funcs/manageLiveStreamGetViewerCount.ts +1 -1
  342. package/src/funcs/manageLiveStreamUpdate.ts +2 -2
  343. package/src/funcs/manageVideosAddTrack.ts +5 -5
  344. package/src/funcs/manageVideosCancelUpload.ts +1 -1
  345. package/src/funcs/manageVideosDelete.ts +1 -1
  346. package/src/funcs/manageVideosGenerateSubtitleTrack.ts +3 -3
  347. package/src/funcs/manageVideosGet.ts +1 -1
  348. package/src/funcs/manageVideosUpdate.ts +1 -1
  349. package/src/funcs/manageVideosUpdateMp4Support.ts +3 -3
  350. package/src/funcs/manageVideosUpdateTrack.ts +4 -4
  351. package/src/funcs/mediaDeleteTrack.ts +2 -2
  352. package/src/funcs/mediaGetClips.ts +1 -1
  353. package/src/funcs/mediaUpdateSourceAccess.ts +1 -1
  354. package/src/funcs/metricsListBreakdownValues.ts +2 -2
  355. package/src/funcs/metricsListCompares.ts +2 -2
  356. package/src/funcs/metricsListOverallValues.ts +2 -2
  357. package/src/funcs/playbackCreate.ts +1 -1
  358. package/src/funcs/playlistCreate.ts +1 -1
  359. package/src/funcs/signingKeysCreate.ts +1 -1
  360. package/src/funcs/signingKeysGetById.ts +2 -2
  361. package/src/funcs/simulcastStreamsDelete.ts +1 -1
  362. package/src/funcs/simulcastsCreate.ts +2 -2
  363. package/src/funcs/simulcastsUpdate.ts +1 -1
  364. package/src/funcs/viewsGetDetails.ts +1 -1
  365. package/src/funcs/viewsList.ts +3 -3
  366. package/src/funcs/viewsListTopContent.ts +1 -1
  367. package/src/hooks/eventsFieldRemapHook.ts +94 -0
  368. package/src/hooks/registration.ts +2 -4
  369. package/src/lib/config.ts +3 -3
  370. package/src/models/addtrackrequest.ts +1 -1
  371. package/src/models/createmediarequest.ts +1 -1
  372. package/src/models/deletesigningkeyresponse.ts +14 -0
  373. package/src/models/operations/directuploadvideomedia.ts +2 -2
  374. package/src/models/pullvideoinput.ts +1 -1
  375. package/src/models/videotrackforgetall.ts +5 -0
  376. package/src/models/views.ts +7 -19
  377. package/src/models/viewslist.ts +21 -22
  378. package/src/models/watermarkinput.ts +1 -1
  379. package/src/sdk/aifeatures.ts +4 -4
  380. package/src/sdk/dimensions.ts +4 -4
  381. package/src/sdk/drmconfigurations.ts +2 -2
  382. package/src/sdk/errors.ts +1 -1
  383. package/src/sdk/inputvideo.ts +9 -9
  384. package/src/sdk/invideoai.ts +2 -2
  385. package/src/sdk/invideoaifeatures.ts +2 -2
  386. package/src/sdk/livestreams.ts +7 -7
  387. package/src/sdk/managelivestream.ts +6 -6
  388. package/src/sdk/managevideos.ts +19 -19
  389. package/src/sdk/media.ts +4 -4
  390. package/src/sdk/metrics.ts +6 -6
  391. package/src/sdk/playback.ts +1 -1
  392. package/src/sdk/playlist.ts +1 -1
  393. package/src/sdk/signingkeys.ts +3 -3
  394. package/src/sdk/simulcasts.ts +3 -3
  395. package/src/sdk/simulcaststreams.ts +1 -1
  396. package/src/sdk/views.ts +5 -5
  397. package/tests/artifacts/get-all-playlists.api.json +26 -0
  398. package/tests/artifacts/get-all-playlists.sdk.json +26 -0
  399. package/tests/artifacts/get-all-streams.api.json +76 -0
  400. package/tests/artifacts/get-all-streams.sdk.json +76 -0
  401. package/tests/artifacts/get-live-stream-by-id.api.json +43 -0
  402. package/tests/artifacts/get-live-stream-by-id.sdk.json +43 -0
  403. package/tests/artifacts/get-live-stream-playback-id.api.json +7 -0
  404. package/tests/artifacts/get-live-stream-playback-id.sdk.json +7 -0
  405. package/tests/artifacts/get-live-stream-viewer-count-by-id.api.json +6 -0
  406. package/tests/artifacts/get-live-stream-viewer-count-by-id.sdk.json +6 -0
  407. package/tests/artifacts/get-media-clips.api.json +9 -0
  408. package/tests/artifacts/get-media-clips.sdk.json +9 -0
  409. package/tests/artifacts/get-media-summary.api.json +8 -0
  410. package/tests/artifacts/get-media-summary.sdk.json +26 -0
  411. package/tests/artifacts/get-media.api.json +57 -0
  412. package/tests/artifacts/get-media.sdk.json +57 -0
  413. package/tests/artifacts/get-playback-id.api.json +19 -0
  414. package/tests/artifacts/get-playback-id.sdk.json +19 -0
  415. package/tests/artifacts/get-playlist-by-id.api.json +15 -0
  416. package/tests/artifacts/get-playlist-by-id.sdk.json +15 -0
  417. package/tests/artifacts/get-signing_key_by_id.api.json +8 -0
  418. package/tests/artifacts/get-signing_key_by_id.sdk.json +8 -0
  419. package/tests/artifacts/get-specific-simulcast-of-stream.api.json +12 -0
  420. package/tests/artifacts/get-specific-simulcast-of-stream.sdk.json +12 -0
  421. package/tests/artifacts/getDrmConfiguration.api.json +8 -0
  422. package/tests/artifacts/getDrmConfiguration.sdk.json +26 -0
  423. package/tests/artifacts/getDrmConfigurationById.api.json +13 -0
  424. package/tests/artifacts/getDrmConfigurationById.sdk.json +31 -0
  425. package/tests/artifacts/get_timeseries_data.api.json +18 -0
  426. package/tests/artifacts/get_timeseries_data.sdk.json +18 -0
  427. package/tests/artifacts/get_video_view_details.api.json +213 -0
  428. package/tests/artifacts/get_video_view_details.sdk.json +213 -0
  429. package/tests/artifacts/list-live-clips.api.json +9 -0
  430. package/tests/artifacts/list-live-clips.sdk.json +9 -0
  431. package/tests/artifacts/list-media.api.json +65 -0
  432. package/tests/artifacts/list-media.sdk.json +65 -0
  433. package/tests/artifacts/list-playback-ids.api.json +21 -0
  434. package/tests/artifacts/list-playback-ids.sdk.json +21 -0
  435. package/tests/artifacts/list-uploads.api.json +43 -0
  436. package/tests/artifacts/list-uploads.sdk.json +43 -0
  437. package/tests/artifacts/list_breakdown_values.api.json +24 -0
  438. package/tests/artifacts/list_breakdown_values.sdk.json +24 -0
  439. package/tests/artifacts/list_by_top_content.api.json +19 -0
  440. package/tests/artifacts/list_by_top_content.sdk.json +19 -0
  441. package/tests/artifacts/list_comparison_values.api.json +350 -0
  442. package/tests/artifacts/list_comparison_values.sdk.json +350 -0
  443. package/tests/artifacts/list_dimensions.api.json +61 -0
  444. package/tests/artifacts/list_dimensions.sdk.json +61 -0
  445. package/tests/artifacts/list_errors.api.json +51 -0
  446. package/tests/artifacts/list_errors.sdk.json +51 -0
  447. package/tests/artifacts/list_filter_values_for_dimension.api.json +14 -0
  448. package/tests/artifacts/list_filter_values_for_dimension.sdk.json +14 -0
  449. package/tests/artifacts/list_overall_values.api.json +18 -0
  450. package/tests/artifacts/list_overall_values.sdk.json +18 -0
  451. package/tests/artifacts/list_signing_keys.api.json +22 -0
  452. package/tests/artifacts/list_signing_keys.sdk.json +22 -0
  453. package/tests/artifacts/list_video_views.api.json +84 -0
  454. package/tests/artifacts/list_video_views.sdk.json +84 -0
  455. package/tests/artifacts/retrieveMediaInputInfo.api.json +28 -0
  456. package/tests/artifacts/retrieveMediaInputInfo.sdk.json +28 -0
  457. package/tests/artifacts-non-get/Add-media-track.raw.json +10 -0
  458. package/tests/artifacts-non-get/Add-media-track.sdk.json +10 -0
  459. package/tests/artifacts-non-get/Generate-subtitle-track.raw.json +9 -0
  460. package/tests/artifacts-non-get/Generate-subtitle-track.sdk.json +9 -0
  461. package/tests/artifacts-non-get/add-media-to-playlist.raw.json +24 -0
  462. package/tests/artifacts-non-get/add-media-to-playlist.sdk.json +24 -0
  463. package/tests/artifacts-non-get/cancel-upload.raw.json +15 -0
  464. package/tests/artifacts-non-get/cancel-upload.sdk.json +15 -0
  465. package/tests/artifacts-non-get/change-media-order-in-playlist.raw.json +24 -0
  466. package/tests/artifacts-non-get/change-media-order-in-playlist.sdk.json +24 -0
  467. package/tests/artifacts-non-get/complete-live-stream.raw.json +8 -0
  468. package/tests/artifacts-non-get/complete-live-stream.sdk.json +13 -0
  469. package/tests/artifacts-non-get/create-a-playlist.raw.json +15 -0
  470. package/tests/artifacts-non-get/create-a-playlist.sdk.json +15 -0
  471. package/tests/artifacts-non-get/create-media-playback-id.raw.json +20 -0
  472. package/tests/artifacts-non-get/create-media-playback-id.sdk.json +19 -0
  473. package/tests/artifacts-non-get/create-media.raw.json +41 -0
  474. package/tests/artifacts-non-get/create-media.sdk.json +41 -0
  475. package/tests/artifacts-non-get/create-new-stream.raw.json +32 -0
  476. package/tests/artifacts-non-get/create-new-stream.sdk.json +32 -0
  477. package/tests/artifacts-non-get/create-playbackId-of-stream.raw.json +7 -0
  478. package/tests/artifacts-non-get/create-playbackId-of-stream.sdk.json +7 -0
  479. package/tests/artifacts-non-get/create-simulcast-of-stream.raw.json +9 -0
  480. package/tests/artifacts-non-get/create-simulcast-of-stream.sdk.json +9 -0
  481. package/tests/artifacts-non-get/create_signing_key.raw.json +8 -0
  482. package/tests/artifacts-non-get/create_signing_key.sdk.json +8 -0
  483. package/tests/artifacts-non-get/delete-a-playlist.raw.json +3 -0
  484. package/tests/artifacts-non-get/delete-a-playlist.sdk.json +3 -0
  485. package/tests/artifacts-non-get/delete-live-stream.raw.json +3 -0
  486. package/tests/artifacts-non-get/delete-live-stream.sdk.json +3 -0
  487. package/tests/artifacts-non-get/delete-media-from-playlist.raw.json +15 -0
  488. package/tests/artifacts-non-get/delete-media-from-playlist.sdk.json +15 -0
  489. package/tests/artifacts-non-get/delete-media-playback-id.raw.json +3 -0
  490. package/tests/artifacts-non-get/delete-media-playback-id.sdk.json +3 -0
  491. package/tests/artifacts-non-get/delete-media-track.raw.json +3 -0
  492. package/tests/artifacts-non-get/delete-media-track.sdk.json +3 -0
  493. package/tests/artifacts-non-get/delete-media.raw.json +3 -0
  494. package/tests/artifacts-non-get/delete-media.sdk.json +3 -0
  495. package/tests/artifacts-non-get/delete-playbackId-of-stream.raw.json +3 -0
  496. package/tests/artifacts-non-get/delete-playbackId-of-stream.sdk.json +3 -0
  497. package/tests/artifacts-non-get/delete-simulcast-of-stream.raw.json +3 -0
  498. package/tests/artifacts-non-get/delete-simulcast-of-stream.sdk.json +3 -0
  499. package/tests/artifacts-non-get/delete_signing_key.raw.json +6 -0
  500. package/tests/artifacts-non-get/delete_signing_key.sdk.json +6 -0
  501. package/tests/artifacts-non-get/direct-upload-video-media.raw.json +36 -0
  502. package/tests/artifacts-non-get/direct-upload-video-media.sdk.json +36 -0
  503. package/tests/artifacts-non-get/disable-live-stream.raw.json +3 -0
  504. package/tests/artifacts-non-get/disable-live-stream.sdk.json +3 -0
  505. package/tests/artifacts-non-get/enable-live-stream.raw.json +3 -0
  506. package/tests/artifacts-non-get/enable-live-stream.sdk.json +3 -0
  507. package/tests/artifacts-non-get/update-a-playlist.raw.json +15 -0
  508. package/tests/artifacts-non-get/update-a-playlist.sdk.json +15 -0
  509. package/tests/artifacts-non-get/update-domain-restrictions.raw.json +10 -0
  510. package/tests/artifacts-non-get/update-domain-restrictions.sdk.json +10 -0
  511. package/tests/artifacts-non-get/update-live-stream.raw.json +36 -0
  512. package/tests/artifacts-non-get/update-live-stream.sdk.json +36 -0
  513. package/tests/artifacts-non-get/update-media-chapters.raw.json +7 -0
  514. package/tests/artifacts-non-get/update-media-chapters.sdk.json +7 -0
  515. package/tests/artifacts-non-get/update-media-moderation.raw.json +7 -0
  516. package/tests/artifacts-non-get/update-media-moderation.sdk.json +7 -0
  517. package/tests/artifacts-non-get/update-media-named-entities.raw.json +7 -0
  518. package/tests/artifacts-non-get/update-media-named-entities.sdk.json +7 -0
  519. package/tests/artifacts-non-get/update-media-summary.raw.json +7 -0
  520. package/tests/artifacts-non-get/update-media-summary.sdk.json +7 -0
  521. package/tests/artifacts-non-get/update-media-track.raw.json +10 -0
  522. package/tests/artifacts-non-get/update-media-track.sdk.json +10 -0
  523. package/tests/artifacts-non-get/update-specific-simulcast-of-stream.raw.json +9 -0
  524. package/tests/artifacts-non-get/update-specific-simulcast-of-stream.sdk.json +9 -0
  525. package/tests/artifacts-non-get/update-user-agent-restrictions.raw.json +10 -0
  526. package/tests/artifacts-non-get/update-user-agent-restrictions.sdk.json +10 -0
  527. package/tests/artifacts-non-get/updated-media.raw.json +94 -0
  528. package/tests/artifacts-non-get/updated-media.sdk.json +94 -0
  529. package/tests/artifacts-non-get/updated-mp4Support.raw.json +95 -0
  530. package/tests/artifacts-non-get/updated-mp4Support.sdk.json +95 -0
  531. package/tests/artifacts-non-get/updated-source-access.raw.json +94 -0
  532. package/tests/artifacts-non-get/updated-source-access.sdk.json +94 -0
  533. package/tests/build-url-mapping-pass2.mjs +77 -0
  534. package/tests/build-url-mapping.mjs +101 -0
  535. package/tests/check-broken-links.mjs +89 -0
  536. package/tests/diff-api-vs-sdk.mjs +94 -0
  537. package/tests/diff-passed.mjs +99 -0
  538. package/tests/diff-strict.mjs +81 -0
  539. package/tests/non-get-endpoints-fixtures.json +328 -0
  540. package/tests/validate-get-endpoints.ts +16 -5
  541. package/tests/validate-non-get-endpoints.ts +477 -0
  542. package/tests/validate-non-get-lifecycle.ts +1093 -0
@@ -0,0 +1,1093 @@
1
+ #!/usr/bin/env tsx
2
+ /*
3
+ * Non-GET endpoints validator (POST / PUT / PATCH / DELETE) — Node.js SDK port.
4
+ *
5
+ * Ported from the PHP-driven version. Calls the Node SDK directly and captures
6
+ * raw response bodies via an HTTPClient "response" hook, so we can run both:
7
+ * - OpenAPI response-schema validation against the raw wire body
8
+ * - SDK-output ↔ raw API diff
9
+ * ...without making the request twice (critical for mutating endpoints).
10
+ *
11
+ * Lifecycle: CREATE → UPDATE → DELETE. Steps whose required IDs were never
12
+ * captured (upstream create failed) are SKIPped, not invoked with nulls.
13
+ *
14
+ * Output:
15
+ * tests/artifacts-non-get/<op>.raw.json raw API wire response
16
+ * tests/artifacts-non-get/<op>.sdk.json SDK parsed/returned value
17
+ * tests/NON_GET_ENDPOINTS_VALIDATION_REPORT.md
18
+ *
19
+ * Requirements:
20
+ * FASTPIX_USERNAME / FASTPIX_PASSWORD env vars (Basic Auth)
21
+ * FASTPIX_BASE_URL / FASTPIX_SERVER_URL (optional override)
22
+ */
23
+
24
+ /// <reference types="node" />
25
+
26
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
27
+ import { join, dirname } from "node:path";
28
+ import { fileURLToPath } from "node:url";
29
+ import { createRequire } from "node:module";
30
+ import yaml from "js-yaml";
31
+ import { Fastpix } from "../src/sdk/sdk.js";
32
+ import { HTTPClient } from "../src/lib/http.js";
33
+
34
+ const require = createRequire(import.meta.url);
35
+ const openapiResponseValidatorMod = require("openapi-response-validator");
36
+ const OpenAPIResponseValidator =
37
+ openapiResponseValidatorMod?.default ?? openapiResponseValidatorMod;
38
+
39
+ const __filename = fileURLToPath(import.meta.url);
40
+ const __dirname = dirname(__filename);
41
+
42
+ const ARTIFACTS_DIRNAME = "artifacts-non-get";
43
+ const REPORT_MD = "NON_GET_ENDPOINTS_VALIDATION_REPORT.md";
44
+ const MAX_PREVIEW_CHARS = 4000;
45
+
46
+ type Phase = "CREATE" | "UPDATE" | "DELETE";
47
+
48
+ type EndpointInfo = {
49
+ path: string;
50
+ method: string;
51
+ operationId: string;
52
+ responses: Record<string, any>;
53
+ };
54
+
55
+ type Ctx = {
56
+ signingKeyId?: string;
57
+ playlistId?: string;
58
+ streamId?: string;
59
+ mediaId?: string;
60
+ mediaPlaybackId?: string;
61
+ createdPlaybackId?: string;
62
+ trackId?: string;
63
+ streamPlaybackId?: string;
64
+ simulcastId?: string;
65
+ uploadId?: string;
66
+ };
67
+
68
+ type SDKInvoker = (client: Fastpix, ctx: Ctx) => Promise<any>;
69
+
70
+ type Step = {
71
+ operationId: string;
72
+ phase: Phase;
73
+ needs?: (keyof Ctx)[];
74
+ invoke: SDKInvoker;
75
+ capture?: (value: any, ctx: Ctx) => void;
76
+ retryOn?: string;
77
+ };
78
+
79
+ type StepResult = {
80
+ operationId: string;
81
+ method: string;
82
+ path: string;
83
+ phase: Phase;
84
+ status: "PASS" | "FAIL" | "SKIP";
85
+ httpStatus: number | null;
86
+ openapiValid: boolean | null;
87
+ openapiErrors: any[];
88
+ sdkOk: boolean;
89
+ sdkError?: string;
90
+ missingInSDK: string[];
91
+ missingInAPI: string[];
92
+ note?: string;
93
+ capturedId?: string;
94
+ };
95
+
96
+ const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
97
+
98
+ function safeFileSlug(input: string): string {
99
+ return input.replace(/[^a-zA-Z0-9_.-]+/g, "_");
100
+ }
101
+ function toPrettyJson(v: unknown): string {
102
+ return JSON.stringify(v, null, 2);
103
+ }
104
+ function preview(text: string): string {
105
+ return text.length > MAX_PREVIEW_CHARS
106
+ ? `${text.slice(0, MAX_PREVIEW_CHARS)}\n... [truncated]`
107
+ : text;
108
+ }
109
+ function basicAuthHeader(u: string, p: string): string {
110
+ return "Basic " + Buffer.from(`${u}:${p}`).toString("base64");
111
+ }
112
+
113
+ // ---------------------------------------------------------------------------
114
+ // Raw response capture via HTTPClient hook
115
+ // ---------------------------------------------------------------------------
116
+ //
117
+ // The SDK reads the response body for parsing, which would close the stream
118
+ // before we could read it ourselves. We clone the Response inside the hook
119
+ // (.clone() must run before the body is consumed) and stash the cloned body
120
+ // on a per-call basis. The Step.invoke wrapper reads it after the SDK call.
121
+
122
+ let lastRawCapture: {
123
+ url: string;
124
+ status: number;
125
+ bodyText: string;
126
+ bodyJson: any;
127
+ } | null = null;
128
+
129
+ const sharedHttpClient = new HTTPClient();
130
+ sharedHttpClient.addHook("response", async (res, req) => {
131
+ // Skip non-API hosts (in case the SDK fans out to GCS etc.).
132
+ if (!/api\.fastpix\.(com|io)/i.test(req.url)) return;
133
+ try {
134
+ const cloned = res.clone();
135
+ const bodyText = await cloned.text();
136
+ let bodyJson: any = null;
137
+ try {
138
+ bodyJson = bodyText ? JSON.parse(bodyText) : null;
139
+ } catch {
140
+ bodyJson = null;
141
+ }
142
+ lastRawCapture = { url: req.url, status: res.status, bodyText, bodyJson };
143
+ } catch {
144
+ // ignore — capture failed; the diff will treat raw as null
145
+ }
146
+ });
147
+
148
+ async function invokeSDK(
149
+ client: Fastpix,
150
+ step: Step,
151
+ ctx: Ctx,
152
+ ):
153
+ | Promise<{ ok: true; value: any; statusCode: number | null; rawBody: any }>
154
+ | Promise<{
155
+ ok: false;
156
+ error: { name?: string; message?: string; statusCode?: number; bodyJson?: any };
157
+ }> {
158
+ lastRawCapture = null;
159
+ try {
160
+ const value = await step.invoke(client, ctx);
161
+ const cap = lastRawCapture;
162
+ return {
163
+ ok: true,
164
+ value,
165
+ statusCode: cap?.status ?? null,
166
+ rawBody: cap?.bodyJson ?? null,
167
+ };
168
+ } catch (e: any) {
169
+ return {
170
+ ok: false,
171
+ error: {
172
+ name: e?.name ?? "Error",
173
+ message: e?.message ?? String(e),
174
+ statusCode: e?.statusCode ?? lastRawCapture?.status ?? undefined,
175
+ bodyJson:
176
+ e?.body && typeof e.body === "string"
177
+ ? safeJsonParse(e.body)
178
+ : lastRawCapture?.bodyJson ?? null,
179
+ },
180
+ };
181
+ }
182
+ }
183
+
184
+ function safeJsonParse(s: string): any {
185
+ try {
186
+ return JSON.parse(s);
187
+ } catch {
188
+ return null;
189
+ }
190
+ }
191
+
192
+ // ---------------------------------------------------------------------------
193
+ // Spec + OpenAPI validation
194
+ // ---------------------------------------------------------------------------
195
+
196
+ function resolveSpecPath(): string {
197
+ const candidates = [
198
+ join(__dirname, "../fixed.yaml"),
199
+ join(__dirname, "../fastpix.yaml"),
200
+ join(__dirname, "../../fixed.yaml"),
201
+ ];
202
+ for (const p of candidates) if (existsSync(p)) return p;
203
+ throw new Error(`OpenAPI spec not found. Tried: ${candidates.join(", ")}`);
204
+ }
205
+
206
+ function loadOpenAPISpec(): any {
207
+ return yaml.load(readFileSync(resolveSpecPath(), "utf-8"));
208
+ }
209
+
210
+ function extractNonGetEndpoints(spec: any): Map<string, EndpointInfo> {
211
+ const out = new Map<string, EndpointInfo>();
212
+ for (const [path, methods] of Object.entries(spec.paths || {})) {
213
+ const m = methods as any;
214
+ for (const method of ["post", "put", "patch", "delete"]) {
215
+ if (!m[method]) continue;
216
+ out.set(m[method].operationId, {
217
+ path,
218
+ method: method.toUpperCase(),
219
+ operationId: m[method].operationId,
220
+ responses: m[method].responses || {},
221
+ });
222
+ }
223
+ }
224
+ return out;
225
+ }
226
+
227
+ function convertRefsToDefinitions(node: any): any {
228
+ if (node == null || typeof node !== "object") return node;
229
+ if (Array.isArray(node)) return node.map(convertRefsToDefinitions);
230
+ const out: any = {};
231
+ for (const [k, v] of Object.entries(node)) {
232
+ if (k === "$ref" && typeof v === "string")
233
+ out[k] = v.replace("#/components/schemas/", "#/definitions/");
234
+ else out[k] = convertRefsToDefinitions(v);
235
+ }
236
+ return out;
237
+ }
238
+
239
+ function makeOpenAPIResponseValidator(spec: any, ep: EndpointInfo) {
240
+ const definitions = convertRefsToDefinitions(spec.components?.schemas || {});
241
+ const responses: any = {};
242
+ for (const [status, def] of Object.entries(ep.responses || {})) {
243
+ const d = def as any;
244
+ const schema = d?.content?.["application/json"]?.schema;
245
+ if (!schema) continue;
246
+ responses[status] = {
247
+ description: d.description || "",
248
+ schema: convertRefsToDefinitions(schema),
249
+ };
250
+ }
251
+ if (Object.keys(responses).length === 0) return null;
252
+ return new OpenAPIResponseValidator({ responses, definitions });
253
+ }
254
+
255
+ // ---------------------------------------------------------------------------
256
+ // JSON diff helpers
257
+ // ---------------------------------------------------------------------------
258
+
259
+ function collectJsonPaths(
260
+ value: any,
261
+ prefix = "",
262
+ opts: { includeEmptyArrays?: boolean } = {},
263
+ ): Set<string> {
264
+ const out = new Set<string>();
265
+ const includeEmptyArrays = opts.includeEmptyArrays ?? true;
266
+ if (value === null || value === undefined) return out;
267
+ if (typeof value !== "object") {
268
+ if (prefix) out.add(prefix);
269
+ return out;
270
+ }
271
+ if (Array.isArray(value)) {
272
+ if (!includeEmptyArrays && value.length === 0) return out;
273
+ const arrayPrefix = prefix ? `${prefix}[]` : "[]";
274
+ out.add(arrayPrefix);
275
+ for (const item of value)
276
+ for (const p of collectJsonPaths(item, arrayPrefix, opts)) out.add(p);
277
+ return out;
278
+ }
279
+ for (const [k, v] of Object.entries(value)) {
280
+ if (!includeEmptyArrays && Array.isArray(v) && v.length === 0) continue;
281
+ if (!includeEmptyArrays && (v === null || v === undefined)) continue;
282
+ const p = prefix ? `${prefix}.${k}` : k;
283
+ out.add(p);
284
+ for (const child of collectJsonPaths(v, p, opts)) out.add(child);
285
+ }
286
+ return out;
287
+ }
288
+
289
+ function canonicalizeKey(key: string): string {
290
+ const camel = key.includes("_")
291
+ ? key.toLowerCase().replace(/_([a-z0-9])/g, (_, c) => String(c).toUpperCase())
292
+ : key;
293
+ return camel.replaceAll("SDK", "Sdk").replaceAll("API", "Api");
294
+ }
295
+
296
+ function normalizeJsonForComparison(value: any): any {
297
+ if (value === null || value === undefined) return value;
298
+ if (Array.isArray(value)) return value.map(normalizeJsonForComparison);
299
+ if (typeof value !== "object") return value;
300
+ const out: any = {};
301
+ for (const [k, v] of Object.entries(value))
302
+ out[canonicalizeKey(k)] = normalizeJsonForComparison(v);
303
+ return out;
304
+ }
305
+
306
+ function sortUnique(arr: string[]) {
307
+ return Array.from(new Set(arr)).sort((a, b) => a.localeCompare(b));
308
+ }
309
+ function jsonRoundTrip(v: any): any {
310
+ return JSON.parse(JSON.stringify(v));
311
+ }
312
+
313
+ // ---------------------------------------------------------------------------
314
+ // Resource-readiness polling
315
+ // ---------------------------------------------------------------------------
316
+
317
+ async function waitForMediaReady(
318
+ baseUrl: string,
319
+ username: string,
320
+ password: string,
321
+ mediaId: string,
322
+ timeoutMs = 180000,
323
+ intervalMs = 5000,
324
+ ): Promise<string> {
325
+ const url = `${baseUrl.replace(/\/$/, "")}/on-demand/${mediaId}`;
326
+ const deadline = Date.now() + timeoutMs;
327
+ let last = "unknown";
328
+ while (Date.now() < deadline) {
329
+ try {
330
+ const res = await fetch(url, {
331
+ headers: {
332
+ Accept: "application/json",
333
+ Authorization: basicAuthHeader(username, password),
334
+ },
335
+ });
336
+ const body: any = await res.json().catch(() => null);
337
+ last = body?.data?.status ?? last;
338
+ if (last === "Ready") return "Ready";
339
+ if (last === "Errored" || last === "Failed") return last;
340
+ } catch {
341
+ /* transient */
342
+ }
343
+ await sleep(intervalMs);
344
+ }
345
+ return last;
346
+ }
347
+
348
+ async function waitForTrackReady(
349
+ baseUrl: string,
350
+ username: string,
351
+ password: string,
352
+ mediaId: string,
353
+ trackId: string,
354
+ timeoutMs = 180000,
355
+ intervalMs = 5000,
356
+ ): Promise<string> {
357
+ const url = `${baseUrl.replace(/\/$/, "")}/on-demand/${mediaId}`;
358
+ const deadline = Date.now() + timeoutMs;
359
+ let last = "absent";
360
+ while (Date.now() < deadline) {
361
+ try {
362
+ const res = await fetch(url, {
363
+ headers: {
364
+ Accept: "application/json",
365
+ Authorization: basicAuthHeader(username, password),
366
+ },
367
+ });
368
+ const body: any = await res.json().catch(() => null);
369
+ const track = (body?.data?.tracks ?? []).find((t: any) => t?.id === trackId);
370
+ if (track) {
371
+ last = track.status ?? "present";
372
+ if (last === "Ready" || last === "present") return last;
373
+ }
374
+ } catch {
375
+ /* transient */
376
+ }
377
+ await sleep(intervalMs);
378
+ }
379
+ return last;
380
+ }
381
+
382
+ // ---------------------------------------------------------------------------
383
+ // Lifecycle (Node SDK invocations)
384
+ // ---------------------------------------------------------------------------
385
+
386
+ const STEPS: Step[] = [
387
+ // ---- CREATE ----
388
+ {
389
+ operationId: "create_signing_key",
390
+ phase: "CREATE",
391
+ invoke: (c) => c.signingKeys.create(),
392
+ capture: (v, c) => { c.signingKeyId = v?.data?.id; },
393
+ },
394
+ {
395
+ operationId: "create-a-playlist",
396
+ phase: "CREATE",
397
+ invoke: (c) =>
398
+ c.playlist.create({
399
+ name: "sdk validate playlist",
400
+ referenceId: "sdkValidate" + Date.now().toString(36),
401
+ type: "manual",
402
+ description: "sdk validate",
403
+ mediaIds: [],
404
+ metadata: {},
405
+ } as any),
406
+ capture: (v, c) => { c.playlistId = v?.data?.id; },
407
+ },
408
+ {
409
+ operationId: "create-new-stream",
410
+ phase: "CREATE",
411
+ invoke: (c) =>
412
+ c.liveStreams.create({
413
+ playbackSettings: { accessPolicy: "public" },
414
+ inputMediaSettings: {
415
+ metadata: { name: "sdk-validate" },
416
+ maxResolution: "1080p",
417
+ reconnectWindow: 60,
418
+ mediaPolicy: "public",
419
+ },
420
+ } as any),
421
+ capture: (v, c) => { c.streamId = v?.data?.streamId ?? v?.data?.id; },
422
+ },
423
+ {
424
+ operationId: "create-media",
425
+ phase: "CREATE",
426
+ invoke: (c) =>
427
+ c.inputVideo.create({
428
+ inputs: [{ type: "video", url: "https://static.fastpix.com/fp-sample-video.mp4" }],
429
+ metadata: { source: "sdk-validate" },
430
+ accessPolicy: "public",
431
+ maxResolution: "720p",
432
+ } as any),
433
+ capture: (v, c) => {
434
+ c.mediaId = v?.data?.id;
435
+ c.mediaPlaybackId = v?.data?.playbackIds?.[0]?.id;
436
+ },
437
+ },
438
+ {
439
+ operationId: "create-media-playback-id",
440
+ phase: "CREATE",
441
+ needs: ["mediaId"],
442
+ invoke: (c, ctx) =>
443
+ c.playback.create({
444
+ mediaId: ctx.mediaId!,
445
+ body: { accessPolicy: "public" },
446
+ } as any),
447
+ capture: (v, c) => { c.createdPlaybackId = v?.data?.id; },
448
+ },
449
+ {
450
+ operationId: "Add-media-track",
451
+ phase: "CREATE",
452
+ needs: ["mediaId"],
453
+ invoke: (c, ctx) =>
454
+ c.manageVideos.addTrack({
455
+ mediaId: ctx.mediaId!,
456
+ body: {
457
+ tracks: {
458
+ url: "https://static.fastpix.com/music-1.mp3",
459
+ type: "audio",
460
+ languageCode: "it",
461
+ languageName: "Italian",
462
+ },
463
+ },
464
+ } as any),
465
+ capture: (v, c) => { c.trackId = v?.data?.id; },
466
+ },
467
+ {
468
+ operationId: "create-playbackId-of-stream",
469
+ phase: "CREATE",
470
+ needs: ["streamId"],
471
+ invoke: (c, ctx) =>
472
+ c.livePlayback.createId({
473
+ streamId: ctx.streamId!,
474
+ body: { accessPolicy: "public" },
475
+ } as any),
476
+ capture: (v, c) => { c.streamPlaybackId = v?.data?.id; },
477
+ },
478
+ {
479
+ operationId: "create-simulcast-of-stream",
480
+ phase: "CREATE",
481
+ needs: ["streamId"],
482
+ invoke: (c, ctx) =>
483
+ c.simulcasts.create({
484
+ streamId: ctx.streamId!,
485
+ body: {
486
+ url: "rtmp://example.com/live",
487
+ streamKey: "sk-" + Date.now().toString(36),
488
+ },
489
+ } as any),
490
+ capture: (v, c) => { c.simulcastId = v?.data?.simulcastId ?? v?.data?.id; },
491
+ },
492
+ {
493
+ operationId: "direct-upload-video-media",
494
+ phase: "CREATE",
495
+ invoke: (c) =>
496
+ c.inputVideo.upload({
497
+ corsOrigin: "*",
498
+ pushMediaSettings: {
499
+ accessPolicy: "public",
500
+ metadata: { source: "sdk-validate" },
501
+ },
502
+ } as any),
503
+ capture: (v, c) => { c.uploadId = v?.data?.uploadId ?? v?.data?.id; },
504
+ },
505
+ {
506
+ operationId: "Generate-subtitle-track",
507
+ phase: "CREATE",
508
+ needs: ["mediaId", "trackId"],
509
+ invoke: (c, ctx) =>
510
+ c.manageVideos.generateSubtitleTrack({
511
+ mediaId: ctx.mediaId!,
512
+ trackId: ctx.trackId!,
513
+ body: {
514
+ languageCode: "en-US",
515
+ languageName: "English",
516
+ },
517
+ } as any),
518
+ },
519
+
520
+ // ---- UPDATE ----
521
+ {
522
+ operationId: "updated-media",
523
+ phase: "UPDATE",
524
+ needs: ["mediaId"],
525
+ invoke: (c, ctx) =>
526
+ c.manageVideos.update({
527
+ mediaId: ctx.mediaId!,
528
+ body: {
529
+ metadata: { updated: "true" },
530
+ title: "sdk validate title",
531
+ },
532
+ } as any),
533
+ },
534
+ {
535
+ operationId: "updated-source-access",
536
+ phase: "UPDATE",
537
+ needs: ["mediaId"],
538
+ invoke: (c, ctx) =>
539
+ c.media.updateSourceAccess({
540
+ mediaId: ctx.mediaId!,
541
+ body: { sourceAccess: true },
542
+ } as any),
543
+ },
544
+ {
545
+ operationId: "updated-mp4Support",
546
+ phase: "UPDATE",
547
+ needs: ["mediaId"],
548
+ invoke: (c, ctx) =>
549
+ c.manageVideos.updateMp4Support({
550
+ mediaId: ctx.mediaId!,
551
+ body: { mp4Support: "capped_4k" },
552
+ } as any),
553
+ },
554
+ {
555
+ operationId: "update-media-summary",
556
+ phase: "UPDATE",
557
+ needs: ["mediaId"],
558
+ invoke: (c, ctx) =>
559
+ c.aiFeatures.updateSummary({
560
+ mediaId: ctx.mediaId!,
561
+ body: { generate: true, summaryLength: 100 },
562
+ } as any),
563
+ },
564
+ {
565
+ operationId: "update-media-chapters",
566
+ phase: "UPDATE",
567
+ needs: ["mediaId"],
568
+ invoke: (c, ctx) =>
569
+ c.inVideoAIfeatures.generateChapters({
570
+ mediaId: ctx.mediaId!,
571
+ body: { chapters: true },
572
+ } as any),
573
+ },
574
+ {
575
+ operationId: "update-media-named-entities",
576
+ phase: "UPDATE",
577
+ needs: ["mediaId"],
578
+ invoke: (c, ctx) =>
579
+ c.aiFeatures.generateNamedEntities({
580
+ mediaId: ctx.mediaId!,
581
+ body: { namedEntities: true },
582
+ } as any),
583
+ },
584
+ {
585
+ operationId: "update-media-moderation",
586
+ phase: "UPDATE",
587
+ needs: ["mediaId"],
588
+ invoke: (c, ctx) =>
589
+ c.inVideoAI.updateModeration({
590
+ mediaId: ctx.mediaId!,
591
+ body: { moderation: { type: "video" } },
592
+ } as any),
593
+ },
594
+ {
595
+ operationId: "update-media-track",
596
+ phase: "UPDATE",
597
+ needs: ["mediaId", "trackId"],
598
+ invoke: (c, ctx) =>
599
+ c.manageVideos.updateTrack({
600
+ mediaId: ctx.mediaId!,
601
+ trackId: ctx.trackId!,
602
+ body: {
603
+ url: "https://static.fastpix.com/music-1.mp3",
604
+ languageCode: "en",
605
+ languageName: "English",
606
+ },
607
+ } as any),
608
+ },
609
+ {
610
+ operationId: "update-domain-restrictions",
611
+ phase: "UPDATE",
612
+ needs: ["mediaId", "mediaPlaybackId"],
613
+ retryOn: "not ready for updates",
614
+ invoke: (c, ctx) =>
615
+ c.playback.updateDomainRestrictions({
616
+ mediaId: ctx.mediaId!,
617
+ playbackId: ctx.mediaPlaybackId!,
618
+ body: {
619
+ defaultPolicy: "allow",
620
+ allow: ["example.com"],
621
+ deny: [],
622
+ },
623
+ } as any),
624
+ },
625
+ {
626
+ operationId: "update-user-agent-restrictions",
627
+ phase: "UPDATE",
628
+ needs: ["mediaId", "mediaPlaybackId"],
629
+ retryOn: "not ready for updates",
630
+ invoke: (c, ctx) =>
631
+ c.playback.updateUserAgentRestrictions({
632
+ mediaId: ctx.mediaId!,
633
+ playbackId: ctx.mediaPlaybackId!,
634
+ body: {
635
+ defaultPolicy: "allow",
636
+ allow: ["Mozilla"],
637
+ deny: [],
638
+ },
639
+ } as any),
640
+ },
641
+ {
642
+ operationId: "update-a-playlist",
643
+ phase: "UPDATE",
644
+ needs: ["playlistId"],
645
+ invoke: (c, ctx) =>
646
+ c.playlist.update({
647
+ playlistId: ctx.playlistId!,
648
+ body: {
649
+ name: "sdk validate updated",
650
+ description: "updated by validator",
651
+ },
652
+ } as any),
653
+ },
654
+ {
655
+ operationId: "add-media-to-playlist",
656
+ phase: "UPDATE",
657
+ needs: ["playlistId", "mediaId"],
658
+ invoke: (c, ctx) =>
659
+ c.playlists.addMedia({
660
+ playlistId: ctx.playlistId!,
661
+ body: { mediaIds: [ctx.mediaId!] },
662
+ } as any),
663
+ },
664
+ {
665
+ operationId: "change-media-order-in-playlist",
666
+ phase: "UPDATE",
667
+ needs: ["playlistId", "mediaId"],
668
+ invoke: (c, ctx) =>
669
+ c.playlist.updateMediaOrder({
670
+ playlistId: ctx.playlistId!,
671
+ body: { mediaIds: [ctx.mediaId!] },
672
+ } as any),
673
+ },
674
+ {
675
+ operationId: "update-live-stream",
676
+ phase: "UPDATE",
677
+ needs: ["streamId"],
678
+ invoke: (c, ctx) =>
679
+ c.manageLiveStream.update({
680
+ streamId: ctx.streamId!,
681
+ body: {
682
+ metadata: { updated: "true" },
683
+ reconnectWindow: 120,
684
+ },
685
+ } as any),
686
+ },
687
+ {
688
+ operationId: "update-specific-simulcast-of-stream",
689
+ phase: "UPDATE",
690
+ needs: ["streamId", "simulcastId"],
691
+ invoke: (c, ctx) =>
692
+ c.simulcasts.update({
693
+ streamId: ctx.streamId!,
694
+ simulcastId: ctx.simulcastId!,
695
+ body: { isEnabled: false },
696
+ } as any),
697
+ },
698
+ {
699
+ operationId: "disable-live-stream",
700
+ phase: "UPDATE",
701
+ needs: ["streamId"],
702
+ invoke: (c, ctx) => c.manageLiveStream.disable({ streamId: ctx.streamId! } as any),
703
+ },
704
+ {
705
+ operationId: "enable-live-stream",
706
+ phase: "UPDATE",
707
+ needs: ["streamId"],
708
+ invoke: (c, ctx) => c.liveStreams.enable({ streamId: ctx.streamId! } as any),
709
+ },
710
+ {
711
+ operationId: "complete-live-stream",
712
+ phase: "UPDATE",
713
+ needs: ["streamId"],
714
+ invoke: (c, ctx) => c.manageLiveStream.complete({ streamId: ctx.streamId! } as any),
715
+ },
716
+ {
717
+ operationId: "cancel-upload",
718
+ phase: "UPDATE",
719
+ needs: ["uploadId"],
720
+ invoke: (c, ctx) => c.manageVideos.cancelUpload({ uploadId: ctx.uploadId! } as any),
721
+ },
722
+
723
+ // ---- DELETE (last) ----
724
+ {
725
+ operationId: "delete-media-from-playlist",
726
+ phase: "DELETE",
727
+ needs: ["playlistId", "mediaId"],
728
+ invoke: (c, ctx) =>
729
+ c.playlists.deleteMedia({
730
+ playlistId: ctx.playlistId!,
731
+ body: { mediaIds: [ctx.mediaId!] },
732
+ } as any),
733
+ },
734
+ {
735
+ operationId: "delete-a-playlist",
736
+ phase: "DELETE",
737
+ needs: ["playlistId"],
738
+ invoke: (c, ctx) => c.playlist.delete({ playlistId: ctx.playlistId! } as any),
739
+ },
740
+ {
741
+ operationId: "delete-media-track",
742
+ phase: "DELETE",
743
+ needs: ["mediaId", "trackId"],
744
+ invoke: (c, ctx) =>
745
+ c.media.deleteTrack({ mediaId: ctx.mediaId!, trackId: ctx.trackId! } as any),
746
+ },
747
+ {
748
+ operationId: "delete-media-playback-id",
749
+ phase: "DELETE",
750
+ needs: ["mediaId", "createdPlaybackId"],
751
+ invoke: (c, ctx) =>
752
+ c.playback.delete({
753
+ mediaId: ctx.mediaId!,
754
+ playbackId: ctx.createdPlaybackId!,
755
+ } as any),
756
+ },
757
+ {
758
+ operationId: "delete-simulcast-of-stream",
759
+ phase: "DELETE",
760
+ needs: ["streamId", "simulcastId"],
761
+ invoke: (c, ctx) =>
762
+ c.simulcastStreams.delete({
763
+ streamId: ctx.streamId!,
764
+ simulcastId: ctx.simulcastId!,
765
+ } as any),
766
+ },
767
+ {
768
+ operationId: "delete-playbackId-of-stream",
769
+ phase: "DELETE",
770
+ needs: ["streamId", "streamPlaybackId"],
771
+ invoke: (c, ctx) =>
772
+ c.livePlayback.delete({
773
+ streamId: ctx.streamId!,
774
+ playbackId: ctx.streamPlaybackId!,
775
+ } as any),
776
+ },
777
+ {
778
+ operationId: "delete-live-stream",
779
+ phase: "DELETE",
780
+ needs: ["streamId"],
781
+ invoke: (c, ctx) => c.liveStreams.delete({ streamId: ctx.streamId! } as any),
782
+ },
783
+ {
784
+ operationId: "delete-media",
785
+ phase: "DELETE",
786
+ needs: ["mediaId"],
787
+ invoke: (c, ctx) => c.manageVideos.delete({ mediaId: ctx.mediaId! } as any),
788
+ },
789
+ {
790
+ operationId: "delete_signing_key",
791
+ phase: "DELETE",
792
+ needs: ["signingKeyId"],
793
+ invoke: (c, ctx) =>
794
+ c.signingKeys.delete({ signingKeyId: ctx.signingKeyId! } as any),
795
+ },
796
+ ];
797
+
798
+ // ---------------------------------------------------------------------------
799
+ // Artifacts + report
800
+ // ---------------------------------------------------------------------------
801
+
802
+ function writeArtifacts(operationId: string, rawBody: any, sdkValue: any) {
803
+ const dir = join(__dirname, ARTIFACTS_DIRNAME);
804
+ mkdirSync(dir, { recursive: true });
805
+ const slug = safeFileSlug(operationId);
806
+ writeFileSync(join(dir, `${slug}.raw.json`), toPrettyJson(rawBody ?? null));
807
+ writeFileSync(join(dir, `${slug}.sdk.json`), toPrettyJson(sdkValue ?? null));
808
+ }
809
+
810
+ function writeReport(results: StepResult[], ctx: Ctx) {
811
+ const total = results.length;
812
+ const pass = results.filter((r) => r.status === "PASS").length;
813
+ const fail = results.filter((r) => r.status === "FAIL").length;
814
+ const skip = results.filter((r) => r.status === "SKIP").length;
815
+
816
+ const lines: string[] = [];
817
+ lines.push("# Non-GET endpoints validation report (Node SDK)\n");
818
+ lines.push(`Generated: ${new Date().toISOString()}\n`);
819
+ lines.push("## Summary\n");
820
+ lines.push(`- **Total**: ${total}`);
821
+ lines.push(`- **PASS**: ${pass}`);
822
+ lines.push(`- **FAIL**: ${fail}`);
823
+ lines.push(`- **SKIP**: ${skip}\n`);
824
+
825
+ lines.push("## Captured resources\n");
826
+ for (const [k, v] of Object.entries(ctx))
827
+ lines.push(`- \`${k}\`: ${v ?? "(not created)"}`);
828
+ lines.push("");
829
+
830
+ lines.push("## Consolidated\n");
831
+ lines.push(
832
+ "| Phase | Method | OperationId | HTTP | OpenAPI valid | SDK | Missing in SDK | Missing in API | Status |",
833
+ );
834
+ lines.push("|---|---|---|---:|:--:|:--:|---|---|:--:|");
835
+ const order: Phase[] = ["CREATE", "UPDATE", "DELETE"];
836
+ for (const ph of order) {
837
+ for (const r of results.filter((x) => x.phase === ph)) {
838
+ const ov = r.openapiValid === null ? "—" : r.openapiValid ? "✅" : "❌";
839
+ const sdk = r.status === "SKIP" ? "—" : r.sdkOk ? "✅" : "❌";
840
+ const mis = (a: string[]) => (a.length ? a.join(", ") : "None");
841
+ const st =
842
+ r.status === "PASS"
843
+ ? "✅ PASS"
844
+ : r.status === "SKIP"
845
+ ? "⤳ SKIP"
846
+ : "❌ FAIL";
847
+ lines.push(
848
+ `| ${r.phase} | ${r.method} | \`${r.operationId}\` | ${r.httpStatus ?? "—"} | ${ov} | ${sdk} | ${mis(r.missingInSDK)} | ${mis(r.missingInAPI)} | ${st} |`,
849
+ );
850
+ }
851
+ }
852
+ lines.push("");
853
+
854
+ lines.push("## Per-operation\n");
855
+ for (const r of results) {
856
+ lines.push(`### ${r.operationId} (\`${r.method} ${r.path}\`)`);
857
+ lines.push(`- **Phase**: ${r.phase}`);
858
+ lines.push(`- **Status**: ${r.status}`);
859
+ if (r.httpStatus !== null) lines.push(`- **HTTP**: ${r.httpStatus}`);
860
+ if (r.capturedId) lines.push(`- **Captured id**: \`${r.capturedId}\``);
861
+ if (r.note) lines.push(`- **Note**: ${r.note}`);
862
+ if (r.sdkError) lines.push(`- **SDK error**: ${preview(r.sdkError)}`);
863
+ if (r.openapiErrors.length) {
864
+ lines.push(`- **OpenAPI errors**:`);
865
+ for (const e of r.openapiErrors.slice(0, 20))
866
+ lines.push(` - \`${e.path ?? ""}\` ${e.message ?? JSON.stringify(e)}`);
867
+ }
868
+ if (r.missingInSDK.length) {
869
+ lines.push(`- **Missing in SDK**:`);
870
+ for (const p of r.missingInSDK) lines.push(` - \`${p}\``);
871
+ }
872
+ if (r.missingInAPI.length) {
873
+ lines.push(`- **Missing in API**:`);
874
+ for (const p of r.missingInAPI) lines.push(` - \`${p}\``);
875
+ }
876
+ lines.push("");
877
+ }
878
+
879
+ writeFileSync(join(__dirname, REPORT_MD), lines.join("\n"));
880
+ console.log(`Report generated: ${join(__dirname, REPORT_MD)}`);
881
+ }
882
+
883
+ // ---------------------------------------------------------------------------
884
+ // Main
885
+ // ---------------------------------------------------------------------------
886
+
887
+ async function main(): Promise<void> {
888
+ const spec = loadOpenAPISpec();
889
+ const endpoints = extractNonGetEndpoints(spec);
890
+
891
+ const baseUrl: string =
892
+ process.env.FASTPIX_BASE_URL ??
893
+ process.env.FASTPIX_SERVER_URL ??
894
+ ((spec.servers?.[0]?.url as string | undefined) ?? "https://api.fastpix.com/v1/");
895
+
896
+ const username = process.env.FASTPIX_USERNAME ?? "";
897
+ const password = process.env.FASTPIX_PASSWORD ?? "";
898
+ if (!username || !password) {
899
+ throw new Error(
900
+ "Set FASTPIX_USERNAME and FASTPIX_PASSWORD env vars (BasicAuth) — use real credentials for live API validation",
901
+ );
902
+ }
903
+
904
+ const client = new Fastpix({
905
+ security: { username, password },
906
+ serverURL: baseUrl,
907
+ httpClient: sharedHttpClient,
908
+ } as any);
909
+
910
+ const ctx: Ctx = {};
911
+ const results: StepResult[] = [];
912
+
913
+ for (let i = 0; i < STEPS.length; i++) {
914
+ const step = STEPS[i];
915
+ const ep = endpoints.get(step.operationId);
916
+ const base = {
917
+ operationId: step.operationId,
918
+ method: ep?.method ?? "?",
919
+ path: ep?.path ?? "?",
920
+ phase: step.phase,
921
+ openapiErrors: [] as any[],
922
+ missingInSDK: [] as string[],
923
+ missingInAPI: [] as string[],
924
+ };
925
+
926
+ console.log(`[${i + 1}/${STEPS.length}] (${step.phase}) ${step.operationId}`);
927
+
928
+ if (!ep) {
929
+ results.push({
930
+ ...base,
931
+ status: "SKIP",
932
+ httpStatus: null,
933
+ openapiValid: null,
934
+ sdkOk: false,
935
+ note: "operationId not found in spec",
936
+ });
937
+ continue;
938
+ }
939
+
940
+ const missing = (step.needs ?? []).filter((k) => !ctx[k]);
941
+ if (missing.length) {
942
+ console.log(` ⤳ SKIP (missing: ${missing.join(", ")})`);
943
+ results.push({
944
+ ...base,
945
+ status: "SKIP",
946
+ httpStatus: null,
947
+ openapiValid: null,
948
+ sdkOk: false,
949
+ note: `missing dependency: ${missing.join(", ")}`,
950
+ });
951
+ continue;
952
+ }
953
+
954
+ // Track generate-subtitles needs the just-added track to be present
955
+ if (
956
+ step.operationId === "Generate-subtitle-track" &&
957
+ ctx.mediaId &&
958
+ ctx.trackId
959
+ ) {
960
+ process.stdout.write(` ⏳ waiting for track ${ctx.trackId} to be ready...`);
961
+ const t = await waitForTrackReady(baseUrl, username, password, ctx.mediaId, ctx.trackId);
962
+ console.log(` ${t}`);
963
+ }
964
+
965
+ let result = await invokeSDK(client, step, ctx);
966
+
967
+ if (step.retryOn) {
968
+ let attempt = 0;
969
+ const maxAttempts = 24;
970
+ while (
971
+ !result.ok &&
972
+ attempt < maxAttempts &&
973
+ JSON.stringify(result.error ?? {}).includes(step.retryOn)
974
+ ) {
975
+ attempt++;
976
+ if (attempt === 1) process.stdout.write(` ⏳ resource not ready, retrying`);
977
+ else process.stdout.write(".");
978
+ await sleep(5000);
979
+ result = await invokeSDK(client, step, ctx);
980
+ }
981
+ if (attempt > 0) console.log("");
982
+ }
983
+
984
+ if (!result.ok) {
985
+ const msg = `${result.error.name ?? "Error"}: ${result.error.message ?? "SDK call failed"}`;
986
+ console.log(` ❌ FAIL — ${msg.split("\n")[0].slice(0, 140)}`);
987
+ writeArtifacts(step.operationId, result.error.bodyJson ?? null, result.error);
988
+ results.push({
989
+ ...base,
990
+ status: "FAIL",
991
+ httpStatus: result.error.statusCode ?? null,
992
+ openapiValid: null,
993
+ sdkOk: false,
994
+ sdkError: msg,
995
+ });
996
+ continue;
997
+ }
998
+
999
+ let capturedId: string | undefined;
1000
+ if (step.capture) step.capture(result.value, ctx);
1001
+
1002
+ if (step.operationId === "create-media" && ctx.mediaId) {
1003
+ process.stdout.write(` ⏳ waiting for media ${ctx.mediaId} to be Ready...`);
1004
+ const status = await waitForMediaReady(baseUrl, username, password, ctx.mediaId);
1005
+ console.log(` ${status}`);
1006
+ }
1007
+
1008
+ capturedId =
1009
+ step.operationId === "create_signing_key"
1010
+ ? ctx.signingKeyId
1011
+ : step.operationId === "create-a-playlist"
1012
+ ? ctx.playlistId
1013
+ : step.operationId === "create-new-stream"
1014
+ ? ctx.streamId
1015
+ : step.operationId === "create-media"
1016
+ ? ctx.mediaId
1017
+ : step.operationId === "create-media-playback-id"
1018
+ ? ctx.createdPlaybackId
1019
+ : step.operationId === "Add-media-track"
1020
+ ? ctx.trackId
1021
+ : step.operationId === "create-playbackId-of-stream"
1022
+ ? ctx.streamPlaybackId
1023
+ : step.operationId === "create-simulcast-of-stream"
1024
+ ? ctx.simulcastId
1025
+ : step.operationId === "direct-upload-video-media"
1026
+ ? ctx.uploadId
1027
+ : undefined;
1028
+
1029
+ const validator = makeOpenAPIResponseValidator(spec, ep);
1030
+ let openapiValid: boolean | null = null;
1031
+ let openapiErrors: any[] = [];
1032
+ if (validator && result.statusCode) {
1033
+ const err = validator.validateResponse(String(result.statusCode), result.rawBody);
1034
+ openapiValid = !err;
1035
+ openapiErrors = err?.errors ?? [];
1036
+ }
1037
+
1038
+ const apiNorm = normalizeJsonForComparison(result.rawBody);
1039
+ const sdkNorm =
1040
+ result.value && typeof result.value === "object"
1041
+ ? normalizeJsonForComparison(jsonRoundTrip(result.value))
1042
+ : null;
1043
+ const apiPaths = collectJsonPaths(apiNorm, "", { includeEmptyArrays: false });
1044
+ const sdkPaths = sdkNorm
1045
+ ? collectJsonPaths(sdkNorm, "", { includeEmptyArrays: false })
1046
+ : new Set<string>();
1047
+ const missingInSDK = sdkPaths.size
1048
+ ? sortUnique([...apiPaths].filter((p) => !sdkPaths.has(p)))
1049
+ : [];
1050
+ const missingInAPI = sdkPaths.size
1051
+ ? sortUnique([...sdkPaths].filter((p) => !apiPaths.has(p)))
1052
+ : [];
1053
+
1054
+ writeArtifacts(step.operationId, result.rawBody, result.value);
1055
+
1056
+ const status: StepResult["status"] =
1057
+ result.ok &&
1058
+ (openapiValid === null || openapiValid) &&
1059
+ missingInSDK.length === 0 &&
1060
+ missingInAPI.length === 0
1061
+ ? "PASS"
1062
+ : "FAIL";
1063
+
1064
+ console.log(
1065
+ ` ${status === "PASS" ? "✅ PASS" : "❌ FAIL"} (HTTP ${result.statusCode ?? "?"})${capturedId ? ` id=${capturedId}` : ""}`,
1066
+ );
1067
+
1068
+ results.push({
1069
+ ...base,
1070
+ status,
1071
+ httpStatus: result.statusCode,
1072
+ openapiValid,
1073
+ openapiErrors,
1074
+ sdkOk: true,
1075
+ missingInSDK,
1076
+ missingInAPI,
1077
+ capturedId,
1078
+ });
1079
+ }
1080
+
1081
+ writeReport(results, ctx);
1082
+ const pass = results.filter((r) => r.status === "PASS").length;
1083
+ const fail = results.filter((r) => r.status === "FAIL").length;
1084
+ const skip = results.filter((r) => r.status === "SKIP").length;
1085
+ console.log(
1086
+ `Summary: total=${results.length} pass=${pass} fail=${fail} skip=${skip}`,
1087
+ );
1088
+ }
1089
+
1090
+ main().catch((err) => {
1091
+ console.error("Fatal:", err);
1092
+ process.exit(1);
1093
+ });