aidol 2.15.0 → 2.16.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/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +23 -16
- package/dist/client.js.map +1 -1
- package/dist/components/group/ChemistryRelationCard.d.ts.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +24 -23
- package/dist/index.js.map +1 -1
- package/dist/repositories/CompanionRelationshipRepository.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChemistryRelationCard.d.ts","sourceRoot":"","sources":["../../../src/components/group/ChemistryRelationCard.tsx"],"names":[],"mappings":"AAMA,UAAU,0BAA0B;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,MAAM,EACN,SAAS,EACT,OAAO,EACP,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,OAAO,GACR,EAAE,0BAA0B,+
|
|
1
|
+
{"version":3,"file":"ChemistryRelationCard.d.ts","sourceRoot":"","sources":["../../../src/components/group/ChemistryRelationCard.tsx"],"names":[],"mappings":"AAMA,UAAU,0BAA0B;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,MAAM,EACN,SAAS,EACT,OAAO,EACP,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,OAAO,GACR,EAAE,0BAA0B,+BAwD5B"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("@aioia/core"),t=require("./relationship-B3AClL0U.js"),l=require("zod");class
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("@aioia/core"),t=require("./relationship-B3AClL0U.js"),l=require("zod");class u extends s.BaseCrudRepository{constructor(){super(...arguments),this.resource="aidols"}getDataSchema(){return t.aidolSchema}async createAIdol(e){const a=this.apiService.buildUrl(this.resource),i=await this.apiService.request(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});return t.aidolCreateResponseSchema.parse(i.data)}async getMy(e){const a=this.apiService.buildUrl(`me/${this.resource}`),i=await this.apiService.request(a,e);return{data:t.aidolSchema.array().parse(i.data)}}async generateImage(e,a){const i=this.apiService.buildUrl(`${this.resource}/images`),o=await this.apiService.request(i,{...a,method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});return this.validateResponse(o,t.imageGenerationResponseSchema)}}const b=l.z.object({messageId:l.z.string(),content:l.z.string()});class y extends s.BaseCrudRepository{constructor(){super(...arguments),this.resource="chatrooms"}getDataSchema(){return t.chatroomSchema}async getMessages(e,a,i){const o=new URLSearchParams;a?.limit!==void 0&&o.set("limit",a.limit.toString()),a?.offset!==void 0&&o.set("offset",a.offset.toString());const r=o.toString(),p=this.apiService.buildUrl(`${this.resource}/${e}/messages${r?`?${r}`:""}`),h=await this.apiService.request(p,i);return this.validateResponse(h,l.z.array(t.messageSchema))}async sendMessage(e,a,i){const o=this.apiService.buildUrl(`${this.resource}/${e}/messages`),r=await this.apiService.request(o,{...i,method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:a,senderType:"USER"})});return this.validateResponse(r,t.messageSchema)}async generateResponse(e,a,i){const o=this.apiService.buildUrl(`${this.resource}/${e}/companions/${a}/response`),r=await this.apiService.request(o,{...i,method:"POST",headers:{"Content-Type":"application/json"}});return this.validateResponse(r,b)}}const c=25;class T extends s.BaseCrudRepository{constructor(){super(...arguments),this.resource="companion-relationships"}getDataSchema(){return t.companionRelationshipSchema}async getByFromCompanionId(e){return this.getList({pagination:{pageSize:c},filters:[{field:"fromCompanionId",operator:"eq",value:e}]})}async deleteOne(e){const a=`${this.apiService.buildUrl(this.resource)}/${e.id}`;return await this.apiService.request(a,{method:"DELETE"}),{data:{}}}}class S extends s.BaseCrudRepository{constructor(){super(...arguments),this.resource="companions"}getDataSchema(){return t.companionSchema}async getByAidolId(e){return this.getList({pagination:{pageSize:c},filters:[{field:"aidolId",operator:"eq",value:e},{field:"status",operator:"eq",value:"PUBLISHED"}]})}async generateImage(e,a){const i=e.prompt.trim();if(!i)throw new Error("promptEmpty");if(i.length>200)throw new Error("promptTooLong");const o=this.apiService.buildUrl(`${this.resource}/images`),r=await this.apiService.request(o,{...a,method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});return this.validateResponse(r,t.imageGenerationResponseSchema)}}class P extends s.BaseCrudRepository{constructor(){super(...arguments),this.resource="aidol-highlights"}getDataSchema(){return t.aidolHighlightSchema}async getByAidolId(e){return this.getList({filters:[{field:"aidolId",operator:"eq",value:e}]})}async getMessages(e,a){const i=this.apiService.buildUrl(`${this.resource}/${e}/messages`),o=await this.apiService.request(i,a);return{data:t.highlightMessageSchema.array().parse(o)}}}class C{constructor(e){this.apiService=e,this.resource="leads"}async create(e){const a=this.apiService.buildUrl(this.resource),i=await this.apiService.request(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});return l.z.object({data:t.leadResponseSchema}).parse(i).data}}const d="aidol_chatroom_ids",f=l.z.record(l.z.string(),l.z.string()),m=()=>{if(typeof window>"u")return{};const n=localStorage.getItem(d);if(!n)return{};try{const e=JSON.parse(n),a=f.safeParse(e);return a.success?a.data:(console.warn("[LocalChatroomIdsRepository] Invalid data, resetting"),{})}catch(e){if(e instanceof SyntaxError)return console.warn("[LocalChatroomIdsRepository] Failed to parse, resetting"),{};throw e}},g=n=>{if(typeof window>"u")throw new Error("LocalChatroomIdsRepository write operations can only be called on the client side.");localStorage.setItem(d,JSON.stringify(n))},R={getChatroomId(n){return m()[n]??null},setChatroomId(n,e){const a=m();a[n]=e,g(a)},removeChatroomId(n){const e=m();delete e[n],g(e)}};function k(n,e,a){if(!n)return a;const o=n.charAt(n.length-1).charCodeAt(0);if(o<44032||o>55203)return a;const r=(o-44032)%28;return e==="으로"&&a==="로"?r===0||r===8?"로":"으로":r===0?a:e}const A={load:{group:"Failed to load group info"}},M={close:"Close",save:"Save",saved:"Saved successfully.",deleted:"Deleted successfully.",error:{save:"Failed to save",load:"Failed to load data"}},v={home:"Home",explore:"Explore",myGroup:"My Group"},N={header:"Position Assignment",title:"Assign positions to each member!",subtitle:"Tap to assign a position",unassigned:"Unassigned",MAIN_VOCAL:"Main Vocal",SUB_VOCAL:"Sub Vocal",MAIN_DANCER:"Main Dancer",SUB_DANCER:"Sub Dancer",MAIN_RAPPER:"Main Rapper",SUB_RAPPER:"Sub Rapper",assignedTo:"{{position}}({{name}})",assign:"Assign",confirm:"Plan Group",needMore:"Assign positions to {{count}} more members",error:{load:"Failed to load members",update:"Failed to assign position"}},I={title:"Debut Member Casting",infoBanner:{title:"Cast your trainees",description:"The idol characters (face, voice, video) in this content are original virtual characters created by AI and are not based on any real person, including idols and celebrities."},tabs:{boy:"Boy Group",girl:"Girl Group",mixed:"Mixed Group"},newMember:{prompt:"Can't find a trainee you like?",subPrompt:"Try casting a new member"},addMember:"New Member",abilities:{title:"Abilities",vocal:"Vocal",dance:"Dance",rap:"Rap",visual:"Visual",stamina:"Stamina",charm:"Charm"},castButton:"Cast",castComplete:{title:"Casting Complete!",description:"The trainee has joined the group",viewBoard:"View Casting Board"},error:{cast:"Failed to cast"}},w="Share",E="URL copied!",L={header:"Final Debut Lineup",title:"My Casted Trainees!",subtitle:"Tap to remove",browse:"Browse Trainees",confirm:"Confirm Debut!",needMore:"Cast {{count}} more to create a group!",delete:"Remove",deleted:"Removed successfully.",empty:{title:`Final Debut Lineup
|
|
2
2
|
is Empty`,description:"Cast your trainees!"},error:{load:"Failed to load members.",delete:"Failed to remove."}},G={title:"Trainee Casting Complete",subtitle:"Added to the casting candidate list",remainingSlots:"Remaining Casting Slots",findNext:"Find Next Trainee",viewBoard:"View Casting Board",error:{load:"Failed to load slot information"}},B={promptPlaceholder:"How does your idol talk? Describe their vibe...",addMember:"Add Member",signed:"Signed 🥺",grade:"Grade {{grade}}",tab:{profile:"Profile",stats:"Stats"},activity:{RESTING:"Resting",PRACTICING:"Practicing",SHORT_BREAK:"Short break",RESTING_AT_HOME:"Resting at home"}},$={notFound:"Group not found",members:"Members",noMembers:"No members yet"},H={groupName:"Group Name",groupNamePlaceholder:"e.g. DREAMERS, STARLIGHT",memberName:"Member Name",memberNamePlaceholder:"e.g. Luna, Kai",concept:"Concept",selectConcept:"Select a concept",personality:"Personality",concepts:{cute:"Cute",cool:"Cool",elegant:"Elegant",powerful:"Powerful"},personalities:{cheerful:{label:"Cheerful",description:"Always bright and positive"},cool:{label:"Cool",description:"Calm and collected"},tsundere:{label:"Tsundere",description:"Cold outside, warm inside"},gentle:{label:"Gentle",description:"Kind and caring"}},step1:"Group",step2:"Members",step3:"Done",step1Title:"Create Your Group",step2Title:"Add Members",groupNameRequired:"Please enter a group name",memberNameRequired:"Please enter a member name",memberRequired:"Please add at least one member",emblem:"Emblem",emblemPromptPlaceholder:"Describe your group's emblem...",emblemRequired:"Please generate an emblem image",generate:"Generate",next:"Next",back:"Back",create:"Create",completeTitle:"Your Idol is Ready!",completeDescription:"Start chatting with your dream idol now",viewProfile:"View Profile"},D={greeting1:"Hello!",greeting2:"We are {{name}}!",greeting3:"Nice to meet you",createAnother:"Create Another Group",share:"Share Profile",banner:"Curious about this group's next move?",error:{load:"Failed to load group info"}},_={header:"Enter Email",previewTitle:`Dorm stories, practice tales
|
|
3
3
|
We'll send you real reviews from members!`,previewMessage:"Shouldn't you talk to your hyung more respectfully?",title:"Stay Updated",description:"Get the latest news and updates about this group via email.",emailLabel:"Email",emailPlaceholder:"example@email.com",submit:"Get Updates",submitting:"Subscribing...",success:"Successfully subscribed!",error:"Failed to subscribe. Please try again."},x={header:"Group Planning",step1Title:"Name your group",step2Title:"Create your group emblem",namePlaceholder:"e.g.) Dreamers, Starlight",promptPlaceholder:"e.g.)",generate:"Generate Image",regenerate:"Regenerate Image",emptyImage:`Generated profile
|
|
4
4
|
image will
|
|
@@ -80,5 +80,5 @@ sắp được mở!`,unlockHint:"Thân hơn với {{name}} để gặp các th
|
|
|
80
80
|
显示`},complete:{nameStepTitle:"叫什么名字?",bioStepTitle:"告诉我们这位偶像的故事",namePlaceholder:"请输入名字",bioPlaceholder:"经历了怎样的时光?",button:"完成选角"}},Tn={header:"我的组合",chatComingSoon:"与成员聊天即将上线👋",settings:"设置",highlights:"精彩集锦",empty:{title:"还没有创建的组合",description:"创建属于你的AI偶像组合吧!",cta:"创建偶像"}},Sn={hero:{title:{line1:"无限可能性的",line2:"偶像团体诞生"},line1:"全球粉丝",line2:"亲自选角并出道",line3:"新人AI偶像团体",line4:"下一代项目",cta:"选拔练习生"},error:{create:"启动失败。"}},Pn={error:{load:"无法加载精彩集锦"}},Cn={title:"第一季出道组",chemistryButton:"成员间默契 💭",followButton:"关注",highlightTab:"精彩集锦",follow:{header:"关注",title:`我们会向您发送
|
|
81
81
|
{{name}}成员们的真实故事!`,previewMessage:"你不应该那样跟哥哥说话吧?",emailPlaceholder:"请输入您的邮箱",submit:"关注并接收动态 ✨",submitting:"订阅中...",success:"关注成功!",error:"关注失败,请重试。",loadError:"加载群组信息失败"},error:{load:"加载群组信息失败"}},fn={infoBanner:{title:"找到你喜欢的组合吧!",description:"本内容中的偶像角色(面部、声音、视频)是由AI制作的原创虚拟人物,不基于任何真实人物,包括偶像和艺人。"},memberCount:"{{count}}人组",error:{load:"无法加载群组列表。"}},Rn={header:"成员间默契",sectionTitle:"成员关系整理",sectionSubtitle:"关系会影响聊天内容!",addRelationship:"添加关系",error:{load:"无法加载成员信息"},add:{header:"添加关系",memberNotFound:"找不到成员。",createRelationshipWith:"创建与{{name}}的关系",selectedMemberPlaceholder:`已选择的
|
|
82
82
|
成员显示`,selectMember:"选择成员",relationshipType:"关系类型",types:{awkward:"还很尴尬",polite:"有礼貌",friendly:"渐渐熟悉",tikitaka:"默契十足",trust:"互相信任",emotional:"情感上的依靠",bestFriend:"最好的朋友",inseparable:"形影不离"},intimacy:"亲密度",startsAt:"从<highlight>{{intimacy}}%</highlight>开始",relationshipNickname:"关系别名",nicknamePlaceholder:"例)同龄组、闺蜜组"}},kn={comingSoon:`与{{name}}的聊天
|
|
83
|
-
即将开放!`,unlockHint:"和{{name}}更亲近就能遇到其他成员 💖",greeting:"和{{name}}自由聊天吧!",placeholder:"输入消息",confirm:"确认",typing:"正在输入...",thinkingLong:"想得有点久了 🥺",reload:"重新加载",resend:"重新发送",time:{justNow:"刚刚",minutesAgo:"{{count}}分钟前",hoursAgo:"{{count}}小时前",am:"上午",pm:"下午",format:"{{period}} {{hour}}:{{minute}}"}},An={error:an,common:tn,navigation:nn,position:on,casting:rn,share:ln,urlCopied:sn,castingBoard:mn,castingComplete:gn,companion:cn,aidol:dn,creation:pn,complete:hn,newsletter:un,groupPlanning:bn,companionCreate:yn,myGroup:Tn,landing:Sn,highlight:Pn,group:Cn,groupList:fn,chemistry:Rn,chat:kn},Mn="aidol",vn={en:z,es:Te,id:je,ja:da,ko:Ha,th:rt,tl:wt,vi:en,zh:An};exports.INTIMACY_TO_RELATIONSHIP_TYPE=t.INTIMACY_TO_RELATIONSHIP_TYPE;exports.RELATIONSHIP_TYPE_TO_INTIMACY=t.RELATIONSHIP_TYPE_TO_INTIMACY;exports.SenderType=t.SenderType;exports.aidolHighlightSchema=t.aidolHighlightSchema;exports.aidolSchema=t.aidolSchema;exports.chatroomSchema=t.chatroomSchema;exports.companionRelationshipSchema=t.companionRelationshipSchema;exports.companionSchema=t.companionSchema;exports.highlightMessageSchema=t.highlightMessageSchema;exports.imageGenerationResponseSchema=t.imageGenerationResponseSchema;exports.isCompanion=t.isCompanion;exports.isUser=t.isUser;exports.messageSchema=t.messageSchema;exports.AIDOL_NS=Mn;exports.AIdolRepository=
|
|
83
|
+
即将开放!`,unlockHint:"和{{name}}更亲近就能遇到其他成员 💖",greeting:"和{{name}}自由聊天吧!",placeholder:"输入消息",confirm:"确认",typing:"正在输入...",thinkingLong:"想得有点久了 🥺",reload:"重新加载",resend:"重新发送",time:{justNow:"刚刚",minutesAgo:"{{count}}分钟前",hoursAgo:"{{count}}小时前",am:"上午",pm:"下午",format:"{{period}} {{hour}}:{{minute}}"}},An={error:an,common:tn,navigation:nn,position:on,casting:rn,share:ln,urlCopied:sn,castingBoard:mn,castingComplete:gn,companion:cn,aidol:dn,creation:pn,complete:hn,newsletter:un,groupPlanning:bn,companionCreate:yn,myGroup:Tn,landing:Sn,highlight:Pn,group:Cn,groupList:fn,chemistry:Rn,chat:kn},Mn="aidol",vn={en:z,es:Te,id:je,ja:da,ko:Ha,th:rt,tl:wt,vi:en,zh:An};exports.INTIMACY_TO_RELATIONSHIP_TYPE=t.INTIMACY_TO_RELATIONSHIP_TYPE;exports.RELATIONSHIP_TYPE_TO_INTIMACY=t.RELATIONSHIP_TYPE_TO_INTIMACY;exports.SenderType=t.SenderType;exports.aidolHighlightSchema=t.aidolHighlightSchema;exports.aidolSchema=t.aidolSchema;exports.chatroomSchema=t.chatroomSchema;exports.companionRelationshipSchema=t.companionRelationshipSchema;exports.companionSchema=t.companionSchema;exports.highlightMessageSchema=t.highlightMessageSchema;exports.imageGenerationResponseSchema=t.imageGenerationResponseSchema;exports.isCompanion=t.isCompanion;exports.isUser=t.isUser;exports.messageSchema=t.messageSchema;exports.AIDOL_NS=Mn;exports.AIdolRepository=u;exports.ChatroomRepository=y;exports.CompanionRelationshipRepository=T;exports.CompanionRepository=S;exports.HighlightRepository=P;exports.LeadsRepository=C;exports.LocalChatroomIdsRepository=R;exports.aidolTranslations=vn;exports.getParticle=k;
|
|
84
84
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/repositories/AIdolRepository.ts","../src/repositories/ChatroomRepository.ts","../src/repositories/CompanionRelationshipRepository.ts","../src/constants/companion.ts","../src/repositories/CompanionRepository.ts","../src/repositories/HighlightRepository.ts","../src/repositories/LeadsRepository.ts","../src/repositories/LocalChatroomIdsRepository.ts","../src/lib/koreanParticle.ts","../src/i18n/translations.ts"],"sourcesContent":["import { BaseCrudRepository } from \"@aioia/core\";\n\nimport type {\n AIdol,\n AIdolCreate,\n AIdolCreateResponse,\n ImageGenerationRequest,\n ImageGenerationResponse,\n} from \"../schemas\";\nimport {\n aidolCreateResponseSchema,\n aidolSchema,\n imageGenerationResponseSchema,\n} from \"../schemas\";\n\nexport class AIdolRepository extends BaseCrudRepository<AIdol> {\n readonly resource = \"aidols\";\n\n protected getDataSchema() {\n return aidolSchema;\n }\n\n async createAIdol(variables: AIdolCreate): Promise<AIdolCreateResponse> {\n const url = this.apiService.buildUrl(this.resource);\n const raw = (await this.apiService.request(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(variables),\n })) as { data: unknown };\n return aidolCreateResponseSchema.parse(raw.data);\n }\n\n async getMy(fetchOptions?: RequestInit): Promise<{ data: AIdol[] }> {\n const url = this.apiService.buildUrl(`me/${this.resource}`);\n const raw = (await this.apiService.request(url, fetchOptions)) as {\n data: unknown[];\n total: number;\n };\n return { data: aidolSchema.array().parse(raw.data) };\n }\n\n async generateImage(\n request: ImageGenerationRequest,\n fetchOptions?: RequestInit,\n ): Promise<ImageGenerationResponse> {\n const url = this.apiService.buildUrl(`${this.resource}/images`);\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n });\n\n return this.validateResponse(rawResponse, imageGenerationResponseSchema);\n }\n}\n","import { BaseCrudRepository } from \"@aioia/core\";\nimport { z } from \"zod\";\n\nimport {\n chatroomSchema,\n messageSchema,\n type Chatroom,\n type Message,\n} from \"../schemas\";\n\n/**\n * Response schema for generate AI response endpoint\n */\nconst generateResponseSchema = z.object({\n messageId: z.string(),\n content: z.string(),\n});\n\nexport interface GenerateResponse {\n messageId: string;\n content: string;\n}\n\n/**\n * Repository for Chatroom entities\n * Handles chatroom CRUD and message operations\n */\nexport class ChatroomRepository extends BaseCrudRepository<Chatroom> {\n readonly resource = \"chatrooms\";\n\n protected getDataSchema() {\n return chatroomSchema;\n }\n\n /**\n * Get messages from a chatroom\n * GET /chatrooms/{id}/messages\n */\n async getMessages(\n chatroomId: string,\n options?: { limit?: number; offset?: number },\n fetchOptions?: RequestInit,\n ): Promise<Message[]> {\n const params = new URLSearchParams();\n if (options?.limit !== undefined) {\n params.set(\"limit\", options.limit.toString());\n }\n if (options?.offset !== undefined) {\n params.set(\"offset\", options.offset.toString());\n }\n\n const queryString = params.toString();\n const url = this.apiService.buildUrl(\n `${this.resource}/${chatroomId}/messages${queryString ? `?${queryString}` : \"\"}`,\n );\n\n const rawResponse = await this.apiService.request(url, fetchOptions);\n return this.validateResponse(rawResponse, z.array(messageSchema));\n }\n\n /**\n * Send a message to a chatroom\n * POST /chatrooms/{id}/messages\n *\n * Anonymous ID is automatically sent via httpOnly cookie.\n *\n * @param chatroomId - The chatroom ID\n * @param content - The message content\n * @param fetchOptions - Optional fetch options\n */\n async sendMessage(\n chatroomId: string,\n content: string,\n fetchOptions?: RequestInit,\n ): Promise<Message> {\n const url = this.apiService.buildUrl(\n `${this.resource}/${chatroomId}/messages`,\n );\n\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ content, senderType: \"USER\" }),\n });\n\n return this.validateResponse(rawResponse, messageSchema);\n }\n\n /**\n * Generate AI response for a chatroom with a specific companion\n * POST /chatrooms/{id}/companions/{companionId}/response\n */\n async generateResponse(\n chatroomId: string,\n companionId: string,\n fetchOptions?: RequestInit,\n ): Promise<GenerateResponse> {\n const url = this.apiService.buildUrl(\n `${this.resource}/${chatroomId}/companions/${companionId}/response`,\n );\n\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n return this.validateResponse(rawResponse, generateResponseSchema);\n }\n}\n","import { BaseCrudRepository } from \"@aioia/core\";\n\nimport type { CompanionRelationship } from \"../schemas\";\nimport { companionRelationshipSchema } from \"../schemas\";\n\nexport class CompanionRelationshipRepository extends BaseCrudRepository<CompanionRelationship> {\n readonly resource = \"companion-relationships\";\n\n protected getDataSchema() {\n return companionRelationshipSchema;\n }\n\n async getByFromCompanionId(fromCompanionId: string) {\n return this.getList({\n filters: [\n { field: \"fromCompanionId\", operator: \"eq\", value: fromCompanionId },\n ],\n });\n }\n\n async deleteOne(params: {\n id: string | number;\n }): Promise<{ data: CompanionRelationship }> {\n const url = `${this.apiService.buildUrl(this.resource)}/${params.id}`;\n await this.apiService.request(url, { method: \"DELETE\" });\n return { data: {} as CompanionRelationship };\n }\n}\n","/** Maximum number of members per aidol group */\nexport const MAX_MEMBERS = 25;\n","import { BaseCrudRepository } from \"@aioia/core\";\n\nimport { MAX_MEMBERS } from \"../constants/companion\";\nimport type {\n Companion,\n ImageGenerationRequest,\n ImageGenerationResponse,\n} from \"../schemas\";\nimport { companionSchema, imageGenerationResponseSchema } from \"../schemas\";\n\n/** CRUD operations use BaseCrudRepository (wrapped { data: T } responses) */\nexport class CompanionRepository extends BaseCrudRepository<Companion> {\n readonly resource = \"companions\";\n\n protected getDataSchema() {\n return companionSchema;\n }\n\n /** PUBLISHED 상태의 멤버만 최대 MAX_MEMBERS명까지 조회 */\n async getByAidolId(aidolId: string) {\n return this.getList({\n pagination: { pageSize: MAX_MEMBERS },\n filters: [\n { field: \"aidolId\", operator: \"eq\", value: aidolId },\n { field: \"status\", operator: \"eq\", value: \"PUBLISHED\" },\n ],\n });\n }\n\n async generateImage(\n request: ImageGenerationRequest,\n fetchOptions?: RequestInit,\n ): Promise<ImageGenerationResponse> {\n const trimmed = request.prompt.trim();\n if (!trimmed) {\n throw new Error(\"promptEmpty\");\n }\n if (trimmed.length > 200) {\n throw new Error(\"promptTooLong\");\n }\n\n const url = this.apiService.buildUrl(`${this.resource}/images`);\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n });\n\n return this.validateResponse(rawResponse, imageGenerationResponseSchema);\n }\n}\n","import { BaseCrudRepository } from \"@aioia/core\";\n\nimport type { AIdolHighlight, HighlightMessage } from \"../schemas\";\nimport { aidolHighlightSchema, highlightMessageSchema } from \"../schemas\";\n\nexport class HighlightRepository extends BaseCrudRepository<AIdolHighlight> {\n readonly resource = \"aidol-highlights\";\n\n protected getDataSchema() {\n return aidolHighlightSchema;\n }\n\n async getByAidolId(aidolId: string) {\n return this.getList({\n filters: [{ field: \"aidolId\", operator: \"eq\", value: aidolId }],\n });\n }\n\n async getMessages(\n highlightId: string,\n fetchOptions?: RequestInit,\n ): Promise<{ data: HighlightMessage[] }> {\n const url = this.apiService.buildUrl(\n `${this.resource}/${highlightId}/messages`,\n );\n const raw = await this.apiService.request(url, fetchOptions);\n return { data: highlightMessageSchema.array().parse(raw) };\n }\n}\n","import { z } from \"zod\";\n\nimport type { LeadRequest, LeadResponse } from \"@/schemas\";\nimport { leadResponseSchema } from \"@/schemas\";\nimport type { ApiService } from \"@/services/ApiService\";\n\nexport class LeadsRepository {\n private readonly resource = \"leads\";\n\n constructor(private readonly apiService: ApiService) {}\n\n async create(request: LeadRequest): Promise<LeadResponse> {\n const url = this.apiService.buildUrl(this.resource);\n const response = await this.apiService.request(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n\n const wrapped = z.object({ data: leadResponseSchema }).parse(response);\n return wrapped.data;\n }\n}\n","import { z } from \"zod\";\n\nconst STORAGE_KEY = \"aidol_chatroom_ids\";\nconst schema = z.record(z.string(), z.string());\n\nconst readStorage = (): Record<string, string> => {\n if (typeof window === \"undefined\") return {};\n\n const stored = localStorage.getItem(STORAGE_KEY);\n if (!stored) return {};\n\n try {\n const parsed = JSON.parse(stored);\n const result = schema.safeParse(parsed);\n if (result.success) {\n return result.data;\n }\n console.warn(`[LocalChatroomIdsRepository] Invalid data, resetting`);\n return {};\n } catch (error) {\n if (error instanceof SyntaxError) {\n console.warn(`[LocalChatroomIdsRepository] Failed to parse, resetting`);\n return {};\n }\n throw error;\n }\n};\n\nconst writeStorage = (data: Record<string, string>): void => {\n if (typeof window === \"undefined\") {\n throw new Error(\n \"LocalChatroomIdsRepository write operations can only be called on the client side.\",\n );\n }\n localStorage.setItem(STORAGE_KEY, JSON.stringify(data));\n};\n\n/**\n * Repository for managing chatroom IDs in localStorage.\n * Maps companionId to chatroomId for persistence across sessions.\n */\nexport const LocalChatroomIdsRepository = {\n getChatroomId(companionId: string): string | null {\n const data = readStorage();\n return data[companionId] ?? null;\n },\n\n setChatroomId(companionId: string, chatroomId: string): void {\n const data = readStorage();\n data[companionId] = chatroomId;\n writeStorage(data);\n },\n\n removeChatroomId(companionId: string): void {\n const data = readStorage();\n delete data[companionId];\n writeStorage(data);\n },\n};\n","// 한글의 마지막 글자를 기준으로 적절한 조사를 반환하는 함수\n// words: 조사 적용 대상 단어\n// withFinalConsonant: 받침이 있을 때 사용할 조사\n// withoutFinalConsonant: 받침이 없을 때 사용할 조사\n// 예: getParticle(\"민준\", \"과\", \"와\") => \"과\"\nexport function getParticle(\n word: string,\n withFinalConsonant: string,\n withoutFinalConsonant: string,\n): string {\n if (!word) return withoutFinalConsonant;\n\n const lastChar = word.charAt(word.length - 1);\n const code = lastChar.charCodeAt(0);\n\n // 한글 유니코드 범위 = 0xAC00 ~ 0xD7A3\n if (code < 0xac00 || code > 0xd7a3) {\n return withoutFinalConsonant;\n }\n\n // 받침 여부 (code - 0xAC00) % 28 !== 0 이면 받침 있음\n const finalConsonantIndex = (code - 0xac00) % 28;\n\n // '로/으로' 예외 처리\n if (withFinalConsonant === \"으로\" && withoutFinalConsonant === \"로\") {\n return finalConsonantIndex === 0 || finalConsonantIndex === 8\n ? \"로\"\n : \"으로\"; // 8 = ㄹ\n }\n\n return finalConsonantIndex === 0 ? withoutFinalConsonant : withFinalConsonant;\n}\n","/**\n * Server-safe exports for aidol translations.\n *\n * This module exports only JSON resources and constants,\n * avoiding React-specific code that would break SSR.\n */\n\nimport en from \"./locales/en/aidol.json\";\nimport es from \"./locales/es/aidol.json\";\nimport id from \"./locales/id/aidol.json\";\nimport ja from \"./locales/ja/aidol.json\";\nimport ko from \"./locales/ko/aidol.json\";\nimport th from \"./locales/th/aidol.json\";\nimport tl from \"./locales/tl/aidol.json\";\nimport vi from \"./locales/vi/aidol.json\";\nimport zh from \"./locales/zh/aidol.json\";\n\n/** AIdol namespace */\nexport const AIDOL_NS = \"aidol\";\n\n/**\n * Translation resources for the aidol namespace.\n * Use with i18next.addResourceBundle(lang, 'aidol', translations)\n *\n * @example\n * import { aidolTranslations, AIDOL_NS } from 'aidol/locale';\n *\n * // Add to existing i18n instance\n * Object.entries(aidolTranslations).forEach(([lang, resources]) => {\n * i18n.addResourceBundle(lang, AIDOL_NS, resources);\n * });\n */\nexport const aidolTranslations = {\n en,\n es,\n id,\n ja,\n ko,\n th,\n tl,\n vi,\n zh,\n};\n"],"names":["AIdolRepository","BaseCrudRepository","aidolSchema","variables","url","raw","aidolCreateResponseSchema","fetchOptions","request","rawResponse","imageGenerationResponseSchema","generateResponseSchema","z","ChatroomRepository","chatroomSchema","chatroomId","options","params","queryString","messageSchema","content","companionId","CompanionRelationshipRepository","companionRelationshipSchema","fromCompanionId","MAX_MEMBERS","CompanionRepository","companionSchema","aidolId","trimmed","HighlightRepository","aidolHighlightSchema","highlightId","highlightMessageSchema","LeadsRepository","apiService","response","leadResponseSchema","STORAGE_KEY","schema","readStorage","stored","parsed","result","error","writeStorage","data","LocalChatroomIdsRepository","getParticle","word","withFinalConsonant","withoutFinalConsonant","code","finalConsonantIndex","AIDOL_NS","aidolTranslations","en","es","id","ja","ko","th","tl","vi","zh"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/repositories/AIdolRepository.ts","../src/repositories/ChatroomRepository.ts","../src/constants/companion.ts","../src/repositories/CompanionRelationshipRepository.ts","../src/repositories/CompanionRepository.ts","../src/repositories/HighlightRepository.ts","../src/repositories/LeadsRepository.ts","../src/repositories/LocalChatroomIdsRepository.ts","../src/lib/koreanParticle.ts","../src/i18n/translations.ts"],"sourcesContent":["import { BaseCrudRepository } from \"@aioia/core\";\n\nimport type {\n AIdol,\n AIdolCreate,\n AIdolCreateResponse,\n ImageGenerationRequest,\n ImageGenerationResponse,\n} from \"../schemas\";\nimport {\n aidolCreateResponseSchema,\n aidolSchema,\n imageGenerationResponseSchema,\n} from \"../schemas\";\n\nexport class AIdolRepository extends BaseCrudRepository<AIdol> {\n readonly resource = \"aidols\";\n\n protected getDataSchema() {\n return aidolSchema;\n }\n\n async createAIdol(variables: AIdolCreate): Promise<AIdolCreateResponse> {\n const url = this.apiService.buildUrl(this.resource);\n const raw = (await this.apiService.request(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(variables),\n })) as { data: unknown };\n return aidolCreateResponseSchema.parse(raw.data);\n }\n\n async getMy(fetchOptions?: RequestInit): Promise<{ data: AIdol[] }> {\n const url = this.apiService.buildUrl(`me/${this.resource}`);\n const raw = (await this.apiService.request(url, fetchOptions)) as {\n data: unknown[];\n total: number;\n };\n return { data: aidolSchema.array().parse(raw.data) };\n }\n\n async generateImage(\n request: ImageGenerationRequest,\n fetchOptions?: RequestInit,\n ): Promise<ImageGenerationResponse> {\n const url = this.apiService.buildUrl(`${this.resource}/images`);\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n });\n\n return this.validateResponse(rawResponse, imageGenerationResponseSchema);\n }\n}\n","import { BaseCrudRepository } from \"@aioia/core\";\nimport { z } from \"zod\";\n\nimport {\n chatroomSchema,\n messageSchema,\n type Chatroom,\n type Message,\n} from \"../schemas\";\n\n/**\n * Response schema for generate AI response endpoint\n */\nconst generateResponseSchema = z.object({\n messageId: z.string(),\n content: z.string(),\n});\n\nexport interface GenerateResponse {\n messageId: string;\n content: string;\n}\n\n/**\n * Repository for Chatroom entities\n * Handles chatroom CRUD and message operations\n */\nexport class ChatroomRepository extends BaseCrudRepository<Chatroom> {\n readonly resource = \"chatrooms\";\n\n protected getDataSchema() {\n return chatroomSchema;\n }\n\n /**\n * Get messages from a chatroom\n * GET /chatrooms/{id}/messages\n */\n async getMessages(\n chatroomId: string,\n options?: { limit?: number; offset?: number },\n fetchOptions?: RequestInit,\n ): Promise<Message[]> {\n const params = new URLSearchParams();\n if (options?.limit !== undefined) {\n params.set(\"limit\", options.limit.toString());\n }\n if (options?.offset !== undefined) {\n params.set(\"offset\", options.offset.toString());\n }\n\n const queryString = params.toString();\n const url = this.apiService.buildUrl(\n `${this.resource}/${chatroomId}/messages${queryString ? `?${queryString}` : \"\"}`,\n );\n\n const rawResponse = await this.apiService.request(url, fetchOptions);\n return this.validateResponse(rawResponse, z.array(messageSchema));\n }\n\n /**\n * Send a message to a chatroom\n * POST /chatrooms/{id}/messages\n *\n * Anonymous ID is automatically sent via httpOnly cookie.\n *\n * @param chatroomId - The chatroom ID\n * @param content - The message content\n * @param fetchOptions - Optional fetch options\n */\n async sendMessage(\n chatroomId: string,\n content: string,\n fetchOptions?: RequestInit,\n ): Promise<Message> {\n const url = this.apiService.buildUrl(\n `${this.resource}/${chatroomId}/messages`,\n );\n\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ content, senderType: \"USER\" }),\n });\n\n return this.validateResponse(rawResponse, messageSchema);\n }\n\n /**\n * Generate AI response for a chatroom with a specific companion\n * POST /chatrooms/{id}/companions/{companionId}/response\n */\n async generateResponse(\n chatroomId: string,\n companionId: string,\n fetchOptions?: RequestInit,\n ): Promise<GenerateResponse> {\n const url = this.apiService.buildUrl(\n `${this.resource}/${chatroomId}/companions/${companionId}/response`,\n );\n\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n return this.validateResponse(rawResponse, generateResponseSchema);\n }\n}\n","/** Maximum number of members per aidol group */\nexport const MAX_MEMBERS = 25;\n","import { BaseCrudRepository } from \"@aioia/core\";\n\nimport { MAX_MEMBERS } from \"../constants/companion\";\nimport type { CompanionRelationship } from \"../schemas\";\nimport { companionRelationshipSchema } from \"../schemas\";\n\nexport class CompanionRelationshipRepository extends BaseCrudRepository<CompanionRelationship> {\n readonly resource = \"companion-relationships\";\n\n protected getDataSchema() {\n return companionRelationshipSchema;\n }\n\n async getByFromCompanionId(fromCompanionId: string) {\n return this.getList({\n pagination: { pageSize: MAX_MEMBERS },\n filters: [\n { field: \"fromCompanionId\", operator: \"eq\", value: fromCompanionId },\n ],\n });\n }\n\n async deleteOne(params: {\n id: string | number;\n }): Promise<{ data: CompanionRelationship }> {\n const url = `${this.apiService.buildUrl(this.resource)}/${params.id}`;\n await this.apiService.request(url, { method: \"DELETE\" });\n return { data: {} as CompanionRelationship };\n }\n}\n","import { BaseCrudRepository } from \"@aioia/core\";\n\nimport { MAX_MEMBERS } from \"../constants/companion\";\nimport type {\n Companion,\n ImageGenerationRequest,\n ImageGenerationResponse,\n} from \"../schemas\";\nimport { companionSchema, imageGenerationResponseSchema } from \"../schemas\";\n\n/** CRUD operations use BaseCrudRepository (wrapped { data: T } responses) */\nexport class CompanionRepository extends BaseCrudRepository<Companion> {\n readonly resource = \"companions\";\n\n protected getDataSchema() {\n return companionSchema;\n }\n\n /** PUBLISHED 상태의 멤버만 최대 MAX_MEMBERS명까지 조회 */\n async getByAidolId(aidolId: string) {\n return this.getList({\n pagination: { pageSize: MAX_MEMBERS },\n filters: [\n { field: \"aidolId\", operator: \"eq\", value: aidolId },\n { field: \"status\", operator: \"eq\", value: \"PUBLISHED\" },\n ],\n });\n }\n\n async generateImage(\n request: ImageGenerationRequest,\n fetchOptions?: RequestInit,\n ): Promise<ImageGenerationResponse> {\n const trimmed = request.prompt.trim();\n if (!trimmed) {\n throw new Error(\"promptEmpty\");\n }\n if (trimmed.length > 200) {\n throw new Error(\"promptTooLong\");\n }\n\n const url = this.apiService.buildUrl(`${this.resource}/images`);\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n });\n\n return this.validateResponse(rawResponse, imageGenerationResponseSchema);\n }\n}\n","import { BaseCrudRepository } from \"@aioia/core\";\n\nimport type { AIdolHighlight, HighlightMessage } from \"../schemas\";\nimport { aidolHighlightSchema, highlightMessageSchema } from \"../schemas\";\n\nexport class HighlightRepository extends BaseCrudRepository<AIdolHighlight> {\n readonly resource = \"aidol-highlights\";\n\n protected getDataSchema() {\n return aidolHighlightSchema;\n }\n\n async getByAidolId(aidolId: string) {\n return this.getList({\n filters: [{ field: \"aidolId\", operator: \"eq\", value: aidolId }],\n });\n }\n\n async getMessages(\n highlightId: string,\n fetchOptions?: RequestInit,\n ): Promise<{ data: HighlightMessage[] }> {\n const url = this.apiService.buildUrl(\n `${this.resource}/${highlightId}/messages`,\n );\n const raw = await this.apiService.request(url, fetchOptions);\n return { data: highlightMessageSchema.array().parse(raw) };\n }\n}\n","import { z } from \"zod\";\n\nimport type { LeadRequest, LeadResponse } from \"@/schemas\";\nimport { leadResponseSchema } from \"@/schemas\";\nimport type { ApiService } from \"@/services/ApiService\";\n\nexport class LeadsRepository {\n private readonly resource = \"leads\";\n\n constructor(private readonly apiService: ApiService) {}\n\n async create(request: LeadRequest): Promise<LeadResponse> {\n const url = this.apiService.buildUrl(this.resource);\n const response = await this.apiService.request(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n\n const wrapped = z.object({ data: leadResponseSchema }).parse(response);\n return wrapped.data;\n }\n}\n","import { z } from \"zod\";\n\nconst STORAGE_KEY = \"aidol_chatroom_ids\";\nconst schema = z.record(z.string(), z.string());\n\nconst readStorage = (): Record<string, string> => {\n if (typeof window === \"undefined\") return {};\n\n const stored = localStorage.getItem(STORAGE_KEY);\n if (!stored) return {};\n\n try {\n const parsed = JSON.parse(stored);\n const result = schema.safeParse(parsed);\n if (result.success) {\n return result.data;\n }\n console.warn(`[LocalChatroomIdsRepository] Invalid data, resetting`);\n return {};\n } catch (error) {\n if (error instanceof SyntaxError) {\n console.warn(`[LocalChatroomIdsRepository] Failed to parse, resetting`);\n return {};\n }\n throw error;\n }\n};\n\nconst writeStorage = (data: Record<string, string>): void => {\n if (typeof window === \"undefined\") {\n throw new Error(\n \"LocalChatroomIdsRepository write operations can only be called on the client side.\",\n );\n }\n localStorage.setItem(STORAGE_KEY, JSON.stringify(data));\n};\n\n/**\n * Repository for managing chatroom IDs in localStorage.\n * Maps companionId to chatroomId for persistence across sessions.\n */\nexport const LocalChatroomIdsRepository = {\n getChatroomId(companionId: string): string | null {\n const data = readStorage();\n return data[companionId] ?? null;\n },\n\n setChatroomId(companionId: string, chatroomId: string): void {\n const data = readStorage();\n data[companionId] = chatroomId;\n writeStorage(data);\n },\n\n removeChatroomId(companionId: string): void {\n const data = readStorage();\n delete data[companionId];\n writeStorage(data);\n },\n};\n","// 한글의 마지막 글자를 기준으로 적절한 조사를 반환하는 함수\n// words: 조사 적용 대상 단어\n// withFinalConsonant: 받침이 있을 때 사용할 조사\n// withoutFinalConsonant: 받침이 없을 때 사용할 조사\n// 예: getParticle(\"민준\", \"과\", \"와\") => \"과\"\nexport function getParticle(\n word: string,\n withFinalConsonant: string,\n withoutFinalConsonant: string,\n): string {\n if (!word) return withoutFinalConsonant;\n\n const lastChar = word.charAt(word.length - 1);\n const code = lastChar.charCodeAt(0);\n\n // 한글 유니코드 범위 = 0xAC00 ~ 0xD7A3\n if (code < 0xac00 || code > 0xd7a3) {\n return withoutFinalConsonant;\n }\n\n // 받침 여부 (code - 0xAC00) % 28 !== 0 이면 받침 있음\n const finalConsonantIndex = (code - 0xac00) % 28;\n\n // '로/으로' 예외 처리\n if (withFinalConsonant === \"으로\" && withoutFinalConsonant === \"로\") {\n return finalConsonantIndex === 0 || finalConsonantIndex === 8\n ? \"로\"\n : \"으로\"; // 8 = ㄹ\n }\n\n return finalConsonantIndex === 0 ? withoutFinalConsonant : withFinalConsonant;\n}\n","/**\n * Server-safe exports for aidol translations.\n *\n * This module exports only JSON resources and constants,\n * avoiding React-specific code that would break SSR.\n */\n\nimport en from \"./locales/en/aidol.json\";\nimport es from \"./locales/es/aidol.json\";\nimport id from \"./locales/id/aidol.json\";\nimport ja from \"./locales/ja/aidol.json\";\nimport ko from \"./locales/ko/aidol.json\";\nimport th from \"./locales/th/aidol.json\";\nimport tl from \"./locales/tl/aidol.json\";\nimport vi from \"./locales/vi/aidol.json\";\nimport zh from \"./locales/zh/aidol.json\";\n\n/** AIdol namespace */\nexport const AIDOL_NS = \"aidol\";\n\n/**\n * Translation resources for the aidol namespace.\n * Use with i18next.addResourceBundle(lang, 'aidol', translations)\n *\n * @example\n * import { aidolTranslations, AIDOL_NS } from 'aidol/locale';\n *\n * // Add to existing i18n instance\n * Object.entries(aidolTranslations).forEach(([lang, resources]) => {\n * i18n.addResourceBundle(lang, AIDOL_NS, resources);\n * });\n */\nexport const aidolTranslations = {\n en,\n es,\n id,\n ja,\n ko,\n th,\n tl,\n vi,\n zh,\n};\n"],"names":["AIdolRepository","BaseCrudRepository","aidolSchema","variables","url","raw","aidolCreateResponseSchema","fetchOptions","request","rawResponse","imageGenerationResponseSchema","generateResponseSchema","z","ChatroomRepository","chatroomSchema","chatroomId","options","params","queryString","messageSchema","content","companionId","MAX_MEMBERS","CompanionRelationshipRepository","companionRelationshipSchema","fromCompanionId","CompanionRepository","companionSchema","aidolId","trimmed","HighlightRepository","aidolHighlightSchema","highlightId","highlightMessageSchema","LeadsRepository","apiService","response","leadResponseSchema","STORAGE_KEY","schema","readStorage","stored","parsed","result","error","writeStorage","data","LocalChatroomIdsRepository","getParticle","word","withFinalConsonant","withoutFinalConsonant","code","finalConsonantIndex","AIDOL_NS","aidolTranslations","en","es","id","ja","ko","th","tl","vi","zh"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseCrudRepository as l } from "@aioia/core";
|
|
2
|
-
import { a as m, b, i as d, c as
|
|
2
|
+
import { a as m, b as y, i as d, c as T, m as g, d as P, e as f, f as S, h as C, l as k } from "./relationship-BP7mIOjL.mjs";
|
|
3
3
|
import { I as jn, R as Vn, S as Un, g as qn, j as On } from "./relationship-BP7mIOjL.mjs";
|
|
4
4
|
import { z as r } from "zod";
|
|
5
5
|
class In extends l {
|
|
@@ -15,7 +15,7 @@ class In extends l {
|
|
|
15
15
|
headers: { "Content-Type": "application/json" },
|
|
16
16
|
body: JSON.stringify(e)
|
|
17
17
|
});
|
|
18
|
-
return
|
|
18
|
+
return y.parse(n.data);
|
|
19
19
|
}
|
|
20
20
|
async getMy(e) {
|
|
21
21
|
const a = this.apiService.buildUrl(`me/${this.resource}`), n = await this.apiService.request(a, e);
|
|
@@ -33,7 +33,7 @@ class In extends l {
|
|
|
33
33
|
return this.validateResponse(i, d);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
const
|
|
36
|
+
const R = r.object({
|
|
37
37
|
messageId: r.string(),
|
|
38
38
|
content: r.string()
|
|
39
39
|
});
|
|
@@ -42,7 +42,7 @@ class En extends l {
|
|
|
42
42
|
super(...arguments), this.resource = "chatrooms";
|
|
43
43
|
}
|
|
44
44
|
getDataSchema() {
|
|
45
|
-
return
|
|
45
|
+
return T;
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
48
|
* Get messages from a chatroom
|
|
@@ -51,10 +51,10 @@ class En extends l {
|
|
|
51
51
|
async getMessages(e, a, n) {
|
|
52
52
|
const i = new URLSearchParams();
|
|
53
53
|
a?.limit !== void 0 && i.set("limit", a.limit.toString()), a?.offset !== void 0 && i.set("offset", a.offset.toString());
|
|
54
|
-
const o = i.toString(),
|
|
54
|
+
const o = i.toString(), u = this.apiService.buildUrl(
|
|
55
55
|
`${this.resource}/${e}/messages${o ? `?${o}` : ""}`
|
|
56
|
-
),
|
|
57
|
-
return this.validateResponse(
|
|
56
|
+
), b = await this.apiService.request(u, n);
|
|
57
|
+
return this.validateResponse(b, r.array(g));
|
|
58
58
|
}
|
|
59
59
|
/**
|
|
60
60
|
* Send a message to a chatroom
|
|
@@ -89,18 +89,20 @@ class En extends l {
|
|
|
89
89
|
method: "POST",
|
|
90
90
|
headers: { "Content-Type": "application/json" }
|
|
91
91
|
});
|
|
92
|
-
return this.validateResponse(o,
|
|
92
|
+
return this.validateResponse(o, R);
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
+
const p = 25;
|
|
95
96
|
class Ln extends l {
|
|
96
97
|
constructor() {
|
|
97
98
|
super(...arguments), this.resource = "companion-relationships";
|
|
98
99
|
}
|
|
99
100
|
getDataSchema() {
|
|
100
|
-
return
|
|
101
|
+
return P;
|
|
101
102
|
}
|
|
102
103
|
async getByFromCompanionId(e) {
|
|
103
104
|
return this.getList({
|
|
105
|
+
pagination: { pageSize: p },
|
|
104
106
|
filters: [
|
|
105
107
|
{ field: "fromCompanionId", operator: "eq", value: e }
|
|
106
108
|
]
|
|
@@ -111,18 +113,17 @@ class Ln extends l {
|
|
|
111
113
|
return await this.apiService.request(a, { method: "DELETE" }), { data: {} };
|
|
112
114
|
}
|
|
113
115
|
}
|
|
114
|
-
const R = 25;
|
|
115
116
|
class Gn extends l {
|
|
116
117
|
constructor() {
|
|
117
118
|
super(...arguments), this.resource = "companions";
|
|
118
119
|
}
|
|
119
120
|
getDataSchema() {
|
|
120
|
-
return
|
|
121
|
+
return f;
|
|
121
122
|
}
|
|
122
123
|
/** PUBLISHED 상태의 멤버만 최대 MAX_MEMBERS명까지 조회 */
|
|
123
124
|
async getByAidolId(e) {
|
|
124
125
|
return this.getList({
|
|
125
|
-
pagination: { pageSize:
|
|
126
|
+
pagination: { pageSize: p },
|
|
126
127
|
filters: [
|
|
127
128
|
{ field: "aidolId", operator: "eq", value: e },
|
|
128
129
|
{ field: "status", operator: "eq", value: "PUBLISHED" }
|
|
@@ -151,7 +152,7 @@ class $n extends l {
|
|
|
151
152
|
super(...arguments), this.resource = "aidol-highlights";
|
|
152
153
|
}
|
|
153
154
|
getDataSchema() {
|
|
154
|
-
return
|
|
155
|
+
return S;
|
|
155
156
|
}
|
|
156
157
|
async getByAidolId(e) {
|
|
157
158
|
return this.getList({
|
|
@@ -162,7 +163,7 @@ class $n extends l {
|
|
|
162
163
|
const n = this.apiService.buildUrl(
|
|
163
164
|
`${this.resource}/${e}/messages`
|
|
164
165
|
), i = await this.apiService.request(n, a);
|
|
165
|
-
return { data:
|
|
166
|
+
return { data: C.array().parse(i) };
|
|
166
167
|
}
|
|
167
168
|
}
|
|
168
169
|
class Bn {
|
|
@@ -175,12 +176,12 @@ class Bn {
|
|
|
175
176
|
headers: { "Content-Type": "application/json" },
|
|
176
177
|
body: JSON.stringify(e)
|
|
177
178
|
});
|
|
178
|
-
return r.object({ data:
|
|
179
|
+
return r.object({ data: k }).parse(n).data;
|
|
179
180
|
}
|
|
180
181
|
}
|
|
181
|
-
const
|
|
182
|
+
const h = "aidol_chatroom_ids", A = r.record(r.string(), r.string()), s = () => {
|
|
182
183
|
if (typeof window > "u") return {};
|
|
183
|
-
const t = localStorage.getItem(
|
|
184
|
+
const t = localStorage.getItem(h);
|
|
184
185
|
if (!t) return {};
|
|
185
186
|
try {
|
|
186
187
|
const e = JSON.parse(t), a = A.safeParse(e);
|
|
@@ -195,7 +196,7 @@ const p = "aidol_chatroom_ids", A = r.record(r.string(), r.string()), s = () =>
|
|
|
195
196
|
throw new Error(
|
|
196
197
|
"LocalChatroomIdsRepository write operations can only be called on the client side."
|
|
197
198
|
);
|
|
198
|
-
localStorage.setItem(
|
|
199
|
+
localStorage.setItem(h, JSON.stringify(t));
|
|
199
200
|
}, Hn = {
|
|
200
201
|
getChatroomId(t) {
|
|
201
202
|
return s()[t] ?? null;
|
|
@@ -538,14 +539,14 @@ export {
|
|
|
538
539
|
Hn as LocalChatroomIdsRepository,
|
|
539
540
|
Vn as RELATIONSHIP_TYPE_TO_INTIMACY,
|
|
540
541
|
Un as SenderType,
|
|
541
|
-
|
|
542
|
+
S as aidolHighlightSchema,
|
|
542
543
|
m as aidolSchema,
|
|
543
544
|
_n as aidolTranslations,
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
545
|
+
T as chatroomSchema,
|
|
546
|
+
P as companionRelationshipSchema,
|
|
547
|
+
f as companionSchema,
|
|
547
548
|
Dn as getParticle,
|
|
548
|
-
|
|
549
|
+
C as highlightMessageSchema,
|
|
549
550
|
d as imageGenerationResponseSchema,
|
|
550
551
|
qn as isCompanion,
|
|
551
552
|
On as isUser,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/repositories/AIdolRepository.ts","../src/repositories/ChatroomRepository.ts","../src/repositories/CompanionRelationshipRepository.ts","../src/constants/companion.ts","../src/repositories/CompanionRepository.ts","../src/repositories/HighlightRepository.ts","../src/repositories/LeadsRepository.ts","../src/repositories/LocalChatroomIdsRepository.ts","../src/lib/koreanParticle.ts","../src/i18n/translations.ts"],"sourcesContent":["import { BaseCrudRepository } from \"@aioia/core\";\n\nimport type {\n AIdol,\n AIdolCreate,\n AIdolCreateResponse,\n ImageGenerationRequest,\n ImageGenerationResponse,\n} from \"../schemas\";\nimport {\n aidolCreateResponseSchema,\n aidolSchema,\n imageGenerationResponseSchema,\n} from \"../schemas\";\n\nexport class AIdolRepository extends BaseCrudRepository<AIdol> {\n readonly resource = \"aidols\";\n\n protected getDataSchema() {\n return aidolSchema;\n }\n\n async createAIdol(variables: AIdolCreate): Promise<AIdolCreateResponse> {\n const url = this.apiService.buildUrl(this.resource);\n const raw = (await this.apiService.request(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(variables),\n })) as { data: unknown };\n return aidolCreateResponseSchema.parse(raw.data);\n }\n\n async getMy(fetchOptions?: RequestInit): Promise<{ data: AIdol[] }> {\n const url = this.apiService.buildUrl(`me/${this.resource}`);\n const raw = (await this.apiService.request(url, fetchOptions)) as {\n data: unknown[];\n total: number;\n };\n return { data: aidolSchema.array().parse(raw.data) };\n }\n\n async generateImage(\n request: ImageGenerationRequest,\n fetchOptions?: RequestInit,\n ): Promise<ImageGenerationResponse> {\n const url = this.apiService.buildUrl(`${this.resource}/images`);\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n });\n\n return this.validateResponse(rawResponse, imageGenerationResponseSchema);\n }\n}\n","import { BaseCrudRepository } from \"@aioia/core\";\nimport { z } from \"zod\";\n\nimport {\n chatroomSchema,\n messageSchema,\n type Chatroom,\n type Message,\n} from \"../schemas\";\n\n/**\n * Response schema for generate AI response endpoint\n */\nconst generateResponseSchema = z.object({\n messageId: z.string(),\n content: z.string(),\n});\n\nexport interface GenerateResponse {\n messageId: string;\n content: string;\n}\n\n/**\n * Repository for Chatroom entities\n * Handles chatroom CRUD and message operations\n */\nexport class ChatroomRepository extends BaseCrudRepository<Chatroom> {\n readonly resource = \"chatrooms\";\n\n protected getDataSchema() {\n return chatroomSchema;\n }\n\n /**\n * Get messages from a chatroom\n * GET /chatrooms/{id}/messages\n */\n async getMessages(\n chatroomId: string,\n options?: { limit?: number; offset?: number },\n fetchOptions?: RequestInit,\n ): Promise<Message[]> {\n const params = new URLSearchParams();\n if (options?.limit !== undefined) {\n params.set(\"limit\", options.limit.toString());\n }\n if (options?.offset !== undefined) {\n params.set(\"offset\", options.offset.toString());\n }\n\n const queryString = params.toString();\n const url = this.apiService.buildUrl(\n `${this.resource}/${chatroomId}/messages${queryString ? `?${queryString}` : \"\"}`,\n );\n\n const rawResponse = await this.apiService.request(url, fetchOptions);\n return this.validateResponse(rawResponse, z.array(messageSchema));\n }\n\n /**\n * Send a message to a chatroom\n * POST /chatrooms/{id}/messages\n *\n * Anonymous ID is automatically sent via httpOnly cookie.\n *\n * @param chatroomId - The chatroom ID\n * @param content - The message content\n * @param fetchOptions - Optional fetch options\n */\n async sendMessage(\n chatroomId: string,\n content: string,\n fetchOptions?: RequestInit,\n ): Promise<Message> {\n const url = this.apiService.buildUrl(\n `${this.resource}/${chatroomId}/messages`,\n );\n\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ content, senderType: \"USER\" }),\n });\n\n return this.validateResponse(rawResponse, messageSchema);\n }\n\n /**\n * Generate AI response for a chatroom with a specific companion\n * POST /chatrooms/{id}/companions/{companionId}/response\n */\n async generateResponse(\n chatroomId: string,\n companionId: string,\n fetchOptions?: RequestInit,\n ): Promise<GenerateResponse> {\n const url = this.apiService.buildUrl(\n `${this.resource}/${chatroomId}/companions/${companionId}/response`,\n );\n\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n return this.validateResponse(rawResponse, generateResponseSchema);\n }\n}\n","import { BaseCrudRepository } from \"@aioia/core\";\n\nimport type { CompanionRelationship } from \"../schemas\";\nimport { companionRelationshipSchema } from \"../schemas\";\n\nexport class CompanionRelationshipRepository extends BaseCrudRepository<CompanionRelationship> {\n readonly resource = \"companion-relationships\";\n\n protected getDataSchema() {\n return companionRelationshipSchema;\n }\n\n async getByFromCompanionId(fromCompanionId: string) {\n return this.getList({\n filters: [\n { field: \"fromCompanionId\", operator: \"eq\", value: fromCompanionId },\n ],\n });\n }\n\n async deleteOne(params: {\n id: string | number;\n }): Promise<{ data: CompanionRelationship }> {\n const url = `${this.apiService.buildUrl(this.resource)}/${params.id}`;\n await this.apiService.request(url, { method: \"DELETE\" });\n return { data: {} as CompanionRelationship };\n }\n}\n","/** Maximum number of members per aidol group */\nexport const MAX_MEMBERS = 25;\n","import { BaseCrudRepository } from \"@aioia/core\";\n\nimport { MAX_MEMBERS } from \"../constants/companion\";\nimport type {\n Companion,\n ImageGenerationRequest,\n ImageGenerationResponse,\n} from \"../schemas\";\nimport { companionSchema, imageGenerationResponseSchema } from \"../schemas\";\n\n/** CRUD operations use BaseCrudRepository (wrapped { data: T } responses) */\nexport class CompanionRepository extends BaseCrudRepository<Companion> {\n readonly resource = \"companions\";\n\n protected getDataSchema() {\n return companionSchema;\n }\n\n /** PUBLISHED 상태의 멤버만 최대 MAX_MEMBERS명까지 조회 */\n async getByAidolId(aidolId: string) {\n return this.getList({\n pagination: { pageSize: MAX_MEMBERS },\n filters: [\n { field: \"aidolId\", operator: \"eq\", value: aidolId },\n { field: \"status\", operator: \"eq\", value: \"PUBLISHED\" },\n ],\n });\n }\n\n async generateImage(\n request: ImageGenerationRequest,\n fetchOptions?: RequestInit,\n ): Promise<ImageGenerationResponse> {\n const trimmed = request.prompt.trim();\n if (!trimmed) {\n throw new Error(\"promptEmpty\");\n }\n if (trimmed.length > 200) {\n throw new Error(\"promptTooLong\");\n }\n\n const url = this.apiService.buildUrl(`${this.resource}/images`);\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n });\n\n return this.validateResponse(rawResponse, imageGenerationResponseSchema);\n }\n}\n","import { BaseCrudRepository } from \"@aioia/core\";\n\nimport type { AIdolHighlight, HighlightMessage } from \"../schemas\";\nimport { aidolHighlightSchema, highlightMessageSchema } from \"../schemas\";\n\nexport class HighlightRepository extends BaseCrudRepository<AIdolHighlight> {\n readonly resource = \"aidol-highlights\";\n\n protected getDataSchema() {\n return aidolHighlightSchema;\n }\n\n async getByAidolId(aidolId: string) {\n return this.getList({\n filters: [{ field: \"aidolId\", operator: \"eq\", value: aidolId }],\n });\n }\n\n async getMessages(\n highlightId: string,\n fetchOptions?: RequestInit,\n ): Promise<{ data: HighlightMessage[] }> {\n const url = this.apiService.buildUrl(\n `${this.resource}/${highlightId}/messages`,\n );\n const raw = await this.apiService.request(url, fetchOptions);\n return { data: highlightMessageSchema.array().parse(raw) };\n }\n}\n","import { z } from \"zod\";\n\nimport type { LeadRequest, LeadResponse } from \"@/schemas\";\nimport { leadResponseSchema } from \"@/schemas\";\nimport type { ApiService } from \"@/services/ApiService\";\n\nexport class LeadsRepository {\n private readonly resource = \"leads\";\n\n constructor(private readonly apiService: ApiService) {}\n\n async create(request: LeadRequest): Promise<LeadResponse> {\n const url = this.apiService.buildUrl(this.resource);\n const response = await this.apiService.request(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n\n const wrapped = z.object({ data: leadResponseSchema }).parse(response);\n return wrapped.data;\n }\n}\n","import { z } from \"zod\";\n\nconst STORAGE_KEY = \"aidol_chatroom_ids\";\nconst schema = z.record(z.string(), z.string());\n\nconst readStorage = (): Record<string, string> => {\n if (typeof window === \"undefined\") return {};\n\n const stored = localStorage.getItem(STORAGE_KEY);\n if (!stored) return {};\n\n try {\n const parsed = JSON.parse(stored);\n const result = schema.safeParse(parsed);\n if (result.success) {\n return result.data;\n }\n console.warn(`[LocalChatroomIdsRepository] Invalid data, resetting`);\n return {};\n } catch (error) {\n if (error instanceof SyntaxError) {\n console.warn(`[LocalChatroomIdsRepository] Failed to parse, resetting`);\n return {};\n }\n throw error;\n }\n};\n\nconst writeStorage = (data: Record<string, string>): void => {\n if (typeof window === \"undefined\") {\n throw new Error(\n \"LocalChatroomIdsRepository write operations can only be called on the client side.\",\n );\n }\n localStorage.setItem(STORAGE_KEY, JSON.stringify(data));\n};\n\n/**\n * Repository for managing chatroom IDs in localStorage.\n * Maps companionId to chatroomId for persistence across sessions.\n */\nexport const LocalChatroomIdsRepository = {\n getChatroomId(companionId: string): string | null {\n const data = readStorage();\n return data[companionId] ?? null;\n },\n\n setChatroomId(companionId: string, chatroomId: string): void {\n const data = readStorage();\n data[companionId] = chatroomId;\n writeStorage(data);\n },\n\n removeChatroomId(companionId: string): void {\n const data = readStorage();\n delete data[companionId];\n writeStorage(data);\n },\n};\n","// 한글의 마지막 글자를 기준으로 적절한 조사를 반환하는 함수\n// words: 조사 적용 대상 단어\n// withFinalConsonant: 받침이 있을 때 사용할 조사\n// withoutFinalConsonant: 받침이 없을 때 사용할 조사\n// 예: getParticle(\"민준\", \"과\", \"와\") => \"과\"\nexport function getParticle(\n word: string,\n withFinalConsonant: string,\n withoutFinalConsonant: string,\n): string {\n if (!word) return withoutFinalConsonant;\n\n const lastChar = word.charAt(word.length - 1);\n const code = lastChar.charCodeAt(0);\n\n // 한글 유니코드 범위 = 0xAC00 ~ 0xD7A3\n if (code < 0xac00 || code > 0xd7a3) {\n return withoutFinalConsonant;\n }\n\n // 받침 여부 (code - 0xAC00) % 28 !== 0 이면 받침 있음\n const finalConsonantIndex = (code - 0xac00) % 28;\n\n // '로/으로' 예외 처리\n if (withFinalConsonant === \"으로\" && withoutFinalConsonant === \"로\") {\n return finalConsonantIndex === 0 || finalConsonantIndex === 8\n ? \"로\"\n : \"으로\"; // 8 = ㄹ\n }\n\n return finalConsonantIndex === 0 ? withoutFinalConsonant : withFinalConsonant;\n}\n","/**\n * Server-safe exports for aidol translations.\n *\n * This module exports only JSON resources and constants,\n * avoiding React-specific code that would break SSR.\n */\n\nimport en from \"./locales/en/aidol.json\";\nimport es from \"./locales/es/aidol.json\";\nimport id from \"./locales/id/aidol.json\";\nimport ja from \"./locales/ja/aidol.json\";\nimport ko from \"./locales/ko/aidol.json\";\nimport th from \"./locales/th/aidol.json\";\nimport tl from \"./locales/tl/aidol.json\";\nimport vi from \"./locales/vi/aidol.json\";\nimport zh from \"./locales/zh/aidol.json\";\n\n/** AIdol namespace */\nexport const AIDOL_NS = \"aidol\";\n\n/**\n * Translation resources for the aidol namespace.\n * Use with i18next.addResourceBundle(lang, 'aidol', translations)\n *\n * @example\n * import { aidolTranslations, AIDOL_NS } from 'aidol/locale';\n *\n * // Add to existing i18n instance\n * Object.entries(aidolTranslations).forEach(([lang, resources]) => {\n * i18n.addResourceBundle(lang, AIDOL_NS, resources);\n * });\n */\nexport const aidolTranslations = {\n en,\n es,\n id,\n ja,\n ko,\n th,\n tl,\n vi,\n zh,\n};\n"],"names":["AIdolRepository","BaseCrudRepository","aidolSchema","variables","url","raw","aidolCreateResponseSchema","fetchOptions","request","rawResponse","imageGenerationResponseSchema","generateResponseSchema","z","ChatroomRepository","chatroomSchema","chatroomId","options","params","queryString","messageSchema","content","companionId","CompanionRelationshipRepository","companionRelationshipSchema","fromCompanionId","MAX_MEMBERS","CompanionRepository","companionSchema","aidolId","trimmed","HighlightRepository","aidolHighlightSchema","highlightId","highlightMessageSchema","LeadsRepository","apiService","response","leadResponseSchema","STORAGE_KEY","schema","readStorage","stored","parsed","result","error","writeStorage","data","LocalChatroomIdsRepository","getParticle","word","withFinalConsonant","withoutFinalConsonant","code","finalConsonantIndex","AIDOL_NS","aidolTranslations","en","es","id","ja","ko","th","tl","vi","zh"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/repositories/AIdolRepository.ts","../src/repositories/ChatroomRepository.ts","../src/constants/companion.ts","../src/repositories/CompanionRelationshipRepository.ts","../src/repositories/CompanionRepository.ts","../src/repositories/HighlightRepository.ts","../src/repositories/LeadsRepository.ts","../src/repositories/LocalChatroomIdsRepository.ts","../src/lib/koreanParticle.ts","../src/i18n/translations.ts"],"sourcesContent":["import { BaseCrudRepository } from \"@aioia/core\";\n\nimport type {\n AIdol,\n AIdolCreate,\n AIdolCreateResponse,\n ImageGenerationRequest,\n ImageGenerationResponse,\n} from \"../schemas\";\nimport {\n aidolCreateResponseSchema,\n aidolSchema,\n imageGenerationResponseSchema,\n} from \"../schemas\";\n\nexport class AIdolRepository extends BaseCrudRepository<AIdol> {\n readonly resource = \"aidols\";\n\n protected getDataSchema() {\n return aidolSchema;\n }\n\n async createAIdol(variables: AIdolCreate): Promise<AIdolCreateResponse> {\n const url = this.apiService.buildUrl(this.resource);\n const raw = (await this.apiService.request(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(variables),\n })) as { data: unknown };\n return aidolCreateResponseSchema.parse(raw.data);\n }\n\n async getMy(fetchOptions?: RequestInit): Promise<{ data: AIdol[] }> {\n const url = this.apiService.buildUrl(`me/${this.resource}`);\n const raw = (await this.apiService.request(url, fetchOptions)) as {\n data: unknown[];\n total: number;\n };\n return { data: aidolSchema.array().parse(raw.data) };\n }\n\n async generateImage(\n request: ImageGenerationRequest,\n fetchOptions?: RequestInit,\n ): Promise<ImageGenerationResponse> {\n const url = this.apiService.buildUrl(`${this.resource}/images`);\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n });\n\n return this.validateResponse(rawResponse, imageGenerationResponseSchema);\n }\n}\n","import { BaseCrudRepository } from \"@aioia/core\";\nimport { z } from \"zod\";\n\nimport {\n chatroomSchema,\n messageSchema,\n type Chatroom,\n type Message,\n} from \"../schemas\";\n\n/**\n * Response schema for generate AI response endpoint\n */\nconst generateResponseSchema = z.object({\n messageId: z.string(),\n content: z.string(),\n});\n\nexport interface GenerateResponse {\n messageId: string;\n content: string;\n}\n\n/**\n * Repository for Chatroom entities\n * Handles chatroom CRUD and message operations\n */\nexport class ChatroomRepository extends BaseCrudRepository<Chatroom> {\n readonly resource = \"chatrooms\";\n\n protected getDataSchema() {\n return chatroomSchema;\n }\n\n /**\n * Get messages from a chatroom\n * GET /chatrooms/{id}/messages\n */\n async getMessages(\n chatroomId: string,\n options?: { limit?: number; offset?: number },\n fetchOptions?: RequestInit,\n ): Promise<Message[]> {\n const params = new URLSearchParams();\n if (options?.limit !== undefined) {\n params.set(\"limit\", options.limit.toString());\n }\n if (options?.offset !== undefined) {\n params.set(\"offset\", options.offset.toString());\n }\n\n const queryString = params.toString();\n const url = this.apiService.buildUrl(\n `${this.resource}/${chatroomId}/messages${queryString ? `?${queryString}` : \"\"}`,\n );\n\n const rawResponse = await this.apiService.request(url, fetchOptions);\n return this.validateResponse(rawResponse, z.array(messageSchema));\n }\n\n /**\n * Send a message to a chatroom\n * POST /chatrooms/{id}/messages\n *\n * Anonymous ID is automatically sent via httpOnly cookie.\n *\n * @param chatroomId - The chatroom ID\n * @param content - The message content\n * @param fetchOptions - Optional fetch options\n */\n async sendMessage(\n chatroomId: string,\n content: string,\n fetchOptions?: RequestInit,\n ): Promise<Message> {\n const url = this.apiService.buildUrl(\n `${this.resource}/${chatroomId}/messages`,\n );\n\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ content, senderType: \"USER\" }),\n });\n\n return this.validateResponse(rawResponse, messageSchema);\n }\n\n /**\n * Generate AI response for a chatroom with a specific companion\n * POST /chatrooms/{id}/companions/{companionId}/response\n */\n async generateResponse(\n chatroomId: string,\n companionId: string,\n fetchOptions?: RequestInit,\n ): Promise<GenerateResponse> {\n const url = this.apiService.buildUrl(\n `${this.resource}/${chatroomId}/companions/${companionId}/response`,\n );\n\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n return this.validateResponse(rawResponse, generateResponseSchema);\n }\n}\n","/** Maximum number of members per aidol group */\nexport const MAX_MEMBERS = 25;\n","import { BaseCrudRepository } from \"@aioia/core\";\n\nimport { MAX_MEMBERS } from \"../constants/companion\";\nimport type { CompanionRelationship } from \"../schemas\";\nimport { companionRelationshipSchema } from \"../schemas\";\n\nexport class CompanionRelationshipRepository extends BaseCrudRepository<CompanionRelationship> {\n readonly resource = \"companion-relationships\";\n\n protected getDataSchema() {\n return companionRelationshipSchema;\n }\n\n async getByFromCompanionId(fromCompanionId: string) {\n return this.getList({\n pagination: { pageSize: MAX_MEMBERS },\n filters: [\n { field: \"fromCompanionId\", operator: \"eq\", value: fromCompanionId },\n ],\n });\n }\n\n async deleteOne(params: {\n id: string | number;\n }): Promise<{ data: CompanionRelationship }> {\n const url = `${this.apiService.buildUrl(this.resource)}/${params.id}`;\n await this.apiService.request(url, { method: \"DELETE\" });\n return { data: {} as CompanionRelationship };\n }\n}\n","import { BaseCrudRepository } from \"@aioia/core\";\n\nimport { MAX_MEMBERS } from \"../constants/companion\";\nimport type {\n Companion,\n ImageGenerationRequest,\n ImageGenerationResponse,\n} from \"../schemas\";\nimport { companionSchema, imageGenerationResponseSchema } from \"../schemas\";\n\n/** CRUD operations use BaseCrudRepository (wrapped { data: T } responses) */\nexport class CompanionRepository extends BaseCrudRepository<Companion> {\n readonly resource = \"companions\";\n\n protected getDataSchema() {\n return companionSchema;\n }\n\n /** PUBLISHED 상태의 멤버만 최대 MAX_MEMBERS명까지 조회 */\n async getByAidolId(aidolId: string) {\n return this.getList({\n pagination: { pageSize: MAX_MEMBERS },\n filters: [\n { field: \"aidolId\", operator: \"eq\", value: aidolId },\n { field: \"status\", operator: \"eq\", value: \"PUBLISHED\" },\n ],\n });\n }\n\n async generateImage(\n request: ImageGenerationRequest,\n fetchOptions?: RequestInit,\n ): Promise<ImageGenerationResponse> {\n const trimmed = request.prompt.trim();\n if (!trimmed) {\n throw new Error(\"promptEmpty\");\n }\n if (trimmed.length > 200) {\n throw new Error(\"promptTooLong\");\n }\n\n const url = this.apiService.buildUrl(`${this.resource}/images`);\n const rawResponse = await this.apiService.request(url, {\n ...fetchOptions,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n });\n\n return this.validateResponse(rawResponse, imageGenerationResponseSchema);\n }\n}\n","import { BaseCrudRepository } from \"@aioia/core\";\n\nimport type { AIdolHighlight, HighlightMessage } from \"../schemas\";\nimport { aidolHighlightSchema, highlightMessageSchema } from \"../schemas\";\n\nexport class HighlightRepository extends BaseCrudRepository<AIdolHighlight> {\n readonly resource = \"aidol-highlights\";\n\n protected getDataSchema() {\n return aidolHighlightSchema;\n }\n\n async getByAidolId(aidolId: string) {\n return this.getList({\n filters: [{ field: \"aidolId\", operator: \"eq\", value: aidolId }],\n });\n }\n\n async getMessages(\n highlightId: string,\n fetchOptions?: RequestInit,\n ): Promise<{ data: HighlightMessage[] }> {\n const url = this.apiService.buildUrl(\n `${this.resource}/${highlightId}/messages`,\n );\n const raw = await this.apiService.request(url, fetchOptions);\n return { data: highlightMessageSchema.array().parse(raw) };\n }\n}\n","import { z } from \"zod\";\n\nimport type { LeadRequest, LeadResponse } from \"@/schemas\";\nimport { leadResponseSchema } from \"@/schemas\";\nimport type { ApiService } from \"@/services/ApiService\";\n\nexport class LeadsRepository {\n private readonly resource = \"leads\";\n\n constructor(private readonly apiService: ApiService) {}\n\n async create(request: LeadRequest): Promise<LeadResponse> {\n const url = this.apiService.buildUrl(this.resource);\n const response = await this.apiService.request(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(request),\n });\n\n const wrapped = z.object({ data: leadResponseSchema }).parse(response);\n return wrapped.data;\n }\n}\n","import { z } from \"zod\";\n\nconst STORAGE_KEY = \"aidol_chatroom_ids\";\nconst schema = z.record(z.string(), z.string());\n\nconst readStorage = (): Record<string, string> => {\n if (typeof window === \"undefined\") return {};\n\n const stored = localStorage.getItem(STORAGE_KEY);\n if (!stored) return {};\n\n try {\n const parsed = JSON.parse(stored);\n const result = schema.safeParse(parsed);\n if (result.success) {\n return result.data;\n }\n console.warn(`[LocalChatroomIdsRepository] Invalid data, resetting`);\n return {};\n } catch (error) {\n if (error instanceof SyntaxError) {\n console.warn(`[LocalChatroomIdsRepository] Failed to parse, resetting`);\n return {};\n }\n throw error;\n }\n};\n\nconst writeStorage = (data: Record<string, string>): void => {\n if (typeof window === \"undefined\") {\n throw new Error(\n \"LocalChatroomIdsRepository write operations can only be called on the client side.\",\n );\n }\n localStorage.setItem(STORAGE_KEY, JSON.stringify(data));\n};\n\n/**\n * Repository for managing chatroom IDs in localStorage.\n * Maps companionId to chatroomId for persistence across sessions.\n */\nexport const LocalChatroomIdsRepository = {\n getChatroomId(companionId: string): string | null {\n const data = readStorage();\n return data[companionId] ?? null;\n },\n\n setChatroomId(companionId: string, chatroomId: string): void {\n const data = readStorage();\n data[companionId] = chatroomId;\n writeStorage(data);\n },\n\n removeChatroomId(companionId: string): void {\n const data = readStorage();\n delete data[companionId];\n writeStorage(data);\n },\n};\n","// 한글의 마지막 글자를 기준으로 적절한 조사를 반환하는 함수\n// words: 조사 적용 대상 단어\n// withFinalConsonant: 받침이 있을 때 사용할 조사\n// withoutFinalConsonant: 받침이 없을 때 사용할 조사\n// 예: getParticle(\"민준\", \"과\", \"와\") => \"과\"\nexport function getParticle(\n word: string,\n withFinalConsonant: string,\n withoutFinalConsonant: string,\n): string {\n if (!word) return withoutFinalConsonant;\n\n const lastChar = word.charAt(word.length - 1);\n const code = lastChar.charCodeAt(0);\n\n // 한글 유니코드 범위 = 0xAC00 ~ 0xD7A3\n if (code < 0xac00 || code > 0xd7a3) {\n return withoutFinalConsonant;\n }\n\n // 받침 여부 (code - 0xAC00) % 28 !== 0 이면 받침 있음\n const finalConsonantIndex = (code - 0xac00) % 28;\n\n // '로/으로' 예외 처리\n if (withFinalConsonant === \"으로\" && withoutFinalConsonant === \"로\") {\n return finalConsonantIndex === 0 || finalConsonantIndex === 8\n ? \"로\"\n : \"으로\"; // 8 = ㄹ\n }\n\n return finalConsonantIndex === 0 ? withoutFinalConsonant : withFinalConsonant;\n}\n","/**\n * Server-safe exports for aidol translations.\n *\n * This module exports only JSON resources and constants,\n * avoiding React-specific code that would break SSR.\n */\n\nimport en from \"./locales/en/aidol.json\";\nimport es from \"./locales/es/aidol.json\";\nimport id from \"./locales/id/aidol.json\";\nimport ja from \"./locales/ja/aidol.json\";\nimport ko from \"./locales/ko/aidol.json\";\nimport th from \"./locales/th/aidol.json\";\nimport tl from \"./locales/tl/aidol.json\";\nimport vi from \"./locales/vi/aidol.json\";\nimport zh from \"./locales/zh/aidol.json\";\n\n/** AIdol namespace */\nexport const AIDOL_NS = \"aidol\";\n\n/**\n * Translation resources for the aidol namespace.\n * Use with i18next.addResourceBundle(lang, 'aidol', translations)\n *\n * @example\n * import { aidolTranslations, AIDOL_NS } from 'aidol/locale';\n *\n * // Add to existing i18n instance\n * Object.entries(aidolTranslations).forEach(([lang, resources]) => {\n * i18n.addResourceBundle(lang, AIDOL_NS, resources);\n * });\n */\nexport const aidolTranslations = {\n en,\n es,\n id,\n ja,\n ko,\n th,\n tl,\n vi,\n zh,\n};\n"],"names":["AIdolRepository","BaseCrudRepository","aidolSchema","variables","url","raw","aidolCreateResponseSchema","fetchOptions","request","rawResponse","imageGenerationResponseSchema","generateResponseSchema","z","ChatroomRepository","chatroomSchema","chatroomId","options","params","queryString","messageSchema","content","companionId","MAX_MEMBERS","CompanionRelationshipRepository","companionRelationshipSchema","fromCompanionId","CompanionRepository","companionSchema","aidolId","trimmed","HighlightRepository","aidolHighlightSchema","highlightId","highlightMessageSchema","LeadsRepository","apiService","response","leadResponseSchema","STORAGE_KEY","schema","readStorage","stored","parsed","result","error","writeStorage","data","LocalChatroomIdsRepository","getParticle","word","withFinalConsonant","withoutFinalConsonant","code","finalConsonantIndex","AIDOL_NS","aidolTranslations","en","es","id","ja","ko","th","tl","vi","zh"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompanionRelationshipRepository.d.ts","sourceRoot":"","sources":["../../src/repositories/CompanionRelationshipRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"CompanionRelationshipRepository.d.ts","sourceRoot":"","sources":["../../src/repositories/CompanionRelationshipRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGxD,qBAAa,+BAAgC,SAAQ,kBAAkB,CAAC,qBAAqB,CAAC;IAC5F,QAAQ,CAAC,QAAQ,6BAA6B;IAE9C,SAAS,CAAC,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;IAIjB,oBAAoB,CAAC,eAAe,EAAE,MAAM;IAS5C,SAAS,CAAC,MAAM,EAAE;QACtB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,qBAAqB,CAAA;KAAE,CAAC;CAK7C"}
|