@fiction/sdk 1.0.18 → 1.0.19

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.
@@ -0,0 +1,92 @@
1
+ import { z } from 'zod'
2
+ import { MediaSchema } from '@/types/media'
3
+
4
+ // Core self schema - define manually for better type control (still using Drizzle as reference)
5
+ export const selfSchema = z.object({
6
+ selfId: z.string().optional(),
7
+ handle: z.string().optional(),
8
+ ownerId: z.string().optional(),
9
+ orgId: z.string().optional(),
10
+ name: z.string().optional(),
11
+ title: z.string().nullable().optional(),
12
+ summary: z.string().nullable().optional(),
13
+ entityType: z.string().optional(),
14
+
15
+ // Media foreign keys and joined objects
16
+ avatarId: z.string().nullable().optional(),
17
+ coverId: z.string().nullable().optional(),
18
+ avatar: MediaSchema.optional(), // Joined MediaObject for UI
19
+ cover: MediaSchema.optional(), // Joined MediaObject for UI
20
+ voiceRecordings: z.array(MediaSchema).optional(), // Joined voice media with context: 'voice'
21
+
22
+ // Contact and social media
23
+ email: z.string().nullable().optional(),
24
+ website: z.string().url().nullable().optional(),
25
+ accounts: z.record(z.string(), z.object({
26
+ handle: z.string().optional(),
27
+ url: z.string().optional(),
28
+ })).nullable().optional(), // Social media accounts: { linkedin?: { handle: string }, x?: { handle: string }, etc. }
29
+
30
+ // AI Configuration
31
+ basePrompt: z.string().nullable().optional(),
32
+ firstMessage: z.string().nullable().optional(),
33
+ personalityPrompt: z.string().nullable().optional(), // AI-generated personality with concise examples
34
+ useCustomPrompts: z.boolean().nullable().optional(), // Boolean flag for custom vs generated prompts
35
+ elevenlabsVoiceId: z.string().nullable().optional(),
36
+ elevenlabsAgentId: z.string().nullable().optional(),
37
+
38
+ // Personality fields
39
+ headline: z.string().nullable().optional(),
40
+ industry: z.string().nullable().optional(),
41
+ location: z.string().nullable().optional(),
42
+ influences: z.array(z.string()).nullable().optional(),
43
+ interests: z.array(z.string()).nullable().optional(),
44
+ personalDetails: z.string().nullable().optional(),
45
+ cloutScore: z.number().nullable().optional(),
46
+
47
+ // Demographics (optional)
48
+ gender: z.string().nullable().optional(),
49
+ birthdayAt: z.string().nullable().optional(), // ISO date string
50
+
51
+ // Business configuration
52
+ businessTemplate: z.string().nullable().optional(),
53
+
54
+ // JSONB fields
55
+ enrichment: z.record(z.string(), z.any()).nullable().optional(),
56
+ onboarding: z.record(z.string(), z.any()).nullable().optional(),
57
+
58
+ // Joined org data - inline type following YAGNI principle
59
+ org: z.object({
60
+ orgId: z.string(),
61
+ handle: z.string(),
62
+ name: z.string(),
63
+ headline: z.string().optional(),
64
+ summary: z.string().optional(),
65
+ status: z.string(),
66
+ }).optional(),
67
+
68
+ // Meta
69
+ visibility: z.enum(['private', 'org', 'public']).optional(),
70
+ status: z.string().optional(),
71
+ createdAt: z.string().optional(), // ISO string for JSON compatibility
72
+ updatedAt: z.string().optional(), // ISO string for JSON compatibility
73
+ })
74
+
75
+ export const EnrichedSelfSchema = selfSchema.extend({
76
+ avatar: MediaSchema.optional(),
77
+ cover: MediaSchema.optional(),
78
+ voiceRecordings: z.array(MediaSchema).optional(),
79
+ isPrimary: z.boolean().optional(), // For selves within org context
80
+ })
81
+
82
+ // Type exports - all derived from Drizzle schema
83
+ export type Self = z.infer<typeof EnrichedSelfSchema>
84
+
85
+ // Create/Update types using the same flexible Self type
86
+ export type CreateSelf = Self
87
+ export type UpdateSelf = Self
88
+
89
+ // AiEnhancement type now imported from onboard/generation.ts
90
+
91
+ // Re-export Drizzle types for database operations
92
+ export type { Self as DrizzleSelf, SelfInsert as DrizzleSelfInsert } from '@/modules/db/tables/schema/selves'
@@ -0,0 +1,139 @@
1
+ import { z } from 'zod'
2
+ import { selfSchema } from '@/modules/self/schema'
3
+ import { MediaSchema } from '@/types/media'
4
+
5
+ export const userSchema = z.object({
6
+ userId: z.string(),
7
+ email: z.string().optional(),
8
+ handle: z.string().optional(),
9
+ fullName: z.string().optional(),
10
+ emailVerified: z.boolean().optional(),
11
+ hashedPassword: z.string().optional(),
12
+ primarySelfId: z.string().optional(),
13
+ onboarding: z.any().optional(),
14
+ recentSelfIds: z.array(z.string()).optional(),
15
+ status: z.string().optional(),
16
+ lastSeenAt: z.string().optional(),
17
+ createdAt: z.string().optional(),
18
+ updatedAt: z.string().optional(),
19
+ onboarded: z.boolean().optional(),
20
+ })
21
+
22
+ export const updateUserSchema = z.object({
23
+ name: z.string().min(1).max(100).optional(),
24
+ primarySelfId: z.string().optional(),
25
+ onboarding: z.any().optional(),
26
+ }).partial()
27
+
28
+ export const emailSchema = z.object({
29
+ email: z.string(),
30
+ })
31
+
32
+ export const loginSchema = z.object({
33
+ email: z.string(),
34
+ password: z.string().min(8, 'Password must be at least 8 characters'),
35
+ })
36
+
37
+ export const registerSchema = z.object({
38
+ email: z.string(),
39
+ password: z.string().min(8, 'Password must be at least 8 characters'),
40
+ fullName: z.string().min(1, 'Name is required'),
41
+ })
42
+
43
+ export const verifyCodeSchema = z.object({
44
+ email: z.string(),
45
+ code: z.string().min(6, 'Verification code is required'),
46
+ })
47
+
48
+ export const resetPasswordSchema = z.object({
49
+ email: z.string(),
50
+ code: z.string().min(6, 'Verification code is required'),
51
+ newPassword: z.string().min(8, 'New password must be at least 8 characters'),
52
+ })
53
+
54
+ export const changeEmailSchema = z.object({
55
+ newEmail: z.string(),
56
+ })
57
+
58
+ export const changePasswordSchema = z.object({
59
+ newPassword: z.string().min(8, 'New password must be at least 8 characters'),
60
+ })
61
+
62
+ export const googleAuthSchema = z.object({
63
+ credential: z.string().optional(),
64
+ code: z.string().optional(),
65
+ createOnEmpty: z.boolean().optional(),
66
+ }).refine((data) => data.credential || data.code, {
67
+ message: 'Either credential or code must be provided',
68
+ })
69
+
70
+ export const orgSchema = z.object({
71
+ orgId: z.string().optional(),
72
+ handle: z.string().optional(),
73
+ name: z.string().optional(),
74
+ email: z.string().optional(),
75
+ website: z.string().url().nullable().optional(),
76
+ summary: z.string().optional(),
77
+ avatarId: z.string().optional(),
78
+ avatar: MediaSchema.optional(),
79
+ coverId: z.string().optional(),
80
+ cover: MediaSchema.optional(),
81
+ accounts: z.record(z.string(), z.object({
82
+ handle: z.string().optional(),
83
+ url: z.string().optional(),
84
+ })).nullable().optional(),
85
+ ownerId: z.string().optional(),
86
+ billingStatus: z.string().optional(),
87
+ isPersonal: z.boolean().optional(),
88
+ stripeCustomerIdTest: z.string().optional(),
89
+ stripeCustomerIdLive: z.string().optional(),
90
+ subscriptionStatus: z.string().optional(),
91
+ planId: z.string().optional(),
92
+ maxSelves: z.number().optional(),
93
+ maxUsers: z.number().optional(),
94
+ onboarding: z.any().optional(),
95
+ status: z.string().optional(),
96
+ createdAt: z.string().optional(),
97
+ updatedAt: z.string().optional(),
98
+ })
99
+
100
+ export type User = z.infer<typeof userSchema>
101
+ export type UpdateUser = z.infer<typeof updateUserSchema>
102
+ export type Org = z.infer<typeof orgSchema>
103
+
104
+ export type { User as DrizzleUser, UserInsert as DrizzleUserInsert } from '@/modules/db/tables/schema/users'
105
+
106
+ export type AuthMode = 'start' | 'pass' | 'verify' | 'set-password' | 'forgot' | 'success'
107
+
108
+ export const orgInfoSchema = z.object({
109
+ membershipId: z.string(),
110
+ orgId: z.string(),
111
+ name: z.string(),
112
+ handle: z.string(),
113
+ avatarId: z.string().optional(),
114
+ avatar: MediaSchema.optional(),
115
+ coverId: z.string().optional(),
116
+ cover: MediaSchema.optional(),
117
+ role: z.enum(['owner', 'admin', 'member', 'observer']),
118
+ joinedAt: z.string(),
119
+ })
120
+
121
+ export const enrichedUserSchema = userSchema.extend({
122
+ orgs: z.array(orgInfoSchema).optional(),
123
+ memberships: z.array(orgInfoSchema).optional(),
124
+ selves: z.array(selfSchema).optional(),
125
+ })
126
+
127
+ export type OrgInfo = z.infer<typeof orgInfoSchema>
128
+ export type MembershipInfo = z.infer<typeof orgInfoSchema> // Alias for OrgInfo
129
+ export type EnrichedUser = z.infer<typeof enrichedUserSchema>
130
+
131
+ export type ApiResponse<T = any> = {
132
+ ok: true
133
+ data: T
134
+ user?: EnrichedUser
135
+ token?: string
136
+ } | {
137
+ ok: false
138
+ error: string
139
+ }
@@ -0,0 +1,106 @@
1
+ import { z } from 'zod'
2
+
3
+ // Core media enums - defined here as single source of truth
4
+ export const MediaFormatSchema = z.enum(['image', 'video', 'audio'])
5
+ export type MediaFormat = z.infer<typeof MediaFormatSchema>
6
+
7
+ export const MediaContextSchema = z.enum(['avatar', 'cover', 'voice', 'general'])
8
+ export type MediaContext = z.infer<typeof MediaContextSchema>
9
+
10
+ export const MediaStatusSchema = z.enum(['processing', 'active', 'failed', 'deleted'])
11
+ export type MediaStatus = z.infer<typeof MediaStatusSchema>
12
+
13
+ // Format-specific enums for file extensions
14
+ export const ImageFormatSchema = z.enum(['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'])
15
+ export type ImageFormat = z.infer<typeof ImageFormatSchema>
16
+
17
+ export const VideoFormatSchema = z.enum(['mp4', 'webm', 'ogg', 'mov', 'avi'])
18
+ export type VideoFormat = z.infer<typeof VideoFormatSchema>
19
+
20
+ export const AudioFormatSchema = z.enum(['mp3', 'wav', 'ogg', 'aac', 'flac'])
21
+ export type AudioFormat = z.infer<typeof AudioFormatSchema>
22
+
23
+ // Base media schema - independent definition
24
+ const baseMediaSchema = z.object({
25
+ mediaId: z.string(),
26
+ userId: z.string(),
27
+ orgId: z.string(),
28
+ selfId: z.string().nullable().optional(),
29
+ filename: z.string(),
30
+ mimeType: z.string(),
31
+ size: z.number(),
32
+ src: z.string(),
33
+ alt: z.string().optional(),
34
+ context: MediaContextSchema.default('general'),
35
+ status: MediaStatusSchema.default('processing'),
36
+ createdAt: z.string().optional(), // ISO string for JSON compatibility
37
+ updatedAt: z.string().optional(), // ISO string for JSON compatibility
38
+ })
39
+
40
+ // Extended MediaObject for UI use - with UI-friendly field names
41
+ export const MediaSchema = baseMediaSchema.extend({
42
+ // Additional UI fields not in database
43
+ format: MediaFormatSchema.optional(), // Derived from mimeType
44
+ className: z.string().optional(), // CSS classes for rendering
45
+
46
+ // Image/video dimensions
47
+ width: z.number().optional(),
48
+ height: z.number().optional(),
49
+
50
+ // Audio/video duration
51
+ duration: z.number().optional(),
52
+
53
+ // Image blur hash for loading placeholders
54
+ blurhash: z.string().optional(),
55
+ }).partial() // Make all fields optional for UI flexibility
56
+
57
+ // Video-specific properties
58
+ export const VideoPropertiesSchema = z.object({
59
+ duration: z.number().optional(), // in seconds
60
+ thumbnail: z.string().optional(),
61
+ autoplay: z.boolean().optional(),
62
+ loop: z.boolean().optional(),
63
+ muted: z.boolean().optional(),
64
+ controls: z.boolean().optional(),
65
+ })
66
+
67
+ // Audio-specific properties
68
+ export const AudioPropertiesSchema = z.object({
69
+ duration: z.number().optional(), // in seconds
70
+ autoplay: z.boolean().optional(),
71
+ loop: z.boolean().optional(),
72
+ muted: z.boolean().optional(),
73
+ controls: z.boolean().optional(),
74
+ })
75
+
76
+ // Extended media schemas with format-specific properties
77
+ export const ImageMediaSchema = MediaSchema.extend({
78
+ format: z.literal('image'),
79
+ imageFormat: ImageFormatSchema,
80
+ })
81
+
82
+ export const VideoMediaSchema = MediaSchema.extend({
83
+ format: z.literal('video'),
84
+ videoFormat: VideoFormatSchema,
85
+ video: VideoPropertiesSchema.optional(),
86
+ })
87
+
88
+ export const AudioMediaSchema = MediaSchema.extend({
89
+ format: z.literal('audio'),
90
+ audioFormat: AudioFormatSchema,
91
+ audio: AudioPropertiesSchema.optional(),
92
+ })
93
+
94
+ // Union type for all media
95
+ export const MediaUnionSchema = z.discriminatedUnion('format', [
96
+ ImageMediaSchema,
97
+ VideoMediaSchema,
98
+ AudioMediaSchema,
99
+ ])
100
+
101
+ // Type exports
102
+ export type MediaObject = z.infer<typeof MediaSchema>
103
+ export type ImageMedia = z.infer<typeof ImageMediaSchema>
104
+ export type VideoMedia = z.infer<typeof VideoMediaSchema>
105
+ export type AudioMedia = z.infer<typeof AudioMediaSchema>
106
+ export type MediaUnion = z.infer<typeof MediaUnionSchema>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiction/sdk",
3
- "version": "1.0.18",
3
+ "version": "1.0.19",
4
4
  "description": "SDK for Fiction app authentication and user management",
5
5
  "type": "module",
6
6
  "main": "./dist/sdk.js",
@@ -54,7 +54,7 @@
54
54
  "nanoid": "^5.1.6",
55
55
  "nanostores": "^1.0.1",
56
56
  "zod": "^4.1.11",
57
- "@fiction/sdk": "1.0.18"
57
+ "@fiction/sdk": "1.0.19"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@antfu/eslint-config": "^5.4.1",