nixamp 0.28.37 → 0.28.41

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 (116) hide show
  1. package/README.md +6 -1
  2. package/backtoschool/dist/assets/{ar-CmpEhms8.js → ar-BQPKp0M2.js} +1 -1
  3. package/backtoschool/dist/assets/{cs-BiiJOLTm.js → cs-DjJnhGNB.js} +1 -1
  4. package/{web/dist/assets/da-M4GDhrcC.js → backtoschool/dist/assets/da-CbTvkIH7.js} +1 -1
  5. package/{web/dist/assets/de-D7yI8cd_.js → backtoschool/dist/assets/de-SsCkny26.js} +1 -1
  6. package/backtoschool/dist/assets/{es-BwQQh_C8.js → es-BBlBPcq1.js} +1 -1
  7. package/backtoschool/dist/assets/{fi-DKPYMsbo.js → fi-ffo35_4W.js} +1 -1
  8. package/backtoschool/dist/assets/{fr-DNekMW0h.js → fr-BVvavrk7.js} +1 -1
  9. package/{web/dist/assets/hi-DO7CO-fI.js → backtoschool/dist/assets/hi-DDy_zxu6.js} +1 -1
  10. package/{web/dist/assets/hls-3VKVEQE3-BCxdTCEU.js → backtoschool/dist/assets/hls-3VKVEQE3-QZWXCWjR.js} +1 -1
  11. package/backtoschool/dist/assets/hls-n74Cnh8A.js +42 -0
  12. package/backtoschool/dist/assets/{hu-gcw9ouWH.js → hu-BoJj7pZa.js} +1 -1
  13. package/backtoschool/dist/assets/{id-Bz51zxz6.js → id-CXN9gchF.js} +1 -1
  14. package/backtoschool/dist/assets/index-BaiHu9CD.css +1 -0
  15. package/backtoschool/dist/assets/index-Dovv39gH.js +112 -0
  16. package/backtoschool/dist/assets/{it-jO8u4ie7.js → it-C9g0xD6S.js} +1 -1
  17. package/{web/dist/assets/mpegts-DsEoUEPH.js → backtoschool/dist/assets/mpegts-GAwbg-pX.js} +1 -1
  18. package/{web/dist/assets/mpegts-LO6RVLD6-CC8jMmPy.js → backtoschool/dist/assets/mpegts-LO6RVLD6-BrVQzFhM.js} +1 -1
  19. package/backtoschool/dist/assets/native-C7JTKWJH-BUyIoj0P.js +1 -0
  20. package/{web/dist/assets/nl-BU0Mn-e-.js → backtoschool/dist/assets/nl-Ciq1Yrk4.js} +1 -1
  21. package/{web/dist/assets/ru-ClqNCOTW.js → backtoschool/dist/assets/ru-B_ZMUvh6.js} +1 -1
  22. package/backtoschool/dist/assets/{sv-CV2-POKP.js → sv-DH0ZO3Eh.js} +1 -1
  23. package/{web/dist/assets/uk-K5yQBF0h.js → backtoschool/dist/assets/uk-Cof-TUZd.js} +1 -1
  24. package/backtoschool/dist/assets/{vi-BDZew-O9.js → vi-D0QPpzbE.js} +1 -1
  25. package/{web/dist/assets/zh-a2v2x-3e.js → backtoschool/dist/assets/zh-CLTzTBOU.js} +1 -1
  26. package/backtoschool/dist/index.html +61 -10
  27. package/dist/classroom.d.ts +1 -1
  28. package/dist/classroom.js +4 -0
  29. package/dist/live-api.d.ts +10 -0
  30. package/dist/live-api.js +8 -0
  31. package/dist/live-events.js +1 -1
  32. package/dist/live-voice.d.ts +3 -0
  33. package/dist/live-voice.js +27 -4
  34. package/dist/locales/ar.d.ts +15 -0
  35. package/dist/locales/cs.d.ts +15 -0
  36. package/dist/locales/da.d.ts +15 -0
  37. package/dist/locales/de.d.ts +15 -0
  38. package/dist/locales/en.d.ts +15 -0
  39. package/dist/locales/es.d.ts +15 -0
  40. package/dist/locales/fi.d.ts +15 -0
  41. package/dist/locales/fr.d.ts +15 -0
  42. package/dist/locales/hi.d.ts +15 -0
  43. package/dist/locales/hu.d.ts +15 -0
  44. package/dist/locales/id.d.ts +15 -0
  45. package/dist/locales/it.d.ts +15 -0
  46. package/dist/locales/nl.d.ts +15 -0
  47. package/dist/locales/platforms.d.ts +19 -0
  48. package/dist/locales/platforms.js +19 -0
  49. package/dist/locales/ru.d.ts +15 -0
  50. package/dist/locales/sv.d.ts +15 -0
  51. package/dist/locales/uk.d.ts +15 -0
  52. package/dist/locales/vi.d.ts +15 -0
  53. package/dist/locales/zh.d.ts +15 -0
  54. package/dist/nixamp-link-api.d.ts +44 -0
  55. package/dist/nixamp-link-api.js +190 -0
  56. package/dist/nixamp-link-types.d.ts +33 -0
  57. package/dist/nixamp-link-types.js +5 -0
  58. package/dist/nixamp-link.d.ts +66 -0
  59. package/dist/nixamp-link.js +231 -0
  60. package/dist/notify.d.ts +6 -4
  61. package/dist/notify.js +14 -25
  62. package/dist/oauth-api.d.ts +1 -1
  63. package/dist/oauth-api.js +27 -9
  64. package/dist/oauth-server.d.ts +9 -1
  65. package/dist/oauth-server.js +24 -2
  66. package/dist/profiles.d.ts +85 -0
  67. package/dist/profiles.js +0 -0
  68. package/dist/server.d.ts +12 -2
  69. package/dist/server.js +205 -13
  70. package/dist/voice-provider.d.ts +9 -0
  71. package/dist/voice-provider.js +27 -0
  72. package/dist/watch-party.d.ts +8 -0
  73. package/dist/watch-party.js +21 -0
  74. package/package.json +6 -6
  75. package/src/classroom.ts +5 -1
  76. package/src/live-api.ts +13 -0
  77. package/src/live-events.ts +1 -1
  78. package/src/live-voice.ts +25 -3
  79. package/src/locales/platforms.ts +21 -0
  80. package/src/nixamp-link-api.ts +220 -0
  81. package/src/nixamp-link-types.ts +36 -0
  82. package/src/nixamp-link.ts +265 -0
  83. package/src/notify.ts +19 -34
  84. package/src/oauth-api.ts +30 -11
  85. package/src/oauth-server.ts +24 -2
  86. package/src/profiles.ts +0 -0
  87. package/src/server.ts +192 -15
  88. package/src/voice-provider.ts +22 -0
  89. package/src/watch-party.ts +23 -0
  90. package/web/dist/assets/{ar-DhdXPO3p.js → ar-BqLaLSMR.js} +1 -1
  91. package/web/dist/assets/{cs-CoTzYnZt.js → cs-CfoQJwKM.js} +1 -1
  92. package/{backtoschool/dist/assets/da-DueRd5zz.js → web/dist/assets/da-8MmH23fh.js} +1 -1
  93. package/{backtoschool/dist/assets/de-DIG6WxUZ.js → web/dist/assets/de-Brry3OMh.js} +1 -1
  94. package/web/dist/assets/{es-BMGb7XlT.js → es-CGxJs7b8.js} +1 -1
  95. package/web/dist/assets/{fi-CXNsmIrh.js → fi-BDAAZtto.js} +1 -1
  96. package/web/dist/assets/{fr-BpvyrESQ.js → fr-9sxYL0Qy.js} +1 -1
  97. package/{backtoschool/dist/assets/hi-CGlN72JQ.js → web/dist/assets/hi-Cc7ZsdL7.js} +1 -1
  98. package/web/dist/assets/hls-3VKVEQE3-Dx7qltzA.js +1 -0
  99. package/web/dist/assets/{hu-CosB3vlS.js → hu-CvB9aIyN.js} +1 -1
  100. package/web/dist/assets/{id-DNumDlwq.js → id-Bmrh06Hw.js} +1 -1
  101. package/web/dist/assets/index-BQuoiKg9.js +3 -0
  102. package/web/dist/assets/{index-jLCo7PIA.css → index-Bo3utcDw.css} +1 -1
  103. package/web/dist/assets/{it-IJKhyCGw.js → it-SbaxFUIP.js} +1 -1
  104. package/web/dist/assets/mpegts-BdwONu8t.js +3 -0
  105. package/web/dist/assets/mpegts-LO6RVLD6-CqW3DT1n.js +1 -0
  106. package/{backtoschool/dist/assets/nl-CnYXq0K4.js → web/dist/assets/nl-CqimSo3B.js} +1 -1
  107. package/{backtoschool/dist/assets/ru-BatrUfYu.js → web/dist/assets/ru-wIfpMpU9.js} +1 -1
  108. package/web/dist/assets/{sv-Df_aXTD6.js → sv-BAyIUHP5.js} +1 -1
  109. package/{backtoschool/dist/assets/uk-vLtqKpHm.js → web/dist/assets/uk-D2jFJm6l.js} +1 -1
  110. package/web/dist/assets/{vi-CYfcOUeA.js → vi-BdH3SLlR.js} +1 -1
  111. package/{backtoschool/dist/assets/zh-C9hBmQKA.js → web/dist/assets/zh-5xz5Agt-.js} +1 -1
  112. package/web/dist/index.html +33 -2
  113. package/web/dist/sw.js +23 -23
  114. package/backtoschool/dist/assets/index-CP4oTs6H.css +0 -1
  115. package/backtoschool/dist/assets/index-DDGO_FOw.js +0 -113
  116. package/web/dist/assets/index-CY3lAwM2.js +0 -3
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ readonly "Nixamp Share link or HTTPS media URL": string;
3
+ readonly "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ readonly Paused: string;
5
+ readonly "Broadcast ended": string;
6
+ readonly "Class broadcast": string;
7
+ readonly "Retry playback": string;
8
+ readonly "Back 10 seconds": string;
9
+ readonly "Forward 10 seconds": string;
10
+ readonly Mute: string;
11
+ readonly Unmute: string;
12
+ readonly "Exit full screen": string;
13
+ readonly "Select Play to watch the broadcast.": string;
14
+ readonly "The broadcast could not be loaded. Try again.": string;
15
+ readonly "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ readonly "Open on Pairux": string;
2
17
  readonly "Supported platforms": string;
3
18
  readonly "In review": string;
4
19
  readonly "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,23 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ Play: string;
8
+ Pause: string;
9
+ "Retry playback": string;
10
+ "Back 10 seconds": string;
11
+ "Forward 10 seconds": string;
12
+ Mute: string;
13
+ Unmute: string;
14
+ "Full screen": string;
15
+ "Exit full screen": string;
16
+ Playing: string;
17
+ "Select Play to watch the broadcast.": string;
18
+ "The broadcast could not be loaded. Try again.": string;
19
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
20
+ "Open on Pairux": string;
2
21
  "Supported platforms": string;
3
22
  "In review": string;
4
23
  "Not available": string;
@@ -1,5 +1,24 @@
1
1
  /* English fallback for BackToSchool platform and installation messages. */
2
2
  export default {
3
+ "Nixamp Share link or HTTPS media URL": "Nixamp Share link or HTTPS media URL",
4
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.",
5
+ "Paused": "Paused",
6
+ "Broadcast ended": "Broadcast ended",
7
+ "Class broadcast": "Class broadcast",
8
+ "Play": "Play",
9
+ "Pause": "Pause",
10
+ "Retry playback": "Retry playback",
11
+ "Back 10 seconds": "Back 10 seconds",
12
+ "Forward 10 seconds": "Forward 10 seconds",
13
+ "Mute": "Mute",
14
+ "Unmute": "Unmute",
15
+ "Full screen": "Full screen",
16
+ "Exit full screen": "Exit full screen",
17
+ "Playing": "Playing",
18
+ "Select Play to watch the broadcast.": "Select Play to watch the broadcast.",
19
+ "The broadcast could not be loaded. Try again.": "The broadcast could not be loaded. Try again.",
20
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.",
21
+ "Open on Pairux": "Open on Pairux",
3
22
  "Supported platforms": "Supported platforms",
4
23
  "In review": "In review",
5
24
  "Not available": "Not available",
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -1,4 +1,19 @@
1
1
  declare const _default: {
2
+ "Nixamp Share link or HTTPS media URL": string;
3
+ "For TV playback, use a Nixamp Share link or a direct HTTPS media URL. Pairux viewing opens separately.": string;
4
+ Paused: string;
5
+ "Broadcast ended": string;
6
+ "Class broadcast": string;
7
+ "Retry playback": string;
8
+ "Back 10 seconds": string;
9
+ "Forward 10 seconds": string;
10
+ Mute: string;
11
+ Unmute: string;
12
+ "Exit full screen": string;
13
+ "Select Play to watch the broadcast.": string;
14
+ "The broadcast could not be loaded. Try again.": string;
15
+ "This Pairux broadcast opens separately. For playback here on Fire TV, the host needs to share a Nixamp stream or direct media link.": string;
16
+ "Open on Pairux": string;
2
17
  "Supported platforms": string;
3
18
  "In review": string;
4
19
  "Not available": string;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The routes behind "Connect nixamp" on a site that runs on this codebase
3
+ * but is not nixamp.com.
4
+ *
5
+ * GET /api/v1/nixamp/connect send the browser to nixamp.com's consent page
6
+ * GET /api/v1/nixamp/callback the code comes back; tokens are kept
7
+ * GET /api/v1/nixamp/connection whether this account is connected, and as whom
8
+ * DELETE /api/v1/nixamp/connection withdraw the grant, both sides
9
+ * GET /api/v1/nixamp/streams the servers you run on nixamp, and what is live
10
+ *
11
+ * All five want the site's own session: the person, signed in here. What
12
+ * they hold on nixamp's side is a client token, and it never leaves the
13
+ * server -- the page only ever learns a handle and a list of streams.
14
+ */
15
+ import type { IncomingMessage, ServerResponse } from "node:http";
16
+ import { type Accounts } from "./accounts.ts";
17
+ import type { NixampLinks } from "./nixamp-link.ts";
18
+ import type { ServerStreams } from "./nixamp-link-types.ts";
19
+ export type { ServerStreams, StreamPick } from "./nixamp-link-types.ts";
20
+ export interface NixampLinkApiOptions {
21
+ links: NixampLinks;
22
+ accounts: Accounts;
23
+ /** nixamp.com, or whatever is the issuer. */
24
+ issuer: string;
25
+ /** This site, as the redirect URI is built from it: https://backtoschool.help. */
26
+ site: string;
27
+ /** The redirect URIs the client registered on the issuer; the callback must be one. */
28
+ redirectUris: string[];
29
+ /** Where the browser lands after the callback. */
30
+ home?: string;
31
+ secureCookies?: boolean;
32
+ fetcher?: typeof fetch;
33
+ }
34
+ export declare function nixampLinkPath(path: string): boolean;
35
+ /**
36
+ * Every server the nixamp account remembers, asked what it is doing.
37
+ *
38
+ * The account's own list comes from nixamp.com with the client token; each
39
+ * server is then asked directly, with the share key the account kept for it,
40
+ * and given four seconds. One that does not answer is listed as out of
41
+ * reach rather than dropped, so a host sees why a stream is missing.
42
+ */
43
+ export declare function streamsFor(token: string, issuer: string, pageSite: string, fetcher: typeof fetch): Promise<ServerStreams[]>;
44
+ export declare function handleNixampLinkApi(request: IncomingMessage, response: ServerResponse, url: URL, options: NixampLinkApiOptions): Promise<boolean>;
@@ -0,0 +1,190 @@
1
+ import { tokenFrom } from "./accounts.js";
2
+ const COOKIE = "nixamp_connect";
3
+ const CALLBACK = "/api/v1/nixamp/callback";
4
+ export function nixampLinkPath(path) {
5
+ return path === "/api/v1/nixamp/connect" || path === CALLBACK || path === "/api/v1/nixamp/connection" || path === "/api/v1/nixamp/streams";
6
+ }
7
+ function json(response, code, body, headers = {}) {
8
+ const value = JSON.stringify(body);
9
+ response.writeHead(code, {
10
+ ...headers,
11
+ "content-type": "application/json; charset=utf-8",
12
+ "content-length": Buffer.byteLength(value),
13
+ "cache-control": "no-store",
14
+ });
15
+ response.end(value);
16
+ }
17
+ function cookieValue(headers, name) {
18
+ const raw = headers.cookie ?? "";
19
+ for (const part of raw.split(";")) {
20
+ const [key, ...rest] = part.trim().split("=");
21
+ if (key === name)
22
+ return decodeURIComponent(rest.join("="));
23
+ }
24
+ return "";
25
+ }
26
+ function legCookie(value, secure) {
27
+ const parts = [`${COOKIE}=${encodeURIComponent(value)}`, `Path=${CALLBACK}`, "Max-Age=600", "SameSite=Lax", "HttpOnly"];
28
+ if (secure)
29
+ parts.push("Secure");
30
+ return parts.join("; ");
31
+ }
32
+ function clearedLegCookie() {
33
+ return `${COOKIE}=; Path=${CALLBACK}; Max-Age=0; SameSite=Lax; HttpOnly`;
34
+ }
35
+ function landing(home, outcome, reason = "") {
36
+ const url = new URL(home, "http://placeholder.invalid");
37
+ url.searchParams.set("nixamp", outcome);
38
+ if (reason)
39
+ url.searchParams.set("reason", reason.slice(0, 200));
40
+ return `${url.pathname}${url.search}${url.hash || "#settings"}`;
41
+ }
42
+ /**
43
+ * Every server the nixamp account remembers, asked what it is doing.
44
+ *
45
+ * The account's own list comes from nixamp.com with the client token; each
46
+ * server is then asked directly, with the share key the account kept for it,
47
+ * and given four seconds. One that does not answer is listed as out of
48
+ * reach rather than dropped, so a host sees why a stream is missing.
49
+ */
50
+ export async function streamsFor(token, issuer, pageSite, fetcher) {
51
+ const base = issuer.replace(/\/+$/, "");
52
+ let servers = [];
53
+ const answer = await fetcher(`${base}/api/v1/servers`, {
54
+ headers: { authorization: `Bearer ${token}`, accept: "application/json" },
55
+ signal: AbortSignal.timeout(8000),
56
+ });
57
+ if (!answer.ok)
58
+ throw new Error(answer.status === 401 ? "nixamp.com no longer accepts this connection" : `nixamp.com answered ${answer.status}`);
59
+ const body = (await answer.json().catch(() => ({})));
60
+ servers = Array.isArray(body.servers) ? body.servers : [];
61
+ const page = pageSite.replace(/\/+$/, "");
62
+ const linkTo = (address, play) => `${page}/?url=${encodeURIComponent(address)}&play=${encodeURIComponent(play)}`;
63
+ return Promise.all(servers.map(async (server) => {
64
+ const out = { id: server.id, name: server.name || server.url, url: server.url, reachable: false, playing: false, nowPlaying: "", live: "", channels: [] };
65
+ try {
66
+ const url = new URL("/api/streams", server.url.endsWith("/") ? server.url : `${server.url}/`);
67
+ if (server.key)
68
+ url.searchParams.set("k", server.key);
69
+ const response = await fetcher(url.href, { headers: { accept: "application/json" }, signal: AbortSignal.timeout(4000) });
70
+ if (!response.ok)
71
+ return out;
72
+ const data = (await response.json());
73
+ // What a viewer link is built on: the server's own view-only address
74
+ // when it publishes one, else its plain address. Never the key the
75
+ // account kept, which may open the controls.
76
+ const viewer = data.server?.url && /^https?:\/\//.test(data.server.url) ? data.server.url : server.url;
77
+ out.reachable = true;
78
+ out.name = data.server?.name || out.name;
79
+ out.playing = data.server?.playing === true;
80
+ out.nowPlaying = data.server?.nowPlaying ?? "";
81
+ out.live = out.playing ? linkTo(viewer, "live") : "";
82
+ out.channels = (data.channels ?? []).map((one) => ({
83
+ server: out.name,
84
+ serverUrl: server.url,
85
+ id: one.id,
86
+ name: one.name,
87
+ kind: one.kind ?? "audio",
88
+ listeners: typeof one.listeners === "number" ? one.listeners : 0,
89
+ link: linkTo(viewer, `channel:${one.id}`),
90
+ }));
91
+ }
92
+ catch {
93
+ // Out of reach: said so, above.
94
+ }
95
+ return out;
96
+ }));
97
+ }
98
+ export async function handleNixampLinkApi(request, response, url, options) {
99
+ const path = url.pathname;
100
+ if (!nixampLinkPath(path))
101
+ return false;
102
+ const home = options.home ?? "/";
103
+ const redirectUri = `${options.site.replace(/\/+$/, "")}${CALLBACK}`;
104
+ const registered = options.redirectUris.includes(redirectUri);
105
+ const account = await options.accounts.whoIs(tokenFrom(request.headers));
106
+ if (account === null) {
107
+ if (path === CALLBACK) {
108
+ response.writeHead(302, { location: landing(home, "failed", "sign in here first, then connect again"), "set-cookie": clearedLegCookie() });
109
+ response.end();
110
+ return true;
111
+ }
112
+ json(response, 401, { error: "sign in first" });
113
+ return true;
114
+ }
115
+ if (path === "/api/v1/nixamp/connect") {
116
+ if (request.method !== "GET") {
117
+ json(response, 405, { error: "GET only" });
118
+ return true;
119
+ }
120
+ if (!registered) {
121
+ json(response, 400, { error: "this site is not registered as a nixamp client" });
122
+ return true;
123
+ }
124
+ const leg = options.links.begin(redirectUri);
125
+ response.writeHead(302, { location: leg.url, "set-cookie": legCookie(`${leg.state}.${leg.verifier}`, options.secureCookies ?? false), "cache-control": "no-store" });
126
+ response.end();
127
+ return true;
128
+ }
129
+ if (path === CALLBACK) {
130
+ if (request.method !== "GET") {
131
+ json(response, 405, { error: "GET only" });
132
+ return true;
133
+ }
134
+ const kept = cookieValue(request.headers, COOKIE);
135
+ const dot = kept.indexOf(".");
136
+ const state = dot > 0 ? kept.slice(0, dot) : "";
137
+ const verifier = dot > 0 ? kept.slice(dot + 1) : "";
138
+ const headers = { "set-cookie": clearedLegCookie(), "cache-control": "no-store" };
139
+ const refused = url.searchParams.get("error");
140
+ if (refused) {
141
+ response.writeHead(302, { ...headers, location: landing(home, refused === "access_denied" ? "denied" : "failed", url.searchParams.get("error_description") ?? refused) });
142
+ response.end();
143
+ return true;
144
+ }
145
+ const code = url.searchParams.get("code") ?? "";
146
+ if (state === "" || url.searchParams.get("state") !== state || code === "") {
147
+ response.writeHead(302, { ...headers, location: landing(home, "failed", "that link is not the one this browser started; try again") });
148
+ response.end();
149
+ return true;
150
+ }
151
+ try {
152
+ await options.links.finish(account.id, { code, verifier, redirectUri });
153
+ response.writeHead(302, { ...headers, location: landing(home, "connected") });
154
+ }
155
+ catch (error) {
156
+ response.writeHead(302, { ...headers, location: landing(home, "failed", error.message) });
157
+ }
158
+ response.end();
159
+ return true;
160
+ }
161
+ if (path === "/api/v1/nixamp/connection") {
162
+ if (request.method === "GET") {
163
+ json(response, 200, { ...(await options.links.of(account.id)), available: registered });
164
+ return true;
165
+ }
166
+ if (request.method === "DELETE") {
167
+ json(response, 200, { ok: true, withdrawn: await options.links.disconnect(account.id) });
168
+ return true;
169
+ }
170
+ json(response, 405, { error: "GET or DELETE" });
171
+ return true;
172
+ }
173
+ // /api/v1/nixamp/streams
174
+ if (request.method !== "GET") {
175
+ json(response, 405, { error: "GET only" });
176
+ return true;
177
+ }
178
+ const token = await options.links.accessToken(account.id);
179
+ if (token === "") {
180
+ json(response, 409, { error: "connect your nixamp account first", connected: false });
181
+ return true;
182
+ }
183
+ try {
184
+ json(response, 200, { servers: await streamsFor(token, options.issuer, options.issuer, options.fetcher ?? fetch) });
185
+ }
186
+ catch (error) {
187
+ json(response, 502, { error: error.message });
188
+ }
189
+ return true;
190
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * What "Connect nixamp" looks like from a page: a leaf module, so a client
3
+ * bundle can name these shapes without pulling the server in behind them.
4
+ */
5
+ /** The connection as the account holder sees it. Never the tokens. */
6
+ export interface LinkView {
7
+ connected: boolean;
8
+ handle: string;
9
+ nixampUserId: string;
10
+ scope: string;
11
+ since: number | null;
12
+ }
13
+ /** A stream somebody could pick: a channel on one of their servers, as a link a classroom accepts. */
14
+ export interface StreamPick {
15
+ server: string;
16
+ serverUrl: string;
17
+ id: string;
18
+ name: string;
19
+ kind: string;
20
+ listeners: number;
21
+ link: string;
22
+ }
23
+ export interface ServerStreams {
24
+ id: string;
25
+ name: string;
26
+ url: string;
27
+ reachable: boolean;
28
+ playing: boolean;
29
+ nowPlaying: string;
30
+ /** A link to what the server itself is playing, when it is. */
31
+ live: string;
32
+ channels: StreamPick[];
33
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * What "Connect nixamp" looks like from a page: a leaf module, so a client
3
+ * bundle can name these shapes without pulling the server in behind them.
4
+ */
5
+ export {};