jansathi-community-schema 0.1.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.
Files changed (58) hide show
  1. package/README.md +41 -0
  2. package/dist/area.d.ts +37 -0
  3. package/dist/area.d.ts.map +1 -0
  4. package/dist/area.js +51 -0
  5. package/dist/area.js.map +1 -0
  6. package/dist/comment.d.ts +54 -0
  7. package/dist/comment.d.ts.map +1 -0
  8. package/dist/comment.js +63 -0
  9. package/dist/comment.js.map +1 -0
  10. package/dist/constants.d.ts +42 -0
  11. package/dist/constants.d.ts.map +1 -0
  12. package/dist/constants.js +47 -0
  13. package/dist/constants.js.map +1 -0
  14. package/dist/engagement.d.ts +69 -0
  15. package/dist/engagement.d.ts.map +1 -0
  16. package/dist/engagement.js +50 -0
  17. package/dist/engagement.js.map +1 -0
  18. package/dist/enums.d.ts +149 -0
  19. package/dist/enums.d.ts.map +1 -0
  20. package/dist/enums.js +143 -0
  21. package/dist/enums.js.map +1 -0
  22. package/dist/feed.d.ts +311 -0
  23. package/dist/feed.d.ts.map +1 -0
  24. package/dist/feed.js +102 -0
  25. package/dist/feed.js.map +1 -0
  26. package/dist/group.d.ts +48 -0
  27. package/dist/group.d.ts.map +1 -0
  28. package/dist/group.js +45 -0
  29. package/dist/group.js.map +1 -0
  30. package/dist/index.d.ts +30 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +43 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/media.d.ts +48 -0
  35. package/dist/media.d.ts.map +1 -0
  36. package/dist/media.js +50 -0
  37. package/dist/media.js.map +1 -0
  38. package/dist/post.d.ts +130 -0
  39. package/dist/post.d.ts.map +1 -0
  40. package/dist/post.js +103 -0
  41. package/dist/post.js.map +1 -0
  42. package/dist/profile.d.ts +116 -0
  43. package/dist/profile.d.ts.map +1 -0
  44. package/dist/profile.js +70 -0
  45. package/dist/profile.js.map +1 -0
  46. package/dist/report.d.ts +62 -0
  47. package/dist/report.d.ts.map +1 -0
  48. package/dist/report.js +30 -0
  49. package/dist/report.js.map +1 -0
  50. package/dist/settings.d.ts +66 -0
  51. package/dist/settings.d.ts.map +1 -0
  52. package/dist/settings.js +75 -0
  53. package/dist/settings.js.map +1 -0
  54. package/dist/social.d.ts +95 -0
  55. package/dist/social.d.ts.map +1 -0
  56. package/dist/social.js +85 -0
  57. package/dist/social.js.map +1 -0
  58. package/package.json +50 -0
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Social graph wire shapes — follows and connections.
3
+ *
4
+ * Two distinct relationships:
5
+ *
6
+ * Follow — one-way, no acceptance required (Twitter / Instagram).
7
+ * The follower starts seeing the followee's posts in their
8
+ * feed regardless of geo scope. Followee is notified.
9
+ *
10
+ * Connection — mutual handshake (LinkedIn). Requester sends, recipient
11
+ * accepts / declines. ACCEPTED connections bypass the
12
+ * visibility-level cascade entirely: connected users
13
+ * always see each other's posts no matter the level.
14
+ * This is the "friend posts always visible" rule.
15
+ *
16
+ * The two surfaces don't overlap: a user can follow someone they're
17
+ * not connected with, and they can be connected without following.
18
+ *
19
+ * @module community-schema/social
20
+ */
21
+ import { z } from 'zod';
22
+ /**
23
+ * The viewer's state w.r.t. a target user. Returned inline on profile
24
+ * reads so the UI can render Follow / Connect buttons without a second
25
+ * request.
26
+ */
27
+ export declare const viewerSocialStateSchema: z.ZodObject<{
28
+ following: z.ZodBoolean;
29
+ connectionStatus: z.ZodNullable<z.ZodEnum<{
30
+ pending: "pending";
31
+ accepted: "accepted";
32
+ declined: "declined";
33
+ blocked: "blocked";
34
+ }>>;
35
+ pendingDirection: z.ZodNullable<z.ZodEnum<{
36
+ sent: "sent";
37
+ received: "received";
38
+ }>>;
39
+ }, z.core.$strip>;
40
+ export type ViewerSocialState = z.infer<typeof viewerSocialStateSchema>;
41
+ /**
42
+ * Response when the viewer toggles follow on a target user. The endpoint
43
+ * is `POST /api/v1/community/users/:id/follow` and is idempotent —
44
+ * calling twice removes the follow.
45
+ */
46
+ export declare const toggleFollowResponseSchema: z.ZodObject<{
47
+ targetUserId: z.ZodString;
48
+ following: z.ZodBoolean;
49
+ followerCount: z.ZodNumber;
50
+ }, z.core.$strip>;
51
+ export type ToggleFollowResponse = z.infer<typeof toggleFollowResponseSchema>;
52
+ /**
53
+ * Send a connection request. The endpoint is
54
+ * `POST /api/v1/community/users/:id/connect`. The body is empty — the
55
+ * relationship is identified by the path id + the authenticated caller.
56
+ */
57
+ export declare const sendConnectionRequestResponseSchema: z.ZodObject<{
58
+ targetUserId: z.ZodString;
59
+ status: z.ZodEnum<{
60
+ pending: "pending";
61
+ accepted: "accepted";
62
+ declined: "declined";
63
+ blocked: "blocked";
64
+ }>;
65
+ }, z.core.$strip>;
66
+ export type SendConnectionRequestResponse = z.infer<typeof sendConnectionRequestResponseSchema>;
67
+ /**
68
+ * Body for `POST /api/v1/community/connections/:id/decision` (accept /
69
+ * decline / block / unblock on an existing connection record).
70
+ */
71
+ export declare const connectionDecisionBodySchema: z.ZodObject<{
72
+ decision: z.ZodEnum<{
73
+ accept: "accept";
74
+ decline: "decline";
75
+ block: "block";
76
+ unblock: "unblock";
77
+ remove: "remove";
78
+ }>;
79
+ }, z.core.$strip>;
80
+ export type ConnectionDecisionBody = z.infer<typeof connectionDecisionBodySchema>;
81
+ export declare const connectionRecordWireSchema: z.ZodObject<{
82
+ _id: z.ZodString;
83
+ otherUserId: z.ZodString;
84
+ status: z.ZodEnum<{
85
+ pending: "pending";
86
+ accepted: "accepted";
87
+ declined: "declined";
88
+ blocked: "blocked";
89
+ }>;
90
+ requestedByUserId: z.ZodString;
91
+ createdAt: z.ZodString;
92
+ acceptedAt: z.ZodNullable<z.ZodString>;
93
+ }, z.core.$strip>;
94
+ export type ConnectionRecordWire = z.infer<typeof connectionRecordWireSchema>;
95
+ //# sourceMappingURL=social.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"social.d.ts","sourceRoot":"","sources":["../src/social.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;iBAgBlC,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;AAI9E;;;;GAIG;AACH,eAAO,MAAM,mCAAmC;;;;;;;;iBAK9C,CAAC;AACH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CACjD,OAAO,mCAAmC,CAC3C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,4BAA4B;;;;;;;;iBAEvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAC1C,OAAO,4BAA4B,CACpC,CAAC;AAEF,eAAO,MAAM,0BAA0B;;;;;;;;;;;;iBASrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
package/dist/social.js ADDED
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Social graph wire shapes — follows and connections.
3
+ *
4
+ * Two distinct relationships:
5
+ *
6
+ * Follow — one-way, no acceptance required (Twitter / Instagram).
7
+ * The follower starts seeing the followee's posts in their
8
+ * feed regardless of geo scope. Followee is notified.
9
+ *
10
+ * Connection — mutual handshake (LinkedIn). Requester sends, recipient
11
+ * accepts / declines. ACCEPTED connections bypass the
12
+ * visibility-level cascade entirely: connected users
13
+ * always see each other's posts no matter the level.
14
+ * This is the "friend posts always visible" rule.
15
+ *
16
+ * The two surfaces don't overlap: a user can follow someone they're
17
+ * not connected with, and they can be connected without following.
18
+ *
19
+ * @module community-schema/social
20
+ */
21
+ import { z } from 'zod';
22
+ import { connectionStatusSchema } from './enums.js';
23
+ // ─── Follow ─────────────────────────────────────────────────────────────────
24
+ /**
25
+ * The viewer's state w.r.t. a target user. Returned inline on profile
26
+ * reads so the UI can render Follow / Connect buttons without a second
27
+ * request.
28
+ */
29
+ export const viewerSocialStateSchema = z.object({
30
+ /** True when the viewer is following the target. */
31
+ following: z.boolean(),
32
+ /** Connection status from the viewer's perspective:
33
+ * - null → no connection record exists
34
+ * - 'pending' → there is a pending request between them
35
+ * - 'accepted' → they're connected
36
+ * - 'declined' → previous request was declined
37
+ * - 'blocked' → either side blocked the other
38
+ */
39
+ connectionStatus: connectionStatusSchema.nullable(),
40
+ /** When connectionStatus === 'pending', identifies who has the action:
41
+ * - 'sent' → viewer sent the request; awaiting target's accept
42
+ * - 'received' → target sent the request; viewer must accept / decline
43
+ * Null in all other states. */
44
+ pendingDirection: z.enum(['sent', 'received']).nullable(),
45
+ });
46
+ /**
47
+ * Response when the viewer toggles follow on a target user. The endpoint
48
+ * is `POST /api/v1/community/users/:id/follow` and is idempotent —
49
+ * calling twice removes the follow.
50
+ */
51
+ export const toggleFollowResponseSchema = z.object({
52
+ targetUserId: z.string(),
53
+ following: z.boolean(),
54
+ followerCount: z.number().int().nonnegative(),
55
+ });
56
+ // ─── Connection ────────────────────────────────────────────────────────────
57
+ /**
58
+ * Send a connection request. The endpoint is
59
+ * `POST /api/v1/community/users/:id/connect`. The body is empty — the
60
+ * relationship is identified by the path id + the authenticated caller.
61
+ */
62
+ export const sendConnectionRequestResponseSchema = z.object({
63
+ targetUserId: z.string(),
64
+ /** The status after the call. For a fresh request → 'pending'. For a
65
+ * reciprocal request that auto-accepts → 'accepted'. */
66
+ status: connectionStatusSchema,
67
+ });
68
+ /**
69
+ * Body for `POST /api/v1/community/connections/:id/decision` (accept /
70
+ * decline / block / unblock on an existing connection record).
71
+ */
72
+ export const connectionDecisionBodySchema = z.object({
73
+ decision: z.enum(['accept', 'decline', 'block', 'unblock', 'remove']),
74
+ });
75
+ export const connectionRecordWireSchema = z.object({
76
+ _id: z.string(),
77
+ /** The "other" user from the viewer's perspective. */
78
+ otherUserId: z.string(),
79
+ status: connectionStatusSchema,
80
+ /** Who initiated the request. Always the same regardless of viewer. */
81
+ requestedByUserId: z.string(),
82
+ createdAt: z.string().datetime(),
83
+ acceptedAt: z.string().datetime().nullable(),
84
+ });
85
+ //# sourceMappingURL=social.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"social.js","sourceRoot":"","sources":["../src/social.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,oDAAoD;IACpD,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;IACtB;;;;;;OAMG;IACH,gBAAgB,EAAE,sBAAsB,CAAC,QAAQ,EAAE;IACnD;;;oCAGgC;IAChC,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC1D,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;AAGH,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1D,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB;6DACyD;IACzD,MAAM,EAAE,sBAAsB;CAC/B,CAAC,CAAC;AAKH;;;GAGG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,MAAM,CAAC;IACnD,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;CACtE,CAAC,CAAC;AAKH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,sDAAsD;IACtD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,MAAM,EAAE,sBAAsB;IAC9B,uEAAuE;IACvE,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC7B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC","sourcesContent":["/**\n * Social graph wire shapes — follows and connections.\n *\n * Two distinct relationships:\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 * Connection — mutual handshake (LinkedIn). Requester sends, recipient\n * accepts / declines. ACCEPTED connections bypass the\n * visibility-level cascade entirely: connected users\n * always see each other's posts no matter the level.\n * This is the \"friend posts always visible\" rule.\n *\n * The two surfaces don't overlap: a user can follow someone they're\n * not connected with, and they can be connected without following.\n *\n * @module community-schema/social\n */\n\nimport { z } from 'zod';\nimport { connectionStatusSchema } from './enums.js';\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 Follow / Connect buttons without a second\n * request.\n */\nexport const viewerSocialStateSchema = z.object({\n /** True when the viewer is following the target. */\n following: z.boolean(),\n /** Connection status from the viewer's perspective:\n * - null → no connection record exists\n * - 'pending' → there is a pending request between them\n * - 'accepted' → they're connected\n * - 'declined' → previous request was declined\n * - 'blocked' → either side blocked the other\n */\n connectionStatus: connectionStatusSchema.nullable(),\n /** When connectionStatus === 'pending', identifies who has the action:\n * - 'sent' → viewer sent the request; awaiting target's accept\n * - 'received' → target sent the request; viewer must accept / decline\n * Null in all other states. */\n pendingDirection: z.enum(['sent', 'received']).nullable(),\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\n// ─── Connection ────────────────────────────────────────────────────────────\n\n/**\n * Send a connection request. The endpoint is\n * `POST /api/v1/community/users/:id/connect`. The body is empty — the\n * relationship is identified by the path id + the authenticated caller.\n */\nexport const sendConnectionRequestResponseSchema = z.object({\n targetUserId: z.string(),\n /** The status after the call. For a fresh request → 'pending'. For a\n * reciprocal request that auto-accepts → 'accepted'. */\n status: connectionStatusSchema,\n});\nexport type SendConnectionRequestResponse = z.infer<\n typeof sendConnectionRequestResponseSchema\n>;\n\n/**\n * Body for `POST /api/v1/community/connections/:id/decision` (accept /\n * decline / block / unblock on an existing connection record).\n */\nexport const connectionDecisionBodySchema = z.object({\n decision: z.enum(['accept', 'decline', 'block', 'unblock', 'remove']),\n});\nexport type ConnectionDecisionBody = z.infer<\n typeof connectionDecisionBodySchema\n>;\n\nexport const connectionRecordWireSchema = z.object({\n _id: z.string(),\n /** The \"other\" user from the viewer's perspective. */\n otherUserId: z.string(),\n status: connectionStatusSchema,\n /** Who initiated the request. Always the same regardless of viewer. */\n requestedByUserId: z.string(),\n createdAt: z.string().datetime(),\n acceptedAt: z.string().datetime().nullable(),\n});\nexport type ConnectionRecordWire = z.infer<typeof connectionRecordWireSchema>;\n"]}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "jansathi-community-schema",
3
+ "version": "0.1.0",
4
+ "description": "Shared Zod schemas + TypeScript types for the Jansathi hyperlocal community feature (feed, posts, engagement, social graph, groups).",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "sideEffects": false,
21
+ "scripts": {
22
+ "build": "tsc -p tsconfig.json",
23
+ "type-check": "tsc --noEmit",
24
+ "lint": "biome lint .",
25
+ "format": "biome format --write .",
26
+ "check": "npm run type-check && biome check --write .",
27
+ "check:staged": "biome check --staged --write --no-errors-on-unmatched",
28
+ "prepublishOnly": "npm run build && npm run check"
29
+ },
30
+ "keywords": [
31
+ "zod",
32
+ "schema",
33
+ "community",
34
+ "social",
35
+ "feed",
36
+ "hyperlocal",
37
+ "typescript"
38
+ ],
39
+ "author": "Hari",
40
+ "license": "MIT",
41
+ "peerDependencies": {
42
+ "zod": "^3.25.0 || ^4.0.0"
43
+ },
44
+ "devDependencies": {
45
+ "@biomejs/biome": "^2.4.5",
46
+ "@types/node": "^24.10.1",
47
+ "typescript": "^5.9.3",
48
+ "zod": "^4.1.13"
49
+ }
50
+ }