@ttt-productions/q-core 0.1.28 → 0.1.30

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 (496) hide show
  1. package/dist/constants/admin-views.d.ts.map +1 -1
  2. package/dist/constants/admin-views.js +0 -3
  3. package/dist/constants/admin-views.js.map +1 -1
  4. package/dist/constants/business.d.ts.map +1 -1
  5. package/dist/constants/business.js +0 -52
  6. package/dist/constants/business.js.map +1 -1
  7. package/dist/constants/deployment.d.ts +0 -2
  8. package/dist/constants/deployment.d.ts.map +1 -1
  9. package/dist/constants/deployment.js +0 -2
  10. package/dist/constants/deployment.js.map +1 -1
  11. package/dist/constants/media.d.ts.map +1 -1
  12. package/dist/constants/media.js +4 -30
  13. package/dist/constants/media.js.map +1 -1
  14. package/dist/constants/scheduled-jobs.d.ts +0 -25
  15. package/dist/constants/scheduled-jobs.d.ts.map +1 -1
  16. package/dist/constants/scheduled-jobs.js +0 -26
  17. package/dist/constants/scheduled-jobs.js.map +1 -1
  18. package/dist/constants/sports.d.ts +1 -0
  19. package/dist/constants/sports.d.ts.map +1 -1
  20. package/dist/constants/sports.js +4 -25
  21. package/dist/constants/sports.js.map +1 -1
  22. package/dist/constants/storage-keys.d.ts +0 -38
  23. package/dist/constants/storage-keys.d.ts.map +1 -1
  24. package/dist/constants/storage-keys.js +0 -41
  25. package/dist/constants/storage-keys.js.map +1 -1
  26. package/dist/constants/telemetry.d.ts +0 -3
  27. package/dist/constants/telemetry.d.ts.map +1 -1
  28. package/dist/constants/telemetry.js +2 -11
  29. package/dist/constants/telemetry.js.map +1 -1
  30. package/dist/doc-schemas/admin-notifications.d.ts +1 -2
  31. package/dist/doc-schemas/admin-notifications.d.ts.map +1 -1
  32. package/dist/doc-schemas/admin-notifications.js +0 -41
  33. package/dist/doc-schemas/admin-notifications.js.map +1 -1
  34. package/dist/doc-schemas/aggregate-stats.d.ts.map +1 -1
  35. package/dist/doc-schemas/aggregate-stats.js +0 -35
  36. package/dist/doc-schemas/aggregate-stats.js.map +1 -1
  37. package/dist/doc-schemas/atoms.d.ts +0 -17
  38. package/dist/doc-schemas/atoms.d.ts.map +1 -1
  39. package/dist/doc-schemas/atoms.js +0 -36
  40. package/dist/doc-schemas/atoms.js.map +1 -1
  41. package/dist/doc-schemas/audit-event.d.ts +2 -0
  42. package/dist/doc-schemas/audit-event.d.ts.map +1 -1
  43. package/dist/doc-schemas/audit-event.js +0 -8
  44. package/dist/doc-schemas/audit-event.js.map +1 -1
  45. package/dist/doc-schemas/award-group-grant.d.ts +2 -8
  46. package/dist/doc-schemas/award-group-grant.d.ts.map +1 -1
  47. package/dist/doc-schemas/award-group-grant.js +0 -25
  48. package/dist/doc-schemas/award-group-grant.js.map +1 -1
  49. package/dist/doc-schemas/catalogs.d.ts.map +1 -1
  50. package/dist/doc-schemas/catalogs.js +0 -12
  51. package/dist/doc-schemas/catalogs.js.map +1 -1
  52. package/dist/doc-schemas/firestore-primitives.d.ts.map +1 -1
  53. package/dist/doc-schemas/firestore-primitives.js +0 -5
  54. package/dist/doc-schemas/firestore-primitives.js.map +1 -1
  55. package/dist/doc-schemas/gallery.d.ts.map +1 -1
  56. package/dist/doc-schemas/gallery.js +9 -18
  57. package/dist/doc-schemas/gallery.js.map +1 -1
  58. package/dist/doc-schemas/game-location.d.ts.map +1 -1
  59. package/dist/doc-schemas/game-location.js +2 -11
  60. package/dist/doc-schemas/game-location.js.map +1 -1
  61. package/dist/doc-schemas/game-stat-history.d.ts.map +1 -1
  62. package/dist/doc-schemas/game-stat-history.js +2 -11
  63. package/dist/doc-schemas/game-stat-history.js.map +1 -1
  64. package/dist/doc-schemas/game-stats.d.ts.map +1 -1
  65. package/dist/doc-schemas/game-stats.js +0 -56
  66. package/dist/doc-schemas/game-stats.js.map +1 -1
  67. package/dist/doc-schemas/league-team.d.ts.map +1 -1
  68. package/dist/doc-schemas/league-team.js +6 -29
  69. package/dist/doc-schemas/league-team.js.map +1 -1
  70. package/dist/doc-schemas/membership-roster-sync.d.ts.map +1 -1
  71. package/dist/doc-schemas/membership-roster-sync.js +0 -17
  72. package/dist/doc-schemas/membership-roster-sync.js.map +1 -1
  73. package/dist/doc-schemas/migration-console.d.ts +21 -15
  74. package/dist/doc-schemas/migration-console.d.ts.map +1 -1
  75. package/dist/doc-schemas/migration-console.js +0 -32
  76. package/dist/doc-schemas/migration-console.js.map +1 -1
  77. package/dist/doc-schemas/pending-media.d.ts.map +1 -1
  78. package/dist/doc-schemas/pending-media.js +8 -20
  79. package/dist/doc-schemas/pending-media.js.map +1 -1
  80. package/dist/doc-schemas/picture-retirement.d.ts.map +1 -1
  81. package/dist/doc-schemas/picture-retirement.js +8 -13
  82. package/dist/doc-schemas/picture-retirement.js.map +1 -1
  83. package/dist/doc-schemas/publicUser.d.ts.map +1 -1
  84. package/dist/doc-schemas/publicUser.js +0 -5
  85. package/dist/doc-schemas/publicUser.js.map +1 -1
  86. package/dist/doc-schemas/registration-start.d.ts.map +1 -1
  87. package/dist/doc-schemas/registration-start.js +2 -5
  88. package/dist/doc-schemas/registration-start.js.map +1 -1
  89. package/dist/doc-schemas/registry.d.ts +25 -14
  90. package/dist/doc-schemas/registry.d.ts.map +1 -1
  91. package/dist/doc-schemas/registry.js +0 -10
  92. package/dist/doc-schemas/registry.js.map +1 -1
  93. package/dist/doc-schemas/reserved-display-name.d.ts.map +1 -1
  94. package/dist/doc-schemas/reserved-display-name.js +0 -5
  95. package/dist/doc-schemas/reserved-display-name.js.map +1 -1
  96. package/dist/doc-schemas/sport-game.d.ts.map +1 -1
  97. package/dist/doc-schemas/sport-game.js +1 -29
  98. package/dist/doc-schemas/sport-game.js.map +1 -1
  99. package/dist/doc-schemas/sport-league.d.ts +0 -9
  100. package/dist/doc-schemas/sport-league.d.ts.map +1 -1
  101. package/dist/doc-schemas/sport-league.js +4 -26
  102. package/dist/doc-schemas/sport-league.js.map +1 -1
  103. package/dist/doc-schemas/stats-operation.d.ts +22 -18
  104. package/dist/doc-schemas/stats-operation.d.ts.map +1 -1
  105. package/dist/doc-schemas/stats-operation.js +7 -44
  106. package/dist/doc-schemas/stats-operation.js.map +1 -1
  107. package/dist/doc-schemas/status-reconcile-queue.d.ts +0 -6
  108. package/dist/doc-schemas/status-reconcile-queue.d.ts.map +1 -1
  109. package/dist/doc-schemas/status-reconcile-queue.js +0 -13
  110. package/dist/doc-schemas/status-reconcile-queue.js.map +1 -1
  111. package/dist/doc-schemas/sweep-state.d.ts.map +1 -1
  112. package/dist/doc-schemas/sweep-state.js +4 -20
  113. package/dist/doc-schemas/sweep-state.js.map +1 -1
  114. package/dist/doc-schemas/system.d.ts.map +1 -1
  115. package/dist/doc-schemas/system.js +1 -27
  116. package/dist/doc-schemas/system.js.map +1 -1
  117. package/dist/doc-schemas/team-membership.d.ts.map +1 -1
  118. package/dist/doc-schemas/team-membership.js +0 -10
  119. package/dist/doc-schemas/team-membership.js.map +1 -1
  120. package/dist/doc-schemas/user-profile.d.ts +0 -1
  121. package/dist/doc-schemas/user-profile.d.ts.map +1 -1
  122. package/dist/doc-schemas/user-profile.js +0 -28
  123. package/dist/doc-schemas/user-profile.js.map +1 -1
  124. package/dist/doc-schemas/waiver-template.d.ts.map +1 -1
  125. package/dist/doc-schemas/waiver-template.js +4 -25
  126. package/dist/doc-schemas/waiver-template.js.map +1 -1
  127. package/dist/doc-schemas/waivers-and-hardware.d.ts.map +1 -1
  128. package/dist/doc-schemas/waivers-and-hardware.js +0 -20
  129. package/dist/doc-schemas/waivers-and-hardware.js.map +1 -1
  130. package/dist/domain-events/domain-events.d.ts.map +1 -1
  131. package/dist/domain-events/domain-events.js +0 -67
  132. package/dist/domain-events/domain-events.js.map +1 -1
  133. package/dist/ids/award-grant-ids.d.ts.map +1 -1
  134. package/dist/ids/award-grant-ids.js +0 -7
  135. package/dist/ids/award-grant-ids.js.map +1 -1
  136. package/dist/ids/compound-ids.d.ts.map +1 -1
  137. package/dist/ids/compound-ids.js +0 -7
  138. package/dist/ids/compound-ids.js.map +1 -1
  139. package/dist/ids/minted-ids.d.ts.map +1 -1
  140. package/dist/ids/minted-ids.js +4 -14
  141. package/dist/ids/minted-ids.js.map +1 -1
  142. package/dist/ids/notification-ids.d.ts.map +1 -1
  143. package/dist/ids/notification-ids.js +0 -15
  144. package/dist/ids/notification-ids.js.map +1 -1
  145. package/dist/ids/picture-ids.d.ts +0 -5
  146. package/dist/ids/picture-ids.d.ts.map +1 -1
  147. package/dist/ids/picture-ids.js +0 -11
  148. package/dist/ids/picture-ids.js.map +1 -1
  149. package/dist/ids/stat-event-ids.d.ts +0 -6
  150. package/dist/ids/stat-event-ids.d.ts.map +1 -1
  151. package/dist/ids/stat-event-ids.js +0 -15
  152. package/dist/ids/stat-event-ids.js.map +1 -1
  153. package/dist/ids/stats-operation-ids.d.ts.map +1 -1
  154. package/dist/ids/stats-operation-ids.js +0 -7
  155. package/dist/ids/stats-operation-ids.js.map +1 -1
  156. package/dist/ids/waiver-template-ids.d.ts +0 -1
  157. package/dist/ids/waiver-template-ids.d.ts.map +1 -1
  158. package/dist/ids/waiver-template-ids.js +0 -2
  159. package/dist/ids/waiver-template-ids.js.map +1 -1
  160. package/dist/index.d.ts +2 -0
  161. package/dist/index.d.ts.map +1 -1
  162. package/dist/index.js +2 -2
  163. package/dist/index.js.map +1 -1
  164. package/dist/input-formats/input-formats.d.ts +0 -80
  165. package/dist/input-formats/input-formats.d.ts.map +1 -1
  166. package/dist/input-formats/input-formats.js +0 -86
  167. package/dist/input-formats/input-formats.js.map +1 -1
  168. package/dist/media/file-origins.d.ts +0 -3
  169. package/dist/media/file-origins.d.ts.map +1 -1
  170. package/dist/media/file-origins.js +0 -26
  171. package/dist/media/file-origins.js.map +1 -1
  172. package/dist/media/picture-aspects.d.ts +0 -2
  173. package/dist/media/picture-aspects.d.ts.map +1 -1
  174. package/dist/media/picture-aspects.js +0 -5
  175. package/dist/media/picture-aspects.js.map +1 -1
  176. package/dist/media/picture-url.d.ts +0 -6
  177. package/dist/media/picture-url.d.ts.map +1 -1
  178. package/dist/media/picture-url.js +0 -9
  179. package/dist/media/picture-url.js.map +1 -1
  180. package/dist/media/upload-tray-display.d.ts +0 -3
  181. package/dist/media/upload-tray-display.d.ts.map +1 -1
  182. package/dist/media/upload-tray-display.js +0 -6
  183. package/dist/media/upload-tray-display.js.map +1 -1
  184. package/dist/migration-console/action-ids.d.ts +4 -1
  185. package/dist/migration-console/action-ids.d.ts.map +1 -1
  186. package/dist/migration-console/action-ids.js +8 -45
  187. package/dist/migration-console/action-ids.js.map +1 -1
  188. package/dist/migration-console/console-lock.d.ts +10 -0
  189. package/dist/migration-console/console-lock.d.ts.map +1 -0
  190. package/dist/migration-console/console-lock.js +14 -0
  191. package/dist/migration-console/console-lock.js.map +1 -0
  192. package/dist/migration-console/consumed-source.d.ts +4 -0
  193. package/dist/migration-console/consumed-source.d.ts.map +1 -0
  194. package/dist/migration-console/consumed-source.js +10 -0
  195. package/dist/migration-console/consumed-source.js.map +1 -0
  196. package/dist/migration-console/manifest.d.ts +2 -24
  197. package/dist/migration-console/manifest.d.ts.map +1 -1
  198. package/dist/migration-console/manifest.js +174 -61
  199. package/dist/migration-console/manifest.js.map +1 -1
  200. package/dist/migration-console/run-state.d.ts +2 -14
  201. package/dist/migration-console/run-state.d.ts.map +1 -1
  202. package/dist/migration-console/run-state.js +3 -16
  203. package/dist/migration-console/run-state.js.map +1 -1
  204. package/dist/notifications/admin-notification-config.d.ts +0 -11
  205. package/dist/notifications/admin-notification-config.d.ts.map +1 -1
  206. package/dist/notifications/admin-notification-config.js +2 -13
  207. package/dist/notifications/admin-notification-config.js.map +1 -1
  208. package/dist/notifications/archive-all.d.ts.map +1 -1
  209. package/dist/notifications/archive-all.js +0 -2
  210. package/dist/notifications/archive-all.js.map +1 -1
  211. package/dist/notifications/occurrences.d.ts +0 -3
  212. package/dist/notifications/occurrences.d.ts.map +1 -1
  213. package/dist/notifications/occurrences.js +0 -7
  214. package/dist/notifications/occurrences.js.map +1 -1
  215. package/dist/paths/app-routes.d.ts +0 -12
  216. package/dist/paths/app-routes.d.ts.map +1 -1
  217. package/dist/paths/app-routes.js +0 -18
  218. package/dist/paths/app-routes.js.map +1 -1
  219. package/dist/paths/collection-groups.d.ts.map +1 -1
  220. package/dist/paths/collection-groups.js +0 -5
  221. package/dist/paths/collection-groups.js.map +1 -1
  222. package/dist/paths/collection-refs.d.ts.map +1 -1
  223. package/dist/paths/collection-refs.js +0 -4
  224. package/dist/paths/collection-refs.js.map +1 -1
  225. package/dist/paths/collections.d.ts +0 -5
  226. package/dist/paths/collections.d.ts.map +1 -1
  227. package/dist/paths/collections.js +0 -68
  228. package/dist/paths/collections.js.map +1 -1
  229. package/dist/paths/path-builders.d.ts.map +1 -1
  230. package/dist/paths/path-builders.js +0 -16
  231. package/dist/paths/path-builders.js.map +1 -1
  232. package/dist/paths/picture-owner-paths.d.ts +0 -4
  233. package/dist/paths/picture-owner-paths.d.ts.map +1 -1
  234. package/dist/paths/picture-owner-paths.js +2 -11
  235. package/dist/paths/picture-owner-paths.js.map +1 -1
  236. package/dist/paths/storage-paths.d.ts +0 -18
  237. package/dist/paths/storage-paths.d.ts.map +1 -1
  238. package/dist/paths/storage-paths.js +0 -23
  239. package/dist/paths/storage-paths.js.map +1 -1
  240. package/dist/paths/utils.d.ts +0 -6
  241. package/dist/paths/utils.d.ts.map +1 -1
  242. package/dist/paths/utils.js +0 -9
  243. package/dist/paths/utils.js.map +1 -1
  244. package/dist/schemas/account-settings.d.ts.map +1 -1
  245. package/dist/schemas/account-settings.js +0 -7
  246. package/dist/schemas/account-settings.js.map +1 -1
  247. package/dist/schemas/admin-notifications.d.ts.map +1 -1
  248. package/dist/schemas/admin-notifications.js +0 -17
  249. package/dist/schemas/admin-notifications.js.map +1 -1
  250. package/dist/schemas/admin-stats.d.ts.map +1 -1
  251. package/dist/schemas/admin-stats.js +0 -9
  252. package/dist/schemas/admin-stats.js.map +1 -1
  253. package/dist/schemas/app-config.d.ts.map +1 -1
  254. package/dist/schemas/app-config.js +0 -10
  255. package/dist/schemas/app-config.js.map +1 -1
  256. package/dist/schemas/atoms.d.ts.map +1 -1
  257. package/dist/schemas/atoms.js +0 -10
  258. package/dist/schemas/atoms.js.map +1 -1
  259. package/dist/schemas/awards.d.ts +3 -3
  260. package/dist/schemas/awards.d.ts.map +1 -1
  261. package/dist/schemas/awards.js +0 -29
  262. package/dist/schemas/awards.js.map +1 -1
  263. package/dist/schemas/dead-letters.d.ts +0 -3
  264. package/dist/schemas/dead-letters.d.ts.map +1 -1
  265. package/dist/schemas/dead-letters.js +0 -15
  266. package/dist/schemas/dead-letters.js.map +1 -1
  267. package/dist/schemas/game-locations.d.ts.map +1 -1
  268. package/dist/schemas/game-locations.js +0 -6
  269. package/dist/schemas/game-locations.js.map +1 -1
  270. package/dist/schemas/hardware-loan-contracts.d.ts.map +1 -1
  271. package/dist/schemas/hardware-loan-contracts.js +0 -13
  272. package/dist/schemas/hardware-loan-contracts.js.map +1 -1
  273. package/dist/schemas/index.d.ts.map +1 -1
  274. package/dist/schemas/index.js +0 -2
  275. package/dist/schemas/index.js.map +1 -1
  276. package/dist/schemas/leagues.d.ts.map +1 -1
  277. package/dist/schemas/leagues.js +0 -24
  278. package/dist/schemas/leagues.js.map +1 -1
  279. package/dist/schemas/migration-console.d.ts +58 -15
  280. package/dist/schemas/migration-console.d.ts.map +1 -1
  281. package/dist/schemas/migration-console.js +4 -34
  282. package/dist/schemas/migration-console.js.map +1 -1
  283. package/dist/schemas/pictures.d.ts.map +1 -1
  284. package/dist/schemas/pictures.js +0 -10
  285. package/dist/schemas/pictures.js.map +1 -1
  286. package/dist/schemas/schedules.d.ts.map +1 -1
  287. package/dist/schemas/schedules.js +0 -26
  288. package/dist/schemas/schedules.js.map +1 -1
  289. package/dist/schemas/scoring.d.ts +20 -26
  290. package/dist/schemas/scoring.d.ts.map +1 -1
  291. package/dist/schemas/scoring.js +0 -33
  292. package/dist/schemas/scoring.js.map +1 -1
  293. package/dist/schemas/signed-waivers.d.ts.map +1 -1
  294. package/dist/schemas/signed-waivers.js +0 -22
  295. package/dist/schemas/signed-waivers.js.map +1 -1
  296. package/dist/schemas/stats.d.ts +12 -0
  297. package/dist/schemas/stats.d.ts.map +1 -1
  298. package/dist/schemas/stats.js +21 -61
  299. package/dist/schemas/stats.js.map +1 -1
  300. package/dist/schemas/team-joining.d.ts.map +1 -1
  301. package/dist/schemas/team-joining.js +0 -30
  302. package/dist/schemas/team-joining.js.map +1 -1
  303. package/dist/schemas/teams.d.ts +0 -1
  304. package/dist/schemas/teams.d.ts.map +1 -1
  305. package/dist/schemas/teams.js +0 -83
  306. package/dist/schemas/teams.js.map +1 -1
  307. package/dist/schemas/uploads.d.ts +0 -8
  308. package/dist/schemas/uploads.d.ts.map +1 -1
  309. package/dist/schemas/uploads.js +0 -29
  310. package/dist/schemas/uploads.js.map +1 -1
  311. package/dist/schemas/users.d.ts +0 -1
  312. package/dist/schemas/users.d.ts.map +1 -1
  313. package/dist/schemas/users.js +0 -41
  314. package/dist/schemas/users.js.map +1 -1
  315. package/dist/schemas/waiver-templates.d.ts.map +1 -1
  316. package/dist/schemas/waiver-templates.js +0 -7
  317. package/dist/schemas/waiver-templates.js.map +1 -1
  318. package/dist/sports/basketball-scoring.d.ts +0 -4
  319. package/dist/sports/basketball-scoring.d.ts.map +1 -1
  320. package/dist/sports/basketball-scoring.js +0 -34
  321. package/dist/sports/basketball-scoring.js.map +1 -1
  322. package/dist/sports/basketball.d.ts.map +1 -1
  323. package/dist/sports/basketball.js +0 -5
  324. package/dist/sports/basketball.js.map +1 -1
  325. package/dist/sports/bulk-entry.d.ts +0 -22
  326. package/dist/sports/bulk-entry.d.ts.map +1 -1
  327. package/dist/sports/bulk-entry.js +0 -10
  328. package/dist/sports/bulk-entry.js.map +1 -1
  329. package/dist/sports/column-catalog.d.ts +0 -17
  330. package/dist/sports/column-catalog.d.ts.map +1 -1
  331. package/dist/sports/column-catalog.js +0 -10
  332. package/dist/sports/column-catalog.js.map +1 -1
  333. package/dist/sports/contribution.d.ts +2 -59
  334. package/dist/sports/contribution.d.ts.map +1 -1
  335. package/dist/sports/contribution.js +2 -45
  336. package/dist/sports/contribution.js.map +1 -1
  337. package/dist/sports/curling-scoring.d.ts +0 -1
  338. package/dist/sports/curling-scoring.d.ts.map +1 -1
  339. package/dist/sports/curling-scoring.js +0 -27
  340. package/dist/sports/curling-scoring.js.map +1 -1
  341. package/dist/sports/curling.d.ts.map +1 -1
  342. package/dist/sports/curling.js +0 -4
  343. package/dist/sports/curling.js.map +1 -1
  344. package/dist/sports/finalized-record.d.ts +2 -19
  345. package/dist/sports/finalized-record.d.ts.map +1 -1
  346. package/dist/sports/finalized-record.js +21 -22
  347. package/dist/sports/finalized-record.js.map +1 -1
  348. package/dist/sports/football-scoring.d.ts.map +1 -1
  349. package/dist/sports/football-scoring.js +0 -21
  350. package/dist/sports/football-scoring.js.map +1 -1
  351. package/dist/sports/football.d.ts.map +1 -1
  352. package/dist/sports/football.js +0 -4
  353. package/dist/sports/football.js.map +1 -1
  354. package/dist/sports/index.d.ts.map +1 -1
  355. package/dist/sports/index.js +0 -2
  356. package/dist/sports/index.js.map +1 -1
  357. package/dist/sports/ledger-continuity.d.ts +0 -2
  358. package/dist/sports/ledger-continuity.d.ts.map +1 -1
  359. package/dist/sports/ledger-continuity.js +0 -5
  360. package/dist/sports/ledger-continuity.js.map +1 -1
  361. package/dist/sports/lifetime-summary.d.ts +0 -6
  362. package/dist/sports/lifetime-summary.d.ts.map +1 -1
  363. package/dist/sports/lifetime-summary.js +0 -7
  364. package/dist/sports/lifetime-summary.js.map +1 -1
  365. package/dist/sports/rankings.d.ts +0 -12
  366. package/dist/sports/rankings.d.ts.map +1 -1
  367. package/dist/sports/rankings.js +0 -15
  368. package/dist/sports/rankings.js.map +1 -1
  369. package/dist/sports/registry.d.ts +0 -10
  370. package/dist/sports/registry.d.ts.map +1 -1
  371. package/dist/sports/registry.js +0 -9
  372. package/dist/sports/registry.js.map +1 -1
  373. package/dist/sports/replay.d.ts +0 -11
  374. package/dist/sports/replay.d.ts.map +1 -1
  375. package/dist/sports/replay.js +0 -16
  376. package/dist/sports/replay.js.map +1 -1
  377. package/dist/sports/rollup-check.d.ts +0 -7
  378. package/dist/sports/rollup-check.d.ts.map +1 -1
  379. package/dist/sports/rollup-check.js +0 -14
  380. package/dist/sports/rollup-check.js.map +1 -1
  381. package/dist/sports/score-mirror.d.ts +0 -1
  382. package/dist/sports/score-mirror.d.ts.map +1 -1
  383. package/dist/sports/score-mirror.js +0 -4
  384. package/dist/sports/score-mirror.js.map +1 -1
  385. package/dist/sports/scoring-display.d.ts +0 -30
  386. package/dist/sports/scoring-display.d.ts.map +1 -1
  387. package/dist/sports/scoring-display.js +0 -9
  388. package/dist/sports/scoring-display.js.map +1 -1
  389. package/dist/sports/scoring.d.ts +0 -36
  390. package/dist/sports/scoring.d.ts.map +1 -1
  391. package/dist/sports/scoring.js +0 -10
  392. package/dist/sports/scoring.js.map +1 -1
  393. package/dist/sports/shared-columns.d.ts +0 -1
  394. package/dist/sports/shared-columns.d.ts.map +1 -1
  395. package/dist/sports/shared-columns.js +0 -7
  396. package/dist/sports/shared-columns.js.map +1 -1
  397. package/dist/sports/sport-adapter.d.ts +0 -32
  398. package/dist/sports/sport-adapter.d.ts.map +1 -1
  399. package/dist/sports/sport-adapter.js +0 -7
  400. package/dist/sports/sport-adapter.js.map +1 -1
  401. package/dist/sports/store-driver.d.ts +0 -28
  402. package/dist/sports/store-driver.d.ts.map +1 -1
  403. package/dist/sports/store-driver.js +0 -38
  404. package/dist/sports/store-driver.js.map +1 -1
  405. package/dist/types/audit.d.ts +1 -1
  406. package/dist/types/audit.d.ts.map +1 -1
  407. package/dist/types/audit.js +1 -67
  408. package/dist/types/audit.js.map +1 -1
  409. package/dist/types/claims.d.ts +0 -10
  410. package/dist/types/claims.d.ts.map +1 -1
  411. package/dist/types/claims.js +0 -16
  412. package/dist/types/claims.js.map +1 -1
  413. package/dist/types/notifications.d.ts.map +1 -1
  414. package/dist/types/notifications.js +7 -25
  415. package/dist/types/notifications.js.map +1 -1
  416. package/dist/types/picture-owners.d.ts +0 -1
  417. package/dist/types/picture-owners.d.ts.map +1 -1
  418. package/dist/types/picture-owners.js +0 -6
  419. package/dist/types/picture-owners.js.map +1 -1
  420. package/dist/types/schedules.d.ts.map +1 -1
  421. package/dist/types/schedules.js +0 -9
  422. package/dist/types/schedules.js.map +1 -1
  423. package/dist/types/sports.d.ts.map +1 -1
  424. package/dist/types/sports.js +0 -24
  425. package/dist/types/sports.js.map +1 -1
  426. package/dist/types/stats.d.ts.map +1 -1
  427. package/dist/types/stats.js +0 -65
  428. package/dist/types/stats.js.map +1 -1
  429. package/dist/types/unions.d.ts +0 -2
  430. package/dist/types/unions.d.ts.map +1 -1
  431. package/dist/types/unions.js +3 -91
  432. package/dist/types/unions.js.map +1 -1
  433. package/dist/types/uploads.d.ts.map +1 -1
  434. package/dist/types/uploads.js +0 -7
  435. package/dist/types/uploads.js.map +1 -1
  436. package/dist/upload-variables/on-progress.d.ts.map +1 -1
  437. package/dist/upload-variables/on-progress.js +2 -5
  438. package/dist/upload-variables/on-progress.js.map +1 -1
  439. package/dist/upload-variables/picture-upload-variables.d.ts +0 -1
  440. package/dist/upload-variables/picture-upload-variables.d.ts.map +1 -1
  441. package/dist/upload-variables/picture-upload-variables.js +0 -4
  442. package/dist/upload-variables/picture-upload-variables.js.map +1 -1
  443. package/dist/upload-variables/sign-hardware-contract-variables.d.ts.map +1 -1
  444. package/dist/upload-variables/sign-hardware-contract-variables.js +0 -2
  445. package/dist/upload-variables/sign-hardware-contract-variables.js.map +1 -1
  446. package/dist/upload-variables/sign-waiver-variables.d.ts.map +1 -1
  447. package/dist/upload-variables/sign-waiver-variables.js +0 -4
  448. package/dist/upload-variables/sign-waiver-variables.js.map +1 -1
  449. package/dist/utils/account-status.d.ts.map +1 -1
  450. package/dist/utils/account-status.js +0 -4
  451. package/dist/utils/account-status.js.map +1 -1
  452. package/dist/utils/app-config.d.ts +0 -53
  453. package/dist/utils/app-config.d.ts.map +1 -1
  454. package/dist/utils/app-config.js +0 -62
  455. package/dist/utils/app-config.js.map +1 -1
  456. package/dist/utils/display-name.d.ts +0 -7
  457. package/dist/utils/display-name.d.ts.map +1 -1
  458. package/dist/utils/display-name.js +0 -8
  459. package/dist/utils/display-name.js.map +1 -1
  460. package/dist/utils/index.d.ts +1 -0
  461. package/dist/utils/index.d.ts.map +1 -1
  462. package/dist/utils/index.js +1 -0
  463. package/dist/utils/index.js.map +1 -1
  464. package/dist/utils/league-calendar.d.ts +0 -11
  465. package/dist/utils/league-calendar.d.ts.map +1 -1
  466. package/dist/utils/league-calendar.js +7 -19
  467. package/dist/utils/league-calendar.js.map +1 -1
  468. package/dist/utils/league-join-warning.d.ts +0 -11
  469. package/dist/utils/league-join-warning.d.ts.map +1 -1
  470. package/dist/utils/league-join-warning.js +0 -28
  471. package/dist/utils/league-join-warning.js.map +1 -1
  472. package/dist/utils/league-joining.d.ts +0 -1
  473. package/dist/utils/league-joining.d.ts.map +1 -1
  474. package/dist/utils/league-joining.js +0 -7
  475. package/dist/utils/league-joining.js.map +1 -1
  476. package/dist/utils/league-mode.d.ts +0 -1
  477. package/dist/utils/league-mode.d.ts.map +1 -1
  478. package/dist/utils/league-mode.js +0 -4
  479. package/dist/utils/league-mode.js.map +1 -1
  480. package/dist/utils/schedules.d.ts +0 -15
  481. package/dist/utils/schedules.d.ts.map +1 -1
  482. package/dist/utils/schedules.js +0 -19
  483. package/dist/utils/schedules.js.map +1 -1
  484. package/dist/utils/stats-operation-request.d.ts +20 -0
  485. package/dist/utils/stats-operation-request.d.ts.map +1 -0
  486. package/dist/utils/stats-operation-request.js +10 -0
  487. package/dist/utils/stats-operation-request.js.map +1 -0
  488. package/dist/utils/team-creation.d.ts +0 -2
  489. package/dist/utils/team-creation.d.ts.map +1 -1
  490. package/dist/utils/team-creation.js +0 -6
  491. package/dist/utils/team-creation.js.map +1 -1
  492. package/dist/utils/team-member-actions.d.ts +0 -6
  493. package/dist/utils/team-member-actions.d.ts.map +1 -1
  494. package/dist/utils/team-member-actions.js +0 -12
  495. package/dist/utils/team-member-actions.js.map +1 -1
  496. package/package.json +2 -1
@@ -1,79 +1,26 @@
1
1
  import type { AppConfig } from '../doc-schemas/system.js';
2
- /** Every operator lever of `_appConfig/app`, each at a value its schema field accepts. */
3
2
  export type AppConfigLevers = Readonly<Required<AppConfig>>;
4
- /** The name of one operator lever. */
5
3
  export type AppConfigLeverKey = keyof AppConfigLevers;
6
- /** Every lever name, derived from the document schema. */
7
4
  export declare const APP_CONFIG_LEVER_KEYS: ("appVersion" | "maintenanceMode" | "maintenanceMessage" | "registrationEnabled" | "announcementMessage")[];
8
- /**
9
- * The document a fresh environment behaves as if it held, and the value each reader falls back to
10
- * for a missing or unreadable field: maintenance off, registration open, no banner.
11
- *
12
- * `appVersion` is `''` — no version has been published — so the version gate stays dormant until an
13
- * operator sets a real one through `updateAppConfig`, whose input refuses `''`.
14
- */
15
5
  export declare const DEFAULT_APP_CONFIG: AppConfigLevers;
16
- /**
17
- * The line shown while maintenance is on and the operator left `maintenanceMessage` blank — on the
18
- * maintenance screen and in the callable refusal alike.
19
- */
20
6
  export declare const DEFAULT_MAINTENANCE_MESSAGE = "Q-Sports is down for maintenance right now. We will be back shortly \u2014 thank you for your patience.";
21
- /**
22
- * The code the callable maintenance refusal is thrown with. `unavailable` is also what a real outage
23
- * produces, so the code alone never identifies the refusal — its details do.
24
- */
25
7
  export declare const MAINTENANCE_REFUSAL_CODE: "unavailable";
26
- /** The `details.reason` the callable maintenance refusal carries. */
27
8
  export declare const MAINTENANCE_REFUSAL_REASON: "maintenance";
28
- /** Structured details carried by the callable maintenance refusal. */
29
9
  export interface MaintenanceRefusalDetails {
30
10
  readonly reason: typeof MAINTENANCE_REFUSAL_REASON;
31
11
  }
32
- /** True when `details` is the maintenance refusal's structured details. */
33
12
  export declare function isMaintenanceRefusalDetails(details: unknown): details is MaintenanceRefusalDetails;
34
- /**
35
- * True when `err` is the callable maintenance refusal — an `unavailable` error in either spelling
36
- * whose details carry `reason: 'maintenance'`. Works on the server-side error and on the client-side
37
- * callable error alike, and is decided by the code and the details, never the message, so a genuine
38
- * outage is never mistaken for the designed refusal.
39
- */
40
13
  export declare function isMaintenanceRefusalError(err: unknown): boolean;
41
- /** A stored lever its schema field refused, with the raw value the document held. */
42
14
  export interface AppConfigLeverRepair {
43
15
  readonly lever: AppConfigLeverKey;
44
16
  readonly storedValue: unknown;
45
17
  }
46
- /** The document a writer writes, and every stored lever the merge had to repair to write it. */
47
18
  export interface AppConfigMerge {
48
19
  readonly next: AppConfig;
49
20
  readonly repairs: readonly AppConfigLeverRepair[];
50
21
  }
51
- /**
52
- * The complete `_appConfig/app` document to write after applying `update` to `existing` (the
53
- * document as read in the writer's transaction; `null` or `undefined` when it does not exist). The
54
- * update's fields win, `existing` supplies the rest, and any field still missing comes from
55
- * DEFAULT_APP_CONFIG. An `undefined` update field changes nothing. Pure.
56
- *
57
- * A stored lever its schema refuses never blocks a save — a console typo must not disable the
58
- * maintenance switch. It is dropped, so the update's value replaces it when the update sends that
59
- * lever and its DEFAULT_APP_CONFIG value (what every reader already falls back to) otherwise, and it
60
- * is reported in `repairs`. A valid stored lever is carried as it is.
61
- *
62
- * Throws when the update itself would not parse, so an invalid document is never written.
63
- */
64
22
  export declare function mergeAppConfigUpdate(existing: Readonly<Record<string, unknown>> | null | undefined, update: Readonly<Partial<AppConfig>>): AppConfigMerge;
65
- /**
66
- * One operator lever off an unvalidated `_appConfig/app` snapshot (`null` or `undefined` when the
67
- * document is missing or not yet read): the stored value when its schema field accepts it, otherwise
68
- * the lever's DEFAULT_APP_CONFIG value — for an absent field and a refused one alike. Never throws.
69
- */
70
23
  export declare function readAppConfigLever<L extends AppConfigLeverKey>(snapshot: Readonly<Record<string, unknown>> | null | undefined, lever: L): AppConfigLevers[L];
71
- /**
72
- * True when an unvalidated `_appConfig/app` snapshot holds `lever` with a value its schema field
73
- * refuses — the value every reader passes over for the default. An absent field is not refused.
74
- * Never throws.
75
- */
76
24
  export declare function isAppConfigLeverRefused(snapshot: Readonly<Record<string, unknown>> | null | undefined, lever: AppConfigLeverKey): boolean;
77
- /** Every lever off an unvalidated snapshot, each through `readAppConfigLever`. Never throws. */
78
25
  export declare function readAppConfigLevers(snapshot: Readonly<Record<string, unknown>> | null | undefined): AppConfigLevers;
79
26
  //# sourceMappingURL=app-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-config.d.ts","sourceRoot":"","sources":["../../src/utils/app-config.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D,0FAA0F;AAC1F,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AAE5D,sCAAsC;AACtC,MAAM,MAAM,iBAAiB,GAAG,MAAM,eAAe,CAAC;AAEtD,0DAA0D;AAC1D,eAAO,MAAM,qBAAqB,6GAAkC,CAAC;AAErE;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,eAM/B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,2BAA2B,4GAC8D,CAAC;AAEvG;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAG,aAAsB,CAAC;AAE/D,qEAAqE;AACrE,eAAO,MAAM,0BAA0B,EAAG,aAAsB,CAAC;AAEjE,sEAAsE;AACtE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,0BAA0B,CAAC;CACpD;AASD,2EAA2E;AAC3E,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,OAAO,GACf,OAAO,IAAI,yBAAyB,CAGtC;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAQ/D;AAMD,qFAAqF;AACrF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAED,gGAAgG;AAChG,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACnD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EAC9D,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GACnC,cAAc,CAsBhB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,iBAAiB,EAC5D,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EAC9D,KAAK,EAAE,CAAC,GACP,eAAe,CAAC,CAAC,CAAC,CAKpB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EAC9D,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAGT;AAED,gGAAgG;AAChG,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,GAC7D,eAAe,CAMjB"}
1
+ {"version":3,"file":"app-config.d.ts","sourceRoot":"","sources":["../../src/utils/app-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AAE5D,MAAM,MAAM,iBAAiB,GAAG,MAAM,eAAe,CAAC;AAEtD,eAAO,MAAM,qBAAqB,6GAAkC,CAAC;AAErE,eAAO,MAAM,kBAAkB,EAAE,eAM/B,CAAC;AAEH,eAAO,MAAM,2BAA2B,4GAC8D,CAAC;AAEvG,eAAO,MAAM,wBAAwB,EAAG,aAAsB,CAAC;AAE/D,eAAO,MAAM,0BAA0B,EAAG,aAAsB,CAAC;AAEjE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,0BAA0B,CAAC;CACpD;AASD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,OAAO,GACf,OAAO,IAAI,yBAAyB,CAGtC;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAQ/D;AAMD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACnD;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EAC9D,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GACnC,cAAc,CAsBhB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,iBAAiB,EAC5D,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EAC9D,KAAK,EAAE,CAAC,GACP,eAAe,CAAC,CAAC,CAAC,CAKpB;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EAC9D,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAGT;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,GAC7D,eAAe,CAMjB"}
@@ -1,27 +1,5 @@
1
- // The `_appConfig/app` singleton at rest, and the one rule each for writing it and reading it.
2
- //
3
- // WRITE. `mergeAppConfigUpdate(existing, update)`: the writer's update on top of the document it
4
- // read, any field that document lacks — and any lever it holds at a value its schema refuses —
5
- // taken from DEFAULT_APP_CONFIG, the whole result validated. A writer that runs first on a fresh
6
- // environment therefore still writes a complete, valid document rather than a partial one, and a
7
- // hand edit in the console that broke one lever never blocks a save of another: the merge resets it
8
- // and reports the repair with the value it replaced, which the writer records.
9
- //
10
- // READ. The stored document is untrusted — an operator can edit any field in the console into any
11
- // shape — and a config read must never take the product down by itself. `readAppConfigLever`
12
- // answers one lever at a time: the stored value when its schema field accepts it, otherwise the
13
- // lever's DEFAULT_APP_CONFIG value, so one bad field never costs the good ones. The server's cached
14
- // snapshot reader and the client's readers both read through it.
15
1
  import { AppConfigSchema } from '../doc-schemas/system.js';
16
- /** Every lever name, derived from the document schema. */
17
2
  export const APP_CONFIG_LEVER_KEYS = AppConfigSchema.keyof().options;
18
- /**
19
- * The document a fresh environment behaves as if it held, and the value each reader falls back to
20
- * for a missing or unreadable field: maintenance off, registration open, no banner.
21
- *
22
- * `appVersion` is `''` — no version has been published — so the version gate stays dormant until an
23
- * operator sets a real one through `updateAppConfig`, whose input refuses `''`.
24
- */
25
3
  export const DEFAULT_APP_CONFIG = Object.freeze({
26
4
  appVersion: '',
27
5
  maintenanceMode: false,
@@ -29,17 +7,8 @@ export const DEFAULT_APP_CONFIG = Object.freeze({
29
7
  registrationEnabled: true,
30
8
  announcementMessage: '',
31
9
  });
32
- /**
33
- * The line shown while maintenance is on and the operator left `maintenanceMessage` blank — on the
34
- * maintenance screen and in the callable refusal alike.
35
- */
36
10
  export const DEFAULT_MAINTENANCE_MESSAGE = 'Q-Sports is down for maintenance right now. We will be back shortly — thank you for your patience.';
37
- /**
38
- * The code the callable maintenance refusal is thrown with. `unavailable` is also what a real outage
39
- * produces, so the code alone never identifies the refusal — its details do.
40
- */
41
11
  export const MAINTENANCE_REFUSAL_CODE = 'unavailable';
42
- /** The `details.reason` the callable maintenance refusal carries. */
43
12
  export const MAINTENANCE_REFUSAL_REASON = 'maintenance';
44
13
  // The refusal code as the server (`unavailable`) and the Firebase client SDK
45
14
  // (`functions/unavailable`) spell it.
@@ -47,18 +16,11 @@ const MAINTENANCE_REFUSAL_CODES = new Set([
47
16
  MAINTENANCE_REFUSAL_CODE,
48
17
  `functions/${MAINTENANCE_REFUSAL_CODE}`,
49
18
  ]);
50
- /** True when `details` is the maintenance refusal's structured details. */
51
19
  export function isMaintenanceRefusalDetails(details) {
52
20
  if (!details || typeof details !== 'object')
53
21
  return false;
54
22
  return details.reason === MAINTENANCE_REFUSAL_REASON;
55
23
  }
56
- /**
57
- * True when `err` is the callable maintenance refusal — an `unavailable` error in either spelling
58
- * whose details carry `reason: 'maintenance'`. Works on the server-side error and on the client-side
59
- * callable error alike, and is decided by the code and the details, never the message, so a genuine
60
- * outage is never mistaken for the designed refusal.
61
- */
62
24
  export function isMaintenanceRefusalError(err) {
63
25
  if (!err || typeof err !== 'object')
64
26
  return false;
@@ -70,19 +32,6 @@ export function isMaintenanceRefusalError(err) {
70
32
  function definedFields(fields) {
71
33
  return Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== undefined));
72
34
  }
73
- /**
74
- * The complete `_appConfig/app` document to write after applying `update` to `existing` (the
75
- * document as read in the writer's transaction; `null` or `undefined` when it does not exist). The
76
- * update's fields win, `existing` supplies the rest, and any field still missing comes from
77
- * DEFAULT_APP_CONFIG. An `undefined` update field changes nothing. Pure.
78
- *
79
- * A stored lever its schema refuses never blocks a save — a console typo must not disable the
80
- * maintenance switch. It is dropped, so the update's value replaces it when the update sends that
81
- * lever and its DEFAULT_APP_CONFIG value (what every reader already falls back to) otherwise, and it
82
- * is reported in `repairs`. A valid stored lever is carried as it is.
83
- *
84
- * Throws when the update itself would not parse, so an invalid document is never written.
85
- */
86
35
  export function mergeAppConfigUpdate(existing, update) {
87
36
  const stored = definedFields(existing ?? {});
88
37
  const repairs = [];
@@ -104,27 +53,16 @@ export function mergeAppConfigUpdate(existing, update) {
104
53
  }
105
54
  return { next: parsed.data, repairs };
106
55
  }
107
- /**
108
- * One operator lever off an unvalidated `_appConfig/app` snapshot (`null` or `undefined` when the
109
- * document is missing or not yet read): the stored value when its schema field accepts it, otherwise
110
- * the lever's DEFAULT_APP_CONFIG value — for an absent field and a refused one alike. Never throws.
111
- */
112
56
  export function readAppConfigLever(snapshot, lever) {
113
57
  const parsed = AppConfigSchema.shape[lever].safeParse(snapshot?.[lever]);
114
58
  return parsed.success && parsed.data !== undefined
115
59
  ? parsed.data
116
60
  : DEFAULT_APP_CONFIG[lever];
117
61
  }
118
- /**
119
- * True when an unvalidated `_appConfig/app` snapshot holds `lever` with a value its schema field
120
- * refuses — the value every reader passes over for the default. An absent field is not refused.
121
- * Never throws.
122
- */
123
62
  export function isAppConfigLeverRefused(snapshot, lever) {
124
63
  const stored = snapshot?.[lever];
125
64
  return stored !== undefined && !AppConfigSchema.shape[lever].safeParse(stored).success;
126
65
  }
127
- /** Every lever off an unvalidated snapshot, each through `readAppConfigLever`. Never throws. */
128
66
  export function readAppConfigLevers(snapshot) {
129
67
  const levers = {};
130
68
  for (const lever of APP_CONFIG_LEVER_KEYS) {
@@ -1 +1 @@
1
- {"version":3,"file":"app-config.js","sourceRoot":"","sources":["../../src/utils/app-config.ts"],"names":[],"mappings":"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","sourcesContent":["// The `_appConfig/app` singleton at rest, and the one rule each for writing it and reading it.\n//\n// WRITE. `mergeAppConfigUpdate(existing, update)`: the writer's update on top of the document it\n// read, any field that document lacks — and any lever it holds at a value its schema refuses —\n// taken from DEFAULT_APP_CONFIG, the whole result validated. A writer that runs first on a fresh\n// environment therefore still writes a complete, valid document rather than a partial one, and a\n// hand edit in the console that broke one lever never blocks a save of another: the merge resets it\n// and reports the repair with the value it replaced, which the writer records.\n//\n// READ. The stored document is untrusted — an operator can edit any field in the console into any\n// shape — and a config read must never take the product down by itself. `readAppConfigLever`\n// answers one lever at a time: the stored value when its schema field accepts it, otherwise the\n// lever's DEFAULT_APP_CONFIG value, so one bad field never costs the good ones. The server's cached\n// snapshot reader and the client's readers both read through it.\n\nimport { AppConfigSchema } from '../doc-schemas/system.js';\nimport type { AppConfig } from '../doc-schemas/system.js';\n\n/** Every operator lever of `_appConfig/app`, each at a value its schema field accepts. */\nexport type AppConfigLevers = Readonly<Required<AppConfig>>;\n\n/** The name of one operator lever. */\nexport type AppConfigLeverKey = keyof AppConfigLevers;\n\n/** Every lever name, derived from the document schema. */\nexport const APP_CONFIG_LEVER_KEYS = AppConfigSchema.keyof().options;\n\n/**\n * The document a fresh environment behaves as if it held, and the value each reader falls back to\n * for a missing or unreadable field: maintenance off, registration open, no banner.\n *\n * `appVersion` is `''` — no version has been published — so the version gate stays dormant until an\n * operator sets a real one through `updateAppConfig`, whose input refuses `''`.\n */\nexport const DEFAULT_APP_CONFIG: AppConfigLevers = Object.freeze({\n appVersion: '',\n maintenanceMode: false,\n maintenanceMessage: '',\n registrationEnabled: true,\n announcementMessage: '',\n});\n\n/**\n * The line shown while maintenance is on and the operator left `maintenanceMessage` blank — on the\n * maintenance screen and in the callable refusal alike.\n */\nexport const DEFAULT_MAINTENANCE_MESSAGE =\n 'Q-Sports is down for maintenance right now. We will be back shortly — thank you for your patience.';\n\n/**\n * The code the callable maintenance refusal is thrown with. `unavailable` is also what a real outage\n * produces, so the code alone never identifies the refusal — its details do.\n */\nexport const MAINTENANCE_REFUSAL_CODE = 'unavailable' as const;\n\n/** The `details.reason` the callable maintenance refusal carries. */\nexport const MAINTENANCE_REFUSAL_REASON = 'maintenance' as const;\n\n/** Structured details carried by the callable maintenance refusal. */\nexport interface MaintenanceRefusalDetails {\n readonly reason: typeof MAINTENANCE_REFUSAL_REASON;\n}\n\n// The refusal code as the server (`unavailable`) and the Firebase client SDK\n// (`functions/unavailable`) spell it.\nconst MAINTENANCE_REFUSAL_CODES: ReadonlySet<string> = new Set([\n MAINTENANCE_REFUSAL_CODE,\n `functions/${MAINTENANCE_REFUSAL_CODE}`,\n]);\n\n/** True when `details` is the maintenance refusal's structured details. */\nexport function isMaintenanceRefusalDetails(\n details: unknown,\n): details is MaintenanceRefusalDetails {\n if (!details || typeof details !== 'object') return false;\n return (details as Record<string, unknown>).reason === MAINTENANCE_REFUSAL_REASON;\n}\n\n/**\n * True when `err` is the callable maintenance refusal — an `unavailable` error in either spelling\n * whose details carry `reason: 'maintenance'`. Works on the server-side error and on the client-side\n * callable error alike, and is decided by the code and the details, never the message, so a genuine\n * outage is never mistaken for the designed refusal.\n */\nexport function isMaintenanceRefusalError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const candidate = err as { code?: unknown; details?: unknown };\n return (\n typeof candidate.code === 'string' &&\n MAINTENANCE_REFUSAL_CODES.has(candidate.code) &&\n isMaintenanceRefusalDetails(candidate.details)\n );\n}\n\nfunction definedFields(fields: Readonly<Record<string, unknown>>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== undefined));\n}\n\n/** A stored lever its schema field refused, with the raw value the document held. */\nexport interface AppConfigLeverRepair {\n readonly lever: AppConfigLeverKey;\n readonly storedValue: unknown;\n}\n\n/** The document a writer writes, and every stored lever the merge had to repair to write it. */\nexport interface AppConfigMerge {\n readonly next: AppConfig;\n readonly repairs: readonly AppConfigLeverRepair[];\n}\n\n/**\n * The complete `_appConfig/app` document to write after applying `update` to `existing` (the\n * document as read in the writer's transaction; `null` or `undefined` when it does not exist). The\n * update's fields win, `existing` supplies the rest, and any field still missing comes from\n * DEFAULT_APP_CONFIG. An `undefined` update field changes nothing. Pure.\n *\n * A stored lever its schema refuses never blocks a save — a console typo must not disable the\n * maintenance switch. It is dropped, so the update's value replaces it when the update sends that\n * lever and its DEFAULT_APP_CONFIG value (what every reader already falls back to) otherwise, and it\n * is reported in `repairs`. A valid stored lever is carried as it is.\n *\n * Throws when the update itself would not parse, so an invalid document is never written.\n */\nexport function mergeAppConfigUpdate(\n existing: Readonly<Record<string, unknown>> | null | undefined,\n update: Readonly<Partial<AppConfig>>,\n): AppConfigMerge {\n const stored = definedFields(existing ?? {});\n const repairs: AppConfigLeverRepair[] = [];\n for (const lever of APP_CONFIG_LEVER_KEYS) {\n if (!(lever in stored) || AppConfigSchema.shape[lever].safeParse(stored[lever]).success)\n continue;\n repairs.push({ lever, storedValue: stored[lever] });\n delete stored[lever];\n }\n const parsed = AppConfigSchema.safeParse({\n ...DEFAULT_APP_CONFIG,\n ...stored,\n ...definedFields(update),\n });\n if (!parsed.success) {\n const issue = parsed.error.issues[0];\n const field = issue?.path.join('.') || 'document';\n throw new Error(\n `_appConfig/app would not match its schema after this update (${field}: ${issue?.message ?? 'invalid'}). Nothing should be written.`,\n );\n }\n return { next: parsed.data, repairs };\n}\n\n/**\n * One operator lever off an unvalidated `_appConfig/app` snapshot (`null` or `undefined` when the\n * document is missing or not yet read): the stored value when its schema field accepts it, otherwise\n * the lever's DEFAULT_APP_CONFIG value — for an absent field and a refused one alike. Never throws.\n */\nexport function readAppConfigLever<L extends AppConfigLeverKey>(\n snapshot: Readonly<Record<string, unknown>> | null | undefined,\n lever: L,\n): AppConfigLevers[L] {\n const parsed = AppConfigSchema.shape[lever].safeParse(snapshot?.[lever]);\n return parsed.success && parsed.data !== undefined\n ? (parsed.data as AppConfigLevers[L])\n : DEFAULT_APP_CONFIG[lever];\n}\n\n/**\n * True when an unvalidated `_appConfig/app` snapshot holds `lever` with a value its schema field\n * refuses — the value every reader passes over for the default. An absent field is not refused.\n * Never throws.\n */\nexport function isAppConfigLeverRefused(\n snapshot: Readonly<Record<string, unknown>> | null | undefined,\n lever: AppConfigLeverKey,\n): boolean {\n const stored = snapshot?.[lever];\n return stored !== undefined && !AppConfigSchema.shape[lever].safeParse(stored).success;\n}\n\n/** Every lever off an unvalidated snapshot, each through `readAppConfigLever`. Never throws. */\nexport function readAppConfigLevers(\n snapshot: Readonly<Record<string, unknown>> | null | undefined,\n): AppConfigLevers {\n const levers: Partial<Record<AppConfigLeverKey, unknown>> = {};\n for (const lever of APP_CONFIG_LEVER_KEYS) {\n levers[lever] = readAppConfigLever(snapshot, lever);\n }\n return levers as AppConfigLevers;\n}\n"]}
1
+ {"version":3,"file":"app-config.js","sourceRoot":"","sources":["../../src/utils/app-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { AppConfigSchema } from '../doc-schemas/system.js';\nimport type { AppConfig } from '../doc-schemas/system.js';\n\nexport type AppConfigLevers = Readonly<Required<AppConfig>>;\n\nexport type AppConfigLeverKey = keyof AppConfigLevers;\n\nexport const APP_CONFIG_LEVER_KEYS = AppConfigSchema.keyof().options;\n\nexport const DEFAULT_APP_CONFIG: AppConfigLevers = Object.freeze({\n appVersion: '',\n maintenanceMode: false,\n maintenanceMessage: '',\n registrationEnabled: true,\n announcementMessage: '',\n});\n\nexport const DEFAULT_MAINTENANCE_MESSAGE =\n 'Q-Sports is down for maintenance right now. We will be back shortly — thank you for your patience.';\n\nexport const MAINTENANCE_REFUSAL_CODE = 'unavailable' as const;\n\nexport const MAINTENANCE_REFUSAL_REASON = 'maintenance' as const;\n\nexport interface MaintenanceRefusalDetails {\n readonly reason: typeof MAINTENANCE_REFUSAL_REASON;\n}\n\n// The refusal code as the server (`unavailable`) and the Firebase client SDK\n// (`functions/unavailable`) spell it.\nconst MAINTENANCE_REFUSAL_CODES: ReadonlySet<string> = new Set([\n MAINTENANCE_REFUSAL_CODE,\n `functions/${MAINTENANCE_REFUSAL_CODE}`,\n]);\n\nexport function isMaintenanceRefusalDetails(\n details: unknown,\n): details is MaintenanceRefusalDetails {\n if (!details || typeof details !== 'object') return false;\n return (details as Record<string, unknown>).reason === MAINTENANCE_REFUSAL_REASON;\n}\n\nexport function isMaintenanceRefusalError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const candidate = err as { code?: unknown; details?: unknown };\n return (\n typeof candidate.code === 'string' &&\n MAINTENANCE_REFUSAL_CODES.has(candidate.code) &&\n isMaintenanceRefusalDetails(candidate.details)\n );\n}\n\nfunction definedFields(fields: Readonly<Record<string, unknown>>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(fields).filter(([, value]) => value !== undefined));\n}\n\nexport interface AppConfigLeverRepair {\n readonly lever: AppConfigLeverKey;\n readonly storedValue: unknown;\n}\n\nexport interface AppConfigMerge {\n readonly next: AppConfig;\n readonly repairs: readonly AppConfigLeverRepair[];\n}\n\nexport function mergeAppConfigUpdate(\n existing: Readonly<Record<string, unknown>> | null | undefined,\n update: Readonly<Partial<AppConfig>>,\n): AppConfigMerge {\n const stored = definedFields(existing ?? {});\n const repairs: AppConfigLeverRepair[] = [];\n for (const lever of APP_CONFIG_LEVER_KEYS) {\n if (!(lever in stored) || AppConfigSchema.shape[lever].safeParse(stored[lever]).success)\n continue;\n repairs.push({ lever, storedValue: stored[lever] });\n delete stored[lever];\n }\n const parsed = AppConfigSchema.safeParse({\n ...DEFAULT_APP_CONFIG,\n ...stored,\n ...definedFields(update),\n });\n if (!parsed.success) {\n const issue = parsed.error.issues[0];\n const field = issue?.path.join('.') || 'document';\n throw new Error(\n `_appConfig/app would not match its schema after this update (${field}: ${issue?.message ?? 'invalid'}). Nothing should be written.`,\n );\n }\n return { next: parsed.data, repairs };\n}\n\nexport function readAppConfigLever<L extends AppConfigLeverKey>(\n snapshot: Readonly<Record<string, unknown>> | null | undefined,\n lever: L,\n): AppConfigLevers[L] {\n const parsed = AppConfigSchema.shape[lever].safeParse(snapshot?.[lever]);\n return parsed.success && parsed.data !== undefined\n ? (parsed.data as AppConfigLevers[L])\n : DEFAULT_APP_CONFIG[lever];\n}\n\nexport function isAppConfigLeverRefused(\n snapshot: Readonly<Record<string, unknown>> | null | undefined,\n lever: AppConfigLeverKey,\n): boolean {\n const stored = snapshot?.[lever];\n return stored !== undefined && !AppConfigSchema.shape[lever].safeParse(stored).success;\n}\n\nexport function readAppConfigLevers(\n snapshot: Readonly<Record<string, unknown>> | null | undefined,\n): AppConfigLevers {\n const levers: Partial<Record<AppConfigLeverKey, unknown>> = {};\n for (const lever of APP_CONFIG_LEVER_KEYS) {\n levers[lever] = readAppConfigLever(snapshot, lever);\n }\n return levers as AppConfigLevers;\n}\n"]}
@@ -1,11 +1,4 @@
1
1
  export declare function normalizeDisplayName(displayName: string): string;
2
- /**
3
- * The `reservedDisplayNames` document id for a display name. Uniqueness is case-insensitive, so the
4
- * key is built from the lowercase form. It is percent-encoded because a name may hold a `/`, which
5
- * a document id cannot, and prefixed because percent-encoding leaves `_` and `.` alone — without
6
- * the prefix the name `__a__` would be an id Firestore reserves (`__.*__`) and rejects.
7
- */
8
2
  export declare function toReservedDisplayNameKey(displayName: string): string;
9
- /** The value stored in `displayName_lowercase`, which powers prefix search and uniqueness checks. */
10
3
  export declare function toDisplayNameLowercase(displayName: string): string;
11
4
  //# sourceMappingURL=display-name.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"display-name.d.ts","sourceRoot":"","sources":["../../src/utils/display-name.ts"],"names":[],"mappings":"AAEA,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAID;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED,qGAAqG;AACrG,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAElE"}
1
+ {"version":3,"file":"display-name.d.ts","sourceRoot":"","sources":["../../src/utils/display-name.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAID,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAElE"}
@@ -1,18 +1,10 @@
1
- // Display-name normalization shared by every writer of `displayName` / `displayName_lowercase`.
2
1
  export function normalizeDisplayName(displayName) {
3
2
  return displayName.trim();
4
3
  }
5
4
  const RESERVED_DISPLAY_NAME_KEY_PREFIX = 'name_';
6
- /**
7
- * The `reservedDisplayNames` document id for a display name. Uniqueness is case-insensitive, so the
8
- * key is built from the lowercase form. It is percent-encoded because a name may hold a `/`, which
9
- * a document id cannot, and prefixed because percent-encoding leaves `_` and `.` alone — without
10
- * the prefix the name `__a__` would be an id Firestore reserves (`__.*__`) and rejects.
11
- */
12
5
  export function toReservedDisplayNameKey(displayName) {
13
6
  return RESERVED_DISPLAY_NAME_KEY_PREFIX + encodeURIComponent(toDisplayNameLowercase(displayName));
14
7
  }
15
- /** The value stored in `displayName_lowercase`, which powers prefix search and uniqueness checks. */
16
8
  export function toDisplayNameLowercase(displayName) {
17
9
  return normalizeDisplayName(displayName).toLowerCase();
18
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"display-name.js","sourceRoot":"","sources":["../../src/utils/display-name.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAEhG,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,OAAO,WAAW,CAAC,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,gCAAgC,GAAG,OAAO,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,WAAmB;IAC1D,OAAO,gCAAgC,GAAG,kBAAkB,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC,CAAC;AACpG,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,sBAAsB,CAAC,WAAmB;IACxD,OAAO,oBAAoB,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;AACzD,CAAC","sourcesContent":["// Display-name normalization shared by every writer of `displayName` / `displayName_lowercase`.\n\nexport function normalizeDisplayName(displayName: string): string {\n return displayName.trim();\n}\n\nconst RESERVED_DISPLAY_NAME_KEY_PREFIX = 'name_';\n\n/**\n * The `reservedDisplayNames` document id for a display name. Uniqueness is case-insensitive, so the\n * key is built from the lowercase form. It is percent-encoded because a name may hold a `/`, which\n * a document id cannot, and prefixed because percent-encoding leaves `_` and `.` alone — without\n * the prefix the name `__a__` would be an id Firestore reserves (`__.*__`) and rejects.\n */\nexport function toReservedDisplayNameKey(displayName: string): string {\n return RESERVED_DISPLAY_NAME_KEY_PREFIX + encodeURIComponent(toDisplayNameLowercase(displayName));\n}\n\n/** The value stored in `displayName_lowercase`, which powers prefix search and uniqueness checks. */\nexport function toDisplayNameLowercase(displayName: string): string {\n return normalizeDisplayName(displayName).toLowerCase();\n}\n"]}
1
+ {"version":3,"file":"display-name.js","sourceRoot":"","sources":["../../src/utils/display-name.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,OAAO,WAAW,CAAC,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,gCAAgC,GAAG,OAAO,CAAC;AAEjD,MAAM,UAAU,wBAAwB,CAAC,WAAmB;IAC1D,OAAO,gCAAgC,GAAG,kBAAkB,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC,CAAC;AACpG,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,WAAmB;IACxD,OAAO,oBAAoB,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;AACzD,CAAC","sourcesContent":["export function normalizeDisplayName(displayName: string): string {\n return displayName.trim();\n}\n\nconst RESERVED_DISPLAY_NAME_KEY_PREFIX = 'name_';\n\nexport function toReservedDisplayNameKey(displayName: string): string {\n return RESERVED_DISPLAY_NAME_KEY_PREFIX + encodeURIComponent(toDisplayNameLowercase(displayName));\n}\n\nexport function toDisplayNameLowercase(displayName: string): string {\n return normalizeDisplayName(displayName).toLowerCase();\n}\n"]}
@@ -8,4 +8,5 @@ export * from './schedules.js';
8
8
  export * from './team-member-actions.js';
9
9
  export * from './league-mode.js';
10
10
  export * from './league-joining.js';
11
+ export * from './stats-operation-request.js';
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC"}
@@ -8,4 +8,5 @@ export * from './schedules.js';
8
8
  export * from './team-member-actions.js';
9
9
  export * from './league-mode.js';
10
10
  export * from './league-joining.js';
11
+ export * from './stats-operation-request.js';
11
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './display-name.js';\nexport * from './app-config.js';\nexport * from './league-calendar.js';\nexport * from './team-creation.js';\nexport * from './account-status.js';\nexport * from './league-join-warning.js';\nexport * from './schedules.js';\nexport * from './team-member-actions.js';\nexport * from './league-mode.js';\nexport * from './league-joining.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC","sourcesContent":["export * from './display-name.js';\nexport * from './app-config.js';\nexport * from './league-calendar.js';\nexport * from './team-creation.js';\nexport * from './account-status.js';\nexport * from './league-join-warning.js';\nexport * from './schedules.js';\nexport * from './team-member-actions.js';\nexport * from './league-mode.js';\nexport * from './league-joining.js';\nexport * from './stats-operation-request.js';\n"]}
@@ -1,16 +1,5 @@
1
- /** The calendar date an instant falls on in LEAGUE_TIME_ZONE. */
2
1
  export declare function toLeagueDayKey(epochMs: number): string;
3
- /**
4
- * The calendar date `days` days after `dayKey` (before it, when negative). Pure calendar arithmetic
5
- * on the date itself, so no time zone or daylight-saving change moves it.
6
- */
7
2
  export declare function addCalendarDays(dayKey: string, days: number): string;
8
- /** The time of day an instant falls at in LEAGUE_TIME_ZONE, as `HH:MM` on a 24-hour clock. */
9
3
  export declare function toLeagueTimeOfDay(epochMs: number): string;
10
- /**
11
- * The instant a calendar day and a time of day (`HH:MM`, 24-hour) name in LEAGUE_TIME_ZONE, in epoch
12
- * milliseconds. The zone's offset is read at the instant itself, so a day on either side of a
13
- * daylight-saving change reads its own offset. Throws on a day or a time that is not one.
14
- */
15
4
  export declare function leagueInstantOf(dayKey: string, timeOfDay: string): number;
16
5
  //# sourceMappingURL=league-calendar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"league-calendar.d.ts","sourceRoot":"","sources":["../../src/utils/league-calendar.ts"],"names":[],"mappings":"AAkBA,iEAAiE;AACjE,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMpE;AAmCD,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAmBzE"}
1
+ {"version":3,"file":"league-calendar.d.ts","sourceRoot":"","sources":["../../src/utils/league-calendar.ts"],"names":[],"mappings":"AAYA,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMpE;AAkCD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAwBzE"}
@@ -1,8 +1,3 @@
1
- // Calendar days and times of day in the leagues' own time zone. A league's dates and a game's `dayKey`
2
- // are calendar dates with no time or zone (`YYYY-MM-DD`), so "today" is read in LEAGUE_TIME_ZONE and
3
- // every comparison is between two calendar dates, never between instants. A game's start is an
4
- // instant, entered and shown as a day and a time of day (`HH:MM`) in LEAGUE_TIME_ZONE, whatever the
5
- // zone of the browser it is entered in.
6
1
  import { LEAGUE_TIME_ZONE } from '../constants/business.js';
7
2
  // `en-CA` formats a date as `YYYY-MM-DD`, the stored calendar-date shape.
8
3
  const LEAGUE_DAY_FORMAT = new Intl.DateTimeFormat('en-CA', {
@@ -12,14 +7,9 @@ const LEAGUE_DAY_FORMAT = new Intl.DateTimeFormat('en-CA', {
12
7
  day: '2-digit',
13
8
  });
14
9
  const DAY_MS = 24 * 60 * 60 * 1000;
15
- /** The calendar date an instant falls on in LEAGUE_TIME_ZONE. */
16
10
  export function toLeagueDayKey(epochMs) {
17
11
  return LEAGUE_DAY_FORMAT.format(new Date(epochMs));
18
12
  }
19
- /**
20
- * The calendar date `days` days after `dayKey` (before it, when negative). Pure calendar arithmetic
21
- * on the date itself, so no time zone or daylight-saving change moves it.
22
- */
23
13
  export function addCalendarDays(dayKey, days) {
24
14
  const day = new Date(`${dayKey}T00:00:00.000Z`);
25
15
  if (Number.isNaN(day.getTime())) {
@@ -27,7 +17,7 @@ export function addCalendarDays(dayKey, days) {
27
17
  }
28
18
  return new Date(day.getTime() + days * DAY_MS).toISOString().slice(0, 10);
29
19
  }
30
- // Every part of an instant's wall-clock reading in LEAGUE_TIME_ZONE. `h23` keeps midnight at hour 0.
20
+ // `h23` keeps midnight at hour 0.
31
21
  const LEAGUE_WALL_CLOCK_FORMAT = new Intl.DateTimeFormat('en-US', {
32
22
  timeZone: LEAGUE_TIME_ZONE,
33
23
  hourCycle: 'h23',
@@ -40,7 +30,6 @@ const LEAGUE_WALL_CLOCK_FORMAT = new Intl.DateTimeFormat('en-US', {
40
30
  });
41
31
  const CALENDAR_DAY_SHAPE = /^(\d{4})-(\d{2})-(\d{2})$/;
42
32
  const TIME_OF_DAY_SHAPE = /^([01]\d|2[0-3]):([0-5]\d)$/;
43
- /** The instant's wall-clock reading in LEAGUE_TIME_ZONE, written as if that reading were UTC. */
44
33
  function leagueWallClockAsUtc(epochMs) {
45
34
  const parts = Object.fromEntries(LEAGUE_WALL_CLOCK_FORMAT.formatToParts(new Date(epochMs)).map((part) => [
46
35
  part.type,
@@ -48,18 +37,12 @@ function leagueWallClockAsUtc(epochMs) {
48
37
  ]));
49
38
  return Date.UTC(Number(parts.year), Number(parts.month) - 1, Number(parts.day), Number(parts.hour), Number(parts.minute), Number(parts.second));
50
39
  }
51
- /** The time of day an instant falls at in LEAGUE_TIME_ZONE, as `HH:MM` on a 24-hour clock. */
52
40
  export function toLeagueTimeOfDay(epochMs) {
53
41
  const wallClock = new Date(leagueWallClockAsUtc(epochMs));
54
42
  const hours = String(wallClock.getUTCHours()).padStart(2, '0');
55
43
  const minutes = String(wallClock.getUTCMinutes()).padStart(2, '0');
56
44
  return `${hours}:${minutes}`;
57
45
  }
58
- /**
59
- * The instant a calendar day and a time of day (`HH:MM`, 24-hour) name in LEAGUE_TIME_ZONE, in epoch
60
- * milliseconds. The zone's offset is read at the instant itself, so a day on either side of a
61
- * daylight-saving change reads its own offset. Throws on a day or a time that is not one.
62
- */
63
46
  export function leagueInstantOf(dayKey, timeOfDay) {
64
47
  const day = CALENDAR_DAY_SHAPE.exec(dayKey);
65
48
  const time = TIME_OF_DAY_SHAPE.exec(timeOfDay);
@@ -72,6 +55,11 @@ export function leagueInstantOf(dayKey, timeOfDay) {
72
55
  // The offset at the wall-clock reading taken as UTC is within a day of the right one; read again at
73
56
  // the instant that offset gives, so a reading on the other side of a change settles on its own.
74
57
  const firstGuess = wallClock - (leagueWallClockAsUtc(wallClock) - wallClock);
75
- return wallClock - (leagueWallClockAsUtc(firstGuess) - firstGuess);
58
+ const instant = wallClock - (leagueWallClockAsUtc(firstGuess) - firstGuess);
59
+ // A reading the clocks skip forward over settles on another hour; only a real one reads back.
60
+ if (toLeagueDayKey(instant) !== dayKey || toLeagueTimeOfDay(instant) !== timeOfDay) {
61
+ throw new RangeError(`Not a time the league's clocks show: '${dayKey}' '${timeOfDay}'.`);
62
+ }
63
+ return instant;
76
64
  }
77
65
  //# sourceMappingURL=league-calendar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"league-calendar.js","sourceRoot":"","sources":["../../src/utils/league-calendar.ts"],"names":[],"mappings":"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","sourcesContent":["// Calendar days and times of day in the leagues' own time zone. A league's dates and a game's `dayKey`\n// are calendar dates with no time or zone (`YYYY-MM-DD`), so \"today\" is read in LEAGUE_TIME_ZONE and\n// every comparison is between two calendar dates, never between instants. A game's start is an\n// instant, entered and shown as a day and a time of day (`HH:MM`) in LEAGUE_TIME_ZONE, whatever the\n// zone of the browser it is entered in.\n\nimport { LEAGUE_TIME_ZONE } from '../constants/business.js';\n\n// `en-CA` formats a date as `YYYY-MM-DD`, the stored calendar-date shape.\nconst LEAGUE_DAY_FORMAT = new Intl.DateTimeFormat('en-CA', {\n timeZone: LEAGUE_TIME_ZONE,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n});\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\n/** The calendar date an instant falls on in LEAGUE_TIME_ZONE. */\nexport function toLeagueDayKey(epochMs: number): string {\n return LEAGUE_DAY_FORMAT.format(new Date(epochMs));\n}\n\n/**\n * The calendar date `days` days after `dayKey` (before it, when negative). Pure calendar arithmetic\n * on the date itself, so no time zone or daylight-saving change moves it.\n */\nexport function addCalendarDays(dayKey: string, days: number): string {\n const day = new Date(`${dayKey}T00:00:00.000Z`);\n if (Number.isNaN(day.getTime())) {\n throw new RangeError(`Not a calendar date: '${dayKey}'.`);\n }\n return new Date(day.getTime() + days * DAY_MS).toISOString().slice(0, 10);\n}\n\n// Every part of an instant's wall-clock reading in LEAGUE_TIME_ZONE. `h23` keeps midnight at hour 0.\nconst LEAGUE_WALL_CLOCK_FORMAT = new Intl.DateTimeFormat('en-US', {\n timeZone: LEAGUE_TIME_ZONE,\n hourCycle: 'h23',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n});\n\nconst CALENDAR_DAY_SHAPE = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst TIME_OF_DAY_SHAPE = /^([01]\\d|2[0-3]):([0-5]\\d)$/;\n\n/** The instant's wall-clock reading in LEAGUE_TIME_ZONE, written as if that reading were UTC. */\nfunction leagueWallClockAsUtc(epochMs: number): number {\n const parts = Object.fromEntries(\n LEAGUE_WALL_CLOCK_FORMAT.formatToParts(new Date(epochMs)).map((part) => [\n part.type,\n part.value,\n ]),\n );\n return Date.UTC(\n Number(parts.year),\n Number(parts.month) - 1,\n Number(parts.day),\n Number(parts.hour),\n Number(parts.minute),\n Number(parts.second),\n );\n}\n\n/** The time of day an instant falls at in LEAGUE_TIME_ZONE, as `HH:MM` on a 24-hour clock. */\nexport function toLeagueTimeOfDay(epochMs: number): string {\n const wallClock = new Date(leagueWallClockAsUtc(epochMs));\n const hours = String(wallClock.getUTCHours()).padStart(2, '0');\n const minutes = String(wallClock.getUTCMinutes()).padStart(2, '0');\n return `${hours}:${minutes}`;\n}\n\n/**\n * The instant a calendar day and a time of day (`HH:MM`, 24-hour) name in LEAGUE_TIME_ZONE, in epoch\n * milliseconds. The zone's offset is read at the instant itself, so a day on either side of a\n * daylight-saving change reads its own offset. Throws on a day or a time that is not one.\n */\nexport function leagueInstantOf(dayKey: string, timeOfDay: string): number {\n const day = CALENDAR_DAY_SHAPE.exec(dayKey);\n const time = TIME_OF_DAY_SHAPE.exec(timeOfDay);\n if (!day || !time)\n throw new RangeError(`Not a calendar day and time of day: '${dayKey}' '${timeOfDay}'.`);\n const wallClock = Date.UTC(\n Number(day[1]),\n Number(day[2]) - 1,\n Number(day[3]),\n Number(time[1]),\n Number(time[2]),\n );\n if (new Date(wallClock).toISOString().slice(0, 10) !== dayKey) {\n throw new RangeError(`Not a calendar day: '${dayKey}'.`);\n }\n // The offset at the wall-clock reading taken as UTC is within a day of the right one; read again at\n // the instant that offset gives, so a reading on the other side of a change settles on its own.\n const firstGuess = wallClock - (leagueWallClockAsUtc(wallClock) - wallClock);\n return wallClock - (leagueWallClockAsUtc(firstGuess) - firstGuess);\n}\n"]}
1
+ {"version":3,"file":"league-calendar.js","sourceRoot":"","sources":["../../src/utils/league-calendar.ts"],"names":[],"mappings":"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","sourcesContent":["import { LEAGUE_TIME_ZONE } from '../constants/business.js';\n\n// `en-CA` formats a date as `YYYY-MM-DD`, the stored calendar-date shape.\nconst LEAGUE_DAY_FORMAT = new Intl.DateTimeFormat('en-CA', {\n timeZone: LEAGUE_TIME_ZONE,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n});\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nexport function toLeagueDayKey(epochMs: number): string {\n return LEAGUE_DAY_FORMAT.format(new Date(epochMs));\n}\n\nexport function addCalendarDays(dayKey: string, days: number): string {\n const day = new Date(`${dayKey}T00:00:00.000Z`);\n if (Number.isNaN(day.getTime())) {\n throw new RangeError(`Not a calendar date: '${dayKey}'.`);\n }\n return new Date(day.getTime() + days * DAY_MS).toISOString().slice(0, 10);\n}\n\n// `h23` keeps midnight at hour 0.\nconst LEAGUE_WALL_CLOCK_FORMAT = new Intl.DateTimeFormat('en-US', {\n timeZone: LEAGUE_TIME_ZONE,\n hourCycle: 'h23',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n});\n\nconst CALENDAR_DAY_SHAPE = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst TIME_OF_DAY_SHAPE = /^([01]\\d|2[0-3]):([0-5]\\d)$/;\n\nfunction leagueWallClockAsUtc(epochMs: number): number {\n const parts = Object.fromEntries(\n LEAGUE_WALL_CLOCK_FORMAT.formatToParts(new Date(epochMs)).map((part) => [\n part.type,\n part.value,\n ]),\n );\n return Date.UTC(\n Number(parts.year),\n Number(parts.month) - 1,\n Number(parts.day),\n Number(parts.hour),\n Number(parts.minute),\n Number(parts.second),\n );\n}\n\nexport function toLeagueTimeOfDay(epochMs: number): string {\n const wallClock = new Date(leagueWallClockAsUtc(epochMs));\n const hours = String(wallClock.getUTCHours()).padStart(2, '0');\n const minutes = String(wallClock.getUTCMinutes()).padStart(2, '0');\n return `${hours}:${minutes}`;\n}\n\nexport function leagueInstantOf(dayKey: string, timeOfDay: string): number {\n const day = CALENDAR_DAY_SHAPE.exec(dayKey);\n const time = TIME_OF_DAY_SHAPE.exec(timeOfDay);\n if (!day || !time)\n throw new RangeError(`Not a calendar day and time of day: '${dayKey}' '${timeOfDay}'.`);\n const wallClock = Date.UTC(\n Number(day[1]),\n Number(day[2]) - 1,\n Number(day[3]),\n Number(time[1]),\n Number(time[2]),\n );\n if (new Date(wallClock).toISOString().slice(0, 10) !== dayKey) {\n throw new RangeError(`Not a calendar day: '${dayKey}'.`);\n }\n // The offset at the wall-clock reading taken as UTC is within a day of the right one; read again at\n // the instant that offset gives, so a reading on the other side of a change settles on its own.\n const firstGuess = wallClock - (leagueWallClockAsUtc(wallClock) - wallClock);\n const instant = wallClock - (leagueWallClockAsUtc(firstGuess) - firstGuess);\n // A reading the clocks skip forward over settles on another hour; only a real one reads back.\n if (toLeagueDayKey(instant) !== dayKey || toLeagueTimeOfDay(instant) !== timeOfDay) {\n throw new RangeError(`Not a time the league's clocks show: '${dayKey}' '${timeOfDay}'.`);\n }\n return instant;\n}\n"]}
@@ -18,7 +18,6 @@ export type LeagueJoinWarningAction = (typeof LEAGUE_JOIN_WARNING_ACTION_KEYS)[n
18
18
  export declare const LEAGUE_JOIN_WARNING_PERSPECTIVE_KEYS: readonly ["self", "other"];
19
19
  export type LeagueJoinWarningPerspective = (typeof LEAGUE_JOIN_WARNING_PERSPECTIVE_KEYS)[number];
20
20
  export declare const LEAGUE_JOIN_WARNING_PERSPECTIVE_BY_ACTION: Readonly<Record<LeagueJoinWarningAction, LeagueJoinWarningPerspective>>;
21
- /** Where the person stands in the league, as the server read it. */
22
21
  export interface LeagueJoinWarningFacts {
23
22
  memberships: readonly {
24
23
  teamId: string;
@@ -43,10 +42,6 @@ export declare const leagueJoinWarningFindingSchema: z.ZodObject<{
43
42
  teamId: z.ZodNullable<z.ZodString>;
44
43
  }, z.core.$strict>;
45
44
  export type LeagueJoinWarningFinding = z.infer<typeof leagueJoinWarningFindingSchema>;
46
- /**
47
- * Every place the person stands in the league, the acted-on item left out, in state order and then
48
- * team order. An empty result means no warning is shown.
49
- */
50
45
  export declare function computeLeagueJoinWarning(facts: LeagueJoinWarningFacts, actedOn: LeagueJoinWarningActedOn | null): LeagueJoinWarningFinding[];
51
46
  export declare const LEAGUE_JOIN_WARNING_COPY: {
52
47
  readonly title: "Already in this league";
@@ -76,15 +71,9 @@ export declare const LEAGUE_JOIN_WARNING_COPY: {
76
71
  };
77
72
  };
78
73
  export interface LeagueJoinWarningText {
79
- /** One sentence per finding, in the findings' order. */
80
74
  lines: string[];
81
75
  question: string;
82
76
  }
83
- /**
84
- * The dialog's words for a warning. `teamName` resolves a finding's team id to its display name;
85
- * `personName` names the person for a door acting on someone else. Empty findings are no warning,
86
- * and a caller shows no dialog for them.
87
- */
88
77
  export declare function formatLeagueJoinWarning(args: {
89
78
  action: LeagueJoinWarningAction;
90
79
  findings: readonly LeagueJoinWarningFinding[];
@@ -1 +1 @@
1
- {"version":3,"file":"league-join-warning.d.ts","sourceRoot":"","sources":["../../src/utils/league-join-warning.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,8BAA8B,mFAKjC,CAAC;AACX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,8BAA8B,CAAC,CAAC,MAAM,CAAC,CAAC;AAIrF,eAAO,MAAM,iCAAiC,mEAIpC,CAAC;AACX,MAAM,MAAM,4BAA4B,GAAG,CAAC,OAAO,iCAAiC,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9F,eAAO,MAAM,8BAA8B;;;;;;;;4BAczC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAItF,eAAO,MAAM,+BAA+B,mKASlC,CAAC;AACX,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,+BAA+B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvF,eAAO,MAAM,oCAAoC,4BAA6B,CAAC;AAC/E,MAAM,MAAM,4BAA4B,GAAG,CAAC,OAAO,oCAAoC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjG,eAAO,MAAM,yCAAyC,EAAE,QAAQ,CAC9D,MAAM,CAAC,uBAAuB,EAAE,4BAA4B,CAAC,CAU9D,CAAC;AAEF,oEAAoE;AACpE,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,SAAS;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,mBAAmB,EAAE,SAAS;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC9E,kBAAkB,EAAE,SAAS;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5E,eAAe,EAAE,OAAO,CAAC;CAC1B;AAGD,eAAO,MAAM,8BAA8B;;;;;;;;kBAEhC,CAAC;AACZ,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,sBAAsB,EAC7B,OAAO,EAAE,wBAAwB,GAAG,IAAI,GACvC,wBAAwB,EAAE,CAqC5B;AAED,eAAO,MAAM,wBAAwB;;;;;oCAMd,MAAM;gDACM,MAAM;+CACP,MAAM;;;;sCAKf,MAAM,YAAY,MAAM;kDACZ,MAAM,YAAY,MAAM;iDAEzB,MAAM,YAAY,MAAM;+CAE1B,MAAM;;;;2CAMD,MAAM;0CACP,MAAM;;yCAGP,MAAM;4CACH,MAAM;0CACR,MAAM;2CACL,MAAM;;CAEnC,CAAC;AAEX,MAAM,WAAW,qBAAqB;IACpC,wDAAwD;IACxD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,MAAM,EAAE,uBAAuB,CAAC;IAChC,QAAQ,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAC9C,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB,GAAG,qBAAqB,CAUxB"}
1
+ {"version":3,"file":"league-join-warning.d.ts","sourceRoot":"","sources":["../../src/utils/league-join-warning.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,8BAA8B,mFAKjC,CAAC;AACX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,8BAA8B,CAAC,CAAC,MAAM,CAAC,CAAC;AAErF,eAAO,MAAM,iCAAiC,mEAIpC,CAAC;AACX,MAAM,MAAM,4BAA4B,GAAG,CAAC,OAAO,iCAAiC,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9F,eAAO,MAAM,8BAA8B;;;;;;;;4BAczC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF,eAAO,MAAM,+BAA+B,mKASlC,CAAC;AACX,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,+BAA+B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvF,eAAO,MAAM,oCAAoC,4BAA6B,CAAC;AAC/E,MAAM,MAAM,4BAA4B,GAAG,CAAC,OAAO,oCAAoC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjG,eAAO,MAAM,yCAAyC,EAAE,QAAQ,CAC9D,MAAM,CAAC,uBAAuB,EAAE,4BAA4B,CAAC,CAU9D,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,SAAS;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,mBAAmB,EAAE,SAAS;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC9E,kBAAkB,EAAE,SAAS;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5E,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,8BAA8B;;;;;;;;kBAEhC,CAAC;AACZ,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,sBAAsB,EAC7B,OAAO,EAAE,wBAAwB,GAAG,IAAI,GACvC,wBAAwB,EAAE,CAqC5B;AAED,eAAO,MAAM,wBAAwB;;;;;oCAKd,MAAM;gDACM,MAAM;+CACP,MAAM;;;;sCAIf,MAAM,YAAY,MAAM;kDACZ,MAAM,YAAY,MAAM;iDAEzB,MAAM,YAAY,MAAM;+CAE1B,MAAM;;;;2CAKD,MAAM;0CACP,MAAM;;yCAGP,MAAM;4CACH,MAAM;0CACR,MAAM;2CACL,MAAM;;CAEnC,CAAC;AAEX,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,MAAM,EAAE,uBAAuB,CAAC;IAChC,QAAQ,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAC9C,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB,GAAG,qBAAqB,CAUxB"}
@@ -1,25 +1,12 @@
1
- // The join warning: before anyone puts a person on a team in a league, or starts
2
- // their way onto one, they see every place that person already stands there. It warns and never
3
- // blocks — confirm proceeds, cancel does nothing, and no server check refuses for it.
4
- //
5
- // One decision serves every door: `computeLeagueJoinWarning` is the whole rule, and the one reader
6
- // of the person's standing is the server core behind `getLeagueJoinWarning` /
7
- // `adminGetLeagueJoinWarning`, because another person's pending requests, invitations, and signup
8
- // are not readable from the client. What the dialog says is `LEAGUE_JOIN_WARNING_COPY`, through
9
- // `formatLeagueJoinWarning` (RULE-STD-ARCH-102, RULE-STD-ENG-005). The acted-on item and a finding cross the wire, so
10
- // each is declared once, as its schema, and its type is inferred from it.
11
1
  import { z } from 'zod';
12
2
  import { teamIdSchema } from '../doc-schemas/atoms.js';
13
3
  import { teamInvitationIdSchema, teamJoinRequestIdSchema } from '../schemas/atoms.js';
14
- // The four places a person can stand in a league.
15
4
  export const LEAGUE_JOIN_WARNING_STATE_KEYS = [
16
5
  'onTeam',
17
6
  'pendingJoinRequest',
18
7
  'pendingInvitation',
19
8
  'freeAgentSignup',
20
9
  ];
21
- // The item a door acts on, which the warning never names: accepting a team's invitation does not
22
- // warn about that invitation.
23
10
  export const LEAGUE_JOIN_WARNING_ACTED_ON_KEYS = [
24
11
  'teamInvitation',
25
12
  'teamJoinRequest',
@@ -40,8 +27,6 @@ export const leagueJoinWarningActedOnSchema = z.discriminatedUnion('kind', [
40
27
  .strict(),
41
28
  z.object({ kind: z.literal('leagueFreeAgent') }).strict(),
42
29
  ]);
43
- // Every door that shows the warning. Each is phrased either for the person acting on their own
44
- // behalf or for someone acting on them.
45
30
  export const LEAGUE_JOIN_WARNING_ACTION_KEYS = [
46
31
  'createTeam',
47
32
  'acceptInvitation',
@@ -63,14 +48,9 @@ export const LEAGUE_JOIN_WARNING_PERSPECTIVE_BY_ACTION = {
63
48
  assignFreeAgent: 'other',
64
49
  closedLeagueLink: 'other',
65
50
  };
66
- // One place the person stands. `teamId` is null only for a free-agent signup.
67
51
  export const leagueJoinWarningFindingSchema = z
68
52
  .object({ state: z.enum(LEAGUE_JOIN_WARNING_STATE_KEYS), teamId: teamIdSchema.nullable() })
69
53
  .strict();
70
- /**
71
- * Every place the person stands in the league, the acted-on item left out, in state order and then
72
- * team order. An empty result means no warning is shown.
73
- */
74
54
  export function computeLeagueJoinWarning(facts, actedOn) {
75
55
  const byTeam = (left, right) => (left.teamId ?? '').localeCompare(right.teamId ?? '');
76
56
  const onTeam = facts.memberships.map((membership) => ({
@@ -99,21 +79,18 @@ export const LEAGUE_JOIN_WARNING_COPY = {
99
79
  title: 'Already in this league',
100
80
  confirmLabel: 'Continue',
101
81
  cancelLabel: 'Cancel',
102
- // What the person acting on their own behalf is told, per state found.
103
82
  self: {
104
83
  onTeam: (teamName) => `You are already on ${teamName}.`,
105
84
  pendingJoinRequest: (teamName) => `You have a request waiting with ${teamName}.`,
106
85
  pendingInvitation: (teamName) => `You have an invitation waiting from ${teamName}.`,
107
86
  freeAgentSignup: () => 'You are signed up as a free agent in this league.',
108
87
  },
109
- // What someone acting on the person is told, per state found.
110
88
  other: {
111
89
  onTeam: (personName, teamName) => `${personName} is already on ${teamName}.`,
112
90
  pendingJoinRequest: (personName, teamName) => `${personName} has asked to join ${teamName}.`,
113
91
  pendingInvitation: (personName, teamName) => `${personName} has an invitation waiting from ${teamName}.`,
114
92
  freeAgentSignup: (personName) => `${personName} is signed up as a free agent in this league.`,
115
93
  },
116
- // The closing question, per door. `targetTeamName` is ignored by the doors that have no team.
117
94
  question: {
118
95
  createTeam: () => 'Do you still want to create a new team?',
119
96
  acceptInvitation: (targetTeamName) => `Do you still want to join ${targetTeamName}?`,
@@ -125,11 +102,6 @@ export const LEAGUE_JOIN_WARNING_COPY = {
125
102
  closedLeagueLink: (targetTeamName) => `Link them to ${targetTeamName} anyway?`,
126
103
  },
127
104
  };
128
- /**
129
- * The dialog's words for a warning. `teamName` resolves a finding's team id to its display name;
130
- * `personName` names the person for a door acting on someone else. Empty findings are no warning,
131
- * and a caller shows no dialog for them.
132
- */
133
105
  export function formatLeagueJoinWarning(args) {
134
106
  const perspective = LEAGUE_JOIN_WARNING_PERSPECTIVE_BY_ACTION[args.action];
135
107
  const lines = args.findings.map((finding) => {