t1y-sdk-js 5.0.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/LICENSE +21 -0
- package/README.md +313 -0
- package/README.zh-CN.md +313 -0
- package/dist/index.d.mts +920 -0
- package/dist/index.d.ts +920 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3 -0
- package/dist/index.mjs.map +1 -0
- package/dist/umd/t1y.min.js +2 -0
- package/package.json +69 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";var ee=Object.defineProperty;var Qe=Object.getOwnPropertyDescriptor;var Xe=Object.getOwnPropertyNames;var ze=Object.prototype.hasOwnProperty;var Ue=e=>{throw TypeError(e)};var et=(e,t)=>{for(var n in t)ee(e,n,{get:t[n],enumerable:!0})},tt=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Xe(t))!ze.call(e,o)&&o!==n&&ee(e,o,{get:()=>t[o],enumerable:!(r=Qe(t,o))||r.enumerable});return e};var nt=e=>tt(ee({},"__esModule",{value:!0}),e);var rt=(e,t,n)=>t.has(e)||Ue("Cannot "+n);var Ie=(e,t,n)=>t.has(e)?Ue("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n);var k=(e,t,n)=>(rt(e,t,"access private method"),n);var lt={};et(lt,{Array:()=>de,Bigint:()=>ye,Boolean:()=>ue,Date:()=>ae,DateTime:()=>ce,Double:()=>le,Empty:()=>Ae,Float:()=>me,Integer:()=>fe,Map:()=>ge,MapArray:()=>he,Nil:()=>be,None:()=>we,Null:()=>xe,ObjectID:()=>ie,T1Collection:()=>N,T1YError:()=>h,T1YOS:()=>v,TimeNow:()=>J,TimeNowUnix:()=>Z,TimeNowUnixNano:()=>V,TimeNowWeekday:()=>Q,TimeNowWeekdayChinese:()=>X,Timestamp:()=>pe,UNDEFINED:()=>Te,Undefined:()=>Ee,ValidationError:()=>y,assertObjectID:()=>b,convertDateTypes:()=>S,createSignature:()=>H,decryptAESGCM:()=>B,default:()=>We,encryptAESGCM:()=>_,formatTimestampsToLocal:()=>M,getSafeTimestamp:()=>$,hmacSHA256Hex:()=>E,hmacSHA256HexAsync:()=>ne,isNonEmptyArrayWithNonEmptyObjects:()=>U,isNonEmptyObject:()=>l,isPlainObject:()=>x,sha256Hex:()=>D,sha256HexAsync:()=>te,timeNow:()=>Re,validateApiKey:()=>G,validateAppId:()=>K,validateBaseUrl:()=>W,validateInitConfig:()=>C,validateSecretKey:()=>Y,verifyHmacSHA256:()=>j});module.exports=nt(lt);var Oe="https://myapp.t1y.net";var F="YYYY-MM-DD HH:mm:ss";var q=/^[0-9a-fA-F]{24}$/;var h=class extends Error{constructor(t,n,r){super(n),this.name="T1YError",this.code=t,this.data=r}toJSON(){return{name:this.name,code:this.code,message:this.message,data:this.data}}},y=class extends Error{constructor(t){super(t),this.name="ValidationError"}};function K(e){if(!Number.isInteger(e))throw new y("appId must be an integer");if(e<1001)throw new y(`appId must be >= ${1001}`)}function G(e){if(typeof e!="string")throw new y("apiKey must be a string");if(e.length!==32)throw new y(`apiKey must be exactly ${32} characters (got ${e.length})`)}function Y(e){if(typeof e!="string")throw new y("secretKey must be a string");if(e.length!==32)throw new y(`secretKey must be exactly ${32} characters (got ${e.length})`)}function W(e){if(!/^https?:\/\//.test(e))throw new y('baseUrl must start with "http://" or "https://"')}function C(e){if(e.baseUrl!==void 0&&W(e.baseUrl),K(e.appId),G(e.apiKey),Y(e.secretKey),e.version!==void 0&&(!Number.isInteger(e.version)||e.version<0))throw new y("version must be a non-negative integer")}function b(e,t="ObjectID"){if(typeof e!="string")throw new y(`${t} must be a string`);if(!q.test(e))throw new y(`Invalid ${t} string: "${e}"`);return!0}function S(e){if(e instanceof Date)return`Date('${e.toISOString()}')`;if(typeof e=="number"){let t=String(e);return/^\d{10,}$/.test(t)?`Timestamp('${t}')`:e}if(Array.isArray(e))return e.map(t=>S(t));if(e&&typeof e=="object"){let t={};for(let n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=S(e[n]));return t}return e}function l(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&Object.keys(e).length>0}function x(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function U(e){return!Array.isArray(e)||e.length===0?!1:e.every(t=>typeof t=="object"&&t!==null&&!Array.isArray(t)&&Object.keys(t).length>0)}function Ce(){try{if(typeof require<"u")return require}catch{}return null}function D(e){let t=Ce();if(t)try{return t("node:crypto").createHash("sha256").update(e).digest("hex")}catch{}let n=ot(e);return P(n)}function P(e){return st(e)}async function te(e){let t=Ce();if(t)try{return t("node:crypto").createHash("sha256").update(e).digest("hex")}catch{}let n=new TextEncoder,r=await crypto.subtle.digest("SHA-256",n.encode(e));return Array.from(new Uint8Array(r)).map(o=>o.toString(16).padStart(2,"0")).join("")}function ot(e){if(typeof TextEncoder<"u")return new TextEncoder().encode(e);let t=[];for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);if(r<128)t.push(r);else if(r<2048)t.push(192|r>>6,128|r&63);else if(r<55296||r>=57344)t.push(224|r>>12,128|r>>6&63,128|r&63);else{n++;let o=e.charCodeAt(n),i=65536+((r&1023)<<10)+(o&1023);t.push(240|i>>18,128|i>>12&63,128|i>>6&63,128|i&63)}}return new Uint8Array(t)}function st(e){let t=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],n=e.length,r=n*8,o=(64-(n+9)%64)%64,i=n+1+o+8,c=new Uint8Array(i);c.set(e),c[n]=128;for(let a=0;a<8;a++)c[i-8+a]=Number(BigInt(r)>>BigInt((7-a)*8)&BigInt(255));let s=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];for(let a=0;a<i;a+=64){let u=new Array(64);for(let p=0;p<16;p++)u[p]=c[a+p*4]<<24|c[a+p*4+1]<<16|c[a+p*4+2]<<8|c[a+p*4+3];for(let p=16;p<64;p++){let g=(A(u[p-15],7)^A(u[p-15],18)^u[p-15]>>>3)>>>0,z=(A(u[p-2],17)^A(u[p-2],19)^u[p-2]>>>10)>>>0;u[p]=u[p-16]+g+u[p-7]+z>>>0}let[f,d,m,I,w,O,R,L]=s;for(let p=0;p<64;p++){let g=(A(w,6)^A(w,11)^A(w,25))>>>0,z=(w&O^~w&R)>>>0,Se=L+g+z+t[p]+u[p]>>>0,Je=(A(f,2)^A(f,13)^A(f,22))>>>0,Ze=(f&d^f&m^d&m)>>>0,Ve=Je+Ze>>>0;L=R,R=O,O=w,w=I+Se>>>0,I=m,m=d,d=f,f=Se+Ve>>>0}s[0]=s[0]+f>>>0,s[1]=s[1]+d>>>0,s[2]=s[2]+m>>>0,s[3]=s[3]+I>>>0,s[4]=s[4]+w>>>0,s[5]=s[5]+O>>>0,s[6]=s[6]+R>>>0,s[7]=s[7]+L>>>0}return s.map(a=>a.toString(16).padStart(8,"0")).join("")}function A(e,t){return e>>>t|e<<32-t}function _e(){try{if(typeof require<"u")return require}catch{}return null}function E(e,t){let n=_e();if(n)try{return n("node:crypto").createHmac("sha256",e).update(t).digest("hex")}catch{}return at(e,t)}async function ne(e,t){let n=_e();if(n)try{return n("node:crypto").createHmac("sha256",e).update(t).digest("hex")}catch{}let r=new TextEncoder,o=await crypto.subtle.importKey("raw",r.encode(e),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),i=await crypto.subtle.sign("HMAC",o,r.encode(t));return Array.from(new Uint8Array(i)).map(c=>c.toString(16).padStart(2,"0")).join("")}function j(e,t,n){if(typeof n!="string")return!1;let r=E(e,t);return it(r,n.toLowerCase())}function it(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r++)n|=e.charCodeAt(r)^t.charCodeAt(r);return n===0}function at(e,t){let r=Pe(e),o=Pe(t);r.length>64&&(r=je(P(r)));let i=new Uint8Array(64);i.set(r.subarray(0,Math.min(r.length,64)));let c=new Uint8Array(64);c.fill(54);let s=De(i,c),a=new Uint8Array(64+o.length);a.set(s),a.set(o,64);let u=je(P(a)),f=new Uint8Array(64);f.fill(92);let d=De(i,f),m=new Uint8Array(64+u.length);return m.set(d),m.set(u,64),P(m)}function De(e,t){let n=new Uint8Array(e.length);for(let r=0;r<e.length;r++)n[r]=e[r]^t[r];return n}function Pe(e){if(typeof TextEncoder<"u")return new TextEncoder().encode(e);let t=[];for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);if(r<128)t.push(r);else if(r<2048)t.push(192|r>>6,128|r&63);else if(r<55296||r>=57344)t.push(224|r>>12,128|r>>6&63,128|r&63);else{n++;let o=e.charCodeAt(n),i=65536+((r&1023)<<10)+(o&1023);t.push(240|i>>18,128|i>>12&63,128|i>>6&63,128|i&63)}}return new Uint8Array(t)}function je(e){let t=new Uint8Array(e.length/2);for(let n=0;n<e.length;n+=2)t[n/2]=parseInt(e.substring(n,n+2),16);return t}function He(){if(typeof globalThis<"u"){if(typeof globalThis.crypto<"u"&&globalThis.crypto.subtle)return globalThis.crypto;try{let e=globalThis.require?globalThis.require("node:crypto"):null;if(e?.webcrypto)return e.webcrypto}catch{}}throw new Error("Web Crypto API is not available in this environment")}var Be=16,ct=12;function re(e){let t="",n=e.byteLength;for(let r=0;r<n;r++)t+=String.fromCharCode(e[r]);return btoa(t)}function oe(e){let t=atob(e),n=t.length,r=new Uint8Array(n);for(let o=0;o<n;o++)r[o]=t.charCodeAt(o);return r}async function _(e,t){if(!(t instanceof Uint8Array))throw new Error("key must be Uint8Array");if(t.length!==32)throw new Error("key length must be 32 bytes for AES-256-GCM");let n=He(),r=await n.subtle.importKey("raw",t,"AES-GCM",!1,["encrypt"]),o=new Uint8Array(ct);n.getRandomValues(o);let i=new TextEncoder().encode(e),c=new Uint8Array(await n.subtle.encrypt({name:"AES-GCM",iv:o,tagLength:128},r,i)),s=c.slice(0,c.length-Be),a=c.slice(c.length-Be),u={n:re(o),j:re(s),t:re(a)};return JSON.stringify(u)}async function B(e,t){if(!(t instanceof Uint8Array))throw new Error("key must be Uint8Array");if(t.length!==32)throw new Error("key length must be 32 bytes for AES-256-GCM");let n=He(),{n:r,j:o,t:i}=JSON.parse(e),c=oe(r),s=oe(o),a=oe(i),u=new Uint8Array(s.length+a.length);u.set(s),u.set(a,s.length);let f=await n.subtle.importKey("raw",t,"AES-GCM",!1,["decrypt"]),d=await n.subtle.decrypt({name:"AES-GCM",iv:c,tagLength:128},f,u);return new TextDecoder().decode(d)}function H(e){let{method:t,pathAndQuery:n,body:r,appId:o,timestamp:i,secretKey:c}=e,s=D(r),a=[t.toUpperCase(),n,s,String(o),String(i)].join(`
|
|
2
|
+
`);return E(c,a)}function $(e){return String(Math.floor(Date.now()/1e3)+e)}function $e(e){return e.replace(/\/+$/,"")}function ve(e,t){for(let n of Object.keys(t)){let r=t[n];r!=null&&e.searchParams.set(n,typeof r=="string"?r:JSON.stringify(r))}}function pt(e,t){let n=new Date(e);if(isNaN(n.getTime()))return e;let r=o=>String(o).padStart(2,"0");return t.replace("YYYY",String(n.getFullYear())).replace("MM",r(n.getMonth()+1)).replace("DD",r(n.getDate())).replace("HH",r(n.getHours())).replace("mm",r(n.getMinutes())).replace("ss",r(n.getSeconds()))}function M(e,t=F){function n(r){if(Array.isArray(r))return r.map(n);if(r&&typeof r=="object"){let o={};for(let i in r)Object.prototype.hasOwnProperty.call(r,i)&&(i==="createdAt"||i==="updatedAt"?o[i]=pt(r[i],t):o[i]=n(r[i]));return o}return r}return n(e)}async function Le(e,t,n,r){let o,i=e.headers.get("content-type")||"",c=await e.text();if(i.includes("application/json"))try{o=JSON.parse(c)}catch{o=c}else o=c;if(t&&o&&typeof o=="object"&&"j"in o)try{let s=await B(JSON.stringify(o),new TextEncoder().encode(n));try{o=JSON.parse(s)}catch{o=s}}catch(s){throw new h(400,"AES-256-GCM decryption failed",s instanceof Error?s.message:null)}if(o&&typeof o=="object"&&"data"in o){let s=o;if(s.data=M(s.data,r),!e.ok)throw new h(s.code||e.status,s.message||e.statusText,s.data);return s}if(!e.ok)throw new h(e.status,e.statusText,o);return{code:0,message:"ok",data:M(o,r)}}function Fe(e){if(e&&typeof e=="object"&&"response"in e){let t=e;throw e}throw e instanceof h?e:e instanceof Error?e.name==="AbortError"?new h(408,"Request timeout",null):new h(0,e.message,null):new h(0,"Unknown error",e)}async function se(e,t){let{method:n,path:r,params:o,encryption:i,timeout:c}=t,s=$e(e.baseUrl),a=i??e.isSafeMode,u=new URL(s+r),f=S(o),d,m="";if(n!=="GET")if(a&&f!==void 0){let g=await _(JSON.stringify(f),new TextEncoder().encode(e.secretKey));d=g,m=g}else if(f!==void 0){let g=JSON.stringify(f);d=g,m=g}else m="";else f&&typeof f=="object"&&Object.keys(f).length>0&&ve(u,f);let I=Number($(e.offset)),w=u.pathname+u.search,O=H({method:n,pathAndQuery:w,body:m,appId:e.appId,timestamp:I,secretKey:e.secretKey}),R=new AbortController,p=setTimeout(()=>R.abort(),c??3e5);try{let g=await fetch(u.toString(),{method:n,headers:{"X-T1Y-Application-ID":String(e.appId),"X-T1Y-API-Key":e.apiKey,"X-T1Y-Safe-Timestamp":String(I),"X-T1Y-Safe-Sign":O,"Content-Type":"application/json"},body:n!=="GET"?d:void 0,signal:R.signal});return clearTimeout(p),await Le(g,a,e.secretKey,e.timeFormat)}catch(g){return clearTimeout(p),Fe(g)}}var N=class{constructor(t,n){this.client=t,this.name=n}async insertOne(t){if(!l(t))throw new TypeError("insertOne data must be a non-empty plain object");return await this.client.request("POST",`/v5/classes/${this.name}`,t)}async deleteById(t){return b(t),await this.client.request("DELETE",`/v5/classes/${this.name}/${t}`)}async updateById(t,n){if(b(t),!l(n))throw new TypeError("update data must be a non-empty plain object");return await this.client.request("PUT",`/v5/classes/${this.name}/${t}`,n)}async findById(t){return b(t),await this.client.request("GET",`/v5/classes/${this.name}/${t}`)}async deleteOne(t){if(!l(t))throw new TypeError("deleteOne filter must be a non-empty plain object");return await this.client.request("DELETE",`/v5/classes/${this.name}/one`,t)}async updateOne(t,n){if(!l(t))throw new TypeError("updateOne filter must be a non-empty plain object");if(!l(n))throw new TypeError("updateOne body must be a non-empty plain object");return await this.client.request("PUT",`/v5/classes/${this.name}/one`,{filter:t,body:n})}async findOne(t){if(!l(t))throw new TypeError("findOne filter must be a non-empty plain object");return await this.client.request("POST",`/v5/classes/${this.name}/one`,t)}async insertMany(t){if(!U(t))throw new TypeError("insertMany dataList must be a non-empty array of non-empty plain objects");return await this.client.request("POST",`/v5/classes/${this.name}/many`,t)}async deleteMany(t){if(!x(t))throw new TypeError("deleteMany filter must be a plain object");return await this.client.request("DELETE",`/v5/classes/${this.name}/many`,t)}async updateMany(t,n){if(!x(t))throw new TypeError("updateMany filter must be a plain object");if(!l(n))throw new TypeError("updateMany body must be a non-empty plain object");return await this.client.request("PUT",`/v5/classes/${this.name}/many`,{filter:t,body:n})}async find(t=1,n=10,r={createdAt:-1},o={}){if(!Number.isInteger(t)||t<1)throw new TypeError("find page must be a positive integer");if(!Number.isInteger(n)||n<1)throw new TypeError("find size must be a positive integer");if(n>100&&(n=100),!l(r))throw new TypeError("find sort must be a non-empty plain object");if(!x(o))throw new TypeError("find filter must be a plain object");return await this.client.request("POST",`/v5/classes/${this.name}/find`,{page:t,size:n,sort:r,filter:o})}async aggregate(t){if(!Array.isArray(t))throw new TypeError("aggregate pipeline must be an array");return await this.client.request("POST",`/v5/classes/${this.name}/aggregate`,t)}async count(t={}){if(!x(t))throw new TypeError("count filter must be a plain object");return await this.client.request("POST",`/v5/classes/${this.name}/count`,t)}async distinct(t,n={}){if(typeof t!="string"||t.length===0)throw new TypeError("distinct fieldName must be a non-empty string");if(!x(n))throw new TypeError("distinct filter must be a plain object");return await this.client.request("POST",`/v5/classes/${this.name}/distinct/${encodeURIComponent(t)}`,n)}async create(){return await this.client.request("POST",`/v5/schemas/${encodeURIComponent(this.name)}`)}async clear(){return await this.client.request("PUT",`/v5/schemas/${encodeURIComponent(this.name)}`)}async drop(){return await this.client.request("DELETE",`/v5/schemas/${encodeURIComponent(this.name)}`)}};var T,qe,Ke,Ge,Ye,v=class{constructor(t){Ie(this,T);C(t),this.config={baseUrl:t.baseUrl??Oe,appId:t.appId,apiKey:t.apiKey,secretKey:t.secretKey,version:t.version??0,isSafeMode:t.isSafeMode??!1,timeFormat:t.timeFormat??F,offset:t.offset??0},this.db={collection:n=>k(this,T,qe).call(this,n),toObjectID:n=>k(this,T,Ge).call(this,n),getCollections:()=>k(this,T,Ke).call(this)}}async init(){try{let n=(await this.request("GET",`/init/${this.config.appId}`,void 0,!1)).data;this.config.isSafeMode=n.is_safe_mode,this.config.offset=n.unix-Math.floor(Date.now()/1e3)}catch(t){console.warn("Failed to get time offset from server, defaulting to 0. Error:",t),this.config.isSafeMode=!1,this.config.offset=0}}async getMeta(t){if(t!==void 0&&t!==""&&typeof t!="string")throw new TypeError("Meta field must be a string");let n=t?`?field=${encodeURIComponent(t)}`:"";return await this.request("GET",`/v5/meta${n}`)}async checkUpdate(){try{return(await this.request("GET","/v5/meta?field=version")).data.result>this.config.version}catch{return!1}}async callFunc(t,n=null,r){if(typeof t!="string")throw new TypeError("Function name must be a string");return await this.request("POST",`/${this.config.appId}/${k(this,T,Ye).call(this,t)}`,n,r)}async request(t,n,r,o){if(typeof n!="string")throw new TypeError("request path must be a string");return await se(this.config,{method:t,path:n,params:r,encryption:o??this.config.isSafeMode})}assertObjectID(t,n="ObjectID"){return b(t,n)}isNonEmptyObject(t){return l(t)}isPlainObject(t){return x(t)}isNonEmptyArrayWithNonEmptyObjects(t){return U(t)}hmacSHA256(t,n){return E(t,n)}verifyHmacSHA256(t,n,r){return j(t,n,r)}};T=new WeakSet,qe=function(t){if(typeof t!="string")throw new TypeError("Collection name must be a string");return new N(this,t)},Ke=async function(){return await this.request("GET","/v5/schemas")},Ge=function(t){return b(t),`ObjectID('${t}')`},Ye=function(t){let n=t.startsWith("/")?t.slice(1):t,r=n.indexOf("#"),o=r!==-1?n.slice(r):"",i=r!==-1?n.slice(0,r):n,c=i.indexOf("?"),s=c!==-1?i.slice(c):"",a=c!==-1?i.slice(0,c):i;return a.endsWith("/")?a=a+"index.jsc":a.endsWith(".jsc")||(a.endsWith(".js")?a=a.replace(/\.js$/,".jsc"):a=a+".jsc"),a+s+o};var We=v;function ie(e){if(!q.test(e))throw new Error(`Invalid ObjectID: "${e}" (must be 24 hex characters)`);return`ObjectID('${e}')`}function ae(e){return`Date('${e}')`}function ce(e){return`DateTime('${e}')`}function pe(e){return`Timestamp('${String(e)}')`}function ue(e){return`Boolean(${e})`}function fe(e){return`Integer(${e})`}function ye(e){return`Bigint(${Number(e)})`}function me(e){return`Float(${e})`}function le(e){return`Double(${e})`}function de(e){return`Array(${JSON.stringify(e)})`}function ge(e){return`Map(${JSON.stringify(e)})`}function he(e){return`Map[](${JSON.stringify(e)})`}var xe="Null",we="None",be="Nil",Ae="",Te="UNDEFINED",Ee="Undefined";var J="time.Now()",Z="time.Now().Unix()",V="time.Now().UnixNano()",Q="time.Now().Weekday()",X="time.Now().Weekday().Chinese()",Re={Now:()=>J,NowUnix:()=>Z,NowUnixNano:()=>V,NowWeekday:()=>Q,NowWeekdayChinese:()=>X};0&&(module.exports={Array,Bigint,Boolean,Date,DateTime,Double,Empty,Float,Integer,Map,MapArray,Nil,None,Null,ObjectID,T1Collection,T1YError,T1YOS,TimeNow,TimeNowUnix,TimeNowUnixNano,TimeNowWeekday,TimeNowWeekdayChinese,Timestamp,UNDEFINED,Undefined,ValidationError,assertObjectID,convertDateTypes,createSignature,decryptAESGCM,encryptAESGCM,formatTimestampsToLocal,getSafeTimestamp,hmacSHA256Hex,hmacSHA256HexAsync,isNonEmptyArrayWithNonEmptyObjects,isNonEmptyObject,isPlainObject,sha256Hex,sha256HexAsync,timeNow,validateApiKey,validateAppId,validateBaseUrl,validateInitConfig,validateSecretKey,verifyHmacSHA256});
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/utils/errors.ts","../src/utils/validators.ts","../src/utils/convert.ts","../src/crypto/sha256.ts","../src/crypto/hmac.ts","../src/crypto/aes.ts","../src/crypto/sign.ts","../src/utils/url.ts","../src/utils/time.ts","../src/http/response.ts","../src/http/request.ts","../src/client/T1Collection.ts","../src/client/T1YOS.ts","../src/special-types/object-id.ts","../src/special-types/date-types.ts","../src/special-types/numeric-types.ts","../src/special-types/structured-types.ts","../src/special-types/null-types.ts","../src/special-types/time-helpers.ts"],"sourcesContent":["/**\n * t1yOS Serverless Platform JavaScript/TypeScript SDK\n *\n * @packageDocumentation\n *\n * @example\n * ```ts\n * import { T1YOS, ObjectID, timeNow } from 't1y-sdk-js'\n *\n * const client = new T1YOS({\n * appId: 1001,\n * apiKey: 'your-api-key-32-characters-here!',\n * secretKey: 'your-secret-key-32-characters!',\n * })\n *\n * await client.init()\n *\n * // Database operations\n * await client.db.collection('users').insertOne({\n * name: 'Alice',\n * age: 25,\n * createdAt: timeNow.Now(),\n * })\n *\n * const { data } = await client.db.collection('users').findOne({ name: 'Alice' })\n * console.log(data.result)\n * ```\n */\n\n// Main client classes\nexport { T1YOS } from './client/T1YOS'\nexport { T1Collection } from './client/T1Collection'\n\n// Special type helpers\nexport {\n ObjectID,\n Date,\n DateTime,\n Timestamp,\n Boolean,\n Integer,\n Bigint,\n Float,\n Double,\n Array,\n Map,\n MapArray,\n Null,\n None,\n Nil,\n Empty,\n UNDEFINED,\n Undefined,\n TimeNow,\n TimeNowUnix,\n TimeNowUnixNano,\n TimeNowWeekday,\n TimeNowWeekdayChinese,\n timeNow,\n} from './special-types'\n\n// Cryptographic utilities (for advanced use)\nexport {\n sha256Hex,\n sha256HexAsync,\n hmacSHA256Hex,\n hmacSHA256HexAsync,\n verifyHmacSHA256,\n encryptAESGCM,\n decryptAESGCM,\n createSignature,\n getSafeTimestamp,\n} from './crypto'\n\n// Utility functions\nexport {\n formatTimestampsToLocal,\n convertDateTypes,\n validateInitConfig,\n validateAppId,\n validateApiKey,\n validateSecretKey,\n validateBaseUrl,\n assertObjectID,\n isNonEmptyObject,\n isPlainObject,\n isNonEmptyArrayWithNonEmptyObjects,\n} from './utils'\n\n// Custom error classes\nexport { T1YError, ValidationError } from './utils/errors'\n\n// Core types\nexport type {\n T1YOSConfig,\n T1YOSInternalConfig,\n HttpMethod,\n ApiResponse,\n InsertResult,\n InsertManyResult,\n DeleteResult,\n DeleteManyResult,\n UpdateResult,\n UpdateManyResult,\n FindResult,\n Pagination,\n PaginationResult,\n AggregateResult,\n InitResult,\n} from './types'\n\nexport type { AESGCMPayload, SignatureInput } from './crypto'\n\n// Special type marker types\nexport type {\n ObjectIDMarker,\n DateMarker,\n DateTimeMarker,\n TimestampMarker,\n BooleanMarker,\n IntegerMarker,\n BigintMarker,\n FloatMarker,\n DoubleMarker,\n ArrayMarker,\n MapMarker,\n MapArrayMarker,\n NullMarker,\n UndefinedMarker,\n TimeNowMarker,\n TimeNowUnixMarker,\n TimeNowUnixNanoMarker,\n TimeNowWeekdayMarker,\n TimeNowWeekdayChineseMarker,\n SpecialTypeMarker,\n} from './types/special-types'\n\n// Default export\nexport { default } from './client/T1YOS'\n","/** Default base URL for the t1yOS platform */\nexport const DEFAULT_BASE_URL = 'https://myapp.t1y.net'\n\n/** Minimum valid application ID */\nexport const MIN_APP_ID = 1001\n\n/** Required length for API Key */\nexport const API_KEY_LENGTH = 32\n\n/** Required length for Secret Key */\nexport const SECRET_KEY_LENGTH = 32\n\n/** Default application version */\nexport const DEFAULT_VERSION = 0\n\n/** Default time format for createdAt/updatedAt fields */\nexport const DEFAULT_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'\n\n/** Default time offset in seconds */\nexport const DEFAULT_OFFSET = 0\n\n/** Default safe mode setting */\nexport const DEFAULT_SAFE_MODE = false\n\n/** Maximum time difference allowed for request timestamp (seconds) */\nexport const MAX_TIME_DIFF = 10\n\n/** Request timeout in milliseconds (5 minutes) */\nexport const REQUEST_TIMEOUT_MS = 5 * 60 * 1000\n\n/** Maximum page size for find queries */\nexport const MAX_PAGE_SIZE = 100\n\n/** Default page size */\nexport const DEFAULT_PAGE_SIZE = 10\n\n/** ObjectID hex string length */\nexport const OBJECT_ID_LENGTH = 24\n\n/** ObjectID hex pattern */\nexport const OBJECT_ID_PATTERN = /^[0-9a-fA-F]{24}$/\n\n/** API version prefix */\nexport const API_VERSION = 'v5'\n","/**\n * Custom error class for t1yOS SDK errors.\n * Wraps API error responses with code, message, and data.\n */\nexport class T1YError extends Error {\n /** HTTP status or error code */\n code: number\n /** Response data from server (if any) */\n data: unknown\n\n constructor(code: number, message: string, data?: unknown) {\n super(message)\n this.name = 'T1YError'\n this.code = code\n this.data = data\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n data: this.data,\n }\n }\n}\n\n/**\n * Validation error thrown when configuration parameters are invalid.\n */\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n","import { MIN_APP_ID, API_KEY_LENGTH, SECRET_KEY_LENGTH, OBJECT_ID_PATTERN } from '../constants'\nimport { ValidationError } from './errors'\nimport type { T1YOSConfig } from '../types'\n\n/**\n * Validate that the application ID is a valid integer >= MIN_APP_ID.\n */\nexport function validateAppId(appId: number): void {\n if (!Number.isInteger(appId)) {\n throw new ValidationError('appId must be an integer')\n }\n if (appId < MIN_APP_ID) {\n throw new ValidationError(`appId must be >= ${MIN_APP_ID}`)\n }\n}\n\n/**\n * Validate that the API Key is exactly the required length.\n */\nexport function validateApiKey(apiKey: string): void {\n if (typeof apiKey !== 'string') {\n throw new ValidationError('apiKey must be a string')\n }\n if (apiKey.length !== API_KEY_LENGTH) {\n throw new ValidationError(\n `apiKey must be exactly ${API_KEY_LENGTH} characters (got ${apiKey.length})`\n )\n }\n}\n\n/**\n * Validate that the Secret Key is exactly the required length.\n */\nexport function validateSecretKey(secretKey: string): void {\n if (typeof secretKey !== 'string') {\n throw new ValidationError('secretKey must be a string')\n }\n if (secretKey.length !== SECRET_KEY_LENGTH) {\n throw new ValidationError(\n `secretKey must be exactly ${SECRET_KEY_LENGTH} characters (got ${secretKey.length})`\n )\n }\n}\n\n/**\n * Validate the base URL format.\n */\nexport function validateBaseUrl(baseUrl: string): void {\n if (!/^https?:\\/\\//.test(baseUrl)) {\n throw new ValidationError('baseUrl must start with \"http://\" or \"https://\"')\n }\n}\n\n/**\n * Validate all configuration parameters at once.\n */\nexport function validateInitConfig(config: T1YOSConfig): void {\n if (config.baseUrl !== undefined) {\n validateBaseUrl(config.baseUrl)\n }\n validateAppId(config.appId)\n validateApiKey(config.apiKey)\n validateSecretKey(config.secretKey)\n\n if (config.version !== undefined && (!Number.isInteger(config.version) || config.version < 0)) {\n throw new ValidationError('version must be a non-negative integer')\n }\n}\n\n/**\n * Validate an ObjectID hex string.\n * Returns true if valid, throws otherwise.\n */\nexport function assertObjectID(idStr: string, name = 'ObjectID'): boolean {\n if (typeof idStr !== 'string') {\n throw new ValidationError(`${name} must be a string`)\n }\n if (!OBJECT_ID_PATTERN.test(idStr)) {\n throw new ValidationError(`Invalid ${name} string: \"${idStr}\"`)\n }\n return true\n}\n","/**\n * Recursively convert JavaScript Date objects and timestamp numbers\n * into the marker string format that the server's GetDataTypes() recognizes.\n *\n * - Date objects → `Date('ISO-8601')`\n * - Numbers >= 10 digits → `Timestamp('unix')`\n * - Already-marker strings (starting with recognized prefixes) are passed through\n */\nexport function convertDateTypes(value: unknown): unknown {\n if (value instanceof Date) {\n return `Date('${value.toISOString()}')`\n }\n\n if (typeof value === 'number') {\n const str = String(value)\n // 10+ digit integer → Timestamp\n if (/^\\d{10,}$/.test(str)) {\n return `Timestamp('${str}')`\n }\n return value\n }\n\n if (Array.isArray(value)) {\n return value.map((v) => convertDateTypes(v))\n }\n\n if (value && typeof value === 'object') {\n const obj: Record<string, unknown> = {}\n for (const key in value as Record<string, unknown>) {\n if (Object.prototype.hasOwnProperty.call(value, key)) {\n obj[key] = convertDateTypes((value as Record<string, unknown>)[key])\n }\n }\n return obj\n }\n\n return value\n}\n\n/**\n * Check if a value is a non-null, non-array object with at least one key.\n */\nexport function isNonEmptyObject(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length > 0\n )\n}\n\n/**\n * Check if a value is a plain object (non-null, non-array).\n */\nexport function isPlainObject(value: unknown): boolean {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Check if a value is a non-empty array where every element is a non-empty object.\n */\nexport function isNonEmptyArrayWithNonEmptyObjects(value: unknown): boolean {\n if (!Array.isArray(value) || value.length === 0) {\n return false\n }\n return value.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n !Array.isArray(item) &&\n Object.keys(item).length > 0\n )\n}\n","/**\n * SHA-256 hashing — works in both Node.js and browser environments.\n *\n * Node.js (CJS): Uses node:crypto (synchronous via require)\n * Node.js (ESM): Falls back to pure-JS (works correctly for all byte values)\n * Browser: Uses pure-JS implementation\n */\n\n// Detect if require is available (CJS context)\nfunction getNodeRequire(): ((m: string) => unknown) | null {\n try {\n // In CJS, `require` is a local variable\n if (typeof require !== 'undefined') {\n return require\n }\n } catch {\n // require is not defined (ESM or browser)\n }\n return null\n}\n\n/**\n * Compute the SHA-256 hash of a string and return the hex digest.\n *\n * For the signing path: the input is always a UTF-8 string\n * (method, URL, body JSON, etc.), so this works correctly.\n *\n * For raw binary data (from HMAC inner hash), use sha256RawBytesHex instead.\n *\n * @param data - Input string to hash (UTF-8)\n * @returns Hex-encoded SHA-256 hash (64 hex characters)\n */\nexport function sha256Hex(data: string): string {\n const nodeReq = getNodeRequire()\n if (nodeReq) {\n try {\n const nodeCrypto = nodeReq('node:crypto') as {\n createHash: (alg: string) => { update: (d: string) => { digest: (enc: string) => string } }\n }\n return nodeCrypto.createHash('sha256').update(data).digest('hex')\n } catch {\n // fall through to pure-JS\n }\n }\n\n // Pure-JS path: encode string as UTF-8 bytes and hash\n const bytes = utf8ToBytes(data)\n return sha256RawBytesHex(bytes)\n}\n\n/**\n * Compute SHA-256 of raw bytes and return hex digest.\n * Used internally by HMAC for hashing binary key data.\n */\nexport function sha256RawBytesHex(bytes: Uint8Array): string {\n return sha256Raw(bytes)\n}\n\n/**\n * Compute SHA-256 hash asynchronously using Web Crypto API.\n */\nexport async function sha256HexAsync(data: string): Promise<string> {\n const nodeReq = getNodeRequire()\n if (nodeReq) {\n try {\n const nodeCrypto = nodeReq('node:crypto') as {\n createHash: (alg: string) => { update: (d: string) => { digest: (enc: string) => string } }\n }\n return nodeCrypto.createHash('sha256').update(data).digest('hex')\n } catch {\n // fall through\n }\n }\n\n const encoder = new TextEncoder()\n const hashBuffer = await crypto.subtle.digest(\n 'SHA-256',\n encoder.encode(data) as Uint8Array<ArrayBuffer>\n )\n return Array.from(new Uint8Array(hashBuffer))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n// ==================== Pure-JS SHA-256 ====================\n\n/**\n * UTF-8 encode a JavaScript string to Uint8Array.\n * Uses TextEncoder when available, falls back to manual encoding.\n */\nfunction utf8ToBytes(str: string): Uint8Array {\n if (typeof TextEncoder !== 'undefined') {\n return new TextEncoder().encode(str) as Uint8Array<ArrayBuffer>\n }\n // Fallback: manual UTF-8 encoding\n const bytes: number[] = []\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i)\n if (c < 0x80) {\n bytes.push(c)\n } else if (c < 0x800) {\n bytes.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f))\n } else if (c < 0xd800 || c >= 0xe000) {\n bytes.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f))\n } else {\n // surrogate pair\n i++\n const c2 = str.charCodeAt(i)\n const cp = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff)\n bytes.push(\n 0xf0 | (cp >> 18),\n 0x80 | ((cp >> 12) & 0x3f),\n 0x80 | ((cp >> 6) & 0x3f),\n 0x80 | (cp & 0x3f)\n )\n }\n }\n return new Uint8Array(bytes) as Uint8Array<ArrayBuffer>\n}\n\n/** SHA-256 implementation that operates on raw bytes */\nfunction sha256Raw(bytes: Uint8Array): string {\n const K = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n ]\n\n // Build message schedule\n const msgByteLen = bytes.length\n const msgBitLen = msgByteLen * 8\n\n // Allocate padded message: original bytes + 0x80 + zeros + 8-byte length\n const padLen = (64 - ((msgByteLen + 9) % 64)) % 64\n const totalLen = msgByteLen + 1 + padLen + 8\n const padded = new Uint8Array(totalLen)\n padded.set(bytes)\n padded[msgByteLen] = 0x80\n // Write length as 64-bit big-endian\n for (let i = 0; i < 8; i++) {\n padded[totalLen - 8 + i] = Number((BigInt(msgBitLen) >> BigInt((7 - i) * 8)) & BigInt(0xff))\n }\n\n const H = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n ]\n\n // Process each 512-bit chunk\n for (let offset = 0; offset < totalLen; offset += 64) {\n const W = new Array<number>(64)\n\n for (let t = 0; t < 16; t++) {\n W[t] =\n (padded[offset + t * 4]! << 24) |\n (padded[offset + t * 4 + 1]! << 16) |\n (padded[offset + t * 4 + 2]! << 8) |\n padded[offset + t * 4 + 3]!\n }\n\n for (let t = 16; t < 64; t++) {\n const s0 = (rotr(W[t - 15]!, 7) ^ rotr(W[t - 15]!, 18) ^ (W[t - 15]! >>> 3)) >>> 0\n const s1 = (rotr(W[t - 2]!, 17) ^ rotr(W[t - 2]!, 19) ^ (W[t - 2]! >>> 10)) >>> 0\n W[t] = (W[t - 16]! + s0 + W[t - 7]! + s1) >>> 0\n }\n\n let [a, b, c, d, e, f, g, h] = H\n\n for (let t = 0; t < 64; t++) {\n const S1 = (rotr(e!, 6) ^ rotr(e!, 11) ^ rotr(e!, 25)) >>> 0\n const ch = ((e! & f!) ^ (~e! & g!)) >>> 0\n const temp1 = (h! + S1 + ch + K[t]! + W[t]!) >>> 0\n const S0 = (rotr(a!, 2) ^ rotr(a!, 13) ^ rotr(a!, 22)) >>> 0\n const maj = ((a! & b!) ^ (a! & c!) ^ (b! & c!)) >>> 0\n const temp2 = (S0 + maj) >>> 0\n\n h = g\n g = f\n f = e\n e = (d! + temp1) >>> 0\n d = c\n c = b\n b = a\n a = (temp1 + temp2) >>> 0\n }\n\n H[0] = (H[0]! + a!) >>> 0\n H[1] = (H[1]! + b!) >>> 0\n H[2] = (H[2]! + c!) >>> 0\n H[3] = (H[3]! + d!) >>> 0\n H[4] = (H[4]! + e!) >>> 0\n H[5] = (H[5]! + f!) >>> 0\n H[6] = (H[6]! + g!) >>> 0\n H[7] = (H[7]! + h!) >>> 0\n }\n\n return H.map((v) => v.toString(16).padStart(8, '0')).join('')\n}\n\nfunction rotr(x: number, n: number): number {\n return (x >>> n) | (x << (32 - n))\n}\n","/**\n * HMAC-SHA256 implementation — works in both Node.js and browser environments.\n *\n * Node.js (CJS): Uses node:crypto (synchronous via require)\n * Browser / ESM: Uses pure-JS implementation operating on Uint8Array\n */\n\nimport { sha256RawBytesHex } from './sha256'\n\n// Detect if require is available (CJS context)\nfunction getNodeRequire(): ((m: string) => unknown) | null {\n try {\n if (typeof require !== 'undefined') {\n return require\n }\n } catch {\n // require is not defined (ESM or browser)\n }\n return null\n}\n\n/**\n * Compute HMAC-SHA256 and return hex digest.\n *\n * This is intentionally synchronous because it's called in the request\n * signing path, which must be fast and cannot defer to async.\n *\n * @param secret - The secret key (raw string, used as-is as bytes)\n * @param message - The message to sign\n * @returns Hex-encoded HMAC-SHA256 signature (64 hex characters)\n */\nexport function hmacSHA256Hex(secret: string, message: string): string {\n const nodeReq = getNodeRequire()\n if (nodeReq) {\n try {\n const nodeCrypto = nodeReq('node:crypto') as {\n createHmac: (\n alg: string,\n key: string\n ) => { update: (d: string) => { digest: (enc: string) => string } }\n }\n return nodeCrypto.createHmac('sha256', secret).update(message).digest('hex')\n } catch {\n // fall through to pure-JS\n }\n }\n\n // Pure-JS HMAC-SHA256 implementation\n return hmacSHA256Pure(secret, message)\n}\n\n/**\n * Compute HMAC-SHA256 asynchronously using Web Crypto API.\n */\nexport async function hmacSHA256HexAsync(secret: string, message: string): Promise<string> {\n const nodeReq = getNodeRequire()\n if (nodeReq) {\n try {\n const nodeCrypto = nodeReq('node:crypto') as {\n createHmac: (\n alg: string,\n key: string\n ) => { update: (d: string) => { digest: (enc: string) => string } }\n }\n return nodeCrypto.createHmac('sha256', secret).update(message).digest('hex')\n } catch {\n // fall through\n }\n }\n\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret) as Uint8Array<ArrayBuffer>,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n )\n const signature = await crypto.subtle.sign(\n 'HMAC',\n key,\n encoder.encode(message) as Uint8Array<ArrayBuffer>\n )\n return Array.from(new Uint8Array(signature))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Verify an HMAC-SHA256 signature using constant-time comparison.\n */\nexport function verifyHmacSHA256(secret: string, message: string, signature: string): boolean {\n if (typeof signature !== 'string') return false\n const expected = hmacSHA256Hex(secret, message)\n return timingSafeEqual(expected, signature.toLowerCase())\n}\n\n/** Constant-time string comparison */\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false\n let result = 0\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i)\n }\n return result === 0\n}\n\n// ==================== Pure-JS HMAC-SHA256 ====================\n\n/**\n * HMAC-SHA256 using only pure-JS SHA-256 (byte-oriented).\n *\n * Implements: HMAC(K, m) = H((K' XOR opad) || H((K' XOR ipad) || m))\n * where H is SHA-256, K' is the processed key, ipad=0x36, opad=0x5c\n *\n * This implementation uses Uint8Array for ALL binary data,\n * avoiding the corruption issue with raw-byte-in-JS-strings.\n */\nfunction hmacSHA256Pure(secret: string, message: string): string {\n const BLOCK_SIZE = 64\n\n // Convert secret and message to UTF-8 bytes\n let keyBytes = utf8ToBytes(secret)\n const msgBytes = utf8ToBytes(message)\n\n // If key is longer than block size, hash it first\n if (keyBytes.length > BLOCK_SIZE) {\n keyBytes = hexToBytes(sha256RawBytesHex(keyBytes))\n }\n\n // Pad key to block size (or truncate — should not happen for SHA-256)\n const paddedKey = new Uint8Array(BLOCK_SIZE)\n paddedKey.set(keyBytes.subarray(0, Math.min(keyBytes.length, BLOCK_SIZE)))\n // rest is already zero-initialized\n\n // Compute inner: H((key XOR ipad) || message)\n const ipad = new Uint8Array(BLOCK_SIZE)\n ipad.fill(0x36)\n const innerKey = xorBytes(paddedKey, ipad)\n const innerData = new Uint8Array(BLOCK_SIZE + msgBytes.length)\n innerData.set(innerKey)\n innerData.set(msgBytes, BLOCK_SIZE)\n const innerHash = hexToBytes(sha256RawBytesHex(innerData))\n\n // Compute outer: H((key XOR opad) || innerHash)\n const opad = new Uint8Array(BLOCK_SIZE)\n opad.fill(0x5c)\n const outerKey = xorBytes(paddedKey, opad)\n const outerData = new Uint8Array(BLOCK_SIZE + innerHash.length)\n outerData.set(outerKey)\n outerData.set(innerHash, BLOCK_SIZE)\n\n return sha256RawBytesHex(outerData)\n}\n\n/** XOR two Uint8Arrays (must be same length) */\nfunction xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n const result = new Uint8Array(a.length)\n for (let i = 0; i < a.length; i++) {\n result[i] = a[i]! ^ b[i]!\n }\n return result as Uint8Array<ArrayBuffer>\n}\n\n/** UTF-8 encode a string to Uint8Array */\nfunction utf8ToBytes(str: string): Uint8Array {\n if (typeof TextEncoder !== 'undefined') {\n return new TextEncoder().encode(str) as Uint8Array<ArrayBuffer>\n }\n // Fallback for ancient browsers\n const bytes: number[] = []\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i)\n if (c < 0x80) {\n bytes.push(c)\n } else if (c < 0x800) {\n bytes.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f))\n } else if (c < 0xd800 || c >= 0xe000) {\n bytes.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f))\n } else {\n i++\n const c2 = str.charCodeAt(i)\n const cp = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff)\n bytes.push(\n 0xf0 | (cp >> 18),\n 0x80 | ((cp >> 12) & 0x3f),\n 0x80 | ((cp >> 6) & 0x3f),\n 0x80 | (cp & 0x3f)\n )\n }\n }\n return new Uint8Array(bytes) as Uint8Array<ArrayBuffer>\n}\n\n/** Convert hex string to Uint8Array */\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2)\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16)\n }\n return bytes as Uint8Array<ArrayBuffer>\n}\n","/**\n * AES-256-GCM encryption and decryption.\n *\n * Compatible with the t1yOS Go server's AES-256-GCM implementation.\n * Payload format: { \"n\": \"<nonce base64>\", \"j\": \"<ciphertext base64>\", \"t\": \"<tag base64>\" }\n *\n * Works in both Node.js and browser via Web Crypto API.\n */\n\n// Detect Web Crypto API (browser globalThis.crypto.subtle or Node require('node:crypto').webcrypto)\nfunction getCrypto(): { subtle: SubtleCrypto; getRandomValues: (arr: Uint8Array) => Uint8Array } {\n if (typeof globalThis !== 'undefined') {\n // Browser\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.subtle) {\n return globalThis.crypto as ReturnType<typeof getCrypto>\n }\n // Node.js — try node:crypto.webcrypto\n try {\n const nodeCryptoModule = (globalThis as unknown as Record<string, unknown>).require\n ? (((globalThis as unknown as Record<string, unknown>).require as (m: string) => unknown)(\n 'node:crypto'\n ) as {\n webcrypto: { subtle: SubtleCrypto; getRandomValues: (arr: Uint8Array) => Uint8Array }\n })\n : null\n if (nodeCryptoModule?.webcrypto) {\n return nodeCryptoModule.webcrypto\n }\n } catch {\n // fall through\n }\n }\n throw new Error('Web Crypto API is not available in this environment')\n}\n\n/** GCM authentication tag length in bytes */\nconst AES_GCM_TAG_LENGTH = 16\n\n/** AES-GCM nonce/IV length in bytes */\nconst AES_GCM_NONCE_LENGTH = 12\n\n// === Base64 helpers (compatible with Go's encoding/base64.StdEncoding) ===\n\nfunction encodeBase64(uint8array: Uint8Array): string {\n let binary = ''\n const len = uint8array.byteLength\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(uint8array[i]!)\n }\n return btoa(binary)\n}\n\nfunction decodeBase64(b64: string): Uint8Array<ArrayBuffer> {\n const binary = atob(b64)\n const len = binary.length\n const bytes = new Uint8Array(len) as Uint8Array<ArrayBuffer>\n for (let i = 0; i < len; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return bytes\n}\n\n/**\n * AES-256-GCM encrypted payload structure.\n * Matches the Go server's AESGCMEncryptedPayload struct.\n */\nexport interface AESGCMPayload {\n /** Base64-encoded nonce */\n n: string\n /** Base64-encoded ciphertext */\n j: string\n /** Base64-encoded authentication tag */\n t: string\n}\n\n/**\n * Encrypt data using AES-256-GCM.\n *\n * @param data - The plaintext data to encrypt (string)\n * @param keyBytes - 32-byte encryption key (Uint8Array)\n * @returns JSON string of { n, j, t } payload\n */\nexport async function encryptAESGCM(data: string, keyBytes: Uint8Array): Promise<string> {\n if (!(keyBytes instanceof Uint8Array)) {\n throw new Error('key must be Uint8Array')\n }\n if (keyBytes.length !== 32) {\n throw new Error('key length must be 32 bytes for AES-256-GCM')\n }\n\n const cryptoApi = getCrypto()\n\n const key = await cryptoApi.subtle.importKey(\n 'raw',\n keyBytes as Uint8Array<ArrayBuffer>,\n 'AES-GCM',\n false,\n ['encrypt']\n )\n\n const nonce = new Uint8Array(AES_GCM_NONCE_LENGTH)\n cryptoApi.getRandomValues(nonce)\n\n const encodedData = new TextEncoder().encode(data) as Uint8Array<ArrayBuffer>\n\n const encrypted = new Uint8Array(\n await cryptoApi.subtle.encrypt(\n { name: 'AES-GCM', iv: nonce as Uint8Array<ArrayBuffer>, tagLength: 128 },\n key,\n encodedData\n )\n )\n\n const ciphertext = encrypted.slice(0, encrypted.length - AES_GCM_TAG_LENGTH)\n const tag = encrypted.slice(encrypted.length - AES_GCM_TAG_LENGTH)\n\n const payload: AESGCMPayload = {\n n: encodeBase64(nonce),\n j: encodeBase64(ciphertext),\n t: encodeBase64(tag),\n }\n\n return JSON.stringify(payload)\n}\n\n/**\n * Decrypt data using AES-256-GCM.\n *\n * @param jsonPayload - JSON string of { n, j, t } payload\n * @param keyBytes - 32-byte decryption key (Uint8Array)\n * @returns Decrypted plaintext string\n */\nexport async function decryptAESGCM(jsonPayload: string, keyBytes: Uint8Array): Promise<string> {\n if (!(keyBytes instanceof Uint8Array)) {\n throw new Error('key must be Uint8Array')\n }\n if (keyBytes.length !== 32) {\n throw new Error('key length must be 32 bytes for AES-256-GCM')\n }\n\n const cryptoApi = getCrypto()\n\n const { n, j, t } = JSON.parse(jsonPayload) as AESGCMPayload\n\n const nonce = decodeBase64(n)\n const ciphertext = decodeBase64(j)\n const tag = decodeBase64(t)\n\n const sealed = new Uint8Array(ciphertext.length + tag.length)\n sealed.set(ciphertext)\n sealed.set(tag, ciphertext.length)\n\n const key = await cryptoApi.subtle.importKey(\n 'raw',\n keyBytes as Uint8Array<ArrayBuffer>,\n 'AES-GCM',\n false,\n ['decrypt']\n )\n\n const decrypted = await cryptoApi.subtle.decrypt(\n { name: 'AES-GCM', iv: nonce as Uint8Array<ArrayBuffer>, tagLength: 128 },\n key,\n sealed as Uint8Array<ArrayBuffer>\n )\n\n return new TextDecoder().decode(decrypted)\n}\n","/**\n * Request signing algorithm for T1Y v5 RESTful API authentication.\n *\n * Implements the same signing logic as the Go server's middleware/v5_auth.go:\n *\n * message = METHOD + \"\\n\" + URL_PATH_AND_QUERY + \"\\n\" + SHA256(body) + \"\\n\" + appId + \"\\n\" + timestamp\n * signature = HMAC-SHA256(secretKey, message)\n */\n\nimport { sha256Hex } from './sha256'\nimport { hmacSHA256Hex } from './hmac'\n\n/**\n * Parameters for creating a request signature.\n */\nexport interface SignatureInput {\n /** HTTP method in uppercase (GET, POST, PUT, DELETE) */\n method: string\n /** URL path including query string, e.g. /v5/classes/users?field=name */\n pathAndQuery: string\n /** Request body as a raw string (empty string for GET requests) */\n body: string\n /** Application ID */\n appId: number\n /** 10-digit Unix timestamp (UTC + offset) */\n timestamp: number\n /** 32-character Secret Key */\n secretKey: string\n}\n\n/**\n * Create an HMAC-SHA256 signature for a T1Y API request.\n *\n * The message format is (each line separated by \\n):\n * 1. HTTP method (uppercase)\n * 2. URL path + query string\n * 3. SHA-256 hex digest of the request body\n * 4. Application ID (as string)\n * 5. Unix timestamp (as string)\n *\n * @param input - Signature parameters\n * @returns 64-character hex-encoded HMAC-SHA256 signature\n *\n * @example\n * ```ts\n * const sign = createSignature({\n * method: 'POST',\n * pathAndQuery: '/v5/classes/users',\n * body: '{\"name\":\"Alice\"}',\n * appId: 1001,\n * timestamp: 1705312200,\n * secretKey: '17b784e359c946ffa65eebbf9ce29752',\n * })\n * // Set as X-T1Y-Safe-Sign header\n * ```\n */\nexport function createSignature(input: SignatureInput): string {\n const { method, pathAndQuery, body, appId, timestamp, secretKey } = input\n\n const bodyHash = sha256Hex(body)\n\n const message = [\n method.toUpperCase(),\n pathAndQuery,\n bodyHash,\n String(appId),\n String(timestamp),\n ].join('\\n')\n\n return hmacSHA256Hex(secretKey, message)\n}\n\n/**\n * Get the current UTC Unix timestamp adjusted by the given offset.\n *\n * @param offset - Time offset in seconds (from server init)\n * @returns 10-digit Unix timestamp string\n */\nexport function getSafeTimestamp(offset: number): string {\n return String(Math.floor(Date.now() / 1000) + offset)\n}\n","/**\n * Strip trailing slashes from a base URL.\n */\nexport function normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, '')\n}\n\n/**\n * Append query parameters from a params object to a URL.\n * Skips undefined and null values.\n * String values are added directly; others are JSON-stringified.\n */\nexport function appendQueryParams(url: URL, params: Record<string, unknown>): void {\n for (const key of Object.keys(params)) {\n const value = params[key]\n if (value === undefined || value === null) continue\n url.searchParams.set(key, typeof value === 'string' ? value : JSON.stringify(value))\n }\n}\n","import { DEFAULT_TIME_FORMAT } from '../constants'\n\n/**\n * Format a UTC date string to local time using the given format template.\n *\n * Format tokens:\n * YYYY - 4-digit year\n * MM - 2-digit month (01-12)\n * DD - 2-digit day (01-31)\n * HH - 2-digit hour (00-23)\n * mm - 2-digit minute (00-59)\n * ss - 2-digit second (00-59)\n */\nfunction formatLocalTime(utcString: string, format: string): string {\n const date = new Date(utcString)\n if (isNaN(date.getTime())) return utcString\n\n const pad = (n: number) => String(n).padStart(2, '0')\n\n return format\n .replace('YYYY', String(date.getFullYear()))\n .replace('MM', pad(date.getMonth() + 1))\n .replace('DD', pad(date.getDate()))\n .replace('HH', pad(date.getHours()))\n .replace('mm', pad(date.getMinutes()))\n .replace('ss', pad(date.getSeconds()))\n}\n\n/**\n * Recursively convert all `createdAt` and `updatedAt` fields in a data structure\n * from UTC strings to local time formatted strings.\n *\n * Returns a new object/array; does not mutate the original.\n */\nexport function formatTimestampsToLocal(\n data: unknown,\n format: string = DEFAULT_TIME_FORMAT\n): unknown {\n function traverse(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(traverse)\n }\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {}\n for (const key in value as Record<string, unknown>) {\n if (!Object.prototype.hasOwnProperty.call(value, key)) continue\n\n if (key === 'createdAt' || key === 'updatedAt') {\n result[key] = formatLocalTime((value as Record<string, unknown>)[key] as string, format)\n } else {\n result[key] = traverse((value as Record<string, unknown>)[key])\n }\n }\n return result\n }\n return value\n }\n\n return traverse(data)\n}\n","/**\n * Response handling — decryption, timestamp formatting, and error wrapping.\n */\n\nimport { decryptAESGCM } from '../crypto/aes'\nimport { formatTimestampsToLocal } from '../utils/time'\nimport { T1YError } from '../utils/errors'\nimport type { ApiResponse } from '../types/api'\n\n/**\n * Process a raw fetch Response into the SDK's standard ApiResponse format.\n *\n * Handles:\n * 1. JSON parsing or string fallback\n * 2. Safe mode AES-GCM decryption (response data has `j` field)\n * 3. Timestamp formatting (createdAt/updatedAt → local time)\n * 4. Error wrapping for non-2xx status codes\n *\n * @param response - Raw fetch Response object\n * @param isSafeMode - Whether safe mode encryption is active\n * @param secretKey - Secret key for decryption (as raw string, will be encoded to Uint8Array)\n * @param timeFormat - Time format for createdAt/updatedAt fields\n * @returns Processed ApiResponse\n */\nexport async function handleResponse<T = unknown>(\n response: Response,\n isSafeMode: boolean,\n secretKey: string,\n timeFormat: string\n): Promise<ApiResponse<T>> {\n // Try to parse response body\n let rawData: unknown\n const contentType = response.headers.get('content-type') || ''\n const responseText = await response.text()\n\n if (contentType.includes('application/json')) {\n try {\n rawData = JSON.parse(responseText)\n } catch {\n rawData = responseText\n }\n } else {\n rawData = responseText\n }\n\n // If safe mode is on and the response data looks encrypted (has `j` field),\n // decrypt it first\n if (\n isSafeMode &&\n rawData &&\n typeof rawData === 'object' &&\n 'j' in (rawData as Record<string, unknown>)\n ) {\n try {\n const decrypted = await decryptAESGCM(\n JSON.stringify(rawData),\n new TextEncoder().encode(secretKey)\n )\n\n // Try to parse decrypted result as JSON\n try {\n rawData = JSON.parse(decrypted)\n } catch {\n rawData = decrypted\n }\n } catch (err) {\n throw new T1YError(\n 400,\n 'AES-256-GCM decryption failed',\n err instanceof Error ? err.message : null\n )\n }\n }\n\n // If the response is a standard ApiResponse wrapper, format timestamps\n if (rawData && typeof rawData === 'object' && 'data' in (rawData as Record<string, unknown>)) {\n const apiResp = rawData as ApiResponse<T>\n apiResp.data = formatTimestampsToLocal(apiResp.data, timeFormat) as T\n\n // If the status code is not 2xx, throw a T1YError\n if (!response.ok) {\n throw new T1YError(\n apiResp.code || response.status,\n apiResp.message || response.statusText,\n apiResp.data\n )\n }\n\n return apiResp\n }\n\n // Handle non-standard responses\n if (!response.ok) {\n throw new T1YError(response.status, response.statusText, rawData)\n }\n\n // Raw success response — wrap in ApiResponse shape\n return {\n code: 0,\n message: 'ok',\n data: formatTimestampsToLocal(rawData, timeFormat) as T,\n }\n}\n\n/**\n * Handle fetch errors (network errors, timeouts, etc.)\n */\nexport function handleFetchError(error: unknown): never {\n // If the error has a response property (some fetch wrappers), try to process it\n if (error && typeof error === 'object' && 'response' in error) {\n const errWithResponse = error as { response: Response }\n // Async error — can't await here, throw as-is\n throw error\n }\n\n // Re-throw as T1YError if it's not already\n if (error instanceof T1YError) {\n throw error\n }\n\n if (error instanceof Error) {\n // Network error\n if (error.name === 'AbortError') {\n throw new T1YError(408, 'Request timeout', null)\n }\n throw new T1YError(0, error.message, null)\n }\n\n throw new T1YError(0, 'Unknown error', error)\n}\n","/**\n * Core HTTP request execution for the t1yOS SDK.\n *\n * Handles:\n * - URL construction (baseUrl + path + query params for GET)\n * - Date type conversion in params\n * - AES-256-GCM encryption (safe mode)\n * - Request signing (HMAC-SHA256)\n * - Auth header injection\n * - Response processing (decryption, timestamp formatting)\n */\n\nimport { encryptAESGCM } from '../crypto/aes'\nimport { createSignature, getSafeTimestamp } from '../crypto/sign'\nimport { convertDateTypes } from '../utils/convert'\nimport { appendQueryParams, normalizeBaseUrl } from '../utils/url'\nimport { REQUEST_TIMEOUT_MS } from '../constants'\nimport { handleResponse, handleFetchError } from './response'\nimport type { T1YOSInternalConfig, HttpMethod, ApiResponse } from '../types'\n\n/**\n * Options for a single HTTP request.\n */\nexport interface RequestOptions {\n /** HTTP method */\n method: HttpMethod\n /** API path (e.g., /v5/classes/users) */\n path: string\n /** Request parameters/body */\n params?: unknown\n /** Override encryption for this request (defaults to client.isSafeMode) */\n encryption?: boolean\n /** Request timeout in milliseconds (default: 5 minutes) */\n timeout?: number\n}\n\n/**\n * Execute an HTTP request to the t1yOS API with full auth and encryption handling.\n *\n * @param client - Internal client configuration\n * @param options - Request options\n * @returns The processed API response\n */\nexport async function executeRequest<T = unknown>(\n client: T1YOSInternalConfig,\n options: RequestOptions\n): Promise<ApiResponse<T>> {\n const { method, path, params, encryption, timeout } = options\n\n // Normalize base URL\n const baseUrl = normalizeBaseUrl(client.baseUrl)\n const isSafeMode = encryption ?? client.isSafeMode\n\n // Build URL\n const fullUrl = new URL(baseUrl + path)\n\n // Convert Date types in params\n const convertedParams = convertDateTypes(params)\n\n // Handle request body\n let bodyForRequest: BodyInit | undefined\n let rawBodyString = ''\n\n if (method !== 'GET') {\n // For non-GET requests, the body is the params\n if (isSafeMode && convertedParams !== undefined) {\n // Safe mode: encrypt the JSON body\n const encryptedBody = await encryptAESGCM(\n JSON.stringify(convertedParams),\n new TextEncoder().encode(client.secretKey)\n )\n bodyForRequest = encryptedBody\n rawBodyString = encryptedBody\n } else if (convertedParams !== undefined) {\n const jsonBody = JSON.stringify(convertedParams)\n bodyForRequest = jsonBody\n rawBodyString = jsonBody\n } else {\n rawBodyString = ''\n }\n } else if (\n convertedParams &&\n typeof convertedParams === 'object' &&\n Object.keys(convertedParams as object).length > 0\n ) {\n // For GET requests, append params as query string\n appendQueryParams(fullUrl, convertedParams as Record<string, unknown>)\n }\n\n // Compute timestamp with offset\n const timestamp = Number(getSafeTimestamp(client.offset))\n\n // Get the path + query for signing\n const originalURL = fullUrl.pathname + fullUrl.search\n\n // Create the HMAC-SHA256 signature\n const sign = createSignature({\n method,\n pathAndQuery: originalURL,\n body: rawBodyString,\n appId: client.appId,\n timestamp,\n secretKey: client.secretKey,\n })\n\n // Set up timeout with AbortController\n const controller = new AbortController()\n const timeoutMs = timeout ?? REQUEST_TIMEOUT_MS\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs)\n\n try {\n const response = await fetch(fullUrl.toString(), {\n method,\n headers: {\n 'X-T1Y-Application-ID': String(client.appId),\n 'X-T1Y-API-Key': client.apiKey,\n 'X-T1Y-Safe-Timestamp': String(timestamp),\n 'X-T1Y-Safe-Sign': sign,\n 'Content-Type': 'application/json',\n },\n body: method !== 'GET' ? bodyForRequest : undefined,\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n\n return await handleResponse<T>(response, isSafeMode, client.secretKey, client.timeFormat)\n } catch (error) {\n clearTimeout(timeoutId)\n return handleFetchError(error)\n }\n}\n","/**\n * T1Collection — Database collection class providing chainable CRUD and schema operations.\n *\n * Created via `client.db.collection('name')` — never instantiated directly.\n */\n\nimport { assertObjectID } from '../utils/validators'\nimport {\n isNonEmptyObject,\n isPlainObject,\n isNonEmptyArrayWithNonEmptyObjects,\n} from '../utils/convert'\nimport { MAX_PAGE_SIZE } from '../constants'\nimport type { T1YOS } from './T1YOS'\nimport type {\n ApiResponse,\n InsertResult,\n InsertManyResult,\n DeleteResult,\n DeleteManyResult,\n UpdateResult,\n UpdateManyResult,\n FindResult,\n PaginationResult,\n AggregateResult,\n} from '../types'\n\nexport class T1Collection {\n /** The parent T1YOS client */\n private client: T1YOS\n /** The collection (table) name */\n private name: string\n\n /**\n * @internal — Use `client.db.collection(name)` instead.\n */\n constructor(client: T1YOS, name: string) {\n this.client = client\n this.name = name\n }\n\n // ==================== Single Document Operations ====================\n\n /**\n * Insert one document into the collection.\n *\n * @param data - Document data (must be a non-empty plain object)\n * @returns Response with the inserted document's ObjectID\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').insertOne({\n * name: 'Alice',\n * age: 25,\n * })\n * console.log(data.objectId) // '507f1f77bcf86cd799439011'\n * ```\n */\n async insertOne(data: Record<string, unknown>): Promise<ApiResponse<InsertResult>> {\n if (!isNonEmptyObject(data)) {\n throw new TypeError('insertOne data must be a non-empty plain object')\n }\n return await this.client.request<InsertResult>('POST', `/v5/classes/${this.name}`, data)\n }\n\n /**\n * Delete one document by ObjectID.\n *\n * @param objectId - 24-character hex ObjectID string\n * @returns Response with deleted count\n *\n * @example\n * ```ts\n * await client.db.collection('users').deleteById('507f1f77bcf86cd799439011')\n * ```\n */\n async deleteById(objectId: string): Promise<ApiResponse<DeleteResult>> {\n assertObjectID(objectId)\n return await this.client.request<DeleteResult>('DELETE', `/v5/classes/${this.name}/${objectId}`)\n }\n\n /**\n * Update one document by ObjectID.\n *\n * @param objectId - 24-character hex ObjectID string\n * @param data - Update data (must be a non-empty plain object)\n * @returns Response with modified count\n *\n * @example\n * ```ts\n * await client.db.collection('users').updateById('507f1f77bcf86cd799439011', { name: 'Bob' })\n * ```\n */\n async updateById(\n objectId: string,\n data: Record<string, unknown>\n ): Promise<ApiResponse<UpdateResult>> {\n assertObjectID(objectId)\n if (!isNonEmptyObject(data)) {\n throw new TypeError('update data must be a non-empty plain object')\n }\n return await this.client.request<UpdateResult>(\n 'PUT',\n `/v5/classes/${this.name}/${objectId}`,\n data\n )\n }\n\n /**\n * Find one document by ObjectID.\n *\n * @param objectId - 24-character hex ObjectID string\n * @returns Response with the found document\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').findById('507f1f77bcf86cd799439011')\n * console.log(data.result) // { _id: '507f1f77...', name: 'Alice', ... }\n * ```\n */\n async findById(objectId: string): Promise<ApiResponse<FindResult>> {\n assertObjectID(objectId)\n return await this.client.request<FindResult>('GET', `/v5/classes/${this.name}/${objectId}`)\n }\n\n // ==================== Filter-based Single Operations ====================\n\n /**\n * Delete one document matching the filter.\n *\n * @param filter - Query filter (must be a non-empty plain object)\n * @returns Response with deleted count\n *\n * @example\n * ```ts\n * await client.db.collection('users').deleteOne({ name: 'Alice' })\n * ```\n */\n async deleteOne(filter: Record<string, unknown>): Promise<ApiResponse<DeleteResult>> {\n if (!isNonEmptyObject(filter)) {\n throw new TypeError('deleteOne filter must be a non-empty plain object')\n }\n return await this.client.request<DeleteResult>('DELETE', `/v5/classes/${this.name}/one`, filter)\n }\n\n /**\n * Update one document matching the filter.\n *\n * @param filter - Query filter to find the document\n * @param body - Update data (MongoDB update operators like $set, $inc, etc.)\n * @returns Response with modified count\n *\n * @example\n * ```ts\n * await client.db.collection('users').updateOne(\n * { name: 'Alice' },\n * { $set: { age: 26 } }\n * )\n * ```\n */\n async updateOne(\n filter: Record<string, unknown>,\n body: Record<string, unknown>\n ): Promise<ApiResponse<UpdateResult>> {\n if (!isNonEmptyObject(filter)) {\n throw new TypeError('updateOne filter must be a non-empty plain object')\n }\n if (!isNonEmptyObject(body)) {\n throw new TypeError('updateOne body must be a non-empty plain object')\n }\n return await this.client.request<UpdateResult>('PUT', `/v5/classes/${this.name}/one`, {\n filter,\n body,\n })\n }\n\n /**\n * Find one document matching the filter.\n *\n * @param filter - Query filter\n * @returns Response with the found document (or null if not found)\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').findOne({ name: 'Alice' })\n * ```\n */\n async findOne(filter: Record<string, unknown>): Promise<ApiResponse<FindResult>> {\n if (!isNonEmptyObject(filter)) {\n throw new TypeError('findOne filter must be a non-empty plain object')\n }\n return await this.client.request<FindResult>('POST', `/v5/classes/${this.name}/one`, filter)\n }\n\n // ==================== Bulk Operations ====================\n\n /**\n * Insert multiple documents into the collection.\n *\n * @param dataList - Array of document data (each must be a non-empty plain object)\n * @returns Response with inserted ObjectIDs and count\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').insertMany([\n * { name: 'Alice', age: 25 },\n * { name: 'Bob', age: 30 },\n * ])\n * console.log(data.insertedCount) // 2\n * ```\n */\n async insertMany(dataList: Record<string, unknown>[]): Promise<ApiResponse<InsertManyResult>> {\n if (!isNonEmptyArrayWithNonEmptyObjects(dataList)) {\n throw new TypeError(\n 'insertMany dataList must be a non-empty array of non-empty plain objects'\n )\n }\n return await this.client.request<InsertManyResult>(\n 'POST',\n `/v5/classes/${this.name}/many`,\n dataList\n )\n }\n\n /**\n * Delete multiple documents matching the filter.\n *\n * @param filter - Query filter (can be an empty object to match all)\n * @returns Response with deleted count\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').deleteMany({ age: { $lt: 18 } })\n * console.log(data.deletedCount) // 5\n * ```\n */\n async deleteMany(filter: Record<string, unknown>): Promise<ApiResponse<DeleteManyResult>> {\n if (!isPlainObject(filter)) {\n throw new TypeError('deleteMany filter must be a plain object')\n }\n return await this.client.request<DeleteManyResult>(\n 'DELETE',\n `/v5/classes/${this.name}/many`,\n filter\n )\n }\n\n /**\n * Update multiple documents matching the filter.\n *\n * @param filter - Query filter to match documents\n * @param body - Update data (MongoDB update operators)\n * @returns Response with modified count\n *\n * @example\n * ```ts\n * await client.db.collection('users').updateMany(\n * { status: 'inactive' },\n * { $set: { status: 'archived' } }\n * )\n * ```\n */\n async updateMany(\n filter: Record<string, unknown>,\n body: Record<string, unknown>\n ): Promise<ApiResponse<UpdateManyResult>> {\n if (!isPlainObject(filter)) {\n throw new TypeError('updateMany filter must be a plain object')\n }\n if (!isNonEmptyObject(body)) {\n throw new TypeError('updateMany body must be a non-empty plain object')\n }\n return await this.client.request<UpdateManyResult>('PUT', `/v5/classes/${this.name}/many`, {\n filter,\n body,\n })\n }\n\n // ==================== Advanced Queries ====================\n\n /**\n * Paginated find query with sorting and filtering.\n *\n * @param page - Page number (1-based, default: 1)\n * @param size - Page size (1-100, default: 10)\n * @param sort - Sort specification, e.g. `{ createdAt: -1 }` for newest first\n * @param filter - Query filter\n * @returns Response with paginated results and pagination metadata\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').find(\n * 1, // page\n * 20, // size\n * { createdAt: -1 }, // sort (newest first)\n * { age: { $gte: 18 } } // filter\n * )\n * console.log(data.results) // Array of documents\n * console.log(data.pagination) // { totalItems: 100, totalPages: 5 }\n * ```\n */\n async find(\n page: number = 1,\n size: number = 10,\n sort: Record<string, number> = { createdAt: -1 },\n filter: Record<string, unknown> = {}\n ): Promise<ApiResponse<PaginationResult>> {\n if (!Number.isInteger(page) || page < 1) {\n throw new TypeError('find page must be a positive integer')\n }\n if (!Number.isInteger(size) || size < 1) {\n throw new TypeError('find size must be a positive integer')\n }\n if (size > MAX_PAGE_SIZE) {\n size = MAX_PAGE_SIZE\n }\n if (!isNonEmptyObject(sort)) {\n throw new TypeError('find sort must be a non-empty plain object')\n }\n if (!isPlainObject(filter)) {\n throw new TypeError('find filter must be a plain object')\n }\n\n return await this.client.request<PaginationResult>('POST', `/v5/classes/${this.name}/find`, {\n page,\n size,\n sort,\n filter,\n })\n }\n\n /**\n * Execute a MongoDB aggregation pipeline.\n *\n * @param pipeline - Array of aggregation stages\n * @returns Response with aggregation results\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('orders').aggregate([\n * { $match: { status: 'completed' } },\n * { $group: { _id: '$category', total: { $sum: '$amount' } } },\n * { $sort: { total: -1 } },\n * ])\n * ```\n */\n async aggregate(pipeline: Record<string, unknown>[]): Promise<ApiResponse<AggregateResult>> {\n if (!Array.isArray(pipeline)) {\n throw new TypeError('aggregate pipeline must be an array')\n }\n return await this.client.request<AggregateResult>(\n 'POST',\n `/v5/classes/${this.name}/aggregate`,\n pipeline\n )\n }\n\n /**\n * Count documents matching a filter.\n *\n * Uses `POST /v5/classes/:name/count` with the filter as the request body.\n *\n * @param filter - Query filter (can be an empty object for total count)\n * @returns Response with `data.count`\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').count({ status: 'active' })\n * console.log(data.count) // 42\n * ```\n */\n async count(filter: Record<string, unknown> = {}): Promise<ApiResponse<{ count: number }>> {\n if (!isPlainObject(filter)) {\n throw new TypeError('count filter must be a plain object')\n }\n return await this.client.request<{ count: number }>(\n 'POST',\n `/v5/classes/${this.name}/count`,\n filter\n )\n }\n\n /**\n * Get distinct values for a field, optionally filtered.\n *\n * Uses `POST /v5/classes/:name/distinct/:field` with the filter as the request body.\n *\n * @param fieldName - The field to get distinct values for\n * @param filter - Optional filter to narrow the documents\n * @returns Response with `data.results` containing distinct values\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('users').distinct('city')\n * console.log(data.results) // ['Beijing', 'Shanghai', ...]\n * ```\n */\n async distinct(\n fieldName: string,\n filter: Record<string, unknown> = {}\n ): Promise<ApiResponse<{ results: unknown[] }>> {\n if (typeof fieldName !== 'string' || fieldName.length === 0) {\n throw new TypeError('distinct fieldName must be a non-empty string')\n }\n if (!isPlainObject(filter)) {\n throw new TypeError('distinct filter must be a plain object')\n }\n return await this.client.request<{ results: unknown[] }>(\n 'POST',\n `/v5/classes/${this.name}/distinct/${encodeURIComponent(fieldName)}`,\n filter\n )\n }\n\n // ==================== Schema Management ====================\n\n /**\n * Create this collection (table) in the application's database.\n *\n * @example\n * ```ts\n * await client.db.collection('posts').create()\n * ```\n */\n async create(): Promise<ApiResponse> {\n return await this.client.request('POST', `/v5/schemas/${encodeURIComponent(this.name)}`)\n }\n\n /**\n * Clear all documents from this collection without dropping it.\n *\n * @returns Response with `data.deletedCount`\n *\n * @example\n * ```ts\n * const { data } = await client.db.collection('temp').clear()\n * console.log(data.deletedCount) // 150\n * ```\n */\n async clear(): Promise<ApiResponse<{ deletedCount: number }>> {\n return await this.client.request<{ deletedCount: number }>(\n 'PUT',\n `/v5/schemas/${encodeURIComponent(this.name)}`\n )\n }\n\n /**\n * Drop (delete) this collection entirely.\n *\n * @example\n * ```ts\n * await client.db.collection('old_collection').drop()\n * ```\n */\n async drop(): Promise<ApiResponse> {\n return await this.client.request('DELETE', `/v5/schemas/${encodeURIComponent(this.name)}`)\n }\n}\n\nexport default T1Collection\n","/**\n * T1YOS — Main client class for the t1yOS Serverless Platform SDK.\n *\n * Provides:\n * - Initialization with server time sync\n * - Chainable database operations via `db.collection(name)`\n * - Cloud function invocation\n * - Metadata retrieval\n * - Cryptographic utilities\n */\n\nimport {\n DEFAULT_BASE_URL,\n DEFAULT_VERSION,\n DEFAULT_SAFE_MODE,\n DEFAULT_TIME_FORMAT,\n DEFAULT_OFFSET,\n} from '../constants'\nimport { validateInitConfig, assertObjectID } from '../utils/validators'\nimport {\n isNonEmptyObject,\n isPlainObject,\n isNonEmptyArrayWithNonEmptyObjects,\n} from '../utils/convert'\nimport { hmacSHA256Hex, verifyHmacSHA256 } from '../crypto'\nimport { executeRequest } from '../http'\nimport { T1Collection } from './T1Collection'\nimport type {\n T1YOSConfig,\n T1YOSInternalConfig,\n HttpMethod,\n ApiResponse,\n InitResult,\n} from '../types'\n\n/**\n * Main T1Y client class.\n *\n * @example\n * ```ts\n * import { T1YOS } from 't1y-sdk-js'\n *\n * const client = new T1YOS({\n * appId: 1001,\n * apiKey: '4fd7448cdc684431a62d8a0111dc6973',\n * secretKey: '17b784e359c946ffa65eebbf9ce29752',\n * })\n *\n * await client.init()\n *\n * // Database operations\n * const { data } = await client.db.collection('users').insertOne({ name: 'Alice' })\n * ```\n */\nexport class T1YOS {\n private config: T1YOSInternalConfig\n\n /**\n * Database accessor providing chainable collection operations.\n *\n * @example\n * ```ts\n * await client.db.collection('users').insertOne({ name: 'Alice' })\n * await client.db.collection('users').findOne({ name: 'Alice' })\n * ```\n */\n readonly db: {\n collection: (name: string) => T1Collection\n toObjectID: (id: string) => string\n getCollections: () => Promise<ApiResponse<{ results: string[] }>>\n }\n\n /**\n * Create a new T1YOS client instance.\n *\n * @param config - Client configuration (appId, apiKey, secretKey are required)\n *\n * @throws {ValidationError} If required parameters are invalid\n */\n constructor(config: T1YOSConfig) {\n // Validate required parameters\n validateInitConfig(config)\n\n this.config = {\n baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n appId: config.appId,\n apiKey: config.apiKey,\n secretKey: config.secretKey,\n version: config.version ?? DEFAULT_VERSION,\n isSafeMode: config.isSafeMode ?? DEFAULT_SAFE_MODE,\n timeFormat: config.timeFormat ?? DEFAULT_TIME_FORMAT,\n offset: config.offset ?? DEFAULT_OFFSET,\n }\n\n // Set up the chainable db accessor\n this.db = {\n collection: (name: string) => this.#collection(name),\n toObjectID: (id: string) => this.#toObjectID(id),\n getCollections: () => this.#getCollections(),\n }\n }\n\n /**\n * Initialize the SDK by syncing with the server.\n *\n * Calls `GET /init/:appId` to:\n * 1. Get the server's current UTC Unix timestamp\n * 2. Get the server's isSafeMode setting\n *\n * The time offset is computed as: `server.unix - client.unix`\n * This offset is used for all subsequent request signing to prevent clock skew issues.\n *\n * @throws {T1YError} If the server returns an error (e.g., app not found, app disabled)\n */\n async init(): Promise<void> {\n try {\n const res = await this.request<InitResult>(\n 'GET',\n `/init/${this.config.appId}`,\n undefined,\n false\n )\n const data = res.data\n this.config.isSafeMode = data.is_safe_mode\n this.config.offset = data.unix - Math.floor(Date.now() / 1000)\n } catch (err) {\n console.warn('Failed to get time offset from server, defaulting to 0. Error:', err)\n this.config.isSafeMode = false\n this.config.offset = 0\n }\n }\n\n // ==================== Public API ====================\n\n /**\n * Get application metadata.\n *\n * @param field - Optional field name to retrieve a specific metadata field\n * @returns Metadata as key-value pairs, or a single field value if `field` is specified\n *\n * @example\n * ```ts\n * // Get all metadata\n * const { data } = await client.getMeta()\n * // data.results = { version: 1, collections: [...] }\n *\n * // Get a specific field\n * const { data } = await client.getMeta('version')\n * // data.result = 1\n * ```\n */\n async getMeta(field?: string): Promise<ApiResponse> {\n if (field !== undefined && field !== '' && typeof field !== 'string') {\n throw new TypeError('Meta field must be a string')\n }\n const queryPath = field ? `?field=${encodeURIComponent(field)}` : ''\n return await this.request('GET', `/v5/meta${queryPath}`)\n }\n\n /**\n * Check if there's a newer version of the application available.\n *\n * Compares the server's `version` metadata field against the configured `version`.\n *\n * @returns `true` if the server version is greater than the client version\n */\n async checkUpdate(): Promise<boolean> {\n try {\n const res = await this.request<{ result: number }>('GET', '/v5/meta?field=version')\n return res.data.result > this.config.version\n } catch {\n return false\n }\n }\n\n /**\n * Call a cloud function (`.jsc` file).\n *\n * If `name` doesn't end with `.jsc`, it's auto-appended.\n * If `name` ends with `/`, `index.jsc` is appended.\n * If `name` ends with `.js`, it's replaced with `.jsc`.\n *\n * @param name - Function name or path (e.g., 'hello' or 'hello.jsc')\n * @param params - Parameters to pass to the function\n * @param enableSafeMode - Override safe mode for this call (defaults to client setting)\n *\n * @example\n * ```ts\n * const { data } = await client.callFunc('hello', { name: 'World' })\n * ```\n */\n async callFunc(\n name: string,\n params: unknown = null,\n enableSafeMode?: boolean\n ): Promise<ApiResponse> {\n if (typeof name !== 'string') {\n throw new TypeError('Function name must be a string')\n }\n return await this.request(\n 'POST',\n `/${this.config.appId}/${this.#ensureJscExtension(name)}`,\n params,\n enableSafeMode\n )\n }\n\n /**\n * Core HTTP request method with full authentication and encryption.\n *\n * @param method - HTTP method (GET, POST, PUT, DELETE)\n * @param path - API path (e.g., /v5/classes/users)\n * @param params - Request parameters/body\n * @param encryption - Override encryption (defaults to client.isSafeMode)\n * @returns Typed API response\n *\n * @throws {T1YError} On API errors (non-2xx responses)\n * @throws {Error} On network errors or timeouts\n */\n async request<T = unknown>(\n method: HttpMethod,\n path: string,\n params?: unknown,\n encryption?: boolean\n ): Promise<ApiResponse<T>> {\n if (typeof path !== 'string') {\n throw new TypeError('request path must be a string')\n }\n\n return await executeRequest<T>(this.config, {\n method,\n path,\n params,\n encryption: encryption ?? this.config.isSafeMode,\n })\n }\n\n // ==================== Utilities ====================\n\n /**\n * Validate an ObjectID hex string.\n *\n * @param idStr - 24-character hex string to validate\n * @param name - Optional name for error messages (default: 'ObjectID')\n * @returns `true` if valid\n * @throws {ValidationError} If the string is not a valid ObjectID\n */\n assertObjectID(idStr: string, name = 'ObjectID'): boolean {\n return assertObjectID(idStr, name)\n }\n\n /** Check if a value is a non-null, non-array object with at least one key */\n isNonEmptyObject(value: unknown): boolean {\n return isNonEmptyObject(value)\n }\n\n /** Check if a value is a plain object (non-null, non-array) */\n isPlainObject(value: unknown): boolean {\n return isPlainObject(value)\n }\n\n /** Check if a value is a non-empty array where every element is a non-empty object */\n isNonEmptyArrayWithNonEmptyObjects(value: unknown): boolean {\n return isNonEmptyArrayWithNonEmptyObjects(value)\n }\n\n // ==================== Crypto ====================\n\n /**\n * Compute HMAC-SHA256 hash and return hex digest.\n *\n * @param message - The message to sign\n * @param secret - The secret key\n * @returns 64-character hex-encoded HMAC-SHA256\n */\n hmacSHA256(secret: string, message: string): string {\n return hmacSHA256Hex(secret, message)\n }\n\n /**\n * Verify an HMAC-SHA256 signature using constant-time comparison.\n *\n * @param secret - The secret key\n * @param message - The message that was signed\n * @param signature - The expected signature (hex string)\n * @returns `true` if the signature matches\n */\n verifyHmacSHA256(secret: string, message: string, signature: string): boolean {\n return verifyHmacSHA256(secret, message, signature)\n }\n\n // ==================== Private Helpers ====================\n\n /** Create a T1Collection for the given collection name */\n #collection(name: string): T1Collection {\n if (typeof name !== 'string') {\n throw new TypeError('Collection name must be a string')\n }\n return new T1Collection(this, name)\n }\n\n /** Get all collections in the application's database */\n async #getCollections(): Promise<ApiResponse<{ results: string[] }>> {\n return await this.request<{ results: string[] }>('GET', '/v5/schemas')\n }\n\n /** Convert a 24-char hex string to an ObjectID marker */\n #toObjectID(idStr: string): string {\n assertObjectID(idStr)\n return `ObjectID('${idStr}')`\n }\n\n /** Ensure a function name has the .jsc extension */\n #ensureJscExtension(input: string): string {\n let path = input.startsWith('/') ? input.slice(1) : input\n\n // Separate hash fragment\n const hashIndex = path.indexOf('#')\n const hash = hashIndex !== -1 ? path.slice(hashIndex) : ''\n const withoutHash = hashIndex !== -1 ? path.slice(0, hashIndex) : path\n\n // Separate query string\n const qIndex = withoutHash.indexOf('?')\n const query = qIndex !== -1 ? withoutHash.slice(qIndex) : ''\n let mainPath = qIndex !== -1 ? withoutHash.slice(0, qIndex) : withoutHash\n\n // Apply extension rules\n if (mainPath.endsWith('/')) {\n mainPath = mainPath + 'index.jsc'\n } else if (mainPath.endsWith('.jsc')) {\n // Already has .jsc\n } else if (mainPath.endsWith('.js')) {\n mainPath = mainPath.replace(/\\.js$/, '.jsc')\n } else {\n mainPath = mainPath + '.jsc'\n }\n\n return mainPath + query + hash\n }\n}\n\nexport default T1YOS\n","import { OBJECT_ID_PATTERN } from '../constants'\n\n/**\n * Create an ObjectID marker string that the server will convert to a MongoDB ObjectID.\n *\n * @param id - 24-character hexadecimal string\n * @returns ObjectID marker string, e.g. `ObjectID('507f1f77bcf86cd799439011')`\n *\n * @example\n * ```ts\n * import { ObjectID } from 't1y-sdk-js'\n *\n * await db.collection('users').find(ObjectID('507f1f77bcf86cd799439011'))\n * ```\n */\nexport function ObjectID(id: string): `ObjectID('${string}')` {\n if (!OBJECT_ID_PATTERN.test(id)) {\n throw new Error(`Invalid ObjectID: \"${id}\" (must be 24 hex characters)`)\n }\n return `ObjectID('${id}')`\n}\n","/**\n * Create a Date marker string. The server converts this to a Go time.Time.\n *\n * @param dateStr - ISO 8601 / RFC 3339 date string\n * @returns Date marker, e.g. `Date('2024-01-15T10:30:00Z')`\n */\nexport function Date_(dateStr: string): `Date('${string}')` {\n return `Date('${dateStr}')`\n}\n\n/**\n * Create a DateTime marker string. Same as Date on the server side.\n *\n * @param dateStr - ISO 8601 / RFC 3339 date string\n * @returns DateTime marker, e.g. `DateTime('2024-01-15T10:30:00Z')`\n */\nexport function DateTime(dateStr: string): `DateTime('${string}')` {\n return `DateTime('${dateStr}')`\n}\n\n/**\n * Create a Timestamp marker string. The server converts this to a Unix timestamp.\n *\n * @param unix - Unix timestamp (seconds) as number or string\n * @returns Timestamp marker, e.g. `Timestamp('1705312200')`\n */\nexport function Timestamp(unix: number | string): `Timestamp('${string}')` {\n return `Timestamp('${String(unix)}')`\n}\n","/**\n * Create a Boolean marker. The server converts this to a Go bool.\n */\nexport function Boolean_(val: boolean): `Boolean(${string})` {\n return `Boolean(${val})`\n}\n\n/**\n * Create an Integer marker. The server converts this to int32.\n */\nexport function Integer(n: number): `Integer(${number})` {\n return `Integer(${n})`\n}\n\n/**\n * Create a Bigint marker. The server converts this to int64.\n */\nexport function Bigint(n: number | bigint): `Bigint(${number})` {\n return `Bigint(${Number(n)})`\n}\n\n/**\n * Create a Float marker. The server converts this to float32.\n */\nexport function Float(n: number): `Float(${number})` {\n return `Float(${n})`\n}\n\n/**\n * Create a Double marker. The server converts this to float64.\n */\nexport function Double(n: number): `Double(${number})` {\n return `Double(${n})`\n}\n","/**\n * Create an Array marker. The server converts this to a Go slice.\n *\n * @param arr - Array to serialize as JSON\n */\nexport function Array_(arr: unknown[]): `Array(${string})` {\n return `Array(${JSON.stringify(arr)})`\n}\n\n/**\n * Create a Map marker. The server converts this to a map[string]interface{}.\n *\n * @param obj - Object to serialize as JSON\n */\nexport function Map_(obj: Record<string, unknown>): `Map(${string})` {\n return `Map(${JSON.stringify(obj)})`\n}\n\n/**\n * Create a Map[] marker. The server converts this to []map[string]interface{}.\n *\n * @param arr - Array of objects to serialize as JSON\n */\nexport function MapArray(arr: Record<string, unknown>[]): `Map[](${string})` {\n return `Map[](${JSON.stringify(arr)})`\n}\n","/**\n * Null / null-equivalent markers that the server converts to Go nil.\n *\n * The server recognizes all these variants as null:\n * 'Null', 'null', 'NULL', 'None', 'none', 'NONE', 'Nil', 'nil', 'NIL', '<nil>', ''\n */\n\n/** Null marker — server converts to nil */\nexport const Null = 'Null' as const\n\n/** None marker — server converts to nil */\nexport const None = 'None' as const\n\n/** Nil marker — server converts to nil */\nexport const Nil = 'Nil' as const\n\n/** empty string — server converts to nil (use '' directly) */\nexport const Empty = '' as const\n\n/**\n * Undefined markers that the server converts to bson.Undefined{}.\n */\nexport const UNDEFINED = 'UNDEFINED' as const\nexport const Undefined = 'Undefined' as const\n","/**\n * Time helper markers that the server evaluates at request time.\n *\n * These are string values that, when sent to the server, are replaced\n * with the actual current time on the server side via Go's time.Now().\n */\n\n/** Server fills in time.Now() (current UTC time) */\nexport const TimeNow = 'time.Now()' as const\n\n/** Server fills in time.Now().Unix() (current Unix timestamp) */\nexport const TimeNowUnix = 'time.Now().Unix()' as const\n\n/** Server fills in time.Now().UnixNano() */\nexport const TimeNowUnixNano = 'time.Now().UnixNano()' as const\n\n/** Server fills in time.Now().Weekday() (e.g., time.Monday) */\nexport const TimeNowWeekday = 'time.Now().Weekday()' as const\n\n/** Server fills in time.Now().Weekday().Chinese() (Chinese weekday name) */\nexport const TimeNowWeekdayChinese = 'time.Now().Weekday().Chinese()' as const\n\n/**\n * Convenience object grouping all time-now helpers.\n *\n * @example\n * ```ts\n * import { timeNow } from 't1y-sdk-js'\n *\n * await db.collection('posts').insertOne({\n * title: 'Hello',\n * createdAt: timeNow.Now(),\n * })\n * ```\n */\nexport const timeNow = {\n Now: () => TimeNow,\n NowUnix: () => TimeNowUnix,\n NowUnixNano: () => TimeNowUnixNano,\n NowWeekday: () => TimeNowWeekday,\n NowWeekdayChinese: () => TimeNowWeekdayChinese,\n}\n"],"mappings":"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","names":["src_exports","__export","Array_","Bigint","Boolean_","Date_","DateTime","Double","Empty","Float","Integer","Map_","MapArray","Nil","None","Null","ObjectID","T1Collection","T1YError","T1YOS","TimeNow","TimeNowUnix","TimeNowUnixNano","TimeNowWeekday","TimeNowWeekdayChinese","Timestamp","UNDEFINED","Undefined","ValidationError","assertObjectID","convertDateTypes","createSignature","decryptAESGCM","T1YOS_default","encryptAESGCM","formatTimestampsToLocal","getSafeTimestamp","hmacSHA256Hex","hmacSHA256HexAsync","isNonEmptyArrayWithNonEmptyObjects","isNonEmptyObject","isPlainObject","sha256Hex","sha256HexAsync","timeNow","validateApiKey","validateAppId","validateBaseUrl","validateInitConfig","validateSecretKey","verifyHmacSHA256","__toCommonJS","DEFAULT_BASE_URL","DEFAULT_TIME_FORMAT","OBJECT_ID_PATTERN","T1YError","code","message","data","ValidationError","validateAppId","appId","ValidationError","validateApiKey","apiKey","validateSecretKey","secretKey","validateBaseUrl","baseUrl","validateInitConfig","config","assertObjectID","idStr","name","OBJECT_ID_PATTERN","convertDateTypes","value","str","v","obj","key","isNonEmptyObject","isPlainObject","isNonEmptyArrayWithNonEmptyObjects","item","getNodeRequire","sha256Hex","data","nodeReq","bytes","utf8ToBytes","sha256RawBytesHex","sha256Raw","sha256HexAsync","encoder","hashBuffer","b","str","i","c","c2","cp","K","msgByteLen","msgBitLen","padLen","totalLen","padded","H","offset","W","t","s0","rotr","s1","a","d","e","f","g","h","S1","ch","temp1","S0","maj","temp2","v","x","n","getNodeRequire","hmacSHA256Hex","secret","message","nodeReq","hmacSHA256Pure","hmacSHA256HexAsync","encoder","key","signature","b","verifyHmacSHA256","expected","timingSafeEqual","a","result","i","keyBytes","utf8ToBytes","msgBytes","hexToBytes","sha256RawBytesHex","paddedKey","ipad","innerKey","xorBytes","innerData","innerHash","opad","outerKey","outerData","str","bytes","c","c2","cp","hex","getCrypto","nodeCryptoModule","AES_GCM_TAG_LENGTH","AES_GCM_NONCE_LENGTH","encodeBase64","uint8array","binary","len","i","decodeBase64","b64","bytes","encryptAESGCM","data","keyBytes","cryptoApi","key","nonce","encodedData","encrypted","ciphertext","tag","payload","decryptAESGCM","jsonPayload","n","j","t","sealed","decrypted","createSignature","input","method","pathAndQuery","body","appId","timestamp","secretKey","bodyHash","sha256Hex","message","hmacSHA256Hex","getSafeTimestamp","offset","normalizeBaseUrl","baseUrl","appendQueryParams","url","params","key","value","formatLocalTime","utcString","format","date","pad","n","formatTimestampsToLocal","data","DEFAULT_TIME_FORMAT","traverse","value","result","key","handleResponse","response","isSafeMode","secretKey","timeFormat","rawData","contentType","responseText","decrypted","decryptAESGCM","err","T1YError","apiResp","formatTimestampsToLocal","handleFetchError","error","errWithResponse","executeRequest","client","options","method","path","params","encryption","timeout","baseUrl","normalizeBaseUrl","isSafeMode","fullUrl","convertedParams","convertDateTypes","bodyForRequest","rawBodyString","encryptedBody","encryptAESGCM","jsonBody","appendQueryParams","timestamp","getSafeTimestamp","originalURL","sign","createSignature","controller","timeoutId","response","handleResponse","error","handleFetchError","T1Collection","client","name","data","isNonEmptyObject","objectId","assertObjectID","filter","body","dataList","isNonEmptyArrayWithNonEmptyObjects","isPlainObject","page","size","sort","pipeline","fieldName","_T1YOS_instances","collection_fn","getCollections_fn","toObjectID_fn","ensureJscExtension_fn","T1YOS","config","__privateAdd","validateInitConfig","DEFAULT_BASE_URL","DEFAULT_TIME_FORMAT","name","__privateMethod","id","data","err","field","queryPath","params","enableSafeMode","method","path","encryption","executeRequest","idStr","assertObjectID","value","isNonEmptyObject","isPlainObject","isNonEmptyArrayWithNonEmptyObjects","secret","message","hmacSHA256Hex","signature","verifyHmacSHA256","T1Collection","input","hashIndex","hash","withoutHash","qIndex","query","mainPath","T1YOS_default","ObjectID","id","OBJECT_ID_PATTERN","Date_","dateStr","DateTime","Timestamp","unix","Boolean_","val","Integer","n","Bigint","Float","Double","Array_","arr","Map_","obj","MapArray","Null","None","Nil","Empty","UNDEFINED","Undefined","TimeNow","TimeNowUnix","TimeNowUnixNano","TimeNowWeekday","TimeNowWeekdayChinese","timeNow"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var se=e=>{throw TypeError(e)};var I=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var Ve=(e,t,n)=>t.has(e)||se("Cannot "+n);var ie=(e,t,n)=>t.has(e)?se("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n);var N=(e,t,n)=>(Ve(e,t,"access private method"),n);var ae="https://myapp.t1y.net";var j="YYYY-MM-DD HH:mm:ss";var _=/^[0-9a-fA-F]{24}$/;var h=class extends Error{constructor(t,n,r){super(n),this.name="T1YError",this.code=t,this.data=r}toJSON(){return{name:this.name,code:this.code,message:this.message,data:this.data}}},m=class extends Error{constructor(t){super(t),this.name="ValidationError"}};function Y(e){if(!Number.isInteger(e))throw new m("appId must be an integer");if(e<1001)throw new m(`appId must be >= ${1001}`)}function W(e){if(typeof e!="string")throw new m("apiKey must be a string");if(e.length!==32)throw new m(`apiKey must be exactly ${32} characters (got ${e.length})`)}function J(e){if(typeof e!="string")throw new m("secretKey must be a string");if(e.length!==32)throw new m(`secretKey must be exactly ${32} characters (got ${e.length})`)}function Z(e){if(!/^https?:\/\//.test(e))throw new m('baseUrl must start with "http://" or "https://"')}function B(e){if(e.baseUrl!==void 0&&Z(e.baseUrl),Y(e.appId),W(e.apiKey),J(e.secretKey),e.version!==void 0&&(!Number.isInteger(e.version)||e.version<0))throw new m("version must be a non-negative integer")}function T(e,t="ObjectID"){if(typeof e!="string")throw new m(`${t} must be a string`);if(!_.test(e))throw new m(`Invalid ${t} string: "${e}"`);return!0}function O(e){if(e instanceof Date)return`Date('${e.toISOString()}')`;if(typeof e=="number"){let t=String(e);return/^\d{10,}$/.test(t)?`Timestamp('${t}')`:e}if(Array.isArray(e))return e.map(t=>O(t));if(e&&typeof e=="object"){let t={};for(let n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=O(e[n]));return t}return e}function g(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)&&Object.keys(e).length>0}function w(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function M(e){return!Array.isArray(e)||e.length===0?!1:e.every(t=>typeof t=="object"&&t!==null&&!Array.isArray(t)&&Object.keys(t).length>0)}function fe(){try{if(typeof I<"u")return I}catch{}return null}function H(e){let t=fe();if(t)try{return t("node:crypto").createHash("sha256").update(e).digest("hex")}catch{}let n=Qe(e);return k(n)}function k(e){return Xe(e)}async function ye(e){let t=fe();if(t)try{return t("node:crypto").createHash("sha256").update(e).digest("hex")}catch{}let n=new TextEncoder,r=await crypto.subtle.digest("SHA-256",n.encode(e));return Array.from(new Uint8Array(r)).map(o=>o.toString(16).padStart(2,"0")).join("")}function Qe(e){if(typeof TextEncoder<"u")return new TextEncoder().encode(e);let t=[];for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);if(r<128)t.push(r);else if(r<2048)t.push(192|r>>6,128|r&63);else if(r<55296||r>=57344)t.push(224|r>>12,128|r>>6&63,128|r&63);else{n++;let o=e.charCodeAt(n),i=65536+((r&1023)<<10)+(o&1023);t.push(240|i>>18,128|i>>12&63,128|i>>6&63,128|i&63)}}return new Uint8Array(t)}function Xe(e){let t=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],n=e.length,r=n*8,o=(64-(n+9)%64)%64,i=n+1+o+8,c=new Uint8Array(i);c.set(e),c[n]=128;for(let a=0;a<8;a++)c[i-8+a]=Number(BigInt(r)>>BigInt((7-a)*8)&BigInt(255));let s=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];for(let a=0;a<i;a+=64){let u=new Array(64);for(let p=0;p<16;p++)u[p]=c[a+p*4]<<24|c[a+p*4+1]<<16|c[a+p*4+2]<<8|c[a+p*4+3];for(let p=16;p<64;p++){let d=(b(u[p-15],7)^b(u[p-15],18)^u[p-15]>>>3)>>>0,G=(b(u[p-2],17)^b(u[p-2],19)^u[p-2]>>>10)>>>0;u[p]=u[p-16]+d+u[p-7]+G>>>0}let[f,l,y,S,x,U,E,P]=s;for(let p=0;p<64;p++){let d=(b(x,6)^b(x,11)^b(x,25))>>>0,G=(x&U^~x&E)>>>0,oe=P+d+G+t[p]+u[p]>>>0,We=(b(f,2)^b(f,13)^b(f,22))>>>0,Je=(f&l^f&y^l&y)>>>0,Ze=We+Je>>>0;P=E,E=U,U=x,x=S+oe>>>0,S=y,y=l,l=f,f=oe+Ze>>>0}s[0]=s[0]+f>>>0,s[1]=s[1]+l>>>0,s[2]=s[2]+y>>>0,s[3]=s[3]+S>>>0,s[4]=s[4]+x>>>0,s[5]=s[5]+U>>>0,s[6]=s[6]+E>>>0,s[7]=s[7]+P>>>0}return s.map(a=>a.toString(16).padStart(8,"0")).join("")}function b(e,t){return e>>>t|e<<32-t}function ge(){try{if(typeof I<"u")return I}catch{}return null}function R(e,t){let n=ge();if(n)try{return n("node:crypto").createHmac("sha256",e).update(t).digest("hex")}catch{}return et(e,t)}async function he(e,t){let n=ge();if(n)try{return n("node:crypto").createHmac("sha256",e).update(t).digest("hex")}catch{}let r=new TextEncoder,o=await crypto.subtle.importKey("raw",r.encode(e),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),i=await crypto.subtle.sign("HMAC",o,r.encode(t));return Array.from(new Uint8Array(i)).map(c=>c.toString(16).padStart(2,"0")).join("")}function $(e,t,n){if(typeof n!="string")return!1;let r=R(e,t);return ze(r,n.toLowerCase())}function ze(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r++)n|=e.charCodeAt(r)^t.charCodeAt(r);return n===0}function et(e,t){let r=le(e),o=le(t);r.length>64&&(r=de(k(r)));let i=new Uint8Array(64);i.set(r.subarray(0,Math.min(r.length,64)));let c=new Uint8Array(64);c.fill(54);let s=me(i,c),a=new Uint8Array(64+o.length);a.set(s),a.set(o,64);let u=de(k(a)),f=new Uint8Array(64);f.fill(92);let l=me(i,f),y=new Uint8Array(64+u.length);return y.set(l),y.set(u,64),k(y)}function me(e,t){let n=new Uint8Array(e.length);for(let r=0;r<e.length;r++)n[r]=e[r]^t[r];return n}function le(e){if(typeof TextEncoder<"u")return new TextEncoder().encode(e);let t=[];for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);if(r<128)t.push(r);else if(r<2048)t.push(192|r>>6,128|r&63);else if(r<55296||r>=57344)t.push(224|r>>12,128|r>>6&63,128|r&63);else{n++;let o=e.charCodeAt(n),i=65536+((r&1023)<<10)+(o&1023);t.push(240|i>>18,128|i>>12&63,128|i>>6&63,128|i&63)}}return new Uint8Array(t)}function de(e){let t=new Uint8Array(e.length/2);for(let n=0;n<e.length;n+=2)t[n/2]=parseInt(e.substring(n,n+2),16);return t}function we(){if(typeof globalThis<"u"){if(typeof globalThis.crypto<"u"&&globalThis.crypto.subtle)return globalThis.crypto;try{let e=globalThis.require?globalThis.require("node:crypto"):null;if(e?.webcrypto)return e.webcrypto}catch{}}throw new Error("Web Crypto API is not available in this environment")}var xe=16,tt=12;function V(e){let t="",n=e.byteLength;for(let r=0;r<n;r++)t+=String.fromCharCode(e[r]);return btoa(t)}function Q(e){let t=atob(e),n=t.length,r=new Uint8Array(n);for(let o=0;o<n;o++)r[o]=t.charCodeAt(o);return r}async function v(e,t){if(!(t instanceof Uint8Array))throw new Error("key must be Uint8Array");if(t.length!==32)throw new Error("key length must be 32 bytes for AES-256-GCM");let n=we(),r=await n.subtle.importKey("raw",t,"AES-GCM",!1,["encrypt"]),o=new Uint8Array(tt);n.getRandomValues(o);let i=new TextEncoder().encode(e),c=new Uint8Array(await n.subtle.encrypt({name:"AES-GCM",iv:o,tagLength:128},r,i)),s=c.slice(0,c.length-xe),a=c.slice(c.length-xe),u={n:V(o),j:V(s),t:V(a)};return JSON.stringify(u)}async function L(e,t){if(!(t instanceof Uint8Array))throw new Error("key must be Uint8Array");if(t.length!==32)throw new Error("key length must be 32 bytes for AES-256-GCM");let n=we(),{n:r,j:o,t:i}=JSON.parse(e),c=Q(r),s=Q(o),a=Q(i),u=new Uint8Array(s.length+a.length);u.set(s),u.set(a,s.length);let f=await n.subtle.importKey("raw",t,"AES-GCM",!1,["decrypt"]),l=await n.subtle.decrypt({name:"AES-GCM",iv:c,tagLength:128},f,u);return new TextDecoder().decode(l)}function F(e){let{method:t,pathAndQuery:n,body:r,appId:o,timestamp:i,secretKey:c}=e,s=H(r),a=[t.toUpperCase(),n,s,String(o),String(i)].join(`
|
|
2
|
+
`);return R(c,a)}function q(e){return String(Math.floor(Date.now()/1e3)+e)}function be(e){return e.replace(/\/+$/,"")}function Ae(e,t){for(let n of Object.keys(t)){let r=t[n];r!=null&&e.searchParams.set(n,typeof r=="string"?r:JSON.stringify(r))}}function nt(e,t){let n=new Date(e);if(isNaN(n.getTime()))return e;let r=o=>String(o).padStart(2,"0");return t.replace("YYYY",String(n.getFullYear())).replace("MM",r(n.getMonth()+1)).replace("DD",r(n.getDate())).replace("HH",r(n.getHours())).replace("mm",r(n.getMinutes())).replace("ss",r(n.getSeconds()))}function C(e,t=j){function n(r){if(Array.isArray(r))return r.map(n);if(r&&typeof r=="object"){let o={};for(let i in r)Object.prototype.hasOwnProperty.call(r,i)&&(i==="createdAt"||i==="updatedAt"?o[i]=nt(r[i],t):o[i]=n(r[i]));return o}return r}return n(e)}async function Te(e,t,n,r){let o,i=e.headers.get("content-type")||"",c=await e.text();if(i.includes("application/json"))try{o=JSON.parse(c)}catch{o=c}else o=c;if(t&&o&&typeof o=="object"&&"j"in o)try{let s=await L(JSON.stringify(o),new TextEncoder().encode(n));try{o=JSON.parse(s)}catch{o=s}}catch(s){throw new h(400,"AES-256-GCM decryption failed",s instanceof Error?s.message:null)}if(o&&typeof o=="object"&&"data"in o){let s=o;if(s.data=C(s.data,r),!e.ok)throw new h(s.code||e.status,s.message||e.statusText,s.data);return s}if(!e.ok)throw new h(e.status,e.statusText,o);return{code:0,message:"ok",data:C(o,r)}}function Ee(e){if(e&&typeof e=="object"&&"response"in e){let t=e;throw e}throw e instanceof h?e:e instanceof Error?e.name==="AbortError"?new h(408,"Request timeout",null):new h(0,e.message,null):new h(0,"Unknown error",e)}async function X(e,t){let{method:n,path:r,params:o,encryption:i,timeout:c}=t,s=be(e.baseUrl),a=i??e.isSafeMode,u=new URL(s+r),f=O(o),l,y="";if(n!=="GET")if(a&&f!==void 0){let d=await v(JSON.stringify(f),new TextEncoder().encode(e.secretKey));l=d,y=d}else if(f!==void 0){let d=JSON.stringify(f);l=d,y=d}else y="";else f&&typeof f=="object"&&Object.keys(f).length>0&&Ae(u,f);let S=Number(q(e.offset)),x=u.pathname+u.search,U=F({method:n,pathAndQuery:x,body:y,appId:e.appId,timestamp:S,secretKey:e.secretKey}),E=new AbortController,p=setTimeout(()=>E.abort(),c??3e5);try{let d=await fetch(u.toString(),{method:n,headers:{"X-T1Y-Application-ID":String(e.appId),"X-T1Y-API-Key":e.apiKey,"X-T1Y-Safe-Timestamp":String(S),"X-T1Y-Safe-Sign":U,"Content-Type":"application/json"},body:n!=="GET"?l:void 0,signal:E.signal});return clearTimeout(p),await Te(d,a,e.secretKey,e.timeFormat)}catch(d){return clearTimeout(p),Ee(d)}}var D=class{constructor(t,n){this.client=t,this.name=n}async insertOne(t){if(!g(t))throw new TypeError("insertOne data must be a non-empty plain object");return await this.client.request("POST",`/v5/classes/${this.name}`,t)}async deleteById(t){return T(t),await this.client.request("DELETE",`/v5/classes/${this.name}/${t}`)}async updateById(t,n){if(T(t),!g(n))throw new TypeError("update data must be a non-empty plain object");return await this.client.request("PUT",`/v5/classes/${this.name}/${t}`,n)}async findById(t){return T(t),await this.client.request("GET",`/v5/classes/${this.name}/${t}`)}async deleteOne(t){if(!g(t))throw new TypeError("deleteOne filter must be a non-empty plain object");return await this.client.request("DELETE",`/v5/classes/${this.name}/one`,t)}async updateOne(t,n){if(!g(t))throw new TypeError("updateOne filter must be a non-empty plain object");if(!g(n))throw new TypeError("updateOne body must be a non-empty plain object");return await this.client.request("PUT",`/v5/classes/${this.name}/one`,{filter:t,body:n})}async findOne(t){if(!g(t))throw new TypeError("findOne filter must be a non-empty plain object");return await this.client.request("POST",`/v5/classes/${this.name}/one`,t)}async insertMany(t){if(!M(t))throw new TypeError("insertMany dataList must be a non-empty array of non-empty plain objects");return await this.client.request("POST",`/v5/classes/${this.name}/many`,t)}async deleteMany(t){if(!w(t))throw new TypeError("deleteMany filter must be a plain object");return await this.client.request("DELETE",`/v5/classes/${this.name}/many`,t)}async updateMany(t,n){if(!w(t))throw new TypeError("updateMany filter must be a plain object");if(!g(n))throw new TypeError("updateMany body must be a non-empty plain object");return await this.client.request("PUT",`/v5/classes/${this.name}/many`,{filter:t,body:n})}async find(t=1,n=10,r={createdAt:-1},o={}){if(!Number.isInteger(t)||t<1)throw new TypeError("find page must be a positive integer");if(!Number.isInteger(n)||n<1)throw new TypeError("find size must be a positive integer");if(n>100&&(n=100),!g(r))throw new TypeError("find sort must be a non-empty plain object");if(!w(o))throw new TypeError("find filter must be a plain object");return await this.client.request("POST",`/v5/classes/${this.name}/find`,{page:t,size:n,sort:r,filter:o})}async aggregate(t){if(!Array.isArray(t))throw new TypeError("aggregate pipeline must be an array");return await this.client.request("POST",`/v5/classes/${this.name}/aggregate`,t)}async count(t={}){if(!w(t))throw new TypeError("count filter must be a plain object");return await this.client.request("POST",`/v5/classes/${this.name}/count`,t)}async distinct(t,n={}){if(typeof t!="string"||t.length===0)throw new TypeError("distinct fieldName must be a non-empty string");if(!w(n))throw new TypeError("distinct filter must be a plain object");return await this.client.request("POST",`/v5/classes/${this.name}/distinct/${encodeURIComponent(t)}`,n)}async create(){return await this.client.request("POST",`/v5/schemas/${encodeURIComponent(this.name)}`)}async clear(){return await this.client.request("PUT",`/v5/schemas/${encodeURIComponent(this.name)}`)}async drop(){return await this.client.request("DELETE",`/v5/schemas/${encodeURIComponent(this.name)}`)}};var A,Re,Se,Ue,Ie,K=class{constructor(t){ie(this,A);B(t),this.config={baseUrl:t.baseUrl??ae,appId:t.appId,apiKey:t.apiKey,secretKey:t.secretKey,version:t.version??0,isSafeMode:t.isSafeMode??!1,timeFormat:t.timeFormat??j,offset:t.offset??0},this.db={collection:n=>N(this,A,Re).call(this,n),toObjectID:n=>N(this,A,Ue).call(this,n),getCollections:()=>N(this,A,Se).call(this)}}async init(){try{let n=(await this.request("GET",`/init/${this.config.appId}`,void 0,!1)).data;this.config.isSafeMode=n.is_safe_mode,this.config.offset=n.unix-Math.floor(Date.now()/1e3)}catch(t){console.warn("Failed to get time offset from server, defaulting to 0. Error:",t),this.config.isSafeMode=!1,this.config.offset=0}}async getMeta(t){if(t!==void 0&&t!==""&&typeof t!="string")throw new TypeError("Meta field must be a string");let n=t?`?field=${encodeURIComponent(t)}`:"";return await this.request("GET",`/v5/meta${n}`)}async checkUpdate(){try{return(await this.request("GET","/v5/meta?field=version")).data.result>this.config.version}catch{return!1}}async callFunc(t,n=null,r){if(typeof t!="string")throw new TypeError("Function name must be a string");return await this.request("POST",`/${this.config.appId}/${N(this,A,Ie).call(this,t)}`,n,r)}async request(t,n,r,o){if(typeof n!="string")throw new TypeError("request path must be a string");return await X(this.config,{method:t,path:n,params:r,encryption:o??this.config.isSafeMode})}assertObjectID(t,n="ObjectID"){return T(t,n)}isNonEmptyObject(t){return g(t)}isPlainObject(t){return w(t)}isNonEmptyArrayWithNonEmptyObjects(t){return M(t)}hmacSHA256(t,n){return R(t,n)}verifyHmacSHA256(t,n,r){return $(t,n,r)}};A=new WeakSet,Re=function(t){if(typeof t!="string")throw new TypeError("Collection name must be a string");return new D(this,t)},Se=async function(){return await this.request("GET","/v5/schemas")},Ue=function(t){return T(t),`ObjectID('${t}')`},Ie=function(t){let n=t.startsWith("/")?t.slice(1):t,r=n.indexOf("#"),o=r!==-1?n.slice(r):"",i=r!==-1?n.slice(0,r):n,c=i.indexOf("?"),s=c!==-1?i.slice(c):"",a=c!==-1?i.slice(0,c):i;return a.endsWith("/")?a=a+"index.jsc":a.endsWith(".jsc")||(a.endsWith(".js")?a=a.replace(/\.js$/,".jsc"):a=a+".jsc"),a+s+o};var at=K;function Oe(e){if(!_.test(e))throw new Error(`Invalid ObjectID: "${e}" (must be 24 hex characters)`);return`ObjectID('${e}')`}function Me(e){return`Date('${e}')`}function Ne(e){return`DateTime('${e}')`}function ke(e){return`Timestamp('${String(e)}')`}function Ce(e){return`Boolean(${e})`}function De(e){return`Integer(${e})`}function Pe(e){return`Bigint(${Number(e)})`}function je(e){return`Float(${e})`}function _e(e){return`Double(${e})`}function Be(e){return`Array(${JSON.stringify(e)})`}function He(e){return`Map(${JSON.stringify(e)})`}function $e(e){return`Map[](${JSON.stringify(e)})`}var ve="Null",Le="None",Fe="Nil",qe="",Ke="UNDEFINED",Ge="Undefined";var z="time.Now()",ee="time.Now().Unix()",te="time.Now().UnixNano()",ne="time.Now().Weekday()",re="time.Now().Weekday().Chinese()",Ye={Now:()=>z,NowUnix:()=>ee,NowUnixNano:()=>te,NowWeekday:()=>ne,NowWeekdayChinese:()=>re};export{Be as Array,Pe as Bigint,Ce as Boolean,Me as Date,Ne as DateTime,_e as Double,qe as Empty,je as Float,De as Integer,He as Map,$e as MapArray,Fe as Nil,Le as None,ve as Null,Oe as ObjectID,D as T1Collection,h as T1YError,K as T1YOS,z as TimeNow,ee as TimeNowUnix,te as TimeNowUnixNano,ne as TimeNowWeekday,re as TimeNowWeekdayChinese,ke as Timestamp,Ke as UNDEFINED,Ge as Undefined,m as ValidationError,T as assertObjectID,O as convertDateTypes,F as createSignature,L as decryptAESGCM,at as default,v as encryptAESGCM,C as formatTimestampsToLocal,q as getSafeTimestamp,R as hmacSHA256Hex,he as hmacSHA256HexAsync,M as isNonEmptyArrayWithNonEmptyObjects,g as isNonEmptyObject,w as isPlainObject,H as sha256Hex,ye as sha256HexAsync,Ye as timeNow,W as validateApiKey,Y as validateAppId,Z as validateBaseUrl,B as validateInitConfig,J as validateSecretKey,$ as verifyHmacSHA256};
|
|
3
|
+
//# sourceMappingURL=index.mjs.map
|