@ttt-productions/q-core 0.1.19 → 0.1.21

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 (201) hide show
  1. package/dist/constants/business.js +2 -2
  2. package/dist/constants/business.js.map +1 -1
  3. package/dist/constants/media.js +1 -1
  4. package/dist/constants/media.js.map +1 -1
  5. package/dist/constants/sports.js +1 -1
  6. package/dist/constants/sports.js.map +1 -1
  7. package/dist/constants/telemetry.js +3 -3
  8. package/dist/constants/telemetry.js.map +1 -1
  9. package/dist/doc-schemas/admin-notifications.js +3 -3
  10. package/dist/doc-schemas/admin-notifications.js.map +1 -1
  11. package/dist/doc-schemas/aggregate-stats.js +3 -3
  12. package/dist/doc-schemas/aggregate-stats.js.map +1 -1
  13. package/dist/doc-schemas/atoms.d.ts +1 -1
  14. package/dist/doc-schemas/atoms.js +3 -3
  15. package/dist/doc-schemas/atoms.js.map +1 -1
  16. package/dist/doc-schemas/audit-event.js +2 -2
  17. package/dist/doc-schemas/audit-event.js.map +1 -1
  18. package/dist/doc-schemas/firestore-primitives.js +1 -1
  19. package/dist/doc-schemas/firestore-primitives.js.map +1 -1
  20. package/dist/doc-schemas/game-location.js +2 -2
  21. package/dist/doc-schemas/game-location.js.map +1 -1
  22. package/dist/doc-schemas/game-stat-history.js +1 -1
  23. package/dist/doc-schemas/game-stat-history.js.map +1 -1
  24. package/dist/doc-schemas/game-stats.js +6 -6
  25. package/dist/doc-schemas/game-stats.js.map +1 -1
  26. package/dist/doc-schemas/league-team.js +4 -4
  27. package/dist/doc-schemas/league-team.js.map +1 -1
  28. package/dist/doc-schemas/membership-roster-sync.js +2 -2
  29. package/dist/doc-schemas/membership-roster-sync.js.map +1 -1
  30. package/dist/doc-schemas/pending-media.d.ts +6 -6
  31. package/dist/doc-schemas/publicUser.js +1 -1
  32. package/dist/doc-schemas/publicUser.js.map +1 -1
  33. package/dist/doc-schemas/registration-start.js +1 -1
  34. package/dist/doc-schemas/registration-start.js.map +1 -1
  35. package/dist/doc-schemas/registry.d.ts +3 -3
  36. package/dist/doc-schemas/sport-game.js +4 -4
  37. package/dist/doc-schemas/sport-game.js.map +1 -1
  38. package/dist/doc-schemas/sport-league.js +1 -1
  39. package/dist/doc-schemas/sport-league.js.map +1 -1
  40. package/dist/doc-schemas/stats-operation.js +2 -2
  41. package/dist/doc-schemas/stats-operation.js.map +1 -1
  42. package/dist/doc-schemas/status-reconcile-queue.js +1 -1
  43. package/dist/doc-schemas/status-reconcile-queue.js.map +1 -1
  44. package/dist/doc-schemas/sweep-state.js +2 -2
  45. package/dist/doc-schemas/sweep-state.js.map +1 -1
  46. package/dist/doc-schemas/team-membership.js +1 -1
  47. package/dist/doc-schemas/team-membership.js.map +1 -1
  48. package/dist/doc-schemas/user-profile.js +1 -1
  49. package/dist/doc-schemas/user-profile.js.map +1 -1
  50. package/dist/doc-schemas/waiver-template.js +1 -1
  51. package/dist/doc-schemas/waiver-template.js.map +1 -1
  52. package/dist/doc-schemas/waivers-and-hardware.js +3 -3
  53. package/dist/doc-schemas/waivers-and-hardware.js.map +1 -1
  54. package/dist/domain-events/domain-events.js +2 -2
  55. package/dist/domain-events/domain-events.js.map +1 -1
  56. package/dist/ids/award-grant-ids.js +1 -1
  57. package/dist/ids/award-grant-ids.js.map +1 -1
  58. package/dist/ids/compound-ids.js +1 -1
  59. package/dist/ids/compound-ids.js.map +1 -1
  60. package/dist/ids/minted-ids.js +1 -1
  61. package/dist/ids/minted-ids.js.map +1 -1
  62. package/dist/ids/notification-ids.js +1 -1
  63. package/dist/ids/notification-ids.js.map +1 -1
  64. package/dist/ids/stat-event-ids.d.ts +1 -1
  65. package/dist/ids/stat-event-ids.js +2 -2
  66. package/dist/ids/stat-event-ids.js.map +1 -1
  67. package/dist/ids/stats-operation-ids.js +1 -1
  68. package/dist/ids/stats-operation-ids.js.map +1 -1
  69. package/dist/index.js +1 -1
  70. package/dist/index.js.map +1 -1
  71. package/dist/input-formats/input-formats.js +1 -1
  72. package/dist/input-formats/input-formats.js.map +1 -1
  73. package/dist/media/file-origins.js +1 -1
  74. package/dist/media/file-origins.js.map +1 -1
  75. package/dist/media/picture-url.js +1 -1
  76. package/dist/media/picture-url.js.map +1 -1
  77. package/dist/migration-console/action-ids.js +1 -1
  78. package/dist/migration-console/action-ids.js.map +1 -1
  79. package/dist/migration-console/manifest.js +1 -1
  80. package/dist/migration-console/manifest.js.map +1 -1
  81. package/dist/notifications/admin-notification-config.js +1 -1
  82. package/dist/notifications/admin-notification-config.js.map +1 -1
  83. package/dist/notifications/occurrences.js +1 -1
  84. package/dist/notifications/occurrences.js.map +1 -1
  85. package/dist/paths/collections.js +3 -3
  86. package/dist/paths/collections.js.map +1 -1
  87. package/dist/paths/picture-owner-paths.js +1 -1
  88. package/dist/paths/picture-owner-paths.js.map +1 -1
  89. package/dist/paths/storage-paths.d.ts +1 -1
  90. package/dist/paths/storage-paths.js +1 -1
  91. package/dist/paths/storage-paths.js.map +1 -1
  92. package/dist/paths/utils.d.ts +1 -1
  93. package/dist/paths/utils.js +1 -1
  94. package/dist/paths/utils.js.map +1 -1
  95. package/dist/schemas/admin-notifications.js +1 -1
  96. package/dist/schemas/admin-notifications.js.map +1 -1
  97. package/dist/schemas/app-config.js +1 -1
  98. package/dist/schemas/app-config.js.map +1 -1
  99. package/dist/schemas/awards.js +1 -1
  100. package/dist/schemas/awards.js.map +1 -1
  101. package/dist/schemas/dead-letters.js +2 -2
  102. package/dist/schemas/dead-letters.js.map +1 -1
  103. package/dist/schemas/leagues.js +1 -1
  104. package/dist/schemas/leagues.js.map +1 -1
  105. package/dist/schemas/migration-console.js +1 -1
  106. package/dist/schemas/migration-console.js.map +1 -1
  107. package/dist/schemas/pictures.js +1 -1
  108. package/dist/schemas/pictures.js.map +1 -1
  109. package/dist/schemas/schedules.js +2 -2
  110. package/dist/schemas/schedules.js.map +1 -1
  111. package/dist/schemas/scoring.js +1 -1
  112. package/dist/schemas/scoring.js.map +1 -1
  113. package/dist/schemas/signed-waivers.js +1 -1
  114. package/dist/schemas/signed-waivers.js.map +1 -1
  115. package/dist/schemas/stats.js +6 -6
  116. package/dist/schemas/stats.js.map +1 -1
  117. package/dist/schemas/team-joining.js +3 -3
  118. package/dist/schemas/team-joining.js.map +1 -1
  119. package/dist/schemas/teams.js +7 -7
  120. package/dist/schemas/teams.js.map +1 -1
  121. package/dist/schemas/users.js +3 -3
  122. package/dist/schemas/users.js.map +1 -1
  123. package/dist/sports/basketball-scoring.js +4 -4
  124. package/dist/sports/basketball-scoring.js.map +1 -1
  125. package/dist/sports/bulk-entry.js +1 -1
  126. package/dist/sports/bulk-entry.js.map +1 -1
  127. package/dist/sports/contribution.d.ts +5 -5
  128. package/dist/sports/contribution.d.ts.map +1 -1
  129. package/dist/sports/contribution.js +4 -4
  130. package/dist/sports/contribution.js.map +1 -1
  131. package/dist/sports/curling-scoring.js +2 -2
  132. package/dist/sports/curling-scoring.js.map +1 -1
  133. package/dist/sports/football-scoring.js +2 -2
  134. package/dist/sports/football-scoring.js.map +1 -1
  135. package/dist/sports/index.js +1 -1
  136. package/dist/sports/index.js.map +1 -1
  137. package/dist/sports/ledger-continuity.js +1 -1
  138. package/dist/sports/ledger-continuity.js.map +1 -1
  139. package/dist/sports/registry.js +2 -2
  140. package/dist/sports/registry.js.map +1 -1
  141. package/dist/sports/replay.js +1 -1
  142. package/dist/sports/replay.js.map +1 -1
  143. package/dist/sports/rollup-check.js +1 -1
  144. package/dist/sports/rollup-check.js.map +1 -1
  145. package/dist/sports/score-mirror.js +1 -1
  146. package/dist/sports/score-mirror.js.map +1 -1
  147. package/dist/sports/scoring-display.d.ts +1 -1
  148. package/dist/sports/scoring-display.js +2 -2
  149. package/dist/sports/scoring-display.js.map +1 -1
  150. package/dist/sports/scoring.d.ts +5 -5
  151. package/dist/sports/scoring.d.ts.map +1 -1
  152. package/dist/sports/scoring.js +2 -2
  153. package/dist/sports/scoring.js.map +1 -1
  154. package/dist/sports/sport-adapter.d.ts +3 -3
  155. package/dist/sports/sport-adapter.d.ts.map +1 -1
  156. package/dist/sports/sport-adapter.js +2 -2
  157. package/dist/sports/sport-adapter.js.map +1 -1
  158. package/dist/sports/store-driver.d.ts +1 -1
  159. package/dist/sports/store-driver.d.ts.map +1 -1
  160. package/dist/sports/store-driver.js +2 -2
  161. package/dist/sports/store-driver.js.map +1 -1
  162. package/dist/types/audit.js +4 -4
  163. package/dist/types/audit.js.map +1 -1
  164. package/dist/types/claims.js +1 -1
  165. package/dist/types/claims.js.map +1 -1
  166. package/dist/types/picture-owners.js +1 -1
  167. package/dist/types/picture-owners.js.map +1 -1
  168. package/dist/types/schedules.js +1 -1
  169. package/dist/types/schedules.js.map +1 -1
  170. package/dist/types/sports.js +2 -2
  171. package/dist/types/sports.js.map +1 -1
  172. package/dist/types/stats.js +5 -5
  173. package/dist/types/stats.js.map +1 -1
  174. package/dist/types/unions.js +2 -2
  175. package/dist/types/unions.js.map +1 -1
  176. package/dist/types/uploads.js +1 -1
  177. package/dist/types/uploads.js.map +1 -1
  178. package/dist/upload-variables/picture-upload-variables.d.ts +2 -2
  179. package/dist/upload-variables/sign-hardware-contract-variables.d.ts +1 -1
  180. package/dist/upload-variables/sign-hardware-contract-variables.js +1 -1
  181. package/dist/upload-variables/sign-hardware-contract-variables.js.map +1 -1
  182. package/dist/upload-variables/sign-waiver-variables.d.ts +1 -1
  183. package/dist/upload-variables/sign-waiver-variables.js +1 -1
  184. package/dist/upload-variables/sign-waiver-variables.js.map +1 -1
  185. package/dist/utils/account-status.d.ts +1 -2
  186. package/dist/utils/account-status.d.ts.map +1 -1
  187. package/dist/utils/account-status.js +1 -1
  188. package/dist/utils/account-status.js.map +1 -1
  189. package/dist/utils/app-routes.js +1 -1
  190. package/dist/utils/app-routes.js.map +1 -1
  191. package/dist/utils/league-join-warning.js +1 -1
  192. package/dist/utils/league-join-warning.js.map +1 -1
  193. package/dist/utils/league-joining.js +1 -1
  194. package/dist/utils/league-joining.js.map +1 -1
  195. package/dist/utils/league-mode.js +1 -1
  196. package/dist/utils/league-mode.js.map +1 -1
  197. package/dist/utils/team-creation.js +1 -1
  198. package/dist/utils/team-creation.js.map +1 -1
  199. package/dist/utils/team-member-actions.js +1 -1
  200. package/dist/utils/team-member-actions.js.map +1 -1
  201. package/package.json +3 -3
@@ -11,7 +11,7 @@ export type PictureUploadTarget = {
11
11
  export declare const PictureUploadTargetSchema: z.ZodType<PictureUploadTarget>;
12
12
  export declare const PictureUploadVariablesSchema: z.ZodObject<{
13
13
  target: z.ZodType<PictureUploadTarget, unknown, z.core.$ZodTypeInternals<PictureUploadTarget, unknown>>;
14
- file: z.ZodCustom<File, File>;
14
+ file: z.ZodInstanceOf<File>;
15
15
  claim: z.ZodOptional<z.ZodObject<{
16
16
  kind: z.ZodEnum<{
17
17
  file: "file";
@@ -26,7 +26,7 @@ export declare const PictureUploadVariablesSchema: z.ZodObject<{
26
26
  }>;
27
27
  }, z.core.$strict>>;
28
28
  onProgress: z.ZodOptional<z.ZodCustom<(state: import("@ttt-productions/media-schemas").UploadState | null) => void, (state: import("@ttt-productions/media-schemas").UploadState | null) => void>>;
29
- signal: z.ZodOptional<z.ZodCustom<AbortSignal, AbortSignal>>;
29
+ signal: z.ZodOptional<z.ZodInstanceOf<AbortSignal>>;
30
30
  }, z.core.$strict>;
31
31
  export type PictureUploadVariables = z.infer<typeof PictureUploadVariablesSchema>;
32
32
  //# sourceMappingURL=picture-upload-variables.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  export declare const SignHardwareContractVariablesSchema: z.ZodObject<{
3
3
  contractId: z.ZodString;
4
- signature: z.ZodCustom<Blob, Blob>;
4
+ signature: z.ZodInstanceOf<Blob>;
5
5
  }, z.core.$strict>;
6
6
  export type SignHardwareContractVariables = z.infer<typeof SignHardwareContractVariablesSchema>;
7
7
  //# sourceMappingURL=sign-hardware-contract-variables.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { hardwareLoanContractIdSchema } from '../doc-schemas/atoms.js';
3
- // Variables for the hardware-contract signing mutation hook (MEDIA-005). The signature is the
3
+ // Variables for the hardware-contract signing mutation hook (RULE-STD-MEDIA-005). The signature is the
4
4
  // drawing as the canvas exported it.
5
5
  export const SignHardwareContractVariablesSchema = z
6
6
  .object({
@@ -1 +1 @@
1
- {"version":3,"file":"sign-hardware-contract-variables.js","sourceRoot":"","sources":["../../src/upload-variables/sign-hardware-contract-variables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AAEvE,8FAA8F;AAC9F,qCAAqC;AACrC,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC;KACjD,MAAM,CAAC;IACN,UAAU,EAAE,4BAA4B;IACxC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;CAC9B,CAAC;KACD,MAAM,EAAE,CAAC","sourcesContent":["import { z } from 'zod';\nimport { hardwareLoanContractIdSchema } from '../doc-schemas/atoms.js';\n\n// Variables for the hardware-contract signing mutation hook (MEDIA-005). The signature is the\n// drawing as the canvas exported it.\nexport const SignHardwareContractVariablesSchema = z\n .object({\n contractId: hardwareLoanContractIdSchema,\n signature: z.instanceof(Blob),\n })\n .strict();\nexport type SignHardwareContractVariables = z.infer<typeof SignHardwareContractVariablesSchema>;\n"]}
1
+ {"version":3,"file":"sign-hardware-contract-variables.js","sourceRoot":"","sources":["../../src/upload-variables/sign-hardware-contract-variables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AAEvE,uGAAuG;AACvG,qCAAqC;AACrC,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC;KACjD,MAAM,CAAC;IACN,UAAU,EAAE,4BAA4B;IACxC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;CAC9B,CAAC;KACD,MAAM,EAAE,CAAC","sourcesContent":["import { z } from 'zod';\nimport { hardwareLoanContractIdSchema } from '../doc-schemas/atoms.js';\n\n// Variables for the hardware-contract signing mutation hook (RULE-STD-MEDIA-005). The signature is the\n// drawing as the canvas exported it.\nexport const SignHardwareContractVariablesSchema = z\n .object({\n contractId: hardwareLoanContractIdSchema,\n signature: z.instanceof(Blob),\n })\n .strict();\nexport type SignHardwareContractVariables = z.infer<typeof SignHardwareContractVariablesSchema>;\n"]}
@@ -15,7 +15,7 @@ export declare const SignWaiverVariablesSchema: z.ZodObject<{
15
15
  leagueId: z.ZodString;
16
16
  waiverTemplateId: z.ZodString;
17
17
  waiverTemplateVersion: z.ZodNumber;
18
- signature: z.ZodCustom<Blob, Blob>;
18
+ signature: z.ZodInstanceOf<Blob>;
19
19
  subject: z.ZodDiscriminatedUnion<[z.ZodObject<{
20
20
  kind: z.ZodLiteral<"self">;
21
21
  }, z.core.$strict>, z.ZodObject<{
@@ -9,7 +9,7 @@ export const WaiverSubjectSchema = z.discriminatedUnion('kind', [
9
9
  z.object({ kind: z.literal('self') }).strict(),
10
10
  ghostWaiverSubjectSchema.extend({ kind: z.literal('ghost'), entry: actingEntrySchema }).strict(),
11
11
  ]);
12
- // Variables for the waiver-signing mutation hook (MEDIA-005). The template id and version are the
12
+ // Variables for the waiver-signing mutation hook (RULE-STD-MEDIA-005). The template id and version are the
13
13
  // wording the signing dialog displayed; the signature is the drawing as the canvas exported it.
14
14
  export const SignWaiverVariablesSchema = z
15
15
  .object({
@@ -1 +1 @@
1
- {"version":3,"file":"sign-waiver-variables.js","sourceRoot":"","sources":["../../src/upload-variables/sign-waiver-variables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,iCAAiC,GAClC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAExE,iGAAiG;AACjG,kBAAkB;AAClB,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAC9D,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9C,wBAAwB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE;CACjG,CAAC,CAAC;AAGH,kGAAkG;AAClG,gGAAgG;AAChG,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC;KACvC,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,gBAAgB,EAAE,sBAAsB;IACxC,qBAAqB,EAAE,iCAAiC;IACxD,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;IAC7B,OAAO,EAAE,mBAAmB;CAC7B,CAAC;KACD,MAAM,EAAE,CAAC","sourcesContent":["import { z } from 'zod';\nimport { leagueIdSchema } from '../doc-schemas/atoms.js';\nimport {\n waiverTemplateIdSchema,\n waiverTemplateVersionNumberSchema,\n} from '../doc-schemas/waiver-template.js';\nimport { actingEntrySchema } from '../schemas/atoms.js';\nimport { ghostWaiverSubjectSchema } from '../schemas/signed-waivers.js';\n\n// Whose waiver a signing is for: the signer's own, or a ghost's, witnessed through the entry the\n// signer acts at.\nexport const WaiverSubjectSchema = z.discriminatedUnion('kind', [\n z.object({ kind: z.literal('self') }).strict(),\n ghostWaiverSubjectSchema.extend({ kind: z.literal('ghost'), entry: actingEntrySchema }).strict(),\n]);\nexport type WaiverSubject = z.infer<typeof WaiverSubjectSchema>;\n\n// Variables for the waiver-signing mutation hook (MEDIA-005). The template id and version are the\n// wording the signing dialog displayed; the signature is the drawing as the canvas exported it.\nexport const SignWaiverVariablesSchema = z\n .object({\n leagueId: leagueIdSchema,\n waiverTemplateId: waiverTemplateIdSchema,\n waiverTemplateVersion: waiverTemplateVersionNumberSchema,\n signature: z.instanceof(Blob),\n subject: WaiverSubjectSchema,\n })\n .strict();\nexport type SignWaiverVariables = z.infer<typeof SignWaiverVariablesSchema>;\n"]}
1
+ {"version":3,"file":"sign-waiver-variables.js","sourceRoot":"","sources":["../../src/upload-variables/sign-waiver-variables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,iCAAiC,GAClC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAExE,iGAAiG;AACjG,kBAAkB;AAClB,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAC9D,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9C,wBAAwB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE;CACjG,CAAC,CAAC;AAGH,2GAA2G;AAC3G,gGAAgG;AAChG,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC;KACvC,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,gBAAgB,EAAE,sBAAsB;IACxC,qBAAqB,EAAE,iCAAiC;IACxD,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;IAC7B,OAAO,EAAE,mBAAmB;CAC7B,CAAC;KACD,MAAM,EAAE,CAAC","sourcesContent":["import { z } from 'zod';\nimport { leagueIdSchema } from '../doc-schemas/atoms.js';\nimport {\n waiverTemplateIdSchema,\n waiverTemplateVersionNumberSchema,\n} from '../doc-schemas/waiver-template.js';\nimport { actingEntrySchema } from '../schemas/atoms.js';\nimport { ghostWaiverSubjectSchema } from '../schemas/signed-waivers.js';\n\n// Whose waiver a signing is for: the signer's own, or a ghost's, witnessed through the entry the\n// signer acts at.\nexport const WaiverSubjectSchema = z.discriminatedUnion('kind', [\n z.object({ kind: z.literal('self') }).strict(),\n ghostWaiverSubjectSchema.extend({ kind: z.literal('ghost'), entry: actingEntrySchema }).strict(),\n]);\nexport type WaiverSubject = z.infer<typeof WaiverSubjectSchema>;\n\n// Variables for the waiver-signing mutation hook (RULE-STD-MEDIA-005). The template id and version are the\n// wording the signing dialog displayed; the signature is the drawing as the canvas exported it.\nexport const SignWaiverVariablesSchema = z\n .object({\n leagueId: leagueIdSchema,\n waiverTemplateId: waiverTemplateIdSchema,\n waiverTemplateVersion: waiverTemplateVersionNumberSchema,\n signature: z.instanceof(Blob),\n subject: WaiverSubjectSchema,\n })\n .strict();\nexport type SignWaiverVariables = z.infer<typeof SignWaiverVariablesSchema>;\n"]}
@@ -1,5 +1,4 @@
1
- import { type UserStatus } from '../types/unions.js';
2
1
  export declare function isActiveAccount(profile: {
3
- userStatus: UserStatus;
2
+ userStatus: unknown;
4
3
  } | null | undefined): boolean;
5
4
  //# sourceMappingURL=account-status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"account-status.d.ts","sourceRoot":"","sources":["../../src/utils/account-status.ts"],"names":[],"mappings":"AAKA,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEzE,wBAAgB,eAAe,CAAC,OAAO,EAAE;IAAE,UAAU,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE/F"}
1
+ {"version":3,"file":"account-status.d.ts","sourceRoot":"","sources":["../../src/utils/account-status.ts"],"names":[],"mappings":"AAOA,wBAAgB,eAAe,CAAC,OAAO,EAAE;IAAE,UAAU,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE5F"}
@@ -1,7 +1,7 @@
1
1
  // Whether an account may act as a member: it has finished registration — its profile exists — and that
2
2
  // profile's status is exactly `active`. Fail closed: a missing profile, or any other status, is refused.
3
3
  // The callable auth assertion refuses every other account before a member callable runs, and a door
4
- // is offered only to an account this answers true for (ENG-006, FRONTEND-110).
4
+ // is offered only to an account this answers true for (RULE-STD-ENG-006, RULE-STD-FRONTEND-110).
5
5
  import { ACTIVE_USER_STATUS } from '../types/unions.js';
6
6
  export function isActiveAccount(profile) {
7
7
  return profile?.userStatus === ACTIVE_USER_STATUS;
@@ -1 +1 @@
1
- {"version":3,"file":"account-status.js","sourceRoot":"","sources":["../../src/utils/account-status.ts"],"names":[],"mappings":"AAAA,uGAAuG;AACvG,yGAAyG;AACzG,oGAAoG;AACpG,+EAA+E;AAE/E,OAAO,EAAE,kBAAkB,EAAmB,MAAM,oBAAoB,CAAC;AAEzE,MAAM,UAAU,eAAe,CAAC,OAAsD;IACpF,OAAO,OAAO,EAAE,UAAU,KAAK,kBAAkB,CAAC;AACpD,CAAC","sourcesContent":["// Whether an account may act as a member: it has finished registration — its profile exists — and that\n// profile's status is exactly `active`. Fail closed: a missing profile, or any other status, is refused.\n// The callable auth assertion refuses every other account before a member callable runs, and a door\n// is offered only to an account this answers true for (ENG-006, FRONTEND-110).\n\nimport { ACTIVE_USER_STATUS, type UserStatus } from '../types/unions.js';\n\nexport function isActiveAccount(profile: { userStatus: UserStatus } | null | undefined): boolean {\n return profile?.userStatus === ACTIVE_USER_STATUS;\n}\n"]}
1
+ {"version":3,"file":"account-status.js","sourceRoot":"","sources":["../../src/utils/account-status.ts"],"names":[],"mappings":"AAAA,uGAAuG;AACvG,yGAAyG;AACzG,oGAAoG;AACpG,iGAAiG;AAEjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,UAAU,eAAe,CAAC,OAAmD;IACjF,OAAO,OAAO,EAAE,UAAU,KAAK,kBAAkB,CAAC;AACpD,CAAC","sourcesContent":["// Whether an account may act as a member: it has finished registration — its profile exists — and that\n// profile's status is exactly `active`. Fail closed: a missing profile, or any other status, is refused.\n// The callable auth assertion refuses every other account before a member callable runs, and a door\n// is offered only to an account this answers true for (RULE-STD-ENG-006, RULE-STD-FRONTEND-110).\n\nimport { ACTIVE_USER_STATUS } from '../types/unions.js';\n\nexport function isActiveAccount(profile: { userStatus: unknown } | null | undefined): boolean {\n return profile?.userStatus === ACTIVE_USER_STATUS;\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  // The app addresses a link is built to: a league's pages — the league, one of its teams, one of its
2
2
  // games and that game's scoring page — and the admin Leagues workspace. Both roots build these links:
3
3
  // the server writes one onto an admin notification card, and the app links to every one of them, so
4
- // each address shape has one change point (ARCH-101).
4
+ // each address shape has one change point (RULE-STD-ARCH-101).
5
5
  const LEAGUE_PATH = '/league';
6
6
  /** The one admin page; every admin group is a `?view=` of it. */
7
7
  export const ADMIN_PATH = '/admin';
@@ -1 +1 @@
1
- {"version":3,"file":"app-routes.js","sourceRoot":"","sources":["../../src/utils/app-routes.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,sGAAsG;AACtG,oGAAoG;AACpG,sDAAsD;AAEtD,MAAM,WAAW,GAAG,SAAS,CAAC;AAE9B,iEAAiE;AACjE,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC;AAEnC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEvC,0DAA0D;AAC1D,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAE7C,6FAA6F;AAC7F,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AAE3C,2FAA2F;AAC3F,MAAM,CAAC,MAAM,kBAAkB,GAAG,qBAAqB,CAAC;AAExD,mGAAmG;AACnG,kDAAkD;AAClD,MAAM,CAAC,MAAM,mCAAmC,GAAG;IACjD,UAAU;IACV,UAAU;IACV,OAAO;IACP,aAAa;CACL,CAAC;AAGX,2EAA2E;AAC3E,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAgD,CAAC;AAExF,8FAA8F;AAC9F,MAAM,CAAC,MAAM,oBAAoB,GAAG,OAA6C,CAAC;AAElF,4FAA4F;AAC5F,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEvC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,0BAA0B,GAAG,aAAmD,CAAC;AAE9F,sFAAsF;AACtF,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,OAAe;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAC9C,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,mBAAmB,IAAI,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,GAAG,WAAW,IAAI,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,MAAc;IAC7D,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,MAAc;IAC5D,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;AACtE,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,oBAAoB,CAAC,QAAgB,EAAE,MAAc;IACnE,OAAO,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;AACpD,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,OAAqC;IACrF,MAAM,IAAI,GAAG,GAAG,kBAAkB,IAAI,kBAAkB,IAAI,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC3F,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACxE,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,MAAc;IAClE,OAAO,GAAG,eAAe,CAAC,QAAQ,EAAE,oBAAoB,CAAC,IAAI,gBAAgB,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;AAChH,CAAC","sourcesContent":["// The app addresses a link is built to: a league's pages — the league, one of its teams, one of its\n// games and that game's scoring page — and the admin Leagues workspace. Both roots build these links:\n// the server writes one onto an admin notification card, and the app links to every one of them, so\n// each address shape has one change point (ARCH-101).\n\nconst LEAGUE_PATH = '/league';\n\n/** The one admin page; every admin group is a `?view=` of it. */\nexport const ADMIN_PATH = '/admin';\n\n/** The query-string key the admin page's groups live under. */\nexport const ADMIN_VIEW_PARAM = 'view';\n\n/** The query-string key a group's sections live under. */\nexport const ADMIN_SECTION_PARAM = 'section';\n\n/** The query-string key the Leagues group names the league whose workspace is open under. */\nexport const ADMIN_LEAGUE_PARAM = 'league';\n\n/** The admin Leagues group: the league list, each league's workspace nested beneath it. */\nexport const ADMIN_LEAGUES_HREF = '/admin?view=leagues';\n\n// The sections a league's admin workspace is addressed by. The workspace declares which of them it\n// has built as tabs; a link may name any of them.\nexport const ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS = [\n 'settings',\n 'schedule',\n 'teams',\n 'free-agents',\n] as const;\nexport type AdminLeagueWorkspaceSection = (typeof ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS)[number];\n\n/** The league workspace's section holding the league's weeks and games. */\nexport const LEAGUE_SCHEDULE_SECTION = 'schedule' satisfies AdminLeagueWorkspaceSection;\n\n/** The league workspace's section listing the league's teams, each opening its admin view. */\nexport const LEAGUE_TEAMS_SECTION = 'teams' satisfies AdminLeagueWorkspaceSection;\n\n/** The query-string key the Teams section names the team whose admin view is open under. */\nexport const ADMIN_TEAM_PARAM = 'team';\n\n/** The league workspace's section listing the league's free-agent signups. */\nexport const LEAGUE_FREE_AGENTS_SECTION = 'free-agents' satisfies AdminLeagueWorkspaceSection;\n\n/** An admin address on one of its sections — the one place a section joins a link. */\nexport function withAdminSection(href: string, section: string): string {\n const joiner = href.includes('?') ? '&' : '?';\n return `${href}${joiner}${ADMIN_SECTION_PARAM}=${encodeURIComponent(section)}`;\n}\n\nexport function leagueHref(leagueId: string): string {\n return `${LEAGUE_PATH}/${encodeURIComponent(leagueId)}`;\n}\n\nexport function leagueTeamHref(leagueId: string, teamId: string): string {\n return `${leagueHref(leagueId)}/team/${encodeURIComponent(teamId)}`;\n}\n\nexport function sportGameHref(leagueId: string, gameId: string): string {\n return `${leagueHref(leagueId)}/game/${encodeURIComponent(gameId)}`;\n}\n\n/** A game's scoring page, where a scorer records its stats. */\nexport function sportGameScoringHref(leagueId: string, gameId: string): string {\n return `${sportGameHref(leagueId, gameId)}/stats`;\n}\n\n/** A league's admin workspace, on one of its sections when one is named. */\nexport function adminLeagueHref(leagueId: string, section?: AdminLeagueWorkspaceSection): string {\n const href = `${ADMIN_LEAGUES_HREF}&${ADMIN_LEAGUE_PARAM}=${encodeURIComponent(leagueId)}`;\n return section === undefined ? href : withAdminSection(href, section);\n}\n\n/** One team's admin view, inside its league's workspace on the Teams section. */\nexport function adminLeagueTeamHref(leagueId: string, teamId: string): string {\n return `${adminLeagueHref(leagueId, LEAGUE_TEAMS_SECTION)}&${ADMIN_TEAM_PARAM}=${encodeURIComponent(teamId)}`;\n}\n"]}
1
+ {"version":3,"file":"app-routes.js","sourceRoot":"","sources":["../../src/utils/app-routes.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,sGAAsG;AACtG,oGAAoG;AACpG,+DAA+D;AAE/D,MAAM,WAAW,GAAG,SAAS,CAAC;AAE9B,iEAAiE;AACjE,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC;AAEnC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEvC,0DAA0D;AAC1D,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAE7C,6FAA6F;AAC7F,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AAE3C,2FAA2F;AAC3F,MAAM,CAAC,MAAM,kBAAkB,GAAG,qBAAqB,CAAC;AAExD,mGAAmG;AACnG,kDAAkD;AAClD,MAAM,CAAC,MAAM,mCAAmC,GAAG;IACjD,UAAU;IACV,UAAU;IACV,OAAO;IACP,aAAa;CACL,CAAC;AAGX,2EAA2E;AAC3E,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAgD,CAAC;AAExF,8FAA8F;AAC9F,MAAM,CAAC,MAAM,oBAAoB,GAAG,OAA6C,CAAC;AAElF,4FAA4F;AAC5F,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEvC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,0BAA0B,GAAG,aAAmD,CAAC;AAE9F,sFAAsF;AACtF,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,OAAe;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAC9C,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,mBAAmB,IAAI,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,GAAG,WAAW,IAAI,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,MAAc;IAC7D,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,MAAc;IAC5D,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;AACtE,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,oBAAoB,CAAC,QAAgB,EAAE,MAAc;IACnE,OAAO,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;AACpD,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,OAAqC;IACrF,MAAM,IAAI,GAAG,GAAG,kBAAkB,IAAI,kBAAkB,IAAI,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC3F,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACxE,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,MAAc;IAClE,OAAO,GAAG,eAAe,CAAC,QAAQ,EAAE,oBAAoB,CAAC,IAAI,gBAAgB,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;AAChH,CAAC","sourcesContent":["// The app addresses a link is built to: a league's pages — the league, one of its teams, one of its\n// games and that game's scoring page — and the admin Leagues workspace. Both roots build these links:\n// the server writes one onto an admin notification card, and the app links to every one of them, so\n// each address shape has one change point (RULE-STD-ARCH-101).\n\nconst LEAGUE_PATH = '/league';\n\n/** The one admin page; every admin group is a `?view=` of it. */\nexport const ADMIN_PATH = '/admin';\n\n/** The query-string key the admin page's groups live under. */\nexport const ADMIN_VIEW_PARAM = 'view';\n\n/** The query-string key a group's sections live under. */\nexport const ADMIN_SECTION_PARAM = 'section';\n\n/** The query-string key the Leagues group names the league whose workspace is open under. */\nexport const ADMIN_LEAGUE_PARAM = 'league';\n\n/** The admin Leagues group: the league list, each league's workspace nested beneath it. */\nexport const ADMIN_LEAGUES_HREF = '/admin?view=leagues';\n\n// The sections a league's admin workspace is addressed by. The workspace declares which of them it\n// has built as tabs; a link may name any of them.\nexport const ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS = [\n 'settings',\n 'schedule',\n 'teams',\n 'free-agents',\n] as const;\nexport type AdminLeagueWorkspaceSection = (typeof ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS)[number];\n\n/** The league workspace's section holding the league's weeks and games. */\nexport const LEAGUE_SCHEDULE_SECTION = 'schedule' satisfies AdminLeagueWorkspaceSection;\n\n/** The league workspace's section listing the league's teams, each opening its admin view. */\nexport const LEAGUE_TEAMS_SECTION = 'teams' satisfies AdminLeagueWorkspaceSection;\n\n/** The query-string key the Teams section names the team whose admin view is open under. */\nexport const ADMIN_TEAM_PARAM = 'team';\n\n/** The league workspace's section listing the league's free-agent signups. */\nexport const LEAGUE_FREE_AGENTS_SECTION = 'free-agents' satisfies AdminLeagueWorkspaceSection;\n\n/** An admin address on one of its sections — the one place a section joins a link. */\nexport function withAdminSection(href: string, section: string): string {\n const joiner = href.includes('?') ? '&' : '?';\n return `${href}${joiner}${ADMIN_SECTION_PARAM}=${encodeURIComponent(section)}`;\n}\n\nexport function leagueHref(leagueId: string): string {\n return `${LEAGUE_PATH}/${encodeURIComponent(leagueId)}`;\n}\n\nexport function leagueTeamHref(leagueId: string, teamId: string): string {\n return `${leagueHref(leagueId)}/team/${encodeURIComponent(teamId)}`;\n}\n\nexport function sportGameHref(leagueId: string, gameId: string): string {\n return `${leagueHref(leagueId)}/game/${encodeURIComponent(gameId)}`;\n}\n\n/** A game's scoring page, where a scorer records its stats. */\nexport function sportGameScoringHref(leagueId: string, gameId: string): string {\n return `${sportGameHref(leagueId, gameId)}/stats`;\n}\n\n/** A league's admin workspace, on one of its sections when one is named. */\nexport function adminLeagueHref(leagueId: string, section?: AdminLeagueWorkspaceSection): string {\n const href = `${ADMIN_LEAGUES_HREF}&${ADMIN_LEAGUE_PARAM}=${encodeURIComponent(leagueId)}`;\n return section === undefined ? href : withAdminSection(href, section);\n}\n\n/** One team's admin view, inside its league's workspace on the Teams section. */\nexport function adminLeagueTeamHref(leagueId: string, teamId: string): string {\n return `${adminLeagueHref(leagueId, LEAGUE_TEAMS_SECTION)}&${ADMIN_TEAM_PARAM}=${encodeURIComponent(teamId)}`;\n}\n"]}
@@ -6,7 +6,7 @@
6
6
  // of the person's standing is the server core behind `getLeagueJoinWarning` /
7
7
  // `adminGetLeagueJoinWarning`, because another person's pending requests, invitations, and signup
8
8
  // are not readable from the client. What the dialog says is `LEAGUE_JOIN_WARNING_COPY`, through
9
- // `formatLeagueJoinWarning` (ARCH-102, ENG-005). The acted-on item and a finding cross the wire, so
9
+ // `formatLeagueJoinWarning` (RULE-STD-ARCH-102, RULE-STD-ENG-005). The acted-on item and a finding cross the wire, so
10
10
  // each is declared once, as its schema, and its type is inferred from it.
11
11
  import { z } from 'zod';
12
12
  import { teamIdSchema } from '../doc-schemas/atoms.js';
@@ -1 +1 @@
1
- {"version":3,"file":"league-join-warning.js","sourceRoot":"","sources":["../../src/utils/league-join-warning.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,gGAAgG;AAChG,sFAAsF;AACtF,EAAE;AACF,mGAAmG;AACnG,8EAA8E;AAC9E,kGAAkG;AAClG,gGAAgG;AAChG,oGAAoG;AACpG,0EAA0E;AAE1E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEtF,kDAAkD;AAClD,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,QAAQ;IACR,oBAAoB;IACpB,mBAAmB;IACnB,iBAAiB;CACT,CAAC;AAGX,iGAAiG;AACjG,8BAA8B;AAC9B,MAAM,CAAC,MAAM,iCAAiC,GAAG;IAC/C,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;CACT,CAAC;AAGX,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IACzE,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAuD,CAAC;QACxE,gBAAgB,EAAE,sBAAsB;KACzC,CAAC;SACD,MAAM,EAAE;IACX,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAwD,CAAC;QACzE,iBAAiB,EAAE,uBAAuB;KAC3C,CAAC;SACD,MAAM,EAAE;IACX,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAwD,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;CACjG,CAAC,CAAC;AAGH,+FAA+F;AAC/F,wCAAwC;AACxC,MAAM,CAAC,MAAM,+BAA+B,GAAG;IAC7C,YAAY;IACZ,kBAAkB;IAClB,iBAAiB;IACjB,mBAAmB;IACnB,gBAAgB;IAChB,mBAAmB;IACnB,iBAAiB;IACjB,kBAAkB;CACV,CAAC;AAGX,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAU,CAAC;AAG/E,MAAM,CAAC,MAAM,yCAAyC,GAElD;IACF,UAAU,EAAE,MAAM;IAClB,gBAAgB,EAAE,MAAM;IACxB,eAAe,EAAE,MAAM;IACvB,iBAAiB,EAAE,MAAM;IACzB,cAAc,EAAE,OAAO;IACvB,iBAAiB,EAAE,OAAO;IAC1B,eAAe,EAAE,OAAO;IACxB,gBAAgB,EAAE,OAAO;CAC1B,CAAC;AAUF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC;KAC5C,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC;KAC1F,MAAM,EAAE,CAAC;AAGZ;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAA6B,EAC7B,OAAwC;IAExC,MAAM,MAAM,GAAG,CAAC,IAA8B,EAAE,KAA+B,EAAE,EAAE,CACjF,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IAExD,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACpD,KAAK,EAAE,QAAiB;QACxB,MAAM,EAAE,UAAU,CAAC,MAAM;KAC1B,CAAC,CAAC,CAAC;IACJ,MAAM,kBAAkB,GAAG,KAAK,CAAC,mBAAmB;SACjD,MAAM,CACL,CAAC,OAAO,EAAE,EAAE,CACV,CAAC,CACC,OAAO,EAAE,IAAI,KAAK,iBAAiB;QACnC,OAAO,CAAC,iBAAiB,KAAK,OAAO,CAAC,iBAAiB,CACxD,CACJ;SACA,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,oBAA6B,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACxF,MAAM,iBAAiB,GAAG,KAAK,CAAC,kBAAkB;SAC/C,MAAM,CACL,CAAC,UAAU,EAAE,EAAE,CACb,CAAC,CACC,OAAO,EAAE,IAAI,KAAK,gBAAgB;QAClC,OAAO,CAAC,gBAAgB,KAAK,UAAU,CAAC,gBAAgB,CACzD,CACJ;SACA,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,mBAA4B,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7F,MAAM,eAAe,GACnB,KAAK,CAAC,eAAe,IAAI,OAAO,EAAE,IAAI,KAAK,iBAAiB;QAC1D,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC9C,CAAC,CAAC,EAAE,CAAC;IAET,OAAO;QACL,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QACtB,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;QAClC,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;QACjC,GAAG,eAAe;KACnB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,KAAK,EAAE,wBAAwB;IAC/B,YAAY,EAAE,UAAU;IACxB,WAAW,EAAE,QAAQ;IACrB,uEAAuE;IACvE,IAAI,EAAE;QACJ,MAAM,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,sBAAsB,QAAQ,GAAG;QAC/D,kBAAkB,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,mCAAmC,QAAQ,GAAG;QACxF,iBAAiB,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,uCAAuC,QAAQ,GAAG;QAC3F,eAAe,EAAE,GAAG,EAAE,CAAC,mDAAmD;KAC3E;IACD,8DAA8D;IAC9D,KAAK,EAAE;QACL,MAAM,EAAE,CAAC,UAAkB,EAAE,QAAgB,EAAE,EAAE,CAAC,GAAG,UAAU,kBAAkB,QAAQ,GAAG;QAC5F,kBAAkB,EAAE,CAAC,UAAkB,EAAE,QAAgB,EAAE,EAAE,CAC3D,GAAG,UAAU,sBAAsB,QAAQ,GAAG;QAChD,iBAAiB,EAAE,CAAC,UAAkB,EAAE,QAAgB,EAAE,EAAE,CAC1D,GAAG,UAAU,mCAAmC,QAAQ,GAAG;QAC7D,eAAe,EAAE,CAAC,UAAkB,EAAE,EAAE,CACtC,GAAG,UAAU,+CAA+C;KAC/D;IACD,8FAA8F;IAC9F,QAAQ,EAAE;QACR,UAAU,EAAE,GAAG,EAAE,CAAC,yCAAyC;QAC3D,gBAAgB,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,6BAA6B,cAAc,GAAG;QAC5F,eAAe,EAAE,CAAC,cAAsB,EAAE,EAAE,CAC1C,oCAAoC,cAAc,GAAG;QACvD,iBAAiB,EAAE,GAAG,EAAE,CAAC,+CAA+C;QACxE,cAAc,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,kBAAkB,cAAc,UAAU;QACtF,iBAAiB,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,oBAAoB,cAAc,UAAU;QAC3F,eAAe,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,kBAAkB,cAAc,UAAU;QACvF,gBAAgB,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,gBAAgB,cAAc,UAAU;KACT;CACvE,CAAC;AAQX;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAMvC;IACC,MAAM,WAAW,GAAG,yCAAyC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1E,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;YAC3B,OAAO,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,wBAAwB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,wBAAwB,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;AAClG,CAAC","sourcesContent":["// The join warning: before anyone puts a person on a team in a league, or starts\n// their way onto one, they see every place that person already stands there. It warns and never\n// blocks — confirm proceeds, cancel does nothing, and no server check refuses for it.\n//\n// One decision serves every door: `computeLeagueJoinWarning` is the whole rule, and the one reader\n// of the person's standing is the server core behind `getLeagueJoinWarning` /\n// `adminGetLeagueJoinWarning`, because another person's pending requests, invitations, and signup\n// are not readable from the client. What the dialog says is `LEAGUE_JOIN_WARNING_COPY`, through\n// `formatLeagueJoinWarning` (ARCH-102, ENG-005). The acted-on item and a finding cross the wire, so\n// each is declared once, as its schema, and its type is inferred from it.\n\nimport { z } from 'zod';\nimport { teamIdSchema } from '../doc-schemas/atoms.js';\nimport { teamInvitationIdSchema, teamJoinRequestIdSchema } from '../schemas/atoms.js';\n\n// The four places a person can stand in a league.\nexport const LEAGUE_JOIN_WARNING_STATE_KEYS = [\n 'onTeam',\n 'pendingJoinRequest',\n 'pendingInvitation',\n 'freeAgentSignup',\n] as const;\nexport type LeagueJoinWarningState = (typeof LEAGUE_JOIN_WARNING_STATE_KEYS)[number];\n\n// The item a door acts on, which the warning never names: accepting a team's invitation does not\n// warn about that invitation.\nexport const LEAGUE_JOIN_WARNING_ACTED_ON_KEYS = [\n 'teamInvitation',\n 'teamJoinRequest',\n 'leagueFreeAgent',\n] as const;\nexport type LeagueJoinWarningActedOnKind = (typeof LEAGUE_JOIN_WARNING_ACTED_ON_KEYS)[number];\n\nexport const leagueJoinWarningActedOnSchema = z.discriminatedUnion('kind', [\n z\n .object({\n kind: z.literal('teamInvitation' satisfies LeagueJoinWarningActedOnKind),\n teamInvitationId: teamInvitationIdSchema,\n })\n .strict(),\n z\n .object({\n kind: z.literal('teamJoinRequest' satisfies LeagueJoinWarningActedOnKind),\n teamJoinRequestId: teamJoinRequestIdSchema,\n })\n .strict(),\n z.object({ kind: z.literal('leagueFreeAgent' satisfies LeagueJoinWarningActedOnKind) }).strict(),\n]);\nexport type LeagueJoinWarningActedOn = z.infer<typeof leagueJoinWarningActedOnSchema>;\n\n// Every door that shows the warning. Each is phrased either for the person acting on their own\n// behalf or for someone acting on them.\nexport const LEAGUE_JOIN_WARNING_ACTION_KEYS = [\n 'createTeam',\n 'acceptInvitation',\n 'sendJoinRequest',\n 'signUpAsFreeAgent',\n 'sendInvitation',\n 'acceptJoinRequest',\n 'assignFreeAgent',\n 'closedLeagueLink',\n] as const;\nexport type LeagueJoinWarningAction = (typeof LEAGUE_JOIN_WARNING_ACTION_KEYS)[number];\n\nexport const LEAGUE_JOIN_WARNING_PERSPECTIVE_KEYS = ['self', 'other'] as const;\nexport type LeagueJoinWarningPerspective = (typeof LEAGUE_JOIN_WARNING_PERSPECTIVE_KEYS)[number];\n\nexport const LEAGUE_JOIN_WARNING_PERSPECTIVE_BY_ACTION: Readonly<\n Record<LeagueJoinWarningAction, LeagueJoinWarningPerspective>\n> = {\n createTeam: 'self',\n acceptInvitation: 'self',\n sendJoinRequest: 'self',\n signUpAsFreeAgent: 'self',\n sendInvitation: 'other',\n acceptJoinRequest: 'other',\n assignFreeAgent: 'other',\n closedLeagueLink: 'other',\n};\n\n/** Where the person stands in the league, as the server read it. */\nexport interface LeagueJoinWarningFacts {\n memberships: readonly { teamId: string }[];\n pendingJoinRequests: readonly { teamJoinRequestId: string; teamId: string }[];\n pendingInvitations: readonly { teamInvitationId: string; teamId: string }[];\n freeAgentSignup: boolean;\n}\n\n// One place the person stands. `teamId` is null only for a free-agent signup.\nexport const leagueJoinWarningFindingSchema = z\n .object({ state: z.enum(LEAGUE_JOIN_WARNING_STATE_KEYS), teamId: teamIdSchema.nullable() })\n .strict();\nexport type LeagueJoinWarningFinding = z.infer<typeof leagueJoinWarningFindingSchema>;\n\n/**\n * Every place the person stands in the league, the acted-on item left out, in state order and then\n * team order. An empty result means no warning is shown.\n */\nexport function computeLeagueJoinWarning(\n facts: LeagueJoinWarningFacts,\n actedOn: LeagueJoinWarningActedOn | null,\n): LeagueJoinWarningFinding[] {\n const byTeam = (left: LeagueJoinWarningFinding, right: LeagueJoinWarningFinding) =>\n (left.teamId ?? '').localeCompare(right.teamId ?? '');\n\n const onTeam = facts.memberships.map((membership) => ({\n state: 'onTeam' as const,\n teamId: membership.teamId,\n }));\n const pendingJoinRequest = facts.pendingJoinRequests\n .filter(\n (request) =>\n !(\n actedOn?.kind === 'teamJoinRequest' &&\n actedOn.teamJoinRequestId === request.teamJoinRequestId\n ),\n )\n .map((request) => ({ state: 'pendingJoinRequest' as const, teamId: request.teamId }));\n const pendingInvitation = facts.pendingInvitations\n .filter(\n (invitation) =>\n !(\n actedOn?.kind === 'teamInvitation' &&\n actedOn.teamInvitationId === invitation.teamInvitationId\n ),\n )\n .map((invitation) => ({ state: 'pendingInvitation' as const, teamId: invitation.teamId }));\n const freeAgentSignup: LeagueJoinWarningFinding[] =\n facts.freeAgentSignup && actedOn?.kind !== 'leagueFreeAgent'\n ? [{ state: 'freeAgentSignup', teamId: null }]\n : [];\n\n return [\n ...onTeam.sort(byTeam),\n ...pendingJoinRequest.sort(byTeam),\n ...pendingInvitation.sort(byTeam),\n ...freeAgentSignup,\n ];\n}\n\nexport const LEAGUE_JOIN_WARNING_COPY = {\n title: 'Already in this league',\n confirmLabel: 'Continue',\n cancelLabel: 'Cancel',\n // What the person acting on their own behalf is told, per state found.\n self: {\n onTeam: (teamName: string) => `You are already on ${teamName}.`,\n pendingJoinRequest: (teamName: string) => `You have a request waiting with ${teamName}.`,\n pendingInvitation: (teamName: string) => `You have an invitation waiting from ${teamName}.`,\n freeAgentSignup: () => 'You are signed up as a free agent in this league.',\n },\n // What someone acting on the person is told, per state found.\n other: {\n onTeam: (personName: string, teamName: string) => `${personName} is already on ${teamName}.`,\n pendingJoinRequest: (personName: string, teamName: string) =>\n `${personName} has asked to join ${teamName}.`,\n pendingInvitation: (personName: string, teamName: string) =>\n `${personName} has an invitation waiting from ${teamName}.`,\n freeAgentSignup: (personName: string) =>\n `${personName} is signed up as a free agent in this league.`,\n },\n // The closing question, per door. `targetTeamName` is ignored by the doors that have no team.\n question: {\n createTeam: () => 'Do you still want to create a new team?',\n acceptInvitation: (targetTeamName: string) => `Do you still want to join ${targetTeamName}?`,\n sendJoinRequest: (targetTeamName: string) =>\n `Do you still want to ask to join ${targetTeamName}?`,\n signUpAsFreeAgent: () => 'Do you still want to sign up as a free agent?',\n sendInvitation: (targetTeamName: string) => `Invite them to ${targetTeamName} anyway?`,\n acceptJoinRequest: (targetTeamName: string) => `Accept them onto ${targetTeamName} anyway?`,\n assignFreeAgent: (targetTeamName: string) => `Assign them to ${targetTeamName} anyway?`,\n closedLeagueLink: (targetTeamName: string) => `Link them to ${targetTeamName} anyway?`,\n } satisfies Record<LeagueJoinWarningAction, (targetTeamName: string) => string>,\n} as const;\n\nexport interface LeagueJoinWarningText {\n /** One sentence per finding, in the findings' order. */\n lines: string[];\n question: string;\n}\n\n/**\n * The dialog's words for a warning. `teamName` resolves a finding's team id to its display name;\n * `personName` names the person for a door acting on someone else. Empty findings are no warning,\n * and a caller shows no dialog for them.\n */\nexport function formatLeagueJoinWarning(args: {\n action: LeagueJoinWarningAction;\n findings: readonly LeagueJoinWarningFinding[];\n teamName: (teamId: string) => string;\n personName: string;\n targetTeamName: string;\n}): LeagueJoinWarningText {\n const perspective = LEAGUE_JOIN_WARNING_PERSPECTIVE_BY_ACTION[args.action];\n const lines = args.findings.map((finding) => {\n const team = finding.teamId === null ? '' : args.teamName(finding.teamId);\n if (perspective === 'self') {\n return LEAGUE_JOIN_WARNING_COPY.self[finding.state](team);\n }\n return LEAGUE_JOIN_WARNING_COPY.other[finding.state](args.personName, team);\n });\n return { lines, question: LEAGUE_JOIN_WARNING_COPY.question[args.action](args.targetTeamName) };\n}\n"]}
1
+ {"version":3,"file":"league-join-warning.js","sourceRoot":"","sources":["../../src/utils/league-join-warning.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,gGAAgG;AAChG,sFAAsF;AACtF,EAAE;AACF,mGAAmG;AACnG,8EAA8E;AAC9E,kGAAkG;AAClG,gGAAgG;AAChG,sHAAsH;AACtH,0EAA0E;AAE1E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEtF,kDAAkD;AAClD,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,QAAQ;IACR,oBAAoB;IACpB,mBAAmB;IACnB,iBAAiB;CACT,CAAC;AAGX,iGAAiG;AACjG,8BAA8B;AAC9B,MAAM,CAAC,MAAM,iCAAiC,GAAG;IAC/C,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;CACT,CAAC;AAGX,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IACzE,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAuD,CAAC;QACxE,gBAAgB,EAAE,sBAAsB;KACzC,CAAC;SACD,MAAM,EAAE;IACX,CAAC;SACE,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAwD,CAAC;QACzE,iBAAiB,EAAE,uBAAuB;KAC3C,CAAC;SACD,MAAM,EAAE;IACX,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAwD,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;CACjG,CAAC,CAAC;AAGH,+FAA+F;AAC/F,wCAAwC;AACxC,MAAM,CAAC,MAAM,+BAA+B,GAAG;IAC7C,YAAY;IACZ,kBAAkB;IAClB,iBAAiB;IACjB,mBAAmB;IACnB,gBAAgB;IAChB,mBAAmB;IACnB,iBAAiB;IACjB,kBAAkB;CACV,CAAC;AAGX,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAU,CAAC;AAG/E,MAAM,CAAC,MAAM,yCAAyC,GAElD;IACF,UAAU,EAAE,MAAM;IAClB,gBAAgB,EAAE,MAAM;IACxB,eAAe,EAAE,MAAM;IACvB,iBAAiB,EAAE,MAAM;IACzB,cAAc,EAAE,OAAO;IACvB,iBAAiB,EAAE,OAAO;IAC1B,eAAe,EAAE,OAAO;IACxB,gBAAgB,EAAE,OAAO;CAC1B,CAAC;AAUF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC;KAC5C,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC;KAC1F,MAAM,EAAE,CAAC;AAGZ;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAA6B,EAC7B,OAAwC;IAExC,MAAM,MAAM,GAAG,CAAC,IAA8B,EAAE,KAA+B,EAAE,EAAE,CACjF,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IAExD,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACpD,KAAK,EAAE,QAAiB;QACxB,MAAM,EAAE,UAAU,CAAC,MAAM;KAC1B,CAAC,CAAC,CAAC;IACJ,MAAM,kBAAkB,GAAG,KAAK,CAAC,mBAAmB;SACjD,MAAM,CACL,CAAC,OAAO,EAAE,EAAE,CACV,CAAC,CACC,OAAO,EAAE,IAAI,KAAK,iBAAiB;QACnC,OAAO,CAAC,iBAAiB,KAAK,OAAO,CAAC,iBAAiB,CACxD,CACJ;SACA,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,oBAA6B,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACxF,MAAM,iBAAiB,GAAG,KAAK,CAAC,kBAAkB;SAC/C,MAAM,CACL,CAAC,UAAU,EAAE,EAAE,CACb,CAAC,CACC,OAAO,EAAE,IAAI,KAAK,gBAAgB;QAClC,OAAO,CAAC,gBAAgB,KAAK,UAAU,CAAC,gBAAgB,CACzD,CACJ;SACA,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,mBAA4B,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7F,MAAM,eAAe,GACnB,KAAK,CAAC,eAAe,IAAI,OAAO,EAAE,IAAI,KAAK,iBAAiB;QAC1D,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC9C,CAAC,CAAC,EAAE,CAAC;IAET,OAAO;QACL,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QACtB,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;QAClC,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;QACjC,GAAG,eAAe;KACnB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,KAAK,EAAE,wBAAwB;IAC/B,YAAY,EAAE,UAAU;IACxB,WAAW,EAAE,QAAQ;IACrB,uEAAuE;IACvE,IAAI,EAAE;QACJ,MAAM,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,sBAAsB,QAAQ,GAAG;QAC/D,kBAAkB,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,mCAAmC,QAAQ,GAAG;QACxF,iBAAiB,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,uCAAuC,QAAQ,GAAG;QAC3F,eAAe,EAAE,GAAG,EAAE,CAAC,mDAAmD;KAC3E;IACD,8DAA8D;IAC9D,KAAK,EAAE;QACL,MAAM,EAAE,CAAC,UAAkB,EAAE,QAAgB,EAAE,EAAE,CAAC,GAAG,UAAU,kBAAkB,QAAQ,GAAG;QAC5F,kBAAkB,EAAE,CAAC,UAAkB,EAAE,QAAgB,EAAE,EAAE,CAC3D,GAAG,UAAU,sBAAsB,QAAQ,GAAG;QAChD,iBAAiB,EAAE,CAAC,UAAkB,EAAE,QAAgB,EAAE,EAAE,CAC1D,GAAG,UAAU,mCAAmC,QAAQ,GAAG;QAC7D,eAAe,EAAE,CAAC,UAAkB,EAAE,EAAE,CACtC,GAAG,UAAU,+CAA+C;KAC/D;IACD,8FAA8F;IAC9F,QAAQ,EAAE;QACR,UAAU,EAAE,GAAG,EAAE,CAAC,yCAAyC;QAC3D,gBAAgB,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,6BAA6B,cAAc,GAAG;QAC5F,eAAe,EAAE,CAAC,cAAsB,EAAE,EAAE,CAC1C,oCAAoC,cAAc,GAAG;QACvD,iBAAiB,EAAE,GAAG,EAAE,CAAC,+CAA+C;QACxE,cAAc,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,kBAAkB,cAAc,UAAU;QACtF,iBAAiB,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,oBAAoB,cAAc,UAAU;QAC3F,eAAe,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,kBAAkB,cAAc,UAAU;QACvF,gBAAgB,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,gBAAgB,cAAc,UAAU;KACT;CACvE,CAAC;AAQX;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAMvC;IACC,MAAM,WAAW,GAAG,yCAAyC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1E,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;YAC3B,OAAO,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,wBAAwB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,wBAAwB,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;AAClG,CAAC","sourcesContent":["// The join warning: before anyone puts a person on a team in a league, or starts\n// their way onto one, they see every place that person already stands there. It warns and never\n// blocks — confirm proceeds, cancel does nothing, and no server check refuses for it.\n//\n// One decision serves every door: `computeLeagueJoinWarning` is the whole rule, and the one reader\n// of the person's standing is the server core behind `getLeagueJoinWarning` /\n// `adminGetLeagueJoinWarning`, because another person's pending requests, invitations, and signup\n// are not readable from the client. What the dialog says is `LEAGUE_JOIN_WARNING_COPY`, through\n// `formatLeagueJoinWarning` (RULE-STD-ARCH-102, RULE-STD-ENG-005). The acted-on item and a finding cross the wire, so\n// each is declared once, as its schema, and its type is inferred from it.\n\nimport { z } from 'zod';\nimport { teamIdSchema } from '../doc-schemas/atoms.js';\nimport { teamInvitationIdSchema, teamJoinRequestIdSchema } from '../schemas/atoms.js';\n\n// The four places a person can stand in a league.\nexport const LEAGUE_JOIN_WARNING_STATE_KEYS = [\n 'onTeam',\n 'pendingJoinRequest',\n 'pendingInvitation',\n 'freeAgentSignup',\n] as const;\nexport type LeagueJoinWarningState = (typeof LEAGUE_JOIN_WARNING_STATE_KEYS)[number];\n\n// The item a door acts on, which the warning never names: accepting a team's invitation does not\n// warn about that invitation.\nexport const LEAGUE_JOIN_WARNING_ACTED_ON_KEYS = [\n 'teamInvitation',\n 'teamJoinRequest',\n 'leagueFreeAgent',\n] as const;\nexport type LeagueJoinWarningActedOnKind = (typeof LEAGUE_JOIN_WARNING_ACTED_ON_KEYS)[number];\n\nexport const leagueJoinWarningActedOnSchema = z.discriminatedUnion('kind', [\n z\n .object({\n kind: z.literal('teamInvitation' satisfies LeagueJoinWarningActedOnKind),\n teamInvitationId: teamInvitationIdSchema,\n })\n .strict(),\n z\n .object({\n kind: z.literal('teamJoinRequest' satisfies LeagueJoinWarningActedOnKind),\n teamJoinRequestId: teamJoinRequestIdSchema,\n })\n .strict(),\n z.object({ kind: z.literal('leagueFreeAgent' satisfies LeagueJoinWarningActedOnKind) }).strict(),\n]);\nexport type LeagueJoinWarningActedOn = z.infer<typeof leagueJoinWarningActedOnSchema>;\n\n// Every door that shows the warning. Each is phrased either for the person acting on their own\n// behalf or for someone acting on them.\nexport const LEAGUE_JOIN_WARNING_ACTION_KEYS = [\n 'createTeam',\n 'acceptInvitation',\n 'sendJoinRequest',\n 'signUpAsFreeAgent',\n 'sendInvitation',\n 'acceptJoinRequest',\n 'assignFreeAgent',\n 'closedLeagueLink',\n] as const;\nexport type LeagueJoinWarningAction = (typeof LEAGUE_JOIN_WARNING_ACTION_KEYS)[number];\n\nexport const LEAGUE_JOIN_WARNING_PERSPECTIVE_KEYS = ['self', 'other'] as const;\nexport type LeagueJoinWarningPerspective = (typeof LEAGUE_JOIN_WARNING_PERSPECTIVE_KEYS)[number];\n\nexport const LEAGUE_JOIN_WARNING_PERSPECTIVE_BY_ACTION: Readonly<\n Record<LeagueJoinWarningAction, LeagueJoinWarningPerspective>\n> = {\n createTeam: 'self',\n acceptInvitation: 'self',\n sendJoinRequest: 'self',\n signUpAsFreeAgent: 'self',\n sendInvitation: 'other',\n acceptJoinRequest: 'other',\n assignFreeAgent: 'other',\n closedLeagueLink: 'other',\n};\n\n/** Where the person stands in the league, as the server read it. */\nexport interface LeagueJoinWarningFacts {\n memberships: readonly { teamId: string }[];\n pendingJoinRequests: readonly { teamJoinRequestId: string; teamId: string }[];\n pendingInvitations: readonly { teamInvitationId: string; teamId: string }[];\n freeAgentSignup: boolean;\n}\n\n// One place the person stands. `teamId` is null only for a free-agent signup.\nexport const leagueJoinWarningFindingSchema = z\n .object({ state: z.enum(LEAGUE_JOIN_WARNING_STATE_KEYS), teamId: teamIdSchema.nullable() })\n .strict();\nexport type LeagueJoinWarningFinding = z.infer<typeof leagueJoinWarningFindingSchema>;\n\n/**\n * Every place the person stands in the league, the acted-on item left out, in state order and then\n * team order. An empty result means no warning is shown.\n */\nexport function computeLeagueJoinWarning(\n facts: LeagueJoinWarningFacts,\n actedOn: LeagueJoinWarningActedOn | null,\n): LeagueJoinWarningFinding[] {\n const byTeam = (left: LeagueJoinWarningFinding, right: LeagueJoinWarningFinding) =>\n (left.teamId ?? '').localeCompare(right.teamId ?? '');\n\n const onTeam = facts.memberships.map((membership) => ({\n state: 'onTeam' as const,\n teamId: membership.teamId,\n }));\n const pendingJoinRequest = facts.pendingJoinRequests\n .filter(\n (request) =>\n !(\n actedOn?.kind === 'teamJoinRequest' &&\n actedOn.teamJoinRequestId === request.teamJoinRequestId\n ),\n )\n .map((request) => ({ state: 'pendingJoinRequest' as const, teamId: request.teamId }));\n const pendingInvitation = facts.pendingInvitations\n .filter(\n (invitation) =>\n !(\n actedOn?.kind === 'teamInvitation' &&\n actedOn.teamInvitationId === invitation.teamInvitationId\n ),\n )\n .map((invitation) => ({ state: 'pendingInvitation' as const, teamId: invitation.teamId }));\n const freeAgentSignup: LeagueJoinWarningFinding[] =\n facts.freeAgentSignup && actedOn?.kind !== 'leagueFreeAgent'\n ? [{ state: 'freeAgentSignup', teamId: null }]\n : [];\n\n return [\n ...onTeam.sort(byTeam),\n ...pendingJoinRequest.sort(byTeam),\n ...pendingInvitation.sort(byTeam),\n ...freeAgentSignup,\n ];\n}\n\nexport const LEAGUE_JOIN_WARNING_COPY = {\n title: 'Already in this league',\n confirmLabel: 'Continue',\n cancelLabel: 'Cancel',\n // What the person acting on their own behalf is told, per state found.\n self: {\n onTeam: (teamName: string) => `You are already on ${teamName}.`,\n pendingJoinRequest: (teamName: string) => `You have a request waiting with ${teamName}.`,\n pendingInvitation: (teamName: string) => `You have an invitation waiting from ${teamName}.`,\n freeAgentSignup: () => 'You are signed up as a free agent in this league.',\n },\n // What someone acting on the person is told, per state found.\n other: {\n onTeam: (personName: string, teamName: string) => `${personName} is already on ${teamName}.`,\n pendingJoinRequest: (personName: string, teamName: string) =>\n `${personName} has asked to join ${teamName}.`,\n pendingInvitation: (personName: string, teamName: string) =>\n `${personName} has an invitation waiting from ${teamName}.`,\n freeAgentSignup: (personName: string) =>\n `${personName} is signed up as a free agent in this league.`,\n },\n // The closing question, per door. `targetTeamName` is ignored by the doors that have no team.\n question: {\n createTeam: () => 'Do you still want to create a new team?',\n acceptInvitation: (targetTeamName: string) => `Do you still want to join ${targetTeamName}?`,\n sendJoinRequest: (targetTeamName: string) =>\n `Do you still want to ask to join ${targetTeamName}?`,\n signUpAsFreeAgent: () => 'Do you still want to sign up as a free agent?',\n sendInvitation: (targetTeamName: string) => `Invite them to ${targetTeamName} anyway?`,\n acceptJoinRequest: (targetTeamName: string) => `Accept them onto ${targetTeamName} anyway?`,\n assignFreeAgent: (targetTeamName: string) => `Assign them to ${targetTeamName} anyway?`,\n closedLeagueLink: (targetTeamName: string) => `Link them to ${targetTeamName} anyway?`,\n } satisfies Record<LeagueJoinWarningAction, (targetTeamName: string) => string>,\n} as const;\n\nexport interface LeagueJoinWarningText {\n /** One sentence per finding, in the findings' order. */\n lines: string[];\n question: string;\n}\n\n/**\n * The dialog's words for a warning. `teamName` resolves a finding's team id to its display name;\n * `personName` names the person for a door acting on someone else. Empty findings are no warning,\n * and a caller shows no dialog for them.\n */\nexport function formatLeagueJoinWarning(args: {\n action: LeagueJoinWarningAction;\n findings: readonly LeagueJoinWarningFinding[];\n teamName: (teamId: string) => string;\n personName: string;\n targetTeamName: string;\n}): LeagueJoinWarningText {\n const perspective = LEAGUE_JOIN_WARNING_PERSPECTIVE_BY_ACTION[args.action];\n const lines = args.findings.map((finding) => {\n const team = finding.teamId === null ? '' : args.teamName(finding.teamId);\n if (perspective === 'self') {\n return LEAGUE_JOIN_WARNING_COPY.self[finding.state](team);\n }\n return LEAGUE_JOIN_WARNING_COPY.other[finding.state](args.personName, team);\n });\n return { lines, question: LEAGUE_JOIN_WARNING_COPY.question[args.action](args.targetTeamName) };\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  // Whether a league takes new members. A closed league's season is over and `closed` is final, so no
2
2
  // door puts a person on one of its teams: sending or accepting an invitation, sending or accepting a
3
3
  // join request, free-agent signup, and the admin's free-agent placement each refuse it, reading the
4
- // league inside their transaction, and the UI does not offer them there (FRONTEND-110). The one way
4
+ // league inside their transaction, and the UI does not offer them there (RULE-STD-FRONTEND-110). The one way
5
5
  // onto a closed league's team is the admin's closed-league ghost link. An admin still creates teams
6
6
  // and edits the schedule on a closed league, to repair a past season.
7
7
  import { CLOSED_LEAGUE_STATUS } from '../types/unions.js';
@@ -1 +1 @@
1
- {"version":3,"file":"league-joining.js","sourceRoot":"","sources":["../../src/utils/league-joining.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,qGAAqG;AACrG,oGAAoG;AACpG,oGAAoG;AACpG,oGAAoG;AACpG,sEAAsE;AAEtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG1D,iFAAiF;AACjF,MAAM,UAAU,qBAAqB,CAAC,MAAoB;IACxD,OAAO,MAAM,KAAK,oBAAoB,CAAC;AACzC,CAAC","sourcesContent":["// Whether a league takes new members. A closed league's season is over and `closed` is final, so no\n// door puts a person on one of its teams: sending or accepting an invitation, sending or accepting a\n// join request, free-agent signup, and the admin's free-agent placement each refuse it, reading the\n// league inside their transaction, and the UI does not offer them there (FRONTEND-110). The one way\n// onto a closed league's team is the admin's closed-league ghost link. An admin still creates teams\n// and edits the schedule on a closed league, to repair a past season.\n\nimport { CLOSED_LEAGUE_STATUS } from '../types/unions.js';\nimport type { LeagueStatus } from '../types/unions.js';\n\n/** Whether a league in `status` takes new members: every status but `closed`. */\nexport function leagueTakesNewMembers(status: LeagueStatus): boolean {\n return status !== CLOSED_LEAGUE_STATUS;\n}\n"]}
1
+ {"version":3,"file":"league-joining.js","sourceRoot":"","sources":["../../src/utils/league-joining.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,qGAAqG;AACrG,oGAAoG;AACpG,6GAA6G;AAC7G,oGAAoG;AACpG,sEAAsE;AAEtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG1D,iFAAiF;AACjF,MAAM,UAAU,qBAAqB,CAAC,MAAoB;IACxD,OAAO,MAAM,KAAK,oBAAoB,CAAC;AACzC,CAAC","sourcesContent":["// Whether a league takes new members. A closed league's season is over and `closed` is final, so no\n// door puts a person on one of its teams: sending or accepting an invitation, sending or accepting a\n// join request, free-agent signup, and the admin's free-agent placement each refuse it, reading the\n// league inside their transaction, and the UI does not offer them there (RULE-STD-FRONTEND-110). The one way\n// onto a closed league's team is the admin's closed-league ghost link. An admin still creates teams\n// and edits the schedule on a closed league, to repair a past season.\n\nimport { CLOSED_LEAGUE_STATUS } from '../types/unions.js';\nimport type { LeagueStatus } from '../types/unions.js';\n\n/** Whether a league in `status` takes new members: every status but `closed`. */\nexport function leagueTakesNewMembers(status: LeagueStatus): boolean {\n return status !== CLOSED_LEAGUE_STATUS;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  // Whether a league sorts its teams by type. It is the one reading every surface makes — the team
2
2
  // form's required type, the type control, the standings and rankings split into pools, the team list
3
- // grouped by type, and the admin's mode copy — so no reader compares the mode on its own (ENG-005).
3
+ // grouped by type, and the admin's mode copy — so no reader compares the mode on its own (RULE-STD-ENG-005).
4
4
  import { TEAM_TYPED_LEAGUE_MODE } from '../types/unions.js';
5
5
  /** Whether a league in `mode` sorts its teams by type, so each team carries a `teamType`. */
6
6
  export function leagueModeSortsTeamsByType(mode) {
@@ -1 +1 @@
1
- {"version":3,"file":"league-mode.js","sourceRoot":"","sources":["../../src/utils/league-mode.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,qGAAqG;AACrG,oGAAoG;AAEpG,OAAO,EAAE,sBAAsB,EAAmB,MAAM,oBAAoB,CAAC;AAE7E,6FAA6F;AAC7F,MAAM,UAAU,0BAA0B,CAAC,IAAgB;IACzD,OAAO,IAAI,KAAK,sBAAsB,CAAC;AACzC,CAAC","sourcesContent":["// Whether a league sorts its teams by type. It is the one reading every surface makes — the team\n// form's required type, the type control, the standings and rankings split into pools, the team list\n// grouped by type, and the admin's mode copy — so no reader compares the mode on its own (ENG-005).\n\nimport { TEAM_TYPED_LEAGUE_MODE, type LeagueMode } from '../types/unions.js';\n\n/** Whether a league in `mode` sorts its teams by type, so each team carries a `teamType`. */\nexport function leagueModeSortsTeamsByType(mode: LeagueMode): boolean {\n return mode === TEAM_TYPED_LEAGUE_MODE;\n}\n"]}
1
+ {"version":3,"file":"league-mode.js","sourceRoot":"","sources":["../../src/utils/league-mode.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,qGAAqG;AACrG,6GAA6G;AAE7G,OAAO,EAAE,sBAAsB,EAAmB,MAAM,oBAAoB,CAAC;AAE7E,6FAA6F;AAC7F,MAAM,UAAU,0BAA0B,CAAC,IAAgB;IACzD,OAAO,IAAI,KAAK,sBAAsB,CAAC;AACzC,CAAC","sourcesContent":["// Whether a league sorts its teams by type. It is the one reading every surface makes — the team\n// form's required type, the type control, the standings and rankings split into pools, the team list\n// grouped by type, and the admin's mode copy — so no reader compares the mode on its own (RULE-STD-ENG-005).\n\nimport { TEAM_TYPED_LEAGUE_MODE, type LeagueMode } from '../types/unions.js';\n\n/** Whether a league in `mode` sorts its teams by type, so each team carries a `teamType`. */\nexport function leagueModeSortsTeamsByType(mode: LeagueMode): boolean {\n return mode === TEAM_TYPED_LEAGUE_MODE;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  // The team-creation window: a player may create a team in a league until TEAM_CREATION_CUTOFF_DAYS
2
2
  // days after the league's start date, inclusive. The create-team callable refuses a late creation
3
- // and the league page hides the affordance, both through these two functions (ENG-005). An admin
3
+ // and the league page hides the affordance, both through these two functions (RULE-STD-ENG-005). An admin
4
4
  // creating a team from the admin console is not held to the window.
5
5
  import { TEAM_CREATION_CUTOFF_DAYS } from '../constants/business.js';
6
6
  import { addCalendarDays } from './league-calendar.js';
@@ -1 +1 @@
1
- {"version":3,"file":"team-creation.js","sourceRoot":"","sources":["../../src/utils/team-creation.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,kGAAkG;AAClG,iGAAiG;AACjG,oEAAoE;AAEpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,qGAAqG;AACrG,MAAM,UAAU,mBAAmB,CAAC,eAAuB;IACzD,OAAO,eAAe,CAAC,eAAe,EAAE,yBAAyB,CAAC,CAAC;AACrE,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,kBAAkB,CAAC,eAAuB,EAAE,WAAmB;IAC7E,OAAO,WAAW,IAAI,mBAAmB,CAAC,eAAe,CAAC,CAAC;AAC7D,CAAC","sourcesContent":["// The team-creation window: a player may create a team in a league until TEAM_CREATION_CUTOFF_DAYS\n// days after the league's start date, inclusive. The create-team callable refuses a late creation\n// and the league page hides the affordance, both through these two functions (ENG-005). An admin\n// creating a team from the admin console is not held to the window.\n\nimport { TEAM_CREATION_CUTOFF_DAYS } from '../constants/business.js';\nimport { addCalendarDays } from './league-calendar.js';\n\n/** The last calendar day a player may create a team in a league that starts on `leagueStartDate`. */\nexport function teamCreationLastDay(leagueStartDate: string): string {\n return addCalendarDays(leagueStartDate, TEAM_CREATION_CUTOFF_DAYS);\n}\n\n/** Whether a player may still create a team on `todayDayKey` (see `toLeagueDayKey`). */\nexport function isTeamCreationOpen(leagueStartDate: string, todayDayKey: string): boolean {\n return todayDayKey <= teamCreationLastDay(leagueStartDate);\n}\n"]}
1
+ {"version":3,"file":"team-creation.js","sourceRoot":"","sources":["../../src/utils/team-creation.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,kGAAkG;AAClG,0GAA0G;AAC1G,oEAAoE;AAEpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,qGAAqG;AACrG,MAAM,UAAU,mBAAmB,CAAC,eAAuB;IACzD,OAAO,eAAe,CAAC,eAAe,EAAE,yBAAyB,CAAC,CAAC;AACrE,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,kBAAkB,CAAC,eAAuB,EAAE,WAAmB;IAC7E,OAAO,WAAW,IAAI,mBAAmB,CAAC,eAAe,CAAC,CAAC;AAC7D,CAAC","sourcesContent":["// The team-creation window: a player may create a team in a league until TEAM_CREATION_CUTOFF_DAYS\n// days after the league's start date, inclusive. The create-team callable refuses a late creation\n// and the league page hides the affordance, both through these two functions (RULE-STD-ENG-005). An admin\n// creating a team from the admin console is not held to the window.\n\nimport { TEAM_CREATION_CUTOFF_DAYS } from '../constants/business.js';\nimport { addCalendarDays } from './league-calendar.js';\n\n/** The last calendar day a player may create a team in a league that starts on `leagueStartDate`. */\nexport function teamCreationLastDay(leagueStartDate: string): string {\n return addCalendarDays(leagueStartDate, TEAM_CREATION_CUTOFF_DAYS);\n}\n\n/** Whether a player may still create a team on `todayDayKey` (see `toLeagueDayKey`). */\nexport function isTeamCreationOpen(leagueStartDate: string, todayDayKey: string): boolean {\n return todayDayKey <= teamCreationLastDay(leagueStartDate);\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  // What a team leader or an admin may do to one member of a team: promote a player to co-captain,
2
2
  // demote a co-captain to player, or remove them. The team's management callables refuse what this
3
- // leaves out, and the team page and the admin Teams tab offer exactly what it allows (FRONTEND-110):
3
+ // leaves out, and the team page and the admin Teams tab offer exactly what it allows (RULE-STD-FRONTEND-110):
4
4
  //
5
5
  // - the captain is never moved or removed here — an admin changes the team's captain first;
6
6
  // - only the captain and an admin promote or demote, and a ghost is never made a co-captain, since no
@@ -1 +1 @@
1
- {"version":3,"file":"team-member-actions.js","sourceRoot":"","sources":["../../src/utils/team-member-actions.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,kGAAkG;AAClG,qGAAqG;AACrG,EAAE;AACF,4FAA4F;AAC5F,sGAAsG;AACtG,uCAAuC;AACvC,2FAA2F;AAC3F,EAAE;AACF,+FAA+F;AAC/F,gBAAgB;AAGhB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GAGjB,MAAM,oBAAoB,CAAC;AAE5B,iFAAiF;AACjF,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAqC,CAAC;AAoB7E,MAAM,IAAI,GAAsB,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAEjF,MAAM,UAAU,iBAAiB,CAC/B,KAAsB,EACtB,MAAwB;IAExB,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,iBAAiB,GAAG,KAAK,KAAK,uBAAuB,IAAI,KAAK,KAAK,iBAAiB,CAAC;IAC3F,OAAO;QACL,OAAO,EAAE,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,MAAM,CAAC,OAAO;QACjF,MAAM,EAAE,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,oBAAoB;QACjE,MAAM,EAAE,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB;KAC9D,CAAC;AACJ,CAAC","sourcesContent":["// What a team leader or an admin may do to one member of a team: promote a player to co-captain,\n// demote a co-captain to player, or remove them. The team's management callables refuse what this\n// leaves out, and the team page and the admin Teams tab offer exactly what it allows (FRONTEND-110):\n//\n// - the captain is never moved or removed here — an admin changes the team's captain first;\n// - only the captain and an admin promote or demote, and a ghost is never made a co-captain, since no\n// one could act with that authority;\n// - a co-captain removes plain players only — never another co-captain, never the captain.\n//\n// A ghost leaves through its own removal, which decides whether it has played; that is still a\n// removal here.\n\nimport type { CaptainTeamRole } from '../types/audit.js';\nimport {\n TEAM_CAPTAIN_ROLE,\n TEAM_CO_CAPTAIN_ROLE,\n TEAM_PLAYER_ROLE,\n type SystemRole,\n type TeamRole,\n} from '../types/unions.js';\n\n/** An action on a member taken through its admin entry, under the admin role. */\nexport const TEAM_MEMBER_ADMIN_ACTOR = 'admin' as const satisfies SystemRole;\n\n/** The authority an action on a member is taken under: an admin, or the caller's role on the team. */\nexport type TeamMemberActor = typeof TEAM_MEMBER_ADMIN_ACTOR | CaptainTeamRole;\n\n/** The member acted on: their role on the team, and whether they are a ghost. */\nexport interface TeamMemberTarget {\n role: TeamRole;\n isGhost: boolean;\n}\n\nexport interface TeamMemberActions {\n /** Make the player a co-captain. */\n promote: boolean;\n /** Make the co-captain a player. */\n demote: boolean;\n /** Take them off the team — a ghost through the ghost removal. */\n remove: boolean;\n}\n\nconst NONE: TeamMemberActions = { promote: false, demote: false, remove: false };\n\nexport function teamMemberActions(\n actor: TeamMemberActor,\n target: TeamMemberTarget,\n): TeamMemberActions {\n if (target.role === TEAM_CAPTAIN_ROLE) return NONE;\n const managesCoCaptains = actor === TEAM_MEMBER_ADMIN_ACTOR || actor === TEAM_CAPTAIN_ROLE;\n return {\n promote: managesCoCaptains && target.role === TEAM_PLAYER_ROLE && !target.isGhost,\n demote: managesCoCaptains && target.role === TEAM_CO_CAPTAIN_ROLE,\n remove: managesCoCaptains || target.role === TEAM_PLAYER_ROLE,\n };\n}\n"]}
1
+ {"version":3,"file":"team-member-actions.js","sourceRoot":"","sources":["../../src/utils/team-member-actions.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,kGAAkG;AAClG,8GAA8G;AAC9G,EAAE;AACF,4FAA4F;AAC5F,sGAAsG;AACtG,uCAAuC;AACvC,2FAA2F;AAC3F,EAAE;AACF,+FAA+F;AAC/F,gBAAgB;AAGhB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GAGjB,MAAM,oBAAoB,CAAC;AAE5B,iFAAiF;AACjF,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAqC,CAAC;AAoB7E,MAAM,IAAI,GAAsB,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAEjF,MAAM,UAAU,iBAAiB,CAC/B,KAAsB,EACtB,MAAwB;IAExB,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,iBAAiB,GAAG,KAAK,KAAK,uBAAuB,IAAI,KAAK,KAAK,iBAAiB,CAAC;IAC3F,OAAO;QACL,OAAO,EAAE,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,MAAM,CAAC,OAAO;QACjF,MAAM,EAAE,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,oBAAoB;QACjE,MAAM,EAAE,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB;KAC9D,CAAC;AACJ,CAAC","sourcesContent":["// What a team leader or an admin may do to one member of a team: promote a player to co-captain,\n// demote a co-captain to player, or remove them. The team's management callables refuse what this\n// leaves out, and the team page and the admin Teams tab offer exactly what it allows (RULE-STD-FRONTEND-110):\n//\n// - the captain is never moved or removed here — an admin changes the team's captain first;\n// - only the captain and an admin promote or demote, and a ghost is never made a co-captain, since no\n// one could act with that authority;\n// - a co-captain removes plain players only — never another co-captain, never the captain.\n//\n// A ghost leaves through its own removal, which decides whether it has played; that is still a\n// removal here.\n\nimport type { CaptainTeamRole } from '../types/audit.js';\nimport {\n TEAM_CAPTAIN_ROLE,\n TEAM_CO_CAPTAIN_ROLE,\n TEAM_PLAYER_ROLE,\n type SystemRole,\n type TeamRole,\n} from '../types/unions.js';\n\n/** An action on a member taken through its admin entry, under the admin role. */\nexport const TEAM_MEMBER_ADMIN_ACTOR = 'admin' as const satisfies SystemRole;\n\n/** The authority an action on a member is taken under: an admin, or the caller's role on the team. */\nexport type TeamMemberActor = typeof TEAM_MEMBER_ADMIN_ACTOR | CaptainTeamRole;\n\n/** The member acted on: their role on the team, and whether they are a ghost. */\nexport interface TeamMemberTarget {\n role: TeamRole;\n isGhost: boolean;\n}\n\nexport interface TeamMemberActions {\n /** Make the player a co-captain. */\n promote: boolean;\n /** Make the co-captain a player. */\n demote: boolean;\n /** Take them off the team — a ghost through the ghost removal. */\n remove: boolean;\n}\n\nconst NONE: TeamMemberActions = { promote: false, demote: false, remove: false };\n\nexport function teamMemberActions(\n actor: TeamMemberActor,\n target: TeamMemberTarget,\n): TeamMemberActions {\n if (target.role === TEAM_CAPTAIN_ROLE) return NONE;\n const managesCoCaptains = actor === TEAM_MEMBER_ADMIN_ACTOR || actor === TEAM_CAPTAIN_ROLE;\n return {\n promote: managesCoCaptains && target.role === TEAM_PLAYER_ROLE && !target.isGhost,\n demote: managesCoCaptains && target.role === TEAM_CO_CAPTAIN_ROLE,\n remove: managesCoCaptains || target.role === TEAM_PLAYER_ROLE,\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/q-core",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "Core types, Firestore path constants, zod schemas, and shared constants for Q-Sports",
5
5
  "repository": {
6
6
  "type": "git",
@@ -78,8 +78,8 @@
78
78
  },
79
79
  "dependencies": {
80
80
  "@ttt-productions/input-format-core": "^0.1.3",
81
- "@ttt-productions/media-schemas": "^0.14.12",
82
- "@ttt-productions/notification-core": "^0.15.18",
81
+ "@ttt-productions/media-schemas": "^0.14.14",
82
+ "@ttt-productions/notification-core": "^0.15.22",
83
83
  "@ttt-productions/theme-core": "^0.12.15",
84
84
  "zod": "^4.4.3"
85
85
  },