@antiphony/shared 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/api-codecs.cjs +26 -650
- package/dist/cjs/api-codecs.d.cts +15 -233
- package/dist/cjs/index.cjs +29 -761
- package/dist/cjs/index.d.cts +4 -4
- package/dist/cjs/nsid.cjs +3 -10
- package/dist/cjs/nsid.d.cts +1 -9
- package/dist/cjs/types/api.cjs +11 -571
- package/dist/cjs/types/api.d.cts +13 -265
- package/dist/cjs/types/audio.cjs +26 -547
- package/dist/cjs/types/audio.d.cts +93 -52
- package/dist/cjs/types/records.cjs +3 -328
- package/dist/cjs/types/records.d.cts +7 -729
- package/dist/cjs/types/views.cjs +8 -649
- package/dist/cjs/types/views.d.cts +43 -9123
- package/dist/esm/api-codecs.d.ts +46 -264
- package/dist/esm/api-codecs.js +5 -5
- package/dist/esm/{chunk-ORMEWXMH.js → chunk-5JBD5THX.js} +1 -16
- package/dist/esm/{chunk-XDBKR6LW.js → chunk-6LROFBKK.js} +3 -10
- package/dist/esm/{chunk-F2CANZZ7.js → chunk-BNNLHRH7.js} +1 -1
- package/dist/esm/{chunk-BUNMR4ZO.js → chunk-F7IHVM34.js} +20 -3
- package/dist/esm/chunk-FDM5FDN4.js +46 -0
- package/dist/esm/chunk-IHIBHQBJ.js +78 -0
- package/dist/esm/chunk-R6SBR3IG.js +97 -0
- package/dist/esm/chunk-Y6HNNRVD.js +12 -0
- package/dist/esm/errors/index.js +1 -1
- package/dist/esm/index.d.ts +4 -4
- package/dist/esm/index.js +8 -8
- package/dist/esm/nsid.d.ts +1 -9
- package/dist/esm/nsid.js +2 -2
- package/dist/esm/observability/index.js +2 -2
- package/dist/esm/observability/report-error.js +2 -2
- package/dist/esm/types/api.d.ts +15 -267
- package/dist/esm/types/api.js +4 -5
- package/dist/esm/types/audio.d.ts +170 -129
- package/dist/esm/types/audio.js +4 -4
- package/dist/esm/types/blob.js +1 -1
- package/dist/esm/types/records.d.ts +10 -732
- package/dist/esm/types/records.js +2 -3
- package/dist/esm/types/views.d.ts +51 -9131
- package/dist/esm/types/views.js +3 -4
- package/dist/esm/utils/index.js +1 -1
- package/package.json +1 -1
- package/dist/cjs/types/channels.cjs +0 -170
- package/dist/cjs/types/channels.d.cts +0 -262
- package/dist/cjs/types/storage.cjs +0 -414
- package/dist/cjs/types/storage.d.cts +0 -197
- package/dist/esm/chunk-3WZJXJNU.js +0 -378
- package/dist/esm/chunk-7V44CPRR.js +0 -132
- package/dist/esm/chunk-EA4OONDV.js +0 -380
- package/dist/esm/chunk-TIZRJORN.js +0 -24
- package/dist/esm/types/channels.d.ts +0 -262
- package/dist/esm/types/channels.js +0 -162
- package/dist/esm/types/storage.d.ts +0 -197
- package/dist/esm/types/storage.js +0 -26
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
import { FirestoreTimestampSchema, PromptRecordSchema, ReplyRecordSchema, OrganizationRecordSchema, OrganizationMemberRecordSchema, OrgInviteRecordSchema } from './chunk-3WZJXJNU.js';
|
|
2
|
-
import { __objRest, __spreadProps, __spreadValues } from './chunk-ORMEWXMH.js';
|
|
3
|
-
import { z } from 'zod';
|
|
4
|
-
|
|
5
|
-
var ProfileViewBasicSchema = z.object({
|
|
6
|
-
id: z.string(),
|
|
7
|
-
handle: z.string().nullable().optional(),
|
|
8
|
-
// `displayName` and `bio` are `.nullable()` — Firestore stores `null` for
|
|
9
|
-
// empty values on these fields (see users-dependencies.ts), and Zod's
|
|
10
|
-
// `.optional()` alone rejects `null`. This hit dashboard rendering on the
|
|
11
|
-
// Phase 3.1 HTTP cutover, when transport-layer Zod validation started
|
|
12
|
-
// actually exercising the wire shape. Consumers already use truthy
|
|
13
|
-
// checks / `??` / `||`, so widening the type to include `null` is safe.
|
|
14
|
-
displayName: z.string().nullable().optional(),
|
|
15
|
-
avatarUrl: z.string().nullable().optional(),
|
|
16
|
-
bio: z.string().nullable().optional(),
|
|
17
|
-
/** Personal website link surfaced on the public profile. */
|
|
18
|
-
website: z.string().nullable().optional(),
|
|
19
|
-
/** Public links (label + URL) shown under the bio. */
|
|
20
|
-
links: z.array(z.object({
|
|
21
|
-
label: z.string(),
|
|
22
|
-
url: z.string()
|
|
23
|
-
})).optional(),
|
|
24
|
-
/**
|
|
25
|
-
* AT Protocol identity, surfaced on the public profile only when the user
|
|
26
|
-
* opts in (`UserRecord.showBlueskyPublicly === true`). Projection happens
|
|
27
|
-
* in the user dependency layer; this schema simply allows the field.
|
|
28
|
-
*/
|
|
29
|
-
bluesky: z.object({
|
|
30
|
-
handle: z.string(),
|
|
31
|
-
did: z.string()
|
|
32
|
-
}).optional(),
|
|
33
|
-
stats: z.object({
|
|
34
|
-
followers: z.number().default(0),
|
|
35
|
-
following: z.number().default(0),
|
|
36
|
-
prompts: z.number().default(0)
|
|
37
|
-
}).optional(),
|
|
38
|
-
badges: z.array(z.string()).optional(),
|
|
39
|
-
isVerified: z.boolean().optional(),
|
|
40
|
-
createdAt: FirestoreTimestampSchema.optional()
|
|
41
|
-
});
|
|
42
|
-
function toProfileViewBasic(profile) {
|
|
43
|
-
const { id, handle, displayName, avatarUrl, bio, website, links, bluesky, showBlueskyPublicly, stats, badges, isVerified, createdAt } = profile;
|
|
44
|
-
return {
|
|
45
|
-
id,
|
|
46
|
-
handle,
|
|
47
|
-
displayName,
|
|
48
|
-
avatarUrl,
|
|
49
|
-
bio,
|
|
50
|
-
website,
|
|
51
|
-
links,
|
|
52
|
-
bluesky: showBlueskyPublicly ? bluesky : void 0,
|
|
53
|
-
stats,
|
|
54
|
-
badges,
|
|
55
|
-
isVerified,
|
|
56
|
-
createdAt
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
var ProfileViewDetailedSchema = ProfileViewBasicSchema.extend({
|
|
60
|
-
/** AT Protocol Identity link */
|
|
61
|
-
bluesky: z.object({
|
|
62
|
-
handle: z.string(),
|
|
63
|
-
did: z.string()
|
|
64
|
-
}).optional(),
|
|
65
|
-
usageIntent: z.string().nullable().optional(),
|
|
66
|
-
/** Hydrated RSS Data (fetched from sub-collection) */
|
|
67
|
-
rssSummary: z.object({
|
|
68
|
-
title: z.string().optional(),
|
|
69
|
-
description: z.string().optional(),
|
|
70
|
-
items: z.array(z.object({
|
|
71
|
-
title: z.string().optional(),
|
|
72
|
-
link: z.string().optional(),
|
|
73
|
-
content: z.string().optional(),
|
|
74
|
-
pubDate: z.string().optional()
|
|
75
|
-
})).optional(),
|
|
76
|
-
lastFetchedAt: FirestoreTimestampSchema.optional()
|
|
77
|
-
}).optional(),
|
|
78
|
-
promptAudioUrl: z.string().optional(),
|
|
79
|
-
/** @deprecated Use stats.prompts from ProfileViewBasic instead */
|
|
80
|
-
totalPrompts: z.number().optional(),
|
|
81
|
-
totalReplies: z.number().optional(),
|
|
82
|
-
favoritePromptId: z.string().optional()
|
|
83
|
-
});
|
|
84
|
-
var ProfileViewSelfSchema = ProfileViewDetailedSchema.extend({
|
|
85
|
-
phoneNumber: z.string().nullable().optional(),
|
|
86
|
-
email: z.string().optional(),
|
|
87
|
-
lastSeenAt: FirestoreTimestampSchema.optional(),
|
|
88
|
-
lastActiveAt: FirestoreTimestampSchema.optional(),
|
|
89
|
-
unreadReplyCount: z.number().default(0),
|
|
90
|
-
newReplierCount: z.number().default(0),
|
|
91
|
-
/**
|
|
92
|
-
* Account tier from UserRecord — surfaced on the self profile so the
|
|
93
|
-
* client can gate paid features (e.g. the Performance dashboard tab).
|
|
94
|
-
* Optional for legacy docs without the field; consumers should treat
|
|
95
|
-
* missing as `'free'`.
|
|
96
|
-
*/
|
|
97
|
-
tier: z.enum(["free", "creator_pro"]).optional(),
|
|
98
|
-
/**
|
|
99
|
-
* Surfaces the linked Bluesky identity (handle + DID) on the public profile
|
|
100
|
-
* when true. Persisted on UserRecord; exposed in self/detailed views so the
|
|
101
|
-
* settings form can render the toggle's current state.
|
|
102
|
-
*/
|
|
103
|
-
showBlueskyPublicly: z.boolean().optional(),
|
|
104
|
-
settings: z.object({
|
|
105
|
-
notifications: z.boolean().optional(),
|
|
106
|
-
theme: z.string().optional()
|
|
107
|
-
}).optional()
|
|
108
|
-
});
|
|
109
|
-
var ProfileViewAdminSchema = ProfileViewSelfSchema.extend({
|
|
110
|
-
blockedUsers: z.array(z.string()).optional(),
|
|
111
|
-
followers: z.array(z.string()).optional(),
|
|
112
|
-
following: z.array(z.string()).optional(),
|
|
113
|
-
reportCount: z.number().optional(),
|
|
114
|
-
isBanned: z.boolean().optional()
|
|
115
|
-
});
|
|
116
|
-
var ProfileViewSchema = ProfileViewAdminSchema;
|
|
117
|
-
var PromptViewSchema = z.object({
|
|
118
|
-
/** AT Protocol URI (e.g. at://did:plc.../app.../123) */
|
|
119
|
-
uri: z.string().optional(),
|
|
120
|
-
/** IPFS Content ID */
|
|
121
|
-
cid: z.string().optional(),
|
|
122
|
-
/** The raw prompt data */
|
|
123
|
-
record: PromptRecordSchema,
|
|
124
|
-
/** The hydrated author profile */
|
|
125
|
-
author: ProfileViewSchema,
|
|
126
|
-
/** Total number of replies */
|
|
127
|
-
replyCount: z.number().default(0),
|
|
128
|
-
likeCount: z.number().default(0),
|
|
129
|
-
updatedAt: FirestoreTimestampSchema.optional(),
|
|
130
|
-
lastReplyAt: FirestoreTimestampSchema.optional(),
|
|
131
|
-
tags: z.array(z.string()).optional(),
|
|
132
|
-
visibility: z.enum(["public", "private", "unlisted", "archived"]).default("public"),
|
|
133
|
-
analytics: z.object({
|
|
134
|
-
views: z.number().default(0),
|
|
135
|
-
listens: z.number().default(0),
|
|
136
|
-
/**
|
|
137
|
-
* Mean engagementScore (1–10) across this prompt's `status: 'live'`
|
|
138
|
-
* replies that completed AI enrichment. `null` when no such replies
|
|
139
|
-
* exist (0 would alias a valid bottom-of-range score). Derived in
|
|
140
|
-
* hydration from the prompt doc's `engagementScoreSum / Count`.
|
|
141
|
-
*/
|
|
142
|
-
avgEngagementScore: z.number().nullable().optional(),
|
|
143
|
-
/**
|
|
144
|
-
* Counts of `status: 'live'` AI-enriched replies grouped by sentiment.
|
|
145
|
-
* Keys lowercase by convention; source enum
|
|
146
|
-
* (`Positive | Neutral | Negative`) is mapped at the write site.
|
|
147
|
-
*/
|
|
148
|
-
sentimentBreakdown: z.object({
|
|
149
|
-
positive: z.number(),
|
|
150
|
-
neutral: z.number(),
|
|
151
|
-
negative: z.number()
|
|
152
|
-
}).optional()
|
|
153
|
-
}).optional(),
|
|
154
|
-
moderation: z.object({
|
|
155
|
-
flagged: z.boolean().default(false),
|
|
156
|
-
reason: z.string().optional()
|
|
157
|
-
}).optional(),
|
|
158
|
-
// AI Enrichment Fields (Hydrated from Record but hidden from Record Schema)
|
|
159
|
-
aiLabels: z.array(z.string()).optional(),
|
|
160
|
-
aiSummary: z.string().optional(),
|
|
161
|
-
aiStatus: z.enum(["pending", "complete", "error"]).optional(),
|
|
162
|
-
aiError: z.string().optional(),
|
|
163
|
-
transcription: z.string().optional()
|
|
164
|
-
});
|
|
165
|
-
var PromptViewPublicSchema = PromptViewSchema.omit({
|
|
166
|
-
analytics: true,
|
|
167
|
-
moderation: true,
|
|
168
|
-
aiLabels: true,
|
|
169
|
-
aiSummary: true,
|
|
170
|
-
aiStatus: true,
|
|
171
|
-
aiError: true,
|
|
172
|
-
transcription: true
|
|
173
|
-
}).extend({
|
|
174
|
-
author: ProfileViewBasicSchema
|
|
175
|
-
});
|
|
176
|
-
function toPromptViewPublic(prompt) {
|
|
177
|
-
const _a = prompt, { analytics, moderation, aiLabels, aiSummary, aiStatus, aiError, transcription } = _a, rest = __objRest(_a, ["analytics", "moderation", "aiLabels", "aiSummary", "aiStatus", "aiError", "transcription"]);
|
|
178
|
-
return __spreadProps(__spreadValues({}, rest), {
|
|
179
|
-
author: toProfileViewBasic(rest.author)
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
var ReplyViewSchema = z.object({
|
|
183
|
-
record: ReplyRecordSchema,
|
|
184
|
-
author: ProfileViewSchema,
|
|
185
|
-
recipient: ProfileViewSchema,
|
|
186
|
-
/** GCS Storage Path for audio file */
|
|
187
|
-
storagePath: z.string().optional(),
|
|
188
|
-
duration: z.number().optional(),
|
|
189
|
-
updatedAt: FirestoreTimestampSchema.optional(),
|
|
190
|
-
isRead: z.boolean(),
|
|
191
|
-
readBy: z.array(z.string()).default([]),
|
|
192
|
-
isDeleted: z.boolean().default(false),
|
|
193
|
-
reactions: z.record(z.string(), z.number()).optional(),
|
|
194
|
-
moderation: z.object({
|
|
195
|
-
flagged: z.boolean().default(false),
|
|
196
|
-
reason: z.string().optional()
|
|
197
|
-
}).optional(),
|
|
198
|
-
// AI Enrichment Fields (Hydrated from Record but hidden from Record Schema)
|
|
199
|
-
aiLabels: z.array(z.string()).optional(),
|
|
200
|
-
aiSummary: z.string().optional(),
|
|
201
|
-
aiStatus: z.enum(["pending", "complete", "error", "skipped_too_short"]).optional(),
|
|
202
|
-
aiError: z.string().optional(),
|
|
203
|
-
transcription: z.string().optional(),
|
|
204
|
-
sentiment: z.enum(["Positive", "Negative", "Neutral"]).optional(),
|
|
205
|
-
/** Must match the widened enum in `ReplyRecordSchema.energyLevel`. */
|
|
206
|
-
energyLevel: z.enum(["High", "Low", "Neutral"]).optional(),
|
|
207
|
-
engagementScore: z.number().min(1).max(10).optional(),
|
|
208
|
-
// === Voice-isolation enrichment (lifted; see specs/ai-enrichment-split.md) ===
|
|
209
|
-
//
|
|
210
|
-
// `enhancedAudioUrl` is the only one of these the public view keeps —
|
|
211
|
-
// it replaces `audioUrl` for downstream players when present.
|
|
212
|
-
// `enhancedStoragePath` is private (storage paths are server-side
|
|
213
|
-
// bookkeeping).
|
|
214
|
-
enhancedAudioUrl: z.string().url().optional(),
|
|
215
|
-
enhancedStoragePath: z.string().optional(),
|
|
216
|
-
// === Social-share video enrichment (lifted; creator-only) ===
|
|
217
|
-
//
|
|
218
|
-
// All `socialVideo*` fields are stripped by `toReplyViewPublic` —
|
|
219
|
-
// the URL points at a generated artifact the creator may share to
|
|
220
|
-
// social media, NOT at content the reply page should render. Status /
|
|
221
|
-
// error / source-audio are job-tracking state.
|
|
222
|
-
socialVideoUrl: z.string().url().optional(),
|
|
223
|
-
socialVideoStoragePath: z.string().optional(),
|
|
224
|
-
socialVideoStatus: z.enum(["pending", "complete", "error"]).optional(),
|
|
225
|
-
socialVideoError: z.string().optional(),
|
|
226
|
-
socialVideoSourceAudio: z.string().optional(),
|
|
227
|
-
/** @private Confirmed listener phone number (never exposed publicly) */
|
|
228
|
-
listenerPhoneNumber: z.string().regex(/^\+[1-9]\d{1,14}$/).optional(),
|
|
229
|
-
/**
|
|
230
|
-
* @private Per-viewer private notes about this reply (CRM enrichment).
|
|
231
|
-
* Lifted into the view from `enrichments/replies/{id}.notes` by the
|
|
232
|
-
* hydrator when the viewer is the prompt author. Never populated for
|
|
233
|
-
* non-author viewers; defensively stripped by `toReplyViewPublic`.
|
|
234
|
-
*/
|
|
235
|
-
notes: z.string().optional()
|
|
236
|
-
});
|
|
237
|
-
var ReplyViewPublicSchema = ReplyViewSchema.omit({
|
|
238
|
-
listenerPhoneNumber: true,
|
|
239
|
-
notes: true,
|
|
240
|
-
// AI cluster — only `transcription` survives.
|
|
241
|
-
aiStatus: true,
|
|
242
|
-
aiError: true,
|
|
243
|
-
aiSummary: true,
|
|
244
|
-
aiLabels: true,
|
|
245
|
-
sentiment: true,
|
|
246
|
-
energyLevel: true,
|
|
247
|
-
engagementScore: true,
|
|
248
|
-
// Voice isolation — keep enhancedAudioUrl, strip the path.
|
|
249
|
-
enhancedStoragePath: true,
|
|
250
|
-
// Social-video — entire cluster is creator-only.
|
|
251
|
-
socialVideoUrl: true,
|
|
252
|
-
socialVideoStoragePath: true,
|
|
253
|
-
socialVideoStatus: true,
|
|
254
|
-
socialVideoError: true,
|
|
255
|
-
socialVideoSourceAudio: true
|
|
256
|
-
});
|
|
257
|
-
function toReplyViewPublic(reply) {
|
|
258
|
-
const _a = reply, {
|
|
259
|
-
listenerPhoneNumber,
|
|
260
|
-
notes,
|
|
261
|
-
aiStatus: aiStatus,
|
|
262
|
-
aiError,
|
|
263
|
-
aiSummary,
|
|
264
|
-
aiLabels,
|
|
265
|
-
sentiment,
|
|
266
|
-
energyLevel,
|
|
267
|
-
engagementScore,
|
|
268
|
-
enhancedStoragePath: enhancedStoragePath,
|
|
269
|
-
socialVideoUrl: socialVideoUrl,
|
|
270
|
-
socialVideoStoragePath,
|
|
271
|
-
socialVideoStatus,
|
|
272
|
-
socialVideoError,
|
|
273
|
-
socialVideoSourceAudio
|
|
274
|
-
} = _a, publicReply = __objRest(_a, [
|
|
275
|
-
"listenerPhoneNumber",
|
|
276
|
-
"notes",
|
|
277
|
-
// AI cluster (only transcription stays public)
|
|
278
|
-
"aiStatus",
|
|
279
|
-
"aiError",
|
|
280
|
-
"aiSummary",
|
|
281
|
-
"aiLabels",
|
|
282
|
-
"sentiment",
|
|
283
|
-
"energyLevel",
|
|
284
|
-
"engagementScore",
|
|
285
|
-
// Voice isolation (only enhancedAudioUrl stays public)
|
|
286
|
-
"enhancedStoragePath",
|
|
287
|
-
// Social-video (entire cluster is creator-only)
|
|
288
|
-
"socialVideoUrl",
|
|
289
|
-
"socialVideoStoragePath",
|
|
290
|
-
"socialVideoStatus",
|
|
291
|
-
"socialVideoError",
|
|
292
|
-
"socialVideoSourceAudio"
|
|
293
|
-
]);
|
|
294
|
-
return publicReply;
|
|
295
|
-
}
|
|
296
|
-
var OrganizationViewSchema = z.object({
|
|
297
|
-
record: OrganizationRecordSchema,
|
|
298
|
-
memberCount: z.number().default(1),
|
|
299
|
-
currentUserRole: z.enum(["owner", "admin", "member"]).optional()
|
|
300
|
-
});
|
|
301
|
-
var OrganizationMemberViewSchema = z.object({
|
|
302
|
-
record: OrganizationMemberRecordSchema,
|
|
303
|
-
profile: ProfileViewBasicSchema
|
|
304
|
-
});
|
|
305
|
-
var OrgInviteViewSchema = z.object({
|
|
306
|
-
record: OrgInviteRecordSchema,
|
|
307
|
-
/** Display name of the user who sent the invite */
|
|
308
|
-
inviterName: z.string().optional(),
|
|
309
|
-
/** Name of the organization */
|
|
310
|
-
orgName: z.string()
|
|
311
|
-
});
|
|
312
|
-
var PromptRepliersSchema = z.object({
|
|
313
|
-
promptId: z.string(),
|
|
314
|
-
repliers: z.record(z.string(), z.object({
|
|
315
|
-
firstReplyAt: FirestoreTimestampSchema,
|
|
316
|
-
lastReplyAt: FirestoreTimestampSchema,
|
|
317
|
-
replyCount: z.number()
|
|
318
|
-
}))
|
|
319
|
-
});
|
|
320
|
-
var PromptWithRepliesSchema = PromptViewSchema.extend({
|
|
321
|
-
replies: z.array(ReplyViewSchema)
|
|
322
|
-
});
|
|
323
|
-
var ReplierSchema = z.object({
|
|
324
|
-
handle: z.string(),
|
|
325
|
-
/** ISO date string */
|
|
326
|
-
lastReplyDate: z.string(),
|
|
327
|
-
/** ISO date string */
|
|
328
|
-
firstReplyAt: z.string(),
|
|
329
|
-
totalReplies: z.number()
|
|
330
|
-
});
|
|
331
|
-
var HandleResolutionSchema = z.discriminatedUnion("type", [
|
|
332
|
-
// Public endpoint (`GET /resolve/:handle`) — project to the basic shape so
|
|
333
|
-
// PII/admin fields (email, phoneNumber, settings, blockedUsers, …) never
|
|
334
|
-
// cross the public API boundary. See `toProfileViewBasic`.
|
|
335
|
-
z.object({ type: z.literal("user"), profile: ProfileViewBasicSchema }),
|
|
336
|
-
z.object({ type: z.literal("org"), org: OrganizationViewSchema })
|
|
337
|
-
]);
|
|
338
|
-
var UserProfileDataSchema = z.object({
|
|
339
|
-
// Public endpoint (`GET /users/:handle/profile`) — basic shape only, so the
|
|
340
|
-
// owner's PII/admin fields never serialize to anonymous callers.
|
|
341
|
-
profileUser: ProfileViewBasicSchema,
|
|
342
|
-
// Each prompt's nested `author` is the profile owner, hydrated from the
|
|
343
|
-
// wide admin profile (`getPromptsForUser` prefetches via getUserDataByUid).
|
|
344
|
-
// Use the PUBLIC prompt/reply shapes so that nested author PII (email,
|
|
345
|
-
// phoneNumber, settings, …) and owner-only prompt enrichment never leak.
|
|
346
|
-
allPromptsWithReplies: z.array(PromptViewPublicSchema.extend({
|
|
347
|
-
replies: z.array(ReplyViewPublicSchema)
|
|
348
|
-
})),
|
|
349
|
-
repliers: z.array(ReplierSchema)
|
|
350
|
-
});
|
|
351
|
-
var RssSummarySchema = z.object({
|
|
352
|
-
title: z.string().optional(),
|
|
353
|
-
description: z.string().optional(),
|
|
354
|
-
image: z.string().optional(),
|
|
355
|
-
link: z.string().optional(),
|
|
356
|
-
items: z.array(z.object({
|
|
357
|
-
title: z.string().optional(),
|
|
358
|
-
link: z.string().optional(),
|
|
359
|
-
content: z.string().optional(),
|
|
360
|
-
pubDate: z.string().optional()
|
|
361
|
-
})).optional(),
|
|
362
|
-
lastFetchedAt: FirestoreTimestampSchema.optional()
|
|
363
|
-
});
|
|
364
|
-
var OrgProfileDataSchema = z.object({
|
|
365
|
-
org: OrganizationViewSchema,
|
|
366
|
-
prompts: z.array(PromptViewSchema),
|
|
367
|
-
rssSummary: RssSummarySchema.nullable()
|
|
368
|
-
});
|
|
369
|
-
var EnrichedReplierSchema = z.object({
|
|
370
|
-
profile: ProfileViewBasicSchema,
|
|
371
|
-
totalReplies: z.number(),
|
|
372
|
-
/** ISO date string */
|
|
373
|
-
lastReplyDate: z.string(),
|
|
374
|
-
/** ISO date string */
|
|
375
|
-
firstReplyAt: z.string(),
|
|
376
|
-
/** Phone number for anonymous repliers (from Firebase Auth, only visible to prompt author) */
|
|
377
|
-
phoneNumber: z.string().optional()
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
export { EnrichedReplierSchema, HandleResolutionSchema, OrgInviteViewSchema, OrgProfileDataSchema, OrganizationMemberViewSchema, OrganizationViewSchema, ProfileViewAdminSchema, ProfileViewBasicSchema, ProfileViewDetailedSchema, ProfileViewSchema, ProfileViewSelfSchema, PromptRepliersSchema, PromptViewPublicSchema, PromptViewSchema, PromptWithRepliesSchema, ReplierSchema, ReplyViewPublicSchema, ReplyViewSchema, RssSummarySchema, UserProfileDataSchema, toProfileViewBasic, toPromptViewPublic, toReplyViewPublic };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { ProfileViewBasicSchema, ProfileViewSelfSchema } from './chunk-EA4OONDV.js';
|
|
2
|
-
import { FirestoreTimestampSchema } from './chunk-3WZJXJNU.js';
|
|
3
|
-
import { z } from 'zod';
|
|
4
|
-
|
|
5
|
-
var PublicProfileDtoSchema = ProfileViewBasicSchema.extend({
|
|
6
|
-
bluesky: z.object({
|
|
7
|
-
handle: z.string(),
|
|
8
|
-
did: z.string()
|
|
9
|
-
}).optional(),
|
|
10
|
-
rssFeedUrl: z.string().nullable().optional()
|
|
11
|
-
});
|
|
12
|
-
var PublicReplyDtoSchema = z.object({
|
|
13
|
-
id: z.string(),
|
|
14
|
-
audioUrl: z.string().url(),
|
|
15
|
-
duration: z.number().optional(),
|
|
16
|
-
createdAt: FirestoreTimestampSchema,
|
|
17
|
-
transcription: z.string().optional(),
|
|
18
|
-
sentiment: z.enum(["Positive", "Negative", "Neutral"]).optional(),
|
|
19
|
-
aiSummary: z.string().optional(),
|
|
20
|
-
author: PublicProfileDtoSchema
|
|
21
|
-
});
|
|
22
|
-
var ActorViewSchema = ProfileViewSelfSchema;
|
|
23
|
-
|
|
24
|
-
export { ActorViewSchema, PublicProfileDtoSchema, PublicReplyDtoSchema };
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Channels — the user-facing inbound/outbound surface over the connector
|
|
5
|
-
* control-plane. See `specs/channels.md`.
|
|
6
|
-
*
|
|
7
|
-
* Phase 1 is a **read-model only**: `GET /api/v1/users/me/channels` projects the
|
|
8
|
-
* scattered per-user channel state (the `telephony` connector envelope, the SIP
|
|
9
|
-
* enrichment doc, the profile's linked Bluesky identity, plus the always-on web
|
|
10
|
-
* / RSS / embed surfaces) into one uniform list. No storage migration — this
|
|
11
|
-
* file defines the projection's shape and the static descriptor registry that
|
|
12
|
-
* both the API (overlaying per-user state) and the settings UI (rendering rows)
|
|
13
|
-
* agree on.
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
|
-
* The known channels. Distinct from `ConnectorTypeSchema` (the storage-layer
|
|
17
|
-
* connector allowlist, currently just `telephony`): a channel is the *product*
|
|
18
|
-
* concept, which may map onto a connector, an always-on surface, or a
|
|
19
|
-
* not-yet-built capability.
|
|
20
|
-
*/
|
|
21
|
-
declare const ChannelTypeSchema: z.ZodEnum<["web-capture", "phone", "bluesky-replies", "bluesky-publishing", "phone-voicemail", "rss", "embed", "sms-invites"]>;
|
|
22
|
-
type ChannelType = z.infer<typeof ChannelTypeSchema>;
|
|
23
|
-
declare const ChannelDirectionSchema: z.ZodEnum<["inbound", "outbound", "bidirectional"]>;
|
|
24
|
-
type ChannelDirection = z.infer<typeof ChannelDirectionSchema>;
|
|
25
|
-
/**
|
|
26
|
-
* Generic, render-without-channel-knowledge lifecycle. The first five mirror
|
|
27
|
-
* `ConnectorStatus.state`; `coming-soon` marks a registered-but-unbuilt channel
|
|
28
|
-
* so the UI can show it greyed without a special case.
|
|
29
|
-
*/
|
|
30
|
-
declare const ChannelStateSchema: z.ZodEnum<["active", "pending", "disabled", "unconfigured", "error", "coming-soon"]>;
|
|
31
|
-
type ChannelState = z.infer<typeof ChannelStateSchema>;
|
|
32
|
-
declare const ChannelViewSchema: z.ZodObject<{
|
|
33
|
-
type: z.ZodEnum<["web-capture", "phone", "bluesky-replies", "bluesky-publishing", "phone-voicemail", "rss", "embed", "sms-invites"]>;
|
|
34
|
-
direction: z.ZodEnum<["inbound", "outbound", "bidirectional"]>;
|
|
35
|
-
/** Human label, e.g. "Phone", "Bluesky publishing". */
|
|
36
|
-
label: z.ZodString;
|
|
37
|
-
/** One-line explanation rendered under the label. */
|
|
38
|
-
description: z.ZodString;
|
|
39
|
-
/** Generic lifecycle state the UI renders as a status pill. */
|
|
40
|
-
state: z.ZodEnum<["active", "pending", "disabled", "unconfigured", "error", "coming-soon"]>;
|
|
41
|
-
/** Channel-specific human detail (e.g. a verification failure reason). */
|
|
42
|
-
statusDetail: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
43
|
-
/** Whether the channel is currently switched on for this user. */
|
|
44
|
-
enabled: z.ZodBoolean;
|
|
45
|
-
/** Always-on surfaces (web capture, RSS, embed) — no real disable. */
|
|
46
|
-
alwaysOn: z.ZodBoolean;
|
|
47
|
-
/** Whether there's a per-channel config screen to open. */
|
|
48
|
-
configurable: z.ZodBoolean;
|
|
49
|
-
/** Requires a paid tier to use (see `docs/feature-gates.md`). */
|
|
50
|
-
gated: z.ZodBoolean;
|
|
51
|
-
/**
|
|
52
|
-
* A prerequisite that must be satisfied elsewhere before this channel works,
|
|
53
|
-
* e.g. `'bluesky-identity'` for Bluesky publishing. Null when self-contained.
|
|
54
|
-
*/
|
|
55
|
-
dependsOn: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
56
|
-
}, "strip", z.ZodTypeAny, {
|
|
57
|
-
description: string;
|
|
58
|
-
type: "embed" | "web-capture" | "phone" | "bluesky-replies" | "bluesky-publishing" | "phone-voicemail" | "rss" | "sms-invites";
|
|
59
|
-
label: string;
|
|
60
|
-
enabled: boolean;
|
|
61
|
-
state: "pending" | "error" | "active" | "unconfigured" | "disabled" | "coming-soon";
|
|
62
|
-
direction: "inbound" | "outbound" | "bidirectional";
|
|
63
|
-
alwaysOn: boolean;
|
|
64
|
-
configurable: boolean;
|
|
65
|
-
gated: boolean;
|
|
66
|
-
statusDetail?: string | null | undefined;
|
|
67
|
-
dependsOn?: string | null | undefined;
|
|
68
|
-
}, {
|
|
69
|
-
description: string;
|
|
70
|
-
type: "embed" | "web-capture" | "phone" | "bluesky-replies" | "bluesky-publishing" | "phone-voicemail" | "rss" | "sms-invites";
|
|
71
|
-
label: string;
|
|
72
|
-
enabled: boolean;
|
|
73
|
-
state: "pending" | "error" | "active" | "unconfigured" | "disabled" | "coming-soon";
|
|
74
|
-
direction: "inbound" | "outbound" | "bidirectional";
|
|
75
|
-
alwaysOn: boolean;
|
|
76
|
-
configurable: boolean;
|
|
77
|
-
gated: boolean;
|
|
78
|
-
statusDetail?: string | null | undefined;
|
|
79
|
-
dependsOn?: string | null | undefined;
|
|
80
|
-
}>;
|
|
81
|
-
type ChannelView = z.infer<typeof ChannelViewSchema>;
|
|
82
|
-
/** The `GET /users/me/channels` response payload (inside the standard envelope). */
|
|
83
|
-
declare const ChannelsResponseSchema: z.ZodObject<{
|
|
84
|
-
inbound: z.ZodArray<z.ZodObject<{
|
|
85
|
-
type: z.ZodEnum<["web-capture", "phone", "bluesky-replies", "bluesky-publishing", "phone-voicemail", "rss", "embed", "sms-invites"]>;
|
|
86
|
-
direction: z.ZodEnum<["inbound", "outbound", "bidirectional"]>;
|
|
87
|
-
/** Human label, e.g. "Phone", "Bluesky publishing". */
|
|
88
|
-
label: z.ZodString;
|
|
89
|
-
/** One-line explanation rendered under the label. */
|
|
90
|
-
description: z.ZodString;
|
|
91
|
-
/** Generic lifecycle state the UI renders as a status pill. */
|
|
92
|
-
state: z.ZodEnum<["active", "pending", "disabled", "unconfigured", "error", "coming-soon"]>;
|
|
93
|
-
/** Channel-specific human detail (e.g. a verification failure reason). */
|
|
94
|
-
statusDetail: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
95
|
-
/** Whether the channel is currently switched on for this user. */
|
|
96
|
-
enabled: z.ZodBoolean;
|
|
97
|
-
/** Always-on surfaces (web capture, RSS, embed) — no real disable. */
|
|
98
|
-
alwaysOn: z.ZodBoolean;
|
|
99
|
-
/** Whether there's a per-channel config screen to open. */
|
|
100
|
-
configurable: z.ZodBoolean;
|
|
101
|
-
/** Requires a paid tier to use (see `docs/feature-gates.md`). */
|
|
102
|
-
gated: z.ZodBoolean;
|
|
103
|
-
/**
|
|
104
|
-
* A prerequisite that must be satisfied elsewhere before this channel works,
|
|
105
|
-
* e.g. `'bluesky-identity'` for Bluesky publishing. Null when self-contained.
|
|
106
|
-
*/
|
|
107
|
-
dependsOn: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
108
|
-
}, "strip", z.ZodTypeAny, {
|
|
109
|
-
description: string;
|
|
110
|
-
type: "embed" | "web-capture" | "phone" | "bluesky-replies" | "bluesky-publishing" | "phone-voicemail" | "rss" | "sms-invites";
|
|
111
|
-
label: string;
|
|
112
|
-
enabled: boolean;
|
|
113
|
-
state: "pending" | "error" | "active" | "unconfigured" | "disabled" | "coming-soon";
|
|
114
|
-
direction: "inbound" | "outbound" | "bidirectional";
|
|
115
|
-
alwaysOn: boolean;
|
|
116
|
-
configurable: boolean;
|
|
117
|
-
gated: boolean;
|
|
118
|
-
statusDetail?: string | null | undefined;
|
|
119
|
-
dependsOn?: string | null | undefined;
|
|
120
|
-
}, {
|
|
121
|
-
description: string;
|
|
122
|
-
type: "embed" | "web-capture" | "phone" | "bluesky-replies" | "bluesky-publishing" | "phone-voicemail" | "rss" | "sms-invites";
|
|
123
|
-
label: string;
|
|
124
|
-
enabled: boolean;
|
|
125
|
-
state: "pending" | "error" | "active" | "unconfigured" | "disabled" | "coming-soon";
|
|
126
|
-
direction: "inbound" | "outbound" | "bidirectional";
|
|
127
|
-
alwaysOn: boolean;
|
|
128
|
-
configurable: boolean;
|
|
129
|
-
gated: boolean;
|
|
130
|
-
statusDetail?: string | null | undefined;
|
|
131
|
-
dependsOn?: string | null | undefined;
|
|
132
|
-
}>, "many">;
|
|
133
|
-
outbound: z.ZodArray<z.ZodObject<{
|
|
134
|
-
type: z.ZodEnum<["web-capture", "phone", "bluesky-replies", "bluesky-publishing", "phone-voicemail", "rss", "embed", "sms-invites"]>;
|
|
135
|
-
direction: z.ZodEnum<["inbound", "outbound", "bidirectional"]>;
|
|
136
|
-
/** Human label, e.g. "Phone", "Bluesky publishing". */
|
|
137
|
-
label: z.ZodString;
|
|
138
|
-
/** One-line explanation rendered under the label. */
|
|
139
|
-
description: z.ZodString;
|
|
140
|
-
/** Generic lifecycle state the UI renders as a status pill. */
|
|
141
|
-
state: z.ZodEnum<["active", "pending", "disabled", "unconfigured", "error", "coming-soon"]>;
|
|
142
|
-
/** Channel-specific human detail (e.g. a verification failure reason). */
|
|
143
|
-
statusDetail: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
144
|
-
/** Whether the channel is currently switched on for this user. */
|
|
145
|
-
enabled: z.ZodBoolean;
|
|
146
|
-
/** Always-on surfaces (web capture, RSS, embed) — no real disable. */
|
|
147
|
-
alwaysOn: z.ZodBoolean;
|
|
148
|
-
/** Whether there's a per-channel config screen to open. */
|
|
149
|
-
configurable: z.ZodBoolean;
|
|
150
|
-
/** Requires a paid tier to use (see `docs/feature-gates.md`). */
|
|
151
|
-
gated: z.ZodBoolean;
|
|
152
|
-
/**
|
|
153
|
-
* A prerequisite that must be satisfied elsewhere before this channel works,
|
|
154
|
-
* e.g. `'bluesky-identity'` for Bluesky publishing. Null when self-contained.
|
|
155
|
-
*/
|
|
156
|
-
dependsOn: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
157
|
-
}, "strip", z.ZodTypeAny, {
|
|
158
|
-
description: string;
|
|
159
|
-
type: "embed" | "web-capture" | "phone" | "bluesky-replies" | "bluesky-publishing" | "phone-voicemail" | "rss" | "sms-invites";
|
|
160
|
-
label: string;
|
|
161
|
-
enabled: boolean;
|
|
162
|
-
state: "pending" | "error" | "active" | "unconfigured" | "disabled" | "coming-soon";
|
|
163
|
-
direction: "inbound" | "outbound" | "bidirectional";
|
|
164
|
-
alwaysOn: boolean;
|
|
165
|
-
configurable: boolean;
|
|
166
|
-
gated: boolean;
|
|
167
|
-
statusDetail?: string | null | undefined;
|
|
168
|
-
dependsOn?: string | null | undefined;
|
|
169
|
-
}, {
|
|
170
|
-
description: string;
|
|
171
|
-
type: "embed" | "web-capture" | "phone" | "bluesky-replies" | "bluesky-publishing" | "phone-voicemail" | "rss" | "sms-invites";
|
|
172
|
-
label: string;
|
|
173
|
-
enabled: boolean;
|
|
174
|
-
state: "pending" | "error" | "active" | "unconfigured" | "disabled" | "coming-soon";
|
|
175
|
-
direction: "inbound" | "outbound" | "bidirectional";
|
|
176
|
-
alwaysOn: boolean;
|
|
177
|
-
configurable: boolean;
|
|
178
|
-
gated: boolean;
|
|
179
|
-
statusDetail?: string | null | undefined;
|
|
180
|
-
dependsOn?: string | null | undefined;
|
|
181
|
-
}>, "many">;
|
|
182
|
-
}, "strip", z.ZodTypeAny, {
|
|
183
|
-
inbound: {
|
|
184
|
-
description: string;
|
|
185
|
-
type: "embed" | "web-capture" | "phone" | "bluesky-replies" | "bluesky-publishing" | "phone-voicemail" | "rss" | "sms-invites";
|
|
186
|
-
label: string;
|
|
187
|
-
enabled: boolean;
|
|
188
|
-
state: "pending" | "error" | "active" | "unconfigured" | "disabled" | "coming-soon";
|
|
189
|
-
direction: "inbound" | "outbound" | "bidirectional";
|
|
190
|
-
alwaysOn: boolean;
|
|
191
|
-
configurable: boolean;
|
|
192
|
-
gated: boolean;
|
|
193
|
-
statusDetail?: string | null | undefined;
|
|
194
|
-
dependsOn?: string | null | undefined;
|
|
195
|
-
}[];
|
|
196
|
-
outbound: {
|
|
197
|
-
description: string;
|
|
198
|
-
type: "embed" | "web-capture" | "phone" | "bluesky-replies" | "bluesky-publishing" | "phone-voicemail" | "rss" | "sms-invites";
|
|
199
|
-
label: string;
|
|
200
|
-
enabled: boolean;
|
|
201
|
-
state: "pending" | "error" | "active" | "unconfigured" | "disabled" | "coming-soon";
|
|
202
|
-
direction: "inbound" | "outbound" | "bidirectional";
|
|
203
|
-
alwaysOn: boolean;
|
|
204
|
-
configurable: boolean;
|
|
205
|
-
gated: boolean;
|
|
206
|
-
statusDetail?: string | null | undefined;
|
|
207
|
-
dependsOn?: string | null | undefined;
|
|
208
|
-
}[];
|
|
209
|
-
}, {
|
|
210
|
-
inbound: {
|
|
211
|
-
description: string;
|
|
212
|
-
type: "embed" | "web-capture" | "phone" | "bluesky-replies" | "bluesky-publishing" | "phone-voicemail" | "rss" | "sms-invites";
|
|
213
|
-
label: string;
|
|
214
|
-
enabled: boolean;
|
|
215
|
-
state: "pending" | "error" | "active" | "unconfigured" | "disabled" | "coming-soon";
|
|
216
|
-
direction: "inbound" | "outbound" | "bidirectional";
|
|
217
|
-
alwaysOn: boolean;
|
|
218
|
-
configurable: boolean;
|
|
219
|
-
gated: boolean;
|
|
220
|
-
statusDetail?: string | null | undefined;
|
|
221
|
-
dependsOn?: string | null | undefined;
|
|
222
|
-
}[];
|
|
223
|
-
outbound: {
|
|
224
|
-
description: string;
|
|
225
|
-
type: "embed" | "web-capture" | "phone" | "bluesky-replies" | "bluesky-publishing" | "phone-voicemail" | "rss" | "sms-invites";
|
|
226
|
-
label: string;
|
|
227
|
-
enabled: boolean;
|
|
228
|
-
state: "pending" | "error" | "active" | "unconfigured" | "disabled" | "coming-soon";
|
|
229
|
-
direction: "inbound" | "outbound" | "bidirectional";
|
|
230
|
-
alwaysOn: boolean;
|
|
231
|
-
configurable: boolean;
|
|
232
|
-
gated: boolean;
|
|
233
|
-
statusDetail?: string | null | undefined;
|
|
234
|
-
dependsOn?: string | null | undefined;
|
|
235
|
-
}[];
|
|
236
|
-
}>;
|
|
237
|
-
type ChannelsResponse = z.infer<typeof ChannelsResponseSchema>;
|
|
238
|
-
interface ChannelDescriptor {
|
|
239
|
-
type: ChannelType;
|
|
240
|
-
direction: ChannelDirection;
|
|
241
|
-
label: string;
|
|
242
|
-
description: string;
|
|
243
|
-
/** No stored config; presence-only status row. */
|
|
244
|
-
alwaysOn: boolean;
|
|
245
|
-
/** Has a config screen (Phase 1 surfaces the flag; screens come later). */
|
|
246
|
-
configurable: boolean;
|
|
247
|
-
/** Paid-tier gated. */
|
|
248
|
-
gated: boolean;
|
|
249
|
-
/** Cross-channel prerequisite (rendered as a "needs …" hint). */
|
|
250
|
-
dependsOn: string | null;
|
|
251
|
-
/** Registered but not built yet — forces `state: 'coming-soon'`. */
|
|
252
|
-
comingSoon: boolean;
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* The single source of truth for which channels exist and how they present.
|
|
256
|
-
* Order within each direction is the display order in the settings UI.
|
|
257
|
-
*/
|
|
258
|
-
declare const CHANNEL_DESCRIPTORS: readonly ChannelDescriptor[];
|
|
259
|
-
/** Lookup a descriptor by type. */
|
|
260
|
-
declare function getChannelDescriptor(type: ChannelType): ChannelDescriptor;
|
|
261
|
-
|
|
262
|
-
export { CHANNEL_DESCRIPTORS, type ChannelDescriptor, type ChannelDirection, ChannelDirectionSchema, type ChannelState, ChannelStateSchema, type ChannelType, ChannelTypeSchema, type ChannelView, ChannelViewSchema, type ChannelsResponse, ChannelsResponseSchema, getChannelDescriptor };
|