founder-schema 0.3.0 → 0.5.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 (106) hide show
  1. package/README.md +44 -16
  2. package/dist/access/access.d.ts +76 -0
  3. package/dist/access/access.d.ts.map +1 -0
  4. package/dist/access/access.js +66 -0
  5. package/dist/access/access.js.map +1 -0
  6. package/dist/access/permissions.d.ts +153 -0
  7. package/dist/access/permissions.d.ts.map +1 -0
  8. package/dist/access/permissions.js +80 -0
  9. package/dist/access/permissions.js.map +1 -0
  10. package/dist/access/roles.d.ts +71 -0
  11. package/dist/access/roles.d.ts.map +1 -0
  12. package/dist/access/roles.js +72 -0
  13. package/dist/access/roles.js.map +1 -0
  14. package/dist/chat.d.ts +4 -4
  15. package/dist/chat.d.ts.map +1 -1
  16. package/dist/chat.js +7 -2
  17. package/dist/chat.js.map +1 -1
  18. package/dist/core/common.d.ts +304 -0
  19. package/dist/core/common.d.ts.map +1 -0
  20. package/dist/core/common.js +340 -0
  21. package/dist/core/common.js.map +1 -0
  22. package/dist/core/errors.d.ts +117 -0
  23. package/dist/core/errors.d.ts.map +1 -0
  24. package/dist/core/errors.js +139 -0
  25. package/dist/core/errors.js.map +1 -0
  26. package/dist/core/limits.d.ts +122 -0
  27. package/dist/core/limits.d.ts.map +1 -0
  28. package/dist/core/limits.js +132 -0
  29. package/dist/core/limits.js.map +1 -0
  30. package/dist/core/responses.d.ts +207 -0
  31. package/dist/core/responses.d.ts.map +1 -0
  32. package/dist/core/responses.js +73 -0
  33. package/dist/core/responses.js.map +1 -0
  34. package/dist/core/validation.d.ts +146 -0
  35. package/dist/core/validation.d.ts.map +1 -0
  36. package/dist/core/validation.js +152 -0
  37. package/dist/core/validation.js.map +1 -0
  38. package/dist/domains/account/account.d.ts +42 -0
  39. package/dist/domains/account/account.d.ts.map +1 -0
  40. package/dist/domains/account/account.js +41 -0
  41. package/dist/domains/account/account.js.map +1 -0
  42. package/dist/domains/audit/audit.d.ts +169 -0
  43. package/dist/domains/audit/audit.d.ts.map +1 -0
  44. package/dist/domains/audit/audit.js +84 -0
  45. package/dist/domains/audit/audit.js.map +1 -0
  46. package/dist/domains/chat/chat.d.ts +187 -0
  47. package/dist/domains/chat/chat.d.ts.map +1 -0
  48. package/dist/domains/chat/chat.js +189 -0
  49. package/dist/domains/chat/chat.js.map +1 -0
  50. package/dist/domains/dashboard/dashboard.d.ts +48 -0
  51. package/dist/domains/dashboard/dashboard.d.ts.map +1 -0
  52. package/dist/domains/dashboard/dashboard.js +58 -0
  53. package/dist/domains/dashboard/dashboard.js.map +1 -0
  54. package/dist/domains/discover/discover.d.ts +245 -0
  55. package/dist/domains/discover/discover.d.ts.map +1 -0
  56. package/dist/domains/discover/discover.js +68 -0
  57. package/dist/domains/discover/discover.js.map +1 -0
  58. package/dist/domains/feed/feed.d.ts +1695 -0
  59. package/dist/domains/feed/feed.d.ts.map +1 -0
  60. package/dist/domains/feed/feed.js +626 -0
  61. package/dist/domains/feed/feed.js.map +1 -0
  62. package/dist/domains/media/media.d.ts +134 -0
  63. package/dist/domains/media/media.d.ts.map +1 -0
  64. package/dist/domains/media/media.js +110 -0
  65. package/dist/domains/media/media.js.map +1 -0
  66. package/dist/domains/members/members.d.ts +175 -0
  67. package/dist/domains/members/members.d.ts.map +1 -0
  68. package/dist/domains/members/members.js +106 -0
  69. package/dist/domains/members/members.js.map +1 -0
  70. package/dist/domains/moderation/moderation.d.ts +184 -0
  71. package/dist/domains/moderation/moderation.d.ts.map +1 -0
  72. package/dist/domains/moderation/moderation.js +90 -0
  73. package/dist/domains/moderation/moderation.js.map +1 -0
  74. package/dist/domains/onboarding/onboarding.d.ts +1018 -0
  75. package/dist/domains/onboarding/onboarding.d.ts.map +1 -0
  76. package/dist/domains/onboarding/onboarding.js +717 -0
  77. package/dist/domains/onboarding/onboarding.js.map +1 -0
  78. package/dist/domains/profile/founder-profile.d.ts +411 -0
  79. package/dist/domains/profile/founder-profile.d.ts.map +1 -0
  80. package/dist/domains/profile/founder-profile.js +202 -0
  81. package/dist/domains/profile/founder-profile.js.map +1 -0
  82. package/dist/domains/support/support.d.ts +305 -0
  83. package/dist/domains/support/support.d.ts.map +1 -0
  84. package/dist/domains/support/support.js +129 -0
  85. package/dist/domains/support/support.js.map +1 -0
  86. package/dist/domains/team/team.d.ts +79 -0
  87. package/dist/domains/team/team.d.ts.map +1 -0
  88. package/dist/domains/team/team.js +54 -0
  89. package/dist/domains/team/team.js.map +1 -0
  90. package/dist/domains/uploads/uploads.d.ts +101 -0
  91. package/dist/domains/uploads/uploads.d.ts.map +1 -0
  92. package/dist/domains/uploads/uploads.js +89 -0
  93. package/dist/domains/uploads/uploads.js.map +1 -0
  94. package/dist/env.d.ts +85 -0
  95. package/dist/env.d.ts.map +1 -0
  96. package/dist/env.js +150 -0
  97. package/dist/env.js.map +1 -0
  98. package/dist/index.d.ts +22 -12
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +32 -19
  101. package/dist/index.js.map +1 -1
  102. package/dist/onboarding.d.ts +58 -32
  103. package/dist/onboarding.d.ts.map +1 -1
  104. package/dist/onboarding.js +155 -32
  105. package/dist/onboarding.js.map +1 -1
  106. package/package.json +14 -2
@@ -0,0 +1,146 @@
1
+ /**
2
+ * founder-schema — How a validation failure is described, on both sides
3
+ *
4
+ * TWO RULES, and they are what let the web client show any error, its own or
5
+ * the server's, on the right field in the member's language:
6
+ *
7
+ * 1. A CUSTOM MESSAGE IS A KEY, NEVER A SENTENCE. Where a schema needs its own
8
+ * message (a refine, a regex), the message is one of `VALIDATION_MESSAGE`,
9
+ * such as `phoneInvalid`. The client turns the key into text in English or
10
+ * Hindi. Before 0.2.0 these were English sentences, so a Hindi screen showed
11
+ * an English error, and a client that wanted to translate one had to match
12
+ * on the wording.
13
+ *
14
+ * Plain bounds carry NO custom message. `.min(1)` and `.max(80)` produce
15
+ * Zod's own `too_small` / `too_big` issues, which already say which bound
16
+ * and what it was (`minimum`, `maximum`, `origin`), and the client words
17
+ * them from those. A hand-written "at most 80 characters" would only
18
+ * restate the number in one language.
19
+ *
20
+ * 2. THE SERVER SENDS EVERY ISSUE, IN THIS SHAPE. A 400 answers with
21
+ * `error.details.issues`, built by `toValidationIssues`, so the client can
22
+ * put each one under its field. Until 0.2.0 the backend sent only the
23
+ * first issue's message, with no path at all.
24
+ *
25
+ * ⚠️ `toValidationIssues` COPIES A WHITELIST OF FIELDS, it never spreads an
26
+ * issue. Zod can carry the rejected `input` on an issue, and these bodies hold a
27
+ * date of birth and a phone number. Echoing them into an error response sends
28
+ * them back to the client, into logs and into any proxy in between. A test
29
+ * proves `input` never survives.
30
+ *
31
+ * @module founder-schema/core/validation
32
+ */
33
+ import { z } from 'zod';
34
+ /**
35
+ * Every custom message a schema in this package can produce. Each is a
36
+ * translation key the clients define in every language they ship.
37
+ *
38
+ * ⚠️ Append only, and add the translation in the same change. Renaming one
39
+ * shows the raw key to every member until each client ships the new name.
40
+ */
41
+ export declare const VALIDATION_MESSAGE: {
42
+ /** Not a 24-hex Mongo id. */
43
+ readonly invalidId: "invalidId";
44
+ /** Handle: wrong characters, or a dot in the wrong place. */
45
+ readonly usernameInvalid: "usernameInvalid";
46
+ /** Not a 10-digit Indian mobile number. */
47
+ readonly phoneInvalid: "phoneInvalid";
48
+ /** Not a `YYYY-MM-DD` date. */
49
+ readonly dateInvalid: "dateInvalid";
50
+ /** A date that does not exist, such as 30 February. */
51
+ readonly dobInvalid: "dobInvalid";
52
+ /** Under the minimum age. */
53
+ readonly dobUnderAge: "dobUnderAge";
54
+ /** Over the sanity ceiling: almost always a mistyped year. */
55
+ readonly dobTooOld: "dobTooOld";
56
+ /** A founding year after this year. */
57
+ readonly foundedYearFuture: "foundedYearFuture";
58
+ /** An upload key that is not one this product mints. */
59
+ readonly uploadKeyInvalid: "uploadKeyInvalid";
60
+ /** The same uploaded image attached twice to one post. */
61
+ readonly mediaDuplicate: "mediaDuplicate";
62
+ /** A post with neither text nor media. */
63
+ readonly postEmpty: "postEmpty";
64
+ /** Two poll options with the same label. */
65
+ readonly pollOptionsDuplicate: "pollOptionsDuplicate";
66
+ /** An empty string sent to clear a patch field; clearing is `null`. */
67
+ readonly clearWithNull: "clearWithNull";
68
+ /** Not a plain http(s) URL on a real domain (`javascript:`, `localhost`, an IP...). */
69
+ readonly urlInvalid: "urlInvalid";
70
+ /** A handle this product keeps for itself (`admin`, `support`...). */
71
+ readonly usernameReserved: "usernameReserved";
72
+ /** Agreed to a version of the guidelines that is not the current one. */
73
+ readonly guidelinesOutdated: "guidelinesOutdated";
74
+ /** An MPIN that is not exactly six digits. */
75
+ readonly mpinInvalid: "mpinInvalid";
76
+ /** The MPIN and its confirmation differ. */
77
+ readonly mpinMismatch: "mpinMismatch";
78
+ /** Switching to a staff role without the MPIN. */
79
+ readonly mpinRequired: "mpinRequired";
80
+ /** The same role twice in one list. */
81
+ readonly rolesDuplicate: "rolesDuplicate";
82
+ };
83
+ export type ValidationMessageKey = (typeof VALIDATION_MESSAGE)[keyof typeof VALIDATION_MESSAGE];
84
+ /**
85
+ * Which part of the request an issue is about.
86
+ *
87
+ * ONE PATH CONVENTION: `path` is ALWAYS relative to this part, so a body field
88
+ * reads `['venture', 'name']` with `location: 'body'`, never
89
+ * `['body', 'venture', 'name']`. A form maps body issues straight onto its
90
+ * fields without stripping a prefix, and a client that sees `query` or
91
+ * `params` knows the problem is the URL, not anything the member typed.
92
+ */
93
+ export declare const REQUEST_PART_VALUES: readonly ["body", "query", "params"];
94
+ export declare const requestPartSchema: z.ZodEnum<{
95
+ params: "params";
96
+ body: "body";
97
+ query: "query";
98
+ }>;
99
+ export type RequestPart = z.infer<typeof requestPartSchema>;
100
+ /**
101
+ * One problem with one field, as it crosses the wire.
102
+ *
103
+ * `code` is Zod's issue code (`too_small`, `too_big`, `invalid_type`,
104
+ * `invalid_format`, `custom`...). `message` is either one of
105
+ * `VALIDATION_MESSAGE` or, for a plain bound, Zod's own English text, which the
106
+ * client ignores in favour of `code` plus `minimum` / `maximum`.
107
+ */
108
+ export declare const validationIssueSchema: z.ZodObject<{
109
+ location: z.ZodOptional<z.ZodEnum<{
110
+ params: "params";
111
+ body: "body";
112
+ query: "query";
113
+ }>>;
114
+ path: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
115
+ code: z.ZodString;
116
+ message: z.ZodString;
117
+ minimum: z.ZodOptional<z.ZodNumber>;
118
+ maximum: z.ZodOptional<z.ZodNumber>;
119
+ origin: z.ZodOptional<z.ZodString>;
120
+ format: z.ZodOptional<z.ZodString>;
121
+ }, z.core.$strip>;
122
+ export type ValidationIssue = z.infer<typeof validationIssueSchema>;
123
+ /** The loosest shape this needs from a Zod issue, so it works across 4.x. */
124
+ interface ZodIssueLike {
125
+ path: readonly PropertyKey[];
126
+ code: string;
127
+ message: string;
128
+ minimum?: unknown;
129
+ maximum?: unknown;
130
+ origin?: unknown;
131
+ format?: unknown;
132
+ }
133
+ /**
134
+ * A Zod error as the wire shape. Use this on the server for every 400, and on
135
+ * the client to treat its own errors and the server's the same way.
136
+ *
137
+ * `location` is stamped on every issue when given; the server always gives it.
138
+ *
139
+ * Copies a WHITELIST of fields (see the module note). A path segment that is a
140
+ * symbol, which JSON cannot carry, becomes its description.
141
+ */
142
+ export declare function toValidationIssues(error: {
143
+ issues: readonly ZodIssueLike[];
144
+ }, location?: RequestPart): ValidationIssue[];
145
+ export {};
146
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/core/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB;IAC7B,6BAA6B;;IAE7B,6DAA6D;;IAE7D,2CAA2C;;IAE3C,+BAA+B;;IAE/B,uDAAuD;;IAEvD,6BAA6B;;IAE7B,8DAA8D;;IAE9D,uCAAuC;;IAEvC,wDAAwD;;IAExD,0DAA0D;;IAE1D,0CAA0C;;IAE1C,4CAA4C;;IAE5C,uEAAuE;;IAEvE,uFAAuF;;IAEvF,sEAAsE;;IAEtE,yEAAyE;;IAEzE,8CAA8C;;IAE9C,4CAA4C;;IAE5C,kDAAkD;;IAElD,uCAAuC;;CAE/B,CAAC;AACX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAEhG;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,sCAAuC,CAAC;AACxE,eAAO,MAAM,iBAAiB;;;;EAA8B,CAAC;AAC7D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;iBAkBhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,6EAA6E;AAC7E,UAAU,YAAY;IACpB,IAAI,EAAE,SAAS,WAAW,EAAE,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAKD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE;IAAE,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;CAAE,EAC1C,QAAQ,CAAC,EAAE,WAAW,GACrB,eAAe,EAAE,CAkBnB"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * founder-schema — How a validation failure is described, on both sides
3
+ *
4
+ * TWO RULES, and they are what let the web client show any error, its own or
5
+ * the server's, on the right field in the member's language:
6
+ *
7
+ * 1. A CUSTOM MESSAGE IS A KEY, NEVER A SENTENCE. Where a schema needs its own
8
+ * message (a refine, a regex), the message is one of `VALIDATION_MESSAGE`,
9
+ * such as `phoneInvalid`. The client turns the key into text in English or
10
+ * Hindi. Before 0.2.0 these were English sentences, so a Hindi screen showed
11
+ * an English error, and a client that wanted to translate one had to match
12
+ * on the wording.
13
+ *
14
+ * Plain bounds carry NO custom message. `.min(1)` and `.max(80)` produce
15
+ * Zod's own `too_small` / `too_big` issues, which already say which bound
16
+ * and what it was (`minimum`, `maximum`, `origin`), and the client words
17
+ * them from those. A hand-written "at most 80 characters" would only
18
+ * restate the number in one language.
19
+ *
20
+ * 2. THE SERVER SENDS EVERY ISSUE, IN THIS SHAPE. A 400 answers with
21
+ * `error.details.issues`, built by `toValidationIssues`, so the client can
22
+ * put each one under its field. Until 0.2.0 the backend sent only the
23
+ * first issue's message, with no path at all.
24
+ *
25
+ * ⚠️ `toValidationIssues` COPIES A WHITELIST OF FIELDS, it never spreads an
26
+ * issue. Zod can carry the rejected `input` on an issue, and these bodies hold a
27
+ * date of birth and a phone number. Echoing them into an error response sends
28
+ * them back to the client, into logs and into any proxy in between. A test
29
+ * proves `input` never survives.
30
+ *
31
+ * @module founder-schema/core/validation
32
+ */
33
+ import { z } from 'zod';
34
+ /**
35
+ * Every custom message a schema in this package can produce. Each is a
36
+ * translation key the clients define in every language they ship.
37
+ *
38
+ * ⚠️ Append only, and add the translation in the same change. Renaming one
39
+ * shows the raw key to every member until each client ships the new name.
40
+ */
41
+ export const VALIDATION_MESSAGE = {
42
+ /** Not a 24-hex Mongo id. */
43
+ invalidId: 'invalidId',
44
+ /** Handle: wrong characters, or a dot in the wrong place. */
45
+ usernameInvalid: 'usernameInvalid',
46
+ /** Not a 10-digit Indian mobile number. */
47
+ phoneInvalid: 'phoneInvalid',
48
+ /** Not a `YYYY-MM-DD` date. */
49
+ dateInvalid: 'dateInvalid',
50
+ /** A date that does not exist, such as 30 February. */
51
+ dobInvalid: 'dobInvalid',
52
+ /** Under the minimum age. */
53
+ dobUnderAge: 'dobUnderAge',
54
+ /** Over the sanity ceiling: almost always a mistyped year. */
55
+ dobTooOld: 'dobTooOld',
56
+ /** A founding year after this year. */
57
+ foundedYearFuture: 'foundedYearFuture',
58
+ /** An upload key that is not one this product mints. */
59
+ uploadKeyInvalid: 'uploadKeyInvalid',
60
+ /** The same uploaded image attached twice to one post. */
61
+ mediaDuplicate: 'mediaDuplicate',
62
+ /** A post with neither text nor media. */
63
+ postEmpty: 'postEmpty',
64
+ /** Two poll options with the same label. */
65
+ pollOptionsDuplicate: 'pollOptionsDuplicate',
66
+ /** An empty string sent to clear a patch field; clearing is `null`. */
67
+ clearWithNull: 'clearWithNull',
68
+ /** Not a plain http(s) URL on a real domain (`javascript:`, `localhost`, an IP...). */
69
+ urlInvalid: 'urlInvalid',
70
+ /** A handle this product keeps for itself (`admin`, `support`...). */
71
+ usernameReserved: 'usernameReserved',
72
+ /** Agreed to a version of the guidelines that is not the current one. */
73
+ guidelinesOutdated: 'guidelinesOutdated',
74
+ /** An MPIN that is not exactly six digits. */
75
+ mpinInvalid: 'mpinInvalid',
76
+ /** The MPIN and its confirmation differ. */
77
+ mpinMismatch: 'mpinMismatch',
78
+ /** Switching to a staff role without the MPIN. */
79
+ mpinRequired: 'mpinRequired',
80
+ /** The same role twice in one list. */
81
+ rolesDuplicate: 'rolesDuplicate',
82
+ };
83
+ /**
84
+ * Which part of the request an issue is about.
85
+ *
86
+ * ONE PATH CONVENTION: `path` is ALWAYS relative to this part, so a body field
87
+ * reads `['venture', 'name']` with `location: 'body'`, never
88
+ * `['body', 'venture', 'name']`. A form maps body issues straight onto its
89
+ * fields without stripping a prefix, and a client that sees `query` or
90
+ * `params` knows the problem is the URL, not anything the member typed.
91
+ */
92
+ export const REQUEST_PART_VALUES = ['body', 'query', 'params'];
93
+ export const requestPartSchema = z.enum(REQUEST_PART_VALUES);
94
+ /**
95
+ * One problem with one field, as it crosses the wire.
96
+ *
97
+ * `code` is Zod's issue code (`too_small`, `too_big`, `invalid_type`,
98
+ * `invalid_format`, `custom`...). `message` is either one of
99
+ * `VALIDATION_MESSAGE` or, for a plain bound, Zod's own English text, which the
100
+ * client ignores in favour of `code` plus `minimum` / `maximum`.
101
+ */
102
+ export const validationIssueSchema = z.object({
103
+ /** Set by the server on every issue it sends; absent on a client's own parse. */
104
+ location: requestPartSchema.optional(),
105
+ /**
106
+ * Where the problem is, RELATIVE TO `location`: `['venture', 'name']`,
107
+ * `['options', 2, 'label']`, `['contentId']`.
108
+ */
109
+ path: z.array(z.union([z.string(), z.number()])),
110
+ code: z.string(),
111
+ message: z.string(),
112
+ /** `too_small`: the bound that was missed. */
113
+ minimum: z.number().optional(),
114
+ /** `too_big`: the bound that was passed. */
115
+ maximum: z.number().optional(),
116
+ /** What was measured: `string`, `array`, `number`... */
117
+ origin: z.string().optional(),
118
+ /** `invalid_format`: which format, e.g. `url`, `regex`, `email`. */
119
+ format: z.string().optional(),
120
+ });
121
+ const toNumber = (v) => typeof v === 'number' ? v : typeof v === 'bigint' ? Number(v) : undefined;
122
+ /**
123
+ * A Zod error as the wire shape. Use this on the server for every 400, and on
124
+ * the client to treat its own errors and the server's the same way.
125
+ *
126
+ * `location` is stamped on every issue when given; the server always gives it.
127
+ *
128
+ * Copies a WHITELIST of fields (see the module note). A path segment that is a
129
+ * symbol, which JSON cannot carry, becomes its description.
130
+ */
131
+ export function toValidationIssues(error, location) {
132
+ return error.issues.map((issue) => {
133
+ const out = {
134
+ ...(location ? { location } : {}),
135
+ path: issue.path.map((p) => typeof p === 'number' ? p : typeof p === 'string' ? p : String(p.description ?? '')),
136
+ code: issue.code,
137
+ message: issue.message,
138
+ };
139
+ const minimum = toNumber(issue.minimum);
140
+ const maximum = toNumber(issue.maximum);
141
+ if (minimum !== undefined)
142
+ out.minimum = minimum;
143
+ if (maximum !== undefined)
144
+ out.maximum = maximum;
145
+ if (typeof issue.origin === 'string')
146
+ out.origin = issue.origin;
147
+ if (typeof issue.format === 'string')
148
+ out.format = issue.format;
149
+ return out;
150
+ });
151
+ }
152
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/core/validation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * founder-schema — How a validation failure is described, on both sides\n *\n * TWO RULES, and they are what let the web client show any error, its own or\n * the server's, on the right field in the member's language:\n *\n * 1. A CUSTOM MESSAGE IS A KEY, NEVER A SENTENCE. Where a schema needs its own\n * message (a refine, a regex), the message is one of `VALIDATION_MESSAGE`,\n * such as `phoneInvalid`. The client turns the key into text in English or\n * Hindi. Before 0.2.0 these were English sentences, so a Hindi screen showed\n * an English error, and a client that wanted to translate one had to match\n * on the wording.\n *\n * Plain bounds carry NO custom message. `.min(1)` and `.max(80)` produce\n * Zod's own `too_small` / `too_big` issues, which already say which bound\n * and what it was (`minimum`, `maximum`, `origin`), and the client words\n * them from those. A hand-written \"at most 80 characters\" would only\n * restate the number in one language.\n *\n * 2. THE SERVER SENDS EVERY ISSUE, IN THIS SHAPE. A 400 answers with\n * `error.details.issues`, built by `toValidationIssues`, so the client can\n * put each one under its field. Until 0.2.0 the backend sent only the\n * first issue's message, with no path at all.\n *\n * ⚠️ `toValidationIssues` COPIES A WHITELIST OF FIELDS, it never spreads an\n * issue. Zod can carry the rejected `input` on an issue, and these bodies hold a\n * date of birth and a phone number. Echoing them into an error response sends\n * them back to the client, into logs and into any proxy in between. A test\n * proves `input` never survives.\n *\n * @module founder-schema/core/validation\n */\n\nimport { z } from 'zod';\n\n/**\n * Every custom message a schema in this package can produce. Each is a\n * translation key the clients define in every language they ship.\n *\n * ⚠️ Append only, and add the translation in the same change. Renaming one\n * shows the raw key to every member until each client ships the new name.\n */\nexport const VALIDATION_MESSAGE = {\n /** Not a 24-hex Mongo id. */\n invalidId: 'invalidId',\n /** Handle: wrong characters, or a dot in the wrong place. */\n usernameInvalid: 'usernameInvalid',\n /** Not a 10-digit Indian mobile number. */\n phoneInvalid: 'phoneInvalid',\n /** Not a `YYYY-MM-DD` date. */\n dateInvalid: 'dateInvalid',\n /** A date that does not exist, such as 30 February. */\n dobInvalid: 'dobInvalid',\n /** Under the minimum age. */\n dobUnderAge: 'dobUnderAge',\n /** Over the sanity ceiling: almost always a mistyped year. */\n dobTooOld: 'dobTooOld',\n /** A founding year after this year. */\n foundedYearFuture: 'foundedYearFuture',\n /** An upload key that is not one this product mints. */\n uploadKeyInvalid: 'uploadKeyInvalid',\n /** The same uploaded image attached twice to one post. */\n mediaDuplicate: 'mediaDuplicate',\n /** A post with neither text nor media. */\n postEmpty: 'postEmpty',\n /** Two poll options with the same label. */\n pollOptionsDuplicate: 'pollOptionsDuplicate',\n /** An empty string sent to clear a patch field; clearing is `null`. */\n clearWithNull: 'clearWithNull',\n /** Not a plain http(s) URL on a real domain (`javascript:`, `localhost`, an IP...). */\n urlInvalid: 'urlInvalid',\n /** A handle this product keeps for itself (`admin`, `support`...). */\n usernameReserved: 'usernameReserved',\n /** Agreed to a version of the guidelines that is not the current one. */\n guidelinesOutdated: 'guidelinesOutdated',\n /** An MPIN that is not exactly six digits. */\n mpinInvalid: 'mpinInvalid',\n /** The MPIN and its confirmation differ. */\n mpinMismatch: 'mpinMismatch',\n /** Switching to a staff role without the MPIN. */\n mpinRequired: 'mpinRequired',\n /** The same role twice in one list. */\n rolesDuplicate: 'rolesDuplicate',\n} as const;\nexport type ValidationMessageKey = (typeof VALIDATION_MESSAGE)[keyof typeof VALIDATION_MESSAGE];\n\n/**\n * Which part of the request an issue is about.\n *\n * ONE PATH CONVENTION: `path` is ALWAYS relative to this part, so a body field\n * reads `['venture', 'name']` with `location: 'body'`, never\n * `['body', 'venture', 'name']`. A form maps body issues straight onto its\n * fields without stripping a prefix, and a client that sees `query` or\n * `params` knows the problem is the URL, not anything the member typed.\n */\nexport const REQUEST_PART_VALUES = ['body', 'query', 'params'] as const;\nexport const requestPartSchema = z.enum(REQUEST_PART_VALUES);\nexport type RequestPart = z.infer<typeof requestPartSchema>;\n\n/**\n * One problem with one field, as it crosses the wire.\n *\n * `code` is Zod's issue code (`too_small`, `too_big`, `invalid_type`,\n * `invalid_format`, `custom`...). `message` is either one of\n * `VALIDATION_MESSAGE` or, for a plain bound, Zod's own English text, which the\n * client ignores in favour of `code` plus `minimum` / `maximum`.\n */\nexport const validationIssueSchema = z.object({\n /** Set by the server on every issue it sends; absent on a client's own parse. */\n location: requestPartSchema.optional(),\n /**\n * Where the problem is, RELATIVE TO `location`: `['venture', 'name']`,\n * `['options', 2, 'label']`, `['contentId']`.\n */\n path: z.array(z.union([z.string(), z.number()])),\n code: z.string(),\n message: z.string(),\n /** `too_small`: the bound that was missed. */\n minimum: z.number().optional(),\n /** `too_big`: the bound that was passed. */\n maximum: z.number().optional(),\n /** What was measured: `string`, `array`, `number`... */\n origin: z.string().optional(),\n /** `invalid_format`: which format, e.g. `url`, `regex`, `email`. */\n format: z.string().optional(),\n});\nexport type ValidationIssue = z.infer<typeof validationIssueSchema>;\n\n/** The loosest shape this needs from a Zod issue, so it works across 4.x. */\ninterface ZodIssueLike {\n path: readonly PropertyKey[];\n code: string;\n message: string;\n minimum?: unknown;\n maximum?: unknown;\n origin?: unknown;\n format?: unknown;\n}\n\nconst toNumber = (v: unknown): number | undefined =>\n typeof v === 'number' ? v : typeof v === 'bigint' ? Number(v) : undefined;\n\n/**\n * A Zod error as the wire shape. Use this on the server for every 400, and on\n * the client to treat its own errors and the server's the same way.\n *\n * `location` is stamped on every issue when given; the server always gives it.\n *\n * Copies a WHITELIST of fields (see the module note). A path segment that is a\n * symbol, which JSON cannot carry, becomes its description.\n */\nexport function toValidationIssues(\n error: { issues: readonly ZodIssueLike[] },\n location?: RequestPart,\n): ValidationIssue[] {\n return error.issues.map((issue) => {\n const out: ValidationIssue = {\n ...(location ? { location } : {}),\n path: issue.path.map((p) =>\n typeof p === 'number' ? p : typeof p === 'string' ? p : String(p.description ?? ''),\n ),\n code: issue.code,\n message: issue.message,\n };\n const minimum = toNumber(issue.minimum);\n const maximum = toNumber(issue.maximum);\n if (minimum !== undefined) out.minimum = minimum;\n if (maximum !== undefined) out.maximum = maximum;\n if (typeof issue.origin === 'string') out.origin = issue.origin;\n if (typeof issue.format === 'string') out.format = issue.format;\n return out;\n });\n}\n"]}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The member's Founder Circle account
3
+ * ===================================
4
+ * Deleting it is PER PRODUCT. It removes the member from Founder Circle and
5
+ * leaves their central-auth account, and every other product they use,
6
+ * exactly as it was. Central auth deleting the whole account arrives here as
7
+ * its `user.deleted` webhook and has the same outcome.
8
+ *
9
+ * @module founder-schema/domains/account
10
+ */
11
+ import { z } from 'zod';
12
+ /**
13
+ * `DELETE /api/v1/users/me`. No body: the confirmation (typing the account's
14
+ * email) is the client's, and the server's check is the signed-in session.
15
+ *
16
+ * What it does, all of it before it answers:
17
+ * - the founder profile stops being listed or reachable;
18
+ * - the member's posts, polls and comments are deleted, and the comment
19
+ * counts on other people's posts go down with them;
20
+ * - their reactions, bookmarks and their votes on polls still open are
21
+ * withdrawn (a closed poll's result is final and is not rewritten);
22
+ * - their messages are erased from chat and they leave every conversation;
23
+ * - every image they uploaded (their photo, their posts' images) is deleted
24
+ * from storage, so a copied image link stops working too;
25
+ * - the onboarding draft is discarded.
26
+ *
27
+ * Signing in to Founder Circle again later starts a NEW, empty account.
28
+ *
29
+ * Refusals: `SERVICE_UNAVAILABLE` (503) when the chat server could not erase
30
+ * the messages. NOTHING was deleted then, and retrying is safe.
31
+ * `RATE_LIMITED` (429). `UNAUTHORIZED` / `TOKEN_EXPIRED` /
32
+ * `SESSION_INVALIDATED` (401) and `FORBIDDEN` (403, an account that is not
33
+ * active) as for every signed-in call.
34
+ *
35
+ * The client signs out after a success: the account is gone, the cookies on
36
+ * the device are not.
37
+ */
38
+ export declare const deleteAccountResponseSchema: z.ZodObject<{
39
+ deleted: z.ZodLiteral<true>;
40
+ }, z.core.$strip>;
41
+ export type DeleteAccountResponse = z.infer<typeof deleteAccountResponseSchema>;
42
+ //# sourceMappingURL=account.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../src/domains/account/account.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,2BAA2B;;iBAEtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * The member's Founder Circle account
3
+ * ===================================
4
+ * Deleting it is PER PRODUCT. It removes the member from Founder Circle and
5
+ * leaves their central-auth account, and every other product they use,
6
+ * exactly as it was. Central auth deleting the whole account arrives here as
7
+ * its `user.deleted` webhook and has the same outcome.
8
+ *
9
+ * @module founder-schema/domains/account
10
+ */
11
+ import { z } from 'zod';
12
+ /**
13
+ * `DELETE /api/v1/users/me`. No body: the confirmation (typing the account's
14
+ * email) is the client's, and the server's check is the signed-in session.
15
+ *
16
+ * What it does, all of it before it answers:
17
+ * - the founder profile stops being listed or reachable;
18
+ * - the member's posts, polls and comments are deleted, and the comment
19
+ * counts on other people's posts go down with them;
20
+ * - their reactions, bookmarks and their votes on polls still open are
21
+ * withdrawn (a closed poll's result is final and is not rewritten);
22
+ * - their messages are erased from chat and they leave every conversation;
23
+ * - every image they uploaded (their photo, their posts' images) is deleted
24
+ * from storage, so a copied image link stops working too;
25
+ * - the onboarding draft is discarded.
26
+ *
27
+ * Signing in to Founder Circle again later starts a NEW, empty account.
28
+ *
29
+ * Refusals: `SERVICE_UNAVAILABLE` (503) when the chat server could not erase
30
+ * the messages. NOTHING was deleted then, and retrying is safe.
31
+ * `RATE_LIMITED` (429). `UNAUTHORIZED` / `TOKEN_EXPIRED` /
32
+ * `SESSION_INVALIDATED` (401) and `FORBIDDEN` (403, an account that is not
33
+ * active) as for every signed-in call.
34
+ *
35
+ * The client signs out after a success: the account is gone, the cookies on
36
+ * the device are not.
37
+ */
38
+ export const deleteAccountResponseSchema = z.object({
39
+ deleted: z.literal(true),
40
+ });
41
+ //# sourceMappingURL=account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../../../src/domains/account/account.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;CACzB,CAAC,CAAC","sourcesContent":["/**\n * The member's Founder Circle account\n * ===================================\n * Deleting it is PER PRODUCT. It removes the member from Founder Circle and\n * leaves their central-auth account, and every other product they use,\n * exactly as it was. Central auth deleting the whole account arrives here as\n * its `user.deleted` webhook and has the same outcome.\n *\n * @module founder-schema/domains/account\n */\n\nimport { z } from 'zod';\n\n/**\n * `DELETE /api/v1/users/me`. No body: the confirmation (typing the account's\n * email) is the client's, and the server's check is the signed-in session.\n *\n * What it does, all of it before it answers:\n * - the founder profile stops being listed or reachable;\n * - the member's posts, polls and comments are deleted, and the comment\n * counts on other people's posts go down with them;\n * - their reactions, bookmarks and their votes on polls still open are\n * withdrawn (a closed poll's result is final and is not rewritten);\n * - their messages are erased from chat and they leave every conversation;\n * - every image they uploaded (their photo, their posts' images) is deleted\n * from storage, so a copied image link stops working too;\n * - the onboarding draft is discarded.\n *\n * Signing in to Founder Circle again later starts a NEW, empty account.\n *\n * Refusals: `SERVICE_UNAVAILABLE` (503) when the chat server could not erase\n * the messages. NOTHING was deleted then, and retrying is safe.\n * `RATE_LIMITED` (429). `UNAUTHORIZED` / `TOKEN_EXPIRED` /\n * `SESSION_INVALIDATED` (401) and `FORBIDDEN` (403, an account that is not\n * active) as for every signed-in call.\n *\n * The client signs out after a success: the account is gone, the cookies on\n * the device are not.\n */\nexport const deleteAccountResponseSchema = z.object({\n deleted: z.literal(true),\n});\nexport type DeleteAccountResponse = z.infer<typeof deleteAccountResponseSchema>;\n"]}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * founder-schema: the audit log
3
+ *
4
+ * GET /api/v1/audit staff actions, newest first
5
+ *
6
+ * Every action a staff member takes on a MEMBER or on what a member wrote
7
+ * (roles, MPIN resets, suspensions, moderation decisions, taking and closing
8
+ * tickets) is written here, at the moment it happens, by the server: who did
9
+ * it, AS WHICH ROLE, what they did, to what, and anything that explains it.
10
+ * The support team's own library (saved replies) is not a member's, so its
11
+ * edits are not entries. Entries are never edited or
12
+ * deleted. It is how a dispute ("who removed my post, and why") gets an
13
+ * answer, and how a misused staff account is noticed.
14
+ *
15
+ * WHO READS WHAT is the reader's permissions, applied to the query: a
16
+ * superadmin reads every entry; any other staff role reads the entries it
17
+ * wrote itself (its History).
18
+ *
19
+ * The action list grows with the staff features; it never shrinks, because an
20
+ * old entry must still parse.
21
+ *
22
+ * @module founder-schema/domains/audit
23
+ */
24
+ import { z } from 'zod';
25
+ export declare const AUDIT_ACTION_VALUES: readonly ["role.granted", "role.revoked", "mpin.cleared", "content.removed", "content.hidden", "content.restored", "report.dismissed", "member.suspended", "member.unsuspended", "ticket.claimed", "ticket.resolved"];
26
+ export declare const auditActionSchema: z.ZodEnum<{
27
+ "role.granted": "role.granted";
28
+ "role.revoked": "role.revoked";
29
+ "mpin.cleared": "mpin.cleared";
30
+ "content.removed": "content.removed";
31
+ "content.hidden": "content.hidden";
32
+ "content.restored": "content.restored";
33
+ "report.dismissed": "report.dismissed";
34
+ "member.suspended": "member.suspended";
35
+ "member.unsuspended": "member.unsuspended";
36
+ "ticket.claimed": "ticket.claimed";
37
+ "ticket.resolved": "ticket.resolved";
38
+ }>;
39
+ export type AuditAction = z.infer<typeof auditActionSchema>;
40
+ /**
41
+ * Who did it. A person, acting as one of their roles; or a server script, which
42
+ * is the only way a superadmin is ever made.
43
+ */
44
+ export declare const auditActorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
45
+ kind: z.ZodLiteral<"staff">;
46
+ id: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
47
+ displayName: z.ZodString;
48
+ actingAs: z.ZodEnum<{
49
+ superadmin: "superadmin";
50
+ manager: "manager";
51
+ moderator: "moderator";
52
+ support_agent: "support_agent";
53
+ member: "member";
54
+ }>;
55
+ }, z.core.$strip>, z.ZodObject<{
56
+ kind: z.ZodLiteral<"script">;
57
+ name: z.ZodString;
58
+ }, z.core.$strip>], "kind">;
59
+ export type AuditActor = z.infer<typeof auditActorSchema>;
60
+ export declare const auditEntrySchema: z.ZodObject<{
61
+ id: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
62
+ actor: z.ZodDiscriminatedUnion<[z.ZodObject<{
63
+ kind: z.ZodLiteral<"staff">;
64
+ id: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
65
+ displayName: z.ZodString;
66
+ actingAs: z.ZodEnum<{
67
+ superadmin: "superadmin";
68
+ manager: "manager";
69
+ moderator: "moderator";
70
+ support_agent: "support_agent";
71
+ member: "member";
72
+ }>;
73
+ }, z.core.$strip>, z.ZodObject<{
74
+ kind: z.ZodLiteral<"script">;
75
+ name: z.ZodString;
76
+ }, z.core.$strip>], "kind">;
77
+ action: z.ZodEnum<{
78
+ "role.granted": "role.granted";
79
+ "role.revoked": "role.revoked";
80
+ "mpin.cleared": "mpin.cleared";
81
+ "content.removed": "content.removed";
82
+ "content.hidden": "content.hidden";
83
+ "content.restored": "content.restored";
84
+ "report.dismissed": "report.dismissed";
85
+ "member.suspended": "member.suspended";
86
+ "member.unsuspended": "member.unsuspended";
87
+ "ticket.claimed": "ticket.claimed";
88
+ "ticket.resolved": "ticket.resolved";
89
+ }>;
90
+ target: z.ZodObject<{
91
+ subject: z.ZodEnum<{
92
+ all: "all";
93
+ Dashboard: "Dashboard";
94
+ Member: "Member";
95
+ FounderProfile: "FounderProfile";
96
+ Post: "Post";
97
+ Poll: "Poll";
98
+ Comment: "Comment";
99
+ Report: "Report";
100
+ SupportTicket: "SupportTicket";
101
+ SavedReply: "SavedReply";
102
+ PlatformRole: "PlatformRole";
103
+ AuditEntry: "AuditEntry";
104
+ PlatformSettings: "PlatformSettings";
105
+ }>;
106
+ id: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
107
+ label: z.ZodNullable<z.ZodString>;
108
+ }, z.core.$strip>;
109
+ detail: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
110
+ at: z.ZodISODateTime;
111
+ }, z.core.$strip>;
112
+ export type AuditEntry = z.infer<typeof auditEntrySchema>;
113
+ export declare const auditPageSchema: z.ZodObject<{
114
+ items: z.ZodArray<z.ZodObject<{
115
+ id: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
116
+ actor: z.ZodDiscriminatedUnion<[z.ZodObject<{
117
+ kind: z.ZodLiteral<"staff">;
118
+ id: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
119
+ displayName: z.ZodString;
120
+ actingAs: z.ZodEnum<{
121
+ superadmin: "superadmin";
122
+ manager: "manager";
123
+ moderator: "moderator";
124
+ support_agent: "support_agent";
125
+ member: "member";
126
+ }>;
127
+ }, z.core.$strip>, z.ZodObject<{
128
+ kind: z.ZodLiteral<"script">;
129
+ name: z.ZodString;
130
+ }, z.core.$strip>], "kind">;
131
+ action: z.ZodEnum<{
132
+ "role.granted": "role.granted";
133
+ "role.revoked": "role.revoked";
134
+ "mpin.cleared": "mpin.cleared";
135
+ "content.removed": "content.removed";
136
+ "content.hidden": "content.hidden";
137
+ "content.restored": "content.restored";
138
+ "report.dismissed": "report.dismissed";
139
+ "member.suspended": "member.suspended";
140
+ "member.unsuspended": "member.unsuspended";
141
+ "ticket.claimed": "ticket.claimed";
142
+ "ticket.resolved": "ticket.resolved";
143
+ }>;
144
+ target: z.ZodObject<{
145
+ subject: z.ZodEnum<{
146
+ all: "all";
147
+ Dashboard: "Dashboard";
148
+ Member: "Member";
149
+ FounderProfile: "FounderProfile";
150
+ Post: "Post";
151
+ Poll: "Poll";
152
+ Comment: "Comment";
153
+ Report: "Report";
154
+ SupportTicket: "SupportTicket";
155
+ SavedReply: "SavedReply";
156
+ PlatformRole: "PlatformRole";
157
+ AuditEntry: "AuditEntry";
158
+ PlatformSettings: "PlatformSettings";
159
+ }>;
160
+ id: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
161
+ label: z.ZodNullable<z.ZodString>;
162
+ }, z.core.$strip>;
163
+ detail: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
164
+ at: z.ZodISODateTime;
165
+ }, z.core.$strip>>;
166
+ nextCursor: z.ZodNullable<z.ZodString>;
167
+ }, z.core.$strip>;
168
+ export type AuditPage = z.infer<typeof auditPageSchema>;
169
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../src/domains/audit/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,mBAAmB,uNAuBtB,CAAC;AACX,eAAO,MAAM,iBAAiB;;;;;;;;;;;;EAA8B,CAAC;AAC7D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;2BAc3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAS3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAoC,CAAC;AACjE,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC"}