jansathi-community-schema 0.17.0 → 0.18.0

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.
package/dist/index.d.ts CHANGED
@@ -21,11 +21,11 @@ export { COMMENT_MAX_BODY_CHARS, COMMENTS_PAGE_SIZE, COMMUNITIES_PAGE_SIZE, COMM
21
21
  export { type SetReactionBody, type SetReactionResponse, setReactionBodySchema, setReactionResponseSchema, type ToggleUpvoteResponse, toggleUpvoteResponseSchema, } from './engagement.js';
22
22
  export { CONTENT_KIND_VALUES, type ContentKind, contentKindSchema, FEED_SORT_VALUES, type FeedSort, feedSortSchema, PROFILE_PRIVACY_VALUES, type ProfilePrivacy, profilePrivacySchema, REACTION_TYPE_VALUES, REPORT_REASON_VALUES, REPORT_STATUS_VALUES, type ReactionType, type ReportReason, type ReportStatus, reactionTypeSchema, reportReasonSchema, reportStatusSchema, VISIBILITY_LEVEL_RANK, VISIBILITY_LEVEL_VALUES, type VisibilityLevel, visibilityLevelSchema, } from './enums.js';
23
23
  export { type DonateItemFeedItem, donateItemFeedItemSchema, type FeedItem, type FeedQueryParams, type FeedResponse, feedItemSchema, feedQueryParamsSchema, feedResponseSchema, type LostFoundFeedItem, lostFoundFeedItemSchema, type VoiceBoxFeedItem, voiceBoxFeedItemSchema, } from './feed.js';
24
- export { type CastVoteBody, castVoteBodySchema, type CommunityPollFeedItem, communityPollFeedItemSchema, type CommunityPollWire, communityPollWireSchema, type CreatePollBody, createPollBodySchema, type PollOptionInput, pollOptionInputSchema, type PollOptionWire, pollOptionWireSchema, POLL_RESULTS_VISIBILITY_VALUES, type PollResultsVisibility, pollResultsVisibilitySchema, type VoteResponse, voteResponseSchema, } from './poll.js';
25
24
  export { type AddGroupMembersBody, addGroupMembersBodySchema, type CommunityGroupWire, type CommunityGroupWithMembers, type CreateGroupBody, communityGroupWireSchema, communityGroupWithMembersSchema, createGroupBodySchema, type GroupMembersListResponse, type GroupMemberWire, type GroupRole, type GroupsListResponse, groupMembersListResponseSchema, groupMemberWireSchema, groupRoleSchema, groupsListResponseSchema, type UpdateGroupBody, updateGroupBodySchema, } from './group.js';
26
25
  export { type PostImage, type PostVideo, postImageSchema, postVideoSchema, } from './media.js';
26
+ export { type CastVoteBody, type CommunityPollFeedItem, type CommunityPollWire, type CreatePollBody, castVoteBodySchema, communityPollFeedItemSchema, communityPollWireSchema, createPollBodySchema, POLL_RESULTS_VISIBILITY_VALUES, type PollOptionInput, type PollOptionWire, type PollResultsVisibility, pollOptionInputSchema, pollOptionWireSchema, pollResultsVisibilitySchema, type VoteResponse, voteResponseSchema, } from './poll.js';
27
27
  export { type CommunityPostWire, type CreatePostBody, communityPostWireSchema, createPostBodySchema, type PostAuthorSnapshot, postAuthorSnapshotSchema, type RepostedSource, repostedSourceSchema, type UpdatePostBody, updatePostBodySchema, } from './post.js';
28
- export { type PeopleListItem, type PeopleListResponse, type PeopleQueryParams, type ProfileMutuals, type PublicProfileWire, peopleListItemSchema, peopleListResponseSchema, peopleQueryParamsSchema, profileMutualsSchema, publicProfileWireSchema, } from './profile.js';
28
+ export { PEOPLE_LIST_FILTER_DEFAULT, PEOPLE_LIST_FILTER_VALUES, type PeopleListFilter, type PeopleListItem, type PeopleListResponse, type PeopleQueryParams, type ProfileMutuals, type PublicProfileWire, peopleListFilterSchema, peopleListItemSchema, peopleListResponseSchema, peopleQueryParamsSchema, profileMutualsSchema, publicProfileWireSchema, } from './profile.js';
29
29
  export { type ReportContentBody, type ReportContentKind, type ReportRecordWire, type ReportSubmissionResponse, type ReportUserBody, reportContentBodySchema, reportContentKindSchema, reportRecordWireSchema, reportSubmissionResponseSchema, reportUserBodySchema, } from './report.js';
30
30
  export { type CreateRepostBody, type CreateRepostResponse, createRepostBodySchema, createRepostResponseSchema, } from './repost.js';
31
31
  export { type BlockedUsersListResponse, type BlockedUserWire, blockedUsersListResponseSchema, blockedUserWireSchema, COMMUNITY_SETTINGS_DEFAULTS, type CommunitySettingsWire, communitySettingsWireSchema, type UpdateCommunitySettingsBody, updateCommunitySettingsBodySchema, } from './settings.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -28,16 +28,16 @@ export { setReactionBodySchema, setReactionResponseSchema, toggleUpvoteResponseS
28
28
  export { CONTENT_KIND_VALUES, contentKindSchema, FEED_SORT_VALUES, feedSortSchema, PROFILE_PRIVACY_VALUES, profilePrivacySchema, REACTION_TYPE_VALUES, REPORT_REASON_VALUES, REPORT_STATUS_VALUES, reactionTypeSchema, reportReasonSchema, reportStatusSchema, VISIBILITY_LEVEL_RANK, VISIBILITY_LEVEL_VALUES, visibilityLevelSchema, } from './enums.js';
29
29
  // ─── Feed (polymorphic union) ──────────────────────────────────────────────
30
30
  export { donateItemFeedItemSchema, feedItemSchema, feedQueryParamsSchema, feedResponseSchema, lostFoundFeedItemSchema, voiceBoxFeedItemSchema, } from './feed.js';
31
- // ─── Poll ──────────────────────────────────────────────────────────────────
32
- export { castVoteBodySchema, communityPollFeedItemSchema, communityPollWireSchema, createPollBodySchema, pollOptionInputSchema, pollOptionWireSchema, POLL_RESULTS_VISIBILITY_VALUES, pollResultsVisibilitySchema, voteResponseSchema, } from './poll.js';
33
31
  // ─── Groups ────────────────────────────────────────────────────────────────
34
32
  export { addGroupMembersBodySchema, communityGroupWireSchema, communityGroupWithMembersSchema, createGroupBodySchema, groupMembersListResponseSchema, groupMemberWireSchema, groupRoleSchema, groupsListResponseSchema, updateGroupBodySchema, } from './group.js';
35
33
  // ─── Media ─────────────────────────────────────────────────────────────────
36
34
  export { postImageSchema, postVideoSchema, } from './media.js';
35
+ // ─── Poll ──────────────────────────────────────────────────────────────────
36
+ export { castVoteBodySchema, communityPollFeedItemSchema, communityPollWireSchema, createPollBodySchema, POLL_RESULTS_VISIBILITY_VALUES, pollOptionInputSchema, pollOptionWireSchema, pollResultsVisibilitySchema, voteResponseSchema, } from './poll.js';
37
37
  // ─── Post ──────────────────────────────────────────────────────────────────
38
38
  export { communityPostWireSchema, createPostBodySchema, postAuthorSnapshotSchema, repostedSourceSchema, updatePostBodySchema, } from './post.js';
39
39
  // ─── Profile + People list ─────────────────────────────────────────────────
40
- export { peopleListItemSchema, peopleListResponseSchema, peopleQueryParamsSchema, profileMutualsSchema, publicProfileWireSchema, } from './profile.js';
40
+ export { PEOPLE_LIST_FILTER_DEFAULT, PEOPLE_LIST_FILTER_VALUES, peopleListFilterSchema, peopleListItemSchema, peopleListResponseSchema, peopleQueryParamsSchema, profileMutualsSchema, publicProfileWireSchema, } from './profile.js';
41
41
  // ─── Reports (moderation) ──────────────────────────────────────────────────
42
42
  export { reportContentBodySchema, reportContentKindSchema, reportRecordWireSchema, reportSubmissionResponseSchema, reportUserBodySchema, } from './report.js';
43
43
  // ─── Repost (quote / amplify) ──────────────────────────────────────────────
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * community-schema — Shared Zod schemas + TypeScript types for the\n * Jansathi hyperlocal community feature (feed, posts, engagement,\n * social graph, groups, settings).\n *\n * Single source of truth consumed by reform-backend and every product\n * frontend. The schemas mirror MongoDB / Mongoose document shapes\n * 1:1 so the same Zod validation runs at the controller boundary on\n * the backend and in the form handlers on the client.\n *\n * Cascade-upward visibility semantics: a viewer whose feed level is L\n * sees posts at L and every BROADER level matching their area lineage.\n * See `./enums.ts#VISIBILITY_LEVEL_VALUES` for the level rank table.\n *\n * @module community-schema\n */\n\n// ─── Area lineage snapshot ─────────────────────────────────────────────────\nexport {\n type AreaLineageSnapshot,\n areaLineageSnapshotSchema,\n} from './area.js';\n\n// ─── Comment ───────────────────────────────────────────────────────────────\nexport {\n type CommunityCommentWire,\n type CreateCommentBody,\n communityCommentWireSchema,\n createCommentBodySchema,\n type UpdateCommentBody,\n updateCommentBodySchema,\n} from './comment.js';\n\n// ─── Communities ───────────────────────────────────────────────────────────\nexport {\n AREA_PICKER_LEVEL_VALUES,\n type AreaPickerItem,\n type AreaPickerLevel,\n type AreaPickerQuery,\n type AreaPickerResponse,\n areaPickerItemSchema,\n areaPickerLevelSchema,\n areaPickerQuerySchema,\n areaPickerResponseSchema,\n COMMUNITY_CATEGORY_VALUES,\n COMMUNITY_DESIGNATION_PRESETS,\n COMMUNITY_DISCOVER_SORT_VALUES,\n COMMUNITY_MEMBERSHIP_STATUS_VALUES,\n COMMUNITY_REACH_VALUES,\n COMMUNITY_ROLE_VALUES,\n COMMUNITY_TAG_VALUES,\n COMMUNITY_TYPE_VALUES,\n COMMUNITY_VERIFIED_SCOPE_VALUES,\n type CommunityCategory,\n type CommunityCenterCoords,\n type CommunityDesignation,\n type CommunityDesignationPreset,\n type CommunityDiscoverSort,\n type CommunityListQuery,\n type CommunityListResponse,\n type CommunityMembershipStatus,\n type CommunityMembersListResponse,\n type CommunityMemberWire,\n type CommunityReach,\n type CommunityRole,\n type CommunityTag,\n type CommunityType,\n type CommunityVerifiedScope,\n type CommunityWire,\n type CreateCommunityBody,\n communityCategorySchema,\n communityCenterCoordsSchema,\n communityDesignationPresetSchema,\n communityDesignationSchema,\n communityDiscoverSortSchema,\n communityListQuerySchema,\n communityListResponseSchema,\n communityMembershipStatusSchema,\n communityMembersListResponseSchema,\n communityMemberWireSchema,\n communityReachSchema,\n communityRoleSchema,\n communityTagSchema,\n communityTypeSchema,\n communityVerifiedScopeSchema,\n communityWireSchema,\n createCommunityBodySchema,\n type JoinCommunityResponse,\n joinCommunityResponseSchema,\n type SetMemberDesignationBody,\n setMemberDesignationBodySchema,\n type UpdateCommunityBody,\n type UpdateMemberRoleBody,\n updateCommunityBodySchema,\n updateMemberRoleBodySchema,\n type VerifyCommunityBody,\n verifyCommunityBodySchema,\n} from './community.js';\n\n// ─── Constants ─────────────────────────────────────────────────────────────\nexport {\n COMMENT_MAX_BODY_CHARS,\n COMMENTS_PAGE_SIZE,\n COMMUNITIES_PAGE_SIZE,\n COMMUNITY_DESCRIPTION_MAX_CHARS,\n COMMUNITY_DESIGNATION_CUSTOM_MAX_CHARS,\n COMMUNITY_DESIGNATION_CUSTOM_MIN_CHARS,\n COMMUNITY_DESIGNATION_CUSTOM_PATTERN,\n COMMUNITY_HYPERLOCAL_RADIUS_KM,\n COMMUNITY_MAX_TAGS,\n COMMUNITY_MEMBERS_PAGE_SIZE,\n COMMUNITY_NAME_MAX_CHARS,\n COMMUNITY_NAME_MIN_CHARS,\n COMMUNITY_SLUG_MAX_CHARS,\n COMMUNITY_SLUG_MIN_CHARS,\n COMMUNITY_SLUG_PATTERN,\n EDIT_GRACE_WINDOW_MS,\n FEED_PAGE_SIZE,\n GROUP_MAX_MEMBERS,\n GROUP_NAME_MAX_CHARS,\n GROUP_NAME_MIN_CHARS,\n PEOPLE_PAGE_SIZE,\n POLL_DURATION_PRESETS_MS,\n POLL_MAX_DURATION_MS,\n POLL_MAX_OPTIONS,\n POLL_MIN_DURATION_MS,\n POLL_MIN_OPTIONS,\n POLL_OPTION_MAX_CHARS,\n POLL_OPTION_MIN_CHARS,\n POLL_QUESTION_MAX_CHARS,\n POLL_QUESTION_MIN_CHARS,\n POLLS_PAGE_SIZE,\n POST_MAX_BODY_CHARS,\n POST_MAX_IMAGE_BYTES,\n POST_MAX_IMAGES,\n POST_MAX_VIDEO_BYTES,\n POST_MAX_VIDEO_SECONDS,\n POST_MAX_VIDEOS,\n PROFILE_MAX_BIO_CHARS,\n REPLIES_PRELOAD_COUNT,\n} from './constants.js';\n\n// ─── Engagement (upvote + reactions) ───────────────────────────────────────\nexport {\n type SetReactionBody,\n type SetReactionResponse,\n setReactionBodySchema,\n setReactionResponseSchema,\n type ToggleUpvoteResponse,\n toggleUpvoteResponseSchema,\n} from './engagement.js';\n\n// ─── Enums ─────────────────────────────────────────────────────────────────\nexport {\n CONTENT_KIND_VALUES,\n type ContentKind,\n contentKindSchema,\n FEED_SORT_VALUES,\n type FeedSort,\n feedSortSchema,\n PROFILE_PRIVACY_VALUES,\n type ProfilePrivacy,\n profilePrivacySchema,\n REACTION_TYPE_VALUES,\n REPORT_REASON_VALUES,\n REPORT_STATUS_VALUES,\n type ReactionType,\n type ReportReason,\n type ReportStatus,\n reactionTypeSchema,\n reportReasonSchema,\n reportStatusSchema,\n VISIBILITY_LEVEL_RANK,\n VISIBILITY_LEVEL_VALUES,\n type VisibilityLevel,\n visibilityLevelSchema,\n} from './enums.js';\n\n// ─── Feed (polymorphic union) ──────────────────────────────────────────────\nexport {\n type DonateItemFeedItem,\n donateItemFeedItemSchema,\n type FeedItem,\n type FeedQueryParams,\n type FeedResponse,\n feedItemSchema,\n feedQueryParamsSchema,\n feedResponseSchema,\n type LostFoundFeedItem,\n lostFoundFeedItemSchema,\n type VoiceBoxFeedItem,\n voiceBoxFeedItemSchema,\n} from './feed.js';\n\n// ─── Poll ──────────────────────────────────────────────────────────────────\nexport {\n type CastVoteBody,\n castVoteBodySchema,\n type CommunityPollFeedItem,\n communityPollFeedItemSchema,\n type CommunityPollWire,\n communityPollWireSchema,\n type CreatePollBody,\n createPollBodySchema,\n type PollOptionInput,\n pollOptionInputSchema,\n type PollOptionWire,\n pollOptionWireSchema,\n POLL_RESULTS_VISIBILITY_VALUES,\n type PollResultsVisibility,\n pollResultsVisibilitySchema,\n type VoteResponse,\n voteResponseSchema,\n} from './poll.js';\n\n// ─── Groups ────────────────────────────────────────────────────────────────\nexport {\n type AddGroupMembersBody,\n addGroupMembersBodySchema,\n type CommunityGroupWire,\n type CommunityGroupWithMembers,\n type CreateGroupBody,\n communityGroupWireSchema,\n communityGroupWithMembersSchema,\n createGroupBodySchema,\n type GroupMembersListResponse,\n type GroupMemberWire,\n type GroupRole,\n type GroupsListResponse,\n groupMembersListResponseSchema,\n groupMemberWireSchema,\n groupRoleSchema,\n groupsListResponseSchema,\n type UpdateGroupBody,\n updateGroupBodySchema,\n} from './group.js';\n\n// ─── Media ─────────────────────────────────────────────────────────────────\nexport {\n type PostImage,\n type PostVideo,\n postImageSchema,\n postVideoSchema,\n} from './media.js';\n\n// ─── Post ──────────────────────────────────────────────────────────────────\nexport {\n type CommunityPostWire,\n type CreatePostBody,\n communityPostWireSchema,\n createPostBodySchema,\n type PostAuthorSnapshot,\n postAuthorSnapshotSchema,\n type RepostedSource,\n repostedSourceSchema,\n type UpdatePostBody,\n updatePostBodySchema,\n} from './post.js';\n// ─── Profile + People list ─────────────────────────────────────────────────\nexport {\n type PeopleListItem,\n type PeopleListResponse,\n type PeopleQueryParams,\n type ProfileMutuals,\n type PublicProfileWire,\n peopleListItemSchema,\n peopleListResponseSchema,\n peopleQueryParamsSchema,\n profileMutualsSchema,\n publicProfileWireSchema,\n} from './profile.js';\n// ─── Reports (moderation) ──────────────────────────────────────────────────\nexport {\n type ReportContentBody,\n type ReportContentKind,\n type ReportRecordWire,\n type ReportSubmissionResponse,\n type ReportUserBody,\n reportContentBodySchema,\n reportContentKindSchema,\n reportRecordWireSchema,\n reportSubmissionResponseSchema,\n reportUserBodySchema,\n} from './report.js';\n// ─── Repost (quote / amplify) ──────────────────────────────────────────────\nexport {\n type CreateRepostBody,\n type CreateRepostResponse,\n createRepostBodySchema,\n createRepostResponseSchema,\n} from './repost.js';\n\n// ─── Settings ──────────────────────────────────────────────────────────────\nexport {\n type BlockedUsersListResponse,\n type BlockedUserWire,\n blockedUsersListResponseSchema,\n blockedUserWireSchema,\n COMMUNITY_SETTINGS_DEFAULTS,\n type CommunitySettingsWire,\n communitySettingsWireSchema,\n type UpdateCommunitySettingsBody,\n updateCommunitySettingsBodySchema,\n} from './settings.js';\n\n// ─── Social (follow) ───────────────────────────────────────────────────────\nexport {\n type ToggleFollowResponse,\n toggleFollowResponseSchema,\n type ViewerSocialState,\n viewerSocialStateSchema,\n} from './social.js';\n\n// ─── Username (URL handle + change / availability) ────────────────────────\nexport {\n type CurrentUsernameState,\n currentUsernameStateSchema,\n type UpdateUsernameBody,\n type UpdateUsernameResponse,\n USERNAME_MAX_LENGTH,\n USERNAME_MIN_LENGTH,\n USERNAME_PATTERN,\n USERNAME_UNAVAILABLE_REASONS,\n type Username,\n type UsernameAvailabilityResponse,\n type UsernameUnavailableReason,\n updateUsernameBodySchema,\n updateUsernameResponseSchema,\n usernameAvailabilityResponseSchema,\n usernameSchema,\n usernameUnavailableReasonSchema,\n} from './username.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * community-schema — Shared Zod schemas + TypeScript types for the\n * Jansathi hyperlocal community feature (feed, posts, engagement,\n * social graph, groups, settings).\n *\n * Single source of truth consumed by reform-backend and every product\n * frontend. The schemas mirror MongoDB / Mongoose document shapes\n * 1:1 so the same Zod validation runs at the controller boundary on\n * the backend and in the form handlers on the client.\n *\n * Cascade-upward visibility semantics: a viewer whose feed level is L\n * sees posts at L and every BROADER level matching their area lineage.\n * See `./enums.ts#VISIBILITY_LEVEL_VALUES` for the level rank table.\n *\n * @module community-schema\n */\n\n// ─── Area lineage snapshot ─────────────────────────────────────────────────\nexport {\n type AreaLineageSnapshot,\n areaLineageSnapshotSchema,\n} from './area.js';\n\n// ─── Comment ───────────────────────────────────────────────────────────────\nexport {\n type CommunityCommentWire,\n type CreateCommentBody,\n communityCommentWireSchema,\n createCommentBodySchema,\n type UpdateCommentBody,\n updateCommentBodySchema,\n} from './comment.js';\n\n// ─── Communities ───────────────────────────────────────────────────────────\nexport {\n AREA_PICKER_LEVEL_VALUES,\n type AreaPickerItem,\n type AreaPickerLevel,\n type AreaPickerQuery,\n type AreaPickerResponse,\n areaPickerItemSchema,\n areaPickerLevelSchema,\n areaPickerQuerySchema,\n areaPickerResponseSchema,\n COMMUNITY_CATEGORY_VALUES,\n COMMUNITY_DESIGNATION_PRESETS,\n COMMUNITY_DISCOVER_SORT_VALUES,\n COMMUNITY_MEMBERSHIP_STATUS_VALUES,\n COMMUNITY_REACH_VALUES,\n COMMUNITY_ROLE_VALUES,\n COMMUNITY_TAG_VALUES,\n COMMUNITY_TYPE_VALUES,\n COMMUNITY_VERIFIED_SCOPE_VALUES,\n type CommunityCategory,\n type CommunityCenterCoords,\n type CommunityDesignation,\n type CommunityDesignationPreset,\n type CommunityDiscoverSort,\n type CommunityListQuery,\n type CommunityListResponse,\n type CommunityMembershipStatus,\n type CommunityMembersListResponse,\n type CommunityMemberWire,\n type CommunityReach,\n type CommunityRole,\n type CommunityTag,\n type CommunityType,\n type CommunityVerifiedScope,\n type CommunityWire,\n type CreateCommunityBody,\n communityCategorySchema,\n communityCenterCoordsSchema,\n communityDesignationPresetSchema,\n communityDesignationSchema,\n communityDiscoverSortSchema,\n communityListQuerySchema,\n communityListResponseSchema,\n communityMembershipStatusSchema,\n communityMembersListResponseSchema,\n communityMemberWireSchema,\n communityReachSchema,\n communityRoleSchema,\n communityTagSchema,\n communityTypeSchema,\n communityVerifiedScopeSchema,\n communityWireSchema,\n createCommunityBodySchema,\n type JoinCommunityResponse,\n joinCommunityResponseSchema,\n type SetMemberDesignationBody,\n setMemberDesignationBodySchema,\n type UpdateCommunityBody,\n type UpdateMemberRoleBody,\n updateCommunityBodySchema,\n updateMemberRoleBodySchema,\n type VerifyCommunityBody,\n verifyCommunityBodySchema,\n} from './community.js';\n\n// ─── Constants ─────────────────────────────────────────────────────────────\nexport {\n COMMENT_MAX_BODY_CHARS,\n COMMENTS_PAGE_SIZE,\n COMMUNITIES_PAGE_SIZE,\n COMMUNITY_DESCRIPTION_MAX_CHARS,\n COMMUNITY_DESIGNATION_CUSTOM_MAX_CHARS,\n COMMUNITY_DESIGNATION_CUSTOM_MIN_CHARS,\n COMMUNITY_DESIGNATION_CUSTOM_PATTERN,\n COMMUNITY_HYPERLOCAL_RADIUS_KM,\n COMMUNITY_MAX_TAGS,\n COMMUNITY_MEMBERS_PAGE_SIZE,\n COMMUNITY_NAME_MAX_CHARS,\n COMMUNITY_NAME_MIN_CHARS,\n COMMUNITY_SLUG_MAX_CHARS,\n COMMUNITY_SLUG_MIN_CHARS,\n COMMUNITY_SLUG_PATTERN,\n EDIT_GRACE_WINDOW_MS,\n FEED_PAGE_SIZE,\n GROUP_MAX_MEMBERS,\n GROUP_NAME_MAX_CHARS,\n GROUP_NAME_MIN_CHARS,\n PEOPLE_PAGE_SIZE,\n POLL_DURATION_PRESETS_MS,\n POLL_MAX_DURATION_MS,\n POLL_MAX_OPTIONS,\n POLL_MIN_DURATION_MS,\n POLL_MIN_OPTIONS,\n POLL_OPTION_MAX_CHARS,\n POLL_OPTION_MIN_CHARS,\n POLL_QUESTION_MAX_CHARS,\n POLL_QUESTION_MIN_CHARS,\n POLLS_PAGE_SIZE,\n POST_MAX_BODY_CHARS,\n POST_MAX_IMAGE_BYTES,\n POST_MAX_IMAGES,\n POST_MAX_VIDEO_BYTES,\n POST_MAX_VIDEO_SECONDS,\n POST_MAX_VIDEOS,\n PROFILE_MAX_BIO_CHARS,\n REPLIES_PRELOAD_COUNT,\n} from './constants.js';\n\n// ─── Engagement (upvote + reactions) ───────────────────────────────────────\nexport {\n type SetReactionBody,\n type SetReactionResponse,\n setReactionBodySchema,\n setReactionResponseSchema,\n type ToggleUpvoteResponse,\n toggleUpvoteResponseSchema,\n} from './engagement.js';\n\n// ─── Enums ─────────────────────────────────────────────────────────────────\nexport {\n CONTENT_KIND_VALUES,\n type ContentKind,\n contentKindSchema,\n FEED_SORT_VALUES,\n type FeedSort,\n feedSortSchema,\n PROFILE_PRIVACY_VALUES,\n type ProfilePrivacy,\n profilePrivacySchema,\n REACTION_TYPE_VALUES,\n REPORT_REASON_VALUES,\n REPORT_STATUS_VALUES,\n type ReactionType,\n type ReportReason,\n type ReportStatus,\n reactionTypeSchema,\n reportReasonSchema,\n reportStatusSchema,\n VISIBILITY_LEVEL_RANK,\n VISIBILITY_LEVEL_VALUES,\n type VisibilityLevel,\n visibilityLevelSchema,\n} from './enums.js';\n\n// ─── Feed (polymorphic union) ──────────────────────────────────────────────\nexport {\n type DonateItemFeedItem,\n donateItemFeedItemSchema,\n type FeedItem,\n type FeedQueryParams,\n type FeedResponse,\n feedItemSchema,\n feedQueryParamsSchema,\n feedResponseSchema,\n type LostFoundFeedItem,\n lostFoundFeedItemSchema,\n type VoiceBoxFeedItem,\n voiceBoxFeedItemSchema,\n} from './feed.js';\n// ─── Groups ────────────────────────────────────────────────────────────────\nexport {\n type AddGroupMembersBody,\n addGroupMembersBodySchema,\n type CommunityGroupWire,\n type CommunityGroupWithMembers,\n type CreateGroupBody,\n communityGroupWireSchema,\n communityGroupWithMembersSchema,\n createGroupBodySchema,\n type GroupMembersListResponse,\n type GroupMemberWire,\n type GroupRole,\n type GroupsListResponse,\n groupMembersListResponseSchema,\n groupMemberWireSchema,\n groupRoleSchema,\n groupsListResponseSchema,\n type UpdateGroupBody,\n updateGroupBodySchema,\n} from './group.js';\n// ─── Media ─────────────────────────────────────────────────────────────────\nexport {\n type PostImage,\n type PostVideo,\n postImageSchema,\n postVideoSchema,\n} from './media.js';\n// ─── Poll ──────────────────────────────────────────────────────────────────\nexport {\n type CastVoteBody,\n type CommunityPollFeedItem,\n type CommunityPollWire,\n type CreatePollBody,\n castVoteBodySchema,\n communityPollFeedItemSchema,\n communityPollWireSchema,\n createPollBodySchema,\n POLL_RESULTS_VISIBILITY_VALUES,\n type PollOptionInput,\n type PollOptionWire,\n type PollResultsVisibility,\n pollOptionInputSchema,\n pollOptionWireSchema,\n pollResultsVisibilitySchema,\n type VoteResponse,\n voteResponseSchema,\n} from './poll.js';\n\n// ─── Post ──────────────────────────────────────────────────────────────────\nexport {\n type CommunityPostWire,\n type CreatePostBody,\n communityPostWireSchema,\n createPostBodySchema,\n type PostAuthorSnapshot,\n postAuthorSnapshotSchema,\n type RepostedSource,\n repostedSourceSchema,\n type UpdatePostBody,\n updatePostBodySchema,\n} from './post.js';\n// ─── Profile + People list ─────────────────────────────────────────────────\nexport {\n PEOPLE_LIST_FILTER_DEFAULT,\n PEOPLE_LIST_FILTER_VALUES,\n type PeopleListFilter,\n type PeopleListItem,\n type PeopleListResponse,\n type PeopleQueryParams,\n type ProfileMutuals,\n type PublicProfileWire,\n peopleListFilterSchema,\n peopleListItemSchema,\n peopleListResponseSchema,\n peopleQueryParamsSchema,\n profileMutualsSchema,\n publicProfileWireSchema,\n} from './profile.js';\n// ─── Reports (moderation) ──────────────────────────────────────────────────\nexport {\n type ReportContentBody,\n type ReportContentKind,\n type ReportRecordWire,\n type ReportSubmissionResponse,\n type ReportUserBody,\n reportContentBodySchema,\n reportContentKindSchema,\n reportRecordWireSchema,\n reportSubmissionResponseSchema,\n reportUserBodySchema,\n} from './report.js';\n// ─── Repost (quote / amplify) ──────────────────────────────────────────────\nexport {\n type CreateRepostBody,\n type CreateRepostResponse,\n createRepostBodySchema,\n createRepostResponseSchema,\n} from './repost.js';\n\n// ─── Settings ──────────────────────────────────────────────────────────────\nexport {\n type BlockedUsersListResponse,\n type BlockedUserWire,\n blockedUsersListResponseSchema,\n blockedUserWireSchema,\n COMMUNITY_SETTINGS_DEFAULTS,\n type CommunitySettingsWire,\n communitySettingsWireSchema,\n type UpdateCommunitySettingsBody,\n updateCommunitySettingsBodySchema,\n} from './settings.js';\n\n// ─── Social (follow) ───────────────────────────────────────────────────────\nexport {\n type ToggleFollowResponse,\n toggleFollowResponseSchema,\n type ViewerSocialState,\n viewerSocialStateSchema,\n} from './social.js';\n\n// ─── Username (URL handle + change / availability) ────────────────────────\nexport {\n type CurrentUsernameState,\n currentUsernameStateSchema,\n type UpdateUsernameBody,\n type UpdateUsernameResponse,\n USERNAME_MAX_LENGTH,\n USERNAME_MIN_LENGTH,\n USERNAME_PATTERN,\n USERNAME_UNAVAILABLE_REASONS,\n type Username,\n type UsernameAvailabilityResponse,\n type UsernameUnavailableReason,\n updateUsernameBodySchema,\n updateUsernameResponseSchema,\n usernameAvailabilityResponseSchema,\n usernameSchema,\n usernameUnavailableReasonSchema,\n} from './username.js';\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../src/poll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,8BAA8B,kCAAmC,CAAC;AAC/E,eAAO,MAAM,2BAA2B;;;EAAyC,CAAC;AAClF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAIhF;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB;;;;iBAI/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,gDAAgD;AAChD,eAAO,MAAM,qBAAqB;;iBAMhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAIpE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+DlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA0B,CAAC;AACnE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAIhF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;iBAwC9B,CAAC;AACJ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAIlE;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB;;iBAK7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAE7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
1
+ {"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../src/poll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,8BAA8B,kCAAmC,CAAC;AAC/E,eAAO,MAAM,2BAA2B;;;EAAyC,CAAC;AAClF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAIhF;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB;;;;iBAQ/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,gDAAgD;AAChD,eAAO,MAAM,qBAAqB;;iBAEhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAIpE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4DlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA0B,CAAC;AACnE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAIhF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;iBA6B9B,CAAC;AACJ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAIlE;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB;;iBAW7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAE7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
package/dist/poll.js CHANGED
@@ -59,17 +59,17 @@ export const pollResultsVisibilitySchema = z.enum(POLL_RESULTS_VISIBILITY_VALUES
59
59
  * is `after_close` AND the poll is still open.
60
60
  */
61
61
  export const pollOptionWireSchema = z.object({
62
- index: z.number().int().min(0).max(POLL_MAX_OPTIONS - 1),
62
+ index: z
63
+ .number()
64
+ .int()
65
+ .min(0)
66
+ .max(POLL_MAX_OPTIONS - 1),
63
67
  label: z.string().min(POLL_OPTION_MIN_CHARS).max(POLL_OPTION_MAX_CHARS),
64
68
  voteCount: z.number().int().nonnegative(),
65
69
  });
66
70
  /** Composer-side option (no vote count yet). */
67
71
  export const pollOptionInputSchema = z.object({
68
- label: z
69
- .string()
70
- .trim()
71
- .min(POLL_OPTION_MIN_CHARS)
72
- .max(POLL_OPTION_MAX_CHARS),
72
+ label: z.string().trim().min(POLL_OPTION_MIN_CHARS).max(POLL_OPTION_MAX_CHARS),
73
73
  });
74
74
  // ─── Wire shape — what the server returns ──────────────────────────────────
75
75
  /**
@@ -88,10 +88,7 @@ export const communityPollWireSchema = z.object({
88
88
  * open AND `resultsVisibility === 'after_close'` (the
89
89
  * total-voters count is still surfaced so the card can show
90
90
  * "X voted" without revealing how it splits). */
91
- options: z
92
- .array(pollOptionWireSchema)
93
- .min(POLL_MIN_OPTIONS)
94
- .max(POLL_MAX_OPTIONS),
91
+ options: z.array(pollOptionWireSchema).min(POLL_MIN_OPTIONS).max(POLL_MAX_OPTIONS),
95
92
  /** Number of UNIQUE voters. Always visible — even when option
96
93
  * counts are hidden — so the card can render "X have voted" as a
97
94
  * social proof signal. */
@@ -151,25 +148,14 @@ export const communityPollFeedItemSchema = communityPollWireSchema;
151
148
  */
152
149
  export const createPollBodySchema = z
153
150
  .object({
154
- question: z
155
- .string()
156
- .trim()
157
- .min(POLL_QUESTION_MIN_CHARS)
158
- .max(POLL_QUESTION_MAX_CHARS),
159
- options: z
160
- .array(pollOptionInputSchema)
161
- .min(POLL_MIN_OPTIONS)
162
- .max(POLL_MAX_OPTIONS),
151
+ question: z.string().trim().min(POLL_QUESTION_MIN_CHARS).max(POLL_QUESTION_MAX_CHARS),
152
+ options: z.array(pollOptionInputSchema).min(POLL_MIN_OPTIONS).max(POLL_MAX_OPTIONS),
163
153
  /** Duration in milliseconds from now until `closesAt`. Validated
164
154
  * against `POLL_MIN_DURATION_MS` / `POLL_MAX_DURATION_MS`. The
165
155
  * server resolves `closesAt = createdAt + durationMs` instead of
166
156
  * taking an absolute date so clock skew between client and server
167
157
  * can't push a poll into the past. */
168
- durationMs: z
169
- .number()
170
- .int()
171
- .min(POLL_MIN_DURATION_MS)
172
- .max(POLL_MAX_DURATION_MS),
158
+ durationMs: z.number().int().min(POLL_MIN_DURATION_MS).max(POLL_MAX_DURATION_MS),
173
159
  allowsMultipleChoices: z.boolean(),
174
160
  resultsVisibility: pollResultsVisibilitySchema,
175
161
  /** Optional community scope. If set the author must be an active
@@ -199,7 +185,11 @@ export const createPollBodySchema = z
199
185
  */
200
186
  export const castVoteBodySchema = z.object({
201
187
  optionIndices: z
202
- .array(z.number().int().min(0).max(POLL_MAX_OPTIONS - 1))
188
+ .array(z
189
+ .number()
190
+ .int()
191
+ .min(0)
192
+ .max(POLL_MAX_OPTIONS - 1))
203
193
  .min(1)
204
194
  .max(POLL_MAX_OPTIONS),
205
195
  });
package/dist/poll.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"poll.js","sourceRoot":"","sources":["../src/poll.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Community poll wire shapes.\n *\n * A poll is a structured-choice feed item: a question + 2..6 options +\n * a fixed expiry. Lives in its own `community_polls` collection (NOT\n * an extension of `CommunityPost`); votes live in a separate\n * `poll_votes` collection keyed by `(pollId, userId)`. Per-option vote\n * counts + total-voter count are denormalised onto the poll so a feed\n * read serves the whole card in one document fetch.\n *\n * Industry alignment:\n * - Twitter / X: single-select, time-limited (5min..7d), results live.\n * - WhatsApp / Telegram: single OR multi-select, time-limited.\n * - Facebook: single OR multi-select, results live, no expiry.\n * - Reddit: single-select, 6h..7d, results post-vote.\n *\n * Our design:\n * - Required expiry, 5min..30d. Composer presets 1d / 3d / 7d / 14d.\n * - Author opts in for multi-select via `allowsMultipleChoices`.\n * - Author opts in for results-after-close (default: live) via\n * `resultsVisibility`. Server hides per-option counts on the wire\n * when the poll is still open AND `resultsVisibility === 'after_close'`,\n * so a peeking viewer can't fish results out of the API.\n *\n * Edits are NOT supported: changing question / options / expiry after\n * a vote has been cast would invalidate that vote. The author can\n * delete (soft-delete, freezes the poll) or close-early (sets\n * `closesAt` to now), but not edit.\n *\n * @module community-schema/poll\n */\n\nimport { z } from 'zod';\nimport { areaLineageSnapshotSchema } from './area.js';\nimport {\n POLL_MAX_DURATION_MS,\n POLL_MAX_OPTIONS,\n POLL_MIN_DURATION_MS,\n POLL_MIN_OPTIONS,\n POLL_OPTION_MAX_CHARS,\n POLL_OPTION_MIN_CHARS,\n POLL_QUESTION_MAX_CHARS,\n POLL_QUESTION_MIN_CHARS,\n} from './constants.js';\nimport { postAuthorSnapshotSchema } from './post.js';\n\n// ─── Results visibility ────────────────────────────────────────────────────\n\n/**\n * When per-option vote counts become visible to voters.\n *\n * - `live` — counts visible to everyone, always. Default;\n * matches Facebook / Telegram. Encourages\n * engagement via \"see what's winning\".\n * - `after_close` — counts hidden until the poll closes. The wire\n * shape's option counts are server-replaced with\n * `0` during the open window so a curious viewer\n * can't fish results out via the JSON. Best for\n * genuinely-blind decisions (community polls\n * about admin selection, etc.).\n */\nexport const POLL_RESULTS_VISIBILITY_VALUES = ['live', 'after_close'] as const;\nexport const pollResultsVisibilitySchema = z.enum(POLL_RESULTS_VISIBILITY_VALUES);\nexport type PollResultsVisibility = z.infer<typeof pollResultsVisibilitySchema>;\n\n// ─── Poll option (denormalised on the poll doc) ────────────────────────────\n\n/**\n * One choice in the poll. `index` is the canonical identifier the vote\n * body refers to (a stable integer 0..N-1 — letting the client send\n * indices instead of labels avoids hash-collision games with non-ASCII\n * labels). `voteCount` is the denormalised aggregate, updated atomically\n * by the vote endpoint and zeroed on the wire when `resultsVisibility`\n * is `after_close` AND the poll is still open.\n */\nexport const pollOptionWireSchema = z.object({\n index: z.number().int().min(0).max(POLL_MAX_OPTIONS - 1),\n label: z.string().min(POLL_OPTION_MIN_CHARS).max(POLL_OPTION_MAX_CHARS),\n voteCount: z.number().int().nonnegative(),\n});\nexport type PollOptionWire = z.infer<typeof pollOptionWireSchema>;\n\n/** Composer-side option (no vote count yet). */\nexport const pollOptionInputSchema = z.object({\n label: z\n .string()\n .trim()\n .min(POLL_OPTION_MIN_CHARS)\n .max(POLL_OPTION_MAX_CHARS),\n});\nexport type PollOptionInput = z.infer<typeof pollOptionInputSchema>;\n\n// ─── Wire shape — what the server returns ──────────────────────────────────\n\n/**\n * A community poll as it appears in the feed and on a poll detail\n * page. Engagement counts mirror the post wire so the same engagement\n * bar component renders for every kind.\n */\nexport const communityPollWireSchema = z.object({\n _id: z.string(),\n contentKind: z.literal('poll'),\n author: postAuthorSnapshotSchema,\n\n /** The poll question. Renders as the card's primary text. */\n question: z.string().min(POLL_QUESTION_MIN_CHARS).max(POLL_QUESTION_MAX_CHARS),\n /** Options 0..N-1 (N in `[POLL_MIN_OPTIONS, POLL_MAX_OPTIONS]`).\n * Per-option `voteCount` is zeroed on the wire while the poll is\n * open AND `resultsVisibility === 'after_close'` (the\n * total-voters count is still surfaced so the card can show\n * \"X voted\" without revealing how it splits). */\n options: z\n .array(pollOptionWireSchema)\n .min(POLL_MIN_OPTIONS)\n .max(POLL_MAX_OPTIONS),\n\n /** Number of UNIQUE voters. Always visible — even when option\n * counts are hidden — so the card can render \"X have voted\" as a\n * social proof signal. */\n totalVoters: z.number().int().nonnegative(),\n\n /** `true` when the author let voters pick more than one option. */\n allowsMultipleChoices: z.boolean(),\n /** Results visibility policy. See `pollResultsVisibilitySchema`. */\n resultsVisibility: pollResultsVisibilitySchema,\n\n /** ISO-string. The poll is closed when this is `<= now()`. Vote\n * endpoints reject after this; the client also hides the Vote CTA. */\n closesAt: z.string().datetime(),\n\n // Authorship area + scope (identical to communityPostWireSchema)\n areaLineage: areaLineageSnapshotSchema,\n communityId: z.string().optional(),\n\n // Denormalised engagement counters\n upvoteCount: z.number().int().nonnegative(),\n commentCount: z.number().int().nonnegative(),\n repostCount: z.number().int().nonnegative(),\n reactionCounts: z.record(z.string(), z.number().int().nonnegative()),\n\n // Lifecycle\n createdAt: z.string().datetime(),\n /** Polls are never edited (see module docstring); editedAt is kept\n * on the wire as `null` for parity with the post envelope so card\n * templates can share a single byline component. */\n editedAt: z.string().datetime().nullable(),\n deletedAt: z.string().datetime().nullable(),\n\n // Per-viewer state (filled at read time)\n viewer: z\n .object({\n upvoted: z.boolean(),\n reaction: z.string().nullable(),\n isAuthor: z.boolean(),\n reposted: z.boolean(),\n /** Indices the viewer voted for. Empty array means \"hasn't\n * voted yet\". Populated for every viewer regardless of\n * `resultsVisibility` — a voter can always see their own\n * choice. */\n votedOptionIndices: z.array(z.number().int().nonnegative()),\n })\n .optional(),\n});\nexport type CommunityPollWire = z.infer<typeof communityPollWireSchema>;\n\n// ─── Feed envelope ─────────────────────────────────────────────────────────\n\n/**\n * Same shape as `communityPollWireSchema` — the wire IS the feed\n * envelope (no pruning needed because polls are compact: a question +\n * ≤6 short option labels + counters). Aliased so consumers can import\n * the feed-envelope name in parallel with the existing lostFound /\n * voiceBox / donateItem envelopes.\n */\nexport const communityPollFeedItemSchema = communityPollWireSchema;\nexport type CommunityPollFeedItem = z.infer<typeof communityPollFeedItemSchema>;\n\n// ─── Create body ───────────────────────────────────────────────────────────\n\n/**\n * Composer payload: what the frontend sends to\n * `POST /api/v1/community/polls`. Author + areaLineage + initial vote\n * counts are filled server-side from the authenticated request and\n * cannot be spoofed by the client.\n */\nexport const createPollBodySchema = z\n .object({\n question: z\n .string()\n .trim()\n .min(POLL_QUESTION_MIN_CHARS)\n .max(POLL_QUESTION_MAX_CHARS),\n options: z\n .array(pollOptionInputSchema)\n .min(POLL_MIN_OPTIONS)\n .max(POLL_MAX_OPTIONS),\n /** Duration in milliseconds from now until `closesAt`. Validated\n * against `POLL_MIN_DURATION_MS` / `POLL_MAX_DURATION_MS`. The\n * server resolves `closesAt = createdAt + durationMs` instead of\n * taking an absolute date so clock skew between client and server\n * can't push a poll into the past. */\n durationMs: z\n .number()\n .int()\n .min(POLL_MIN_DURATION_MS)\n .max(POLL_MAX_DURATION_MS),\n allowsMultipleChoices: z.boolean(),\n resultsVisibility: pollResultsVisibilitySchema,\n /** Optional community scope. If set the author must be an active\n * member of the community — the server checks. */\n communityId: z.string().optional(),\n })\n .refine(\n (b) => {\n // Options must be unique by their trimmed label — duplicate\n // options fragment votes and confuse voters.\n const seen = new Set<string>();\n for (const o of b.options) {\n const k = o.label.trim().toLowerCase();\n if (seen.has(k)) return false;\n seen.add(k);\n }\n return true;\n },\n { message: 'Poll options must be unique', path: ['options'] },\n );\nexport type CreatePollBody = z.infer<typeof createPollBodySchema>;\n\n// ─── Vote body + response ──────────────────────────────────────────────────\n\n/**\n * What the client sends to `POST /api/v1/community/polls/:id/votes`\n * (cast OR change a vote — the server upserts on `(pollId, userId)`).\n *\n * For single-choice polls, `optionIndices` must be a single-element\n * array. The server enforces `length === 1` when the poll's\n * `allowsMultipleChoices` is false.\n */\nexport const castVoteBodySchema = z.object({\n optionIndices: z\n .array(z.number().int().min(0).max(POLL_MAX_OPTIONS - 1))\n .min(1)\n .max(POLL_MAX_OPTIONS),\n});\nexport type CastVoteBody = z.infer<typeof castVoteBodySchema>;\n\n/**\n * Server returns the updated poll wire after a vote / unvote so the\n * client can swap its local state for the authoritative copy (vote\n * counts, viewer.votedOptionIndices, totalVoters).\n */\nexport const voteResponseSchema = z.object({\n poll: communityPollWireSchema,\n});\nexport type VoteResponse = z.infer<typeof voteResponseSchema>;\n"]}
1
+ {"version":3,"file":"poll.js","sourceRoot":"","sources":["../src/poll.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Community poll wire shapes.\n *\n * A poll is a structured-choice feed item: a question + 2..6 options +\n * a fixed expiry. Lives in its own `community_polls` collection (NOT\n * an extension of `CommunityPost`); votes live in a separate\n * `poll_votes` collection keyed by `(pollId, userId)`. Per-option vote\n * counts + total-voter count are denormalised onto the poll so a feed\n * read serves the whole card in one document fetch.\n *\n * Industry alignment:\n * - Twitter / X: single-select, time-limited (5min..7d), results live.\n * - WhatsApp / Telegram: single OR multi-select, time-limited.\n * - Facebook: single OR multi-select, results live, no expiry.\n * - Reddit: single-select, 6h..7d, results post-vote.\n *\n * Our design:\n * - Required expiry, 5min..30d. Composer presets 1d / 3d / 7d / 14d.\n * - Author opts in for multi-select via `allowsMultipleChoices`.\n * - Author opts in for results-after-close (default: live) via\n * `resultsVisibility`. Server hides per-option counts on the wire\n * when the poll is still open AND `resultsVisibility === 'after_close'`,\n * so a peeking viewer can't fish results out of the API.\n *\n * Edits are NOT supported: changing question / options / expiry after\n * a vote has been cast would invalidate that vote. The author can\n * delete (soft-delete, freezes the poll) or close-early (sets\n * `closesAt` to now), but not edit.\n *\n * @module community-schema/poll\n */\n\nimport { z } from 'zod';\nimport { areaLineageSnapshotSchema } from './area.js';\nimport {\n POLL_MAX_DURATION_MS,\n POLL_MAX_OPTIONS,\n POLL_MIN_DURATION_MS,\n POLL_MIN_OPTIONS,\n POLL_OPTION_MAX_CHARS,\n POLL_OPTION_MIN_CHARS,\n POLL_QUESTION_MAX_CHARS,\n POLL_QUESTION_MIN_CHARS,\n} from './constants.js';\nimport { postAuthorSnapshotSchema } from './post.js';\n\n// ─── Results visibility ────────────────────────────────────────────────────\n\n/**\n * When per-option vote counts become visible to voters.\n *\n * - `live` — counts visible to everyone, always. Default;\n * matches Facebook / Telegram. Encourages\n * engagement via \"see what's winning\".\n * - `after_close` — counts hidden until the poll closes. The wire\n * shape's option counts are server-replaced with\n * `0` during the open window so a curious viewer\n * can't fish results out via the JSON. Best for\n * genuinely-blind decisions (community polls\n * about admin selection, etc.).\n */\nexport const POLL_RESULTS_VISIBILITY_VALUES = ['live', 'after_close'] as const;\nexport const pollResultsVisibilitySchema = z.enum(POLL_RESULTS_VISIBILITY_VALUES);\nexport type PollResultsVisibility = z.infer<typeof pollResultsVisibilitySchema>;\n\n// ─── Poll option (denormalised on the poll doc) ────────────────────────────\n\n/**\n * One choice in the poll. `index` is the canonical identifier the vote\n * body refers to (a stable integer 0..N-1 — letting the client send\n * indices instead of labels avoids hash-collision games with non-ASCII\n * labels). `voteCount` is the denormalised aggregate, updated atomically\n * by the vote endpoint and zeroed on the wire when `resultsVisibility`\n * is `after_close` AND the poll is still open.\n */\nexport const pollOptionWireSchema = z.object({\n index: z\n .number()\n .int()\n .min(0)\n .max(POLL_MAX_OPTIONS - 1),\n label: z.string().min(POLL_OPTION_MIN_CHARS).max(POLL_OPTION_MAX_CHARS),\n voteCount: z.number().int().nonnegative(),\n});\nexport type PollOptionWire = z.infer<typeof pollOptionWireSchema>;\n\n/** Composer-side option (no vote count yet). */\nexport const pollOptionInputSchema = z.object({\n label: z.string().trim().min(POLL_OPTION_MIN_CHARS).max(POLL_OPTION_MAX_CHARS),\n});\nexport type PollOptionInput = z.infer<typeof pollOptionInputSchema>;\n\n// ─── Wire shape — what the server returns ──────────────────────────────────\n\n/**\n * A community poll as it appears in the feed and on a poll detail\n * page. Engagement counts mirror the post wire so the same engagement\n * bar component renders for every kind.\n */\nexport const communityPollWireSchema = z.object({\n _id: z.string(),\n contentKind: z.literal('poll'),\n author: postAuthorSnapshotSchema,\n\n /** The poll question. Renders as the card's primary text. */\n question: z.string().min(POLL_QUESTION_MIN_CHARS).max(POLL_QUESTION_MAX_CHARS),\n /** Options 0..N-1 (N in `[POLL_MIN_OPTIONS, POLL_MAX_OPTIONS]`).\n * Per-option `voteCount` is zeroed on the wire while the poll is\n * open AND `resultsVisibility === 'after_close'` (the\n * total-voters count is still surfaced so the card can show\n * \"X voted\" without revealing how it splits). */\n options: z.array(pollOptionWireSchema).min(POLL_MIN_OPTIONS).max(POLL_MAX_OPTIONS),\n\n /** Number of UNIQUE voters. Always visible — even when option\n * counts are hidden — so the card can render \"X have voted\" as a\n * social proof signal. */\n totalVoters: z.number().int().nonnegative(),\n\n /** `true` when the author let voters pick more than one option. */\n allowsMultipleChoices: z.boolean(),\n /** Results visibility policy. See `pollResultsVisibilitySchema`. */\n resultsVisibility: pollResultsVisibilitySchema,\n\n /** ISO-string. The poll is closed when this is `<= now()`. Vote\n * endpoints reject after this; the client also hides the Vote CTA. */\n closesAt: z.string().datetime(),\n\n // Authorship area + scope (identical to communityPostWireSchema)\n areaLineage: areaLineageSnapshotSchema,\n communityId: z.string().optional(),\n\n // Denormalised engagement counters\n upvoteCount: z.number().int().nonnegative(),\n commentCount: z.number().int().nonnegative(),\n repostCount: z.number().int().nonnegative(),\n reactionCounts: z.record(z.string(), z.number().int().nonnegative()),\n\n // Lifecycle\n createdAt: z.string().datetime(),\n /** Polls are never edited (see module docstring); editedAt is kept\n * on the wire as `null` for parity with the post envelope so card\n * templates can share a single byline component. */\n editedAt: z.string().datetime().nullable(),\n deletedAt: z.string().datetime().nullable(),\n\n // Per-viewer state (filled at read time)\n viewer: z\n .object({\n upvoted: z.boolean(),\n reaction: z.string().nullable(),\n isAuthor: z.boolean(),\n reposted: z.boolean(),\n /** Indices the viewer voted for. Empty array means \"hasn't\n * voted yet\". Populated for every viewer regardless of\n * `resultsVisibility` — a voter can always see their own\n * choice. */\n votedOptionIndices: z.array(z.number().int().nonnegative()),\n })\n .optional(),\n});\nexport type CommunityPollWire = z.infer<typeof communityPollWireSchema>;\n\n// ─── Feed envelope ─────────────────────────────────────────────────────────\n\n/**\n * Same shape as `communityPollWireSchema` — the wire IS the feed\n * envelope (no pruning needed because polls are compact: a question +\n * ≤6 short option labels + counters). Aliased so consumers can import\n * the feed-envelope name in parallel with the existing lostFound /\n * voiceBox / donateItem envelopes.\n */\nexport const communityPollFeedItemSchema = communityPollWireSchema;\nexport type CommunityPollFeedItem = z.infer<typeof communityPollFeedItemSchema>;\n\n// ─── Create body ───────────────────────────────────────────────────────────\n\n/**\n * Composer payload: what the frontend sends to\n * `POST /api/v1/community/polls`. Author + areaLineage + initial vote\n * counts are filled server-side from the authenticated request and\n * cannot be spoofed by the client.\n */\nexport const createPollBodySchema = z\n .object({\n question: z.string().trim().min(POLL_QUESTION_MIN_CHARS).max(POLL_QUESTION_MAX_CHARS),\n options: z.array(pollOptionInputSchema).min(POLL_MIN_OPTIONS).max(POLL_MAX_OPTIONS),\n /** Duration in milliseconds from now until `closesAt`. Validated\n * against `POLL_MIN_DURATION_MS` / `POLL_MAX_DURATION_MS`. The\n * server resolves `closesAt = createdAt + durationMs` instead of\n * taking an absolute date so clock skew between client and server\n * can't push a poll into the past. */\n durationMs: z.number().int().min(POLL_MIN_DURATION_MS).max(POLL_MAX_DURATION_MS),\n allowsMultipleChoices: z.boolean(),\n resultsVisibility: pollResultsVisibilitySchema,\n /** Optional community scope. If set the author must be an active\n * member of the community — the server checks. */\n communityId: z.string().optional(),\n })\n .refine(\n (b) => {\n // Options must be unique by their trimmed label — duplicate\n // options fragment votes and confuse voters.\n const seen = new Set<string>();\n for (const o of b.options) {\n const k = o.label.trim().toLowerCase();\n if (seen.has(k)) return false;\n seen.add(k);\n }\n return true;\n },\n { message: 'Poll options must be unique', path: ['options'] },\n );\nexport type CreatePollBody = z.infer<typeof createPollBodySchema>;\n\n// ─── Vote body + response ──────────────────────────────────────────────────\n\n/**\n * What the client sends to `POST /api/v1/community/polls/:id/votes`\n * (cast OR change a vote — the server upserts on `(pollId, userId)`).\n *\n * For single-choice polls, `optionIndices` must be a single-element\n * array. The server enforces `length === 1` when the poll's\n * `allowsMultipleChoices` is false.\n */\nexport const castVoteBodySchema = z.object({\n optionIndices: z\n .array(\n z\n .number()\n .int()\n .min(0)\n .max(POLL_MAX_OPTIONS - 1),\n )\n .min(1)\n .max(POLL_MAX_OPTIONS),\n});\nexport type CastVoteBody = z.infer<typeof castVoteBodySchema>;\n\n/**\n * Server returns the updated poll wire after a vote / unvote so the\n * client can swap its local state for the authoritative copy (vote\n * counts, viewer.votedOptionIndices, totalVoters).\n */\nexport const voteResponseSchema = z.object({\n poll: communityPollWireSchema,\n});\nexport type VoteResponse = z.infer<typeof voteResponseSchema>;\n"]}
package/dist/profile.d.ts CHANGED
@@ -17,6 +17,28 @@
17
17
  * @module community-schema/profile
18
18
  */
19
19
  import { z } from 'zod';
20
+ /**
21
+ * Filter axis for the People tab. Each value corresponds to a distinct
22
+ * source of candidate users on the backend; the cascade-by-area behaviour
23
+ * is now scoped to the `'nearby'` filter only.
24
+ *
25
+ * - `'followers'` — users following the viewer, newest-first by follow
26
+ * time. The viewer's incoming social graph.
27
+ * - `'following'` — users the viewer is following, newest-first.
28
+ * - `'nearby'` — area-cascade (local → district → state → national →
29
+ * global), capped at 100 results. The legacy single-lens behaviour.
30
+ * - `'suggested'` — friends-of-friends ranked by mutual-follower count,
31
+ * excluding users the viewer already follows (PYMK).
32
+ */
33
+ export declare const PEOPLE_LIST_FILTER_VALUES: readonly ["followers", "following", "nearby", "suggested"];
34
+ export declare const peopleListFilterSchema: z.ZodEnum<{
35
+ following: "following";
36
+ followers: "followers";
37
+ nearby: "nearby";
38
+ suggested: "suggested";
39
+ }>;
40
+ export type PeopleListFilter = (typeof PEOPLE_LIST_FILTER_VALUES)[number];
41
+ export declare const PEOPLE_LIST_FILTER_DEFAULT: PeopleListFilter;
20
42
  /**
21
43
  * Mini-row used in the "Followed by X, Y + N more" mutuals line on the
22
44
  * profile header. The server picks up to 3 sample names + a count of
@@ -52,6 +74,9 @@ export declare const publicProfileWireSchema: z.ZodObject<{
52
74
  }, z.core.$strip>>;
53
75
  viewer: z.ZodObject<{
54
76
  following: z.ZodBoolean;
77
+ followsViewer: z.ZodDefault<z.ZodBoolean>;
78
+ followedYouAt: z.ZodOptional<z.ZodString>;
79
+ followedAt: z.ZodOptional<z.ZodString>;
55
80
  }, z.core.$strip>;
56
81
  identityVerified: z.ZodOptional<z.ZodBoolean>;
57
82
  }, z.core.$strip>;
@@ -72,11 +97,26 @@ export declare const peopleListItemSchema: z.ZodObject<{
72
97
  }>;
73
98
  viewer: z.ZodObject<{
74
99
  following: z.ZodBoolean;
100
+ followsViewer: z.ZodDefault<z.ZodBoolean>;
101
+ followedYouAt: z.ZodOptional<z.ZodString>;
102
+ followedAt: z.ZodOptional<z.ZodString>;
75
103
  }, z.core.$strip>;
76
104
  identityVerified: z.ZodOptional<z.ZodBoolean>;
105
+ mutuals: z.ZodOptional<z.ZodObject<{
106
+ avatars: z.ZodArray<z.ZodNullable<z.ZodString>>;
107
+ sampleNames: z.ZodArray<z.ZodString>;
108
+ extraCount: z.ZodNumber;
109
+ }, z.core.$strip>>;
110
+ mutualCount: z.ZodOptional<z.ZodNumber>;
77
111
  }, z.core.$strip>;
78
112
  export type PeopleListItem = z.infer<typeof peopleListItemSchema>;
79
113
  export declare const peopleQueryParamsSchema: z.ZodObject<{
114
+ filter: z.ZodOptional<z.ZodEnum<{
115
+ following: "following";
116
+ followers: "followers";
117
+ nearby: "nearby";
118
+ suggested: "suggested";
119
+ }>>;
80
120
  q: z.ZodOptional<z.ZodString>;
81
121
  level: z.ZodOptional<z.ZodEnum<{
82
122
  local: "local";
@@ -102,8 +142,17 @@ export declare const peopleListResponseSchema: z.ZodObject<{
102
142
  }>;
103
143
  viewer: z.ZodObject<{
104
144
  following: z.ZodBoolean;
145
+ followsViewer: z.ZodDefault<z.ZodBoolean>;
146
+ followedYouAt: z.ZodOptional<z.ZodString>;
147
+ followedAt: z.ZodOptional<z.ZodString>;
105
148
  }, z.core.$strip>;
106
149
  identityVerified: z.ZodOptional<z.ZodBoolean>;
150
+ mutuals: z.ZodOptional<z.ZodObject<{
151
+ avatars: z.ZodArray<z.ZodNullable<z.ZodString>>;
152
+ sampleNames: z.ZodArray<z.ZodString>;
153
+ extraCount: z.ZodNumber;
154
+ }, z.core.$strip>>;
155
+ mutualCount: z.ZodOptional<z.ZodNumber>;
107
156
  }, z.core.$strip>>;
108
157
  nextCursor: z.ZodNullable<z.ZodString>;
109
158
  }, z.core.$strip>;
@@ -1 +1 @@
1
- {"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../src/profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;iBAW/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;iBAgDlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;iBAe/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,uBAAuB;;;;;;;;;;;iBAQlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;iBAGnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
1
+ {"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../src/profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB,4DAK5B,CAAC;AACX,eAAO,MAAM,sBAAsB;;;;;EAAoC,CAAC;AACxE,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC1E,eAAO,MAAM,0BAA0B,EAAE,gBAA8B,CAAC;AAExE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;iBAW/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgDlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;iBAwB/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;iBAalC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
package/dist/profile.js CHANGED
@@ -21,6 +21,28 @@ import { PROFILE_MAX_BIO_CHARS } from './constants.js';
21
21
  import { profilePrivacySchema, visibilityLevelSchema } from './enums.js';
22
22
  import { viewerSocialStateSchema } from './social.js';
23
23
  import { usernameSchema } from './username.js';
24
+ // ─── People list filter ─────────────────────────────────────────────────────
25
+ /**
26
+ * Filter axis for the People tab. Each value corresponds to a distinct
27
+ * source of candidate users on the backend; the cascade-by-area behaviour
28
+ * is now scoped to the `'nearby'` filter only.
29
+ *
30
+ * - `'followers'` — users following the viewer, newest-first by follow
31
+ * time. The viewer's incoming social graph.
32
+ * - `'following'` — users the viewer is following, newest-first.
33
+ * - `'nearby'` — area-cascade (local → district → state → national →
34
+ * global), capped at 100 results. The legacy single-lens behaviour.
35
+ * - `'suggested'` — friends-of-friends ranked by mutual-follower count,
36
+ * excluding users the viewer already follows (PYMK).
37
+ */
38
+ export const PEOPLE_LIST_FILTER_VALUES = [
39
+ 'followers',
40
+ 'following',
41
+ 'nearby',
42
+ 'suggested',
43
+ ];
44
+ export const peopleListFilterSchema = z.enum(PEOPLE_LIST_FILTER_VALUES);
45
+ export const PEOPLE_LIST_FILTER_DEFAULT = 'followers';
24
46
  /**
25
47
  * Mini-row used in the "Followed by X, Y + N more" mutuals line on the
26
48
  * profile header. The server picks up to 3 sample names + a count of
@@ -101,12 +123,26 @@ export const peopleListItemSchema = z.object({
101
123
  * display name in the row. Optional for forward-compat with
102
124
  * un-migrated backends. */
103
125
  identityVerified: z.boolean().optional(),
126
+ /** Mutual followers between the viewer and this row's user. Populated
127
+ * on every People-list filter so the row can render the FB-style
128
+ * "Followed by A, B + N more" line. Omitted when there are no
129
+ * mutuals to avoid wasting bytes on the common cold-start case. */
130
+ mutuals: profileMutualsSchema.optional(),
131
+ /** Total number of mutual followers (NOT just the sampled three).
132
+ * Drives the "X mutuals" count badge + sort key for the `suggested`
133
+ * filter. Defaults to 0 when omitted. */
134
+ mutualCount: z.number().int().nonnegative().optional(),
104
135
  });
105
136
  export const peopleQueryParamsSchema = z.object({
137
+ /** Filter axis (followers / following / nearby / suggested). The
138
+ * backend defaults to `PEOPLE_LIST_FILTER_DEFAULT` when omitted so
139
+ * every cold landing has the same source-of-truth. */
140
+ filter: peopleListFilterSchema.optional(),
106
141
  /** Free-text search across `displayName`. */
107
142
  q: z.string().optional(),
108
- /** Area-scope filter. When set, server filters to users whose primary
109
- * area lineage matches the viewer's lineage at the chosen level. */
143
+ /** Legacy area-scope filter. Retained for backward compat when set
144
+ * with no `filter`, the server treats it as `filter: 'nearby'` plus
145
+ * the level override. Newer clients should pass `filter` directly. */
110
146
  level: visibilityLevelSchema.optional(),
111
147
  cursor: z.string().optional(),
112
148
  pageSize: z.number().int().positive().max(50).optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"profile.js","sourceRoot":"","sources":["../src/profile.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Public community-profile wire shape.\n *\n * What every viewer can see about another user's community presence.\n * Differs from the auth/UDP `User` shape — this view is purposely thin\n * and content-engagement-oriented (post count, follower count, …).\n *\n * Privacy gating:\n * - `public` profile: the full shape is returned to any signed-in viewer.\n * - `private` profile: only `userId`, `displayName`, `avatarUrl`, and\n * the viewer's follow state are returned to non-followers. Posts and\n * counters are hidden until the viewer follows the profile owner and\n * the owner has accepted (TODO: follow-approval lifecycle — currently\n * \"private\" simply hides counters/posts from anyone who isn't the\n * owner).\n *\n * @module community-schema/profile\n */\n\nimport { z } from 'zod';\nimport { PROFILE_MAX_BIO_CHARS } from './constants.js';\nimport { profilePrivacySchema, visibilityLevelSchema } from './enums.js';\nimport { viewerSocialStateSchema } from './social.js';\nimport { usernameSchema } from './username.js';\n\n/**\n * Mini-row used in the \"Followed by X, Y + N more\" mutuals line on the\n * profile header. The server picks up to 3 sample names + a count of\n * the remaining mutuals so the row reads naturally without paginating\n * the full mutuals list inline.\n */\nexport const profileMutualsSchema = z.object({\n /** Avatar URLs (or single-letter fallbacks via `null`) for the sample\n * mutuals — order is \"show first\" → \"show last\". Capped at 3. */\n avatars: z.array(z.string().url().nullable()).max(3),\n /** Display names matched 1:1 with `avatars` order. Empty when the\n * viewer has no mutuals with the profile owner. */\n sampleNames: z.array(z.string()).max(3),\n /** How many additional mutuals exist beyond the sample. Used to\n * render the trailing \"+ N more\" suffix. Zero when the sample IS\n * the full list. */\n extraCount: z.number().int().nonnegative(),\n});\nexport type ProfileMutuals = z.infer<typeof profileMutualsSchema>;\n\nexport const publicProfileWireSchema = z.object({\n userId: z.string(),\n /** Public URL handle. The profile page lives at `/<username>`; this\n * is the canonical identity surfaced to the viewer. Always present\n * — every user is auto-minted a username at provisioning time and\n * can change it from community Settings (14-day cooldown). */\n username: usernameSchema,\n displayName: z.string(),\n avatarUrl: z.string().url().optional(),\n\n /** Author area at view time (resolved server-side). Hidden when\n * privacy is `private` and the viewer is not the owner. */\n localName: z.string().optional(),\n\n /** Privacy of THIS profile (not the viewer's). Useful for the UI\n * to render a lock chip when the profile is private. */\n privacy: profilePrivacySchema,\n\n /** Short bio — present only when set by the user. */\n bio: z.string().max(PROFILE_MAX_BIO_CHARS).optional(),\n\n /** Engagement counters. Hidden on private profiles when the viewer is\n * not the owner. Three-tuple post-redesign: connections went away\n * when the connection-request feature was removed in v0.9.0. */\n counters: z\n .object({\n postCount: z.number().int().nonnegative(),\n followerCount: z.number().int().nonnegative(),\n followingCount: z.number().int().nonnegative(),\n })\n .optional(),\n\n /** Mutual followees between the viewer and the profile owner. Renders\n * the \"Followed by X, Y + N more\" line. Omitted for self-view (no\n * point telling you about yourself) and when the viewer has no\n * mutuals with the owner. */\n mutuals: profileMutualsSchema.optional(),\n\n /** Per-viewer relationship state. Always present (never gated). */\n viewer: viewerSocialStateSchema,\n\n /** True when this user has been identity-verified by a Jansathi\n * volunteer / leader (UDP step-1 `verifiedFields`). Surfaces the\n * green check badge next to the display name on the profile\n * header. Optional so backends not yet populating the field\n * serialize a valid wire shape — readers treat undefined as\n * unverified. Live-joined at read time, NOT a snapshot. */\n identityVerified: z.boolean().optional(),\n});\nexport type PublicProfileWire = z.infer<typeof publicProfileWireSchema>;\n\n// ─── People list ────────────────────────────────────────────────────────────\n\n/**\n * Lightweight row used in the People tab list. Fewer fields than the\n * full profile to keep the list response small.\n */\nexport const peopleListItemSchema = z.object({\n userId: z.string(),\n /** Public URL handle (see `publicProfileWireSchema.username`). Always\n * present — the row's display + tap-to-profile link both depend on it. */\n username: usernameSchema,\n displayName: z.string(),\n avatarUrl: z.string().url().optional(),\n localName: z.string().optional(),\n privacy: profilePrivacySchema,\n viewer: viewerSocialStateSchema,\n /** True when this user has been identity-verified by a Jansathi\n * volunteer / leader. Drives the green check badge next to the\n * display name in the row. Optional for forward-compat with\n * un-migrated backends. */\n identityVerified: z.boolean().optional(),\n});\nexport type PeopleListItem = z.infer<typeof peopleListItemSchema>;\n\nexport const peopleQueryParamsSchema = z.object({\n /** Free-text search across `displayName`. */\n q: z.string().optional(),\n /** Area-scope filter. When set, server filters to users whose primary\n * area lineage matches the viewer's lineage at the chosen level. */\n level: visibilityLevelSchema.optional(),\n cursor: z.string().optional(),\n pageSize: z.number().int().positive().max(50).optional(),\n});\nexport type PeopleQueryParams = z.infer<typeof peopleQueryParamsSchema>;\n\nexport const peopleListResponseSchema = z.object({\n items: z.array(peopleListItemSchema),\n nextCursor: z.string().nullable(),\n});\nexport type PeopleListResponse = z.infer<typeof peopleListResponseSchema>;\n"]}
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../src/profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,+EAA+E;AAE/E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,WAAW;IACX,WAAW;IACX,QAAQ;IACR,WAAW;CACH,CAAC;AACX,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;AAExE,MAAM,CAAC,MAAM,0BAA0B,GAAqB,WAAW,CAAC;AAExE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C;sEACkE;IAClE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD;wDACoD;IACpD,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC;;yBAEqB;IACrB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CAC3C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB;;;mEAG+D;IAC/D,QAAQ,EAAE,cAAc;IACxB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAEtC;gEAC4D;IAC5D,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAEhC;6DACyD;IACzD,OAAO,EAAE,oBAAoB;IAE7B,qDAAqD;IACrD,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;IAErD;;qEAEiE;IACjE,QAAQ,EAAE,CAAC;SACR,MAAM,CAAC;QACN,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;QACzC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;QAC7C,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;KAC/C,CAAC;SACD,QAAQ,EAAE;IAEb;;;kCAG8B;IAC9B,OAAO,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IAExC,mEAAmE;IACnE,MAAM,EAAE,uBAAuB;IAE/B;;;;;gEAK4D;IAC5D,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACzC,CAAC,CAAC;AAGH,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB;+EAC2E;IAC3E,QAAQ,EAAE,cAAc;IACxB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACtC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,OAAO,EAAE,oBAAoB;IAC7B,MAAM,EAAE,uBAAuB;IAC/B;;;gCAG4B;IAC5B,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACxC;;;wEAGoE;IACpE,OAAO,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IACxC;;8CAE0C;IAC1C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;CACvD,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C;;2DAEuD;IACvD,MAAM,EAAE,sBAAsB,CAAC,QAAQ,EAAE;IACzC,6CAA6C;IAC7C,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxB;;2EAEuE;IACvE,KAAK,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IACvC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;CACzD,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC;IACpC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAC","sourcesContent":["/**\n * Public community-profile wire shape.\n *\n * What every viewer can see about another user's community presence.\n * Differs from the auth/UDP `User` shape — this view is purposely thin\n * and content-engagement-oriented (post count, follower count, …).\n *\n * Privacy gating:\n * - `public` profile: the full shape is returned to any signed-in viewer.\n * - `private` profile: only `userId`, `displayName`, `avatarUrl`, and\n * the viewer's follow state are returned to non-followers. Posts and\n * counters are hidden until the viewer follows the profile owner and\n * the owner has accepted (TODO: follow-approval lifecycle — currently\n * \"private\" simply hides counters/posts from anyone who isn't the\n * owner).\n *\n * @module community-schema/profile\n */\n\nimport { z } from 'zod';\nimport { PROFILE_MAX_BIO_CHARS } from './constants.js';\nimport { profilePrivacySchema, visibilityLevelSchema } from './enums.js';\nimport { viewerSocialStateSchema } from './social.js';\nimport { usernameSchema } from './username.js';\n\n// ─── People list filter ─────────────────────────────────────────────────────\n\n/**\n * Filter axis for the People tab. Each value corresponds to a distinct\n * source of candidate users on the backend; the cascade-by-area behaviour\n * is now scoped to the `'nearby'` filter only.\n *\n * - `'followers'` — users following the viewer, newest-first by follow\n * time. The viewer's incoming social graph.\n * - `'following'` — users the viewer is following, newest-first.\n * - `'nearby'` — area-cascade (local → district → state → national →\n * global), capped at 100 results. The legacy single-lens behaviour.\n * - `'suggested'` — friends-of-friends ranked by mutual-follower count,\n * excluding users the viewer already follows (PYMK).\n */\nexport const PEOPLE_LIST_FILTER_VALUES = [\n 'followers',\n 'following',\n 'nearby',\n 'suggested',\n] as const;\nexport const peopleListFilterSchema = z.enum(PEOPLE_LIST_FILTER_VALUES);\nexport type PeopleListFilter = (typeof PEOPLE_LIST_FILTER_VALUES)[number];\nexport const PEOPLE_LIST_FILTER_DEFAULT: PeopleListFilter = 'followers';\n\n/**\n * Mini-row used in the \"Followed by X, Y + N more\" mutuals line on the\n * profile header. The server picks up to 3 sample names + a count of\n * the remaining mutuals so the row reads naturally without paginating\n * the full mutuals list inline.\n */\nexport const profileMutualsSchema = z.object({\n /** Avatar URLs (or single-letter fallbacks via `null`) for the sample\n * mutuals — order is \"show first\" → \"show last\". Capped at 3. */\n avatars: z.array(z.string().url().nullable()).max(3),\n /** Display names matched 1:1 with `avatars` order. Empty when the\n * viewer has no mutuals with the profile owner. */\n sampleNames: z.array(z.string()).max(3),\n /** How many additional mutuals exist beyond the sample. Used to\n * render the trailing \"+ N more\" suffix. Zero when the sample IS\n * the full list. */\n extraCount: z.number().int().nonnegative(),\n});\nexport type ProfileMutuals = z.infer<typeof profileMutualsSchema>;\n\nexport const publicProfileWireSchema = z.object({\n userId: z.string(),\n /** Public URL handle. The profile page lives at `/<username>`; this\n * is the canonical identity surfaced to the viewer. Always present\n * — every user is auto-minted a username at provisioning time and\n * can change it from community Settings (14-day cooldown). */\n username: usernameSchema,\n displayName: z.string(),\n avatarUrl: z.string().url().optional(),\n\n /** Author area at view time (resolved server-side). Hidden when\n * privacy is `private` and the viewer is not the owner. */\n localName: z.string().optional(),\n\n /** Privacy of THIS profile (not the viewer's). Useful for the UI\n * to render a lock chip when the profile is private. */\n privacy: profilePrivacySchema,\n\n /** Short bio — present only when set by the user. */\n bio: z.string().max(PROFILE_MAX_BIO_CHARS).optional(),\n\n /** Engagement counters. Hidden on private profiles when the viewer is\n * not the owner. Three-tuple post-redesign: connections went away\n * when the connection-request feature was removed in v0.9.0. */\n counters: z\n .object({\n postCount: z.number().int().nonnegative(),\n followerCount: z.number().int().nonnegative(),\n followingCount: z.number().int().nonnegative(),\n })\n .optional(),\n\n /** Mutual followees between the viewer and the profile owner. Renders\n * the \"Followed by X, Y + N more\" line. Omitted for self-view (no\n * point telling you about yourself) and when the viewer has no\n * mutuals with the owner. */\n mutuals: profileMutualsSchema.optional(),\n\n /** Per-viewer relationship state. Always present (never gated). */\n viewer: viewerSocialStateSchema,\n\n /** True when this user has been identity-verified by a Jansathi\n * volunteer / leader (UDP step-1 `verifiedFields`). Surfaces the\n * green check badge next to the display name on the profile\n * header. Optional so backends not yet populating the field\n * serialize a valid wire shape — readers treat undefined as\n * unverified. Live-joined at read time, NOT a snapshot. */\n identityVerified: z.boolean().optional(),\n});\nexport type PublicProfileWire = z.infer<typeof publicProfileWireSchema>;\n\n// ─── People list ────────────────────────────────────────────────────────────\n\n/**\n * Lightweight row used in the People tab list. Fewer fields than the\n * full profile to keep the list response small.\n */\nexport const peopleListItemSchema = z.object({\n userId: z.string(),\n /** Public URL handle (see `publicProfileWireSchema.username`). Always\n * present — the row's display + tap-to-profile link both depend on it. */\n username: usernameSchema,\n displayName: z.string(),\n avatarUrl: z.string().url().optional(),\n localName: z.string().optional(),\n privacy: profilePrivacySchema,\n viewer: viewerSocialStateSchema,\n /** True when this user has been identity-verified by a Jansathi\n * volunteer / leader. Drives the green check badge next to the\n * display name in the row. Optional for forward-compat with\n * un-migrated backends. */\n identityVerified: z.boolean().optional(),\n /** Mutual followers between the viewer and this row's user. Populated\n * on every People-list filter so the row can render the FB-style\n * \"Followed by A, B + N more\" line. Omitted when there are no\n * mutuals to avoid wasting bytes on the common cold-start case. */\n mutuals: profileMutualsSchema.optional(),\n /** Total number of mutual followers (NOT just the sampled three).\n * Drives the \"X mutuals\" count badge + sort key for the `suggested`\n * filter. Defaults to 0 when omitted. */\n mutualCount: z.number().int().nonnegative().optional(),\n});\nexport type PeopleListItem = z.infer<typeof peopleListItemSchema>;\n\nexport const peopleQueryParamsSchema = z.object({\n /** Filter axis (followers / following / nearby / suggested). The\n * backend defaults to `PEOPLE_LIST_FILTER_DEFAULT` when omitted so\n * every cold landing has the same source-of-truth. */\n filter: peopleListFilterSchema.optional(),\n /** Free-text search across `displayName`. */\n q: z.string().optional(),\n /** Legacy area-scope filter. Retained for backward compat — when set\n * with no `filter`, the server treats it as `filter: 'nearby'` plus\n * the level override. Newer clients should pass `filter` directly. */\n level: visibilityLevelSchema.optional(),\n cursor: z.string().optional(),\n pageSize: z.number().int().positive().max(50).optional(),\n});\nexport type PeopleQueryParams = z.infer<typeof peopleQueryParamsSchema>;\n\nexport const peopleListResponseSchema = z.object({\n items: z.array(peopleListItemSchema),\n nextCursor: z.string().nullable(),\n});\nexport type PeopleListResponse = z.infer<typeof peopleListResponseSchema>;\n"]}
package/dist/social.d.ts CHANGED
@@ -19,9 +19,24 @@ import { z } from 'zod';
19
19
  /**
20
20
  * The viewer's state w.r.t. a target user. Returned inline on profile
21
21
  * reads so the UI can render the Follow button without a second request.
22
+ *
23
+ * The reverse edge (`followsViewer`) is what powers the People-tab
24
+ * "Follow back" affordance — if the target follows me but I don't
25
+ * follow them, the row's primary CTA flips from "Follow" to
26
+ * "Follow back". Timestamps are populated for the People list filters
27
+ * that imply a follow event:
28
+ * - `followers` list: `followedYouAt` is the row's authoritative
29
+ * timestamp (when they followed me).
30
+ * - `following` list: `followedAt` is the timestamp (when I
31
+ * followed them).
32
+ * - profile reads + the other filters: timestamps may be omitted to
33
+ * save a round trip; the UI falls back to "no timestamp shown".
22
34
  */
23
35
  export declare const viewerSocialStateSchema: z.ZodObject<{
24
36
  following: z.ZodBoolean;
37
+ followsViewer: z.ZodDefault<z.ZodBoolean>;
38
+ followedYouAt: z.ZodOptional<z.ZodString>;
39
+ followedAt: z.ZodOptional<z.ZodString>;
25
40
  }, z.core.$strip>;
26
41
  export type ViewerSocialState = z.infer<typeof viewerSocialStateSchema>;
27
42
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"social.d.ts","sourceRoot":"","sources":["../src/social.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;GAGG;AACH,eAAO,MAAM,uBAAuB;;iBAGlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;;;GAIG;AACH,eAAO,MAAM,0BAA0B;;;;iBAIrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
1
+ {"version":3,"file":"social.d.ts","sourceRoot":"","sources":["../src/social.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,uBAAuB;;;;;iBAalC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;;;GAIG;AACH,eAAO,MAAM,0BAA0B;;;;iBAIrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
package/dist/social.js CHANGED
@@ -20,10 +20,32 @@ import { z } from 'zod';
20
20
  /**
21
21
  * The viewer's state w.r.t. a target user. Returned inline on profile
22
22
  * reads so the UI can render the Follow button without a second request.
23
+ *
24
+ * The reverse edge (`followsViewer`) is what powers the People-tab
25
+ * "Follow back" affordance — if the target follows me but I don't
26
+ * follow them, the row's primary CTA flips from "Follow" to
27
+ * "Follow back". Timestamps are populated for the People list filters
28
+ * that imply a follow event:
29
+ * - `followers` list: `followedYouAt` is the row's authoritative
30
+ * timestamp (when they followed me).
31
+ * - `following` list: `followedAt` is the timestamp (when I
32
+ * followed them).
33
+ * - profile reads + the other filters: timestamps may be omitted to
34
+ * save a round trip; the UI falls back to "no timestamp shown".
23
35
  */
24
36
  export const viewerSocialStateSchema = z.object({
25
37
  /** True when the viewer is following the target. */
26
38
  following: z.boolean(),
39
+ /** True when the target is following the viewer (reverse edge).
40
+ * Drives the "Follow back" CTA on People rows. Defaults to false
41
+ * for backward compat with backends not yet populating it. */
42
+ followsViewer: z.boolean().default(false),
43
+ /** ISO timestamp of when the target followed the viewer. Populated
44
+ * by the `followers` People-list filter; absent elsewhere. */
45
+ followedYouAt: z.string().datetime().optional(),
46
+ /** ISO timestamp of when the viewer followed the target. Populated
47
+ * by the `following` People-list filter; absent elsewhere. */
48
+ followedAt: z.string().datetime().optional(),
27
49
  });
28
50
  /**
29
51
  * Response when the viewer toggles follow on a target user. The endpoint
@@ -1 +1 @@
1
- {"version":3,"file":"social.js","sourceRoot":"","sources":["../src/social.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,oDAAoD;IACpD,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;CACvB,CAAC,CAAC;AAGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;IACtB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CAC9C,CAAC,CAAC","sourcesContent":["/**\n * Social graph wire shapes — follow only.\n *\n * Single relationship now:\n *\n * Follow — one-way, no acceptance required (Twitter / Instagram).\n * The follower starts seeing the followee's posts in their\n * feed regardless of geo scope. Followee is notified.\n *\n * The mutual-handshake \"Connection\" concept was removed in schema 0.9.0;\n * the redesign aligns the social model with Instagram / Twitter where a\n * one-way follow is the only relationship primitive. Connections-only\n * post audiences and the connection-bypass on the feed visibility cascade\n * went with it.\n *\n * @module community-schema/social\n */\n\nimport { z } from 'zod';\n\n// ─── Follow ─────────────────────────────────────────────────────────────────\n\n/**\n * The viewer's state w.r.t. a target user. Returned inline on profile\n * reads so the UI can render the Follow button without a second request.\n */\nexport const viewerSocialStateSchema = z.object({\n /** True when the viewer is following the target. */\n following: z.boolean(),\n});\nexport type ViewerSocialState = z.infer<typeof viewerSocialStateSchema>;\n\n/**\n * Response when the viewer toggles follow on a target user. The endpoint\n * is `POST /api/v1/community/users/:id/follow` and is idempotent —\n * calling twice removes the follow.\n */\nexport const toggleFollowResponseSchema = z.object({\n targetUserId: z.string(),\n following: z.boolean(),\n followerCount: z.number().int().nonnegative(),\n});\nexport type ToggleFollowResponse = z.infer<typeof toggleFollowResponseSchema>;\n"]}
1
+ {"version":3,"file":"social.js","sourceRoot":"","sources":["../src/social.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,+EAA+E;AAE/E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,oDAAoD;IACpD,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;IACtB;;mEAE+D;IAC/D,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACzC;mEAC+D;IAC/D,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC/C;mEAC+D;IAC/D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;IACtB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CAC9C,CAAC,CAAC","sourcesContent":["/**\n * Social graph wire shapes — follow only.\n *\n * Single relationship now:\n *\n * Follow — one-way, no acceptance required (Twitter / Instagram).\n * The follower starts seeing the followee's posts in their\n * feed regardless of geo scope. Followee is notified.\n *\n * The mutual-handshake \"Connection\" concept was removed in schema 0.9.0;\n * the redesign aligns the social model with Instagram / Twitter where a\n * one-way follow is the only relationship primitive. Connections-only\n * post audiences and the connection-bypass on the feed visibility cascade\n * went with it.\n *\n * @module community-schema/social\n */\n\nimport { z } from 'zod';\n\n// ─── Follow ─────────────────────────────────────────────────────────────────\n\n/**\n * The viewer's state w.r.t. a target user. Returned inline on profile\n * reads so the UI can render the Follow button without a second request.\n *\n * The reverse edge (`followsViewer`) is what powers the People-tab\n * \"Follow back\" affordance — if the target follows me but I don't\n * follow them, the row's primary CTA flips from \"Follow\" to\n * \"Follow back\". Timestamps are populated for the People list filters\n * that imply a follow event:\n * - `followers` list: `followedYouAt` is the row's authoritative\n * timestamp (when they followed me).\n * - `following` list: `followedAt` is the timestamp (when I\n * followed them).\n * - profile reads + the other filters: timestamps may be omitted to\n * save a round trip; the UI falls back to \"no timestamp shown\".\n */\nexport const viewerSocialStateSchema = z.object({\n /** True when the viewer is following the target. */\n following: z.boolean(),\n /** True when the target is following the viewer (reverse edge).\n * Drives the \"Follow back\" CTA on People rows. Defaults to false\n * for backward compat with backends not yet populating it. */\n followsViewer: z.boolean().default(false),\n /** ISO timestamp of when the target followed the viewer. Populated\n * by the `followers` People-list filter; absent elsewhere. */\n followedYouAt: z.string().datetime().optional(),\n /** ISO timestamp of when the viewer followed the target. Populated\n * by the `following` People-list filter; absent elsewhere. */\n followedAt: z.string().datetime().optional(),\n});\nexport type ViewerSocialState = z.infer<typeof viewerSocialStateSchema>;\n\n/**\n * Response when the viewer toggles follow on a target user. The endpoint\n * is `POST /api/v1/community/users/:id/follow` and is idempotent —\n * calling twice removes the follow.\n */\nexport const toggleFollowResponseSchema = z.object({\n targetUserId: z.string(),\n following: z.boolean(),\n followerCount: z.number().int().nonnegative(),\n});\nexport type ToggleFollowResponse = z.infer<typeof toggleFollowResponseSchema>;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jansathi-community-schema",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "description": "Shared Zod schemas + TypeScript types for the Jansathi hyperlocal community feature (feed, posts, engagement, social graph, groups, communities).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",