@nxcode/sdk 1.0.0 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +535 -0
- package/dist/nxcode.esm.js +371 -2
- package/dist/nxcode.esm.js.map +1 -1
- package/dist/nxcode.js +371 -2
- package/dist/nxcode.js.map +1 -1
- package/dist/nxcode.min.js +1 -1
- package/dist/types/ai.d.ts +149 -0
- package/dist/types/auth.test.d.ts +6 -0
- package/dist/types/index.d.ts +52 -3
- package/package.json +1 -1
package/dist/nxcode.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Nxcode={})}(this,function(t){"use strict";const e="nxcode_sdk_auth";class i{constructor(t,e){this.user=null,this.token=null,this.refreshToken=null,this.expiresAt=null,this.authCallbacks=[],this.popupWindow=null,this.messageHandler=null,this.apiEndpoint=t,this.appId=e,this.loadFromStorage(),this.setupMessageListener()}async login(t="google"){return new Promise((e,i)=>{const s=window.screenX+(window.outerWidth-500)/2,n=window.screenY+(window.outerHeight-600)/2,o=`${this.apiEndpoint}/api/sdk/auth/login?app_id=${this.appId}&provider=${t}`;if(this.popupWindow=window.open(o,"nxcode_login",`width=500,height=600,left=${s},top=${n}`),!this.popupWindow)return void i(new Error("Failed to open login popup. Please allow popups for this site."));const a=setTimeout(()=>{this.popupWindow?.close(),i(new Error("Login timeout"))},12e4),r=t=>{if("NXCODE_SDK_AUTH"!==t.data?.type)return;clearTimeout(a),window.removeEventListener("message",r);const s=t.data.payload;s.success&&s.user&&s.token?(this.setAuth(s),e(s.user)):i(new Error(s.error||"Login failed"))};window.addEventListener("message",r)})}async logout(){try{this.token&&await fetch(`${this.apiEndpoint}/api/sdk/auth/logout`,{method:"POST",headers:this.getHeaders()})}catch(t){console.warn("Logout request failed:",t)}this.clearAuth()}getUser(){return this.user}getToken(){return this.expiresAt&&new Date>this.expiresAt?(this.refreshSession().catch(console.error),null):this.token}async getValidToken(){return this.expiresAt&&new Date>this.expiresAt&&await this.refreshSession(),this.token}onAuthStateChange(t){return this.authCallbacks.push(t),t(this.user),()=>{const e=this.authCallbacks.indexOf(t);e>-1&&this.authCallbacks.splice(e,1)}}isLoggedIn(){return null!==this.user&&null!==this.token}async refreshSession(){if(this.refreshToken)try{const t=await fetch(`${this.apiEndpoint}/api/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json","X-App-Id":this.appId},body:JSON.stringify({refreshToken:this.refreshToken})});if(!t.ok)throw new Error("Refresh failed");const e=await t.json();this.setAuth({success:!0,token:e.token,refreshToken:e.refreshToken,expiresAt:e.expiresAt,user:e.user})}catch(t){console.error("Session refresh failed:",t),this.clearAuth()}else this.clearAuth()}async fetchUser(){if(!this.token)return null;try{const t=await fetch(`${this.apiEndpoint}/api/sdk/auth/me`,{headers:this.getHeaders()});if(!t.ok){if(401===t.status)return await this.refreshSession(),this.user;throw new Error("Failed to fetch user")}const e=await t.json();return this.user=e,this.notifyAuthChange(),this.saveToStorage(),e}catch(t){return console.error("Failed to fetch user:",t),null}}setAuth(t){t.success&&t.user&&t.token&&(this.user=t.user,this.token=t.token,this.refreshToken=t.refreshToken||null,this.expiresAt=t.expiresAt?new Date(t.expiresAt):null,this.saveToStorage(),this.notifyAuthChange())}clearAuth(){this.user=null,this.token=null,this.refreshToken=null,this.expiresAt=null,localStorage.removeItem(`${e}_${this.appId}`),this.notifyAuthChange()}saveToStorage(){if(this.user&&this.token){const t={token:this.token,refreshToken:this.refreshToken||"",expiresAt:this.expiresAt?.toISOString()||"",user:this.user};localStorage.setItem(`${e}_${this.appId}`,JSON.stringify(t))}}loadFromStorage(){try{const t=localStorage.getItem(`${e}_${this.appId}`);if(t){const e=JSON.parse(t);this.token=e.token,this.refreshToken=e.refreshToken,this.expiresAt=e.expiresAt?new Date(e.expiresAt):null,this.user=e.user,this.expiresAt&&new Date>this.expiresAt&&this.refreshSession().catch(()=>this.clearAuth())}}catch(t){console.warn("Failed to load auth from storage:",t)}}notifyAuthChange(){for(const t of this.authCallbacks)try{t(this.user)}catch(t){console.error("Auth callback error:",t)}}setupMessageListener(){}getHeaders(){const t={"Content-Type":"application/json","X-App-Id":this.appId};return this.token&&(t.Authorization=`Bearer ${this.token}`),t}}class s{constructor(t,e,i){this.apiEndpoint=t,this.appId=e,this.getToken=i}async getBalance(){const t=this.getToken();if(!t)throw new Error("Not authenticated. Please login first.");const e=await fetch(`${this.apiEndpoint}/api/sdk/billing/balance`,{headers:this.getHeaders(t)});if(!e.ok){if(401===e.status)throw new Error("Session expired. Please login again.");throw new Error("Failed to fetch balance")}return(await e.json()).balance}topUp(){const t=`${this.apiEndpoint}/api/sdk/billing/topup?app_id=${this.appId}`;window.open(t,"_blank")}getHeaders(t){return{"Content-Type":"application/json","X-App-Id":this.appId,Authorization:`Bearer ${t}`}}}class n{constructor(t,e,i){this.apiEndpoint=t,this.appId=e,this.getToken=i}async charge(t){const e=this.getToken();if(!e)return{success:!1,error:"Not authenticated. Please login first."};try{const i=await fetch(`${this.apiEndpoint}/api/sdk/payment/charge`,{method:"POST",headers:this.getHeaders(e),body:JSON.stringify({amount:t.amount,description:t.description,metadata:t.metadata})});if(!i.ok){if(401===i.status)return{success:!1,error:"Session expired. Please login again."};if(402===i.status)return{success:!1,error:"Insufficient balance. Please top up."};return{success:!1,error:(await i.json().catch(()=>({}))).detail||"Payment failed"}}return await i.json()}catch(t){return{success:!1,error:t instanceof Error?t.message:"Payment failed"}}}async getTransactions(t=50,e=0){const i=this.getToken();if(!i)throw new Error("Not authenticated. Please login first.");const s=await fetch(`${this.apiEndpoint}/api/sdk/payment/transactions?limit=${t}&offset=${e}`,{headers:this.getHeaders(i)});if(!s.ok){if(401===s.status)throw new Error("Session expired. Please login again.");throw new Error("Failed to fetch transactions")}return(await s.json()).transactions}getHeaders(t){return{"Content-Type":"application/json","X-App-Id":this.appId,Authorization:`Bearer ${t}`}}}const o=new class{constructor(){this.config=null,this._auth=null,this._billing=null,this._payment=null,this.initPromise=null,this.apiEndpoint=this.detectApiEndpoint(),this.autoInit()}async autoInit(){return this.initPromise||(this.initPromise=this.init()),this.initPromise}async init(){try{const t=await fetch(`${this.apiEndpoint}/api/sdk/config`,{credentials:"include"});t.ok&&(this.config=await t.json(),this.config.apiEndpoint=this.apiEndpoint,this.setupModules())}catch(t){console.warn("Nxcode SDK: Could not auto-detect app config. Call Nxcode.configure() manually.")}}configure(t){this.config={appId:t,name:"",billingMode:"creator_pays",apiEndpoint:this.apiEndpoint},this.setupModules()}setupModules(){this.config&&(this._auth=new i(this.config.apiEndpoint,this.config.appId),this._billing=new s(this.config.apiEndpoint,this.config.appId,()=>this._auth?.getToken()||null),this._payment=new n(this.config.apiEndpoint,this.config.appId,()=>this._auth?.getToken()||null))}detectApiEndpoint(){if("undefined"!=typeof window){const t=window.location.hostname;if("localhost"===t||"127.0.0.1"===t)return"http://localhost:8001";if(t.includes(".nxcode.dev")||t.includes(".nxcode.app"))return"https://studio-api.nxcode.io"}return"https://studio-api.nxcode.io"}async ensureInitialized(){if(this.initPromise&&await this.initPromise,!this.config)throw new Error("Nxcode SDK not configured. Add X-App-Id header or call Nxcode.configure(appId).")}get auth(){const t=this;return{login:async(e="google")=>(await t.ensureInitialized(),t._auth.login(e)),logout:async()=>(await t.ensureInitialized(),t._auth.logout()),getUser:()=>t._auth?.getUser()||null,getToken:()=>t._auth?.getToken()||null,onAuthStateChange(e){if(!t._auth){let i=null,s=!1;return t.ensureInitialized().then(()=>{!s&&t._auth&&(i=t._auth.onAuthStateChange(e))}),()=>{s=!0,i&&i()}}return t._auth.onAuthStateChange(e)},isLoggedIn:()=>t._auth?.isLoggedIn()||!1}}get billing(){const t=this;return{getBalance:async()=>(await t.ensureInitialized(),t._billing.getBalance()),topUp(){t._billing?.topUp()}}}get payment(){const t=this;return{charge:async e=>(await t.ensureInitialized(),t._payment.charge(e)),getTransactions:async(e,i)=>(await t.ensureInitialized(),t._payment.getTransactions(e,i))}}getConfig(){return this.config}isReady(){return null!==this.config&&null!==this._auth}async ready(){await this.ensureInitialized()}};"undefined"!=typeof window&&(window.Nxcode=o),t.Nxcode=o,t.default=o,Object.defineProperty(t,"__esModule",{value:!0})});
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Nxcode={})}(this,function(t){"use strict";const e="nxcode_sdk_auth";class n{constructor(t,e){this.user=null,this.token=null,this.refreshToken=null,this.expiresAt=null,this.authCallbacks=[],this.popupWindow=null,this.messageHandler=null,this.apiEndpoint=t,this.appId=e,this.loadFromStorage(),this.setupMessageListener()}async login(t="google"){return new Promise((e,n)=>{const s=window.screenX+(window.outerWidth-500)/2,i=window.screenY+(window.outerHeight-600)/2,a=`${this.apiEndpoint}/api/sdk/auth/login?app_id=${this.appId}&provider=${t}`;if(this.popupWindow=window.open(a,"nxcode_login",`width=500,height=600,left=${s},top=${i}`),!this.popupWindow)return void n(new Error("Failed to open login popup. Please allow popups for this site."));const o=setTimeout(()=>{this.popupWindow?.close(),n(new Error("Login timeout"))},12e4),r=t=>{if("NXCODE_SDK_AUTH"!==t.data?.type)return;clearTimeout(o),window.removeEventListener("message",r);const s=t.data.payload;s.success&&s.user&&s.token?(this.setAuth(s),e(s.user)):n(new Error(s.error||"Login failed"))};window.addEventListener("message",r)})}async logout(){try{this.token&&await fetch(`${this.apiEndpoint}/api/sdk/auth/logout`,{method:"POST",headers:this.getHeaders()})}catch(t){console.warn("Logout request failed:",t)}this.clearAuth()}getUser(){return this.user}getToken(){return this.expiresAt&&new Date>this.expiresAt?(this.refreshSession().catch(console.error),null):this.token}async getValidToken(){return this.expiresAt&&new Date>this.expiresAt&&await this.refreshSession(),this.token}onAuthStateChange(t){return this.authCallbacks.push(t),t(this.user),()=>{const e=this.authCallbacks.indexOf(t);e>-1&&this.authCallbacks.splice(e,1)}}isLoggedIn(){return null!==this.user&&null!==this.token}async refreshSession(){if(this.refreshToken)try{const t=await fetch(`${this.apiEndpoint}/api/sdk/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json","X-App-Id":this.appId},body:JSON.stringify({refreshToken:this.refreshToken})});if(!t.ok)throw new Error("Refresh failed");const e=await t.json();this.setAuth({success:!0,token:e.token,refreshToken:e.refreshToken,expiresAt:e.expiresAt,user:e.user})}catch(t){console.error("Session refresh failed:",t),this.clearAuth()}else this.clearAuth()}async fetchUser(){if(!this.token)return null;try{const t=await fetch(`${this.apiEndpoint}/api/sdk/auth/me`,{headers:this.getHeaders()});if(!t.ok){if(401===t.status)return await this.refreshSession(),this.user;throw new Error("Failed to fetch user")}const e=await t.json();return this.user=e,this.notifyAuthChange(),this.saveToStorage(),e}catch(t){return console.error("Failed to fetch user:",t),null}}setAuth(t){t.success&&t.user&&t.token&&(this.user=t.user,this.token=t.token,this.refreshToken=t.refreshToken||null,this.expiresAt=t.expiresAt?new Date(t.expiresAt):null,this.saveToStorage(),this.notifyAuthChange())}clearAuth(){this.user=null,this.token=null,this.refreshToken=null,this.expiresAt=null,localStorage.removeItem(`${e}_${this.appId}`),this.notifyAuthChange()}saveToStorage(){if(this.user&&this.token){const t={token:this.token,refreshToken:this.refreshToken||"",expiresAt:this.expiresAt?.toISOString()||"",user:this.user};localStorage.setItem(`${e}_${this.appId}`,JSON.stringify(t))}}loadFromStorage(){try{const t=localStorage.getItem(`${e}_${this.appId}`);if(t){const e=JSON.parse(t);this.token=e.token,this.refreshToken=e.refreshToken,this.expiresAt=e.expiresAt?new Date(e.expiresAt):null,this.user=e.user,this.expiresAt&&new Date>this.expiresAt&&this.refreshSession().catch(()=>this.clearAuth())}}catch(t){console.warn("Failed to load auth from storage:",t)}}notifyAuthChange(){for(const t of this.authCallbacks)try{t(this.user)}catch(t){console.error("Auth callback error:",t)}}setupMessageListener(){}getHeaders(){const t={"Content-Type":"application/json","X-App-Id":this.appId};return this.token&&(t.Authorization=`Bearer ${this.token}`),t}}class s{constructor(t,e,n){this.apiEndpoint=t,this.appId=e,this.getToken=n}async getBalance(){const t=this.getToken();if(!t)throw new Error("Not authenticated. Please login first.");const e=await fetch(`${this.apiEndpoint}/api/sdk/billing/balance`,{headers:this.getHeaders(t)});if(!e.ok){if(401===e.status)throw new Error("Session expired. Please login again.");throw new Error("Failed to fetch balance")}return(await e.json()).balance}topUp(){const t=`${this.apiEndpoint}/api/sdk/billing/topup?app_id=${this.appId}`;window.open(t,"_blank")}getHeaders(t){return{"Content-Type":"application/json","X-App-Id":this.appId,Authorization:`Bearer ${t}`}}}class i{constructor(t,e,n){this.apiEndpoint=t,this.appId=e,this.getToken=n}async charge(t){const e=this.getToken();if(!e)return{success:!1,error:"Not authenticated. Please login first."};try{const n=await fetch(`${this.apiEndpoint}/api/sdk/payment/charge`,{method:"POST",headers:this.getHeaders(e),body:JSON.stringify({amount:t.amount,description:t.description,metadata:t.metadata})});if(!n.ok){if(401===n.status)return{success:!1,error:"Session expired. Please login again."};if(402===n.status)return{success:!1,error:"Insufficient balance. Please top up."};return{success:!1,error:(await n.json().catch(()=>({}))).detail||"Payment failed"}}return await n.json()}catch(t){return{success:!1,error:t instanceof Error?t.message:"Payment failed"}}}async getTransactions(t=50,e=0){const n=this.getToken();if(!n)throw new Error("Not authenticated. Please login first.");const s=await fetch(`${this.apiEndpoint}/api/sdk/payment/transactions?limit=${t}&offset=${e}`,{headers:this.getHeaders(n)});if(!s.ok){if(401===s.status)throw new Error("Session expired. Please login again.");throw new Error("Failed to fetch transactions")}return(await s.json()).transactions}getHeaders(t){return{"Content-Type":"application/json","X-App-Id":this.appId,Authorization:`Bearer ${t}`}}}function a(t){if("string"===t)return{type:"STRING"};if("number"===t)return{type:"NUMBER"};if("boolean"===t)return{type:"BOOLEAN"};if(Array.isArray(t)){if(1!==t.length)throw new Error("Array schema must have exactly one element type");return{type:"ARRAY",items:a(t[0])}}if("object"==typeof t&&null!==t){const e={},n=[];for(const[s,i]of Object.entries(t))e[s]=a(i),n.push(s);return{type:"OBJECT",properties:e,required:n}}throw new Error(`Invalid schema type: ${t}`)}class o{constructor(t,e,n){this.apiEndpoint=t,this.appId=e,this.getToken=n}async chat(t){const e=this.getToken();if(!e)throw new Error("Not authenticated. Please login first.");const n=t.model||"fast",s={contents:this.convertMessagesToGemini(t.messages)};t.responseSchema&&(s.generationConfig={responseMimeType:"application/json",responseSchema:a(t.responseSchema)});const i=await fetch(`${this.apiEndpoint}/api/ai-gateway/v1beta/models/${n}:generateContent`,{method:"POST",headers:this.getHeaders(e),body:JSON.stringify(s)});i.ok||await this.handleError(i);const o=await i.json();return this.parseGeminiResponse(o)}async generate(t){const e=await this.chat({messages:[{role:"user",content:t.prompt}],model:t.model,responseSchema:t.responseSchema});return{text:e.content,usage:e.usage}}async chatStream(t){const e=this.getToken(),n=e?this.getHeaders(e):this.getAnonymousHeaders(),s=t.model||"fast",i={contents:this.convertMessagesToGemini(t.messages)},a=await fetch(`${this.apiEndpoint}/api/ai-gateway/v1beta/models/${s}:streamGenerateContent?alt=sse`,{method:"POST",headers:n,body:JSON.stringify(i)});a.ok||await this.handleError(a);const o=a.body?.getReader();if(!o)throw new Error("Streaming not supported");const r=new TextDecoder;let h="";try{for(;;){const{done:e,value:n}=await o.read();if(e)break;h+=r.decode(n,{stream:!0});const s=h.split("\n");h=s.pop()||"";for(const e of s)if(e.startsWith("data: ")){const n=e.slice(6).trim();if("[DONE]"===n)return void t.onChunk({content:"",done:!0});try{const e=JSON.parse(n),s=this.parseStreamChunk(e);t.onChunk(s)}catch{}}}if(h.startsWith("data: ")){const e=h.slice(6).trim();if(e&&"[DONE]"!==e)try{const n=JSON.parse(e),s=this.parseStreamChunk(n);t.onChunk(s)}catch{}}t.onChunk({content:"",done:!0})}finally{o.releaseLock()}}async generateStream(t){return this.chatStream({messages:[{role:"user",content:t.prompt}],model:t.model,onChunk:t.onChunk})}getHeaders(t){return{"Content-Type":"application/json","X-App-Id":this.appId,Authorization:`Bearer ${t}`}}getAnonymousHeaders(){return{"Content-Type":"application/json","X-App-Id":this.appId}}convertMessagesToGemini(t){return t.map(t=>({role:"assistant"===t.role?"model":"user",parts:this.convertContentToParts(t.content)}))}convertContentToParts(t){return"string"==typeof t?[{text:t}]:t.map(t=>{switch(t.type){case"text":return{text:t.text};case"image":return{inlineData:{mimeType:t.mimeType,data:t.data}};case"image_url":return{fileData:{fileUri:t.url}};default:return{text:""}}})}parseGeminiResponse(t){const e=t.candidates,n=e?.[0]?.content?.parts?.[0]?.text||"",s=t.usageMetadata;return{content:n,usage:s?{inputTokens:s.promptTokenCount||0,outputTokens:s.candidatesTokenCount||0}:void 0}}parseStreamChunk(t){const e=t.candidates,n=e?.[0]?.content?.parts?.[0]?.text||"",s=e?.[0]?.finishReason,i="STOP"===s||"END_TURN"===s,a=t.usageMetadata;return{content:n,done:i,usage:a?{inputTokens:a.promptTokenCount||0,outputTokens:a.candidatesTokenCount||0}:void 0}}async handleError(t){if(401===t.status)throw new Error("Session expired. Please login again.");if(402===t.status)throw new Error("Insufficient balance. Please top up to continue.");let e="AI request failed";try{const n=await t.json();e=n.detail||n.message||e}catch{}throw new Error(e)}}const r=new class{constructor(){this.config=null,this._auth=null,this._billing=null,this._payment=null,this._ai=null,this.initPromise=null,this.apiEndpoint=this.detectApiEndpoint(),this.autoInit()}async autoInit(){return this.initPromise||(this.initPromise=this.init()),this.initPromise}async init(){try{const t=await fetch(`${this.apiEndpoint}/api/sdk/config`,{credentials:"include"});t.ok&&(this.config=await t.json(),this.config.apiEndpoint=this.apiEndpoint,this.setupModules())}catch(t){console.warn("Nxcode SDK: Could not auto-detect app config. Call Nxcode.configure() manually.")}}configure(t,e){e?.apiEndpoint&&(this.apiEndpoint=e.apiEndpoint),this.config={appId:t,name:"",billingMode:"creator_pays",apiEndpoint:this.apiEndpoint},this.setupModules()}setupModules(){this.config&&(this._auth=new n(this.config.apiEndpoint,this.config.appId),this._billing=new s(this.config.apiEndpoint,this.config.appId,()=>this._auth?.getToken()||null),this._payment=new i(this.config.apiEndpoint,this.config.appId,()=>this._auth?.getToken()||null),this._ai=new o(this.config.apiEndpoint,this.config.appId,()=>this._auth?.getToken()||null))}detectApiEndpoint(){if("undefined"!=typeof window){const t=window.location.hostname;if("localhost"===t||"127.0.0.1"===t)return"http://localhost:8001";if(t.includes(".nxcode.dev")||t.includes(".nxcode.app"))return"https://studio-api.nxcode.io"}return"https://studio-api.nxcode.io"}async ensureInitialized(){if(this.initPromise&&await this.initPromise,!this.config)throw new Error("Nxcode SDK not configured. Add X-App-Id header or call Nxcode.configure(appId).")}get auth(){const t=this;return{login:async(e="google")=>(await t.ensureInitialized(),t._auth.login(e)),logout:async()=>(await t.ensureInitialized(),t._auth.logout()),getUser:()=>t._auth?.getUser()||null,getToken:()=>t._auth?.getToken()||null,onAuthStateChange(e){if(!t._auth){let n=null,s=!1;return t.ensureInitialized().then(()=>{!s&&t._auth&&(n=t._auth.onAuthStateChange(e))}),()=>{s=!0,n&&n()}}return t._auth.onAuthStateChange(e)},isLoggedIn:()=>t._auth?.isLoggedIn()||!1}}get billing(){const t=this;return{getBalance:async()=>(await t.ensureInitialized(),t._billing.getBalance()),topUp(){t._billing?.topUp()}}}get payment(){const t=this;return{charge:async e=>(await t.ensureInitialized(),t._payment.charge(e)),getTransactions:async(e,n)=>(await t.ensureInitialized(),t._payment.getTransactions(e,n))}}get ai(){const t=this;return{chat:async e=>(await t.ensureInitialized(),t._ai.chat(e)),generate:async e=>(await t.ensureInitialized(),t._ai.generate(e)),chatStream:async e=>(await t.ensureInitialized(),t._ai.chatStream(e)),generateStream:async e=>(await t.ensureInitialized(),t._ai.generateStream(e))}}getConfig(){return this.config}isReady(){return null!==this.config&&null!==this._auth}async ready(){await this.ensureInitialized()}};"undefined"!=typeof window&&(window.Nxcode=r),t.Nxcode=r,t.default=r,Object.defineProperty(t,"__esModule",{value:!0})});
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nxcode SDK - AI Module
|
|
3
|
+
*
|
|
4
|
+
* Provides access to AI capabilities through the Nxcode AI Gateway.
|
|
5
|
+
* All AI calls require user authentication and are billed to the user's balance.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Simplified schema type for structured output.
|
|
9
|
+
*
|
|
10
|
+
* Use simple TypeScript-style notation:
|
|
11
|
+
* - Primitives: 'string', 'number', 'boolean'
|
|
12
|
+
* - Arrays: ['string'], ['number'], [{ nested: 'object' }]
|
|
13
|
+
* - Objects: { key: 'type', nested: { ... } }
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Simple object
|
|
17
|
+
* { name: 'string', age: 'number', active: 'boolean' }
|
|
18
|
+
*
|
|
19
|
+
* // With arrays
|
|
20
|
+
* { tags: ['string'], scores: ['number'] }
|
|
21
|
+
*
|
|
22
|
+
* // Nested objects
|
|
23
|
+
* { user: { name: 'string', profile: { bio: 'string' } } }
|
|
24
|
+
*/
|
|
25
|
+
export type SimpleSchema = 'string' | 'number' | 'boolean' | SimpleSchema[] | {
|
|
26
|
+
[key: string]: SimpleSchema;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Content part for multimodal messages
|
|
30
|
+
*/
|
|
31
|
+
export interface TextPart {
|
|
32
|
+
type: 'text';
|
|
33
|
+
text: string;
|
|
34
|
+
}
|
|
35
|
+
export interface ImagePart {
|
|
36
|
+
type: 'image';
|
|
37
|
+
/** Base64 encoded image data */
|
|
38
|
+
data: string;
|
|
39
|
+
/** MIME type (e.g., 'image/png', 'image/jpeg') */
|
|
40
|
+
mimeType: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ImageUrlPart {
|
|
43
|
+
type: 'image_url';
|
|
44
|
+
/** URL of the image */
|
|
45
|
+
url: string;
|
|
46
|
+
}
|
|
47
|
+
export type ContentPart = TextPart | ImagePart | ImageUrlPart;
|
|
48
|
+
export interface ChatMessage {
|
|
49
|
+
role: 'user' | 'assistant' | 'system';
|
|
50
|
+
/** Text content or array of content parts for multimodal */
|
|
51
|
+
content: string | ContentPart[];
|
|
52
|
+
}
|
|
53
|
+
export interface ChatOptions {
|
|
54
|
+
messages: ChatMessage[];
|
|
55
|
+
model?: string;
|
|
56
|
+
/** Schema for structured output. AI will return JSON matching this schema. */
|
|
57
|
+
responseSchema?: SimpleSchema;
|
|
58
|
+
}
|
|
59
|
+
export interface ChatResponse {
|
|
60
|
+
content: string;
|
|
61
|
+
usage?: {
|
|
62
|
+
inputTokens: number;
|
|
63
|
+
outputTokens: number;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export interface GenerateOptions {
|
|
67
|
+
prompt: string;
|
|
68
|
+
model?: string;
|
|
69
|
+
/** Schema for structured output. AI will return JSON matching this schema. */
|
|
70
|
+
responseSchema?: SimpleSchema;
|
|
71
|
+
}
|
|
72
|
+
export interface GenerateResponse {
|
|
73
|
+
text: string;
|
|
74
|
+
usage?: {
|
|
75
|
+
inputTokens: number;
|
|
76
|
+
outputTokens: number;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export interface StreamChunk {
|
|
80
|
+
content: string;
|
|
81
|
+
done: boolean;
|
|
82
|
+
usage?: {
|
|
83
|
+
inputTokens: number;
|
|
84
|
+
outputTokens: number;
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export type StreamCallback = (chunk: StreamChunk) => void;
|
|
88
|
+
export declare class NxcodeAI {
|
|
89
|
+
private apiEndpoint;
|
|
90
|
+
private appId;
|
|
91
|
+
private getToken;
|
|
92
|
+
constructor(apiEndpoint: string, appId: string, getToken: () => string | null);
|
|
93
|
+
/**
|
|
94
|
+
* Send a chat message and get a response.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* const response = await Nxcode.ai.chat({
|
|
98
|
+
* messages: [
|
|
99
|
+
* { role: 'user', content: 'Hello!' }
|
|
100
|
+
* ]
|
|
101
|
+
* });
|
|
102
|
+
* console.log(response.content);
|
|
103
|
+
*/
|
|
104
|
+
chat(options: ChatOptions): Promise<ChatResponse>;
|
|
105
|
+
/**
|
|
106
|
+
* Generate text from a prompt.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* const response = await Nxcode.ai.generate({
|
|
110
|
+
* prompt: 'Write a haiku about coding'
|
|
111
|
+
* });
|
|
112
|
+
* console.log(response.text);
|
|
113
|
+
*/
|
|
114
|
+
generate(options: GenerateOptions): Promise<GenerateResponse>;
|
|
115
|
+
/**
|
|
116
|
+
* Stream a chat response in real-time.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* await Nxcode.ai.chatStream({
|
|
120
|
+
* messages: [{ role: 'user', content: 'Tell me a story' }],
|
|
121
|
+
* onChunk: (chunk) => {
|
|
122
|
+
* process.stdout.write(chunk.content);
|
|
123
|
+
* if (chunk.done) console.log('\n--- Done ---');
|
|
124
|
+
* }
|
|
125
|
+
* });
|
|
126
|
+
*/
|
|
127
|
+
chatStream(options: ChatOptions & {
|
|
128
|
+
onChunk: StreamCallback;
|
|
129
|
+
}): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Stream text generation from a prompt.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* await Nxcode.ai.generateStream({
|
|
135
|
+
* prompt: 'Write a poem',
|
|
136
|
+
* onChunk: (chunk) => console.log(chunk.content)
|
|
137
|
+
* });
|
|
138
|
+
*/
|
|
139
|
+
generateStream(options: GenerateOptions & {
|
|
140
|
+
onChunk: StreamCallback;
|
|
141
|
+
}): Promise<void>;
|
|
142
|
+
private getHeaders;
|
|
143
|
+
private getAnonymousHeaders;
|
|
144
|
+
private convertMessagesToGemini;
|
|
145
|
+
private convertContentToParts;
|
|
146
|
+
private parseGeminiResponse;
|
|
147
|
+
private parseStreamChunk;
|
|
148
|
+
private handleError;
|
|
149
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -11,12 +11,14 @@
|
|
|
11
11
|
* console.log('Logged in:', user.email);
|
|
12
12
|
* </script>
|
|
13
13
|
*/
|
|
14
|
+
import { type ChatOptions, type ChatResponse, type GenerateOptions, type GenerateResponse, type StreamChunk, type StreamCallback, type ChatMessage, type ContentPart, type TextPart, type ImagePart, type ImageUrlPart } from './ai';
|
|
14
15
|
import type { NxcodeUser, NxcodeConfig, ChargeOptions, ChargeResult, Transaction, AuthStateCallback } from './types';
|
|
15
16
|
declare class NxcodeSDK {
|
|
16
17
|
private config;
|
|
17
18
|
private _auth;
|
|
18
19
|
private _billing;
|
|
19
20
|
private _payment;
|
|
21
|
+
private _ai;
|
|
20
22
|
private initPromise;
|
|
21
23
|
private apiEndpoint;
|
|
22
24
|
constructor();
|
|
@@ -29,9 +31,11 @@ declare class NxcodeSDK {
|
|
|
29
31
|
*/
|
|
30
32
|
private init;
|
|
31
33
|
/**
|
|
32
|
-
* Manually configure SDK with app ID
|
|
34
|
+
* Manually configure SDK with app ID and optional endpoint
|
|
33
35
|
*/
|
|
34
|
-
configure(appId: string
|
|
36
|
+
configure(appId: string, options?: {
|
|
37
|
+
apiEndpoint?: string;
|
|
38
|
+
}): void;
|
|
35
39
|
/**
|
|
36
40
|
* Set up SDK modules after configuration
|
|
37
41
|
*/
|
|
@@ -90,6 +94,51 @@ declare class NxcodeSDK {
|
|
|
90
94
|
*/
|
|
91
95
|
getTransactions(limit?: number, offset?: number): Promise<Transaction[]>;
|
|
92
96
|
};
|
|
97
|
+
get ai(): {
|
|
98
|
+
/**
|
|
99
|
+
* Send a chat message and get a response
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* const response = await Nxcode.ai.chat({
|
|
103
|
+
* messages: [{ role: 'user', content: 'Hello!' }]
|
|
104
|
+
* });
|
|
105
|
+
*/
|
|
106
|
+
chat(options: ChatOptions): Promise<ChatResponse>;
|
|
107
|
+
/**
|
|
108
|
+
* Generate text from a prompt
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* const response = await Nxcode.ai.generate({ prompt: 'Write a haiku' });
|
|
112
|
+
*/
|
|
113
|
+
generate(options: GenerateOptions): Promise<GenerateResponse>;
|
|
114
|
+
/**
|
|
115
|
+
* Stream a chat response in real-time
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* await Nxcode.ai.chatStream({
|
|
119
|
+
* messages: [{ role: 'user', content: 'Tell me a story' }],
|
|
120
|
+
* onChunk: (chunk) => {
|
|
121
|
+
* document.body.innerText += chunk.content;
|
|
122
|
+
* if (chunk.done) console.log('Done!');
|
|
123
|
+
* }
|
|
124
|
+
* });
|
|
125
|
+
*/
|
|
126
|
+
chatStream(options: ChatOptions & {
|
|
127
|
+
onChunk: StreamCallback;
|
|
128
|
+
}): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* Stream text generation from a prompt
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* await Nxcode.ai.generateStream({
|
|
134
|
+
* prompt: 'Write a poem',
|
|
135
|
+
* onChunk: (chunk) => console.log(chunk.content)
|
|
136
|
+
* });
|
|
137
|
+
*/
|
|
138
|
+
generateStream(options: GenerateOptions & {
|
|
139
|
+
onChunk: StreamCallback;
|
|
140
|
+
}): Promise<void>;
|
|
141
|
+
};
|
|
93
142
|
/**
|
|
94
143
|
* Get current configuration
|
|
95
144
|
*/
|
|
@@ -106,4 +155,4 @@ declare class NxcodeSDK {
|
|
|
106
155
|
declare const Nxcode: NxcodeSDK;
|
|
107
156
|
export default Nxcode;
|
|
108
157
|
export { Nxcode };
|
|
109
|
-
export type { NxcodeUser, NxcodeConfig, ChargeOptions, ChargeResult, Transaction, AuthStateCallback, };
|
|
158
|
+
export type { NxcodeUser, NxcodeConfig, ChargeOptions, ChargeResult, Transaction, AuthStateCallback, ChatOptions, ChatResponse, ChatMessage, ContentPart, TextPart, ImagePart, ImageUrlPart, GenerateOptions, GenerateResponse, StreamChunk, StreamCallback, };
|