founder-schema 0.5.0 → 0.7.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/README.md +67 -0
- package/dist/access/permissions.d.ts +24 -2
- package/dist/access/permissions.d.ts.map +1 -1
- package/dist/access/permissions.js +9 -0
- package/dist/access/permissions.js.map +1 -1
- package/dist/core/common.d.ts +44 -0
- package/dist/core/common.d.ts.map +1 -1
- package/dist/core/common.js +76 -0
- package/dist/core/common.js.map +1 -1
- package/dist/core/errors.d.ts +29 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +52 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/core/limits.d.ts +53 -0
- package/dist/core/limits.d.ts.map +1 -1
- package/dist/core/limits.js +57 -0
- package/dist/core/limits.js.map +1 -1
- package/dist/core/responses.d.ts +43 -0
- package/dist/core/responses.d.ts.map +1 -1
- package/dist/core/responses.js +3 -1
- package/dist/core/responses.js.map +1 -1
- package/dist/core/validation.d.ts +14 -0
- package/dist/core/validation.d.ts.map +1 -1
- package/dist/core/validation.js +14 -0
- package/dist/core/validation.js.map +1 -1
- package/dist/domains/audit/audit.d.ts +4 -0
- package/dist/domains/audit/audit.d.ts.map +1 -1
- package/dist/domains/audit/audit.js +6 -3
- package/dist/domains/audit/audit.js.map +1 -1
- package/dist/domains/contributions/contributions.d.ts +165 -0
- package/dist/domains/contributions/contributions.d.ts.map +1 -0
- package/dist/domains/contributions/contributions.js +103 -0
- package/dist/domains/contributions/contributions.js.map +1 -0
- package/dist/domains/discover/discover.d.ts +5 -0
- package/dist/domains/discover/discover.d.ts.map +1 -1
- package/dist/domains/discover/discover.js +3 -13
- package/dist/domains/discover/discover.js.map +1 -1
- package/dist/domains/feed/feed.d.ts +231 -7
- package/dist/domains/feed/feed.d.ts.map +1 -1
- package/dist/domains/feed/feed.js +86 -18
- package/dist/domains/feed/feed.js.map +1 -1
- package/dist/domains/media/media.d.ts +30 -5
- package/dist/domains/media/media.d.ts.map +1 -1
- package/dist/domains/media/media.js +32 -6
- package/dist/domains/media/media.js.map +1 -1
- package/dist/domains/members/members.d.ts +5 -5
- package/dist/domains/moderation/moderation.d.ts +53 -3
- package/dist/domains/moderation/moderation.d.ts.map +1 -1
- package/dist/domains/moderation/moderation.js +47 -8
- package/dist/domains/moderation/moderation.js.map +1 -1
- package/dist/domains/notifications/notifications.d.ts +212 -0
- package/dist/domains/notifications/notifications.d.ts.map +1 -0
- package/dist/domains/notifications/notifications.js +148 -0
- package/dist/domains/notifications/notifications.js.map +1 -0
- package/dist/domains/onboarding/onboarding.d.ts +10 -13
- package/dist/domains/onboarding/onboarding.d.ts.map +1 -1
- package/dist/domains/onboarding/onboarding.js +6 -5
- package/dist/domains/onboarding/onboarding.js.map +1 -1
- package/dist/domains/products/products.d.ts +1464 -0
- package/dist/domains/products/products.d.ts.map +1 -0
- package/dist/domains/products/products.js +474 -0
- package/dist/domains/products/products.js.map +1 -0
- package/dist/domains/profile/founder-profile.d.ts +43 -0
- package/dist/domains/profile/founder-profile.d.ts.map +1 -1
- package/dist/domains/profile/founder-profile.js +48 -0
- package/dist/domains/profile/founder-profile.js.map +1 -1
- package/dist/domains/reviews/reviews.d.ts +184 -0
- package/dist/domains/reviews/reviews.d.ts.map +1 -0
- package/dist/domains/reviews/reviews.js +99 -0
- package/dist/domains/reviews/reviews.js.map +1 -0
- package/dist/domains/uploads/uploads.d.ts +2 -0
- package/dist/domains/uploads/uploads.d.ts.map +1 -1
- package/dist/index.d.ts +10 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -56,6 +56,40 @@ export declare const ventureSchema: z.ZodObject<{
|
|
|
56
56
|
foundedYear: z.ZodOptional<z.ZodNumber>;
|
|
57
57
|
}, z.core.$strip>;
|
|
58
58
|
export type Venture = z.infer<typeof ventureSchema>;
|
|
59
|
+
/**
|
|
60
|
+
* A member as a byline renders them: on a post (`feedAuthorSchema` is this), a
|
|
61
|
+
* product's team, a review, a notification, the top-helpers list.
|
|
62
|
+
*
|
|
63
|
+
* Every field is LIVE, joined against the profile at read time rather than
|
|
64
|
+
* frozen onto the post or review at write time. So a renamed handle, a new
|
|
65
|
+
* photo or an edited headline updates everywhere, the link always targets the
|
|
66
|
+
* current username, and nothing personal survives in other people's rows once
|
|
67
|
+
* an account is deleted.
|
|
68
|
+
*/
|
|
69
|
+
export declare const memberBylineSchema: z.ZodObject<{
|
|
70
|
+
userId: z.ZodString;
|
|
71
|
+
username: z.ZodString;
|
|
72
|
+
displayName: z.ZodString;
|
|
73
|
+
avatarUrl: z.ZodOptional<z.ZodURL>;
|
|
74
|
+
headline: z.ZodOptional<z.ZodString>;
|
|
75
|
+
}, z.core.$strip>;
|
|
76
|
+
export type MemberByline = z.infer<typeof memberBylineSchema>;
|
|
77
|
+
/**
|
|
78
|
+
* What a member has given the community, on their profile and card.
|
|
79
|
+
*
|
|
80
|
+
* `score` is points earned from OTHER members' recognition only: a product's
|
|
81
|
+
* team marking your feedback helpful, confirming you tested their product,
|
|
82
|
+
* and members finding your review helpful (writing one earns nothing by
|
|
83
|
+
* itself). Nothing a member
|
|
84
|
+
* does to their own product counts, so the score cannot be bought by having a
|
|
85
|
+
* popular one. `helpedCount` is how many different founders recognised that
|
|
86
|
+
* help ("Helped 12 founders"). See `domains/contributions`.
|
|
87
|
+
*/
|
|
88
|
+
export declare const contributionSummarySchema: z.ZodObject<{
|
|
89
|
+
score: z.ZodNumber;
|
|
90
|
+
helpedCount: z.ZodNumber;
|
|
91
|
+
}, z.core.$strip>;
|
|
92
|
+
export type ContributionSummary = z.infer<typeof contributionSummarySchema>;
|
|
59
93
|
/**
|
|
60
94
|
* The founder's off-platform links. ONE shape: onboarding's contact step picks
|
|
61
95
|
* its three from this, so a link one side knows can never be missing on the
|
|
@@ -180,6 +214,10 @@ export declare const founderProfileSchema: z.ZodObject<{
|
|
|
180
214
|
github: z.ZodOptional<z.ZodURL>;
|
|
181
215
|
website: z.ZodOptional<z.ZodURL>;
|
|
182
216
|
}, z.core.$strip>>;
|
|
217
|
+
contribution: z.ZodObject<{
|
|
218
|
+
score: z.ZodNumber;
|
|
219
|
+
helpedCount: z.ZodNumber;
|
|
220
|
+
}, z.core.$strip>;
|
|
183
221
|
isOnboarded: z.ZodDefault<z.ZodBoolean>;
|
|
184
222
|
isActive: z.ZodDefault<z.ZodBoolean>;
|
|
185
223
|
createdAt: z.ZodISODateTime;
|
|
@@ -201,9 +239,14 @@ export declare const founderCardSchema: z.ZodObject<{
|
|
|
201
239
|
country: z.ZodString;
|
|
202
240
|
}, z.core.$strip>>;
|
|
203
241
|
displayName: z.ZodString;
|
|
242
|
+
userId: z.ZodString;
|
|
204
243
|
username: z.ZodString;
|
|
205
244
|
avatarUrl: z.ZodOptional<z.ZodURL>;
|
|
206
245
|
headline: z.ZodPreprocess<z.ZodOptional<z.ZodString>, unknown>;
|
|
246
|
+
contribution: z.ZodObject<{
|
|
247
|
+
score: z.ZodNumber;
|
|
248
|
+
helpedCount: z.ZodNumber;
|
|
249
|
+
}, z.core.$strip>;
|
|
207
250
|
venture: z.ZodOptional<z.ZodObject<{
|
|
208
251
|
name: z.ZodString;
|
|
209
252
|
tagline: z.ZodPreprocess<z.ZodOptional<z.ZodString>, unknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"founder-profile.d.ts","sourceRoot":"","sources":["../../../src/domains/profile/founder-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA8BxB;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0BxB,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAIpD;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB;;;;;;iBAM7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;GAIG;AACH,eAAO,MAAM,oBAAoB
|
|
1
|
+
{"version":3,"file":"founder-profile.d.ts","sourceRoot":"","sources":["../../../src/domains/profile/founder-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA8BxB;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0BxB,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAIpD;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB;;;;;;iBAS7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB;;;iBAGpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAI5E;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB;;;;;;iBAM7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqD/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgB5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAqB5D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAWzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF;;;GAGG;AACH,eAAO,MAAM,wBAAwB;;iBAA+C,CAAC;AACrF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,oDAAoD;AACpD,eAAO,MAAM,0BAA0B;;;;;;;iBAKrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAI9E;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB;;iBAAwC,CAAC;AACzE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
|
|
@@ -47,6 +47,42 @@ export const ventureSchema = z.object({
|
|
|
47
47
|
})
|
|
48
48
|
.optional(),
|
|
49
49
|
});
|
|
50
|
+
// ─── A member as other surfaces name them ────────────────────────────────────
|
|
51
|
+
/**
|
|
52
|
+
* A member as a byline renders them: on a post (`feedAuthorSchema` is this), a
|
|
53
|
+
* product's team, a review, a notification, the top-helpers list.
|
|
54
|
+
*
|
|
55
|
+
* Every field is LIVE, joined against the profile at read time rather than
|
|
56
|
+
* frozen onto the post or review at write time. So a renamed handle, a new
|
|
57
|
+
* photo or an edited headline updates everywhere, the link always targets the
|
|
58
|
+
* current username, and nothing personal survives in other people's rows once
|
|
59
|
+
* an account is deleted.
|
|
60
|
+
*/
|
|
61
|
+
export const memberBylineSchema = z.object({
|
|
62
|
+
userId: z.string(),
|
|
63
|
+
username: usernameSchema,
|
|
64
|
+
displayName: z.string(),
|
|
65
|
+
/** Server-generated or from the login provider, never member-typed, so a
|
|
66
|
+
* plain URL check. Same reasoning as `avatarUrl` on the profile. */
|
|
67
|
+
avatarUrl: z.url().optional(),
|
|
68
|
+
/** The member's one-line headline, live-joined. */
|
|
69
|
+
headline: z.string().optional(),
|
|
70
|
+
});
|
|
71
|
+
/**
|
|
72
|
+
* What a member has given the community, on their profile and card.
|
|
73
|
+
*
|
|
74
|
+
* `score` is points earned from OTHER members' recognition only: a product's
|
|
75
|
+
* team marking your feedback helpful, confirming you tested their product,
|
|
76
|
+
* and members finding your review helpful (writing one earns nothing by
|
|
77
|
+
* itself). Nothing a member
|
|
78
|
+
* does to their own product counts, so the score cannot be bought by having a
|
|
79
|
+
* popular one. `helpedCount` is how many different founders recognised that
|
|
80
|
+
* help ("Helped 12 founders"). See `domains/contributions`.
|
|
81
|
+
*/
|
|
82
|
+
export const contributionSummarySchema = z.object({
|
|
83
|
+
score: z.number().int().nonnegative(),
|
|
84
|
+
helpedCount: z.number().int().nonnegative(),
|
|
85
|
+
});
|
|
50
86
|
// ─── Profile ─────────────────────────────────────────────────────────────────
|
|
51
87
|
/**
|
|
52
88
|
* The founder's off-platform links. ONE shape: onboarding's contact step picks
|
|
@@ -110,6 +146,12 @@ export const founderProfileSchema = z.object({
|
|
|
110
146
|
skills: z.array(skillSchema).max(SKILLS_MAX).default([]),
|
|
111
147
|
goals: z.array(goalSchema).max(GOAL_VALUES.length).default([]),
|
|
112
148
|
links: founderLinksSchema.default({}),
|
|
149
|
+
/**
|
|
150
|
+
* Their contribution to other founders. Server-computed, never written by a
|
|
151
|
+
* member. REQUIRED, no default: a read-side default would let a server that
|
|
152
|
+
* forgot the field pass as a real zero.
|
|
153
|
+
*/
|
|
154
|
+
contribution: contributionSummarySchema,
|
|
113
155
|
/** Onboarding is finished and the member is visible in Discover. */
|
|
114
156
|
isOnboarded: z.boolean().default(false),
|
|
115
157
|
/** Member paused their own profile. Hidden from Discover, keeps their data. */
|
|
@@ -126,6 +168,11 @@ export const founderProfileSchema = z.object({
|
|
|
126
168
|
*/
|
|
127
169
|
export const founderCardSchema = founderProfileSchema.pick({
|
|
128
170
|
id: true,
|
|
171
|
+
/**
|
|
172
|
+
* The MEMBER's id (0.6.0): what a team invitation, a chat and every byline
|
|
173
|
+
* key on. `id` is the profile's own id, which nothing takes as input.
|
|
174
|
+
*/
|
|
175
|
+
userId: true,
|
|
129
176
|
username: true,
|
|
130
177
|
displayName: true,
|
|
131
178
|
headline: true,
|
|
@@ -134,6 +181,7 @@ export const founderCardSchema = founderProfileSchema.pick({
|
|
|
134
181
|
venture: true,
|
|
135
182
|
skills: true,
|
|
136
183
|
goals: true,
|
|
184
|
+
contribution: true,
|
|
137
185
|
});
|
|
138
186
|
// ─── Write bodies ────────────────────────────────────────────────────────────
|
|
139
187
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"founder-profile.js","sourceRoot":"","sources":["../../../src/domains/profile/founder-profile.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * founder-schema — The founder profile\n *\n * One member, one profile. The central auth account owns identity (email,\n * verification, deletion); this owns everything Founder Circle shows.\n *\n * @module founder-schema/domains/profile\n */\n\nimport { z } from 'zod';\nimport {\n chosenUsernameSchema,\n GOAL_VALUES,\n goalSchema,\n httpUrlSchema,\n industrySchema,\n locationSchema,\n objectIdSchema,\n optionalTrimmedString,\n skillSchema,\n startupStageSchema,\n usernameSchema,\n} from '../../core/common.js';\nimport {\n ABOUT_MAX,\n DISPLAY_NAME_MAX,\n FOUNDED_YEAR_MIN,\n HEADLINE_MAX,\n SKILLS_MAX,\n TEAM_SIZE_MAX,\n TEAM_SIZE_MIN,\n VENTURE_NAME_MAX,\n VENTURE_TAGLINE_MAX,\n} from '../../core/limits.js';\nimport { VALIDATION_MESSAGE } from '../../core/validation.js';\nimport { mediaImageSchema } from '../media/media.js';\n\n// ─── Venture ─────────────────────────────────────────────────────────────────\n\n/**\n * ⚠ NUMBERS ARE NUMBERS, never coerced. This is a BODY, which arrives as JSON\n * and already carries types. `z.coerce.number()` here accepted `teamSize: true`\n * as 1 and `\" \"` as 0, and made the schema's input type `unknown`, so a form\n * typed against it could put anything in the field. Coercion belongs to query\n * strings, where everything is text; a form converts its text input before it\n * builds the body.\n */\nexport const ventureSchema = z.object({\n name: z.string().trim().min(1).max(VENTURE_NAME_MAX),\n tagline: optionalTrimmedString(VENTURE_TAGLINE_MAX),\n website: httpUrlSchema.optional(),\n industry: industrySchema,\n stage: startupStageSchema,\n /** Team size including the founder. Optional: a solo pre-idea founder has none to report. */\n teamSize: z.number().int().min(TEAM_SIZE_MIN).max(TEAM_SIZE_MAX).optional(),\n /**\n * Not in the future. The bound is read per parse, never captured once.\n *\n * `.max(new Date().getUTCFullYear())` looks equivalent and is not: it is\n * evaluated when this module is imported, so a server process still up on\n * 1 January rejects the new year until somebody restarts it. The backend's\n * Mongoose model deliberately carries no upper bound for the same reason, a\n * `max` there being frozen at schema construction. This is where the ceiling\n * lives.\n */\n foundedYear: z\n .number()\n .int()\n .min(FOUNDED_YEAR_MIN)\n .refine((year) => year <= new Date().getUTCFullYear(), {\n error: VALIDATION_MESSAGE.foundedYearFuture,\n })\n .optional(),\n});\nexport type Venture = z.infer<typeof ventureSchema>;\n\n// ─── Profile ─────────────────────────────────────────────────────────────────\n\n/**\n * The founder's off-platform links. ONE shape: onboarding's contact step picks\n * its three from this, so a link one side knows can never be missing on the\n * other. (It was written twice until 0.2.0, and the profile side lacked\n * Instagram, which onboarding collected.)\n *\n * Defined without a default, because the read side wants one and the write\n * side must not have one; each adds its own.\n */\nexport const founderLinksSchema = z.object({\n linkedin: httpUrlSchema.optional(),\n x: httpUrlSchema.optional(),\n instagram: httpUrlSchema.optional(),\n github: httpUrlSchema.optional(),\n website: httpUrlSchema.optional(),\n});\nexport type FounderLinks = z.infer<typeof founderLinksSchema>;\n\n/**\n * The profile as the owner sees it. A peer sees the redacted projection\n * (`founderCardSchema`), which is built on the server and never by dropping\n * fields on the client.\n */\nexport const founderProfileSchema = z.object({\n id: z.string(),\n userId: z.string(),\n username: usernameSchema,\n displayName: z.string().trim().min(1).max(DISPLAY_NAME_MAX),\n headline: optionalTrimmedString(HEADLINE_MAX),\n about: optionalTrimmedString(ABOUT_MAX),\n /**\n * Plain `z.url()`, NOT `httpUrlSchema`, and the difference is deliberate.\n *\n * No member can write this field: it appears in no write body, and\n * `public-surface.test.ts` asserts that and will fail the day somebody adds it\n * to a form. So the scheme restriction would be defending a field that takes\n * no member input, while refusing hosts we legitimately serve avatars from,\n * our own dev host among them. A read schema that rejects our own response is\n * a self-inflicted outage.\n *\n * ⚠️ That argument holds only while nothing member-supplied reaches this\n * field. Two sources write an avatar today and NEITHER is a member typing a\n * URL: our own upload path, and the central-auth `user.created` /\n * `user.updated` webhook, which carries the Google OAuth picture. If a\n * \"paste a link to your photo\" control is ever added, this goes back to\n * `httpUrlSchema` and the ruling behind it is void.\n *\n * WHICH picture: the member's uploaded photo at its small size (192, see\n * `MEDIA_SIZES.avatar`), else their sign-in provider's picture, else absent.\n * Every surface that shows this member resolves it the same way.\n */\n avatarUrl: z.url().optional(),\n /**\n * The uploaded photo itself, every size, when the member has one. Absent\n * means `avatarUrl` (if any) is the sign-in provider's picture, so a client\n * offers \"Remove photo\" only when this is present. Not on `founderCardSchema`:\n * a card needs one small picture, not the set.\n */\n avatar: mediaImageSchema.optional(),\n location: locationSchema.optional(),\n venture: ventureSchema.optional(),\n skills: z.array(skillSchema).max(SKILLS_MAX).default([]),\n goals: z.array(goalSchema).max(GOAL_VALUES.length).default([]),\n links: founderLinksSchema.default({}),\n /** Onboarding is finished and the member is visible in Discover. */\n isOnboarded: z.boolean().default(false),\n /** Member paused their own profile. Hidden from Discover, keeps their data. */\n isActive: z.boolean().default(true),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n});\nexport type FounderProfile = z.infer<typeof founderProfileSchema>;\n\n/**\n * What one founder sees of another in Discover and on a profile page.\n *\n * Built server-side. Keep it a strict subset of `founderProfileSchema` — if a\n * private field ever needs to show here, that is a product decision, not an\n * accident of spreading the full document.\n */\nexport const founderCardSchema = founderProfileSchema.pick({\n id: true,\n username: true,\n displayName: true,\n headline: true,\n avatarUrl: true,\n location: true,\n venture: true,\n skills: true,\n goals: true,\n});\nexport type FounderCard = z.infer<typeof founderCardSchema>;\n\n// ─── Write bodies ────────────────────────────────────────────────────────────\n\n/**\n * A text field the member is allowed to empty.\n *\n * Three states, and they are deliberately distinct:\n * absent do not touch this field\n * null clear it (the backend turns this into an `$unset`)\n * \"\" REJECTED\n *\n * The empty string is refused on purpose. A form that forgets to convert a\n * cleared input to `null` then fails loudly at the boundary, instead of being\n * silently dropped and leaving the member staring at text they just deleted.\n * `optionalTrimmedString` does the dropping, which is right for a create body\n * and wrong for a patch.\n */\nconst clearableText = (maxLength: number) =>\n z.string().trim().min(1, VALIDATION_MESSAGE.clearWithNull).max(maxLength).nullable().optional();\n\n/**\n * Patch body for the Me tab. Only the keys the member actually changed.\n *\n * ⚠️ Written as its own object ON PURPOSE. Do NOT rebuild it as\n * `founderProfileSchema.pick({...}).partial()`: `.partial()` does not switch\n * off `.default()`, so `skills`, `goals` and `links` would materialise as\n * `[]`, `[]` and `{}` on every request, including an empty one. Under a `$set`\n * that wipes a member's skills and every one of their links the moment they\n * edit their display name. `tsc` cannot see it and the request looks correct in\n * the network tab.\n *\n * The rule this comes from: defaults belong on the READ side. A write body\n * states what the caller sent and nothing else.\n */\nexport const updateFounderProfileBodySchema = z.object({\n displayName: z.string().trim().min(1).max(DISPLAY_NAME_MAX).optional(),\n headline: clearableText(HEADLINE_MAX),\n about: clearableText(ABOUT_MAX),\n /** Carries the whole location; `locationSchema` has no default to fill a gap. */\n location: locationSchema.optional(),\n venture: ventureSchema.optional(),\n skills: z.array(skillSchema).max(SKILLS_MAX).optional(),\n goals: z.array(goalSchema).max(GOAL_VALUES.length).optional(),\n /** Sent whole. To drop one link, send the object without that key. */\n links: founderLinksSchema.optional(),\n});\nexport type UpdateFounderProfileBody = z.infer<typeof updateFounderProfileBodySchema>;\n\n/**\n * Username change. Separate from the profile patch because it needs a\n * uniqueness check, and it refuses a reserved handle (`chosenUsernameSchema`).\n */\nexport const updateUsernameBodySchema = z.object({ username: chosenUsernameSchema });\nexport type UpdateUsernameBody = z.infer<typeof updateUsernameBodySchema>;\n\n/** Availability probe behind the username field. */\nexport const usernameAvailabilitySchema = z.object({\n username: usernameSchema,\n available: z.boolean(),\n /** Present when unavailable: `taken` or `reserved`. */\n reason: z.enum(['taken', 'reserved']).optional(),\n});\nexport type UsernameAvailability = z.infer<typeof usernameAvailabilitySchema>;\n\n// ─── The member's own photo ──────────────────────────────────────────────────\n\n/**\n * `PUT /api/v1/profiles/me/avatar`: use a completed upload (purpose `avatar`)\n * as the member's photo. Answers with the updated `founderProfileSchema`.\n *\n * The previous photo is deleted from storage, not merely unlinked, so its old\n * address stops working. `DELETE /api/v1/profiles/me/avatar` removes the photo\n * the same way and the member falls back to their sign-in provider's picture.\n */\nexport const setAvatarBodySchema = z.object({ mediaId: objectIdSchema });\nexport type SetAvatarBody = z.infer<typeof setAvatarBodySchema>;\n"]}
|
|
1
|
+
{"version":3,"file":"founder-profile.js","sourceRoot":"","sources":["../../../src/domains/profile/founder-profile.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * founder-schema — The founder profile\n *\n * One member, one profile. The central auth account owns identity (email,\n * verification, deletion); this owns everything Founder Circle shows.\n *\n * @module founder-schema/domains/profile\n */\n\nimport { z } from 'zod';\nimport {\n chosenUsernameSchema,\n GOAL_VALUES,\n goalSchema,\n httpUrlSchema,\n industrySchema,\n locationSchema,\n objectIdSchema,\n optionalTrimmedString,\n skillSchema,\n startupStageSchema,\n usernameSchema,\n} from '../../core/common.js';\nimport {\n ABOUT_MAX,\n DISPLAY_NAME_MAX,\n FOUNDED_YEAR_MIN,\n HEADLINE_MAX,\n SKILLS_MAX,\n TEAM_SIZE_MAX,\n TEAM_SIZE_MIN,\n VENTURE_NAME_MAX,\n VENTURE_TAGLINE_MAX,\n} from '../../core/limits.js';\nimport { VALIDATION_MESSAGE } from '../../core/validation.js';\nimport { mediaImageSchema } from '../media/media.js';\n\n// ─── Venture ─────────────────────────────────────────────────────────────────\n\n/**\n * ⚠ NUMBERS ARE NUMBERS, never coerced. This is a BODY, which arrives as JSON\n * and already carries types. `z.coerce.number()` here accepted `teamSize: true`\n * as 1 and `\" \"` as 0, and made the schema's input type `unknown`, so a form\n * typed against it could put anything in the field. Coercion belongs to query\n * strings, where everything is text; a form converts its text input before it\n * builds the body.\n */\nexport const ventureSchema = z.object({\n name: z.string().trim().min(1).max(VENTURE_NAME_MAX),\n tagline: optionalTrimmedString(VENTURE_TAGLINE_MAX),\n website: httpUrlSchema.optional(),\n industry: industrySchema,\n stage: startupStageSchema,\n /** Team size including the founder. Optional: a solo pre-idea founder has none to report. */\n teamSize: z.number().int().min(TEAM_SIZE_MIN).max(TEAM_SIZE_MAX).optional(),\n /**\n * Not in the future. The bound is read per parse, never captured once.\n *\n * `.max(new Date().getUTCFullYear())` looks equivalent and is not: it is\n * evaluated when this module is imported, so a server process still up on\n * 1 January rejects the new year until somebody restarts it. The backend's\n * Mongoose model deliberately carries no upper bound for the same reason, a\n * `max` there being frozen at schema construction. This is where the ceiling\n * lives.\n */\n foundedYear: z\n .number()\n .int()\n .min(FOUNDED_YEAR_MIN)\n .refine((year) => year <= new Date().getUTCFullYear(), {\n error: VALIDATION_MESSAGE.foundedYearFuture,\n })\n .optional(),\n});\nexport type Venture = z.infer<typeof ventureSchema>;\n\n// ─── A member as other surfaces name them ────────────────────────────────────\n\n/**\n * A member as a byline renders them: on a post (`feedAuthorSchema` is this), a\n * product's team, a review, a notification, the top-helpers list.\n *\n * Every field is LIVE, joined against the profile at read time rather than\n * frozen onto the post or review at write time. So a renamed handle, a new\n * photo or an edited headline updates everywhere, the link always targets the\n * current username, and nothing personal survives in other people's rows once\n * an account is deleted.\n */\nexport const memberBylineSchema = z.object({\n userId: z.string(),\n username: usernameSchema,\n displayName: z.string(),\n /** Server-generated or from the login provider, never member-typed, so a\n * plain URL check. Same reasoning as `avatarUrl` on the profile. */\n avatarUrl: z.url().optional(),\n /** The member's one-line headline, live-joined. */\n headline: z.string().optional(),\n});\nexport type MemberByline = z.infer<typeof memberBylineSchema>;\n\n/**\n * What a member has given the community, on their profile and card.\n *\n * `score` is points earned from OTHER members' recognition only: a product's\n * team marking your feedback helpful, confirming you tested their product,\n * and members finding your review helpful (writing one earns nothing by\n * itself). Nothing a member\n * does to their own product counts, so the score cannot be bought by having a\n * popular one. `helpedCount` is how many different founders recognised that\n * help (\"Helped 12 founders\"). See `domains/contributions`.\n */\nexport const contributionSummarySchema = z.object({\n score: z.number().int().nonnegative(),\n helpedCount: z.number().int().nonnegative(),\n});\nexport type ContributionSummary = z.infer<typeof contributionSummarySchema>;\n\n// ─── Profile ─────────────────────────────────────────────────────────────────\n\n/**\n * The founder's off-platform links. ONE shape: onboarding's contact step picks\n * its three from this, so a link one side knows can never be missing on the\n * other. (It was written twice until 0.2.0, and the profile side lacked\n * Instagram, which onboarding collected.)\n *\n * Defined without a default, because the read side wants one and the write\n * side must not have one; each adds its own.\n */\nexport const founderLinksSchema = z.object({\n linkedin: httpUrlSchema.optional(),\n x: httpUrlSchema.optional(),\n instagram: httpUrlSchema.optional(),\n github: httpUrlSchema.optional(),\n website: httpUrlSchema.optional(),\n});\nexport type FounderLinks = z.infer<typeof founderLinksSchema>;\n\n/**\n * The profile as the owner sees it. A peer sees the redacted projection\n * (`founderCardSchema`), which is built on the server and never by dropping\n * fields on the client.\n */\nexport const founderProfileSchema = z.object({\n id: z.string(),\n userId: z.string(),\n username: usernameSchema,\n displayName: z.string().trim().min(1).max(DISPLAY_NAME_MAX),\n headline: optionalTrimmedString(HEADLINE_MAX),\n about: optionalTrimmedString(ABOUT_MAX),\n /**\n * Plain `z.url()`, NOT `httpUrlSchema`, and the difference is deliberate.\n *\n * No member can write this field: it appears in no write body, and\n * `public-surface.test.ts` asserts that and will fail the day somebody adds it\n * to a form. So the scheme restriction would be defending a field that takes\n * no member input, while refusing hosts we legitimately serve avatars from,\n * our own dev host among them. A read schema that rejects our own response is\n * a self-inflicted outage.\n *\n * ⚠️ That argument holds only while nothing member-supplied reaches this\n * field. Two sources write an avatar today and NEITHER is a member typing a\n * URL: our own upload path, and the central-auth `user.created` /\n * `user.updated` webhook, which carries the Google OAuth picture. If a\n * \"paste a link to your photo\" control is ever added, this goes back to\n * `httpUrlSchema` and the ruling behind it is void.\n *\n * WHICH picture: the member's uploaded photo at its small size (192, see\n * `MEDIA_SIZES.avatar`), else their sign-in provider's picture, else absent.\n * Every surface that shows this member resolves it the same way.\n */\n avatarUrl: z.url().optional(),\n /**\n * The uploaded photo itself, every size, when the member has one. Absent\n * means `avatarUrl` (if any) is the sign-in provider's picture, so a client\n * offers \"Remove photo\" only when this is present. Not on `founderCardSchema`:\n * a card needs one small picture, not the set.\n */\n avatar: mediaImageSchema.optional(),\n location: locationSchema.optional(),\n venture: ventureSchema.optional(),\n skills: z.array(skillSchema).max(SKILLS_MAX).default([]),\n goals: z.array(goalSchema).max(GOAL_VALUES.length).default([]),\n links: founderLinksSchema.default({}),\n /**\n * Their contribution to other founders. Server-computed, never written by a\n * member. REQUIRED, no default: a read-side default would let a server that\n * forgot the field pass as a real zero.\n */\n contribution: contributionSummarySchema,\n /** Onboarding is finished and the member is visible in Discover. */\n isOnboarded: z.boolean().default(false),\n /** Member paused their own profile. Hidden from Discover, keeps their data. */\n isActive: z.boolean().default(true),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n});\nexport type FounderProfile = z.infer<typeof founderProfileSchema>;\n\n/**\n * What one founder sees of another in Discover and on a profile page.\n *\n * Built server-side. Keep it a strict subset of `founderProfileSchema` — if a\n * private field ever needs to show here, that is a product decision, not an\n * accident of spreading the full document.\n */\nexport const founderCardSchema = founderProfileSchema.pick({\n id: true,\n /**\n * The MEMBER's id (0.6.0): what a team invitation, a chat and every byline\n * key on. `id` is the profile's own id, which nothing takes as input.\n */\n userId: true,\n username: true,\n displayName: true,\n headline: true,\n avatarUrl: true,\n location: true,\n venture: true,\n skills: true,\n goals: true,\n contribution: true,\n});\nexport type FounderCard = z.infer<typeof founderCardSchema>;\n\n// ─── Write bodies ────────────────────────────────────────────────────────────\n\n/**\n * A text field the member is allowed to empty.\n *\n * Three states, and they are deliberately distinct:\n * absent do not touch this field\n * null clear it (the backend turns this into an `$unset`)\n * \"\" REJECTED\n *\n * The empty string is refused on purpose. A form that forgets to convert a\n * cleared input to `null` then fails loudly at the boundary, instead of being\n * silently dropped and leaving the member staring at text they just deleted.\n * `optionalTrimmedString` does the dropping, which is right for a create body\n * and wrong for a patch.\n */\nconst clearableText = (maxLength: number) =>\n z.string().trim().min(1, VALIDATION_MESSAGE.clearWithNull).max(maxLength).nullable().optional();\n\n/**\n * Patch body for the Me tab. Only the keys the member actually changed.\n *\n * ⚠️ Written as its own object ON PURPOSE. Do NOT rebuild it as\n * `founderProfileSchema.pick({...}).partial()`: `.partial()` does not switch\n * off `.default()`, so `skills`, `goals` and `links` would materialise as\n * `[]`, `[]` and `{}` on every request, including an empty one. Under a `$set`\n * that wipes a member's skills and every one of their links the moment they\n * edit their display name. `tsc` cannot see it and the request looks correct in\n * the network tab.\n *\n * The rule this comes from: defaults belong on the READ side. A write body\n * states what the caller sent and nothing else.\n */\nexport const updateFounderProfileBodySchema = z.object({\n displayName: z.string().trim().min(1).max(DISPLAY_NAME_MAX).optional(),\n headline: clearableText(HEADLINE_MAX),\n about: clearableText(ABOUT_MAX),\n /** Carries the whole location; `locationSchema` has no default to fill a gap. */\n location: locationSchema.optional(),\n venture: ventureSchema.optional(),\n skills: z.array(skillSchema).max(SKILLS_MAX).optional(),\n goals: z.array(goalSchema).max(GOAL_VALUES.length).optional(),\n /** Sent whole. To drop one link, send the object without that key. */\n links: founderLinksSchema.optional(),\n});\nexport type UpdateFounderProfileBody = z.infer<typeof updateFounderProfileBodySchema>;\n\n/**\n * Username change. Separate from the profile patch because it needs a\n * uniqueness check, and it refuses a reserved handle (`chosenUsernameSchema`).\n */\nexport const updateUsernameBodySchema = z.object({ username: chosenUsernameSchema });\nexport type UpdateUsernameBody = z.infer<typeof updateUsernameBodySchema>;\n\n/** Availability probe behind the username field. */\nexport const usernameAvailabilitySchema = z.object({\n username: usernameSchema,\n available: z.boolean(),\n /** Present when unavailable: `taken` or `reserved`. */\n reason: z.enum(['taken', 'reserved']).optional(),\n});\nexport type UsernameAvailability = z.infer<typeof usernameAvailabilitySchema>;\n\n// ─── The member's own photo ──────────────────────────────────────────────────\n\n/**\n * `PUT /api/v1/profiles/me/avatar`: use a completed upload (purpose `avatar`)\n * as the member's photo. Answers with the updated `founderProfileSchema`.\n *\n * The previous photo is deleted from storage, not merely unlinked, so its old\n * address stops working. `DELETE /api/v1/profiles/me/avatar` removes the photo\n * the same way and the member falls back to their sign-in provider's picture.\n */\nexport const setAvatarBodySchema = z.object({ mediaId: objectIdSchema });\nexport type SetAvatarBody = z.infer<typeof setAvatarBodySchema>;\n"]}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* founder-schema — Reviews: stars and words on a product
|
|
3
|
+
*
|
|
4
|
+
* One review per member per product: 1 to 5 stars AND text of at least
|
|
5
|
+
* `REVIEW_TEXT_MIN` characters, because a star with no reason does not help
|
|
6
|
+
* the founder. Nobody on a product's team reviews it. The writer may edit it
|
|
7
|
+
* any time (it then shows as edited) or delete it. The team may answer each
|
|
8
|
+
* review once, publicly; other members may find it Helpful.
|
|
9
|
+
*
|
|
10
|
+
* `testedIt` marks a review by a member the team confirmed as a tester of the
|
|
11
|
+
* product, so a reader can tell a review from use from a review from a glance.
|
|
12
|
+
*
|
|
13
|
+
* The product's average shows from `REVIEW_AVERAGE_MIN_COUNT` reviews. Hidden
|
|
14
|
+
* reviews (staff) are not counted.
|
|
15
|
+
*
|
|
16
|
+
* Routes (all signed in):
|
|
17
|
+
* GET /api/v1/products/:productId/reviews reviewsQuerySchema -> reviewPageSchema
|
|
18
|
+
* POST /api/v1/products/:productId/reviews createReviewBodySchema -> productReviewSchema
|
|
19
|
+
* GET /api/v1/reviews/:reviewId -> productReviewSchema (yours, to edit it)
|
|
20
|
+
* PATCH /api/v1/reviews/:reviewId updateReviewBodySchema -> productReviewSchema
|
|
21
|
+
* DELETE /api/v1/reviews/:reviewId -> IdResponse
|
|
22
|
+
* PUT /api/v1/reviews/:reviewId/reply reviewReplyBodySchema -> productReviewSchema
|
|
23
|
+
* DELETE /api/v1/reviews/:reviewId/reply -> productReviewSchema
|
|
24
|
+
* PUT /api/v1/reviews/:reviewId/helpful -> reviewHelpfulResponseSchema
|
|
25
|
+
* DELETE /api/v1/reviews/:reviewId/helpful -> reviewHelpfulResponseSchema
|
|
26
|
+
* POST /api/v1/reviews/:reviewId/report createReportBodySchema -> CreateReportResponse
|
|
27
|
+
*
|
|
28
|
+
* @module founder-schema/domains/reviews
|
|
29
|
+
*/
|
|
30
|
+
import { z } from 'zod';
|
|
31
|
+
/** Whole stars. */
|
|
32
|
+
export declare const reviewRatingSchema: z.ZodNumber;
|
|
33
|
+
export type ReviewRating = z.infer<typeof reviewRatingSchema>;
|
|
34
|
+
/** `new` (the default) or `helpful` first. */
|
|
35
|
+
export declare const REVIEW_SORT_VALUES: readonly ["new", "helpful"];
|
|
36
|
+
export declare const reviewSortSchema: z.ZodEnum<{
|
|
37
|
+
new: "new";
|
|
38
|
+
helpful: "helpful";
|
|
39
|
+
}>;
|
|
40
|
+
export type ReviewSort = z.infer<typeof reviewSortSchema>;
|
|
41
|
+
/** The team's public answer to a review. */
|
|
42
|
+
export declare const reviewReplySchema: z.ZodObject<{
|
|
43
|
+
text: z.ZodString;
|
|
44
|
+
author: z.ZodNullable<z.ZodObject<{
|
|
45
|
+
userId: z.ZodString;
|
|
46
|
+
username: z.ZodString;
|
|
47
|
+
displayName: z.ZodString;
|
|
48
|
+
avatarUrl: z.ZodOptional<z.ZodURL>;
|
|
49
|
+
headline: z.ZodOptional<z.ZodString>;
|
|
50
|
+
}, z.core.$strip>>;
|
|
51
|
+
createdAt: z.ZodISODateTime;
|
|
52
|
+
editedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
53
|
+
}, z.core.$strip>;
|
|
54
|
+
export type ReviewReply = z.infer<typeof reviewReplySchema>;
|
|
55
|
+
/** What this viewer may do with a review, decided by the server. */
|
|
56
|
+
export declare const reviewViewerSchema: z.ZodObject<{
|
|
57
|
+
isAuthor: z.ZodBoolean;
|
|
58
|
+
votedHelpful: z.ZodBoolean;
|
|
59
|
+
canEdit: z.ZodBoolean;
|
|
60
|
+
canDelete: z.ZodBoolean;
|
|
61
|
+
canReply: z.ZodBoolean;
|
|
62
|
+
canVoteHelpful: z.ZodBoolean;
|
|
63
|
+
canReport: z.ZodBoolean;
|
|
64
|
+
}, z.core.$strip>;
|
|
65
|
+
export type ReviewViewer = z.infer<typeof reviewViewerSchema>;
|
|
66
|
+
export declare const productReviewSchema: z.ZodObject<{
|
|
67
|
+
id: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
68
|
+
productId: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
69
|
+
author: z.ZodObject<{
|
|
70
|
+
userId: z.ZodString;
|
|
71
|
+
username: z.ZodString;
|
|
72
|
+
displayName: z.ZodString;
|
|
73
|
+
avatarUrl: z.ZodOptional<z.ZodURL>;
|
|
74
|
+
headline: z.ZodOptional<z.ZodString>;
|
|
75
|
+
}, z.core.$strip>;
|
|
76
|
+
rating: z.ZodNumber;
|
|
77
|
+
text: z.ZodString;
|
|
78
|
+
testedIt: z.ZodBoolean;
|
|
79
|
+
helpfulCount: z.ZodNumber;
|
|
80
|
+
reply: z.ZodNullable<z.ZodObject<{
|
|
81
|
+
text: z.ZodString;
|
|
82
|
+
author: z.ZodNullable<z.ZodObject<{
|
|
83
|
+
userId: z.ZodString;
|
|
84
|
+
username: z.ZodString;
|
|
85
|
+
displayName: z.ZodString;
|
|
86
|
+
avatarUrl: z.ZodOptional<z.ZodURL>;
|
|
87
|
+
headline: z.ZodOptional<z.ZodString>;
|
|
88
|
+
}, z.core.$strip>>;
|
|
89
|
+
createdAt: z.ZodISODateTime;
|
|
90
|
+
editedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
91
|
+
}, z.core.$strip>>;
|
|
92
|
+
createdAt: z.ZodISODateTime;
|
|
93
|
+
editedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
94
|
+
viewer: z.ZodOptional<z.ZodObject<{
|
|
95
|
+
isAuthor: z.ZodBoolean;
|
|
96
|
+
votedHelpful: z.ZodBoolean;
|
|
97
|
+
canEdit: z.ZodBoolean;
|
|
98
|
+
canDelete: z.ZodBoolean;
|
|
99
|
+
canReply: z.ZodBoolean;
|
|
100
|
+
canVoteHelpful: z.ZodBoolean;
|
|
101
|
+
canReport: z.ZodBoolean;
|
|
102
|
+
}, z.core.$strip>>;
|
|
103
|
+
}, z.core.$strip>;
|
|
104
|
+
export type ProductReview = z.infer<typeof productReviewSchema>;
|
|
105
|
+
export declare const reviewPageSchema: z.ZodObject<{
|
|
106
|
+
items: z.ZodArray<z.ZodObject<{
|
|
107
|
+
id: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
108
|
+
productId: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
109
|
+
author: z.ZodObject<{
|
|
110
|
+
userId: z.ZodString;
|
|
111
|
+
username: z.ZodString;
|
|
112
|
+
displayName: z.ZodString;
|
|
113
|
+
avatarUrl: z.ZodOptional<z.ZodURL>;
|
|
114
|
+
headline: z.ZodOptional<z.ZodString>;
|
|
115
|
+
}, z.core.$strip>;
|
|
116
|
+
rating: z.ZodNumber;
|
|
117
|
+
text: z.ZodString;
|
|
118
|
+
testedIt: z.ZodBoolean;
|
|
119
|
+
helpfulCount: z.ZodNumber;
|
|
120
|
+
reply: z.ZodNullable<z.ZodObject<{
|
|
121
|
+
text: z.ZodString;
|
|
122
|
+
author: z.ZodNullable<z.ZodObject<{
|
|
123
|
+
userId: z.ZodString;
|
|
124
|
+
username: z.ZodString;
|
|
125
|
+
displayName: z.ZodString;
|
|
126
|
+
avatarUrl: z.ZodOptional<z.ZodURL>;
|
|
127
|
+
headline: z.ZodOptional<z.ZodString>;
|
|
128
|
+
}, z.core.$strip>>;
|
|
129
|
+
createdAt: z.ZodISODateTime;
|
|
130
|
+
editedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
131
|
+
}, z.core.$strip>>;
|
|
132
|
+
createdAt: z.ZodISODateTime;
|
|
133
|
+
editedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
134
|
+
viewer: z.ZodOptional<z.ZodObject<{
|
|
135
|
+
isAuthor: z.ZodBoolean;
|
|
136
|
+
votedHelpful: z.ZodBoolean;
|
|
137
|
+
canEdit: z.ZodBoolean;
|
|
138
|
+
canDelete: z.ZodBoolean;
|
|
139
|
+
canReply: z.ZodBoolean;
|
|
140
|
+
canVoteHelpful: z.ZodBoolean;
|
|
141
|
+
canReport: z.ZodBoolean;
|
|
142
|
+
}, z.core.$strip>>;
|
|
143
|
+
}, z.core.$strip>>;
|
|
144
|
+
nextCursor: z.ZodNullable<z.ZodString>;
|
|
145
|
+
}, z.core.$strip>;
|
|
146
|
+
export type ReviewPage = z.infer<typeof reviewPageSchema>;
|
|
147
|
+
export declare const reviewsQuerySchema: z.ZodObject<{
|
|
148
|
+
limit: z.ZodPreprocess<z.ZodDefault<z.ZodCoercedNumber<unknown>>, unknown>;
|
|
149
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
150
|
+
sort: z.ZodPreprocess<z.ZodDefault<z.ZodEnum<{
|
|
151
|
+
new: "new";
|
|
152
|
+
helpful: "helpful";
|
|
153
|
+
}>>, unknown>;
|
|
154
|
+
}, z.core.$strip>;
|
|
155
|
+
export type ReviewsQuery = z.infer<typeof reviewsQuerySchema>;
|
|
156
|
+
export type ReviewsQueryInput = z.input<typeof reviewsQuerySchema>;
|
|
157
|
+
export declare const reviewParamsSchema: z.ZodObject<{
|
|
158
|
+
reviewId: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
159
|
+
}, z.core.$strip>;
|
|
160
|
+
export type ReviewParams = z.infer<typeof reviewParamsSchema>;
|
|
161
|
+
export declare const createReviewBodySchema: z.ZodObject<{
|
|
162
|
+
rating: z.ZodNumber;
|
|
163
|
+
text: z.ZodString;
|
|
164
|
+
}, z.core.$strip>;
|
|
165
|
+
export type CreateReviewBody = z.infer<typeof createReviewBodySchema>;
|
|
166
|
+
/** Only what changed. An empty body changes nothing and answers the review as it is. */
|
|
167
|
+
export declare const updateReviewBodySchema: z.ZodObject<{
|
|
168
|
+
rating: z.ZodOptional<z.ZodNumber>;
|
|
169
|
+
text: z.ZodOptional<z.ZodString>;
|
|
170
|
+
}, z.core.$strip>;
|
|
171
|
+
export type UpdateReviewBody = z.infer<typeof updateReviewBodySchema>;
|
|
172
|
+
/** The team's reply: written once, then edited in place by sending it again. */
|
|
173
|
+
export declare const reviewReplyBodySchema: z.ZodObject<{
|
|
174
|
+
text: z.ZodString;
|
|
175
|
+
}, z.core.$strip>;
|
|
176
|
+
export type ReviewReplyBody = z.infer<typeof reviewReplyBodySchema>;
|
|
177
|
+
/** `PUT|DELETE /reviews/:id/helpful`: the state it settled on and the fresh count. */
|
|
178
|
+
export declare const reviewHelpfulResponseSchema: z.ZodObject<{
|
|
179
|
+
reviewId: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
180
|
+
votedHelpful: z.ZodBoolean;
|
|
181
|
+
helpfulCount: z.ZodNumber;
|
|
182
|
+
}, z.core.$strip>;
|
|
183
|
+
export type ReviewHelpfulResponse = z.infer<typeof reviewHelpfulResponseSchema>;
|
|
184
|
+
//# sourceMappingURL=reviews.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviews.d.ts","sourceRoot":"","sources":["../../../src/domains/reviews/reviews.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,mBAAmB;AACnB,eAAO,MAAM,kBAAkB,aAAiC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,8CAA8C;AAC9C,eAAO,MAAM,kBAAkB,6BAA8B,CAAC;AAC9D,eAAO,MAAM,gBAAgB;;;EAA6B,CAAC;AAC3D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB;;;;;;;;;;;iBAM5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,oEAAoE;AACpE,eAAO,MAAM,kBAAkB;;;;;;;;iBAU7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAa9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAuC,CAAC;AACrE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,kBAAkB;;;;;;;iBAE7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEnE,eAAO,MAAM,kBAAkB;;iBAAyC,CAAC;AACzE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,eAAO,MAAM,sBAAsB;;;iBAGjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,wFAAwF;AACxF,eAAO,MAAM,sBAAsB;;;iBAGjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,gFAAgF;AAChF,eAAO,MAAM,qBAAqB;;iBAEhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,sFAAsF;AACtF,eAAO,MAAM,2BAA2B;;;;iBAItC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* founder-schema — Reviews: stars and words on a product
|
|
3
|
+
*
|
|
4
|
+
* One review per member per product: 1 to 5 stars AND text of at least
|
|
5
|
+
* `REVIEW_TEXT_MIN` characters, because a star with no reason does not help
|
|
6
|
+
* the founder. Nobody on a product's team reviews it. The writer may edit it
|
|
7
|
+
* any time (it then shows as edited) or delete it. The team may answer each
|
|
8
|
+
* review once, publicly; other members may find it Helpful.
|
|
9
|
+
*
|
|
10
|
+
* `testedIt` marks a review by a member the team confirmed as a tester of the
|
|
11
|
+
* product, so a reader can tell a review from use from a review from a glance.
|
|
12
|
+
*
|
|
13
|
+
* The product's average shows from `REVIEW_AVERAGE_MIN_COUNT` reviews. Hidden
|
|
14
|
+
* reviews (staff) are not counted.
|
|
15
|
+
*
|
|
16
|
+
* Routes (all signed in):
|
|
17
|
+
* GET /api/v1/products/:productId/reviews reviewsQuerySchema -> reviewPageSchema
|
|
18
|
+
* POST /api/v1/products/:productId/reviews createReviewBodySchema -> productReviewSchema
|
|
19
|
+
* GET /api/v1/reviews/:reviewId -> productReviewSchema (yours, to edit it)
|
|
20
|
+
* PATCH /api/v1/reviews/:reviewId updateReviewBodySchema -> productReviewSchema
|
|
21
|
+
* DELETE /api/v1/reviews/:reviewId -> IdResponse
|
|
22
|
+
* PUT /api/v1/reviews/:reviewId/reply reviewReplyBodySchema -> productReviewSchema
|
|
23
|
+
* DELETE /api/v1/reviews/:reviewId/reply -> productReviewSchema
|
|
24
|
+
* PUT /api/v1/reviews/:reviewId/helpful -> reviewHelpfulResponseSchema
|
|
25
|
+
* DELETE /api/v1/reviews/:reviewId/helpful -> reviewHelpfulResponseSchema
|
|
26
|
+
* POST /api/v1/reviews/:reviewId/report createReportBodySchema -> CreateReportResponse
|
|
27
|
+
*
|
|
28
|
+
* @module founder-schema/domains/reviews
|
|
29
|
+
*/
|
|
30
|
+
import { z } from 'zod';
|
|
31
|
+
import { emptyStringToUndefined, objectIdSchema, paginationQuerySchema, } from '../../core/common.js';
|
|
32
|
+
import { REVIEW_REPLY_MAX, REVIEW_TEXT_MAX, REVIEW_TEXT_MIN } from '../../core/limits.js';
|
|
33
|
+
import { paginatedSchema } from '../../core/responses.js';
|
|
34
|
+
import { memberBylineSchema } from '../profile/founder-profile.js';
|
|
35
|
+
/** Whole stars. */
|
|
36
|
+
export const reviewRatingSchema = z.number().int().min(1).max(5);
|
|
37
|
+
/** `new` (the default) or `helpful` first. */
|
|
38
|
+
export const REVIEW_SORT_VALUES = ['new', 'helpful'];
|
|
39
|
+
export const reviewSortSchema = z.enum(REVIEW_SORT_VALUES);
|
|
40
|
+
/** The team's public answer to a review. */
|
|
41
|
+
export const reviewReplySchema = z.object({
|
|
42
|
+
text: z.string().max(REVIEW_REPLY_MAX),
|
|
43
|
+
/** Who on the team wrote it; null when they have since deleted their account. */
|
|
44
|
+
author: memberBylineSchema.nullable(),
|
|
45
|
+
createdAt: z.iso.datetime(),
|
|
46
|
+
editedAt: z.iso.datetime().nullable(),
|
|
47
|
+
});
|
|
48
|
+
/** What this viewer may do with a review, decided by the server. */
|
|
49
|
+
export const reviewViewerSchema = z.object({
|
|
50
|
+
isAuthor: z.boolean(),
|
|
51
|
+
votedHelpful: z.boolean(),
|
|
52
|
+
canEdit: z.boolean(),
|
|
53
|
+
canDelete: z.boolean(),
|
|
54
|
+
/** On the product's team: write, edit or remove the team's reply. */
|
|
55
|
+
canReply: z.boolean(),
|
|
56
|
+
/** Not the writer. */
|
|
57
|
+
canVoteHelpful: z.boolean(),
|
|
58
|
+
canReport: z.boolean(),
|
|
59
|
+
});
|
|
60
|
+
export const productReviewSchema = z.object({
|
|
61
|
+
id: objectIdSchema,
|
|
62
|
+
productId: objectIdSchema,
|
|
63
|
+
author: memberBylineSchema,
|
|
64
|
+
rating: reviewRatingSchema,
|
|
65
|
+
text: z.string().max(REVIEW_TEXT_MAX),
|
|
66
|
+
/** The team confirmed the writer as a tester of this product. */
|
|
67
|
+
testedIt: z.boolean(),
|
|
68
|
+
helpfulCount: z.number().int().nonnegative(),
|
|
69
|
+
reply: reviewReplySchema.nullable(),
|
|
70
|
+
createdAt: z.iso.datetime(),
|
|
71
|
+
editedAt: z.iso.datetime().nullable(),
|
|
72
|
+
viewer: reviewViewerSchema.optional(),
|
|
73
|
+
});
|
|
74
|
+
export const reviewPageSchema = paginatedSchema(productReviewSchema);
|
|
75
|
+
export const reviewsQuerySchema = paginationQuerySchema.extend({
|
|
76
|
+
sort: z.preprocess(emptyStringToUndefined, reviewSortSchema.default('new')),
|
|
77
|
+
});
|
|
78
|
+
export const reviewParamsSchema = z.object({ reviewId: objectIdSchema });
|
|
79
|
+
const reviewTextSchema = z.string().trim().min(REVIEW_TEXT_MIN).max(REVIEW_TEXT_MAX);
|
|
80
|
+
export const createReviewBodySchema = z.object({
|
|
81
|
+
rating: reviewRatingSchema,
|
|
82
|
+
text: reviewTextSchema,
|
|
83
|
+
});
|
|
84
|
+
/** Only what changed. An empty body changes nothing and answers the review as it is. */
|
|
85
|
+
export const updateReviewBodySchema = z.object({
|
|
86
|
+
rating: reviewRatingSchema.optional(),
|
|
87
|
+
text: reviewTextSchema.optional(),
|
|
88
|
+
});
|
|
89
|
+
/** The team's reply: written once, then edited in place by sending it again. */
|
|
90
|
+
export const reviewReplyBodySchema = z.object({
|
|
91
|
+
text: z.string().trim().min(1).max(REVIEW_REPLY_MAX),
|
|
92
|
+
});
|
|
93
|
+
/** `PUT|DELETE /reviews/:id/helpful`: the state it settled on and the fresh count. */
|
|
94
|
+
export const reviewHelpfulResponseSchema = z.object({
|
|
95
|
+
reviewId: objectIdSchema,
|
|
96
|
+
votedHelpful: z.boolean(),
|
|
97
|
+
helpfulCount: z.number().int().nonnegative(),
|
|
98
|
+
});
|
|
99
|
+
//# sourceMappingURL=reviews.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviews.js","sourceRoot":"","sources":["../../../src/domains/reviews/reviews.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * founder-schema — Reviews: stars and words on a product\n *\n * One review per member per product: 1 to 5 stars AND text of at least\n * `REVIEW_TEXT_MIN` characters, because a star with no reason does not help\n * the founder. Nobody on a product's team reviews it. The writer may edit it\n * any time (it then shows as edited) or delete it. The team may answer each\n * review once, publicly; other members may find it Helpful.\n *\n * `testedIt` marks a review by a member the team confirmed as a tester of the\n * product, so a reader can tell a review from use from a review from a glance.\n *\n * The product's average shows from `REVIEW_AVERAGE_MIN_COUNT` reviews. Hidden\n * reviews (staff) are not counted.\n *\n * Routes (all signed in):\n * GET /api/v1/products/:productId/reviews reviewsQuerySchema -> reviewPageSchema\n * POST /api/v1/products/:productId/reviews createReviewBodySchema -> productReviewSchema\n * GET /api/v1/reviews/:reviewId -> productReviewSchema (yours, to edit it)\n * PATCH /api/v1/reviews/:reviewId updateReviewBodySchema -> productReviewSchema\n * DELETE /api/v1/reviews/:reviewId -> IdResponse\n * PUT /api/v1/reviews/:reviewId/reply reviewReplyBodySchema -> productReviewSchema\n * DELETE /api/v1/reviews/:reviewId/reply -> productReviewSchema\n * PUT /api/v1/reviews/:reviewId/helpful -> reviewHelpfulResponseSchema\n * DELETE /api/v1/reviews/:reviewId/helpful -> reviewHelpfulResponseSchema\n * POST /api/v1/reviews/:reviewId/report createReportBodySchema -> CreateReportResponse\n *\n * @module founder-schema/domains/reviews\n */\n\nimport { z } from 'zod';\nimport {\n emptyStringToUndefined,\n objectIdSchema,\n paginationQuerySchema,\n} from '../../core/common.js';\nimport { REVIEW_REPLY_MAX, REVIEW_TEXT_MAX, REVIEW_TEXT_MIN } from '../../core/limits.js';\nimport { paginatedSchema } from '../../core/responses.js';\nimport { memberBylineSchema } from '../profile/founder-profile.js';\n\n/** Whole stars. */\nexport const reviewRatingSchema = z.number().int().min(1).max(5);\nexport type ReviewRating = z.infer<typeof reviewRatingSchema>;\n\n/** `new` (the default) or `helpful` first. */\nexport const REVIEW_SORT_VALUES = ['new', 'helpful'] as const;\nexport const reviewSortSchema = z.enum(REVIEW_SORT_VALUES);\nexport type ReviewSort = z.infer<typeof reviewSortSchema>;\n\n/** The team's public answer to a review. */\nexport const reviewReplySchema = z.object({\n text: z.string().max(REVIEW_REPLY_MAX),\n /** Who on the team wrote it; null when they have since deleted their account. */\n author: memberBylineSchema.nullable(),\n createdAt: z.iso.datetime(),\n editedAt: z.iso.datetime().nullable(),\n});\nexport type ReviewReply = z.infer<typeof reviewReplySchema>;\n\n/** What this viewer may do with a review, decided by the server. */\nexport const reviewViewerSchema = z.object({\n isAuthor: z.boolean(),\n votedHelpful: z.boolean(),\n canEdit: z.boolean(),\n canDelete: z.boolean(),\n /** On the product's team: write, edit or remove the team's reply. */\n canReply: z.boolean(),\n /** Not the writer. */\n canVoteHelpful: z.boolean(),\n canReport: z.boolean(),\n});\nexport type ReviewViewer = z.infer<typeof reviewViewerSchema>;\n\nexport const productReviewSchema = z.object({\n id: objectIdSchema,\n productId: objectIdSchema,\n author: memberBylineSchema,\n rating: reviewRatingSchema,\n text: z.string().max(REVIEW_TEXT_MAX),\n /** The team confirmed the writer as a tester of this product. */\n testedIt: z.boolean(),\n helpfulCount: z.number().int().nonnegative(),\n reply: reviewReplySchema.nullable(),\n createdAt: z.iso.datetime(),\n editedAt: z.iso.datetime().nullable(),\n viewer: reviewViewerSchema.optional(),\n});\nexport type ProductReview = z.infer<typeof productReviewSchema>;\n\nexport const reviewPageSchema = paginatedSchema(productReviewSchema);\nexport type ReviewPage = z.infer<typeof reviewPageSchema>;\n\nexport const reviewsQuerySchema = paginationQuerySchema.extend({\n sort: z.preprocess(emptyStringToUndefined, reviewSortSchema.default('new')),\n});\nexport type ReviewsQuery = z.infer<typeof reviewsQuerySchema>;\nexport type ReviewsQueryInput = z.input<typeof reviewsQuerySchema>;\n\nexport const reviewParamsSchema = z.object({ reviewId: objectIdSchema });\nexport type ReviewParams = z.infer<typeof reviewParamsSchema>;\n\nconst reviewTextSchema = z.string().trim().min(REVIEW_TEXT_MIN).max(REVIEW_TEXT_MAX);\n\nexport const createReviewBodySchema = z.object({\n rating: reviewRatingSchema,\n text: reviewTextSchema,\n});\nexport type CreateReviewBody = z.infer<typeof createReviewBodySchema>;\n\n/** Only what changed. An empty body changes nothing and answers the review as it is. */\nexport const updateReviewBodySchema = z.object({\n rating: reviewRatingSchema.optional(),\n text: reviewTextSchema.optional(),\n});\nexport type UpdateReviewBody = z.infer<typeof updateReviewBodySchema>;\n\n/** The team's reply: written once, then edited in place by sending it again. */\nexport const reviewReplyBodySchema = z.object({\n text: z.string().trim().min(1).max(REVIEW_REPLY_MAX),\n});\nexport type ReviewReplyBody = z.infer<typeof reviewReplyBodySchema>;\n\n/** `PUT|DELETE /reviews/:id/helpful`: the state it settled on and the fresh count. */\nexport const reviewHelpfulResponseSchema = z.object({\n reviewId: objectIdSchema,\n votedHelpful: z.boolean(),\n helpfulCount: z.number().int().nonnegative(),\n});\nexport type ReviewHelpfulResponse = z.infer<typeof reviewHelpfulResponseSchema>;\n"]}
|
|
@@ -63,6 +63,8 @@ export declare const uploadPresignBodySchema: z.ZodObject<{
|
|
|
63
63
|
purpose: z.ZodEnum<{
|
|
64
64
|
post: "post";
|
|
65
65
|
avatar: "avatar";
|
|
66
|
+
product_logo: "product_logo";
|
|
67
|
+
product_screenshot: "product_screenshot";
|
|
66
68
|
}>;
|
|
67
69
|
contentType: z.ZodEnum<{
|
|
68
70
|
"image/jpeg": "image/jpeg";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploads.d.ts","sourceRoot":"","sources":["../../../src/domains/uploads/uploads.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,gDAAiD,CAAC;AACpF,eAAO,MAAM,wBAAwB;;;;;;EAAgC,CAAC;AACtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,oBAAoB;;;;;;CAMiC,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,mGAAmG;AACnG,eAAO,MAAM,kBAAkB,QAE9B,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,eAAe,aAMuD,CAAC;AACpF,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB
|
|
1
|
+
{"version":3,"file":"uploads.d.ts","sourceRoot":"","sources":["../../../src/domains/uploads/uploads.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,gDAAiD,CAAC;AACpF,eAAO,MAAM,wBAAwB;;;;;;EAAgC,CAAC;AACtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,oBAAoB;;;;;;CAMiC,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,mGAAmG;AACnG,eAAO,MAAM,kBAAkB,QAE9B,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,eAAe,aAMuD,CAAC;AACpF,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;iBAIlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,2BAA2B;;;;;;iBAMtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,iFAAiF;AACjF,eAAO,MAAM,kBAAkB;;iBAAwC,CAAC;AACxE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,22 +11,26 @@
|
|
|
11
11
|
export { type ChangeMpinBody, changeMpinBodySchema, type MeAccessResponse, MPIN_LENGTH, MPIN_LOCK_MS, MPIN_MAX_ATTEMPTS, meAccessResponseSchema, mpinSchema, type SetMpinBody, type SwitchRoleBody, setMpinBodySchema, switchRoleBodySchema, } from './access/access.js';
|
|
12
12
|
export { ACTION_VALUES, type Action, type AppAbility, actionSchema, type PackedRules, packedRulesSchema, SUBJECT_VALUES, type Subject, type SubjectFields, type SubjectInstance, subjectSchema, } from './access/permissions.js';
|
|
13
13
|
export { ACTIVE_ROLE_TTL_MS, canGrantRole, isPlatformRole, MEMBER_ROLE, PLATFORM_ROLE_VALUES, type PlatformRole, platformRoleSchema, ROLE_GRANTED_BY, ROLE_VALUES, type Role, roleSchema, } from './access/roles.js';
|
|
14
|
-
export { type CoordinatesQuery, type CoordinatesQueryInput, chosenUsernameSchema, coordinatesQuerySchema, emptyStringToUndefined, type FounderLocation, GENDER_VALUES, type Gender, GOAL_VALUES, type Goal, genderSchema, goalSchema, type HttpUrl, httpUrlSchema, INDUSTRY_VALUES, type Industry, industrySchema, isReservedUsername, locationSchema, type ObjectIdString, objectIdSchema, optionalTrimmedString, type PaginationQuery, type PaginationQueryInput, type Phone, paginationQuerySchema, phoneSchema, RESERVED_USERNAMES, type SafeUrl, SKILL_VALUES, type Skill, STARTUP_STAGE_VALUES, type StartupStage, type SuggestedLocation, safeUrlSchema, skillSchema, startupStageSchema, suggestedLocationSchema, USERNAME_MAX, USERNAME_MIN, type Username, usernameSchema, } from './core/common.js';
|
|
14
|
+
export { type CoordinatesQuery, type CoordinatesQueryInput, chosenUsernameSchema, coordinatesQuerySchema, emptyStringToUndefined, type FounderLocation, GENDER_VALUES, type Gender, GOAL_VALUES, type Goal, genderSchema, goalSchema, type HttpUrl, httpUrlOnHosts, httpUrlSchema, INDUSTRY_VALUES, type Industry, industrySchema, isReservedUsername, isUrlOnHost, locationSchema, multiValueQuery, type ObjectIdString, objectIdSchema, optionalTrimmedString, type PaginationQuery, type PaginationQueryInput, type Phone, paginationQuerySchema, phoneSchema, RESERVED_USERNAMES, type SafeUrl, SKILL_VALUES, type Skill, STARTUP_STAGE_VALUES, type StartupStage, type SuggestedLocation, safeUrlSchema, skillSchema, startupStageSchema, suggestedLocationSchema, USERNAME_MAX, USERNAME_MIN, type Username, usernameSchema, YOUTUBE_HOSTS, youtubeVideoId, } from './core/common.js';
|
|
15
15
|
export { API_ERROR_CODE, API_ERROR_CODE_VALUES, type ApiErrorCode, apiErrorCodeSchema, } from './core/errors.js';
|
|
16
|
-
export { ABOUT_MAX, CHAT_PARTICIPANTS_MAX, CITY_MAX, COUNTRY_MAX, DISCOVER_FILTER_VALUES_MAX, DISCOVER_TEXT_MAX, DISPLAY_NAME_MAX, FOUNDED_YEAR_MIN, GOALS_MIN, HEADLINE_MAX, LINK_PREVIEW_DESCRIPTION_MAX, LINK_PREVIEW_TITLE_MAX, LINK_URL_MAX, MEDIA_ALT_MAX, MEDIA_MAX_INPUT_PIXELS, MEDIA_PENDING_MAX, MEDIA_PLACEHOLDER_MAX, MEDIA_UNATTACHED_TTL_HOURS, MEMBER_SEARCH_MAX, MODERATION_EXCERPT_MAX, MODERATION_NOTE_MAX, PAGE_SIZE_DEFAULT, PAGE_SIZE_MAX, REPORT_NOTE_MAX, SAVED_REPLIES_MAX, SAVED_REPLY_BODY_MAX, SAVED_REPLY_TITLE_MAX, SKILLS_MAX, STATE_MAX, SUSPENSION_REASON_MAX, SUSPENSION_REASON_MIN, TEAM_SIZE_MAX, TEAM_SIZE_MIN, TICKET_MESSAGE_MAX, TICKET_MESSAGES_MAX, TICKET_SUBJECT_MAX, TICKET_SUBJECT_MIN, UPLOAD_MAX_BYTES, VENTURE_NAME_MAX, VENTURE_TAGLINE_MAX, } from './core/limits.js';
|
|
16
|
+
export { ABOUT_MAX, CHAT_PARTICIPANTS_MAX, CITY_MAX, CONTRIBUTION_LEADERBOARD_SIZE, CONTRIBUTION_PAIR_POINTS_MAX, CONTRIBUTION_RECENT_DAYS, COUNTRY_MAX, DISCOVER_FILTER_VALUES_MAX, DISCOVER_TEXT_MAX, DISPLAY_NAME_MAX, FOUNDED_YEAR_MIN, GOALS_MIN, HEADLINE_MAX, LINK_PREVIEW_DESCRIPTION_MAX, LINK_PREVIEW_TITLE_MAX, LINK_URL_MAX, MEDIA_ALT_MAX, MEDIA_MAX_INPUT_PIXELS, MEDIA_PENDING_MAX, MEDIA_PLACEHOLDER_MAX, MEDIA_UNATTACHED_TTL_HOURS, MEMBER_SEARCH_MAX, MODERATION_EXCERPT_MAX, MODERATION_NOTE_MAX, NOTIFICATION_EXCERPT_MAX, NOTIFICATION_RETENTION_DAYS, PAGE_SIZE_DEFAULT, PAGE_SIZE_MAX, PRODUCT_ASK_OPEN_DAYS, PRODUCT_CAPTION_MAX, PRODUCT_DESCRIPTION_MAX, PRODUCT_NAME_MAX, PRODUCT_SCREENSHOTS_MAX, PRODUCT_TAGLINE_MAX, PRODUCT_TEAM_SHOWN, PRODUCTS_OWNED_MAX, REPORT_NOTE_MAX, REVIEW_AVERAGE_MIN_COUNT, REVIEW_HELPFUL_POINTS_MAX, REVIEW_REPLY_MAX, REVIEW_TEXT_MAX, REVIEW_TEXT_MIN, REVIEWS_REWARDED_PER_DAY, SAVED_REPLIES_MAX, SAVED_REPLY_BODY_MAX, SAVED_REPLY_TITLE_MAX, SKILLS_MAX, STATE_MAX, SUSPENSION_REASON_MAX, SUSPENSION_REASON_MIN, TEAM_SIZE_MAX, TEAM_SIZE_MIN, TICKET_MESSAGE_MAX, TICKET_MESSAGES_MAX, TICKET_SUBJECT_MAX, TICKET_SUBJECT_MIN, UPLOAD_MAX_BYTES, VENTURE_NAME_MAX, VENTURE_TAGLINE_MAX, } from './core/limits.js';
|
|
17
17
|
export { type ApiError, type ApiErrorDetails, apiErrorDetailsSchema, apiErrorSchema, type ErrorResponse, errorResponseSchema, type IdResponse, idResponseSchema, paginatedSchema, successResponseSchema, } from './core/responses.js';
|
|
18
18
|
export { REQUEST_PART_VALUES, type RequestPart, requestPartSchema, toValidationIssues, VALIDATION_MESSAGE, type ValidationIssue, type ValidationMessageKey, validationIssueSchema, } from './core/validation.js';
|
|
19
19
|
export { type DeleteAccountResponse, deleteAccountResponseSchema, } from './domains/account/account.js';
|
|
20
20
|
export { AUDIT_ACTION_VALUES, type AuditAction, type AuditActor, type AuditEntry, type AuditPage, auditActionSchema, auditActorSchema, auditEntrySchema, auditPageSchema, } from './domains/audit/audit.js';
|
|
21
21
|
export { CHAT_PRODUCT_ID, CHAT_SOCKET_REAUTH_SECONDS, CHAT_TOKEN_REFRESH_MARGIN_SECONDS, type ChatAuthToken, type ChatConfig, type ChatInvitation, type ChatInvitationBody, type ChatParticipant, type ChatParticipantsBody, type ChatParticipantsResponse, type ChatProductId, chatAuthTokenSchema, chatConfigSchema, chatInvitationBodySchema, chatInvitationSchema, chatParticipantSchema, chatParticipantsBodySchema, chatParticipantsResponseSchema, chatProductIdSchema, type OpenChatBody, type OpenChatResponse, openChatBodySchema, openChatResponseSchema, } from './domains/chat/chat.js';
|
|
22
|
+
export { CONTRIBUTION_AWARDED_KIND_VALUES, CONTRIBUTION_KIND_VALUES, CONTRIBUTION_POINTS, type ContributionEntry, type ContributionKind, type ContributionLeaderboard, type ContributionLeaderEntry, type ContributionPage, contributionEntrySchema, contributionKindSchema, contributionLeaderboardSchema, contributionLeaderEntrySchema, contributionPageSchema, } from './domains/contributions/contributions.js';
|
|
22
23
|
export { type Dashboard, dashboardSchema } from './domains/dashboard/dashboard.js';
|
|
23
24
|
export { type DiscoverFacets, type DiscoverPage, type DiscoverQuery, type DiscoverQueryInput, discoverFacetsSchema, discoverPageSchema, discoverQuerySchema, } from './domains/discover/discover.js';
|
|
24
|
-
export { type AttachedMedia, type AuthorParams, attachedMediaSchema, authorParamsSchema, type CastVoteBody, type CastVoteResponse, COMMENT_MAX_BODY_CHARS, CONTENT_KIND_VALUES, type CommentPage, type CommentParams, type CommentsQuery, type CommentsQueryInput, type ContentKind, type ContentParams, type ContentTargetParams, type CreateCommentBody, type CreatePollBody, type CreatePostBody, type CreateReportBody, type CreateReportResponse, castVoteBodySchema, castVoteResponseSchema, commentPageSchema, commentParamsSchema, commentsQuerySchema, contentKindSchema, contentParamsSchema, contentTargetParamsSchema, createCommentBodySchema, createPollBodySchema, createPostBodySchema, createReportBodySchema, createReportResponseSchema, EDIT_WINDOW_MS, ENGAGEMENT_TARGET_KIND_VALUES, type EngagementTargetKind, type EngagementTargetParams, engagementTargetKindSchema, engagementTargetParamsSchema, FEED_SORT_VALUES, type FeedAuthor, type FeedComment, type FeedImage, type FeedItem, type FeedItemParams, type FeedMedia, type FeedPage, type FeedPoll, type FeedPost, type FeedQuery, type FeedQueryInput, type FeedSort, type FeedVideo, feedAuthorSchema, feedCommentSchema, feedImageSchema, feedItemParamsSchema, feedItemSchema, feedMediaSchema, feedPageSchema, feedPollSchema, feedPostSchema, feedQuerySchema, feedSortSchema, feedVideoSchema, type LinkPreview, linkPreviewSchema, MAX_TOPICS, POLL_MAX_DURATION_MS, POLL_MAX_OPTIONS, POLL_MIN_DURATION_MS, POLL_MIN_OPTIONS, POLL_OPTION_MAX_CHARS, POLL_QUESTION_MAX_CHARS, POST_MAX_BODY_CHARS, POST_MAX_MEDIA, type PollOption, type PollParams, pollOptionSchema, pollParamsSchema, REACTION_TYPE_VALUES, REPORT_REASON_VALUES, type ReactionCounts, type ReactionType, type ReportReason, reactionCountsSchema, reactionTypeSchema, reportReasonSchema, type SetReactionBody, type SetReactionResponse, setReactionBodySchema, setReactionResponseSchema, type ToggleBookmarkResponse, toggleBookmarkResponseSchema, type UpdateCommentBody, type UpdatePostBody, updateCommentBodySchema, updatePostBodySchema, type ViewerState, viewerStateSchema, } from './domains/feed/feed.js';
|
|
25
|
-
export { MEDIA_PURPOSE_VALUES, MEDIA_SIZES, MEDIA_UPLOAD_CONTENT_TYPES, type MediaImage, type MediaPurpose, type MediaUploadContentType, type MediaVariant, mediaImageSchema, mediaPurposeSchema, mediaUploadContentTypeSchema, mediaVariantSchema, type UploadedMedia, uploadedMediaSchema, } from './domains/media/media.js';
|
|
25
|
+
export { type AttachedMedia, type AuthorParams, attachedMediaSchema, authorParamsSchema, type CastVoteBody, type CastVoteResponse, COMMENT_MAX_BODY_CHARS, CONTENT_KIND_VALUES, type CommentHelpfulResponse, type CommentPage, type CommentParams, type CommentsQuery, type CommentsQueryInput, type ContentKind, type ContentParams, type ContentTargetParams, type CreateCommentBody, type CreatePollBody, type CreatePostBody, type CreateReportBody, type CreateReportResponse, castVoteBodySchema, castVoteResponseSchema, commentHelpfulResponseSchema, commentPageSchema, commentParamsSchema, commentsQuerySchema, contentKindSchema, contentParamsSchema, contentTargetParamsSchema, createCommentBodySchema, createPollBodySchema, createPostBodySchema, createReportBodySchema, createReportResponseSchema, EDIT_WINDOW_MS, ENGAGEMENT_TARGET_KIND_VALUES, type EngagementTargetKind, type EngagementTargetParams, engagementTargetKindSchema, engagementTargetParamsSchema, FEED_SORT_VALUES, type FeedAuthor, type FeedComment, type FeedImage, type FeedItem, type FeedItemParams, type FeedMedia, type FeedPage, type FeedPoll, type FeedPost, type FeedQuery, type FeedQueryInput, type FeedSort, type FeedVideo, feedAuthorSchema, feedCommentSchema, feedImageSchema, feedItemParamsSchema, feedItemSchema, feedMediaSchema, feedPageSchema, feedPollSchema, feedPostSchema, feedQuerySchema, feedSortSchema, feedVideoSchema, type LinkPreview, linkPreviewSchema, MAX_TOPICS, POLL_MAX_DURATION_MS, POLL_MAX_OPTIONS, POLL_MIN_DURATION_MS, POLL_MIN_OPTIONS, POLL_OPTION_MAX_CHARS, POLL_QUESTION_MAX_CHARS, POST_MAX_BODY_CHARS, POST_MAX_MEDIA, type PollOption, type PollParams, type ProductFeedbackItem, type ProductFeedbackPage, pollOptionSchema, pollParamsSchema, productFeedbackItemSchema, productFeedbackPageSchema, REACTION_TYPE_VALUES, REPORT_REASON_VALUES, REPORT_TARGET_KIND_VALUES, type ReactionCounts, type ReactionType, type ReportReason, type ReportTargetKind, reactionCountsSchema, reactionTypeSchema, reportReasonSchema, reportTargetKindSchema, type SetReactionBody, type SetReactionResponse, setReactionBodySchema, setReactionResponseSchema, type ToggleBookmarkResponse, toggleBookmarkResponseSchema, type UpdateCommentBody, type UpdatePostBody, updateCommentBodySchema, updatePostBodySchema, type ViewerState, viewerStateSchema, } from './domains/feed/feed.js';
|
|
26
|
+
export { MEDIA_PURPOSE_VALUES, MEDIA_SIZES, MEDIA_UPLOAD_CONTENT_TYPES, MEDIA_VARIANTS_MAX, type MediaImage, type MediaPurpose, type MediaUploadContentType, type MediaVariant, mediaImageSchema, mediaPurposeSchema, mediaUploadContentTypeSchema, mediaVariantSchema, type UploadedMedia, uploadedMediaSchema, } from './domains/media/media.js';
|
|
26
27
|
export { MEMBER_STATUS_VALUES, type MemberDetail, type MemberDirectoryPage, type MemberDirectoryQuery, type MemberDirectoryQueryInput, type MemberParams, type MemberStatus, type MemberSummary, memberDetailSchema, memberDirectoryPageSchema, memberDirectoryQuerySchema, memberParamsSchema, memberStatusSchema, memberSummarySchema, type SuspendMemberBody, type Suspension, suspendMemberBodySchema, suspensionSchema, } from './domains/members/members.js';
|
|
27
|
-
export { MODERATION_ACTION_VALUES, MODERATION_STATE_VALUES, type ModerationAction, type ModerationContentQuery, type ModerationContentQueryInput, type ModerationDecisionBody, type ModerationItem, type ModerationPage, type ModerationState, moderationActionSchema, moderationContentQuerySchema, moderationDecisionBodySchema, moderationItemSchema, moderationPageSchema, moderationStateSchema, } from './domains/moderation/moderation.js';
|
|
28
|
+
export { MODERATION_ACTION_VALUES, MODERATION_ACTIONS_BY_TARGET_KIND, MODERATION_CONTEXT_KIND_VALUES, MODERATION_STATE_VALUES, type ModerationAction, type ModerationContentQuery, type ModerationContentQueryInput, type ModerationContextKind, type ModerationDecisionBody, type ModerationItem, type ModerationPage, type ModerationState, type ModerationTargetParams, moderationActionSchema, moderationContentQuerySchema, moderationContextKindSchema, moderationDecisionBodySchema, moderationItemSchema, moderationPageSchema, moderationStateSchema, moderationTargetParamsSchema, } from './domains/moderation/moderation.js';
|
|
29
|
+
export { NOTIFICATION_KIND_VALUES, NOTIFICATION_PREFERENCE_OF, NOTIFICATION_PREFERENCE_VALUES, type Notification, type NotificationKind, type NotificationPage, type NotificationParams, type NotificationPreference, type NotificationPreferences, type NotificationUnreadCount, notificationKindSchema, notificationPageSchema, notificationParamsSchema, notificationPreferenceSchema, notificationPreferencesSchema, notificationSchema, notificationUnreadCountSchema, type UpdateNotificationPreferencesBody, updateNotificationPreferencesBodySchema, } from './domains/notifications/notifications.js';
|
|
28
30
|
export { ageInYears, BUSINESS_TYPE_VALUES, type BusinessType, businessTypeSchema, type CompleteOnboardingBody, type CompleteOnboardingBodyInput, type CompleteOnboardingResponse, type ContactLinks, completeOnboardingBodySchema, completeOnboardingResponseSchema, contactLinksSchema, type DateOfBirth, dateOfBirthSchema, EMPTY_ONBOARDING_VENTURE, FOUNDER_ONBOARDING_STEPS, GUIDELINES_VERSION, guidelinesVersionSchema, INTERESTS_MAX, INTERESTS_MIN, type IsoDate, isoDateSchema, MAX_AGE_YEARS, MIN_AGE_YEARS, ONBOARDING_DRAFT_KEYS, ONBOARDING_STEP_FIELDS, ONBOARDING_STEP_KEYS, ONBOARDING_STEP_SCHEMAS, ONBOARDING_TOTAL_STEPS, type OnboardingDraft, type OnboardingDraftKey, type OnboardingField, type OnboardingForm, type OnboardingProgress, type OnboardingProgressUpdate, type OnboardingStatus, type OnboardingStepBody, type OnboardingStepConfig, type OnboardingStepKey, onboardingDraftKeySchema, onboardingDraftSchema, onboardingFormSchema, onboardingProgressSchema, onboardingProgressUpdateSchema, onboardingStatusSchema, readOnboardingDraft, TEAM_SIZE_DIGITS_MAX, TOPIC_CATEGORIES, TOPIC_CATEGORY_KEYS, TOPIC_VALUES, type Topic, type TopicCategory, type TopicCategoryKey, topicSchema, } from './domains/onboarding/onboarding.js';
|
|
29
|
-
export { type
|
|
31
|
+
export { type CreateProductBody, createProductBodySchema, type InviteProductMemberBody, inviteProductMemberBodySchema, type MyProducts, myProductsSchema, PRODUCT_ASK_VALUES, PRODUCT_INVITABLE_ROLE_VALUES, PRODUCT_LISTING_REQUIREMENT_VALUES, PRODUCT_PLATFORM_VALUES, PRODUCT_SORT_VALUES, PRODUCT_STAGE_VALUES, PRODUCT_STATUS_VALUES, PRODUCT_TEAM_ROLE_VALUES, PRODUCT_TOPICS_MAX, PRODUCT_VISIBILITY_VALUES, type Product, type ProductAsk, type ProductCard, type ProductCardPage, type ProductChip, type ProductDiscoverQuery, type ProductDiscoverQueryInput, type ProductFacets, type ProductFeedbackQuery, type ProductFeedbackQueryInput, type ProductInvitableRole, type ProductInvite, type ProductInvites, type ProductLinks, type ProductListingRequirement, type ProductMemberParams, type ProductParams, type ProductPendingInvite, type ProductPendingInvitePage, type ProductPlatform, type ProductRating, type ProductScreenshot, type ProductScreenshotInput, type ProductSort, type ProductStage, type ProductStatus, type ProductsByMemberParams, type ProductTeamMember, type ProductTeamPage, type ProductTeamRole, type ProductTester, type ProductTesterPage, type ProductUpvoteResponse, type ProductViewer, type ProductVisibility, productAskSchema, productCardPageSchema, productCardSchema, productCardViewerSchema, productChipSchema, productDiscoverQuerySchema, productFacetsSchema, productFeedbackQuerySchema, productInvitableRoleSchema, productInviteSchema, productInvitesSchema, productLinksSchema, productListingRequirementSchema, productMemberParamsSchema, productParamsSchema, productPendingInvitePageSchema, productPendingInviteSchema, productPlatformSchema, productRatingSchema, productSchema, productScreenshotInputSchema, productScreenshotSchema, productSortSchema, productStageSchema, productStatusSchema, productsByMemberParamsSchema, productTeamMemberSchema, productTeamPageSchema, productTeamRoleSchema, productTesterPageSchema, productTesterSchema, productUpvoteResponseSchema, productVideoUrlSchema, productViewerSchema, productVisibilitySchema, type SetProductLogoBody, type SetProductMemberRoleBody, type SetProductScreenshotsBody, type SetProductStatusBody, type SetProductVisibilityBody, setProductLogoBodySchema, setProductMemberRoleBodySchema, setProductScreenshotsBodySchema, setProductStatusBodySchema, setProductVisibilityBodySchema, type TransferProductBody, transferProductBodySchema, type UpdateProductBody, updateProductBodySchema, } from './domains/products/products.js';
|
|
32
|
+
export { type ContributionSummary, contributionSummarySchema, type FounderCard, type FounderLinks, type FounderProfile, founderCardSchema, founderLinksSchema, founderProfileSchema, type MemberByline, memberBylineSchema, type SetAvatarBody, setAvatarBodySchema, type UpdateFounderProfileBody, type UpdateUsernameBody, type UsernameAvailability, updateFounderProfileBodySchema, updateUsernameBodySchema, usernameAvailabilitySchema, type Venture, ventureSchema, } from './domains/profile/founder-profile.js';
|
|
33
|
+
export { type CreateReviewBody, createReviewBodySchema, type ProductReview, productReviewSchema, REVIEW_SORT_VALUES, type ReviewHelpfulResponse, type ReviewPage, type ReviewParams, type ReviewRating, type ReviewReply, type ReviewReplyBody, type ReviewSort, type ReviewsQuery, type ReviewsQueryInput, type ReviewViewer, reviewHelpfulResponseSchema, reviewPageSchema, reviewParamsSchema, reviewRatingSchema, reviewReplyBodySchema, reviewReplySchema, reviewSortSchema, reviewsQuerySchema, reviewViewerSchema, type UpdateReviewBody, updateReviewBodySchema, } from './domains/reviews/reviews.js';
|
|
30
34
|
export { type CreateTicketBody, createTicketBodySchema, type ReplyTicketBody, replyTicketBodySchema, type SavedReply, type SavedReplyBody, type SavedReplyList, type SavedReplyParams, savedReplyBodySchema, savedReplyListSchema, savedReplyParamsSchema, savedReplySchema, TICKET_ASSIGNEE_FILTER_VALUES, TICKET_CATEGORY_VALUES, TICKET_SCOPE_VALUES, TICKET_STATUS_VALUES, type TicketAssigneeFilter, type TicketCategory, type TicketDetail, type TicketListQuery, type TicketListQueryInput, type TicketMessage, type TicketPage, type TicketParams, type TicketScope, type TicketStatus, type TicketSummary, ticketAssigneeFilterSchema, ticketCategorySchema, ticketDetailSchema, ticketListQuerySchema, ticketMessageSchema, ticketPageSchema, ticketParamsSchema, ticketScopeSchema, ticketStatusSchema, ticketSummarySchema, } from './domains/support/support.js';
|
|
31
35
|
export { type SetMemberRolesBody, type SetMemberRolesResponse, setMemberRolesBodySchema, setMemberRolesResponseSchema, type TeamMember, type TeamMemberParams, type TeamPage, teamMemberParamsSchema, teamMemberSchema, teamPageSchema, } from './domains/team/team.js';
|
|
32
36
|
export { UPLOAD_CONTENT_TYPES, UPLOAD_KEY_EXTENSIONS, UPLOAD_KEY_MAX_CHARS, UPLOAD_KEY_PATTERN, type UploadKey, type UploadKeyExtension, type UploadParams, type UploadPresignBody, type UploadPresignResponse, uploadKeyExtensionSchema, uploadKeySchema, uploadParamsSchema, uploadPresignBodySchema, uploadPresignResponseSchema, } from './domains/uploads/uploads.js';
|