@oddington/sdk 0.1.42 → 0.1.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ ${suffix}`}function identifyRegistrationError({error,options}){var _a,_b,_c;cons
|
|
|
18
18
|
`);const maybeSignature=await resolvedWallet.signMessage(new TextEncoder().encode(message),"utf8");if(!maybeSignature||!(maybeSignature instanceof Uint8Array)){throw new Error("@supabase/auth-js: Wallet signMessage() API returned an recognized value")}signature=maybeSignature}}try{const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/token?grant_type=web3`,{headers:this.headers,body:Object.assign({chain:"solana",message,signature:bytesToBase64URL(signature)},((_m=credentials.options)===null||_m===undefined?undefined:_m.captchaToken)?{gotrue_meta_security:{captcha_token:(_o=credentials.options)===null||_o===undefined?undefined:_o.captchaToken}}:null),xform:_sessionResponse});if(error){throw error}if(!data2||!data2.session||!data2.user){const invalidTokenError=new AuthInvalidTokenResponseError;return this._returnResult({data:{user:null,session:null},error:invalidTokenError})}if(data2.session){await this._saveSession(data2.session);await this._notifyAllSubscribers("SIGNED_IN",data2.session)}return this._returnResult({data:Object.assign({},data2),error})}catch(error){if(isAuthError(error)){return this._returnResult({data:{user:null,session:null},error})}throw error}}async _exchangeCodeForSession(authCode,options){const hasExplicitFlowId=(options===null||options===undefined?undefined:options.flowId)!=null;const requestedFlowId=hasExplicitFlowId?validatePKCEFlowId(options===null||options===undefined?undefined:options.flowId):isBrowser()?validatePKCEFlowId(parseParametersFromURL(window.location.href)[PKCE_FLOW_ID_PARAM]):null;if(hasExplicitFlowId&&!requestedFlowId){this._debug("#_exchangeCodeForSession()","provided flowId is not a valid flow id",options===null||options===undefined?undefined:options.flowId)}const{verifier:storageItem,flowId}=hasExplicitFlowId&&!requestedFlowId?{verifier:null,flowId:null}:await retrievePKCEVerifier(this.storage,this.storageKey,requestedFlowId);const[codeVerifier,redirectType]=(storageItem!==null&&storageItem!==undefined?storageItem:"").split("/");try{if(!codeVerifier&&this.flowType==="pkce"){throw new AuthPKCECodeVerifierMissingError}const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/token?grant_type=pkce`,{headers:this.headers,body:{auth_code:authCode,code_verifier:codeVerifier},xform:_sessionResponse});await removePKCEVerifier(this.storage,this.storageKey,flowId);if(error){throw error}if(!data2||!data2.session||!data2.user){const invalidTokenError=new AuthInvalidTokenResponseError;return this._returnResult({data:{user:null,session:null,redirectType:null},error:invalidTokenError})}if(data2.session){await this._saveSession(data2.session);await this._notifyAllSubscribers(redirectType==="recovery"?"PASSWORD_RECOVERY":"SIGNED_IN",data2.session)}return this._returnResult({data:Object.assign(Object.assign({},data2),{redirectType:redirectType!==null&&redirectType!==undefined?redirectType:null}),error})}catch(error){await removePKCEVerifier(this.storage,this.storageKey,flowId);if(isAuthError(error)){return this._returnResult({data:{user:null,session:null,redirectType:null},error})}throw error}}async signInWithIdToken(credentials){try{const{options,provider,token,access_token,nonce}=credentials;const res=await _request(this.fetch,"POST",`${this.url}/token?grant_type=id_token`,{headers:this.headers,body:{provider,id_token:token,access_token,nonce,gotrue_meta_security:{captcha_token:options===null||options===undefined?undefined:options.captchaToken}},xform:_sessionResponse});const{data:data2,error}=res;if(error){return this._returnResult({data:{user:null,session:null},error})}else if(!data2||!data2.session||!data2.user){const invalidTokenError=new AuthInvalidTokenResponseError;return this._returnResult({data:{user:null,session:null},error:invalidTokenError})}if(data2.session){await this._saveSession(data2.session);await this._notifyAllSubscribers("SIGNED_IN",data2.session)}return this._returnResult({data:data2,error})}catch(error){if(isAuthError(error)){return this._returnResult({data:{user:null,session:null},error})}throw error}}async signInWithOtp(credentials){var _a,_b,_c,_d,_f;let flowId=null;try{if("email"in credentials){const{email,options}=credentials;let codeChallenge=null;let codeChallengeMethod=null;if(this.flowType==="pkce"){[codeChallenge,codeChallengeMethod,flowId]=await this._getCodeChallengeAndMethod()}const{error}=await _request(this.fetch,"POST",`${this.url}/otp`,{headers:this.headers,body:{email,data:(_a=options===null||options===undefined?undefined:options.data)!==null&&_a!==undefined?_a:{},create_user:(_b=options===null||options===undefined?undefined:options.shouldCreateUser)!==null&&_b!==undefined?_b:true,gotrue_meta_security:{captcha_token:options===null||options===undefined?undefined:options.captchaToken},code_challenge:codeChallenge,code_challenge_method:codeChallengeMethod},redirectTo:this._maybeAppendFlowIdToRedirect(options===null||options===undefined?undefined:options.emailRedirectTo,flowId)});return this._returnResult({data:{user:null,session:null},error})}if("phone"in credentials){const{phone,options}=credentials;const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/otp`,{headers:this.headers,body:{phone,data:(_c=options===null||options===undefined?undefined:options.data)!==null&&_c!==undefined?_c:{},create_user:(_d=options===null||options===undefined?undefined:options.shouldCreateUser)!==null&&_d!==undefined?_d:true,gotrue_meta_security:{captcha_token:options===null||options===undefined?undefined:options.captchaToken},channel:(_f=options===null||options===undefined?undefined:options.channel)!==null&&_f!==undefined?_f:"sms"}});return this._returnResult({data:{user:null,session:null,messageId:data2===null||data2===undefined?undefined:data2.message_id},error})}throw new AuthInvalidCredentialsError("You must provide either an email or phone number.")}catch(error){await removePKCEVerifier(this.storage,this.storageKey,flowId);if(isAuthError(error)){return this._returnResult({data:{user:null,session:null},error})}throw error}}async verifyOtp(params){var _a,_b;try{let redirectTo=undefined;let captchaToken=undefined;if("options"in params){redirectTo=(_a=params.options)===null||_a===undefined?undefined:_a.redirectTo;captchaToken=(_b=params.options)===null||_b===undefined?undefined:_b.captchaToken}const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/verify`,{headers:this.headers,body:Object.assign(Object.assign({},params),{gotrue_meta_security:{captcha_token:captchaToken}}),redirectTo,xform:_sessionResponse});if(error){throw error}if(!data2){const tokenVerificationError=new Error("An error occurred on token verification.");throw tokenVerificationError}const session=data2.session;const user=data2.user;if(session===null||session===undefined?undefined:session.access_token){await this._saveSession(session);await this._notifyAllSubscribers(params.type=="recovery"?"PASSWORD_RECOVERY":"SIGNED_IN",session)}return this._returnResult({data:{user,session},error:null})}catch(error){if(isAuthError(error)){return this._returnResult({data:{user:null,session:null},error})}throw error}}async signInWithSSO(params){var _a,_b,_c,_d;let flowId=null;try{let codeChallenge=null;let codeChallengeMethod=null;if(this.flowType==="pkce"){[codeChallenge,codeChallengeMethod,flowId]=await this._getCodeChallengeAndMethod()}const result2=await _request(this.fetch,"POST",`${this.url}/sso`,{body:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},"providerId"in params?{provider_id:params.providerId}:null),"domain"in params?{domain:params.domain}:null),{redirect_to:this._maybeAppendFlowIdToRedirect((_a=params.options)===null||_a===undefined?undefined:_a.redirectTo,flowId)}),((_b=params===null||params===undefined?undefined:params.options)===null||_b===undefined?undefined:_b.captchaToken)?{gotrue_meta_security:{captcha_token:params.options.captchaToken}}:null),{skip_http_redirect:true,code_challenge:codeChallenge,code_challenge_method:codeChallengeMethod}),headers:this.headers,xform:_ssoResponse});if(((_c=result2.data)===null||_c===undefined?undefined:_c.url)&&isBrowser()&&!((_d=params.options)===null||_d===undefined?undefined:_d.skipBrowserRedirect)){window.location.assign(result2.data.url)}return this._returnResult(result2)}catch(error){await removePKCEVerifier(this.storage,this.storageKey,flowId);if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async reauthenticate(){await this.initializePromise;if(this.lock!=null){return await this._acquireLock(this.lockAcquireTimeout,async()=>{return await this._reauthenticate()})}return await this._reauthenticate()}async _reauthenticate(){try{return await this._useSession(async(result2)=>{const{data:{session},error:sessionError}=result2;if(sessionError)throw sessionError;if(!session)throw new AuthSessionMissingError;const{error}=await _request(this.fetch,"GET",`${this.url}/reauthenticate`,{headers:this.headers,jwt:session.access_token});return this._returnResult({data:{user:null,session:null},error})})}catch(error){if(isAuthError(error)){return this._returnResult({data:{user:null,session:null},error})}throw error}}async resend(credentials){let flowId=null;try{const endpoint=`${this.url}/resend`;if("email"in credentials){const{email,type,options}=credentials;let codeChallenge=null;let codeChallengeMethod=null;if(this.flowType==="pkce"){[codeChallenge,codeChallengeMethod,flowId]=await this._getCodeChallengeAndMethod()}const{error}=await _request(this.fetch,"POST",endpoint,{headers:this.headers,body:{email,type,gotrue_meta_security:{captcha_token:options===null||options===undefined?undefined:options.captchaToken},code_challenge:codeChallenge,code_challenge_method:codeChallengeMethod},redirectTo:this._maybeAppendFlowIdToRedirect(options===null||options===undefined?undefined:options.emailRedirectTo,flowId)});if(error){await removePKCEVerifier(this.storage,this.storageKey,flowId)}return this._returnResult({data:{user:null,session:null},error})}else if("phone"in credentials){const{phone,type,options}=credentials;const{data:data2,error}=await _request(this.fetch,"POST",endpoint,{headers:this.headers,body:{phone,type,gotrue_meta_security:{captcha_token:options===null||options===undefined?undefined:options.captchaToken}}});return this._returnResult({data:{user:null,session:null,messageId:data2===null||data2===undefined?undefined:data2.message_id},error})}throw new AuthInvalidCredentialsError("You must provide either an email or phone number and a type")}catch(error){await removePKCEVerifier(this.storage,this.storageKey,flowId);if(isAuthError(error)){return this._returnResult({data:{user:null,session:null},error})}throw error}}async getSession(){await this.initializePromise;if(this.lock!=null){return await this._acquireLock(this.lockAcquireTimeout,async()=>{return this._useSession(async(result2)=>{return result2})})}return await this._useSession(async(result2)=>{return result2})}async _acquireLock(acquireTimeout,fn){this._debug("#_acquireLock","begin",acquireTimeout);try{if(this.lockAcquired){const last=this.pendingInLock.length?this.pendingInLock[this.pendingInLock.length-1]:Promise.resolve();const result2=(async()=>{await last;return await fn()})();this.pendingInLock.push((async()=>{try{await result2}catch(_e){}})());return result2}return await this.lock(`lock:${this.storageKey}`,acquireTimeout,async()=>{this._debug("#_acquireLock","lock acquired for storage key",this.storageKey);try{this.lockAcquired=true;const result2=fn();this.pendingInLock.push((async()=>{try{await result2}catch(e){}})());await result2;while(this.pendingInLock.length){const waitOn=[...this.pendingInLock];await Promise.all(waitOn);this.pendingInLock.splice(0,waitOn.length)}return await result2}finally{this._debug("#_acquireLock","lock released for storage key",this.storageKey);this.lockAcquired=false}})}finally{this._debug("#_acquireLock","end")}}async _useSession(fn){this._debug("#_useSession","begin");try{const result2=await this.__loadSession();return await fn(result2)}finally{this._debug("#_useSession","end")}}async __loadSession(){this._debug("#__loadSession()","begin");if(this.lock!=null&&!this.lockAcquired){this._debug("#__loadSession()","used outside of an acquired lock!",new Error().stack)}try{let currentSession=null;const maybeSession=await getItemAsync(this.storage,this.storageKey);this._debug("#getSession()","session from storage",maybeSession);if(maybeSession!==null){if(this._isValidSession(maybeSession)){currentSession=maybeSession}else{this._debug("#getSession()","session from storage is not valid");await this._removeSession()}}if(!currentSession){return{data:{session:null},error:null}}const hasExpired=currentSession.expires_at?currentSession.expires_at*1000-Date.now()<EXPIRY_MARGIN_MS:false;this._debug("#__loadSession()",`session has${hasExpired?"":" not"} expired`,"expires_at",currentSession.expires_at);if(!hasExpired){if(this.userStorage){const maybeUser=await getItemAsync(this.userStorage,this.storageKey+"-user");if(maybeUser===null||maybeUser===undefined?undefined:maybeUser.user){currentSession.user=maybeUser.user}else{currentSession.user=userNotAvailableProxy()}}if(this.storage.isServer&¤tSession.user&&!currentSession.user.__isUserNotAvailableProxy){const suppressWarningRef={value:this.suppressGetSessionWarning};currentSession.user=insecureUserWarningProxy(currentSession.user,suppressWarningRef);if(suppressWarningRef.value){this.suppressGetSessionWarning=true}}return{data:{session:currentSession},error:null}}const{data:session,error}=await this._callRefreshToken(currentSession.refresh_token);if(error){const accessTokenStillValid=!!(currentSession.expires_at&¤tSession.expires_at*1000>Date.now());if(accessTokenStillValid){const stillStored=await getItemAsync(this.storage,this.storageKey);if(stillStored&&stillStored.refresh_token===currentSession.refresh_token){return this._returnResult({data:{session:currentSession},error:null})}}return this._returnResult({data:{session:null},error})}return this._returnResult({data:{session},error:null})}finally{this._debug("#__loadSession()","end")}}async getUser(jwt){if(jwt){return await this._getUser(jwt)}await this.initializePromise;let result2;if(this.lock!=null){result2=await this._acquireLock(this.lockAcquireTimeout,async()=>{return await this._getUser()})}else{result2=await this._getUser()}if(result2.data.user){this.suppressGetSessionWarning=true}return result2}async _getUser(jwt){try{if(jwt){return await _request(this.fetch,"GET",`${this.url}/user`,{headers:this.headers,jwt,xform:_userResponse})}return await this._useSession(async(result2)=>{var _a,_b,_c;const{data:data2,error}=result2;if(error){throw error}if(!((_a=data2.session)===null||_a===undefined?undefined:_a.access_token)&&!this.hasCustomAuthorizationHeader){return{data:{user:null},error:new AuthSessionMissingError}}return await _request(this.fetch,"GET",`${this.url}/user`,{headers:this.headers,jwt:(_c=(_b=data2.session)===null||_b===undefined?undefined:_b.access_token)!==null&&_c!==undefined?_c:undefined,xform:_userResponse})})}catch(error){if(isAuthError(error)){if(isAuthSessionMissingError(error)){await this._removeSession()}return this._returnResult({data:{user:null},error})}throw error}}async updateUser(attributes,options={}){await this.initializePromise;if(this.lock!=null){return await this._acquireLock(this.lockAcquireTimeout,async()=>{return await this._updateUser(attributes,options)})}return await this._updateUser(attributes,options)}async _updateUser(attributes,options={}){let flowId=null;try{return await this._useSession(async(result2)=>{const{data:sessionData,error:sessionError}=result2;if(sessionError){throw sessionError}if(!sessionData.session){throw new AuthSessionMissingError}const session=sessionData.session;let codeChallenge=null;let codeChallengeMethod=null;if(this.flowType==="pkce"&&attributes.email!=null){[codeChallenge,codeChallengeMethod,flowId]=await this._getCodeChallengeAndMethod()}const{data:data2,error:userError}=await _request(this.fetch,"PUT",`${this.url}/user`,{headers:this.headers,redirectTo:this._maybeAppendFlowIdToRedirect(options===null||options===undefined?undefined:options.emailRedirectTo,flowId),body:Object.assign(Object.assign({},attributes),{code_challenge:codeChallenge,code_challenge_method:codeChallengeMethod}),jwt:session.access_token,xform:_userResponse});if(userError){throw userError}session.user=data2.user;await this._saveSession(session);await this._notifyAllSubscribers("USER_UPDATED",session);return this._returnResult({data:{user:session.user},error:null})})}catch(error){await removePKCEVerifier(this.storage,this.storageKey,flowId);if(isAuthError(error)){return this._returnResult({data:{user:null},error})}throw error}}async setSession(currentSession){await this.initializePromise;if(this.lock!=null){return await this._acquireLock(this.lockAcquireTimeout,async()=>{return await this._setSession(currentSession)})}return await this._setSession(currentSession)}async _setSession(currentSession){try{if(!currentSession.access_token||!currentSession.refresh_token){throw new AuthSessionMissingError}const timeNow=Date.now()/1000;let expiresAt2=timeNow;let hasExpired=true;let session=null;const{payload}=decodeJWT(currentSession.access_token);if(payload.exp){expiresAt2=payload.exp;hasExpired=expiresAt2<=timeNow}if(hasExpired){const{data:refreshedSession,error}=await this._callRefreshToken(currentSession.refresh_token);if(error){return this._returnResult({data:{user:null,session:null},error})}if(!refreshedSession){return{data:{user:null,session:null},error:null}}session=refreshedSession}else{const{data:data2,error}=await this._getUser(currentSession.access_token);if(error){return this._returnResult({data:{user:null,session:null},error})}session={access_token:currentSession.access_token,refresh_token:currentSession.refresh_token,user:data2.user,token_type:"bearer",expires_in:expiresAt2-timeNow,expires_at:expiresAt2};await this._saveSession(session);await this._notifyAllSubscribers("SIGNED_IN",session)}return this._returnResult({data:{user:session.user,session},error:null})}catch(error){if(isAuthError(error)){return this._returnResult({data:{session:null,user:null},error})}throw error}}async refreshSession(currentSession){await this.initializePromise;if(this.lock!=null){return await this._acquireLock(this.lockAcquireTimeout,async()=>{return await this._refreshSession(currentSession)})}return await this._refreshSession(currentSession)}async _refreshSession(currentSession){try{return await this._useSession(async(result2)=>{var _a;if(!currentSession){const{data:data2,error:error2}=result2;if(error2){throw error2}currentSession=(_a=data2.session)!==null&&_a!==undefined?_a:undefined}if(!(currentSession===null||currentSession===undefined?undefined:currentSession.refresh_token)){throw new AuthSessionMissingError}const{data:session,error}=await this._callRefreshToken(currentSession.refresh_token);if(error){return this._returnResult({data:{user:null,session:null},error})}if(!session){return this._returnResult({data:{user:null,session:null},error:null})}return this._returnResult({data:{user:session.user,session},error:null})})}catch(error){if(isAuthError(error)){return this._returnResult({data:{user:null,session:null},error})}throw error}}async _getSessionFromURL(params,callbackUrlType){var _a;try{if(!isBrowser())throw new AuthImplicitGrantRedirectError("No browser detected.");if(params.error||params.error_description||params.error_code){throw new AuthImplicitGrantRedirectError(params.error_description||"Error in URL with unspecified error_description",{error:params.error||"unspecified_error",code:params.error_code||"unspecified_code"})}switch(callbackUrlType){case"implicit":if(this.flowType==="pkce"){throw new AuthPKCEGrantCodeExchangeError("Not a valid PKCE flow url.")}break;case"pkce":if(this.flowType==="implicit"){throw new AuthImplicitGrantRedirectError("Not a valid implicit grant flow url.")}break;default:}if(callbackUrlType==="pkce"){this._debug("#_initialize()","begin","is PKCE flow",true);if(!params.code)throw new AuthPKCEGrantCodeExchangeError("No code detected.");const{data:data3,error:error2}=await this._exchangeCodeForSession(params.code,{flowId:params[PKCE_FLOW_ID_PARAM]});if(error2)throw error2;const url=new URL(window.location.href);url.searchParams.delete("code");url.searchParams.delete(PKCE_FLOW_ID_PARAM);window.history.replaceState(window.history.state,"",url.toString());return{data:{session:data3.session,redirectType:(_a=data3.redirectType)!==null&&_a!==undefined?_a:null},error:null}}const{provider_token,provider_refresh_token,access_token,refresh_token,expires_in,expires_at,token_type}=params;if(!access_token||!expires_in||!refresh_token||!token_type){throw new AuthImplicitGrantRedirectError("No session defined in URL")}const timeNow=Math.round(Date.now()/1000);const expiresIn=parseInt(expires_in);let expiresAt2=timeNow+expiresIn;if(expires_at){expiresAt2=parseInt(expires_at)}const actuallyExpiresIn=expiresAt2-timeNow;if(actuallyExpiresIn*1000<=AUTO_REFRESH_TICK_DURATION_MS){console.warn(`@supabase/gotrue-js: Session as retrieved from URL expires in ${actuallyExpiresIn}s, should have been closer to ${expiresIn}s`)}const issuedAt=expiresAt2-expiresIn;if(timeNow-issuedAt>=120){console.warn("@supabase/gotrue-js: Session as retrieved from URL was issued over 120s ago, URL could be stale",issuedAt,expiresAt2,timeNow)}else if(timeNow-issuedAt<0){console.warn("@supabase/gotrue-js: Session as retrieved from URL was issued in the future? Check the device clock for skew",issuedAt,expiresAt2,timeNow)}const{data:data2,error}=await this._getUser(access_token);if(error)throw error;const session={provider_token,provider_refresh_token,access_token,expires_in:expiresIn,expires_at:expiresAt2,refresh_token,token_type,user:data2.user};window.location.hash="";this._debug("#_getSessionFromURL()","clearing window.location.hash");return this._returnResult({data:{session,redirectType:params.type},error:null})}catch(error){if(isAuthError(error)){return this._returnResult({data:{session:null,redirectType:null},error})}throw error}}_isImplicitGrantCallback(params){if(typeof this.detectSessionInUrl==="function"){return this.detectSessionInUrl(new URL(window.location.href),params)}return Boolean(params.access_token||params.error||params.error_description||params.error_code)}async _isPKCECallback(params){if(!params.code){return false}const flowId=validatePKCEFlowId(params[PKCE_FLOW_ID_PARAM]);if(flowId&&await getItemAsync(this.storage,pkceVerifierSlotKey(this.storageKey,flowId))){return true}const currentStorageContent=await getItemAsync(this.storage,`${this.storageKey}-code-verifier`);return!!currentStorageContent}async signOut(options={scope:"global"}){await this.initializePromise;if(this.lock!=null){return await this._acquireLock(this.lockAcquireTimeout,async()=>{return await this._signOut(options)})}return await this._signOut(options)}async _signOut({scope}={scope:"global"}){return await this._useSession(async(result2)=>{var _a;const removeCurrentSession=async()=>{await this._removeSession()};const{data:data2,error:sessionError}=result2;if(sessionError&&!isAuthSessionMissingError(sessionError)){return this._returnResult({error:sessionError})}const accessToken=(_a=data2.session)===null||_a===undefined?undefined:_a.access_token;if(accessToken){const{error}=await this.admin.signOut(accessToken,scope);if(error){if(!(isAuthApiError(error)&&(error.status===404||error.status===401||error.status===403)||isAuthSessionMissingError(error))){if(scope!=="others"){await removeCurrentSession()}return this._returnResult({error})}}}if(scope!=="others"){await removeCurrentSession()}return this._returnResult({error:null})})}onAuthStateChange(callback){const id3=generateCallbackId();const subscription={id:id3,callback,unsubscribe:()=>{this._debug("#unsubscribe()","state change callback with id removed",id3);this.stateChangeEmitters.delete(id3)}};this._debug("#onAuthStateChange()","registered callback with id",id3);this.stateChangeEmitters.set(id3,subscription);(async()=>{await this.initializePromise;if(this.lock!=null){await this._acquireLock(this.lockAcquireTimeout,async()=>{this._emitInitialSession(id3)})}else{await this._emitInitialSession(id3)}})();return{data:{subscription}}}async _emitInitialSession(id3){return await this._useSession(async(result2)=>{var _a,_b;try{const{data:{session},error}=result2;if(error)throw error;await((_a=this.stateChangeEmitters.get(id3))===null||_a===undefined?undefined:_a.callback("INITIAL_SESSION",session));this._debug("INITIAL_SESSION","callback id",id3,"session",session)}catch(err){await((_b=this.stateChangeEmitters.get(id3))===null||_b===undefined?undefined:_b.callback("INITIAL_SESSION",null));this._debug("INITIAL_SESSION","callback id",id3,"error",err);if(isAuthRefreshDiscardedError(err)){return}if(isAuthSessionMissingError(err)||isAuthRetryableFetchError(err)||isAuthApiError(err)&&(err.code==="refresh_token_not_found"||err.code==="refresh_token_already_used"||err.code==="session_expired")){console.warn(err)}else{console.error(err)}}})}async resetPasswordForEmail(email,options={}){let codeChallenge=null;let codeChallengeMethod=null;let flowId=null;if(this.flowType==="pkce"){[codeChallenge,codeChallengeMethod,flowId]=await this._getCodeChallengeAndMethod(true)}try{return await _request(this.fetch,"POST",`${this.url}/recover`,{body:{email,code_challenge:codeChallenge,code_challenge_method:codeChallengeMethod,gotrue_meta_security:{captcha_token:options.captchaToken}},headers:this.headers,redirectTo:this._maybeAppendFlowIdToRedirect(options.redirectTo,flowId)})}catch(error){await removePKCEVerifier(this.storage,this.storageKey,flowId);if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async getUserIdentities(){var _a;try{const{data:data2,error}=await this.getUser();if(error)throw error;return this._returnResult({data:{identities:(_a=data2.user.identities)!==null&&_a!==undefined?_a:[]},error:null})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async linkIdentity(credentials){if("token"in credentials){return this.linkIdentityIdToken(credentials)}return this.linkIdentityOAuth(credentials)}async linkIdentityOAuth(credentials){var _a;let flowId=null;try{const{data:data2,error}=await this._useSession(async(result2)=>{var _a2,_b,_c,_d,_f;const{data:data3,error:error2}=result2;if(error2)throw error2;const{url,flowId:urlFlowId}=await this._getUrlForProvider(`${this.url}/user/identities/authorize`,credentials.provider,{redirectTo:(_a2=credentials.options)===null||_a2===undefined?undefined:_a2.redirectTo,scopes:(_b=credentials.options)===null||_b===undefined?undefined:_b.scopes,queryParams:(_c=credentials.options)===null||_c===undefined?undefined:_c.queryParams,skipBrowserRedirect:true});flowId=urlFlowId;return await _request(this.fetch,"GET",url,{headers:this.headers,jwt:(_f=(_d=data3.session)===null||_d===undefined?undefined:_d.access_token)!==null&&_f!==undefined?_f:undefined})});if(error)throw error;if(isBrowser()&&!((_a=credentials.options)===null||_a===undefined?undefined:_a.skipBrowserRedirect)){window.location.assign(data2===null||data2===undefined?undefined:data2.url)}return this._returnResult({data:{provider:credentials.provider,url:data2===null||data2===undefined?undefined:data2.url,flowId},error:null})}catch(error){if(isAuthError(error)){return this._returnResult({data:{provider:credentials.provider,url:null,flowId},error})}throw error}}async linkIdentityIdToken(credentials){return await this._useSession(async(result2)=>{var _a;try{const{error:sessionError,data:{session}}=result2;if(sessionError)throw sessionError;const{options,provider,token,access_token,nonce}=credentials;const res=await _request(this.fetch,"POST",`${this.url}/token?grant_type=id_token`,{headers:this.headers,jwt:(_a=session===null||session===undefined?undefined:session.access_token)!==null&&_a!==undefined?_a:undefined,body:{provider,id_token:token,access_token,nonce,link_identity:true,gotrue_meta_security:{captcha_token:options===null||options===undefined?undefined:options.captchaToken}},xform:_sessionResponse});const{data:data2,error}=res;if(error){return this._returnResult({data:{user:null,session:null},error})}else if(!data2||!data2.session||!data2.user){return this._returnResult({data:{user:null,session:null},error:new AuthInvalidTokenResponseError})}if(data2.session){await this._saveSession(data2.session);await this._notifyAllSubscribers("USER_UPDATED",data2.session)}return this._returnResult({data:data2,error})}catch(error){await removePKCEVerifier(this.storage,this.storageKey,null);if(isAuthError(error)){return this._returnResult({data:{user:null,session:null},error})}throw error}})}async unlinkIdentity(identity){try{return await this._useSession(async(result2)=>{var _a,_b;const{data:data2,error}=result2;if(error){throw error}return await _request(this.fetch,"DELETE",`${this.url}/user/identities/${identity.identity_id}`,{headers:this.headers,jwt:(_b=(_a=data2.session)===null||_a===undefined?undefined:_a.access_token)!==null&&_b!==undefined?_b:undefined})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _refreshAccessToken(refreshToken){const debugName=`#_refreshAccessToken()`;this._debug(debugName,"begin");try{const startedAt=Date.now();return await retryable(async(attempt)=>{if(attempt>0){await sleep(200*Math.pow(2,attempt-1))}this._debug(debugName,"refreshing attempt",attempt);return await _request(this.fetch,"POST",`${this.url}/token?grant_type=refresh_token`,{body:{refresh_token:refreshToken},headers:this.headers,xform:_sessionResponse})},(attempt,error)=>{const nextBackOffInterval=200*Math.pow(2,attempt);return error&&isAuthRetryableFetchError(error)&&Date.now()+nextBackOffInterval-startedAt<AUTO_REFRESH_TICK_DURATION_MS})}catch(error){this._debug(debugName,"error",error);if(isAuthError(error)){return this._returnResult({data:{session:null,user:null},error})}throw error}finally{this._debug(debugName,"end")}}_isValidSession(maybeSession){const isValidSession=typeof maybeSession==="object"&&maybeSession!==null&&"access_token"in maybeSession&&"refresh_token"in maybeSession&&"expires_at"in maybeSession;return isValidSession}async _handleProviderSignIn(provider,options){const{url,flowId}=await this._getUrlForProvider(`${this.url}/authorize`,provider,{redirectTo:options.redirectTo,scopes:options.scopes,queryParams:options.queryParams});this._debug("#_handleProviderSignIn()","provider",provider,"options",options,"url",url);if(isBrowser()&&!options.skipBrowserRedirect){window.location.assign(url)}return{data:{provider,url,flowId},error:null}}async _recoverAndRefresh(){var _a,_b;const debugName="#_recoverAndRefresh()";this._debug(debugName,"begin");try{const currentSession=await getItemAsync(this.storage,this.storageKey);if(currentSession&&this.userStorage){let maybeUser=await getItemAsync(this.userStorage,this.storageKey+"-user");if(!this.storage.isServer&&Object.is(this.storage,this.userStorage)&&!maybeUser){maybeUser={user:currentSession.user};await setItemAsync(this.userStorage,this.storageKey+"-user",maybeUser)}currentSession.user=(_a=maybeUser===null||maybeUser===undefined?undefined:maybeUser.user)!==null&&_a!==undefined?_a:userNotAvailableProxy()}else if(currentSession&&!currentSession.user){if(!currentSession.user){const separateUser=await getItemAsync(this.storage,this.storageKey+"-user");if(separateUser&&(separateUser===null||separateUser===undefined?undefined:separateUser.user)){currentSession.user=separateUser.user;await removeItemAsync(this.storage,this.storageKey+"-user");await setItemAsync(this.storage,this.storageKey,currentSession)}else{currentSession.user=userNotAvailableProxy()}}}this._debug(debugName,"session from storage",currentSession);if(!this._isValidSession(currentSession)){this._debug(debugName,"session is not valid");if(currentSession!==null){await this._removeSession()}return}const expiresWithMargin=((_b=currentSession.expires_at)!==null&&_b!==undefined?_b:Infinity)*1000-Date.now()<EXPIRY_MARGIN_MS;this._debug(debugName,`session has${expiresWithMargin?"":" not"} expired with margin of ${EXPIRY_MARGIN_MS}s`);if(expiresWithMargin){if(this.autoRefreshToken&¤tSession.refresh_token){const{error}=await this._callRefreshToken(currentSession.refresh_token);if(error){if(isAuthRefreshDiscardedError(error)){this._debug(debugName,"refresh discarded by commit guard",error)}else{this._debug(debugName,"refresh failed",error)}}}}else if(currentSession.user&¤tSession.user.__isUserNotAvailableProxy===true){try{const{data:data2,error:userError}=await this._getUser(currentSession.access_token);if(!userError&&(data2===null||data2===undefined?undefined:data2.user)){currentSession.user=data2.user;await this._saveSession(currentSession);await this._notifyAllSubscribers("SIGNED_IN",currentSession)}else{this._debug(debugName,"could not get user data, skipping SIGNED_IN notification")}}catch(getUserError){console.error("Error getting user data:",getUserError);this._debug(debugName,"error getting user data, skipping SIGNED_IN notification",getUserError)}}else{await this._notifyAllSubscribers("SIGNED_IN",currentSession)}}catch(err){this._debug(debugName,"error",err);if(isAuthRetryableFetchError(err)){console.warn(err)}else{console.error(err)}return}finally{this._debug(debugName,"end")}}async _callRefreshToken(refreshToken){var _a,_b;if(!refreshToken){throw new AuthSessionMissingError}if(this.refreshingDeferred){return this.refreshingDeferred.promise}if(this.lastRefreshFailure&&this.lastRefreshFailure.refreshToken===refreshToken&&Date.now()<this.lastRefreshFailure.expiresAt){this._debug("#_callRefreshToken()","returning cached failure (cooldown active)");return this.lastRefreshFailure.result}const debugName=`#_callRefreshToken()`;this._debug(debugName,"begin");try{this.refreshingDeferred=new Deferred;this.refreshingDeferred.promise.then(undefined,()=>{});const storedAtStart=await getItemAsync(this.storage,this.storageKey);const{data:data2,error}=await this._refreshAccessToken(refreshToken);if(error)throw error;if(!data2.session)throw new AuthSessionMissingError;const storedAfter=await getItemAsync(this.storage,this.storageKey);const storageChangedUnderUs=storedAtStart!==null&&(storedAfter===null||storedAfter.refresh_token!==storedAtStart.refresh_token);if(storageChangedUnderUs){this._debug(debugName,"commit guard: storage changed since refresh started, discarding rotated tokens",{startedWith:"present",nowHolds:storedAfter?"replaced":"cleared"});const discarded={data:null,error:new AuthRefreshDiscardedError};this.refreshingDeferred.resolve(discarded);return discarded}const epochBeforeSave=this._sessionRemovalEpoch;await this._saveSession(data2.session);if(this._sessionRemovalEpoch!==epochBeforeSave){this._debug(debugName,"commit guard (post-save): _removeSession ran during _saveSession, undoing write");await removeItemAsync(this.storage,this.storageKey);if(this.userStorage){await removeItemAsync(this.userStorage,this.storageKey+"-user")}const discarded={data:null,error:new AuthRefreshDiscardedError};this.refreshingDeferred.resolve(discarded);return discarded}await this._notifyAllSubscribers("TOKEN_REFRESHED",data2.session);const result2={data:data2.session,error:null};this.lastRefreshFailure=null;this.refreshingDeferred.resolve(result2);return result2}catch(error){this._debug(debugName,"error",error);if(isAuthError(error)){const result2={data:null,error};if(!isAuthRetryableFetchError(error)){const storedNow=await getItemAsync(this.storage,this.storageKey);const accessTokenStillValid=!!((storedNow===null||storedNow===undefined?undefined:storedNow.expires_at)&&storedNow.expires_at*1000>Date.now());if(accessTokenStillValid){this._debug(debugName,"proactive refresh failed, access token still valid — preserving session")}else{await this._removeSession()}}this.lastRefreshFailure={refreshToken,result:result2,expiresAt:Date.now()+REFRESH_FAILURE_COOLDOWN_MS};(_a=this.refreshingDeferred)===null||_a===undefined||_a.resolve(result2);return result2}(_b=this.refreshingDeferred)===null||_b===undefined||_b.reject(error);throw error}finally{this.refreshingDeferred=null;this._debug(debugName,"end")}}async _notifyAllSubscribers(event,session,broadcast=true){if(this._pendingInitNotifications!==null&&broadcast){this._pendingInitNotifications.push({event,session,broadcast});return}const debugName=`#_notifyAllSubscribers(${event})`;this._debug(debugName,"begin",session,`broadcast = ${broadcast}`);try{if(this.broadcastChannel&&broadcast){this.broadcastChannel.postMessage({event,session})}const errors=[];const promises=Array.from(this.stateChangeEmitters.values()).map(async(x)=>{try{await x.callback(event,session)}catch(e){errors.push(e)}});await Promise.all(promises);if(errors.length>0){for(let i=0;i<errors.length;i+=1){console.error(errors[i])}throw errors[0]}}finally{this._debug(debugName,"end")}}async _saveSession(session){this._debug("#_saveSession()",session);this.suppressGetSessionWarning=true;const sessionToProcess=Object.assign({},session);const userIsProxy=sessionToProcess.user&&sessionToProcess.user.__isUserNotAvailableProxy===true;if(this.userStorage){if(!userIsProxy&&sessionToProcess.user){await setItemAsync(this.userStorage,this.storageKey+"-user",{user:sessionToProcess.user})}else if(userIsProxy){}const mainSessionData=Object.assign({},sessionToProcess);delete mainSessionData.user;const clonedMainSessionData=deepClone(mainSessionData);await setItemAsync(this.storage,this.storageKey,clonedMainSessionData)}else{const clonedSession=deepClone(sessionToProcess);await setItemAsync(this.storage,this.storageKey,clonedSession)}}async _removeSession(){this._sessionRemovalEpoch+=1;this._debug("#_removeSession()");this.lastRefreshFailure=null;this.suppressGetSessionWarning=false;await removeItemAsync(this.storage,this.storageKey);await removeAllPKCEVerifiers(this.storage,this.storageKey);await removeItemAsync(this.storage,this.storageKey+"-user");if(this.userStorage){await removeItemAsync(this.userStorage,this.storageKey+"-user")}await this._notifyAllSubscribers("SIGNED_OUT",null)}_removeVisibilityChangedCallback(){this._debug("#_removeVisibilityChangedCallback()");const callback=this.visibilityChangedCallback;this.visibilityChangedCallback=null;try{if(callback&&isBrowser()&&(window===null||window===undefined?undefined:window.removeEventListener)){window.removeEventListener("visibilitychange",callback)}}catch(e){console.error("removing visibilitychange callback failed",e)}}async _startAutoRefresh(){await this._stopAutoRefresh();this._debug("#_startAutoRefresh()");const ticker=setInterval(()=>this._autoRefreshTokenTick(),AUTO_REFRESH_TICK_DURATION_MS);this.autoRefreshTicker=ticker;if(ticker&&typeof ticker==="object"&&typeof ticker.unref==="function"){ticker.unref()}else if(typeof Deno!=="undefined"&&typeof Deno.unrefTimer==="function"){Deno.unrefTimer(ticker)}const timeout=setTimeout(async()=>{await this.initializePromise;await this._autoRefreshTokenTick()},0);this.autoRefreshTickTimeout=timeout;if(timeout&&typeof timeout==="object"&&typeof timeout.unref==="function"){timeout.unref()}else if(typeof Deno!=="undefined"&&typeof Deno.unrefTimer==="function"){Deno.unrefTimer(timeout)}}async _stopAutoRefresh(){this._debug("#_stopAutoRefresh()");const ticker=this.autoRefreshTicker;this.autoRefreshTicker=null;if(ticker){clearInterval(ticker)}const timeout=this.autoRefreshTickTimeout;this.autoRefreshTickTimeout=null;if(timeout){clearTimeout(timeout)}}async startAutoRefresh(){this._removeVisibilityChangedCallback();await this._startAutoRefresh()}async stopAutoRefresh(){this._removeVisibilityChangedCallback();await this._stopAutoRefresh()}async dispose(){var _a;this._removeVisibilityChangedCallback();await this._stopAutoRefresh();(_a=this.broadcastChannel)===null||_a===undefined||_a.close();this.broadcastChannel=null;this.stateChangeEmitters.clear()}async _autoRefreshTokenTick(){this._debug("#_autoRefreshTokenTick()","begin");if(this.lock!=null){try{await this._acquireLock(0,async()=>{try{const now=Date.now();try{return await this._useSession(async(result2)=>{const{data:{session}}=result2;if(!session||!session.refresh_token||!session.expires_at){this._debug("#_autoRefreshTokenTick()","no session");return}const expiresInTicks=Math.floor((session.expires_at*1000-now)/AUTO_REFRESH_TICK_DURATION_MS);this._debug("#_autoRefreshTokenTick()",`access token expires in ${expiresInTicks} ticks, a tick lasts ${AUTO_REFRESH_TICK_DURATION_MS}ms, refresh threshold is ${AUTO_REFRESH_TICK_THRESHOLD} ticks`);if(expiresInTicks<=AUTO_REFRESH_TICK_THRESHOLD){await this._callRefreshToken(session.refresh_token)}})}catch(e){console.error("Auto refresh tick failed with error. This is likely a transient error.",e)}}finally{this._debug("#_autoRefreshTokenTick()","end")}})}catch(e){if(e instanceof LockAcquireTimeoutError){this._debug("auto refresh token tick lock not available")}else{throw e}}return}if(this.refreshingDeferred!==null){this._debug("#_autoRefreshTokenTick()","refresh already in flight, skipping");return}try{const now=Date.now();try{await this._useSession(async(result2)=>{const{data:{session}}=result2;if(!session||!session.refresh_token||!session.expires_at){this._debug("#_autoRefreshTokenTick()","no session");return}const expiresInTicks=Math.floor((session.expires_at*1000-now)/AUTO_REFRESH_TICK_DURATION_MS);this._debug("#_autoRefreshTokenTick()",`access token expires in ${expiresInTicks} ticks, a tick lasts ${AUTO_REFRESH_TICK_DURATION_MS}ms, refresh threshold is ${AUTO_REFRESH_TICK_THRESHOLD} ticks`);if(expiresInTicks<=AUTO_REFRESH_TICK_THRESHOLD){await this._callRefreshToken(session.refresh_token)}})}catch(e){console.error("Auto refresh tick failed with error. This is likely a transient error.",e)}}finally{this._debug("#_autoRefreshTokenTick()","end")}}async _handleVisibilityChange(){this._debug("#_handleVisibilityChange()");if(!isBrowser()||!(window===null||window===undefined?undefined:window.addEventListener)){if(this.autoRefreshToken){this.startAutoRefresh()}return false}try{this.visibilityChangedCallback=async()=>{try{await this._onVisibilityChanged(false)}catch(error){this._debug("#visibilityChangedCallback","error",error)}};window===null||window===undefined||window.addEventListener("visibilitychange",this.visibilityChangedCallback);await this._onVisibilityChanged(true)}catch(error){console.error("_handleVisibilityChange",error)}}async _onVisibilityChanged(calledFromInitialize){const methodName=`#_onVisibilityChanged(${calledFromInitialize})`;this._debug(methodName,"visibilityState",document.visibilityState);if(document.visibilityState==="visible"){if(this.autoRefreshToken){this._startAutoRefresh()}if(!calledFromInitialize){await this.initializePromise;if(this.lock!=null){await this._acquireLock(this.lockAcquireTimeout,async()=>{if(document.visibilityState!=="visible"){this._debug(methodName,"acquired the lock to recover the session, but the browser visibilityState is no longer visible, aborting");return}await this._recoverAndRefresh()})}else{if(document.visibilityState!=="visible"){this._debug(methodName,"visibilityState is no longer visible, skipping recovery");return}await this._recoverAndRefresh()}}}else if(document.visibilityState==="hidden"){if(this.autoRefreshToken){this._stopAutoRefresh()}}}async _getUrlForProvider(url,provider,options){let redirectTo=options===null||options===undefined?undefined:options.redirectTo;let codeChallenge=null;let codeChallengeMethod=null;let flowId=null;if(this.flowType==="pkce"){[codeChallenge,codeChallengeMethod,flowId]=await this._getCodeChallengeAndMethod();redirectTo=this._maybeAppendFlowIdToRedirect(redirectTo,flowId)}const urlParams=[`provider=${encodeURIComponent(provider)}`];if(redirectTo){urlParams.push(`redirect_to=${encodeURIComponent(redirectTo)}`)}if(options===null||options===undefined?undefined:options.scopes){urlParams.push(`scopes=${encodeURIComponent(options.scopes)}`)}if(codeChallenge!=null&&codeChallengeMethod!=null){const flowParams=new URLSearchParams({code_challenge:`${encodeURIComponent(codeChallenge)}`,code_challenge_method:`${encodeURIComponent(codeChallengeMethod)}`});urlParams.push(flowParams.toString())}if(options===null||options===undefined?undefined:options.queryParams){const query=new URLSearchParams(options.queryParams);urlParams.push(query.toString())}if(options===null||options===undefined?undefined:options.skipBrowserRedirect){urlParams.push(`skip_http_redirect=${options.skipBrowserRedirect}`)}return{url:`${url}?${urlParams.join("&")}`,flowId}}_maybeAppendFlowIdToRedirect(redirectTo,flowId){if(!redirectTo||!flowId||!this.experimental.appendPkceFlowIdToRedirects){return redirectTo!==null&&redirectTo!==undefined?redirectTo:undefined}return appendFlowIdToRedirectTo(redirectTo,flowId)}async _getCodeChallengeAndMethod(isPasswordRecovery=false){return getCodeChallengeAndMethod(this.storage,this.storageKey,isPasswordRecovery,(evictedFlowId)=>this._debug("#_getCodeChallengeAndMethod()","evicted oldest pending PKCE verifier slot",evictedFlowId))}async _unenroll(params){try{return await this._useSession(async(result2)=>{var _a;const{data:sessionData,error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}return await _request(this.fetch,"DELETE",`${this.url}/factors/${params.factorId}`,{headers:this.headers,jwt:(_a=sessionData===null||sessionData===undefined?undefined:sessionData.session)===null||_a===undefined?undefined:_a.access_token})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _enroll(params){try{return await this._useSession(async(result2)=>{var _a,_b;const{data:sessionData,error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}const body=Object.assign({friendly_name:params.friendlyName,factor_type:params.factorType},params.factorType==="phone"?{phone:params.phone}:params.factorType==="totp"?{issuer:params.issuer}:{});const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/factors`,{body,headers:this.headers,jwt:(_a=sessionData===null||sessionData===undefined?undefined:sessionData.session)===null||_a===undefined?undefined:_a.access_token});if(error){return this._returnResult({data:null,error})}if(params.factorType==="totp"&&data2.type==="totp"&&((_b=data2===null||data2===undefined?undefined:data2.totp)===null||_b===undefined?undefined:_b.qr_code)){data2.totp.qr_code=`data:image/svg+xml;utf-8,${data2.totp.qr_code}`}return this._returnResult({data:data2,error:null})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _verify(params){const run=async()=>{try{return await this._useSession(async(result2)=>{var _a;const{data:sessionData,error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}const body=Object.assign({challenge_id:params.challengeId},"webauthn"in params?{webauthn:Object.assign(Object.assign({},params.webauthn),{credential_response:params.webauthn.type==="create"?serializeCredentialCreationResponse(params.webauthn.credential_response):serializeCredentialRequestResponse(params.webauthn.credential_response)})}:{code:params.code});const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/factors/${params.factorId}/verify`,{body,headers:this.headers,jwt:(_a=sessionData===null||sessionData===undefined?undefined:sessionData.session)===null||_a===undefined?undefined:_a.access_token});if(error){return this._returnResult({data:null,error})}await this._saveSession(Object.assign({expires_at:Math.round(Date.now()/1000)+data2.expires_in},data2));await this._notifyAllSubscribers("MFA_CHALLENGE_VERIFIED",data2);return this._returnResult({data:data2,error})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}};if(this.lock!=null){return this._acquireLock(this.lockAcquireTimeout,run)}return run()}async _challenge(params){const run=async()=>{try{return await this._useSession(async(result2)=>{var _a;const{data:sessionData,error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}const response2=await _request(this.fetch,"POST",`${this.url}/factors/${params.factorId}/challenge`,{body:params,headers:this.headers,jwt:(_a=sessionData===null||sessionData===undefined?undefined:sessionData.session)===null||_a===undefined?undefined:_a.access_token});if(response2.error){return response2}const{data:data2}=response2;if(data2.type!=="webauthn"){return{data:data2,error:null}}switch(data2.webauthn.type){case"create":return{data:Object.assign(Object.assign({},data2),{webauthn:Object.assign(Object.assign({},data2.webauthn),{credential_options:Object.assign(Object.assign({},data2.webauthn.credential_options),{publicKey:deserializeCredentialCreationOptions(data2.webauthn.credential_options.publicKey)})})}),error:null};case"request":return{data:Object.assign(Object.assign({},data2),{webauthn:Object.assign(Object.assign({},data2.webauthn),{credential_options:Object.assign(Object.assign({},data2.webauthn.credential_options),{publicKey:deserializeCredentialRequestOptions(data2.webauthn.credential_options.publicKey)})})}),error:null}}})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}};if(this.lock!=null){return this._acquireLock(this.lockAcquireTimeout,run)}return run()}async _challengeAndVerify(params){const{data:challengeData,error:challengeError}=await this._challenge({factorId:params.factorId});if(challengeError){return this._returnResult({data:null,error:challengeError})}return await this._verify({factorId:params.factorId,challengeId:challengeData.id,code:params.code})}async _listFactors(){var _a;const{data:{user},error:userError}=await this.getUser();if(userError){return{data:null,error:userError}}const data2={all:[],phone:[],totp:[],webauthn:[],recovery_code:[]};for(const factor of(_a=user===null||user===undefined?undefined:user.factors)!==null&&_a!==undefined?_a:[]){data2.all.push(factor);if(factor.status==="verified"&&factor.factor_type in data2&&Array.isArray(data2[factor.factor_type])){data2[factor.factor_type].push(factor)}}return{data:data2,error:null}}async _getAuthenticatorAssuranceLevel(jwt){var _a,_b,_c,_d;if(jwt){try{const{payload:payload2}=decodeJWT(jwt);let currentLevel2=null;if(payload2.aal){currentLevel2=payload2.aal}let nextLevel2=currentLevel2;const{data:{user},error:userError}=await this.getUser(jwt);if(userError){return this._returnResult({data:null,error:userError})}const verifiedFactors2=(_b=(_a=user===null||user===undefined?undefined:user.factors)===null||_a===undefined?undefined:_a.filter((factor)=>factor.status==="verified"))!==null&&_b!==undefined?_b:[];if(verifiedFactors2.length>0){nextLevel2="aal2"}const currentAuthenticationMethods2=payload2.amr||[];return{data:{currentLevel:currentLevel2,nextLevel:nextLevel2,currentAuthenticationMethods:currentAuthenticationMethods2},error:null}}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}const{data:{session},error:sessionError}=await this.getSession();if(sessionError){return this._returnResult({data:null,error:sessionError})}if(!session){return{data:{currentLevel:null,nextLevel:null,currentAuthenticationMethods:[]},error:null}}const{payload}=decodeJWT(session.access_token);let currentLevel=null;if(payload.aal){currentLevel=payload.aal}let nextLevel=currentLevel;const verifiedFactors=(_d=(_c=session.user.factors)===null||_c===undefined?undefined:_c.filter((factor)=>factor.status==="verified"))!==null&&_d!==undefined?_d:[];if(verifiedFactors.length>0){nextLevel="aal2"}const currentAuthenticationMethods=payload.amr||[];return{data:{currentLevel,nextLevel,currentAuthenticationMethods},error:null}}async _getRecoveryCodesStatus(){assertRecoveryCodesExperimentalEnabled(this.experimental);try{return await this._useSession(async(result2)=>{var _a;const{data:sessionData,error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}const{data:data2,error}=await _request(this.fetch,"GET",`${this.url}/factors/recovery-codes`,{headers:this.headers,jwt:(_a=sessionData===null||sessionData===undefined?undefined:sessionData.session)===null||_a===undefined?undefined:_a.access_token});if(error){return this._returnResult({data:null,error})}return this._returnResult({data:data2,error:null})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _generateRecoveryCodes(params){assertRecoveryCodesExperimentalEnabled(this.experimental);try{return await this._useSession(async(result2)=>{var _a;const{data:sessionData,error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/factors/recovery-codes`,{body:(params===null||params===undefined?undefined:params.friendlyName)?{friendly_name:params.friendlyName}:undefined,headers:this.headers,jwt:(_a=sessionData===null||sessionData===undefined?undefined:sessionData.session)===null||_a===undefined?undefined:_a.access_token});if(error){return this._returnResult({data:null,error})}return this._returnResult({data:data2,error:null})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _verifyRecoveryCode(params){assertRecoveryCodesExperimentalEnabled(this.experimental);const run=async()=>{try{return await this._useSession(async(result2)=>{var _a;const{data:sessionData,error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/factors/recovery-codes/verify`,{body:{code:params.code},headers:this.headers,jwt:(_a=sessionData===null||sessionData===undefined?undefined:sessionData.session)===null||_a===undefined?undefined:_a.access_token});if(error){return this._returnResult({data:null,error})}const session=Object.assign({expires_at:expiresAt(data2.expires_in)},data2);await this._saveSession(session);await this._notifyAllSubscribers("MFA_CHALLENGE_VERIFIED",session);return this._returnResult({data:data2,error:null})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}};if(this.lock!=null){return this._acquireLock(this.lockAcquireTimeout,run)}return run()}async _regenerateRecoveryCodes(){assertRecoveryCodesExperimentalEnabled(this.experimental);try{return await this._useSession(async(result2)=>{var _a;const{data:sessionData,error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/factors/recovery-codes/regenerate`,{headers:this.headers,jwt:(_a=sessionData===null||sessionData===undefined?undefined:sessionData.session)===null||_a===undefined?undefined:_a.access_token});if(error){return this._returnResult({data:null,error})}return this._returnResult({data:data2,error:null})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _unenrollRecoveryCodes(){assertRecoveryCodesExperimentalEnabled(this.experimental);try{return await this._useSession(async(result2)=>{var _a;const{data:sessionData,error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}const{data:data2,error}=await _request(this.fetch,"DELETE",`${this.url}/factors/recovery-codes`,{headers:this.headers,jwt:(_a=sessionData===null||sessionData===undefined?undefined:sessionData.session)===null||_a===undefined?undefined:_a.access_token});if(error){return this._returnResult({data:null,error})}return this._returnResult({data:data2,error:null})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _getAuthorizationDetails(authorizationId){try{return await this._useSession(async(result2)=>{const{data:{session},error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}if(!session){return this._returnResult({data:null,error:new AuthSessionMissingError})}return await _request(this.fetch,"GET",`${this.url}/oauth/authorizations/${authorizationId}`,{headers:this.headers,jwt:session.access_token,xform:(data2)=>({data:data2,error:null})})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _approveAuthorization(authorizationId,options){try{return await this._useSession(async(result2)=>{const{data:{session},error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}if(!session){return this._returnResult({data:null,error:new AuthSessionMissingError})}const response2=await _request(this.fetch,"POST",`${this.url}/oauth/authorizations/${authorizationId}/consent`,{headers:this.headers,jwt:session.access_token,body:{action:"approve"},xform:(data2)=>({data:data2,error:null})});if(response2.data&&response2.data.redirect_url){if(isBrowser()&&!(options===null||options===undefined?undefined:options.skipBrowserRedirect)){window.location.assign(response2.data.redirect_url)}}return response2})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _denyAuthorization(authorizationId,options){try{return await this._useSession(async(result2)=>{const{data:{session},error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}if(!session){return this._returnResult({data:null,error:new AuthSessionMissingError})}const response2=await _request(this.fetch,"POST",`${this.url}/oauth/authorizations/${authorizationId}/consent`,{headers:this.headers,jwt:session.access_token,body:{action:"deny"},xform:(data2)=>({data:data2,error:null})});if(response2.data&&response2.data.redirect_url){if(isBrowser()&&!(options===null||options===undefined?undefined:options.skipBrowserRedirect)){window.location.assign(response2.data.redirect_url)}}return response2})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _listOAuthGrants(){try{return await this._useSession(async(result2)=>{const{data:{session},error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}if(!session){return this._returnResult({data:null,error:new AuthSessionMissingError})}return await _request(this.fetch,"GET",`${this.url}/user/oauth/grants`,{headers:this.headers,jwt:session.access_token,xform:(data2)=>({data:data2,error:null})})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _revokeOAuthGrant(options){try{return await this._useSession(async(result2)=>{const{data:{session},error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}if(!session){return this._returnResult({data:null,error:new AuthSessionMissingError})}await _request(this.fetch,"DELETE",`${this.url}/user/oauth/grants`,{headers:this.headers,jwt:session.access_token,query:{client_id:options.clientId},noResolveJson:true});return{data:{},error:null}})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async fetchJwk(kid,jwks={keys:[]}){let jwk=jwks.keys.find((key)=>key.kid===kid);if(jwk){return jwk}const now=Date.now();jwk=this.jwks.keys.find((key)=>key.kid===kid);if(jwk&&this.jwks_cached_at+JWKS_TTL>now){return jwk}const{data:data2,error}=await _request(this.fetch,"GET",`${this.url}/.well-known/jwks.json`,{headers:this.headers});if(error){throw error}if(!data2.keys||data2.keys.length===0){return null}this.jwks=data2;this.jwks_cached_at=now;jwk=data2.keys.find((key)=>key.kid===kid);if(!jwk){return null}return jwk}async getClaims(jwt,options={}){try{let token=jwt;if(!token){const{data:data2,error}=await this.getSession();if(error||!data2.session){return this._returnResult({data:null,error})}token=data2.session.access_token}const{header,payload,signature,raw:{header:rawHeader,payload:rawPayload}}=decodeJWT(token);if(!(options===null||options===undefined?undefined:options.allowExpired)){try{validateExp(payload.exp)}catch(e){throw new AuthInvalidJwtError(e instanceof Error?e.message:"JWT validation failed")}}const signingKey=!header.alg||header.alg.startsWith("HS")||!header.kid||!(("crypto"in globalThis)&&("subtle"in globalThis.crypto))?null:await this.fetchJwk(header.kid,(options===null||options===undefined?undefined:options.keys)?{keys:options.keys}:options===null||options===undefined?undefined:options.jwks);if(!signingKey){const{error}=await this.getUser(token);if(error){throw error}return{data:{claims:payload,header,signature},error:null}}const algorithm=getAlgorithm(header.alg);const publicKey=await crypto.subtle.importKey("jwk",signingKey,algorithm,true,["verify"]);const isValid=await crypto.subtle.verify(algorithm,publicKey,signature,stringToUint8Array(`${rawHeader}.${rawPayload}`));if(!isValid){throw new AuthInvalidJwtError("Invalid JWT signature")}return{data:{claims:payload,header,signature},error:null}}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async signInWithPasskey(credentials){var _a,_b,_c;assertPasskeyExperimentalEnabled(this.experimental);try{if(!browserSupportsWebAuthn()){return this._returnResult({data:null,error:new AuthUnknownError("Browser does not support WebAuthn",null)})}const{data:options,error:optionsError}=await this._startPasskeyAuthentication({options:{captchaToken:(_a=credentials===null||credentials===undefined?undefined:credentials.options)===null||_a===undefined?undefined:_a.captchaToken}});if(optionsError||!options){return this._returnResult({data:null,error:optionsError})}const publicKeyOptions=deserializeCredentialRequestOptions(options.options);const signal=(_c=(_b=credentials===null||credentials===undefined?undefined:credentials.options)===null||_b===undefined?undefined:_b.signal)!==null&&_c!==undefined?_c:webAuthnAbortService.createNewAbortSignal();const{data:credential,error:credentialError}=await getCredential({publicKey:publicKeyOptions,signal});if(credentialError||!credential){return this._returnResult({data:null,error:credentialError!==null&&credentialError!==undefined?credentialError:new AuthUnknownError("WebAuthn ceremony failed",null)})}const serialized=serializeCredentialRequestResponse(credential);return this._verifyPasskeyAuthentication({challengeId:options.challenge_id,credential:serialized})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async registerPasskey(credentials){var _a,_b;assertPasskeyExperimentalEnabled(this.experimental);try{if(!browserSupportsWebAuthn()){return this._returnResult({data:null,error:new AuthUnknownError("Browser does not support WebAuthn",null)})}const{data:options,error:optionsError}=await this._startPasskeyRegistration();if(optionsError||!options){return this._returnResult({data:null,error:optionsError})}const publicKeyOptions=deserializeCredentialCreationOptions(options.options);const signal=(_b=(_a=credentials===null||credentials===undefined?undefined:credentials.options)===null||_a===undefined?undefined:_a.signal)!==null&&_b!==undefined?_b:webAuthnAbortService.createNewAbortSignal();const{data:credential,error:credentialError}=await createCredential({publicKey:publicKeyOptions,signal});if(credentialError||!credential){return this._returnResult({data:null,error:credentialError!==null&&credentialError!==undefined?credentialError:new AuthUnknownError("WebAuthn ceremony failed",null)})}const serialized=serializeCredentialCreationResponse(credential);return this._verifyPasskeyRegistration({challengeId:options.challenge_id,credential:serialized})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _startPasskeyRegistration(){assertPasskeyExperimentalEnabled(this.experimental);try{return await this._useSession(async(result2)=>{const{data:{session},error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}if(!session){return this._returnResult({data:null,error:new AuthSessionMissingError})}const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/passkeys/registration/options`,{headers:this.headers,jwt:session.access_token,body:{}});if(error){return this._returnResult({data:null,error})}return this._returnResult({data:data2,error:null})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _verifyPasskeyRegistration(params){assertPasskeyExperimentalEnabled(this.experimental);try{return await this._useSession(async(result2)=>{const{data:{session},error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}if(!session){return this._returnResult({data:null,error:new AuthSessionMissingError})}const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/passkeys/registration/verify`,{headers:this.headers,jwt:session.access_token,body:{challenge_id:params.challengeId,credential:params.credential}});if(error){return this._returnResult({data:null,error})}return this._returnResult({data:data2,error:null})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _startPasskeyAuthentication(params){var _a;assertPasskeyExperimentalEnabled(this.experimental);try{const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/passkeys/authentication/options`,{headers:this.headers,body:{gotrue_meta_security:{captcha_token:(_a=params===null||params===undefined?undefined:params.options)===null||_a===undefined?undefined:_a.captchaToken}}});if(error){return this._returnResult({data:null,error})}return this._returnResult({data:data2,error:null})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _verifyPasskeyAuthentication(params){assertPasskeyExperimentalEnabled(this.experimental);try{const{data:data2,error}=await _request(this.fetch,"POST",`${this.url}/passkeys/authentication/verify`,{headers:this.headers,body:{challenge_id:params.challengeId,credential:params.credential},xform:_sessionResponse});if(error){return this._returnResult({data:null,error})}if(data2.session){await this._saveSession(data2.session);await this._notifyAllSubscribers("SIGNED_IN",data2.session)}return this._returnResult({data:data2,error:null})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _listPasskeys(){assertPasskeyExperimentalEnabled(this.experimental);try{return await this._useSession(async(result2)=>{const{data:{session},error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}if(!session){return this._returnResult({data:null,error:new AuthSessionMissingError})}const{data:data2,error}=await _request(this.fetch,"GET",`${this.url}/passkeys`,{headers:this.headers,jwt:session.access_token,xform:(data3)=>({data:data3,error:null})});if(error){return this._returnResult({data:null,error})}return this._returnResult({data:data2,error:null})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _updatePasskey(params){assertPasskeyExperimentalEnabled(this.experimental);try{return await this._useSession(async(result2)=>{const{data:{session},error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}if(!session){return this._returnResult({data:null,error:new AuthSessionMissingError})}const{data:data2,error}=await _request(this.fetch,"PATCH",`${this.url}/passkeys/${params.passkeyId}`,{headers:this.headers,jwt:session.access_token,body:{friendly_name:params.friendlyName}});if(error){return this._returnResult({data:null,error})}return this._returnResult({data:data2,error:null})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}async _deletePasskey(params){assertPasskeyExperimentalEnabled(this.experimental);try{return await this._useSession(async(result2)=>{const{data:{session},error:sessionError}=result2;if(sessionError){return this._returnResult({data:null,error:sessionError})}if(!session){return this._returnResult({data:null,error:new AuthSessionMissingError})}const{error}=await _request(this.fetch,"DELETE",`${this.url}/passkeys/${params.passkeyId}`,{headers:this.headers,jwt:session.access_token,noResolveJson:true});if(error){return this._returnResult({data:null,error})}return this._returnResult({data:null,error:null})})}catch(error){if(isAuthError(error)){return this._returnResult({data:null,error})}throw error}}}var DEFAULT_OPTIONS,GLOBAL_JWKS,deprecatedLockWarned=false,GoTrueClient_default;var init_GoTrueClient=__esm(()=>{init_GoTrueAdminApi();init_constants();init_errors();init_fetch();init_helpers();init_locks();init_base64url();init_webauthn();polyfillGlobalThis();DEFAULT_OPTIONS={url:GOTRUE_URL,storageKey:STORAGE_KEY,autoRefreshToken:true,persistSession:true,detectSessionInUrl:true,headers:DEFAULT_HEADERS,flowType:"implicit",debug:false,hasCustomAuthorizationHeader:false,throwOnError:false,lockAcquireTimeout:5000,skipAutoInitialize:false,experimental:{}};GLOBAL_JWKS={};GoTrueClient.nextInstanceID={};GoTrueClient_default=GoTrueClient});var init_AuthAdminApi=__esm(()=>{init_GoTrueAdminApi()});var AuthClient,AuthClient_default;var init_AuthClient=__esm(()=>{init_GoTrueClient();AuthClient=GoTrueClient_default;AuthClient_default=AuthClient});var init_module=__esm(()=>{init_GoTrueAdminApi();init_GoTrueClient();init_AuthAdminApi();init_AuthClient();init_locks();init_types();init_errors()});var exports_auth_provider={};__export(exports_auth_provider,{AuthClient:()=>AuthClient_default});var init_auth_provider=__esm(()=>{init_module()});var fileValidationReasons={invalid_metadata:"File metadata must contain only the supported fields.",invalid_name:"File name must be 1–255 characters, with no reserved names, path separators, control characters or trailing spaces/dots.",invalid_path:"File path must contain safe relative folder names and cannot start with .os.",invalid_storage:"File storage must be local or remote.",invalid_media_type:"The media type must use a value such as text/markdown or application/json.",invalid_size:"File size must be a non-negative safe integer byte count.",invalid_request_key:"File request key must contain 1–256 characters, with no surrounding whitespace or control characters.",invalid_enrichment_name:"The enrichment name must be a filename without folders, such as read.md. Names such as original and original.pdf are reserved.",invalid_enrichment_request:"The save request has invalid content or metadata.",invalid_replacement:"To replace an enrichment, pass its current SHA-256 value as replace.",invalid_bytes:"File content must contain byte chunks.",original_changed:"The selected file changed while OS was reading it. Wait for it to finish saving, then try again."};var localStorageReasons={local_storage_legacy:`OS found an older local file storage layout: the internal metadata folder is still named .oddington-files.
|
|
19
19
|
|
|
20
20
|
Stop any OS routines using this workspace, then rename .oddington-files to .os in the same directory and rerun your command. Keep the folder’s contents intact.`,local_storage_ambiguous:"OS found both .oddington-files and .os metadata folders in local file storage and could not safely choose one. Reconcile their metadata before continuing; do not overwrite either folder. Your stored files have been left in place.",local_storage_unrecognized:"OS could not open its local file storage because the folder contains files but has no recognized metadata. The storage folder needs to be checked before continuing. Your stored files have been left in place.",local_storage_tracked:"OS could not use its local file storage because it contains Git-tracked files. Local file storage must be outside tracked repository content. Your stored files have been left in place."};function parseFileErrorDetail(value){if(!value||typeof value!=="object"||Array.isArray(value))return;const v=value;if(typeof v.reason!=="string")return;if(Object.hasOwn(fileValidationReasons,v.reason)||Object.hasOwn(localStorageReasons,v.reason))return Object.keys(v).length===1?{reason:v.reason}:undefined;if(v.reason!=="size_mismatch"&&v.reason!=="size_limit")return;const count=v.reason==="size_mismatch"?"expectedBytes":"limitBytes";if(Object.keys(v).some((key)=>!["reason",count,"receivedBytes","receivedAtLeast"].includes(key))||!Number.isSafeInteger(v[count])||v[count]<0||!Number.isSafeInteger(v.receivedBytes)||v.receivedBytes<0||v.receivedAtLeast!==undefined&&v.receivedAtLeast!==true)return;return{reason:v.reason,[count]:v[count],receivedBytes:v.receivedBytes,...v.receivedAtLeast?{receivedAtLeast:true}:{}}}function fileErrorExplanation(detail){if(detail.reason==="size_mismatch")return`The request declared ${detail.expectedBytes} bytes, but contained ${detail.receivedAtLeast?"at least ":""}${detail.receivedBytes} bytes.`;if(detail.reason==="size_limit")return`The file content exceeds the ${fileSizeLabel(detail.limitBytes)} limit; received ${detail.receivedAtLeast?"at least ":""}${fileSizeLabel(detail.receivedBytes)}.`;return Object.hasOwn(localStorageReasons,detail.reason)?localStorageReasons[detail.reason]:fileValidationReasons[detail.reason]}function fileSizeLabel(bytes){for(const[unit,size]of[["GiB",1024**3],["MiB",1024**2],["KiB",1024]])if(bytes>=size&&bytes%size===0)return`${bytes/size} ${unit}`;return`${bytes} bytes`}function fileErrorDetailForCode(code,detail){const parsed=parseFileErrorDetail(detail);if(!parsed)return;const storage=Object.hasOwn(localStorageReasons,parsed.reason);if(storage?code==="unavailable":["invalid_input","request_too_large"].includes(code))return parsed}var FILE_CAPACITY_MESSAGE="OS reached its file-processing limit. Try again in a moment. "+"If this keeps happening with a large batch, split the files into smaller groups.";var FILE_INTEGRITY_MESSAGE="OS could not verify this File against its saved record. Try again. "+"If the problem continues, add the original file again.";function fileErrorMessage(error){const detail=fileErrorDetailForCode(error.code,error.detail);if(detail){const enrichment=["invalid_enrichment_name","invalid_enrichment_request","invalid_replacement"].includes(detail.reason);return`${enrichment?`Couldn’t save the file’s enrichment.
|
|
21
|
-
`:""}${fileErrorExplanation(detail)}`}switch(error.code){case"invalid_input":return"The file request is invalid.";case"unsupported_context":return"This environment does not support this file operation.";case"unauthenticated":return"Sign in to OS before accessing files.";case"access_denied":return"You don’t have access to this file operation.";case"request_too_large":return"The file request exceeds the size limit.";case"conflict":return"The saved file or enrichment doesn’t match this request. Reload it before trying again.";case"local_only":return"This file is stored on a computer and isn’t available through remote storage.";case"integrity":return FILE_INTEGRITY_MESSAGE;case"capacity":return FILE_CAPACITY_MESSAGE;case"method_not_allowed":return"This request uses an unsupported file operation.";case"unavailable":return`OS couldn’t complete the file operation.${error.retryable?" Try again.":""}`}}class FileOperationError extends Error{code;status;retryable;detail;constructor(code,status,retryable=false,detail){const safe=fileErrorDetailForCode(code,detail);super(fileErrorMessage({code,retryable,detail:safe}));this.code=code;this.status=status;this.retryable=retryable;if(safe)this.detail=Object.freeze(safe);if(safe&&Object.hasOwn(localStorageReasons,safe.reason))this.retryable=false}}var FILE_ID_PATTERN=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;var FILE_ORIGINAL_MAX_BYTES=5*1024**3;function parseFileDescriptor(value){const invalid=()=>{throw new FileOperationError("unavailable",503,true)};if(!value||typeof value!=="object"||Array.isArray(value))return invalid();const f=value;if(Object.keys(f).sort().join(",")!=="enrichments,id,mediaType,name,path,sha256,size"||typeof f.id!=="string"||!FILE_ID_PATTERN.test(f.id)||!safeFileName(f.name)||!safeFilePath(f.path)||!Number.isSafeInteger(f.size)||f.size<0||f.size>FILE_ORIGINAL_MAX_BYTES||typeof f.sha256!=="string"||!/^[0-9a-f]{64}$/.test(f.sha256)||!f.enrichments||typeof f.enrichments!=="object"||Array.isArray(f.enrichments)||!isCanonicalOriginalMediaType(f.mediaType))return invalid();for(const[name,descriptor]of Object.entries(f.enrichments)){if(!safeEnrichmentName(name))return invalid();parseEnrichmentDescriptor(descriptor)}if(new TextEncoder().encode(JSON.stringify(f)).byteLength>16*1024)return invalid();return f}function parseEnrichmentDescriptor(value){const invalid=()=>{throw new FileOperationError("unavailable",503,true)};if(!value||typeof value!=="object"||Array.isArray(value))return invalid();const d=value;if(Object.keys(d).sort().join(",")!=="mediaType,sha256,size"||!["application/octet-stream","text/plain","text/markdown","application/json"].includes(d.mediaType)||!Number.isSafeInteger(d.size)||d.size<0||d.size>16*1024*1024||typeof d.sha256!=="string"||!/^[0-9a-f]{64}$/.test(d.sha256))return invalid();return d}function safeEnrichmentName(value){return safeFileName(value)&&!/^original(?:\.|$)/i.test(value)}function parseFileEnrichMetadata(value,maxBytes){const invalid=(reason="invalid_metadata")=>{throw new FileOperationError("invalid_input",400,false,{reason})};if(!value||typeof value!=="object"||Array.isArray(value))return invalid();const d=value;if(Object.keys(d).some((key)=>!["name","size","mediaType","replace"].includes(key)))return invalid();if(!safeEnrichmentName(d.name))return invalid("invalid_enrichment_name");if(!Number.isSafeInteger(d.size)||d.size<0)return invalid("invalid_size");if(d.mediaType!==undefined&&(typeof d.mediaType!=="string"||d.mediaType.length>255||/[\u0000-\u001f\u007f]/.test(d.mediaType)))return invalid("invalid_media_type");if(d.replace!==undefined&&(typeof d.replace!=="string"||!/^[0-9a-f]{64}$/.test(d.replace)))return invalid("invalid_replacement");if(d.size>maxBytes)throw new FileOperationError("request_too_large",413,false,{reason:"size_limit",limitBytes:maxBytes,receivedBytes:d.size});return d}function safeFileName(value){return typeof value==="string"&&value.length>0&&value.length<=255&&value===value.trim()&&value!=="."&&value!==".."&&!/[\u0000-\u001f\u007f-\u009f/\\:*?"<>|]/u.test(value)&&!/[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/.test(value)&&!/[. ]$/.test(value)&&!/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(value)}function safeFilePath(value){return typeof value==="string"&&value.length<=1024&&value.split("/").every(safeFileName)}function safeManagedFilePath(value){return safeFilePath(value)&&value.split("/")[0].toLowerCase()!==".os"}function declaredOriginalMediaType(value){if(typeof value!=="string"||value.length>255||/[\u0000-\u001f\u007f-\u009f]/.test(value))throw new FileOperationError("invalid_input",400,false,{reason:"invalid_media_type"});const normalized=value.split(";",1)[0].trim().toLowerCase();const token="[a-z0-9!#$%&'+.^_`|~-]+";if(!new RegExp(`^${token}/${token}$`).test(normalized))throw new FileOperationError("invalid_input",400,false,{reason:"invalid_media_type"});return normalized}function isCanonicalOriginalMediaType(value){try{return declaredOriginalMediaType(value)===value}catch{return false}}function parseFileCreateMetadata(value,maxBytes){const invalid=(reason="invalid_metadata")=>{throw new FileOperationError("invalid_input",400,false,{reason})};if(!value||typeof value!=="object"||Array.isArray(value))return invalid();const input=value;if(Object.keys(input).some((key)=>!["name","path","storage","mediaType","size","requestKey"].includes(key)))return invalid();const path=input.path===undefined?"Files":input.path;if(!safeFileName(input.name))return invalid("invalid_name");if(!safeManagedFilePath(path))return invalid("invalid_path");if(input.storage!==undefined&&input.storage!=="remote"&&input.storage!=="local")return invalid("invalid_storage");const mediaType=input.mediaType===undefined?"application/octet-stream":declaredOriginalMediaType(input.mediaType);if(!Number.isSafeInteger(input.size)||input.size<0)return invalid("invalid_size");if(input.size>maxBytes)throw new FileOperationError("request_too_large",413,false,{reason:"size_limit",limitBytes:maxBytes,receivedBytes:input.size});if(typeof input.requestKey!=="string"||input.requestKey.length<1||input.requestKey.length>256||input.requestKey!==input.requestKey.trim()||/[\u0000-\u001f\u007f]/.test(input.requestKey))return invalid("invalid_request_key");return{name:input.name,path,...input.storage?{storage:input.storage}:{},mediaType,size:input.size,requestKey:input.requestKey}}class AppRoutineContractError extends Error{code;constructor(code){super(code);this.code=code}}var propertyName=/^[a-z][A-Za-z0-9]*(?![\s\S])/;var stepId=/^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/;var routineName=/^[a-z0-9][a-z0-9-]{0,62}(?![\s\S])/;function isAppRoutineName(value){return typeof value==="string"&&routineName.test(value)}var owns=(value,key)=>Object.hasOwn(value,key);var invalidContract=()=>{throw new AppRoutineContractError("invalid_contract")};var invalidValue=()=>{throw new AppRoutineContractError("invalid_value")};function record(value){return value!==null&&typeof value==="object"&&!Array.isArray(value)&&(Object.getPrototypeOf(value)===Object.prototype||Object.getPrototypeOf(value)===null)}function fields(value,required,optional=[]){return required.every((key)=>owns(value,key))&&Object.keys(value).every((key)=>required.includes(key)||optional.includes(key))}function denseArray(value){return Array.isArray(value)&&Object.keys(value).length===value.length&&Array.from({length:value.length},(_,index)=>owns(value,String(index))).every(Boolean)}function parseAppRoutineContract(value){let properties=0;function schema(value2,depth=1){if(depth>8||!record(value2))return invalidContract();switch(value2.type){case"object":{if(!fields(value2,["type","properties","additionalProperties"],["required"])||value2.additionalProperties!==false||!record(value2.properties))return invalidContract();const entries=Object.entries(value2.properties);properties+=entries.length;if(properties>64||entries.some(([key])=>!propertyName.test(key)))return invalidContract();let required;if(owns(value2,"required")){if(!denseArray(value2.required)||value2.required.some((key)=>typeof key!=="string"||!owns(value2.properties,key))||new Set(value2.required).size!==value2.required.length)return invalidContract();required=[...value2.required]}return{type:"object",properties:Object.fromEntries(entries.map(([key,child])=>[key,schema(child,depth+1)])),...required===undefined?{}:{required},additionalProperties:false}}case"array":if(!fields(value2,["type","items"],["maxItems"])||owns(value2,"maxItems")&&(!Number.isSafeInteger(value2.maxItems)||value2.maxItems<1))return invalidContract();return{type:"array",items:schema(value2.items,depth+1),...owns(value2,"maxItems")?{maxItems:value2.maxItems}:{}};case"boolean":if(!fields(value2,["type"]))return invalidContract();return{type:value2.type};case"file":if(!fields(value2,["type"],["storage","path"])||owns(value2,"storage")&&value2.storage!=="local"&&value2.storage!=="remote"||owns(value2,"path")&&!safeManagedFilePath(value2.path))return invalidContract();return{type:"file",...owns(value2,"storage")?{storage:value2.storage}:{},...owns(value2,"path")?{path:value2.path}:{}};case"string":if(!fields(value2,["type"],["maxLength"])||owns(value2,"maxLength")&&(!Number.isSafeInteger(value2.maxLength)||value2.maxLength<0||value2.maxLength>4096))return invalidContract();return{type:"string",...owns(value2,"maxLength")?{maxLength:value2.maxLength}:{}};case"integer":case"number":{const validNumber=value2.type==="integer"?Number.isSafeInteger:Number.isFinite;if(!fields(value2,["type"],["minimum","maximum"])||owns(value2,"minimum")&&!validNumber(value2.minimum)||owns(value2,"maximum")&&!validNumber(value2.maximum)||owns(value2,"minimum")&&owns(value2,"maximum")&&value2.minimum>value2.maximum)return invalidContract();return{type:value2.type,...owns(value2,"minimum")?{minimum:value2.minimum}:{},...owns(value2,"maximum")?{maximum:value2.maximum}:{}}}default:return invalidContract()}}if(!record(value)||!fields(value,["routine","input","steps"],["result"])||!isAppRoutineName(value.routine)||!denseArray(value.steps)||value.steps.length<1||value.steps.length>64)return invalidContract();const input=schema(value.input);const result=owns(value,"result")?schema(value.result):undefined;const ids=new Set;const steps=value.steps.map((step)=>{if(!record(step)||!fields(step,["id"],["summary"])||typeof step.id!=="string"||!stepId.test(step.id)||ids.has(step.id))return invalidContract();ids.add(step.id);return{id:step.id,...owns(step,"summary")?{summary:schema(step.summary)}:{}}});return{routine:value.routine,input,steps,...result===undefined?{}:{result}}}function jsonData(value,ancestors=new Set){if(value===null||typeof value==="string"||typeof value==="boolean"||typeof value==="number"&&Number.isFinite(value))return;if(!record(value)&&!denseArray(value))return invalidValue();if(ancestors.has(value))return invalidValue();ancestors.add(value);for(const child of Object.values(value))jsonData(child,ancestors);ancestors.delete(value)}function validateRoutineSchemaValue(schema,value,rejected){const type=(value2)=>value2===null?"null":Array.isArray(value2)?"array":["object","boolean","string","number"].includes(typeof value2)?typeof value2:"other";function check(schema2,value2,path){const fail=(reason,extra={})=>{rejected?.({reason,path:path.length<=256?path:"$",expected:schema2.type,received:type(value2),...extra});return invalidValue()};switch(schema2.type){case"object":if(!record(value2))return fail("wrong_type");for(const key of schema2.required??[])if(!owns(value2,key))return fail("missing_field",{path:`${path}.${key}`.length<=256?`${path}.${key}`:"$",expected:schema2.properties[key].type,received:"missing"});if(Object.keys(value2).some((key)=>!owns(schema2.properties,key)))return fail("unexpected_field");for(const[key,child]of Object.entries(value2))check(schema2.properties[key],child,`${path}.${key}`);return;case"array":if(!denseArray(value2))return fail("wrong_type");if(schema2.maxItems!==undefined&&value2.length>schema2.maxItems)return fail("out_of_bounds",{constraint:"maxItems",limit:schema2.maxItems});value2.forEach((child,index)=>check(schema2.items,child,`${path}[${index}]`));return;case"boolean":if(typeof value2!=="boolean")return fail("wrong_type");return;case"string":if(typeof value2!=="string")return fail("wrong_type");if(Array.from(value2).length>(schema2.maxLength??4096))return fail("out_of_bounds",{constraint:"maxLength",limit:schema2.maxLength??4096});return;case"integer":case"number":if(typeof value2!=="number"||!(schema2.type==="integer"?Number.isSafeInteger(value2):Number.isFinite(value2)))return fail("wrong_type");if(schema2.minimum!==undefined&&value2<schema2.minimum)return fail("out_of_bounds",{constraint:"minimum",limit:schema2.minimum});if(schema2.maximum!==undefined&&value2>schema2.maximum)return fail("out_of_bounds",{constraint:"maximum",limit:schema2.maximum});return;case"file":{let file;try{jsonData(value2);file=parseFileDescriptor(value2)}catch{return fail("invalid_file")}if(schema2.path!==undefined&&file.path!==schema2.path)return fail("invalid_file")}}}check(schema,value,"$")}class InboxContractError extends Error{constructor(message){super(message);this.name="InboxContractError"}}var INBOX_PUBLICATION_ITEM_BYTES=1024*1024;var INBOX_PUBLICATION_REQUEST_BYTES=INBOX_PUBLICATION_ITEM_BYTES+4096;var publicationAdvice="Trim the content, or attach long reports, data, and supporting materials as files instead. Then try again.";var INBOX_PUBLICATION_TOO_LARGE=`Your Inbox item failed to publish. Its content exceeds the 1 MB limit. ${publicationAdvice}`;class InboxPublicationSizeError extends InboxContractError{kind;bytes;constructor(kind,bytes){const label=kind==="ask"?"Ask":"Digest";const size=Math.ceil(bytes/INBOX_PUBLICATION_ITEM_BYTES*100)/100;super(`Your ${label} failed to publish. Its content is ${size} MB, which exceeds the 1 MB limit. ${publicationAdvice}`);this.kind=kind;this.bytes=bytes;this.name="InboxPublicationSizeError"}}function enforcePublicationSize(value){const bytes=new TextEncoder().encode(JSON.stringify(value)).byteLength;if(bytes>INBOX_PUBLICATION_ITEM_BYTES)throw new InboxPublicationSizeError(value.kind,bytes);return value}function fail(message){throw new InboxContractError(message)}function object(value,label){if(!value||typeof value!=="object"||Array.isArray(value)||![Object.prototype,null].includes(Object.getPrototypeOf(value)))fail(`${label} must be a plain object`);return value}function keys(value,allowed,label){for(const key of Reflect.ownKeys(value)){if(typeof key!=="string"||!allowed.includes(key))fail(`${label} does not support ${String(key)}`);const descriptor=Object.getOwnPropertyDescriptor(value,key);if(!descriptor.enumerable||!("value"in descriptor))fail(`${label} must contain only JSON data`)}}function text(value,label){if(typeof value!=="string"||!value.trim())fail(`${label} must be nonempty text`);return value}function id(value,label){const result=text(value,label);if(result!==result.trim())fail(`${label} cannot have surrounding whitespace`);return result}function array(value,label){if(!Array.isArray(value)||Object.getPrototypeOf(value)!==Array.prototype||Reflect.ownKeys(value).length!==value.length+1)fail(`${label} must be a dense array`);for(let index=0;index<value.length;index+=1){const descriptor=Object.getOwnPropertyDescriptor(value,String(index));if(!descriptor?.enumerable||!("value"in descriptor))fail(`${label} must contain only JSON data`)}return value}function distinctIds(value,label,nonempty=true){const result=array(value,label).map((entry)=>id(entry,label));if(nonempty&&!result.length)fail(`${label} must not be empty`);if(new Set(result).size!==result.length)fail(`${label} contains duplicate IDs`);return result}var memberEmail=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;function personReference(value,label){const result=id(value,label);return memberEmail.test(result)?result.toLowerCase():result}function distinctPeople(value,label,nonempty=true){const result=array(value,label).map((entry)=>personReference(entry,label));if(nonempty&&!result.length)fail(`${label} must not be empty`);if(new Set(result).size!==result.length)fail(`${label} contains duplicate IDs`);return result}function serializable(value,ancestors=new Set){if(value===null||typeof value==="boolean"||typeof value==="string")return value;if(typeof value==="number"&&Number.isFinite(value))return value;if(!value||typeof value!=="object")fail("Input must be losslessly serializable JSON");if(ancestors.has(value))fail("Input cannot contain cycles");ancestors.add(value);try{if(Array.isArray(value)){array(value,"JSON array");return value.map((entry)=>serializable(entry,ancestors))}const source=object(value,"JSON input");keys(source,Object.keys(source),"JSON input");return Object.fromEntries(Object.entries(source).map(([key,entry])=>[key,serializable(entry,ancestors)]))}finally{ancestors.delete(value)}}function natural(value,label,minimum=0){if(!Number.isSafeInteger(value)||value<minimum)fail(`${label} must be an integer >= ${minimum}`);return value}function validateInboxFile(value){const v=object(serializable(value),"Inbox file");keys(v,["id","name","mediaType","size","sha256"],"Inbox file");const fileId=id(v.id,"Inbox file ID"),name=id(v.name,"filename"),mediaType=id(v.mediaType,"media type");if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(fileId)||/[\x00-\x1f\x7f/\\]/.test(name)||!isCanonicalOriginalMediaType(mediaType)||typeof v.sha256!=="string"||!/^[0-9a-f]{64}$/.test(v.sha256))fail("Invalid Inbox file identity or metadata");const size=natural(v.size,"file size");if(size>FILE_ORIGINAL_MAX_BYTES)fail("File exceeds supported size");return{id:fileId,name,mediaType,size,sha256:v.sha256}}function fields2(value){const result=array(value,"selected fields").map((entry)=>{const field=object(entry,"field");keys(field,["label","value"],"field");return{label:text(field.label,"field label"),value:text(field.value,"field value")}});if(new Set(result.map((field)=>field.label)).size!==result.length)fail("Duplicate field label");return result}function validateBlock(value){const b=object(serializable(value),"Block");if(b.kind==="rich-text"){keys(b,["kind","markdown"],"Rich text Block");return{kind:"rich-text",markdown:text(b.markdown,"Markdown")}}if(b.kind==="asks"){keys(b,["kind","problem","asks"],"Asks Block");const asks=distinctIds(b.asks,"Ask IDs");if(asks.some((ask)=>!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(ask)))fail("Invalid Ask ID");return{kind:"asks",problem:text(b.problem,"problem"),asks}}if(!["record","records","files"].includes(b.kind))fail("Unknown Block kind");keys(b,["kind","label","initiallyExpanded",...b.kind==="record"?["record","view"]:b.kind==="records"?["records","view"]:["files"]],"Block");const label=text(b.label,"Block label");if(b.initiallyExpanded!==undefined&&typeof b.initiallyExpanded!=="boolean")fail("Invalid initiallyExpanded");const expanded=b.initiallyExpanded===undefined?{}:{initiallyExpanded:b.initiallyExpanded};const target=b.view===undefined?{}:{view:id(b.view,"View target")};if(b.kind==="record"){const r=object(b.record,"presented record");keys(r,["ref","title","fields"],"presented record");return{kind:"record",label,...target,...expanded,record:{ref:id(r.ref,"record reference"),title:text(r.title,"record title"),fields:fields2(r.fields)}}}if(b.kind==="records"){const records=array(b.records,"records").map((entry)=>{const r=object(entry,"record summary");keys(r,["ref","title","description","facts","view"],"record summary");return{ref:id(r.ref,"record reference"),title:text(r.title,"record title"),...r.description===undefined?{}:{description:text(r.description,"record description")},...r.facts===undefined?{}:{facts:fields2(r.facts)},...r.view===undefined?{}:{view:id(r.view,"row View target")}}});if(!records.length||new Set(records.map((r)=>r.ref)).size!==records.length)fail("Empty or duplicate records");return{kind:"records",label,records,...target,...expanded}}const files=array(b.files,"files").map(validateInboxFile);if(!files.length||new Set(files.map((file)=>file.id)).size!==files.length)fail("Empty or duplicate files");return{kind:"files",label,files,...expanded}}function richTextBlock(value){return validateBlock({...value,kind:"rich-text"})}function recordBlock(value){return validateBlock({...value,kind:"record"})}function recordsBlock(value){return validateBlock({...value,kind:"records"})}function fileBlock(value){const input=object(serializable(value),"Files Block");const files=array(input.files,"files").map((entry)=>{const descriptor=object(entry,"File");if(!(("path"in descriptor)||("enrichments"in descriptor)))return validateInboxFile(descriptor);let file;try{file=parseFileDescriptor(descriptor)}catch{return fail("Invalid shared File descriptor")}const{id:id2,name,mediaType,size,sha256}=file;return{id:id2,name,mediaType,size,sha256}});return validateBlock({...input,kind:"files",files})}function asksBlock(value){return validateBlock({...value,kind:"asks"})}function selection(value){const input=object(value,"selection");keys(input,["source"],"selection");return validateResponseDefinition({type:"selection",source:input.source})}function validateAuthoredSource(value){const source=object(value,"response definition");keys(source,["type","options","suggestions","search"],"response definition");if(source.type!=="authored")fail("Expected authored options");const options=array(source.options,"options").map((entry)=>{const option=object(entry,"choice");keys(option,["value","label","description","note"],"choice");let note;if(option.note!==undefined){const declaration=object(option.note,"choice note");keys(declaration,["placeholder"],"choice note");note={placeholder:text(declaration.placeholder,"note placeholder")}}return{value:id(option.value,"choice value"),label:text(option.label,"choice label"),...option.description===undefined?{}:{description:text(option.description,"choice description")},...note?{note}:{}}});if(!options.length)fail("Choices require at least one option");if(new Set(options.map((option)=>option.value)).size!==options.length)fail("Duplicate choice value");if(Object.hasOwn(source,"search")||Object.hasOwn(source,"suggestions")){const labels=object(source.search,"choice search");keys(labels,["triggerLabel","placeholder","emptyLabel"],"choice search");const search={triggerLabel:text(labels.triggerLabel,"search trigger label"),placeholder:text(labels.placeholder,"search placeholder"),emptyLabel:text(labels.emptyLabel,"search empty label")};const suggestions=array(source.suggestions,"suggestions").map((value2)=>id(value2,"suggestion value"));if(suggestions.length>8||new Set(suggestions).size!==suggestions.length||suggestions.some((value2)=>!options.some((option)=>option.value===value2)))fail("Search permits at most eight unique published suggestions");return{type:"authored",options,suggestions,search}}if(options.length>9)fail("Choices require one to nine options");return{type:"authored",options}}function validateRecordReference(value){const row=object(value,"Record reference");keys(row,["repository","ref"],"Record reference");const repository=id(row.repository,"repository"),ref=id(row.ref,"Record reference");if(!/^[a-z0-9][a-z0-9._/-]{0,127}$/.test(repository)||/\.\.|\/\//.test(repository)||ref.length>512||!/^[_a-zA-Z0-9][a-zA-Z0-9_-]*(\/[_a-zA-Z0-9][a-zA-Z0-9_-]*)+$/.test(ref))fail("Invalid Record identity");return{repository,ref}}function validateRecordSource(value){const source=object(value,"Record selection");keys(source,["type","collection","refPrefix","where","display","suggestions"],"Record selection");if(source.type!=="records")fail("Expected Record options");const collection=object(source.collection,"collection");keys(collection,["repository","name"],"collection");const repository=validateRecordReference({repository:collection.repository,ref:"records/example"}).repository;const name=id(collection.name,"collection name");if(!/^[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_-]+)*$/.test(name))fail("Invalid collection name");const refPrefix=source.refPrefix===undefined?undefined:id(source.refPrefix,"Record reference prefix");if(refPrefix!==undefined&&(!refPrefix.endsWith("/")||refPrefix.length>512||!/^[_a-zA-Z0-9][a-zA-Z0-9_-]*(\/[_a-zA-Z0-9][a-zA-Z0-9_-]*)*\/$/.test(refPrefix)))fail("Invalid Record reference prefix");const where=object(source.where??{},"Record filter");const fieldName=(name2)=>/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name2)&&!["constructor","prototype"].includes(name2);for(const[name2,value2]of Object.entries(where)){if(!fieldName(name2)||!(value2===null||["string","number","boolean"].includes(typeof value2))||typeof value2==="number"&&!Number.isFinite(value2))fail("Record filters require scalar equality")}const display=object(source.display,"Record display");keys(display,["labelFields"],"Record display");const labelFields=distinctIds(display.labelFields,"label fields");if(labelFields.length>2||labelFields.some((name2)=>!fieldName(name2)))fail("Select one or two scalar label fields");const suggestions=array(source.suggestions??[],"suggestions").map((value2)=>{const entry=object(value2,"suggestion");keys(entry,["record","reason"],"suggestion");const record2=validateRecordReference(entry.record);if(record2.repository!==repository)fail("Suggestion belongs to another repository");return{record:record2,...entry.reason===undefined?{}:{reason:text(entry.reason,"suggestion reason")}}});if(suggestions.length>8||new Set(suggestions.map((entry)=>entry.record.ref)).size!==suggestions.length)fail("Record selection permits at most eight unique suggestions");return{type:"records",collection:{repository,name},...refPrefix?{refPrefix}:{},where:{...where},display:{labelFields},suggestions}}function validateResponseDefinition(value){const definition=object(value,"response definition");keys(definition,["type","source"],"response definition");if(definition.type!=="selection")fail("Expected a selection definition");const source=object(definition.source,"option source");switch(source.type){case"authored":return{type:"selection",source:validateAuthoredSource(source)};case"records":return{type:"selection",source:validateRecordSource(source)};default:return fail("Unsupported option source")}}function handlerReference(value){const source=object(value,"handler reference");keys(source,["id","input"],"handler reference");return{id:id(source.id,"handler ID"),input:serializable(source.input)}}function defineHandler(value){const source=object(value,"handler");keys(source,["id","results","run"],"handler");const stable=(value2)=>typeof value2==="string"&&/^[a-zA-Z0-9][a-zA-Z0-9_./-]{0,127}$/.test(value2);if(!stable(source.id))fail("Handler ID must be stable");const results=source.results===undefined?undefined:distinctIds(source.results,"handler results",false);if(results&&(results.length>64||results.some((result)=>!stable(result))))fail("Handler results must be stable IDs");if(typeof source.run!=="function")fail("Handler requires a run function");return Object.freeze({id:value.id,...results===undefined?{}:{results:Object.freeze(results.sort())},run:value.run})}function respond(handler,input){defineHandler(handler);return handlerReference({id:handler.id,input})}function question(value){const source=object(value,"question");keys(source,["id","to","allowedResponders","prompt","instructions","response","handler"],"question");const to=personReference(source.to,"question assignee");const allowedResponders=source.allowedResponders===undefined?[to]:distinctPeople(source.allowedResponders,"allowed responders");if(!allowedResponders.includes(to))fail("Allowed responders must include the assignee");return{id:id(source.id,"question ID"),to,allowedResponders,prompt:text(source.prompt,"question prompt"),...source.instructions===undefined?{}:{instructions:text(source.instructions,"instructions")},response:validateResponseDefinition(source.response),...Object.hasOwn(source,"handler")?{handler:handlerReference(source.handler)}:{}}}function presentation(source){const views=source.views===undefined?[]:array(source.views,"views").map((entry)=>{const view=object(entry,"view");keys(view,["id","view","input"],"view");return{id:id(view.id,"view ID"),view:id(view.view,"view name"),input:serializable(view.input)}});if(new Set(views.map((view)=>view.id)).size!==views.length)fail("Duplicate view ID");const body=source.body===undefined?[]:array(source.body,"body").map(validateBlock);for(const block of body){const targets=block.kind==="record"?[block.view]:block.kind==="records"?[block.view,...block.records.map((record2)=>record2.view)]:[];for(const target of targets)if(target!==undefined&&!views.some((view)=>view.id===target))fail(`Unknown Block View target: ${target}`)}return{title:text(source.title,"title"),description:text(source.description,"description"),views,body}}function validatePublication(value){const source=object(value,"publication");if(source.kind!=="ask"&&source.kind!=="digest")fail("Publication requires an explicit kind");keys(source,["kind","title","description","recipients","views","body","notifyImmediately",...source.kind==="ask"?["questions","tags","recordRefs"]:[]],"publication");if(source.notifyImmediately!==undefined&&typeof source.notifyImmediately!=="boolean")fail("notifyImmediately must be a boolean");const itemPresentation={...presentation(source),...source.notifyImmediately===undefined?{}:{notifyImmediately:source.notifyImmediately}};const linkedAsks=(itemPresentation.body??[]).flatMap((block)=>block.kind==="asks"?block.asks:[]);if(new Set(linkedAsks).size!==linkedAsks.length)fail("Ask belongs to more than one problem");if(source.kind==="digest")return{kind:"digest",...itemPresentation,recipients:distinctPeople(source.recipients,"digest recipients")};if(itemPresentation.body?.some((block)=>block.kind==="asks"))fail("Asks Blocks belong to Digests");const questions=array(source.questions===undefined?[]:source.questions,"questions").map((value2)=>question(value2));if(new Set(questions.map((entry)=>entry.id)).size!==questions.length)fail("Duplicate question ID");const extra=source.recipients===undefined?[]:distinctPeople(source.recipients,"recipients",false);if(!questions.length&&!extra.length)fail("Ask requires at least one recipient");const tags=array(source.tags===undefined?[]:source.tags,"Ask tags").map((value2)=>{const tag=text(value2,"Ask tag");if(new TextEncoder().encode(tag).byteLength>64)fail("Ask tag exceeds 64 UTF-8 bytes");return tag});if(tags.length>32||new Set(tags).size!==tags.length)fail("Ask tags exceed bounds or contain duplicates");const recordRefs=array(source.recordRefs===undefined?[]:source.recordRefs,"Ask Record references").map((value2)=>{const row=object(value2,"Ask Record reference");keys(row,["repository","id"],"Ask Record reference");const{repository,ref}=validateRecordReference({repository:row.repository,ref:row.id});return{repository,id:ref}});if(new Set(recordRefs.map((ref)=>JSON.stringify([ref.repository,ref.id]))).size!==recordRefs.length)fail("Ask Record references contain duplicates");return{kind:"ask",...itemPresentation,questions,tags,recordRefs,recipients:[...new Set([...extra,...questions.flatMap((entry)=>[entry.to,...entry.allowedResponders])])]}}function continueAsk(value){const source=object(value,"continueAsk");keys(source,[],"continueAsk");return{type:"continue"}}function resolution(value){const source=object(value,"resolution");keys(source,["outcome","evidence"],"resolution");return{outcome:text(source.outcome,"outcome"),...source.evidence===undefined?{}:{evidence:array(source.evidence,"evidence").map((entry)=>serializable(entry))}}}function resolveAsk(value){return{type:"resolve",...resolution(value)}}function validateResolution(value){const source=object(value,"published resolution");keys(source,["expectedRevision","outcome","evidence"],"published resolution");if(!Number.isSafeInteger(source.expectedRevision)||source.expectedRevision<1)fail("Expected revision must be a positive integer");return{expectedRevision:source.expectedRevision,...resolution({outcome:source.outcome,...source.evidence===undefined?{}:{evidence:source.evidence}})}}function publicationRequestKey(value){const options=object(value,"publication options");keys(options,["requestKey"],"publication options");return id(options.requestKey,"publication request key")}function createInboxPublisher(transport){return{async publishAsk(value,options){const source=object(value,"ask");keys(source,["title","description","recipients","views","body","questions","notifyImmediately","tags","recordRefs"],"ask");const result=await transport.publish({requestKey:publicationRequestKey(options),item:enforcePublicationSize(validatePublication({...source,kind:"ask"}))});id(result.id,"published ask ID");if(!("revision"in result)||!Number.isSafeInteger(result.revision)||result.revision!==1)fail("Initial ask publication must return revision 1");return{id:result.id,revision:result.revision}},async publishDigest(value,options){const source=object(value,"digest");keys(source,["title","description","recipients","views","body","notifyImmediately"],"digest");const result=await transport.publish({requestKey:publicationRequestKey(options),item:enforcePublicationSize(validatePublication({...source,kind:"digest"}))});return{id:id(result.id,"published digest ID")}},async publishResolution(askId,value){await transport.resolve({askId:id(askId,"ask ID"),resolution:validateResolution(value)})}}}var ROUTINE_DECLARATION_SCHEMA="https://schemas.oddington.ai/routine/v1.json";var ROUTINE_SOURCE_LIMITS={files:20000,bytes:256*1024*1024,declarationBytes:64*1024};var invalid=(field)=>{throw new Error(`Invalid routine declaration: ${field}`)};var object2=(value,fields3,field)=>{if(!value||typeof value!=="object"||Array.isArray(value)||Object.getPrototypeOf(value)!==Object.prototype&&Object.getPrototypeOf(value)!==null||Reflect.ownKeys(value).some((key)=>typeof key!=="string"||!fields3.includes(key)||!Object.getOwnPropertyDescriptor(value,key).enumerable||!Object.hasOwn(Object.getOwnPropertyDescriptor(value,key),"value")))invalid(field);return value};var routineAlias=(value)=>typeof value==="string"&&/^[a-z][a-z0-9-]{0,62}$/.test(value);var list=(value,field,allowed,qualified=false)=>{if(value===undefined)return[];if(!Array.isArray(value)||value.length>64||value.some((item)=>!(routineAlias(item)||qualified&&typeof item==="string"&&item.split("/").length===2&&item.split("/").every(routineAlias))||allowed&&!allowed.includes(item))||new Set(value).size!==value.length)invalid(field);return[...value].sort()};function routineAssetPattern(value){return typeof value==="string"&&value.length<=512&&!value.startsWith("/")&&!value.includes("\\")&&!value.includes(":")&&value.split("/").every((part)=>!!part&&part!=="."&&part!==".."&&/^[a-zA-Z0-9_.*-]+$/.test(part))}function parseRoutineDeclaration(value){const v=object2(value,["$schema","access","runtime","retry","assets"],"fields");if(v.$schema!==ROUTINE_DECLARATION_SCHEMA)invalid("$schema");const access=object2(v.access===undefined?{}:v.access,["repositories","connections","ai","files","publish"],"access");if(Object.hasOwn(access,"ai")&&access.ai!==true)invalid("access.ai");const rawRepositories=access.repositories===undefined?{}:access.repositories;const repositories=object2(rawRepositories,rawRepositories&&typeof rawRepositories==="object"?Object.keys(rawRepositories):[],"access.repositories");if(Object.keys(repositories).length>64)invalid("access.repositories");const grants={};for(const key of Object.keys(repositories).sort()){if(!routineAlias(key)||!["read","write"].includes(repositories[key]))invalid(`access.repositories.${key}`);grants[key]=repositories[key]}if(access.files!==undefined&&!["read","read-write"].includes(access.files))invalid("access.files");const runtime=object2(v.runtime===undefined?{}:v.runtime,["features","resources","maxDuration"],"runtime");if(runtime.features!==undefined&&(!Array.isArray(runtime.features)||runtime.features.length!==0))invalid("runtime.features");if(runtime.resources!==undefined&&runtime.resources!=="standard")invalid("runtime.resources");if(runtime.maxDuration!==undefined&&!["15m","60m"].includes(runtime.maxDuration))invalid("runtime.maxDuration");const retry=object2(v.retry===undefined?{}:v.retry,["maxAttempts"],"retry");if(retry.maxAttempts!==undefined&&retry.maxAttempts!==1)invalid("retry.maxAttempts");const assets=v.assets===undefined?[]:v.assets;if(!Array.isArray(assets)||assets.length>64||assets.some((item)=>!routineAssetPattern(item))||new Set(assets).size!==assets.length)invalid("assets");return{$schema:ROUTINE_DECLARATION_SCHEMA,access:{repositories:grants,connections:list(access.connections,"access.connections",undefined,true),...access.ai===true?{ai:true}:{},...access.files===undefined?{}:{files:access.files},publish:list(access.publish,"access.publish",["asks","digests"])},runtime:{features:[],resources:"standard",maxDuration:runtime.maxDuration??"60m"},retry:{maxAttempts:1},assets:[...assets].sort()}}var invalid2=()=>{throw new AppRoutineContractError("invalid_value")};var invalidContract2=()=>{throw new AppRoutineContractError("invalid_contract")};var routineTitle=(value)=>typeof value==="string"&&value.trim().length>0&&value.length<=256;function freezeRoutineMetadata(value){if(value!==null&&typeof value==="object"){for(const child of Object.values(value))freezeRoutineMetadata(child);Object.freeze(value)}return value}function assertRoutineJson(value,ancestors=new Set){if(value===null||typeof value==="string"||typeof value==="boolean"||typeof value==="number"&&Number.isFinite(value))return;if(!value||typeof value!=="object"||ancestors.has(value))return invalid2();const array2=Array.isArray(value);if(!array2&&Object.getPrototypeOf(value)!==Object.prototype&&Object.getPrototypeOf(value)!==null)return invalid2();const keys2=Reflect.ownKeys(value);if(array2&&(keys2.length!==value.length+1||!Array.from({length:value.length},(_,index)=>Object.hasOwn(value,index)).every(Boolean)))return invalid2();ancestors.add(value);for(const key of keys2){if(array2&&key==="length")continue;if(typeof key!=="string")return invalid2();const descriptor=Object.getOwnPropertyDescriptor(value,key);if(!descriptor.enumerable||!Object.hasOwn(descriptor,"value"))return invalid2();assertRoutineJson(descriptor.value,ancestors)}ancestors.delete(value)}function assertRoutineFields(value,allowed){if(!value||typeof value!=="object"||Object.getPrototypeOf(value)!==Object.prototype||Reflect.ownKeys(value).some((key)=>typeof key!=="string"||allowed&&!allowed.includes(key)||!Object.getOwnPropertyDescriptor(value,key).enumerable||!Object.hasOwn(Object.getOwnPropertyDescriptor(value,key),"value")))return invalidContract2()}function parseRoutineAccess(value){try{if(value!==undefined)assertRoutineJson(value);assertRoutineFields(value??{},["repositories","connections","ai","files","publish"]);const access=value;const names=access?.connections??[];if(!Array.isArray(names)||names.length>64||new Set(names).size!==names.length||names.some((name)=>typeof name!=="string"||name.split("/").length!==2||name.split("/").some((part)=>!isAppRoutineName(part))))return invalidContract2();const parsed=parseRoutineDeclaration({$schema:ROUTINE_DECLARATION_SCHEMA,access:{...access,connections:[]}}).access;return freezeRoutineMetadata({...parsed,connections:[...names]})}catch{return invalidContract2()}}function parseRoutineAIOutputIssue(value){if(!value||typeof value!=="object"||Array.isArray(value))return;const v=value;if(["invalid_json","invalid_response","empty_text","structured_output_limit"].includes(String(v.reason)))return Object.keys(v).join(",")==="reason"?{reason:v.reason}:undefined;if(!["missing_field","unexpected_field","wrong_type","out_of_bounds","invalid_file"].includes(String(v.reason))||typeof v.path!=="string"||v.path.length>256||!/^\$(?:\.[a-z][A-Za-z0-9]*|\[(?:0|[1-9][0-9]*)\])*$/.test(v.path)||!["object","array","boolean","string","integer","number","file"].includes(String(v.expected))||!["missing","null","object","array","boolean","string","number","other"].includes(String(v.received))||Object.keys(v).some((key)=>!["reason","path","expected","received","constraint","limit"].includes(key)))return;if(v.reason==="out_of_bounds"){if(!["maxLength","maxItems","minimum","maximum"].includes(String(v.constraint))||typeof v.limit!=="number"||!Number.isFinite(v.limit))return}else if(Object.hasOwn(v,"constraint")||Object.hasOwn(v,"limit"))return;return{reason:v.reason,path:v.path,expected:v.expected,received:v.received,...v.reason==="out_of_bounds"?{constraint:v.constraint,limit:v.limit}:{}}}function routineAIOutputMessage(issue){if(issue.reason==="structured_output_limit")return"AI couldn’t produce an answer matching the requested format within its submission limit.";if(issue.reason==="invalid_json")return"AI replied, but its answer could not be read as JSON.";if(issue.reason==="invalid_response")return"AI returned a response OS could not read.";if(issue.reason==="empty_text")return"AI returned an empty answer.";const field=issue.path==="$"?"response":issue.path.slice(issue.path.startsWith("$.")?2:1);const expected={object:"an object",array:"a list",boolean:"true or false",string:"text",integer:"a whole number",number:"a number",file:"a File"}[issue.expected];const received={missing:"a missing field",null:"null",object:"an object",array:"a list",boolean:"true or false",string:"text",number:"a number",other:"an unsupported value"}[issue.received];if(issue.reason==="missing_field")return`AI response is missing a required field.
|
|
21
|
+
`:""}${fileErrorExplanation(detail)}`}switch(error.code){case"invalid_input":return"The file request is invalid.";case"unsupported_context":return"This environment does not support this file operation.";case"unauthenticated":return"Sign in to OS before accessing files.";case"access_denied":return"You don’t have access to this file operation.";case"not_found":return"This file isn’t available in this workspace.";case"request_too_large":return"The file request exceeds the size limit.";case"conflict":return"The saved file or enrichment doesn’t match this request. Reload it before trying again.";case"local_only":return"This file is stored on a computer and isn’t available through remote storage.";case"integrity":return FILE_INTEGRITY_MESSAGE;case"capacity":return FILE_CAPACITY_MESSAGE;case"method_not_allowed":return"This request uses an unsupported file operation.";case"unavailable":return`OS couldn’t complete the file operation.${error.retryable?" Try again.":""}`}}class FileOperationError extends Error{code;status;retryable;detail;constructor(code,status,retryable=false,detail){const safe=fileErrorDetailForCode(code,detail);super(fileErrorMessage({code,retryable,detail:safe}));this.code=code;this.status=status;this.retryable=retryable;if(safe)this.detail=Object.freeze(safe);if(safe&&Object.hasOwn(localStorageReasons,safe.reason))this.retryable=false}}var FILE_ID_PATTERN=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;var FILE_ORIGINAL_MAX_BYTES=5*1024**3;function parseFileDescriptor(value){const invalid=()=>{throw new FileOperationError("unavailable",503,true)};if(!value||typeof value!=="object"||Array.isArray(value))return invalid();const f=value;if(Object.keys(f).sort().join(",")!=="enrichments,id,mediaType,name,path,sha256,size"||typeof f.id!=="string"||!FILE_ID_PATTERN.test(f.id)||!safeFileName(f.name)||!safeFilePath(f.path)||!Number.isSafeInteger(f.size)||f.size<0||f.size>FILE_ORIGINAL_MAX_BYTES||typeof f.sha256!=="string"||!/^[0-9a-f]{64}$/.test(f.sha256)||!f.enrichments||typeof f.enrichments!=="object"||Array.isArray(f.enrichments)||!isCanonicalOriginalMediaType(f.mediaType))return invalid();for(const[name,descriptor]of Object.entries(f.enrichments)){if(!safeEnrichmentName(name))return invalid();parseEnrichmentDescriptor(descriptor)}if(new TextEncoder().encode(JSON.stringify(f)).byteLength>16*1024)return invalid();return f}function parseEnrichmentDescriptor(value){const invalid=()=>{throw new FileOperationError("unavailable",503,true)};if(!value||typeof value!=="object"||Array.isArray(value))return invalid();const d=value;if(Object.keys(d).sort().join(",")!=="mediaType,sha256,size"||!["application/octet-stream","text/plain","text/markdown","application/json"].includes(d.mediaType)||!Number.isSafeInteger(d.size)||d.size<0||d.size>16*1024*1024||typeof d.sha256!=="string"||!/^[0-9a-f]{64}$/.test(d.sha256))return invalid();return d}function safeEnrichmentName(value){return safeFileName(value)&&!/^original(?:\.|$)/i.test(value)}function parseFileEnrichMetadata(value,maxBytes){const invalid=(reason="invalid_metadata")=>{throw new FileOperationError("invalid_input",400,false,{reason})};if(!value||typeof value!=="object"||Array.isArray(value))return invalid();const d=value;if(Object.keys(d).some((key)=>!["name","size","mediaType","replace"].includes(key)))return invalid();if(!safeEnrichmentName(d.name))return invalid("invalid_enrichment_name");if(!Number.isSafeInteger(d.size)||d.size<0)return invalid("invalid_size");if(d.mediaType!==undefined&&(typeof d.mediaType!=="string"||d.mediaType.length>255||/[\u0000-\u001f\u007f]/.test(d.mediaType)))return invalid("invalid_media_type");if(d.replace!==undefined&&(typeof d.replace!=="string"||!/^[0-9a-f]{64}$/.test(d.replace)))return invalid("invalid_replacement");if(d.size>maxBytes)throw new FileOperationError("request_too_large",413,false,{reason:"size_limit",limitBytes:maxBytes,receivedBytes:d.size});return d}function safeFileName(value){return typeof value==="string"&&value.length>0&&value.length<=255&&value===value.trim()&&value!=="."&&value!==".."&&!/[\u0000-\u001f\u007f-\u009f/\\:*?"<>|]/u.test(value)&&!/[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/.test(value)&&!/[. ]$/.test(value)&&!/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(value)}function safeFilePath(value){return typeof value==="string"&&value.length<=1024&&value.split("/").every(safeFileName)}function safeManagedFilePath(value){return safeFilePath(value)&&value.split("/")[0].toLowerCase()!==".os"}function declaredOriginalMediaType(value){if(typeof value!=="string"||value.length>255||/[\u0000-\u001f\u007f-\u009f]/.test(value))throw new FileOperationError("invalid_input",400,false,{reason:"invalid_media_type"});const normalized=value.split(";",1)[0].trim().toLowerCase();const token="[a-z0-9!#$%&'+.^_`|~-]+";if(!new RegExp(`^${token}/${token}$`).test(normalized))throw new FileOperationError("invalid_input",400,false,{reason:"invalid_media_type"});return normalized}function isCanonicalOriginalMediaType(value){try{return declaredOriginalMediaType(value)===value}catch{return false}}function parseFileCreateMetadata(value,maxBytes){const invalid=(reason="invalid_metadata")=>{throw new FileOperationError("invalid_input",400,false,{reason})};if(!value||typeof value!=="object"||Array.isArray(value))return invalid();const input=value;if(Object.keys(input).some((key)=>!["name","path","storage","mediaType","size","requestKey"].includes(key)))return invalid();const path=input.path===undefined?"Files":input.path;if(!safeFileName(input.name))return invalid("invalid_name");if(!safeManagedFilePath(path))return invalid("invalid_path");if(input.storage!==undefined&&input.storage!=="remote"&&input.storage!=="local")return invalid("invalid_storage");const mediaType=input.mediaType===undefined?"application/octet-stream":declaredOriginalMediaType(input.mediaType);if(!Number.isSafeInteger(input.size)||input.size<0)return invalid("invalid_size");if(input.size>maxBytes)throw new FileOperationError("request_too_large",413,false,{reason:"size_limit",limitBytes:maxBytes,receivedBytes:input.size});if(typeof input.requestKey!=="string"||input.requestKey.length<1||input.requestKey.length>256||input.requestKey!==input.requestKey.trim()||/[\u0000-\u001f\u007f]/.test(input.requestKey))return invalid("invalid_request_key");return{name:input.name,path,...input.storage?{storage:input.storage}:{},mediaType,size:input.size,requestKey:input.requestKey}}class AppRoutineContractError extends Error{code;constructor(code){super(code);this.code=code}}var propertyName=/^[a-z][A-Za-z0-9]*(?![\s\S])/;var stepId=/^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/;var routineName=/^[a-z0-9][a-z0-9-]{0,62}(?![\s\S])/;function isAppRoutineName(value){return typeof value==="string"&&routineName.test(value)}var owns=(value,key)=>Object.hasOwn(value,key);var invalidContract=()=>{throw new AppRoutineContractError("invalid_contract")};var invalidValue=()=>{throw new AppRoutineContractError("invalid_value")};function record(value){return value!==null&&typeof value==="object"&&!Array.isArray(value)&&(Object.getPrototypeOf(value)===Object.prototype||Object.getPrototypeOf(value)===null)}function fields(value,required,optional=[]){return required.every((key)=>owns(value,key))&&Object.keys(value).every((key)=>required.includes(key)||optional.includes(key))}function denseArray(value){return Array.isArray(value)&&Object.keys(value).length===value.length&&Array.from({length:value.length},(_,index)=>owns(value,String(index))).every(Boolean)}function parseAppRoutineContract(value){let properties=0;function schema(value2,depth=1){if(depth>8||!record(value2))return invalidContract();switch(value2.type){case"object":{if(!fields(value2,["type","properties","additionalProperties"],["required"])||value2.additionalProperties!==false||!record(value2.properties))return invalidContract();const entries=Object.entries(value2.properties);properties+=entries.length;if(properties>64||entries.some(([key])=>!propertyName.test(key)))return invalidContract();let required;if(owns(value2,"required")){if(!denseArray(value2.required)||value2.required.some((key)=>typeof key!=="string"||!owns(value2.properties,key))||new Set(value2.required).size!==value2.required.length)return invalidContract();required=[...value2.required]}return{type:"object",properties:Object.fromEntries(entries.map(([key,child])=>[key,schema(child,depth+1)])),...required===undefined?{}:{required},additionalProperties:false}}case"array":if(!fields(value2,["type","items"],["maxItems"])||owns(value2,"maxItems")&&(!Number.isSafeInteger(value2.maxItems)||value2.maxItems<1))return invalidContract();return{type:"array",items:schema(value2.items,depth+1),...owns(value2,"maxItems")?{maxItems:value2.maxItems}:{}};case"boolean":if(!fields(value2,["type"]))return invalidContract();return{type:value2.type};case"file":if(!fields(value2,["type"],["storage","path"])||owns(value2,"storage")&&value2.storage!=="local"&&value2.storage!=="remote"||owns(value2,"path")&&!safeManagedFilePath(value2.path))return invalidContract();return{type:"file",...owns(value2,"storage")?{storage:value2.storage}:{},...owns(value2,"path")?{path:value2.path}:{}};case"string":if(!fields(value2,["type"],["maxLength"])||owns(value2,"maxLength")&&(!Number.isSafeInteger(value2.maxLength)||value2.maxLength<0||value2.maxLength>4096))return invalidContract();return{type:"string",...owns(value2,"maxLength")?{maxLength:value2.maxLength}:{}};case"integer":case"number":{const validNumber=value2.type==="integer"?Number.isSafeInteger:Number.isFinite;if(!fields(value2,["type"],["minimum","maximum"])||owns(value2,"minimum")&&!validNumber(value2.minimum)||owns(value2,"maximum")&&!validNumber(value2.maximum)||owns(value2,"minimum")&&owns(value2,"maximum")&&value2.minimum>value2.maximum)return invalidContract();return{type:value2.type,...owns(value2,"minimum")?{minimum:value2.minimum}:{},...owns(value2,"maximum")?{maximum:value2.maximum}:{}}}default:return invalidContract()}}if(!record(value)||!fields(value,["routine","input","steps"],["result"])||!isAppRoutineName(value.routine)||!denseArray(value.steps)||value.steps.length<1||value.steps.length>64)return invalidContract();const input=schema(value.input);const result=owns(value,"result")?schema(value.result):undefined;const ids=new Set;const steps=value.steps.map((step)=>{if(!record(step)||!fields(step,["id"],["summary"])||typeof step.id!=="string"||!stepId.test(step.id)||ids.has(step.id))return invalidContract();ids.add(step.id);return{id:step.id,...owns(step,"summary")?{summary:schema(step.summary)}:{}}});return{routine:value.routine,input,steps,...result===undefined?{}:{result}}}function jsonData(value,ancestors=new Set){if(value===null||typeof value==="string"||typeof value==="boolean"||typeof value==="number"&&Number.isFinite(value))return;if(!record(value)&&!denseArray(value))return invalidValue();if(ancestors.has(value))return invalidValue();ancestors.add(value);for(const child of Object.values(value))jsonData(child,ancestors);ancestors.delete(value)}function validateRoutineSchemaValue(schema,value,rejected){const type=(value2)=>value2===null?"null":Array.isArray(value2)?"array":["object","boolean","string","number"].includes(typeof value2)?typeof value2:"other";function check(schema2,value2,path){const fail=(reason,extra={})=>{rejected?.({reason,path:path.length<=256?path:"$",expected:schema2.type,received:type(value2),...extra});return invalidValue()};switch(schema2.type){case"object":if(!record(value2))return fail("wrong_type");for(const key of schema2.required??[])if(!owns(value2,key))return fail("missing_field",{path:`${path}.${key}`.length<=256?`${path}.${key}`:"$",expected:schema2.properties[key].type,received:"missing"});if(Object.keys(value2).some((key)=>!owns(schema2.properties,key)))return fail("unexpected_field");for(const[key,child]of Object.entries(value2))check(schema2.properties[key],child,`${path}.${key}`);return;case"array":if(!denseArray(value2))return fail("wrong_type");if(schema2.maxItems!==undefined&&value2.length>schema2.maxItems)return fail("out_of_bounds",{constraint:"maxItems",limit:schema2.maxItems});value2.forEach((child,index)=>check(schema2.items,child,`${path}[${index}]`));return;case"boolean":if(typeof value2!=="boolean")return fail("wrong_type");return;case"string":if(typeof value2!=="string")return fail("wrong_type");if(Array.from(value2).length>(schema2.maxLength??4096))return fail("out_of_bounds",{constraint:"maxLength",limit:schema2.maxLength??4096});return;case"integer":case"number":if(typeof value2!=="number"||!(schema2.type==="integer"?Number.isSafeInteger(value2):Number.isFinite(value2)))return fail("wrong_type");if(schema2.minimum!==undefined&&value2<schema2.minimum)return fail("out_of_bounds",{constraint:"minimum",limit:schema2.minimum});if(schema2.maximum!==undefined&&value2>schema2.maximum)return fail("out_of_bounds",{constraint:"maximum",limit:schema2.maximum});return;case"file":{let file;try{jsonData(value2);file=parseFileDescriptor(value2)}catch{return fail("invalid_file")}if(schema2.path!==undefined&&file.path!==schema2.path)return fail("invalid_file")}}}check(schema,value,"$")}class InboxContractError extends Error{constructor(message){super(message);this.name="InboxContractError"}}var INBOX_PUBLICATION_ITEM_BYTES=1024*1024;var INBOX_PUBLICATION_REQUEST_BYTES=INBOX_PUBLICATION_ITEM_BYTES+4096;var publicationAdvice="Trim the content, or attach long reports, data, and supporting materials as files instead. Then try again.";var INBOX_PUBLICATION_TOO_LARGE=`Your Inbox item failed to publish. Its content exceeds the 1 MB limit. ${publicationAdvice}`;class InboxPublicationSizeError extends InboxContractError{kind;bytes;constructor(kind,bytes){const label=kind==="ask"?"Ask":"Digest";const size=Math.ceil(bytes/INBOX_PUBLICATION_ITEM_BYTES*100)/100;super(`Your ${label} failed to publish. Its content is ${size} MB, which exceeds the 1 MB limit. ${publicationAdvice}`);this.kind=kind;this.bytes=bytes;this.name="InboxPublicationSizeError"}}function enforcePublicationSize(value){const bytes=new TextEncoder().encode(JSON.stringify(value)).byteLength;if(bytes>INBOX_PUBLICATION_ITEM_BYTES)throw new InboxPublicationSizeError(value.kind,bytes);return value}function fail(message){throw new InboxContractError(message)}function object(value,label){if(!value||typeof value!=="object"||Array.isArray(value)||![Object.prototype,null].includes(Object.getPrototypeOf(value)))fail(`${label} must be a plain object`);return value}function keys(value,allowed,label){for(const key of Reflect.ownKeys(value)){if(typeof key!=="string"||!allowed.includes(key))fail(`${label} does not support ${String(key)}`);const descriptor=Object.getOwnPropertyDescriptor(value,key);if(!descriptor.enumerable||!("value"in descriptor))fail(`${label} must contain only JSON data`)}}function text(value,label){if(typeof value!=="string"||!value.trim())fail(`${label} must be nonempty text`);return value}function id(value,label){const result=text(value,label);if(result!==result.trim())fail(`${label} cannot have surrounding whitespace`);return result}function array(value,label){if(!Array.isArray(value)||Object.getPrototypeOf(value)!==Array.prototype||Reflect.ownKeys(value).length!==value.length+1)fail(`${label} must be a dense array`);for(let index=0;index<value.length;index+=1){const descriptor=Object.getOwnPropertyDescriptor(value,String(index));if(!descriptor?.enumerable||!("value"in descriptor))fail(`${label} must contain only JSON data`)}return value}function distinctIds(value,label,nonempty=true){const result=array(value,label).map((entry)=>id(entry,label));if(nonempty&&!result.length)fail(`${label} must not be empty`);if(new Set(result).size!==result.length)fail(`${label} contains duplicate IDs`);return result}var memberEmail=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;function personReference(value,label){const result=id(value,label);return memberEmail.test(result)?result.toLowerCase():result}function distinctPeople(value,label,nonempty=true){const result=array(value,label).map((entry)=>personReference(entry,label));if(nonempty&&!result.length)fail(`${label} must not be empty`);if(new Set(result).size!==result.length)fail(`${label} contains duplicate IDs`);return result}function serializable(value,ancestors=new Set){if(value===null||typeof value==="boolean"||typeof value==="string")return value;if(typeof value==="number"&&Number.isFinite(value))return value;if(!value||typeof value!=="object")fail("Input must be losslessly serializable JSON");if(ancestors.has(value))fail("Input cannot contain cycles");ancestors.add(value);try{if(Array.isArray(value)){array(value,"JSON array");return value.map((entry)=>serializable(entry,ancestors))}const source=object(value,"JSON input");keys(source,Object.keys(source),"JSON input");return Object.fromEntries(Object.entries(source).map(([key,entry])=>[key,serializable(entry,ancestors)]))}finally{ancestors.delete(value)}}function natural(value,label,minimum=0){if(!Number.isSafeInteger(value)||value<minimum)fail(`${label} must be an integer >= ${minimum}`);return value}function validateInboxFile(value){const v=object(serializable(value),"Inbox file");keys(v,["id","name","mediaType","size","sha256"],"Inbox file");const fileId=id(v.id,"Inbox file ID"),name=id(v.name,"filename"),mediaType=id(v.mediaType,"media type");if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(fileId)||/[\x00-\x1f\x7f/\\]/.test(name)||!isCanonicalOriginalMediaType(mediaType)||typeof v.sha256!=="string"||!/^[0-9a-f]{64}$/.test(v.sha256))fail("Invalid Inbox file identity or metadata");const size=natural(v.size,"file size");if(size>FILE_ORIGINAL_MAX_BYTES)fail("File exceeds supported size");return{id:fileId,name,mediaType,size,sha256:v.sha256}}function fields2(value){const result=array(value,"selected fields").map((entry)=>{const field=object(entry,"field");keys(field,["label","value"],"field");return{label:text(field.label,"field label"),value:text(field.value,"field value")}});if(new Set(result.map((field)=>field.label)).size!==result.length)fail("Duplicate field label");return result}function validateBlock(value){const b=object(serializable(value),"Block");if(b.kind==="rich-text"){keys(b,["kind","markdown"],"Rich text Block");return{kind:"rich-text",markdown:text(b.markdown,"Markdown")}}if(b.kind==="asks"){keys(b,["kind","problem","asks"],"Asks Block");const asks=distinctIds(b.asks,"Ask IDs");if(asks.some((ask)=>!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(ask)))fail("Invalid Ask ID");return{kind:"asks",problem:text(b.problem,"problem"),asks}}if(!["record","records","files"].includes(b.kind))fail("Unknown Block kind");keys(b,["kind","label","initiallyExpanded",...b.kind==="record"?["record","view"]:b.kind==="records"?["records","view"]:["files"]],"Block");const label=text(b.label,"Block label");if(b.initiallyExpanded!==undefined&&typeof b.initiallyExpanded!=="boolean")fail("Invalid initiallyExpanded");const expanded=b.initiallyExpanded===undefined?{}:{initiallyExpanded:b.initiallyExpanded};const target=b.view===undefined?{}:{view:id(b.view,"View target")};if(b.kind==="record"){const r=object(b.record,"presented record");keys(r,["ref","title","fields"],"presented record");return{kind:"record",label,...target,...expanded,record:{ref:id(r.ref,"record reference"),title:text(r.title,"record title"),fields:fields2(r.fields)}}}if(b.kind==="records"){const records=array(b.records,"records").map((entry)=>{const r=object(entry,"record summary");keys(r,["ref","title","description","facts","view"],"record summary");return{ref:id(r.ref,"record reference"),title:text(r.title,"record title"),...r.description===undefined?{}:{description:text(r.description,"record description")},...r.facts===undefined?{}:{facts:fields2(r.facts)},...r.view===undefined?{}:{view:id(r.view,"row View target")}}});if(!records.length||new Set(records.map((r)=>r.ref)).size!==records.length)fail("Empty or duplicate records");return{kind:"records",label,records,...target,...expanded}}const files=array(b.files,"files").map(validateInboxFile);if(!files.length||new Set(files.map((file)=>file.id)).size!==files.length)fail("Empty or duplicate files");return{kind:"files",label,files,...expanded}}function richTextBlock(value){return validateBlock({...value,kind:"rich-text"})}function recordBlock(value){return validateBlock({...value,kind:"record"})}function recordsBlock(value){return validateBlock({...value,kind:"records"})}function fileBlock(value){const input=object(serializable(value),"Files Block");const files=array(input.files,"files").map((entry)=>{const descriptor=object(entry,"File");if(!(("path"in descriptor)||("enrichments"in descriptor)))return validateInboxFile(descriptor);let file;try{file=parseFileDescriptor(descriptor)}catch{return fail("Invalid shared File descriptor")}const{id:id2,name,mediaType,size,sha256}=file;return{id:id2,name,mediaType,size,sha256}});return validateBlock({...input,kind:"files",files})}function asksBlock(value){return validateBlock({...value,kind:"asks"})}function selection(value){const input=object(value,"selection");keys(input,["source"],"selection");return validateResponseDefinition({type:"selection",source:input.source})}function validateAuthoredSource(value){const source=object(value,"response definition");keys(source,["type","options","suggestions","search"],"response definition");if(source.type!=="authored")fail("Expected authored options");const options=array(source.options,"options").map((entry)=>{const option=object(entry,"choice");keys(option,["value","label","description","note"],"choice");let note;if(option.note!==undefined){const declaration=object(option.note,"choice note");keys(declaration,["placeholder"],"choice note");note={placeholder:text(declaration.placeholder,"note placeholder")}}return{value:id(option.value,"choice value"),label:text(option.label,"choice label"),...option.description===undefined?{}:{description:text(option.description,"choice description")},...note?{note}:{}}});if(!options.length)fail("Choices require at least one option");if(new Set(options.map((option)=>option.value)).size!==options.length)fail("Duplicate choice value");if(Object.hasOwn(source,"search")||Object.hasOwn(source,"suggestions")){const labels=object(source.search,"choice search");keys(labels,["triggerLabel","placeholder","emptyLabel"],"choice search");const search={triggerLabel:text(labels.triggerLabel,"search trigger label"),placeholder:text(labels.placeholder,"search placeholder"),emptyLabel:text(labels.emptyLabel,"search empty label")};const suggestions=array(source.suggestions,"suggestions").map((value2)=>id(value2,"suggestion value"));if(suggestions.length>8||new Set(suggestions).size!==suggestions.length||suggestions.some((value2)=>!options.some((option)=>option.value===value2)))fail("Search permits at most eight unique published suggestions");return{type:"authored",options,suggestions,search}}if(options.length>9)fail("Choices require one to nine options");return{type:"authored",options}}function validateRecordReference(value){const row=object(value,"Record reference");keys(row,["repository","ref"],"Record reference");const repository=id(row.repository,"repository"),ref=id(row.ref,"Record reference");if(!/^[a-z0-9][a-z0-9._/-]{0,127}$/.test(repository)||/\.\.|\/\//.test(repository)||ref.length>512||!/^[_a-zA-Z0-9][a-zA-Z0-9_-]*(\/[_a-zA-Z0-9][a-zA-Z0-9_-]*)+$/.test(ref))fail("Invalid Record identity");return{repository,ref}}function validateRecordSource(value){const source=object(value,"Record selection");keys(source,["type","collection","refPrefix","where","display","suggestions"],"Record selection");if(source.type!=="records")fail("Expected Record options");const collection=object(source.collection,"collection");keys(collection,["repository","name"],"collection");const repository=validateRecordReference({repository:collection.repository,ref:"records/example"}).repository;const name=id(collection.name,"collection name");if(!/^[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_-]+)*$/.test(name))fail("Invalid collection name");const refPrefix=source.refPrefix===undefined?undefined:id(source.refPrefix,"Record reference prefix");if(refPrefix!==undefined&&(!refPrefix.endsWith("/")||refPrefix.length>512||!/^[_a-zA-Z0-9][a-zA-Z0-9_-]*(\/[_a-zA-Z0-9][a-zA-Z0-9_-]*)*\/$/.test(refPrefix)))fail("Invalid Record reference prefix");const where=object(source.where??{},"Record filter");const fieldName=(name2)=>/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name2)&&!["constructor","prototype"].includes(name2);for(const[name2,value2]of Object.entries(where)){if(!fieldName(name2)||!(value2===null||["string","number","boolean"].includes(typeof value2))||typeof value2==="number"&&!Number.isFinite(value2))fail("Record filters require scalar equality")}const display=object(source.display,"Record display");keys(display,["labelFields"],"Record display");const labelFields=distinctIds(display.labelFields,"label fields");if(labelFields.length>2||labelFields.some((name2)=>!fieldName(name2)))fail("Select one or two scalar label fields");const suggestions=array(source.suggestions??[],"suggestions").map((value2)=>{const entry=object(value2,"suggestion");keys(entry,["record","reason"],"suggestion");const record2=validateRecordReference(entry.record);if(record2.repository!==repository)fail("Suggestion belongs to another repository");return{record:record2,...entry.reason===undefined?{}:{reason:text(entry.reason,"suggestion reason")}}});if(suggestions.length>8||new Set(suggestions.map((entry)=>entry.record.ref)).size!==suggestions.length)fail("Record selection permits at most eight unique suggestions");return{type:"records",collection:{repository,name},...refPrefix?{refPrefix}:{},where:{...where},display:{labelFields},suggestions}}function validateResponseDefinition(value){const definition=object(value,"response definition");keys(definition,["type","source"],"response definition");if(definition.type!=="selection")fail("Expected a selection definition");const source=object(definition.source,"option source");switch(source.type){case"authored":return{type:"selection",source:validateAuthoredSource(source)};case"records":return{type:"selection",source:validateRecordSource(source)};default:return fail("Unsupported option source")}}function handlerReference(value){const source=object(value,"handler reference");keys(source,["id","input"],"handler reference");return{id:id(source.id,"handler ID"),input:serializable(source.input)}}function defineHandler(value){const source=object(value,"handler");keys(source,["id","results","run"],"handler");const stable=(value2)=>typeof value2==="string"&&/^[a-zA-Z0-9][a-zA-Z0-9_./-]{0,127}$/.test(value2);if(!stable(source.id))fail("Handler ID must be stable");const results=source.results===undefined?undefined:distinctIds(source.results,"handler results",false);if(results&&(results.length>64||results.some((result)=>!stable(result))))fail("Handler results must be stable IDs");if(typeof source.run!=="function")fail("Handler requires a run function");return Object.freeze({id:value.id,...results===undefined?{}:{results:Object.freeze(results.sort())},run:value.run})}function respond(handler,input){defineHandler(handler);return handlerReference({id:handler.id,input})}function question(value){const source=object(value,"question");keys(source,["id","to","allowedResponders","prompt","instructions","response","handler"],"question");const to=personReference(source.to,"question assignee");const allowedResponders=source.allowedResponders===undefined?[to]:distinctPeople(source.allowedResponders,"allowed responders");if(!allowedResponders.includes(to))fail("Allowed responders must include the assignee");return{id:id(source.id,"question ID"),to,allowedResponders,prompt:text(source.prompt,"question prompt"),...source.instructions===undefined?{}:{instructions:text(source.instructions,"instructions")},response:validateResponseDefinition(source.response),...Object.hasOwn(source,"handler")?{handler:handlerReference(source.handler)}:{}}}function presentation(source){const views=source.views===undefined?[]:array(source.views,"views").map((entry)=>{const view=object(entry,"view");keys(view,["id","view","input"],"view");return{id:id(view.id,"view ID"),view:id(view.view,"view name"),input:serializable(view.input)}});if(new Set(views.map((view)=>view.id)).size!==views.length)fail("Duplicate view ID");const body=source.body===undefined?[]:array(source.body,"body").map(validateBlock);for(const block of body){const targets=block.kind==="record"?[block.view]:block.kind==="records"?[block.view,...block.records.map((record2)=>record2.view)]:[];for(const target of targets)if(target!==undefined&&!views.some((view)=>view.id===target))fail(`Unknown Block View target: ${target}`)}return{title:text(source.title,"title"),description:text(source.description,"description"),views,body}}function validatePublication(value){const source=object(value,"publication");if(source.kind!=="ask"&&source.kind!=="digest")fail("Publication requires an explicit kind");keys(source,["kind","title","description","recipients","views","body","notifyImmediately",...source.kind==="ask"?["questions","tags","recordRefs"]:[]],"publication");if(source.notifyImmediately!==undefined&&typeof source.notifyImmediately!=="boolean")fail("notifyImmediately must be a boolean");const itemPresentation={...presentation(source),...source.notifyImmediately===undefined?{}:{notifyImmediately:source.notifyImmediately}};const linkedAsks=(itemPresentation.body??[]).flatMap((block)=>block.kind==="asks"?block.asks:[]);if(new Set(linkedAsks).size!==linkedAsks.length)fail("Ask belongs to more than one problem");if(source.kind==="digest")return{kind:"digest",...itemPresentation,recipients:distinctPeople(source.recipients,"digest recipients")};if(itemPresentation.body?.some((block)=>block.kind==="asks"))fail("Asks Blocks belong to Digests");const questions=array(source.questions===undefined?[]:source.questions,"questions").map((value2)=>question(value2));if(new Set(questions.map((entry)=>entry.id)).size!==questions.length)fail("Duplicate question ID");const extra=source.recipients===undefined?[]:distinctPeople(source.recipients,"recipients",false);if(!questions.length&&!extra.length)fail("Ask requires at least one recipient");const tags=array(source.tags===undefined?[]:source.tags,"Ask tags").map((value2)=>{const tag=text(value2,"Ask tag");if(new TextEncoder().encode(tag).byteLength>64)fail("Ask tag exceeds 64 UTF-8 bytes");return tag});if(tags.length>32||new Set(tags).size!==tags.length)fail("Ask tags exceed bounds or contain duplicates");const recordRefs=array(source.recordRefs===undefined?[]:source.recordRefs,"Ask Record references").map((value2)=>{const row=object(value2,"Ask Record reference");keys(row,["repository","id"],"Ask Record reference");const{repository,ref}=validateRecordReference({repository:row.repository,ref:row.id});return{repository,id:ref}});if(new Set(recordRefs.map((ref)=>JSON.stringify([ref.repository,ref.id]))).size!==recordRefs.length)fail("Ask Record references contain duplicates");return{kind:"ask",...itemPresentation,questions,tags,recordRefs,recipients:[...new Set([...extra,...questions.flatMap((entry)=>[entry.to,...entry.allowedResponders])])]}}function continueAsk(value){const source=object(value,"continueAsk");keys(source,[],"continueAsk");return{type:"continue"}}function resolution(value){const source=object(value,"resolution");keys(source,["outcome","evidence"],"resolution");return{outcome:text(source.outcome,"outcome"),...source.evidence===undefined?{}:{evidence:array(source.evidence,"evidence").map((entry)=>serializable(entry))}}}function resolveAsk(value){return{type:"resolve",...resolution(value)}}function validateResolution(value){const source=object(value,"published resolution");keys(source,["expectedRevision","outcome","evidence"],"published resolution");if(!Number.isSafeInteger(source.expectedRevision)||source.expectedRevision<1)fail("Expected revision must be a positive integer");return{expectedRevision:source.expectedRevision,...resolution({outcome:source.outcome,...source.evidence===undefined?{}:{evidence:source.evidence}})}}function publicationRequestKey(value){const options=object(value,"publication options");keys(options,["requestKey"],"publication options");return id(options.requestKey,"publication request key")}function createInboxPublisher(transport){return{async publishAsk(value,options){const source=object(value,"ask");keys(source,["title","description","recipients","views","body","questions","notifyImmediately","tags","recordRefs"],"ask");const result=await transport.publish({requestKey:publicationRequestKey(options),item:enforcePublicationSize(validatePublication({...source,kind:"ask"}))});id(result.id,"published ask ID");if(!("revision"in result)||!Number.isSafeInteger(result.revision)||result.revision!==1)fail("Initial ask publication must return revision 1");return{id:result.id,revision:result.revision}},async publishDigest(value,options){const source=object(value,"digest");keys(source,["title","description","recipients","views","body","notifyImmediately"],"digest");const result=await transport.publish({requestKey:publicationRequestKey(options),item:enforcePublicationSize(validatePublication({...source,kind:"digest"}))});return{id:id(result.id,"published digest ID")}},async publishResolution(askId,value){await transport.resolve({askId:id(askId,"ask ID"),resolution:validateResolution(value)})}}}var ROUTINE_DECLARATION_SCHEMA="https://schemas.oddington.ai/routine/v1.json";var ROUTINE_SOURCE_LIMITS={files:20000,bytes:256*1024*1024,declarationBytes:64*1024};var invalid=(field)=>{throw new Error(`Invalid routine declaration: ${field}`)};var object2=(value,fields3,field)=>{if(!value||typeof value!=="object"||Array.isArray(value)||Object.getPrototypeOf(value)!==Object.prototype&&Object.getPrototypeOf(value)!==null||Reflect.ownKeys(value).some((key)=>typeof key!=="string"||!fields3.includes(key)||!Object.getOwnPropertyDescriptor(value,key).enumerable||!Object.hasOwn(Object.getOwnPropertyDescriptor(value,key),"value")))invalid(field);return value};var routineAlias=(value)=>typeof value==="string"&&/^[a-z][a-z0-9-]{0,62}$/.test(value);var list=(value,field,allowed,qualified=false)=>{if(value===undefined)return[];if(!Array.isArray(value)||value.length>64||value.some((item)=>!(routineAlias(item)||qualified&&typeof item==="string"&&item.split("/").length===2&&item.split("/").every(routineAlias))||allowed&&!allowed.includes(item))||new Set(value).size!==value.length)invalid(field);return[...value].sort()};function routineAssetPattern(value){return typeof value==="string"&&value.length<=512&&!value.startsWith("/")&&!value.includes("\\")&&!value.includes(":")&&value.split("/").every((part)=>!!part&&part!=="."&&part!==".."&&/^[a-zA-Z0-9_.*-]+$/.test(part))}function parseRoutineDeclaration(value){const v=object2(value,["$schema","access","runtime","retry","assets"],"fields");if(v.$schema!==ROUTINE_DECLARATION_SCHEMA)invalid("$schema");const access=object2(v.access===undefined?{}:v.access,["repositories","connections","ai","files","publish"],"access");if(Object.hasOwn(access,"ai")&&access.ai!==true)invalid("access.ai");const rawRepositories=access.repositories===undefined?{}:access.repositories;const repositories=object2(rawRepositories,rawRepositories&&typeof rawRepositories==="object"?Object.keys(rawRepositories):[],"access.repositories");if(Object.keys(repositories).length>64)invalid("access.repositories");const grants={};for(const key of Object.keys(repositories).sort()){if(!routineAlias(key)||!["read","write"].includes(repositories[key]))invalid(`access.repositories.${key}`);grants[key]=repositories[key]}if(access.files!==undefined&&!["read","read-write"].includes(access.files))invalid("access.files");const runtime=object2(v.runtime===undefined?{}:v.runtime,["features","resources","maxDuration"],"runtime");if(runtime.features!==undefined&&(!Array.isArray(runtime.features)||runtime.features.length!==0))invalid("runtime.features");if(runtime.resources!==undefined&&runtime.resources!=="standard")invalid("runtime.resources");if(runtime.maxDuration!==undefined&&!["15m","60m"].includes(runtime.maxDuration))invalid("runtime.maxDuration");const retry=object2(v.retry===undefined?{}:v.retry,["maxAttempts"],"retry");if(retry.maxAttempts!==undefined&&retry.maxAttempts!==1)invalid("retry.maxAttempts");const assets=v.assets===undefined?[]:v.assets;if(!Array.isArray(assets)||assets.length>64||assets.some((item)=>!routineAssetPattern(item))||new Set(assets).size!==assets.length)invalid("assets");return{$schema:ROUTINE_DECLARATION_SCHEMA,access:{repositories:grants,connections:list(access.connections,"access.connections",undefined,true),...access.ai===true?{ai:true}:{},...access.files===undefined?{}:{files:access.files},publish:list(access.publish,"access.publish",["asks","digests"])},runtime:{features:[],resources:"standard",maxDuration:runtime.maxDuration??"60m"},retry:{maxAttempts:1},assets:[...assets].sort()}}var invalid2=()=>{throw new AppRoutineContractError("invalid_value")};var invalidContract2=()=>{throw new AppRoutineContractError("invalid_contract")};var routineTitle=(value)=>typeof value==="string"&&value.trim().length>0&&value.length<=256;function freezeRoutineMetadata(value){if(value!==null&&typeof value==="object"){for(const child of Object.values(value))freezeRoutineMetadata(child);Object.freeze(value)}return value}function assertRoutineJson(value,ancestors=new Set){if(value===null||typeof value==="string"||typeof value==="boolean"||typeof value==="number"&&Number.isFinite(value))return;if(!value||typeof value!=="object"||ancestors.has(value))return invalid2();const array2=Array.isArray(value);if(!array2&&Object.getPrototypeOf(value)!==Object.prototype&&Object.getPrototypeOf(value)!==null)return invalid2();const keys2=Reflect.ownKeys(value);if(array2&&(keys2.length!==value.length+1||!Array.from({length:value.length},(_,index)=>Object.hasOwn(value,index)).every(Boolean)))return invalid2();ancestors.add(value);for(const key of keys2){if(array2&&key==="length")continue;if(typeof key!=="string")return invalid2();const descriptor=Object.getOwnPropertyDescriptor(value,key);if(!descriptor.enumerable||!Object.hasOwn(descriptor,"value"))return invalid2();assertRoutineJson(descriptor.value,ancestors)}ancestors.delete(value)}function assertRoutineFields(value,allowed){if(!value||typeof value!=="object"||Object.getPrototypeOf(value)!==Object.prototype||Reflect.ownKeys(value).some((key)=>typeof key!=="string"||allowed&&!allowed.includes(key)||!Object.getOwnPropertyDescriptor(value,key).enumerable||!Object.hasOwn(Object.getOwnPropertyDescriptor(value,key),"value")))return invalidContract2()}function parseRoutineAccess(value){try{if(value!==undefined)assertRoutineJson(value);assertRoutineFields(value??{},["repositories","connections","ai","files","publish"]);const access=value;const names=access?.connections??[];if(!Array.isArray(names)||names.length>64||new Set(names).size!==names.length||names.some((name)=>typeof name!=="string"||name.split("/").length!==2||name.split("/").some((part)=>!isAppRoutineName(part))))return invalidContract2();const parsed=parseRoutineDeclaration({$schema:ROUTINE_DECLARATION_SCHEMA,access:{...access,connections:[]}}).access;return freezeRoutineMetadata({...parsed,connections:[...names]})}catch{return invalidContract2()}}function parseRoutineAIOutputIssue(value){if(!value||typeof value!=="object"||Array.isArray(value))return;const v=value;if(["invalid_json","invalid_response","empty_text","structured_output_limit"].includes(String(v.reason)))return Object.keys(v).join(",")==="reason"?{reason:v.reason}:undefined;if(!["missing_field","unexpected_field","wrong_type","out_of_bounds","invalid_file"].includes(String(v.reason))||typeof v.path!=="string"||v.path.length>256||!/^\$(?:\.[a-z][A-Za-z0-9]*|\[(?:0|[1-9][0-9]*)\])*$/.test(v.path)||!["object","array","boolean","string","integer","number","file"].includes(String(v.expected))||!["missing","null","object","array","boolean","string","number","other"].includes(String(v.received))||Object.keys(v).some((key)=>!["reason","path","expected","received","constraint","limit"].includes(key)))return;if(v.reason==="out_of_bounds"){if(!["maxLength","maxItems","minimum","maximum"].includes(String(v.constraint))||typeof v.limit!=="number"||!Number.isFinite(v.limit))return}else if(Object.hasOwn(v,"constraint")||Object.hasOwn(v,"limit"))return;return{reason:v.reason,path:v.path,expected:v.expected,received:v.received,...v.reason==="out_of_bounds"?{constraint:v.constraint,limit:v.limit}:{}}}function routineAIOutputMessage(issue){if(issue.reason==="structured_output_limit")return"AI couldn’t produce an answer matching the requested format within its submission limit.";if(issue.reason==="invalid_json")return"AI replied, but its answer could not be read as JSON.";if(issue.reason==="invalid_response")return"AI returned a response OS could not read.";if(issue.reason==="empty_text")return"AI returned an empty answer.";const field=issue.path==="$"?"response":issue.path.slice(issue.path.startsWith("$.")?2:1);const expected={object:"an object",array:"a list",boolean:"true or false",string:"text",integer:"a whole number",number:"a number",file:"a File"}[issue.expected];const received={missing:"a missing field",null:"null",object:"an object",array:"a list",boolean:"true or false",string:"text",number:"a number",other:"an unsupported value"}[issue.received];if(issue.reason==="missing_field")return`AI response is missing a required field.
|
|
22
22
|
${field}: expected ${expected}; the field was missing.`;if(issue.reason==="unexpected_field")return`AI response includes an unexpected field.
|
|
23
23
|
${field}: only the fields declared by the routine are allowed.`;if(issue.reason==="invalid_file")return`AI response contains an invalid File.
|
|
24
24
|
${field}: expected a valid File matching the routine's requirements.`;if(issue.reason==="out_of_bounds"){const constraint={maxLength:`at most ${issue.limit} characters`,maxItems:`at most ${issue.limit} items`,minimum:`a value of at least ${issue.limit}`,maximum:`a value of at most ${issue.limit}`}[issue.constraint];return`AI response is outside a permitted limit.
|
|
@@ -33,11 +33,11 @@ Set tools to true or false.`;case"tools_require_file":return`The AI request is i
|
|
|
33
33
|
Using tools requires a File input.`;case"unsupported_media_type":return`AI couldn’t read this file.
|
|
34
34
|
Its media type is ${detail.mediaType}, which this input path doesn’t support.
|
|
35
35
|
|
|
36
|
-
Check the file’s stored media type before retrying. The model was not called.`}switch(code){case"access_denied":return"This routine doesn’t currently have permission to use AI.";case"capability_unavailable":return"AI is unavailable in this execution environment.";case"invalid_input":return"The AI request is invalid. Check its input, instructions and schema.";case"unsupported_file":return"AI couldn’t read this file in the requested format.";case"file_unavailable":return"AI couldn’t read or verify the file.";case"input_too_large":return"The AI input exceeds the size limit for this execution path.";case"output_too_large":return"The AI response exceeds the size limit for this execution path.";case"provider_failure":return"AI couldn’t complete the request. No more specific reason was recorded.";case"invalid_output":return"AI returned an answer OS could not accept.";case"cancelled":return"The AI operation was stopped before it completed."}}var ROUTINE_AI_VALUE_BYTES=256*1024;var ROUTINE_AI_RESULT_BYTES=6*ROUTINE_AI_VALUE_BYTES+1024;var ROUTINE_AI_EVIDENCE_BYTES=4*1024;var ROUTINE_AI_ERROR_CODES=["access_denied","capability_unavailable","invalid_input","unsupported_file","file_unavailable","input_too_large","output_too_large","provider_failure","invalid_output","cancelled"];class AIError extends Error{code;detail;constructor(code,options={}){const detail=parseRoutineAIErrorDetail(code,options.detail);super(routineAIErrorMessage(code,detail));this.code=code;this.name="AIError";if(detail)this.detail=Object.freeze(detail);if(code==="invalid_output"&&typeof options.text==="string"&&new TextEncoder().encode(options.text).byteLength<=ROUTINE_AI_VALUE_BYTES)Object.defineProperty(this,"text",{value:options.text})}}function parseRoutineAIError(value){try{const v=capture(value,"invalid_output","output_too_large",ROUTINE_AI_RESULT_BYTES);assertRoutineFields(v,["code","detail","text"]);if(!ROUTINE_AI_ERROR_CODES.includes(v.code))throw new Error;const detail=parseRoutineAIErrorDetail(v.code,v.detail);if(Object.hasOwn(v,"detail")&&!detail||Object.hasOwn(v,"text")&&(typeof v.text!=="string"||new TextEncoder().encode(v.text).byteLength>ROUTINE_AI_VALUE_BYTES)||v.code!=="invalid_output"&&Object.hasOwn(v,"text"))throw new Error;return new AIError(v.code,{detail,...v.text===undefined?{}:{text:v.text}})}catch{throw new AIError("invalid_output")}}function capture(value,invalid3,oversized,limit=ROUTINE_AI_VALUE_BYTES){try{assertRoutineJson(value);const encoded=JSON.stringify(value);if(new TextEncoder().encode(encoded).byteLength>limit)throw new AIError(oversized);return freezeRoutineMetadata(JSON.parse(encoded))}catch(error){if(error instanceof AIError)throw error;throw new AIError(invalid3)}}function parseRoutineAIRequest(value){const v=capture(value,"invalid_input","input_too_large");try{assertRoutineFields(v,v.kind==="generateObject"?["kind","instructions","input","schema","tools"]:["kind","instructions","input","tools"]);if(!["generateText","generateObject"].includes(v.kind)||typeof v.instructions!=="string"||!v.instructions.trim())throw new Error;const input=typeof v.input==="string"?v.input:parseFileDescriptor(v.input);if(Object.hasOwn(v,"tools")&&typeof v.tools!=="boolean")throw new AIError("invalid_input",{detail:{reason:"invalid_tools"}});if(v.tools===true&&typeof input==="string")throw new AIError("invalid_input",{detail:{reason:"tools_require_file"}});const tools=v.tools===true?{tools:true}:{};if(v.kind==="generateText")return freezeRoutineMetadata({kind:v.kind,instructions:v.instructions,input,...tools});const schema=parseAppRoutineContract({routine:"ai",input:v.schema,steps:[{id:"generate"}]}).input;return freezeRoutineMetadata({kind:v.kind,instructions:v.instructions,input,schema,...tools})}catch(error){if(error instanceof AIError)throw error;throw new AIError("invalid_input")}}function parseRoutineAIResult(request,value){let v;try{v=capture(value,"invalid_output","output_too_large",request.kind==="generateText"?ROUTINE_AI_RESULT_BYTES:ROUTINE_AI_VALUE_BYTES);assertRoutineFields(v,request.kind==="generateText"?["text"]:["object"]);if(request.kind==="generateText"){if(typeof v.text!=="string")throw new Error;return acceptText(request,v.text)}if(!Object.hasOwn(v,"object"))throw new Error}catch(error){if(error instanceof AIError)throw error;throw new AIError("invalid_output",{detail:{reason:"invalid_response"}})}validateObject(request.schema,v.object);return freezeRoutineMetadata({object:v.object})}function validateObject(schema,object3,text2){let detail={reason:"invalid_response"};try{validateRoutineSchemaValue(schema,object3,(issue)=>{detail=issue})}catch{throw new AIError("invalid_output",{...text2===undefined?{}:{text:text2},detail})}}function acceptText(request,text2){if(new TextEncoder().encode(text2).byteLength>ROUTINE_AI_VALUE_BYTES)throw new AIError("output_too_large");if(request.kind==="generateText"){if(!text2.trim())throw new AIError("invalid_output",{text:text2,detail:{reason:"empty_text"}});return freezeRoutineMetadata({text:text2})}let object3;const trimmed=text2.trim();const fenced=/^(`{3,}|~{3,})(?:json)?[ \t]*\r?\n([\s\S]*?)\r?\n\1[ \t]*$/i.exec(trimmed);try{object3=JSON.parse(fenced?fenced[2]:text2)}catch{throw new AIError("invalid_output",{text:text2,detail:{reason:"invalid_json"}})}validateObject(request.schema,object3,text2);return capture({object:object3},"invalid_output","output_too_large")}var LIMIT=256*1024;var invalid3=()=>{throw new AppRoutineContractError("invalid_value")};var invalidContract3=()=>{throw new AppRoutineContractError("invalid_contract")};var empty={type:"object",properties:{},required:[],additionalProperties:false};function captureJson(value,maximum=LIMIT){assertRoutineJson(value);const encoded=JSON.stringify(value);if(maximum!==null&&new TextEncoder().encode(encoded).byteLength>maximum)return invalid3();return freezeRoutineMetadata(JSON.parse(encoded))}function capture2(schema,value){const captured=captureJson(value);validateRoutineSchemaValue(schema,captured);return captured}var schemas=new WeakMap;function nestedSchema(value){const metadata=schemaMetadata(value);if(Object.hasOwn(metadata,"default"))return invalidContract3();return metadata.schema}function schemaMetadata(value){if(!value||typeof value!=="object")return invalidContract3();const registered=schemas.get(value);if(registered)return registered;try{assertRoutineJson(value)}catch{return invalidContract3()}return{schema:parseAppRoutineContract({routine:"definition",input:value,steps:[{id:"inspect"}]}).input}}function declaration(value,defaults){try{assertRoutineJson(value)}catch{return invalidContract3()}const parsed=freezeRoutineMetadata(parseAppRoutineContract({routine:"definition",input:value,steps:[{id:"inspect"}]}).input);const captured=defaults?capture2(parsed,defaults.value):undefined;const builder=Object.defineProperty({...parsed},"default",{value:(value2)=>declaration(parsed,{value:value2})});schemas.set(builder,{schema:parsed,...defaults?{default:captured}:{}});return Object.freeze(builder)}var schema={object(properties){return declaration({type:"object",properties:Object.fromEntries(Object.entries(properties).map(([key,value])=>[key,nestedSchema(value)])),required:Object.keys(properties),additionalProperties:false})},array(items,options={}){assertRoutineFields(options,["maxItems"]);return declaration({type:"array",items:nestedSchema(items),...options})},string(options={}){return declaration({type:"string",...options})},integer(options={}){return declaration({type:"integer",...options})},number(options={}){return declaration({type:"number",...options})},boolean(){return declaration({type:"boolean"})}};var file=(options={})=>{assertRoutineFields(options,["storage","path"]);return declaration({type:"file",...options})};var definitions=new WeakMap;var defineRoutine=(definition)=>{assertRoutineFields(definition,["id","title","input","steps","result","access","responses","run"]);if(!isAppRoutineName(definition.id)||definition.title!==undefined&&!routineTitle(definition.title)||typeof definition.run!=="function")return invalidContract3();const input=definition.input===undefined?{schema:empty,default:{}}:schemaMetadata(definition.input);const result=definition.result===undefined?undefined:schemaMetadata(definition.result).schema;const access=parseRoutineAccess(definition.access);assertRoutineFields(definition.steps??{});const executable=Object.fromEntries(Object.entries(definition.steps??{}).map(([id2,step])=>{assertRoutineFields(step,["title","run"]);if(!routineTitle(step.title)||typeof step.run!=="function")return invalidContract3();return[id2,Object.freeze({title:step.title,run:step.run})]}));const steps=Object.entries(executable).map(([id2,step])=>({id:id2,title:step.title}));parseAppRoutineContract({routine:definition.id,input:input.schema,steps:steps.length?steps.map(({id:id2})=>({id:id2})):[{id:"inspect"}],...result?{result}:{}});const responses=[];const ids=new Set;if(definition.responses!==undefined){if(!Array.isArray(definition.responses)||definition.responses.length>64||Reflect.ownKeys(definition.responses).length!==definition.responses.length+1)return invalidContract3();for(let index=0;index<definition.responses.length;index++){const descriptor=Object.getOwnPropertyDescriptor(definition.responses,String(index));if(!descriptor||!Object.hasOwn(descriptor,"value"))return invalidContract3();const response=descriptor.value;assertRoutineFields(response,["id","results","run"]);if(!isAppRoutineName(response.id)||ids.has(response.id))return invalidContract3();ids.add(response.id);if(response.results!==undefined){try{assertRoutineJson(response.results)}catch{return invalidContract3()}}try{responses.push(defineHandler(response))}catch{return invalidContract3()}}}const contract=freezeRoutineMetadata({id:definition.id,...definition.title===undefined?{}:{title:definition.title},input:input.schema,...Object.hasOwn(input,"default")?{inputDefault:input.default}:{},access,responses:responses.map(({id:id2})=>({id:id2})),steps,...result?{result}:{}});const captured=Object.freeze({...definition,access,steps:Object.freeze(executable),responses:Object.freeze(responses),...definition.input===undefined?{}:{input:declaration(input.schema,Object.hasOwn(input,"default")?{value:input.default}:undefined)},...result===undefined?{}:{result:declaration(result)},run:(input2,os)=>executeRoutineDefinition(captured,input2,os)});definitions.set(captured,{contract,steps:executable,run:definition.run});return captured};function inspectRoutineDefinition(definition){if(!definition||typeof definition!=="object")return invalidContract3();const registered=definitions.get(definition);if(!registered)return invalidContract3();return registered.contract}function captureRoutineInput(definition,input){const contract=inspectRoutineDefinition(definition);return capture2(contract.input,input===undefined&&Object.hasOwn(contract,"inputDefault")?contract.inputDefault:input)}async function executeRoutineDefinition(definition,input,runtime){const captured=captureRoutineInput(definition,input);const{contract,steps,run}=definitions.get(definition);let active=true,accepting=true,broken=false;let work=Promise.resolve();const aiWork=new Set;const generate=(kind,value)=>{const operation=(async()=>{if(!active||broken||contract.access.ai!==true)throw new AIError("access_denied");if(!runtime.ai)throw new AIError("capability_unavailable");let request;try{assertRoutineFields(value,kind==="generateObject"?["instructions","input","schema","tools"]:["instructions","input","tools"]);request=parseRoutineAIRequest({kind,instructions:value.instructions,input:value.input,...kind==="generateObject"?{schema:schemaMetadata(value.schema).schema}:{},...value.tools===undefined?{}:{tools:value.tools}})}catch(error){if(error instanceof AIError)throw error;throw new AIError("invalid_input")}const result2=await runtime.ai[kind](request);if(!active||broken)throw new AIError("access_denied");return parseRoutineAIResult(request,result2)})();aiWork.add(operation);operation.then(()=>aiWork.delete(operation),()=>aiWork.delete(operation));return operation};const called=new Set;const reached=new Set;const guarded=(value,receiver)=>typeof value==="function"?(...args)=>{if(!active||broken)throw new Error("Run authority ended");return guarded(Reflect.apply(value,receiver,args))}:value&&typeof value==="object"&&!(value instanceof Promise)?new Proxy({...value},{get(_target,key){return guarded(Reflect.get(value,key,value),value)}}):value;const validateHandlers=(value)=>{for(const question2 of value.questions??[])if(question2.handler&&!contract.responses.some((handler)=>handler.id===question2.handler.id))return invalid3();return value};let activeStep;const progress=new Map;const os=Object.freeze({...guarded({...runtime,run:freezeRoutineMetadata({id:runtime.run.id,async progress(value){assertRoutineFields(value,["completed","total"]);const{completed,total}=value;const prior=activeStep?progress.get(activeStep):undefined;if(!active||broken||!activeStep||!Number.isSafeInteger(completed)||!Number.isSafeInteger(total)||completed<1||completed>total||prior&&(prior.total!==total||completed<=prior.completed))return invalid3();const accepted=freezeRoutineMetadata({step:activeStep,completed,total});await runtime.run.progress(accepted);progress.set(activeStep,accepted)}}),ai:{generateText:(value)=>generate("generateText",value),generateObject:(value)=>generate("generateObject",value)},connections:{...runtime.connections,get:async(identity)=>{if(!active||broken||!contract.access.connections?.includes(identity))throw new Error("Connection unavailable");const value=await runtime.connections.get(identity);if(!active||broken)throw new Error("Run authority ended");return value}},inbox:{...runtime.inbox,publishAsk:(value,options)=>runtime.inbox.publishAsk(validateHandlers(value),options)}}),step(id2,...input2){let saved;try{if(!active||!accepting||broken||!Object.hasOwn(steps,id2)||called.has(id2)||input2.length>1)return invalid3();if(input2.length)saved=captureJson(input2[0],null);called.add(id2)}catch(error){broken=true;return Promise.reject(error)}const next=work.then(async()=>{if(broken)return invalid3();reached.add(id2);try{await runtime.step(id2,{status:"running"});activeStep=id2;const output=await steps[id2].run(saved,os);assertRoutineFields(output,["summary","data"]);if(!Object.hasOwn(output,"summary")||!Object.hasOwn(output,"data"))return invalid3();const summary=captureJson(output.summary),data=captureJson(output.data);await runtime.step(id2,{status:"completed",summary,data});activeStep=undefined;return freezeRoutineMetadata({summary,data})}catch(error){broken=true;activeStep=undefined;await runtime.step(id2,{status:"failed"});throw error}});work=next.then(()=>{},()=>{broken=true});return next}});let result,failure;try{result=await run(captured,os)}catch(error){failure=error;broken=true}accepting=false;await work;while(aiWork.size)await Promise.allSettled([...aiWork]);active=false;for(const step of contract.steps)if(!reached.has(step.id))await runtime.step(step.id,{status:"skipped"});if(broken)throw failure??new AppRoutineContractError("invalid_value");if(contract.result!==undefined)return capture2(contract.result,result);if(result!==undefined)return invalid3();return}var RECORD_READ_INPUT_LIMIT=1024*1024;var RECORD_CAPTURE_OUTPUT_LIMIT=25*1024*1024;function validRecordRef(value){return typeof value==="string"&&value.length<=512&&/^[_a-zA-Z0-9][a-zA-Z0-9_-]*(\/[_a-zA-Z0-9][a-zA-Z0-9_-]*)+$/.test(value)}var fieldProblems=["unknown","missing","invalid","source_schema"];var reasons={unknown:"unknown_field",missing:"missing_field",invalid:"invalid_value",source_schema:"source_schema_mismatch"};var expectationKinds={string:"a string",integer:"a safe integer",number:"a finite number",boolean:"a boolean",date:"a date in YYYY-MM-DD format",const:"the constant declared in the schema",enum:"one of the choices declared in the schema",link:"a link to an existing record of an allowed type",object:"an object matching the schema",map:"a map matching the schema"};function expectationText(expected){if(!Object.hasOwn(expectationKinds,expected.type)||typeof expected.many!=="boolean"||typeof expected.nullable!=="boolean"||expected.decimalPlaces!==undefined&&(expected.type!=="number"||!Number.isInteger(expected.decimalPlaces)||expected.decimalPlaces<0||expected.decimalPlaces>6)||expected.format!==undefined&&(expected.type!=="date"||expected.format!=="month"))return;const scalar=expected.type==="number"&&expected.decimalPlaces!==undefined?`a finite number with at most ${expected.decimalPlaces} decimal places`:expected.type==="date"&&expected.format==="month"?"a date in YYYY-MM format":expectationKinds[expected.type];return`${expected.many?"Expected a list. Each item must be":"Expected"} ${scalar}.${expected.nullable?" The field may also be null.":""}`}function parseExpectation(text2){if(!text2)return;const parts=/^Expected (a list\. Each item must be )?(.+?)\.( The field may also be null\.)?$/.exec(text2);if(!parts)return;const number=/^a finite number with at most ([0-6]) decimal places$/.exec(parts[2]);const month=parts[2]==="a date in YYYY-MM format";const kind=number?"number":month?"date":Object.keys(expectationKinds).find((kind2)=>expectationKinds[kind2]===parts[2]);if(!kind)return;const expected={type:kind,many:!!parts[1],nullable:!!parts[3],...number?{decimalPlaces:Number(number[1])}:{},...month?{format:"month"}:{}};return expectationText(expected)===text2?expected:undefined}function parseDataValidationDetail(value){if(!value||typeof value!=="object"||Array.isArray(value))return;const v=value;if(Object.keys(v).some((key)=>!["record","field","reason","schemaFile","expected"].includes(key))||typeof v.record!=="string"||typeof v.field!=="string")return;const problem=fieldProblems.find((problem2)=>reasons[problem2]===v.reason);if(!problem||v.schemaFile!==undefined&&typeof v.schemaFile!=="string")return;let expected;if(Object.hasOwn(v,"expected")){if(!v.expected||typeof v.expected!=="object"||Array.isArray(v.expected))return;const e=v.expected;if(Object.keys(e).some((key)=>!["type","many","nullable","decimalPlaces","format"].includes(key)))return;expected={...e};if(!expectationText(expected))return}if(problem==="unknown"&&expected||problem==="source_schema"&&(v.field!=="media_type"||expected?.type!=="string"||expected.many||expected.nullable))return;if(!recordFieldMessage(v.record,v.field,problem,v.schemaFile,expected))return;return{record:v.record,field:v.field,reason:reasons[problem],...typeof v.schemaFile==="string"?{schemaFile:v.schemaFile}:{},...expected?{expected}:{}}}function recordFieldMessage(record2,field,problem,schemaPath,expected){if(!validRecordRef(record2)||!/^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/.test(field))return;if(schemaPath!==undefined&&(schemaPath.length>256||!/^[a-zA-Z0-9_.-]+(?:\/[a-zA-Z0-9_.-]+)*\/_schema\.yaml$/.test(schemaPath)||schemaPath.split("/").some((part)=>[".","..",".git","routines"].includes(part))))return;const prefix=`Record "${record2}" isn't valid.`;const schema2=schemaPath?`"${schemaPath}"`:"the collection schema";if(problem==="source_schema")return field==="media_type"?`${prefix} This repository's Source schema${schemaPath?` ${schema2}`:""} doesn't include "media_type". The OS SDK uses "media_type" for file Sources. Update the Source schema in this repository to include this field.`:undefined;if(problem==="unknown")return`${prefix} The record contains "${field}", but ${schema2} doesn't define that field. Check that the record and ${schemaPath?"that file":"the collection schema"} use the same field name.`;if(problem==="missing")return`${prefix} The record is missing required field "${field}". Add it as defined in ${schema2}.`;const expectation=expected?expectationText(expected):undefined;if(expected&&!expectation)return;return`${prefix} The record has an invalid value for field "${field}".${expectation?` ${expectation}`:""} Check its definition in ${schema2}.`}function safeRecordFieldMessage(value){if(typeof value!=="string"||value.length>1200)return;const parts=/^Record "([^"]+)" isn't valid\. (.+)$/.exec(value);if(!parts)return;const schemaPath=/"([^"]+\/_schema\.yaml)"/.exec(value)?.[1];const field=[...parts[2].matchAll(/"([^"]+)"/g)].map((match)=>match[1]).find((part)=>part!==schemaPath);if(!field)return;const expected=parseExpectation(/\. (Expected .+) Check its definition in /.exec(value)?.[1]);return fieldProblems.map((problem)=>recordFieldMessage(parts[1],field,problem,schemaPath,expected)).find((message)=>message===value)}function dataValidationMessageFacts(error){if(error.code==="invalid_change"){const detail=parseDataValidationDetail(error.detail);if(detail){const problem=fieldProblems.find((problem2)=>reasons[problem2]===detail.reason);return{detail,message:recordFieldMessage(detail.record,detail.field,problem,detail.schemaFile,detail.expected)}}}const message=error.code==="invalid_change"?safeRecordFieldMessage(error.message):undefined;return message?{message}:{}}function explainDataValidation(error,message,detail){Object.assign(error,dataValidationMessageFacts({code:error.code,message:typeof message==="string"?message:"",detail}));return error}var localDataPath=(value,repository)=>typeof value==="string"&&value.length<=1024&&value.startsWith(`${repository}/`)&&!value.includes("\\")&&!/[\x00-\x1f\x7f]/.test(value)&&value.split("/").every((part)=>!!part&&part!=="."&&part!=="..");var localDataFile=(value,repository)=>{if(!value||typeof value!=="object"||Array.isArray(value))return false;const row=value;return Object.keys(row).sort().join(",")==="action,path"&&["created","updated","deleted"].includes(String(row.action))&&localDataPath(row.path,repository)};function parseDataFailureDetail(value){const invalid4=()=>{throw new Error("Invalid local Data failure detail")};if(!value||typeof value!=="object"||Array.isArray(value))return invalid4();const row=value;if(Object.keys(row).sort().join(",")!=="cause,code,files,nextAction,operation,repository"||!["local_data_read_failed","local_data_write_failed","local_data_write_partial"].includes(String(row.code))||!["read","write"].includes(String(row.operation))||typeof row.repository!=="string"||!/^[a-z0-9][a-z0-9._/-]{0,127}$/.test(row.repository)||row.repository.includes("//")||row.repository.includes("..")||!["fix_failed_file_then_rerun","review_resolve_then_rerun"].includes(String(row.nextAction)))return invalid4();const repository=row.repository;if(!row.cause||typeof row.cause!=="object"||Array.isArray(row.cause))return invalid4();const cause=row.cause;if(!["code,message","code,message,path"].includes(Object.keys(cause).sort().join(","))||!["schema_validation_failed","invalid_record","unsafe_record","stale_record","path_conflict","filesystem_unavailable"].includes(String(cause.code))||typeof cause.message!=="string"||!cause.message||cause.message.length>512||/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/.test(cause.message)||cause.path!==undefined&&!localDataPath(cause.path,repository))return invalid4();if(!row.files||typeof row.files!=="object"||Array.isArray(row.files))return invalid4();const files=row.files;if(Object.keys(files).some((key)=>!["state","saved","failed","notAttempted","savedOmitted","notAttemptedOmitted"].includes(key))||!["none","partial"].includes(String(files.state))||!Array.isArray(files.saved)||files.saved.length>128||!files.saved.every((item)=>localDataFile(item,repository))||files.failed!==undefined&&!localDataFile(files.failed,repository)||!Array.isArray(files.notAttempted)||files.notAttempted.length>128||!files.notAttempted.every((item)=>localDataFile(item,repository)))return invalid4();for(const key of["savedOmitted","notAttemptedOmitted"])if(files[key]!==undefined&&(!Number.isSafeInteger(files[key])||Number(files[key])<1||Number(files[key])>1e4))return invalid4();if(row.operation==="read"&&(row.code!=="local_data_read_failed"||files.state!=="none"||files.saved.length||files.failed!==undefined||files.notAttempted.length)||row.operation==="write"&&row.code==="local_data_read_failed"||row.code==="local_data_write_partial"&&(files.state!=="partial"||!files.saved.length)||row.code!=="local_data_write_partial"&&files.state==="partial")return invalid4();return structuredClone(value)}function parseDataOperationDetail(value){const validation=parseDataValidationDetail(value);if(validation)return validation;if(value&&typeof value==="object"&&!Array.isArray(value)&&value.code==="record_limit_exceeded"){const row=value;if(Object.keys(row).sort().join(",")!=="code,collections,maxRecords"||!Number.isSafeInteger(row.maxRecords)||Number(row.maxRecords)<1||!Array.isArray(row.collections)||!row.collections.length||row.collections.length>16||!row.collections.every((name)=>typeof name==="string"&&name.length<=512&&/^[_a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(name))||new Set(row.collections).size!==row.collections.length)throw new Error("Invalid Data operation detail");return structuredClone(value)}return parseDataFailureDetail(value)}function dataRecordLimitMessage(detail){const scope=detail.collections.length===1?` from ${detail.collections[0]}`:` across ${detail.collections.join(", ")}`;return`The routine tried to load more than ${detail.maxRecords.toLocaleString("en-US")} matching Records${scope}. `+"Narrow the query or increase maxRecords."}class DataOperationError extends Error{code;retryable;effect;component;detail;constructor(code,retryable=false,effect,component,detail){const parsed=detail===undefined?undefined:parseDataOperationDetail(detail);if(parsed&&("reason"in parsed?code!=="invalid_change":parsed.code==="record_limit_exceeded"&&code!=="capacity"))throw new Error("Invalid Data operation detail");super(code==="capacity"&&parsed&&"code"in parsed&&parsed.code==="record_limit_exceeded"?dataRecordLimitMessage(parsed):`Data operation failed: ${code}`);this.code=code;this.retryable=retryable;this.effect=effect;this.component=component;this.detail=detail;this.name="DataOperationError";if(parsed!==undefined)this.detail=parsed}}var invalid4=()=>{throw new DataOperationError("invalid_query")};var historyText=(value)=>typeof value==="string"&&!/[\u0000\uD800-\uDFFF]/u.test(value);function historyVersion(value){return historyText(value)&&value.length>0&&new TextEncoder().encode(value).length<=1024&&!/[\u0000-\u001f\u007f-\u009f]/.test(value)&&!/^[0-9a-f]{40}$/i.test(value)}function historyProperties(value){if(!value||typeof value!=="object"||Array.isArray(value)||![Object.prototype,null].includes(Object.getPrototypeOf(value)))return invalid4();const descriptors=Object.getOwnPropertyDescriptors(value);if(Reflect.ownKeys(value).some((key)=>typeof key!=="string"||!descriptors[key]?.enumerable||!Object.hasOwn(descriptors[key],"value")))return invalid4();return descriptors}var historyCollection=(value)=>typeof value==="string"&&value.length<=512&&/^[_a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value);var historyCursor=(value)=>typeof value==="string"&&value.length<=128*1024&&/^history-cursor-v1\.[A-Za-z0-9_-]{1,64}\.[A-Za-z0-9_-]{16}\.[A-Za-z0-9_-]+$/.test(value);function historyArray(value){if(!Array.isArray(value)||Object.getPrototypeOf(value)!==Array.prototype)return invalid4();const descriptors=Object.getOwnPropertyDescriptors(value);if(Reflect.ownKeys(value).length!==value.length+1)return invalid4();const result=[];for(let i=0;i<value.length;i++){const descriptor=descriptors[i];if(!descriptor?.enumerable||!Object.hasOwn(descriptor,"value"))return invalid4();result.push(descriptor.value)}return result}function captureOptions(value,changes){if(value===undefined)return{};const descriptors=historyProperties(value),result={};const allowed=changes?["collections","refs","from","through","limit","after"]:["limit","before"];if(Object.keys(descriptors).some((key)=>!allowed.includes(key)))return invalid4();for(const key of allowed){if(!Object.hasOwn(descriptors,key))continue;const scalar=descriptors[key].value;if(key==="collections"||key==="refs"){const values=historyArray(scalar);if(!values.length||values.length>(key==="collections"?16:100)||!values.every(key==="collections"?historyCollection:validRecordRef)||new Set(values).size!==values.length)return invalid4();result[key]=values}else if(key==="limit"){if(!Number.isInteger(scalar)||scalar<1||scalar>(changes?500:100))return invalid4();result.limit=scalar}else{if(!(key==="after"?historyCursor(scalar):historyVersion(scalar)))return invalid4();result[key]=scalar}}return result}var captureHistoryListOptions=(value)=>captureOptions(value,false);var captureHistoryChangesOptions=(value)=>captureOptions(value,true);function captureHistoryInstant(value){if(!historyText(value)||value.length>1024)return invalid4();const match=/^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2}):(\d{2})(?:\.\d+)?([Zz]|([+-])(\d{2}):(\d{2}))$/.exec(value);if(!match)return invalid4();const[year,month,day,hour,minute,second]=match.slice(1,7).map(Number);const days=new Date(Date.UTC(year,month,0));days.setUTCFullYear(year);if(year<1||month<1||month>12||day<1||day>days.getUTCDate()||hour>23||minute>59||second>59||Number(match[9]??0)>23||Number(match[10]??0)>59)return invalid4();return value}var invalid5=()=>{throw new DataOperationError("invalid_query")};function captureRecordsSearchInput(query,options){if(!historyText(query))return invalid5();const length=[...query.trim()].length;if(length<1||length>256)return invalid5();if(options===undefined)return{query};const descriptors=historyProperties(options);if(Object.keys(descriptors).some((key)=>!["collections","limit"].includes(key)))return invalid5();const captured={};if(Object.hasOwn(descriptors,"collections")){const supplied=descriptors.collections.value;if(!Array.isArray(supplied)||supplied.length<1||supplied.length>16||Reflect.ownKeys(supplied).length!==supplied.length+1)return invalid5();const collections=[];for(let index=0;index<supplied.length;index++){const descriptor=Object.getOwnPropertyDescriptor(supplied,String(index));if(!descriptor?.enumerable||!Object.hasOwn(descriptor,"value")||!historyText(descriptor.value))return invalid5();collections.push(descriptor.value)}if(new Set(collections).size!==collections.length)return invalid5();captured.collections=collections}if(Object.hasOwn(descriptors,"limit")){const supplied=descriptors.limit.value;if(!Number.isInteger(supplied)||supplied<1||supplied>100)return invalid5();captured.limit=supplied}return{query,options:captured}}function captureRecordsReadRefs(value){if(!Array.isArray(value)||value.length<1||value.length>100)throw new DataOperationError("invalid_query");const refs=historyArray(value);if(!refs.every((ref)=>validRecordRef(ref)&&!/[\r\n]/.test(ref))||new Set(refs).size!==refs.length)throw new DataOperationError("invalid_query");return refs}function captureRecordsReadOptions(value){if(value===undefined)return{};let row;try{row=Object.fromEntries(Object.entries(historyProperties(value)).map(([key,descriptor])=>[key,descriptor.value]))}catch{throw new DataOperationError("invalid_query")}if(!value||typeof value!=="object"||Array.isArray(value)||![Object.prototype,null].includes(Object.getPrototypeOf(value))||Reflect.ownKeys(value).some((key)=>key!=="body"||!Object.hasOwn(Object.getOwnPropertyDescriptor(value,key),"value"))||Object.hasOwn(row,"body")&&typeof row.body!=="boolean")throw new DataOperationError("invalid_query");return Object.hasOwn(row,"body")?{body:row.body}:{}}function validRecordBody(value){return typeof value==="string"&&value===new TextDecoder("utf-8",{ignoreBOM:true}).decode(new TextEncoder().encode(value))}var RECORD_BODY_READ_BYTES=8*1024*1024;var DATA_REQUEST_LIMIT=256*1024;var LOCAL_DATA_CHANGE_REQUEST_LIMIT=32*1024*1024;var invalidChange=()=>{throw new DataOperationError("invalid_change",false,"unapplied")};function mapping(value){try{historyProperties(value);return value}catch{return invalidChange()}}function captureValue(value,ancestors=new Set,depth=0){if(value===null||typeof value==="string"||typeof value==="boolean"||typeof value==="number"&&Number.isFinite(value))return value;if(!value||typeof value!=="object"||ancestors.has(value)||depth>32)return invalidChange();ancestors.add(value);try{if(Array.isArray(value)){if(value.length>1e5||Object.keys(value).length!==value.length||Object.getOwnPropertySymbols(value).length)return invalidChange();return Array.from(value,(item)=>captureValue(item,ancestors,depth+1))}return Object.fromEntries(Object.entries(mapping(value)).map(([key,item])=>{if(["__proto__","constructor","prototype"].includes(key))return invalidChange();return[key,captureValue(item,ancestors,depth+1)]}))}finally{ancestors.delete(value)}}function captureDataDelete(record2){const identity=mapping(record2);if(!validRecordRef(identity.$ref)||typeof identity.$version!=="string"||!identity.$version.length||identity.$version.length>512)return invalidChange();return{ref:identity.$ref,expectedVersion:identity.$version}}function captureDataUpdate(record2,set){const identity=captureDataDelete(record2),input=mapping(set);const{$body,...fields3}=input;const body=Object.hasOwn(input,"$body");if(body&&!validRecordBody($body)||!Object.keys(fields3).length&&!body||Object.keys(fields3).some((key)=>key.startsWith("$")||["id","type"].includes(key)))return invalidChange();return{...identity,set:captureValue(fields3),...body?{body:$body}:{}}}function captureIdentities(value,update,allowEmpty=true){if(!Array.isArray(value)||!allowEmpty&&!value.length||value.length>1e4)return invalidChange();const captured=value.map((item)=>{const row=mapping(item);if(Object.keys(row).filter((key)=>!update||key!=="body").sort().join(",")!==(update?"expectedVersion,ref,set":"expectedVersion,ref"))return invalidChange();const identity={$ref:row.ref,$version:row.expectedVersion};if(update&&Object.keys(mapping(row.set)).some((key)=>key.startsWith("$")))return invalidChange();return update?captureDataUpdate(identity,{...mapping(row.set),...Object.hasOwn(row,"body")?{$body:row.body}:{}}):captureDataDelete(identity)});if(new Set(captured.map((item)=>item.ref)).size!==captured.length)return invalidChange();return captured}function captureDataUpdates(value,allowEmpty=false){return captureIdentities(value,true,allowEmpty)}function captureDataCreate(value){const row=mapping(value);if(!validRecordRef(row.$ref)||Object.keys(row).some((key)=>key.startsWith("$")&&!["$ref","$filing","$body"].includes(key)))return invalidChange();const{$ref:ref,$filing,$body,...fields3}=row;const body=Object.hasOwn(row,"$body");if(body&&!validRecordBody($body))return invalidChange();let filing;if($filing!==undefined){const components=mapping($filing);if(Object.entries(components).some(([name,value2])=>!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)||["constructor","prototype"].includes(name)||typeof value2!=="string"||!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value2)))return invalidChange();filing={...components}}return{ref,fields:captureValue(fields3),...filing?{filing}:{},...body?{body:$body}:{}}}function captureDataChanges(updatesValue,createsValue=[],deletesValue=[]){const updates=captureDataUpdates(updatesValue,true);if(!Array.isArray(createsValue)||createsValue.length>1e4)return invalidChange();const creates=createsValue.map((item)=>{const row=mapping(item);if(Object.keys(row).some((key)=>!["ref","fields","filing","body"].includes(key))||!Object.hasOwn(row,"ref")||!Object.hasOwn(row,"fields"))return invalidChange();const fields3=mapping(row.fields);if(Object.keys(fields3).some((key)=>key.startsWith("$")))return invalidChange();return captureDataCreate({...fields3,$ref:row.ref,...Object.hasOwn(row,"filing")?{$filing:row.filing}:{},...Object.hasOwn(row,"body")?{$body:row.body}:{}})});const deletes=captureIdentities(deletesValue,false);const refs=[...updates,...creates,...deletes].map((item)=>item.ref);if(!refs.length||refs.length>1e4||new Set(refs).size!==refs.length)return invalidChange();return{updates,creates,deletes}}function checkDataRequestSize(input,limit=DATA_REQUEST_LIMIT){if(new TextEncoder().encode(JSON.stringify(input)).byteLength>limit)throw new DataOperationError("request_too_large",false,"unapplied")}function dataTransportError(status,value){const failures={400:["invalid_query","invalid_change"],401:["unauthenticated"],403:["access_denied"],409:["conflict","apply_pending"],413:["request_too_large"],429:["capacity"],503:["unavailable","apply_pending"]};const error=value&&typeof value==="object"&&"error"in value?value.error:undefined;const row=error&&typeof error==="object"?error:undefined;const code=failures[status]?.find((allowed)=>allowed===row?.code)??"unavailable";const effect=["unapplied","uncertain","applied"].includes(String(row?.effect))?row.effect:undefined;let detail;try{detail=row?.detail===undefined?undefined:parseDataOperationDetail(row.detail)}catch{}if(detail&&"reason"in detail&&code!=="invalid_change")detail=undefined;return explainDataValidation(new DataOperationError(code,typeof row?.retryable==="boolean"?row.retryable:["capacity","unavailable","apply_pending"].includes(code),code==="conflict"?"unapplied":effect,code==="invalid_change"&&typeof row?.component==="string"&&/^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/.test(row.component)?row.component:undefined,detail),row?.message,row?.detail)}var AUTH_ORIGIN="https://auth.oddington.ai";function oddingtonOrigin(environment=process.env){const value=environment.OS_ORIGIN??AUTH_ORIGIN;const url=new URL(value);if(url.protocol!=="https:"&&url.hostname!=="127.0.0.1")throw new Error("OS_ORIGIN must use HTTPS");return url.origin}var nodeRequest;var nodeReadable;if(typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__){({request:nodeRequest}=await import("node:http"));({Readable:nodeReadable}=await import("node:stream"))}function privateRoutineRequest(environment=typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__?{}:typeof process==="undefined"?{}:process.env){if(typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__)return;const prepared=["OS_ROUTINE_LOCAL","OS_ROUTINE_LOCAL_SOCKET","OS_ROUTINE_LOCAL_TOKEN"].some((key)=>environment[key]!==undefined);const managed=["OS_FILES_SOCKET","OS_FILES_TOKEN"].some((key)=>environment[key]!==undefined);if(!prepared&&!managed)return;const socket=prepared?environment.OS_ROUTINE_LOCAL_SOCKET:environment.OS_FILES_SOCKET;const token=prepared?environment.OS_ROUTINE_LOCAL_TOKEN:environment.OS_FILES_TOKEN;const request=localRoutineRequest(prepared?environment:{OS_ROUTINE_LOCAL:"1",OS_ROUTINE_LOCAL_SOCKET:socket,OS_ROUTINE_LOCAL_TOKEN:token});const isCurrent=()=>prepared?environment.OS_ROUTINE_LOCAL==="1"&&environment.OS_ROUTINE_LOCAL_SOCKET===socket&&environment.OS_ROUTINE_LOCAL_TOKEN===token:environment.OS_FILES_SOCKET===socket&&environment.OS_FILES_TOKEN===token;if(!nodeRequest||!nodeReadable)throw new Error("Files transport unavailable");const httpRequest=nodeRequest,Readable=nodeReadable;const files=async(suffix,init,signal)=>{if(!isCurrent())throw new FileOperationError("unsupported_context",400);const tcp=/^tcp:\/\/127\.0\.0\.1:([1-9][0-9]{0,4})$/.exec(socket);const endpoint=tcp?{hostname:"127.0.0.1",port:Number(tcp[1])}:{socketPath:socket};const id2=crypto.randomUUID();if(init.body instanceof ReadableStream||suffix===""&&init.method==="POST"){await new Promise((resolve,reject)=>{const check=httpRequest({...endpoint,path:"/files/check-create",method:"POST",timeout:30000,signal,agent:false,headers:{...Object.fromEntries(new Headers(init.headers)),authorization:`Bearer ${token}`,"x-os-files-suffix":encodeURIComponent(suffix),"x-os-files-method":init.method??"GET"}},(response)=>{const bytes=Buffer.alloc(16384);let size=0;response.on("data",(chunk)=>{size+=chunk.length;if(size>16384)response.destroy(new Error("File operation start response exceeded 16 KiB."));else bytes.set(chunk,size-chunk.length)});response.once("error",reject);response.once("end",()=>{if(response.statusCode===204){resolve();return}try{const value=JSON.parse(bytes.subarray(0,size).toString());const code=value?.error?.code;const status=response.statusCode??503;if(["invalid_input","request_too_large","unsupported_context","access_denied","capacity","unavailable"].includes(code))reject(new FileOperationError(code,status,code==="capacity"||code==="unavailable",parseFileErrorDetail(value?.error?.detail)));else reject(new FileOperationError("unavailable",503,true))}catch{reject(new FileOperationError("unavailable",503,true))}})});check.once("error",()=>reject(new FileOperationError("unavailable",503,true)));check.once("timeout",()=>check.destroy(new Error("The file create check did not finish in time.")));check.end()});if(!isCurrent())throw new FileOperationError("unsupported_context",400)}let cancellation;const cancelCall=()=>cancellation??=new Promise((resolve,reject)=>{const cancel=httpRequest({...endpoint,path:"/files/cancel",method:"POST",timeout:30000,headers:{authorization:`Bearer ${token}`,"x-os-files-call":id2}},(response)=>{response.resume();response.once("end",resolve);response.once("error",reject)});cancel.once("error",reject);cancel.once("timeout",()=>cancel.destroy(new Error("Files cancellation stalled")));cancel.end()});let pumping=Promise.resolve();let sourceReader;const result=new Promise((resolve,reject)=>{const call=httpRequest({...endpoint,path:"/files/stream",method:"POST",headers:{...Object.fromEntries(new Headers(init.headers)),authorization:`Bearer ${token}`,"x-os-files-call":id2,"x-os-files-suffix":encodeURIComponent(suffix),"x-os-files-method":init.method??"GET"},signal,timeout:30000,agent:false},async(response)=>{try{call.setTimeout(0);if((response.statusCode??503)>=400){await sourceReader?.cancel().catch(()=>{});call.end()}await pumping;if(!isCurrent()){response.destroy();reject(new FileOperationError("unsupported_context",400));return}const headers=new Headers;for(const[key,value]of Object.entries(response.headers))if(value!==undefined)headers.set(key,Array.isArray(value)?value.join(", "):value);const source=Readable.toWeb(response,{strategy:{highWaterMark:65536,size:(chunk)=>chunk.byteLength}});const reader=source.getReader();if(response.statusCode===204){const timer=setTimeout(()=>response.destroy(new Error("Files completion stalled")),30000);try{if(!(await reader.read()).done)throw new FileOperationError("unavailable",503,true);if(!isCurrent())throw new FileOperationError("unsupported_context",400);resolve(new Response(null,{status:204,headers}))}finally{clearTimeout(timer);reader.releaseLock()}return}let closed=false;const body=new ReadableStream({async pull(controller){let timer;try{if(!isCurrent())throw new FileOperationError("unsupported_context",400);timer=setTimeout(()=>response.destroy(new Error("Files delivery stalled")),30000);const next=await reader.read();if(closed)return;if(next.done){closed=true;reader.releaseLock();controller.close()}else controller.enqueue(next.value)}catch(error){closed=true;controller.error(error);await cancelCall().catch(()=>{});response.socket?.destroy();response.destroy();await reader.cancel(error).catch(()=>{});reader.releaseLock()}finally{clearTimeout(timer)}},async cancel(reason){closed=true;await cancelCall().catch(()=>{});response.socket?.destroy();response.destroy();call.destroy();await reader.cancel(reason).catch(()=>{});reader.releaseLock()}},{highWaterMark:0});resolve(new Response(body,{status:response.statusCode??503,headers}))}catch(error){response.destroy();reject(error instanceof FileOperationError?error:new FileOperationError("unavailable",503,true))}});call.on("error",(error)=>{cancelCall().catch(()=>{});reject(error instanceof FileOperationError?error:new FileOperationError("unavailable",503,true))});call.on("timeout",()=>call.destroy(new Error("Files I/O stalled")));call.on("information",()=>call.setTimeout(30000));if(init.body instanceof ReadableStream){call.flushHeaders();const reader=sourceReader=init.body.getReader();const abort=()=>{reader.cancel(signal.reason).catch(()=>{})};signal.addEventListener("abort",abort,{once:true});call.once("close",abort);pumping=(async()=>{try{for(;;){const next=await reader.read();if(next.done)break;if(!(next.value instanceof Uint8Array))throw new FileOperationError("invalid_input",400);if(!isCurrent())throw new FileOperationError("unsupported_context",400);for(let offset=0;offset<next.value.byteLength;offset+=262144){if(call.destroyed)throw new Error("Files parent disconnected");await new Promise((done,fail2)=>{const closed=()=>fail2(new Error("Files parent disconnected"));call.once("close",closed);call.write(next.value.subarray(offset,offset+262144),(error)=>{call.removeListener("close",closed);error?fail2(error):done()})})}}call.end()}catch(error){call.destroy(error instanceof Error?error:new Error("Files transport failed"))}finally{await reader.cancel().catch(()=>{});signal.removeEventListener("abort",abort);call.removeListener("close",abort);reader.releaseLock()}})()}else call.end(init.body===undefined?undefined:Buffer.from(init.body))});try{return await result}finally{await pumping}};return{request,files,isCurrent,identity:`private:${socket}`}}function localRoutineRequest(environment=typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__?{}:typeof process==="undefined"?{}:process.env){if(typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__){const{OS_ROUTINE_LOCAL:mode,OS_ROUTINE_LOCAL_SOCKET:socket,OS_ROUTINE_LOCAL_TOKEN:token}=environment;if(mode===undefined&&socket===undefined&&token===undefined)return;if(mode!=="1"||!socket||!token||!/^[0-9a-f]{64}$/.test(token))throw new Error("Preparation transport unavailable; nothing can publish");const tcp=/^tcp:\/\/127\.0\.0\.1:([1-9][0-9]{0,4})$/.exec(socket);const endpoint=tcp&&tcp[0]===socket&&Number(tcp[1])<=65535?{hostname:"127.0.0.1",port:Number(tcp[1])}:socket.startsWith("/")&&!socket.startsWith("//")&&!socket.includes("\x00")?{socketPath:socket}:undefined;if(!endpoint)throw new Error("Preparation transport unavailable; nothing can publish");return async(operation,input)=>{const{request}=await import("node:http");return await new Promise((resolve,reject)=>{const call=request({...endpoint,path:`/${operation}`,method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${token}`},timeout:operation==="ai/generate"?125000:120000},(response)=>{const limit=operation==="ai/generate"?ROUTINE_AI_RESULT_BYTES:33554432;const bytes=Buffer.alloc(limit);let size=0;response.on("data",(chunk)=>{size+=chunk.length;if(size>limit){response.destroy();reject(operation==="ai/generate"?new AIError("output_too_large"):new Error("Local result exceeds supported size"))}else bytes.set(chunk,size-chunk.length)});response.on("error",(error)=>reject(operation==="ai/generate"?new AIError("capability_unavailable"):error));response.on("end",()=>{try{const result=JSON.parse(bytes.subarray(0,size).toString());if(response.statusCode!==200){if(operation==="ai/generate")throw parseRoutineAIError(result.error);if(operation==="files/request"){const error=result.error;const status=response.statusCode??503;const codes=["invalid_input","unsupported_context","unauthenticated","access_denied","request_too_large","conflict","local_only","integrity","unavailable","capacity","method_not_allowed"];if(error?.code&&codes.includes(error.code))throw new FileOperationError(error.code,status,error.code==="capacity"||error.code==="unavailable",parseFileErrorDetail(error.detail));throw new FileOperationError("unavailable",503,true)}if(operation==="data/query"){throw dataTransportError(response.statusCode??0,result)}throw new Error(typeof result.error==="string"?result.error:"Preparation failed")}resolve(result)}catch(error){reject(operation==="ai/generate"&&!(error instanceof AIError)?new AIError("invalid_output"):error)}})});call.on("error",()=>reject(operation==="ai/generate"?new AIError("capability_unavailable"):operation==="data/query"?dataTransportError(503,{error:{code:"unavailable"}}):new Error("Preparation transport unavailable; nothing was published")));call.on("timeout",()=>call.destroy(new Error("Preparation timed out")));call.end(JSON.stringify(input))})}}}var installed;var ended=false;function routineTransport(){if(ended||installed&&!installed.isCurrent())throw new Error("Routine authority ended");return installed}var memberContext;var retainedContext;function installMemberContext(resolve,retained=resolve){memberContext=resolve;retainedContext=retained;return()=>{if(memberContext===resolve){memberContext=undefined;retainedContext=undefined}}}async function resolveAppContext(retained=false){const host=memberContext;if(!host)throw new Error("App context unavailable.");const context=await(retained?retainedContext:host)();if(host!==memberContext||!context.isCurrent()||context.expiresAt<=Date.now()||context.kind!=="local"&&(typeof context.accessToken!=="string"||!/^[^\s]{1,8192}$/.test(context.accessToken))){throw new Error("App context unavailable.")}return context}async function resolveDataContext(){try{if(typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__){const installed2=routineTransport();if(installed2)return{local:installed2.request};const local=localRoutineRequest();if(local)return{local};const managed=privateRoutineRequest();if(managed)return{local:managed.request}}const host=memberContext;if(host!==undefined){const context=await host();if(host!==memberContext||!context.isCurrent()||context.expiresAt<=Date.now())throw new Error;if(context.kind==="local")return{local:context.requestData};if(!context||!Number.isFinite(context.expiresAt)||context.expiresAt<=Date.now()||typeof context.accessToken!=="string"||!/^[^\s]{1,8192}$/.test(context.accessToken))throw new Error;return checked(context.workspace,context.endpoint,{authorization:`Bearer ${context.accessToken}`})}if(typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__){const environment=typeof process==="undefined"?undefined:process.env;if(!environment||!/^[0-9a-f]{64}$/.test(environment.OS_ROUTINE_RUN??""))throw new Error;return checked(environment.OS_ROUTINE_WORKSPACE,oddingtonOrigin(environment),{"x-os-run":environment.OS_ROUTINE_RUN})}throw new Error}catch{throw new DataOperationError("context_unavailable")}}async function resolveFilesContext(){try{const environment=typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__?{}:typeof process==="undefined"?{}:process.env;if(typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__){const installed2=routineTransport();if(installed2)return{url:"private:installed",headers:{},isCurrent:installed2.isCurrent,local:installed2.request,localFiles:installed2.files,signal:undefined};const local=privateRoutineRequest(environment);if(local)return{url:local.identity,headers:{},isCurrent:local.isCurrent,local:local.request,localFiles:local.files,signal:undefined}}const host=memberContext;if(host){const context=await host();if(host!==memberContext||!context.isCurrent()||context.expiresAt<=Date.now())throw new Error;if(context.kind==="local")return{url:`private:app:${context.workspace}/${context.memberId}`,headers:{},isCurrent:context.isCurrent,signal:context.signal,local:undefined,localFiles:context.requestFiles};if(!Number.isFinite(context.expiresAt)||context.expiresAt<=Date.now()||typeof context.accessToken!=="string"||!/^[^\s]{1,8192}$/.test(context.accessToken))throw new Error;return{...filesContext(context.workspace,context.endpoint,{authorization:`Bearer ${context.accessToken}`}),isCurrent:context.isCurrent,local:undefined,localFiles:undefined,signal:undefined}}if(typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__){if(!/^[0-9a-f]{64}$/.test(environment.OS_ROUTINE_RUN??""))throw new Error;const workspace=environment.OS_ROUTINE_WORKSPACE;return{...filesContext(workspace,`https://${workspace}.oddington.ai`,{"x-os-run":environment.OS_ROUTINE_RUN}),local:undefined,localFiles:undefined,signal:undefined}}throw new Error}catch{throw new FileOperationError("unsupported_context",400)}}function filesContext(workspace,endpoint,headers){if(!workspace||!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(workspace)||workspace.length>63||["auth","www","api","os"].includes(workspace)||endpoint!==`https://${workspace}.oddington.ai`)throw new Error;return{url:`${endpoint}/api/files`,headers:{...headers,"x-os-workspace":workspace},isCurrent:()=>true}}function checked(workspace,endpoint,headers){if(!workspace||!/^[a-z0-9][a-z0-9-]{0,127}$/.test(workspace))throw new Error;const origin=new URL(endpoint);if(origin.protocol!=="https:"||origin.username||origin.password||origin.search||origin.hash||origin.pathname!=="/")throw new Error;return{url:`${origin.origin}/api/data`,headers:{...headers,"x-os-workspace":workspace}}}var invalid6=()=>{throw new DataOperationError("invalid_query")};var unavailable=()=>{throw new DataOperationError("unavailable")};var text2=(value)=>typeof value==="string"&&value.length>0;function capture3(value,ancestors=new Set,depth=0){if(value===null||typeof value==="string"||typeof value==="boolean"||typeof value==="number"&&Number.isFinite(value))return value;if(!value||typeof value!=="object"||ancestors.has(value)||depth>32)return invalid6();ancestors.add(value);try{if(Array.isArray(value))return historyArray(value).map((item)=>capture3(item,ancestors,depth+1));return Object.fromEntries(Object.entries(historyProperties(value)).map(([key,descriptor])=>[key,capture3(descriptor.value,ancestors,depth+1)]))}finally{ancestors.delete(value)}}function recordPagination(queryRecords){function pages(query){const captured=capture3(query);const names=Object.keys(historyProperties(captured));for(const name of names){const selection2=historyProperties(captured[name]);if(Object.hasOwn(selection2,"$")){const options=historyProperties(selection2.$.value);if(Object.hasOwn(options,"after"))return invalid6()}}return iterate();async function*iterate(){const state=new Map(names.map((name)=>[name,{seen:new Set,total:0,count:undefined,next:undefined}]));let active=names,version;do{const request=Object.fromEntries(active.map((name)=>{const selection2=captured[name];const next=state.get(name).next;return[name,next===undefined?selection2:{...selection2,$:{...selection2.$,after:next}}]}));const response=await queryRecords(request);let page;try{page=capture3(response);const keys2=Object.keys(historyProperties(page));if(keys2.length!==active.length+1||keys2.some((key)=>key!=="$meta"&&!active.includes(key)))unavailable();const meta=page.$meta;if(Object.keys(historyProperties(meta)).sort().join(",")!=="collections,version"||!text2(meta.version)||version!==undefined&&version!==meta.version)unavailable();version=meta.version;const collectionKeys=Object.keys(historyProperties(meta.collections));if(collectionKeys.some((key)=>!active.includes(key)))unavailable();for(const name of active){const records=historyArray(page[name]);const metadata=Object.hasOwn(meta.collections,name)?meta.collections[name]:{};if(Object.keys(historyProperties(metadata)).some((key)=>key!=="count"&&key!=="next")||Object.hasOwn(metadata,"next")&&!text2(metadata.next))unavailable();for(const record2 of records){historyProperties(record2);const row=record2;if(!validRecordRef(row.$ref)||!text2(row.$version))unavailable()}const current=state.get(name);if(captured[name].$?.count===true){if(!Number.isSafeInteger(metadata.count)||metadata.count<0||current.count!==undefined&¤t.count!==metadata.count)unavailable();current.count=metadata.count}else if(Object.hasOwn(metadata,"count"))unavailable();current.total+=records.length;if(!Number.isSafeInteger(current.total)||current.count!==undefined&&(current.total>current.count||metadata.next===undefined&¤t.total!==current.count))unavailable();if(metadata.next!==undefined){if(current.seen.has(metadata.next))unavailable();current.seen.add(metadata.next)}current.next=metadata.next}}catch{return unavailable()}const collections=Object.fromEntries(names.map((name)=>{const current=state.get(name);return[name,{...current.count===undefined?{}:{count:current.count},...current.next===undefined?{}:{next:current.next}}]}));const output=Object.fromEntries(names.map((name)=>[name,active.includes(name)?page[name]:[]]));active=active.filter((name)=>state.get(name).next!==undefined);yield{...output,$meta:{version,collections}}}while(active.length)}}async function all(query,options){const properties=historyProperties(options);const maxRecords=properties.maxRecords?.value;if(Object.keys(properties).join(",")!=="maxRecords"||!Number.isSafeInteger(maxRecords)||maxRecords<1)invalid6();const captured=capture3(query);const names=Object.keys(historyProperties(captured));if(names.length===1){const name=names[0],selection2=historyProperties(captured[name]);const selectionNames=Object.keys(selection2);const authored=selection2.$?historyProperties(selection2.$.value):{};if(selectionNames.every((key)=>key==="$")&&!Object.hasOwn(authored,"limit"))captured[name]={...captured[name],$:{...captured[name].$,limit:Math.min(500,maxRecords)}}}let result,total=0;for await(const page of pages(captured)){const names2=Object.keys(page.$meta.collections);const size=names2.reduce((sum,name)=>sum+page[name].length,0);if(size>maxRecords-total)throw new DataOperationError("capacity",false,undefined,undefined,{code:"record_limit_exceeded",maxRecords,collections:names2});total+=size;result??={...Object.fromEntries(names2.map((name)=>[name,[]])),$meta:page.$meta};for(const name of names2){const target=result[name];for(const record2 of page[name])target.push(record2)}result.$meta=page.$meta}return result}return{pages,all}}var genericData={repository(repository){async function send(input){const context=await resolveDataContext();const envelope={repository,...input};const changing="operation"in input&&["changes.validate","changes.apply"].includes(String(input.operation));checkDataRequestSize(envelope,"local"in context&&changing?LOCAL_DATA_CHANGE_REQUEST_LIMIT:DATA_REQUEST_LIMIT);if("local"in context)return await context.local("data/query",envelope);try{const response=await fetch(context.url,{method:"POST",redirect:"error",cache:"no-store",headers:{"content-type":"application/json",...context.headers},body:JSON.stringify(envelope)});const result=await response.json();if(!response.ok){throw dataTransportError(response.status,result)}return result}catch(error){if(error instanceof DataOperationError)throw error;throw new DataOperationError("unavailable",true)}}async function read(input,options){const refs=captureRecordsReadRefs(typeof input==="string"?[input]:input);const captured=captureRecordsReadOptions(options);const result=await send({operation:"records.read",refs,...options===undefined?{}:{options:captured}});return typeof input==="string"?result.records[0]:result}const queryRecords=(query)=>send({operation:"records.query",query});return{collections:{list:()=>send({operation:"collections.list"}),schema:(name)=>send({operation:"collections.schema",name})},records:{read,query:queryRecords,...recordPagination(queryRecords),search:async(query,options)=>send({operation:"records.search",...captureRecordsSearchInput(query,options)})},history:{list:async(options)=>send({operation:"history.list",options:captureHistoryListOptions(options)}),at:async(instant)=>send({operation:"history.at",instant:captureHistoryInstant(instant)}),changes:async(options)=>send({operation:"history.changes",options:captureHistoryChangesOptions(options)})},changes(){let updates=[],creates=[],deletes=[],applyId;let pending,confirmed;const assertMutable=()=>{if(applyId)throw new DataOperationError("invalid_change",false,"unapplied")};const snapshot=(nextUpdates=updates,nextCreates=creates,nextDeletes=deletes)=>{const{updates:updates2,creates:creates2,deletes:deletes2}=captureDataChanges(nextUpdates,nextCreates,nextDeletes);const input={updates:updates2,...creates2.length?{creates:creates2}:{},...deletes2.length?{deletes:deletes2}:{}};checkDataRequestSize({repository,operation:"changes.apply",...input,applyId:applyId??"00000000-0000-4000-8000-000000000000"},LOCAL_DATA_CHANGE_REQUEST_LIMIT);return input};return{create(record2){assertMutable();const next=[...creates,captureDataCreate(record2)];snapshot(updates,next,deletes);creates=next},update(record2,set){assertMutable();const next=[...updates,captureDataUpdate(record2,set)];snapshot(next,creates,deletes);updates=next},delete(record2){assertMutable();const next=[...deletes,captureDataDelete(record2)];snapshot(updates,creates,next);deletes=next},async validate(){await send({operation:"changes.validate",...snapshot()})},apply(){if(confirmed)return Promise.resolve(structuredClone(confirmed));if(!pending){let captured;try{captured=snapshot()}catch(error){return Promise.reject(error)}applyId??=routineTransport()?.key("data")??crypto.randomUUID();pending=send({operation:"changes.apply",...captured,applyId}).then((result)=>{confirmed=structuredClone(result);return result}).catch((error)=>{if(error instanceof DataOperationError)throw explainDataValidation(new DataOperationError(error.code,error.retryable,error.effect??(["unavailable","apply_pending"].includes(error.code)?"uncertain":"unapplied"),error.component,error.detail),error.message,error.detail);throw new DataOperationError("unavailable",true,"uncertain")}).finally(()=>{pending=undefined})}return pending.then((result)=>structuredClone(result))}}}}}};var data=genericData;async function hostedContent(url,init,parent,upstream=fetch,check=async()=>{},failure){const delivery=new AbortController;const abort=()=>delivery.abort(parent.reason);parent.addEventListener("abort",abort,{once:true});if(parent.aborted)abort();const detach=()=>parent.removeEventListener("abort",abort);try{const response=await upstream(url,{...init,signal:delivery.signal});try{await check();if(delivery.signal.aborted)throw failure?.()??new FileOperationError("unavailable",503,true)}catch(error){response.body?.cancel().catch(()=>{});throw error}if(!response.body){detach();return response}const source=response.body;let reader;let settled=false;let output;const cancel=async(reason)=>{if(settled)return;settled=true;detach();delivery.signal.removeEventListener("abort",stop);delivery.abort(reason);try{await(reader?reader.cancel(reason):source.cancel(reason))}catch(error){if(error!==delivery.signal.reason&&!(error instanceof Error&&error.name==="AbortError"))throw error}finally{reader?.releaseLock()}};const stop=()=>{if(settled)return;const error=failure?.()??delivery.signal.reason;cancel(error).catch(()=>{});output.error(error)};const body=new ReadableStream({start(controller){output=controller;delivery.signal.addEventListener("abort",stop,{once:true});if(delivery.signal.aborted)stop()},async pull(controller){try{await check();if(settled)return;reader??=source.getReader();const{done,value}=await reader.read();await check();if(settled)return;if(done){settled=true;detach();delivery.signal.removeEventListener("abort",stop);reader.releaseLock();controller.close()}else controller.enqueue(value)}catch(error){if(settled)return;controller.error(failure?.()??error);await cancel(error).catch(()=>{})}},cancel},{highWaterMark:0});const wrapped=new Response(body,{status:response.status,statusText:response.statusText,headers:response.headers});for(const key of["url","redirected","type"])Object.defineProperty(wrapped,key,{value:response[key]});return wrapped}catch(error){detach();delivery.abort(error);throw error}}var MAX_BYTES=16*1024*1024;var PART_BYTES=8*1024*1024;var METADATA_BYTES=4096;var RESULT_BYTES=16*1024;var CONTROL_RESULT_BYTES=128*1024;var TIMEOUT_MS=30000;var MAX_ACTIVE=4;var ATTEMPTS=2;var active=0;var waiters=[];var invalid7=()=>new FileOperationError("invalid_input",400);var unavailable2=()=>new FileOperationError("unavailable",503,true);var failures={400:["invalid_input","unsupported_context"],401:["unauthenticated"],403:["access_denied"],405:["method_not_allowed"],409:["conflict","local_only"],413:["request_too_large"],429:["capacity"],503:["integrity","unavailable"]};function heldSlot(){let held=true;return()=>{if(!held)return;held=false;for(;;){const waiter=waiters.shift();if(!waiter){active--;return}if(!waiter.waiting)continue;waiter.waiting=false;waiter.signal?.removeEventListener("abort",waiter.abort);waiter.resolve(heldSlot());return}}}async function acquireSlot(signal){if(signal?.aborted)throw unavailable2();if(active<MAX_ACTIVE){active++;return heldSlot()}return new Promise((resolve,reject)=>{const waiter={signal,waiting:true,resolve,reject,abort(){if(!waiter.waiting)return;waiter.waiting=false;const index=waiters.indexOf(waiter);if(index!==-1)waiters.splice(index,1);reject(unavailable2())}};waiters.push(waiter);signal?.addEventListener("abort",waiter.abort,{once:true});if(signal?.aborted)waiter.abort()})}async function boundedBytes(stream,limit,signal){if(!stream)return new Uint8Array;const reader=stream.getReader();const bytes=new Uint8Array(limit);let size=0;const cancel=()=>{reader.cancel().catch(()=>{})};signal?.addEventListener("abort",cancel,{once:true});if(signal?.aborted)cancel();try{for(;;){const{done,value}=await reader.read();if(signal?.aborted)throw unavailable2();if(done)break;if(!(value instanceof Uint8Array))throw new FileOperationError("invalid_input",400,false,{reason:"invalid_bytes"});size+=value.byteLength;if(size>limit)throw new FileOperationError("request_too_large",413,false,{reason:"size_limit",limitBytes:limit,receivedBytes:size,receivedAtLeast:true});bytes.set(value,size-value.byteLength)}}catch(error){cancel();throw error}finally{signal?.removeEventListener("abort",cancel);reader.releaseLock()}return bytes.slice(0,size)}async function timed(work,parent,timeout=TIMEOUT_MS){const controller=new AbortController;let timer;let abort;const expiry=new Promise((_,reject)=>{abort=()=>{controller.abort();reject(unavailable2())};timer=setTimeout(abort,timeout);parent?.addEventListener("abort",abort,{once:true});if(parent?.aborted)abort()});try{return await Promise.race([work(controller.signal),expiry])}finally{clearTimeout(timer);parent?.removeEventListener("abort",abort)}}async function result(response,maximum=RESULT_BYTES){try{const bytes=await boundedBytes(response.body,maximum);return JSON.parse(new TextDecoder("utf-8",{fatal:true}).decode(bytes))}catch{throw unavailable2()}}async function send(suffix,init,descriptor,initial,parent){const original=initial;const checkCurrent=(context=original)=>{if(parent?.aborted)throw unavailable2();if(!original.isCurrent()||context.url!==original.url)throw new FileOperationError("unsupported_context",400)};for(let attempt=0;attempt<ATTEMPTS;attempt++){checkCurrent();const context=await resolveFilesContext();checkCurrent(context);try{const response=context.localFiles?await context.localFiles(suffix,init,parent):await(async()=>{const url=`${context.url}${suffix}`;const request={...init,signal:parent,headers:{...context.headers,...init.headers},redirect:"error",cache:"no-store"};return descriptor?fetch(url,request):hostedContent(url,request,parent)})();if(!response.ok){const value2=await result(response);const error=value2&&typeof value2==="object"&&"error"in value2?value2.error:undefined;const received=error&&typeof error==="object"&&"code"in error?error.code:undefined;const code=failures[response.status]?.find((code2)=>code2===received);throw code?new FileOperationError(code,response.status,code==="capacity"||code==="unavailable",parseFileErrorDetail(error?.detail)):unavailable2()}if(response.status!==200){response.body?.cancel().catch(()=>{});throw unavailable2()}try{checkCurrent()}catch(error){response.body?.cancel().catch(()=>{});throw error}if(!descriptor)return response;const value=await result(response,descriptor==="control"?CONTROL_RESULT_BYTES:RESULT_BYTES);if(descriptor==="control"){checkCurrent();return value}let parsed;if(descriptor==="enrichment"){if(!value||typeof value!=="object"||Array.isArray(value))throw unavailable2();const{name,...metadata}=value;if(!safeEnrichmentName(name))throw unavailable2();parsed={name,...parseEnrichmentDescriptor(metadata)}}else parsed=parseFileDescriptor(value);checkCurrent();return parsed}catch(error){const failure=error instanceof FileOperationError?error:unavailable2();if(init.body instanceof ReadableStream||!failure.retryable||attempt+1===ATTEMPTS)throw failure}}throw unavailable2()}function idPath(id2){if(typeof id2!=="string"||!FILE_ID_PATTERN.test(id2))throw invalid7();return`/${id2}`}async function multipartCreate(input,metadata,exchange,release,upload,expectedSha256){const route=upload?`${idPath(upload.file.id)}/upload/multipart`:"/multipart";let ticket;let reader;let chunk,offset=0;const receipts=[];const pending=new Set;const request=(work,timeout=TIMEOUT_MS)=>timed((signal)=>{const task=work(signal);pending.add(task);task.then(()=>pending.delete(task),()=>pending.delete(task));return task},undefined,timeout);const control=(body)=>({method:"POST",headers:{"content-type":"application/json",...ticket?{"x-os-transfer":ticket}:{}},body:JSON.stringify(body)});try{const startRequest=control(upload?.file??metadata);if(expectedSha256)startRequest.headers["x-os-original-sha256"]=expectedSha256;const start=await request((signal)=>exchange(`${route}/start`,startRequest,"control",signal));if(!start||typeof start!=="object"||Array.isArray(start))throw unavailable2();const session=start;if(Object.keys(session).sort().join(",")!=="partBytes,ticket"||session.partBytes!==PART_BYTES||typeof session.ticket!=="string"||!session.ticket||session.ticket.length>64*1024)throw unavailable2();ticket=session.ticket;if(input.file instanceof ReadableStream)reader=input.file.getReader();let lastProgress=Date.now();const next=async()=>{try{if(Date.now()-lastProgress>=TIMEOUT_MS)throw unavailable2();const value=await request(()=>reader.read(),Math.max(1,TIMEOUT_MS-(Date.now()-lastProgress)));if(value.value?.byteLength)lastProgress=Date.now();return value}catch(error){await reader.cancel(error).catch(()=>{});throw error}};for(let sent=0,partNumber=1;sent<metadata.size||metadata.size===0&&partNumber===1;partNumber++){const length=Math.min(PART_BYTES,metadata.size-sent);let part;if(input.file instanceof Uint8Array)part=new Uint8Array(input.file.subarray(sent,sent+length));else if(input.file instanceof Blob){const slice=input.file.slice(sent,sent+length);part=new Uint8Array(await request(()=>slice.arrayBuffer()))}else{part=new Uint8Array(length);let filled=0;while(filled<length){if(!chunk||offset===chunk.byteLength){chunk=undefined;offset=0;const value2=await next();if(value2.done)throw invalid7();if(!(value2.value instanceof Uint8Array))throw invalid7();chunk=value2.value;if(chunk.byteLength>metadata.size-sent-filled)throw invalid7()}const take=Math.min(length-filled,chunk.byteLength-offset);part.set(chunk.subarray(offset,offset+take),filled);filled+=take;offset+=take;if(offset===chunk.byteLength){chunk=undefined;offset=0}}}if(part.byteLength!==length)throw invalid7();if(reader&&sent+length===metadata.size){lastProgress=Date.now();for(;;){const value2=await next();if(value2.done)break;if(!(value2.value instanceof Uint8Array)||value2.value.byteLength)throw invalid7()}}const value=await request((signal)=>exchange(`${route}/part`,{method:"POST",headers:{"content-type":"application/octet-stream","x-os-transfer":ticket,"x-os-part":String(partNumber)},body:part.buffer},"control",signal));part=undefined;const receipt=value;if(!receipt||typeof receipt!=="object"||Object.keys(receipt).sort().join(",")!=="etag,partNumber"||receipt.partNumber!==partNumber||typeof receipt.etag!=="string"||!receipt.etag||receipt.etag.length>256||/[\u0000-\u001f\u007f]/.test(receipt.etag))throw unavailable2();receipts.push({partNumber,etag:receipt.etag});sent+=length;lastProgress=Date.now()}if(upload)for(const name of Object.keys(upload.file.enrichments)){const bytes=await request(()=>upload.enrichment(name));if(bytes.byteLength!==upload.file.enrichments[name].size||bytes.byteLength>MAX_BYTES)throw invalid7();await request((signal)=>exchange(`${route}/enrichments/${encodeURIComponent(name)}`,{method:"POST",headers:{"content-type":"application/octet-stream","x-os-transfer":ticket},body:bytes.buffer.slice(bytes.byteOffset,bytes.byteOffset+bytes.byteLength)},"control",signal))}await upload?.beforeComplete();const completion=control({parts:receipts});if(new TextEncoder().encode(completion.body).byteLength>128*1024)throw unavailable2();const completed=parseFileDescriptor(await request((signal)=>exchange(`${route}/complete`,completion,true,signal),TIMEOUT_MS+Math.ceil(metadata.size/(1024*1024))*1000));if(!upload){const acknowledged=await request((signal)=>exchange(`${route}/acknowledge`,control(completed),"control",signal));if(!acknowledged||typeof acknowledged!=="object"||Object.keys(acknowledged).join(",")!=="acknowledged"||acknowledged.acknowledged!==true)throw unavailable2()}return completed}catch(error){if(reader)await reader.cancel(error).catch(()=>{});if(ticket)await request((signal)=>exchange(`${route}/abort`,control({}),"control",signal)).catch(()=>{});throw error instanceof FileOperationError?error:unavailable2()}finally{chunk=undefined;reader?.releaseLock();if(pending.size)Promise.allSettled([...pending]).then(release);else release()}}async function operation(work,initial,parent){const context=initial??await resolveFilesContext();const signal=context.signal&&parent?AbortSignal.any([context.signal,parent]):context.signal??parent;const release=await acquireSlot(signal);const execute=async(signal2)=>{try{return await work(context,signal2)}finally{release()}};if(context.localFiles)return execute(signal??new AbortController().signal);return timed(execute,signal).catch((error)=>{throw error instanceof FileOperationError?error:unavailable2()})}function contentPath(id2,name){const path=idPath(id2);if(name===undefined)return`${path}/content`;if(!safeEnrichmentName(name))throw invalid7();return`${path}/enrichments/${encodeURIComponent(name)}/content`}async function read(id2,names){const context=await resolveFilesContext();idPath(id2);if(names===undefined||typeof names==="string"){const path=contentPath(id2,names);return operation((context2,signal)=>send(path,{method:"GET"},false,context2,signal),context)}if(!Array.isArray(names))throw invalid7();const distinct=[];const seen=new Set;for(const name of names){if(typeof name!=="string"||!safeEnrichmentName(name))throw invalid7();if(seen.has(name))continue;if(seen.size===16)throw invalid7();seen.add(name);distinct.push(name)}const paths=distinct.map((name)=>contentPath(id2,name));return timed(async(parent)=>{const responses={};try{for(let i=0;i<paths.length;i++){const response=await operation((context2,signal)=>send(paths[i],{method:"GET"},false,context2,signal),context,parent);Object.defineProperty(responses,distinct[i],{value:response,enumerable:true})}if(!context.isCurrent())throw new FileOperationError("unsupported_context",400);return responses}catch(error){for(const response of Object.values(responses))response.body?.cancel().catch(()=>{});throw error}})}var files={async upload(id2){return operation(async(context,signal)=>{const file2=await send(`${idPath(id2)}/upload`,{method:"POST"},true,context,signal);if(file2.id!==id2)throw unavailable2();return file2})},async create(input,options){const context=await resolveFilesContext();if(!input||typeof input!=="object"||Array.isArray(input)||Object.keys(input).some((key)=>!["file","size","path","name","storage","mediaType"].includes(key))||options!==undefined&&(!options||typeof options!=="object"||Array.isArray(options)||Object.keys(options).some((key)=>key!=="requestKey")))throw invalid7();const blob=input.file instanceof Blob;const array2=input.file instanceof Uint8Array;const stream=input.file instanceof ReadableStream;if(!blob&&!array2&&!stream)throw invalid7();const intrinsic=blob?input.file.size:array2?input.file.byteLength:undefined;if(intrinsic!==undefined&&input.size!==undefined&&input.size!==intrinsic){if(!Number.isSafeInteger(input.size)||input.size<0)throw new FileOperationError("invalid_input",400,false,{reason:"invalid_size"});throw new FileOperationError("invalid_input",400,false,{reason:"size_mismatch",expectedBytes:input.size,receivedBytes:intrinsic})}let name=input.name;if(name===undefined&&blob&&"name"in input.file&&typeof input.file.name==="string"){name=typeof globalThis.File!=="undefined"&&input.file instanceof globalThis.File?input.file.name:input.file.name.split(/[\\/]/).at(-1)}const mediaType=declaredOriginalMediaType(input.mediaType===undefined?blob&&input.file.type?input.file.type:"application/octet-stream":input.mediaType);const metadata=parseFileCreateMetadata({name,size:intrinsic??input.size,path:input.path,storage:input.storage,mediaType,requestKey:options?.requestKey===undefined?routineTransport()?.key("files")??crypto.randomUUID():options.requestKey},FILE_ORIGINAL_MAX_BYTES);if(!context.local&&!context.localFiles&&metadata.storage==="local")throw new FileOperationError("unsupported_context",400);const header=encodeURIComponent(JSON.stringify(metadata));if(new TextEncoder().encode(header).byteLength>METADATA_BYTES)throw invalid7();const release=await acquireSlot(context.signal);if(context.localFiles&&!routineTransport()&&metadata.size>MAX_BYTES){try{const signal=context.signal??new AbortController().signal;const file2=input.file;let offset=0;const body=file2 instanceof Blob?context.signal?file2:file2.stream():file2 instanceof ReadableStream?file2:new ReadableStream({pull(controller){if(offset===file2.byteLength){controller.close();return}const end=Math.min(offset+256*1024,file2.byteLength);controller.enqueue(file2.subarray(offset,end));offset=end}},{highWaterMark:0});return await send("",{method:"POST",headers:{"content-type":"application/octet-stream","x-os-file":header},body},true,context,signal)}finally{release()}}if(metadata.size>MAX_BYTES)return multipartCreate(input,metadata,(suffix,init,kind,signal)=>kind===true?send(suffix,init,true,context,signal):send(suffix,init,"control",context,signal),release);return timed(async(signal)=>{try{const bytes=array2?new Uint8Array(input.file):await boundedBytes(blob?input.file.stream():input.file,metadata.size,signal);if(bytes.byteLength!==metadata.size)throw new FileOperationError("invalid_input",400,false,{reason:"size_mismatch",expectedBytes:metadata.size,receivedBytes:bytes.byteLength});if(signal.aborted)throw unavailable2();return await send("",{method:"POST",headers:{"content-type":"application/octet-stream","x-os-file":header},body:bytes.buffer},true,context,signal)}finally{release()}},context.signal).catch((error)=>{throw error instanceof FileOperationError?error:unavailable2()})},async enrich(input){const context=await resolveFilesContext();if(!input||typeof input!=="object"||Array.isArray(input)||Object.keys(input).some((key)=>!["file","name","content","mediaType","replace"].includes(key))||typeof input.content!=="string"&&!(input.content instanceof Uint8Array))throw invalid7();const path=`${idPath(input.file)}/enrichments`;if(typeof input.content==="string"?input.content.length>MAX_BYTES:input.content.byteLength>MAX_BYTES)throw new FileOperationError("request_too_large",413);return operation(async(context2,signal)=>{let bytes;if(typeof input.content==="string"){const buffer=new Uint8Array(Math.min(MAX_BYTES,input.content.length*3));const encoded=new TextEncoder().encodeInto(input.content,buffer);if(encoded.read!==input.content.length)throw new FileOperationError("request_too_large",413);bytes=buffer.slice(0,encoded.written)}else bytes=new Uint8Array(input.content);const metadata=parseFileEnrichMetadata({name:input.name,size:bytes.byteLength,...input.mediaType===undefined?{}:{mediaType:input.mediaType},...input.replace===undefined?{}:{replace:input.replace}},MAX_BYTES);const header=encodeURIComponent(JSON.stringify(metadata));if(new TextEncoder().encode(header).byteLength>METADATA_BYTES)throw invalid7();const result2=await send(path,{method:"POST",headers:{"content-type":"application/octet-stream","x-os-enrichment":header},body:bytes.buffer},"enrichment",context2,signal);if(result2.name!==metadata.name)throw unavailable2();return result2},context)},async get(id2){return operation((context,signal)=>send(idPath(id2),{method:"GET"},true,context,signal))},read};function validDropboxRootPath(value){return typeof value==="string"&&value.length<=2048&&value.startsWith("/")&&!/[\\\x00-\x1f\x7f]/.test(value)&&value.slice(1).split("/").every((segment)=>segment.length>0&&segment.trim()===segment&&segment!=="."&&segment!=="..")}function validMicrosoftId(value){return typeof value==="string"&&/^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i.test(value)}function validMicrosoftMailbox(value){return typeof value==="string"&&value.length<=254&&/^[^\s@/?#\\\x00-\x1f\x7f]+@[^\s@/?#\\\x00-\x1f\x7f]+\.[^\s@/?#\\\x00-\x1f\x7f]+$/.test(value)}function sharePointHost(value){return/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.sharepoint\.com$/.test(value)}function canonicalSharePointSiteUrl(value){if(typeof value!=="string"||value.length>2048||/[\s\\?#\x00-\x1f\x7f]/.test(value)||!/^https:\/\/[^/:@]+(?:\/|$)/i.test(value))return;try{const url=new URL(value);if(url.protocol!=="https:"||!sharePointHost(url.hostname)||url.username||url.password||url.port)return;const rawPath=value.replace(/^https:\/\/[^/]+/i,"")||"/";const path=rawPath.endsWith("/")?rawPath.slice(0,-1):rawPath;const segments=path.slice(1).split("/");if(path&&segments.some((segment)=>!segment))return;const encoded=path?segments.map((segment)=>{const decoded=decodeURIComponent(segment);if(decoded==="."||decoded===".."||/[/%\\?#\x00-\x1f\x7f]/.test(decoded))throw new Error;return encodeURIComponent(decoded)}).join("/"):"";const canonical=`https://${url.hostname}/${encoded}`;return canonical.length<=2048?canonical:undefined}catch{return}}function validSharePointSiteId(value,siteUrl){if(typeof value!=="string"||value.length>512)return false;const[host,collection,site,extra]=value.split(",");return extra===undefined&&host===new URL(siteUrl).hostname&&validMicrosoftId(collection)&&validMicrosoftId(site)}function validGoogleScopes(value){return Array.isArray(value)&&value.length>0&&value.length<=32&&value.every((scope)=>typeof scope==="string"&&scope.length<=256&&/^(https:\/\/www\.googleapis\.com\/auth\/[A-Za-z0-9._-]+|https:\/\/mail\.google\.com\/|openid|email|profile)$/.test(scope))&&new Set(value).size===value.length}var DROPBOX_FILE_SCOPES=["account_info.read","files.metadata.read","files.content.read","files.content.write"];function validDropboxFileScopes(value){return Array.isArray(value)&&value.length===DROPBOX_FILE_SCOPES.length&&new Set(value).size===value.length&&DROPBOX_FILE_SCOPES.every((scope)=>value.includes(scope))}var ROUTINE_CONNECTION_CREDENTIALS_ENV="OS_ROUTINE_CONNECTION_CREDENTIALS";function parseRoutineConnectionNames(value){if(!Array.isArray(value)||value.some((name)=>typeof name!=="string"||!/^(gmail|airtable|dropbox|outlook|sharepoint)\/[a-z0-9][a-z0-9-]{0,62}$/.test(name))||new Set(value).size!==value.length)throw new Error("Invalid routine connections");return value}var connectionUuid=(v)=>typeof v==="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(v);function runtimeConnection(lease){switch(lease.provider){case"outlook":return{id:`outlook/${lease.name}`,provider:lease.provider,name:lease.name,mailboxEmail:lease.mailboxEmail,accessToken:lease.accessToken,expiresAt:lease.expiresAt};case"sharepoint":return{id:`sharepoint/${lease.name}`,provider:lease.provider,name:lease.name,siteId:lease.siteId,siteUrl:lease.siteUrl,accessToken:lease.accessToken,expiresAt:lease.expiresAt};case"gmail":return{id:`gmail/${lease.name}`,provider:lease.provider,name:lease.name,accountEmail:lease.accountEmail,scopes:[...lease.scopes],accessToken:lease.accessToken,expiresAt:lease.expiresAt};case"airtable":return{id:`airtable/${lease.name}`,provider:lease.provider,name:lease.name,baseId:lease.baseId,accessToken:lease.accessToken,runExpiresAt:lease.runExpiresAt};case"dropbox":return{id:`dropbox/${lease.name}`,provider:lease.provider,name:lease.name,accountId:lease.accountId,access:lease.access,rootPath:lease.rootPath,scopes:[...lease.scopes],accessToken:lease.accessToken,expiresAt:lease.expiresAt}}}function parseConnectionLease(raw,now=Date.now()){const v=raw;if(!v||typeof v!=="object"||Array.isArray(v)||!connectionUuid(v.connectionId)||!connectionUuid(v.runId)||typeof v.name!=="string"||!/^[a-z0-9][a-z0-9-]{0,62}$/.test(v.name)||typeof v.accessToken!=="string"||!/^[A-Za-z0-9._~+/-]{1,8192}={0,2}$/.test(v.accessToken))throw new Error("Invalid connection credential");if(v.provider==="outlook"||v.provider==="sharepoint"){const targetValid=v.provider==="outlook"?Object.keys(v).sort().join(",")==="accessToken,connectionId,expiresAt,mailboxEmail,name,provider,runId"&&validMicrosoftMailbox(v.mailboxEmail):Object.keys(v).sort().join(",")==="accessToken,connectionId,expiresAt,name,provider,runId,siteId,siteUrl"&&typeof v.siteUrl==="string"&&canonicalSharePointSiteUrl(v.siteUrl)===v.siteUrl&&validSharePointSiteId(v.siteId,v.siteUrl);if(!targetValid||typeof v.expiresAt!=="string"||!Number.isFinite(Date.parse(v.expiresAt))||Date.parse(v.expiresAt)<=now||Date.parse(v.expiresAt)>now+3600000)throw new Error("Invalid connection credential");return v}if(v.provider==="gmail"){if(Object.keys(v).sort().join(",")!=="accessToken,accountEmail,connectionId,expiresAt,name,provider,runId,scopes"||typeof v.accountEmail!=="string"||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v.accountEmail)||!validGoogleScopes(v.scopes)||typeof v.expiresAt!=="string"||!Number.isFinite(Date.parse(v.expiresAt))||Date.parse(v.expiresAt)<=now||Date.parse(v.expiresAt)>now+3600000)throw new Error("Invalid connection credential");return v}if(v.provider==="airtable"&&Object.keys(v).sort().join(",")==="accessToken,baseId,connectionId,name,provider,runExpiresAt,runId"&&typeof v.baseId==="string"&&/^app[A-Za-z0-9]+$/.test(v.baseId)&&typeof v.runExpiresAt==="string"&&Number.isFinite(Date.parse(v.runExpiresAt))&&Date.parse(v.runExpiresAt)>now&&Date.parse(v.runExpiresAt)<=now+15*60000)return v;if(v.provider==="dropbox"&&Object.keys(v).sort().join(",")==="access,accessToken,accountId,connectionId,expiresAt,name,provider,rootPath,runId,scopes"&&typeof v.accountId==="string"&&/^dbid:[A-Za-z0-9_-]{1,128}$/.test(v.accountId)&&v.access==="full_dropbox"&&validDropboxRootPath(v.rootPath)&&validDropboxFileScopes(v.scopes)&&typeof v.expiresAt==="string"&&Number.isFinite(Date.parse(v.expiresAt))&&Date.parse(v.expiresAt)>now&&Date.parse(v.expiresAt)<=now+14400000)return v;throw new Error("Invalid connection credential")}class AirtableOperationError extends Error{effect;receipts;constructor(message,effect="unapplied",receipts=[]){super(message);this.effect=effect;this.receipts=receipts;this.name="AirtableOperationError"}}var recordId=(v)=>typeof v==="string"&&/^rec[A-Za-z0-9]+$/.test(v);var tableId=(v)=>typeof v==="string"&&/^tbl[A-Za-z0-9]+$/.test(v);function fail2(message){throw new AirtableOperationError(message)}function object3(v){if(!v||typeof v!=="object"||Array.isArray(v)||![null,Object.prototype].includes(Object.getPrototypeOf(v)))fail2("Invalid Airtable data");return v}function keys2(v,allowed,required=allowed){if(Object.keys(v).some((k)=>!allowed.includes(k))||required.some((k)=>!Object.hasOwn(v,k)))fail2("Invalid Airtable input")}function text3(v){return typeof v==="string"&&v.length>0&&v.length<=1024}function fields3(v,nonempty=false){const result2=object3(v);if(nonempty&&!Object.keys(result2).length||Object.keys(result2).some((k)=>!text3(k)))fail2("Invalid Airtable fields");try{return serializable(result2)}catch{return fail2("Invalid Airtable fields")}}function record2(v){const r=object3(v);if(!recordId(r.id)||r.createdTime!==undefined&&(typeof r.createdTime!=="string"||!Number.isFinite(Date.parse(r.createdTime))))fail2("Malformed Airtable record");return{id:r.id,...r.createdTime===undefined?{}:{createdTime:r.createdTime},fields:fields3(r.fields)}}function equal(a,b){if(a===b)return true;if(!a||!b||typeof a!=="object"||typeof b!=="object"||Array.isArray(a)!==Array.isArray(b))return false;const left=Object.keys(a),right=Object.keys(b);return left.length===right.length&&left.every((k)=>Object.hasOwn(b,k)&&equal(a[k],b[k]))}function createConnections(transport){return{async get(){throw new Error("Connection unavailable")},airtable(name){if(typeof name!=="string"||!/^[a-z0-9][a-z0-9-]{0,62}$/.test(name))fail2("Invalid Airtable connection name");const call=(operation2,input)=>transport(name,operation2,input);return{tables:{list:async()=>await call("tables.list",{})},records:{list:async(input)=>await call("records.list",input),get:async(input)=>await call("records.get",input),create:async(input)=>await call("records.create",input),update:async(input)=>await call("records.update",input),delete:async(input)=>await call("records.delete",input)}}}}}async function executeAirtableOperation(authority,operation2,raw,options={}){const{name,baseId,accessToken}=authority;if(!/^[a-z0-9][a-z0-9-]{0,62}$/.test(name)||!/^app[A-Za-z0-9]+$/.test(baseId)||!/^[A-Za-z0-9._~+/-]{1,8192}={0,2}$/.test(accessToken))fail2("Airtable connection unavailable");let input;try{input=object3(serializable(raw))}catch{return fail2("Invalid Airtable input")}const mutation=["records.create","records.update","records.delete"].includes(operation2);const receipt=(ids2)=>({provider:"airtable",connection:`airtable/${name}`,baseId,table:input.table,operation:operation2.slice(8),records:ids2.map((id2)=>({id:id2}))});async function request(path2,init={},write=false){let response;try{response=await(options.fetch??fetch)(`https://api.airtable.com/v0/${path2}`,{...init,headers:{authorization:`Bearer ${accessToken}`,"content-type":"application/json"},redirect:"manual",signal:options.signal?AbortSignal.any([options.signal,AbortSignal.timeout(15000)]):AbortSignal.timeout(15000)})}catch{throw new AirtableOperationError("Airtable request acknowledgment unavailable",write?"uncertain":"unapplied")}if(!response.ok){await response.body?.cancel().catch(()=>{});throw new AirtableOperationError("Airtable request rejected",write&&(response.status>=500||response.status===408||response.status<400)?"uncertain":"unapplied")}try{if(!response.headers.get("content-type")?.toLowerCase().includes("application/json"))throw new Error;const value=object3(await response.json());const safe=serializable(value);if(Object.hasOwn(value,"error")||JSON.stringify(safe).includes(accessToken))throw new Error;return value}catch{throw new AirtableOperationError("Malformed Airtable acknowledgment",write?"uncertain":"unapplied")}}if(operation2==="tables.list"){keys2(input,[]);const tables=[],seen=new Set;let offset;do{const query2=new URLSearchParams(offset?{offset}:{});const page=await request(`meta/bases/${baseId}/tables?${query2}`);if(!Array.isArray(page.tables))fail2("Malformed Airtable tables");for(const value of page.tables){const t=object3(value);if(!tableId(t.id)||!text3(t.name)||!text3(t.primaryFieldId)||!Array.isArray(t.fields)||tables.some((existing)=>existing.id===t.id))fail2("Malformed Airtable table");const metadata=t.fields.map((value2)=>{const f=object3(value2);if(typeof f.id!=="string"||!/^fld[A-Za-z0-9]+$/.test(f.id)||!text3(f.name)||!text3(f.type))fail2("Malformed Airtable field");return{id:f.id,name:f.name,type:f.type,...f.options===undefined?{}:{options:serializable(f.options)}}});if(!metadata.some((f)=>f.id===t.primaryFieldId)||new Set(metadata.map((f)=>f.id)).size!==metadata.length)fail2("Malformed Airtable fields");tables.push({id:t.id,name:t.name,primaryFieldId:t.primaryFieldId,fields:metadata})}offset=nextOffset(page.offset,seen)}while(offset);return tables}if(!text3(input.table)||input.table==="."||input.table==="..")fail2("Invalid Airtable table");if(mutation&&!tableId(input.table))fail2("Airtable writes require a stable table ID");const path=`${baseId}/${encodeURIComponent(input.table)}`;if(operation2==="records.get"){keys2(input,["table","id"]);if(!recordId(input.id))fail2("Invalid Airtable record ID");const result3=record2(await request(`${path}/${input.id}`));if(result3.id!==input.id)fail2("Malformed Airtable record");return result3}if(operation2==="records.list"){keys2(input,["table","fields"],["table"]);if(input.fields!==undefined&&(!Array.isArray(input.fields)||!input.fields.length||input.fields.some((f)=>!text3(f))||new Set(input.fields).size!==input.fields.length))fail2("Invalid Airtable field selection");const records2=[],ids2=new Set,seen=new Set;let offset;do{const query2=new URLSearchParams;for(const field of input.fields??[])query2.append("fields[]",field);if(offset)query2.set("offset",offset);const page=await request(`${path}?${query2}`);if(!Array.isArray(page.records))fail2("Malformed Airtable records");for(const value of page.records){const r=record2(value);if(ids2.has(r.id))fail2("Malformed Airtable pagination");ids2.add(r.id);records2.push(r)}offset=nextOffset(page.offset,seen)}while(offset);return records2}if(!mutation)fail2("Unsupported Airtable operation");keys2(input,["table","records"]);if(!Array.isArray(input.records)||!input.records.length||input.records.length>10)fail2("Invalid Airtable batch");const kind=operation2.slice(8),ids=new Set;const records=input.records.map((value)=>{const r=object3(value);keys2(r,kind==="create"?["fields"]:kind==="update"?["id","expected","set"]:["id","expected"]);if(kind==="create")return{fields:fields3(r.fields,true)};if(!recordId(r.id)||ids.has(r.id))fail2("Invalid Airtable batch record ID");ids.add(r.id);const set=kind==="update"?fields3(r.set,true):undefined;if(set&&Object.values(set).some((value2)=>value2===null))fail2("Airtable guard null cannot be an update value");return{id:r.id,expected:fields3(r.expected),...set?{set}:{}}});for(const r of records){if(!("id"in r))continue;const current=record2(await request(`${path}/${r.id}`));if(current.id!==r.id)fail2("Malformed Airtable record");for(const[key,value]of Object.entries(r.expected)){if(value===null?Object.hasOwn(current.fields,key):!Object.hasOwn(current.fields,key)||!equal(current.fields[key],value))fail2("Airtable reviewed values are stale")}}await options.beforeMutation?.();const query=new URLSearchParams;if(kind==="delete")for(const id2 of ids)query.append("records[]",id2);const result2=await request(`${path}${kind==="delete"?`?${query}`:""}`,{method:kind==="create"?"POST":kind==="update"?"PATCH":"DELETE",...kind==="delete"?{}:{body:JSON.stringify({records:records.map((r)=>("id"in r)?{id:r.id,fields:r.set}:r)})}},true);const acknowledged=[],returned=[];try{if(!Array.isArray(result2.records))throw new Error;for(const value of result2.records){const r=object3(value);if(!recordId(r.id)||acknowledged.includes(r.id)||kind!=="create"&&!ids.has(r.id)||kind==="delete"&&r.deleted!==true)throw new Error;acknowledged.push(r.id);if(kind!=="delete")returned.push(record2(r))}if(acknowledged.length!==records.length)throw new Error}catch{throw new AirtableOperationError("Incomplete Airtable mutation acknowledgment",acknowledged.length?"partial":"uncertain",acknowledged.length?[receipt(acknowledged)]:[])}return{receipt:receipt(acknowledged),...kind==="delete"?{}:{records:returned}}}function nextOffset(value,seen){if(value===undefined)return;if(!text3(value)||seen.has(value))fail2("Malformed Airtable pagination");seen.add(value);return value}var MANAGED_CONNECTION_CAPABILITY_ENV="OS_MANAGED_CONNECTION_CAPABILITY";function managedConnections(capability){const endpoint=new URL(capability.endpoint);if(endpoint.protocol!=="http:"||endpoint.hostname!=="127.0.0.1"||!endpoint.port||endpoint.pathname!=="/"||endpoint.search||endpoint.hash||endpoint.username||endpoint.password||!/^[0-9a-f-]{36}$/.test(capability.token))throw new AirtableOperationError("Airtable capability unavailable");const transport=async(name,operation2,input)=>{let safeInput;try{safeInput=serializable(input)}catch{safeInput=null}try{const response=await fetch(new URL("airtable",endpoint),{method:"POST",redirect:"error",headers:{authorization:`Bearer ${capability.token}`,"content-type":"application/json"},body:JSON.stringify({name,operation:operation2,input:safeInput}),signal:AbortSignal.timeout(125000)});const value=await response.json();if(!response.ok)throw new AirtableOperationError("Airtable operation failed; the execution retains its evidence",value.effect==="partial"||value.effect==="uncertain"?value.effect:"unapplied",value.receipts??[]);return value}catch(error){if(error instanceof AirtableOperationError)throw error;throw new AirtableOperationError("Airtable parent acknowledgment unavailable",["records.create","records.update","records.delete"].includes(operation2)?"uncertain":"unapplied")}};return createConnections(transport)}var observer;function observeLocalRoutineEffects(value){observer=value}async function reportLocalRoutineEffect(value){await observer?.(value)}var identityPattern=/^(gmail|airtable|dropbox|outlook|sharepoint)\/([a-z0-9][a-z0-9-]{0,62})$/;var workspacePattern=/^[a-z0-9][a-z0-9-]{0,62}$/;var providerNames={gmail:"Gmail",airtable:"Airtable",dropbox:"Dropbox",outlook:"Outlook",sharepoint:"SharePoint"};function parseConnectionFailureDetail(value){if(!value||typeof value!=="object"||Array.isArray(value))throw new Error("Invalid Connection failure");const detail=value;if(!["identity","identity,workspace"].includes(Object.keys(detail).sort().join(","))||typeof detail.identity!=="string"||!identityPattern.test(detail.identity)||detail.workspace!==undefined&&(typeof detail.workspace!=="string"||!workspacePattern.test(detail.workspace)))throw new Error("Invalid Connection failure");return{identity:detail.identity,...detail.workspace===undefined?{}:{workspace:detail.workspace}}}function connectionFailureMessage(value){const detail=parseConnectionFailureDetail(value);const[,provider,name]=identityPattern.exec(detail.identity);const first=`Couldn’t use ${providerNames[provider]??provider} connection ${name}.`;return detail.workspace?`${first}
|
|
36
|
+
Check the file’s stored media type before retrying. The model was not called.`}switch(code){case"access_denied":return"This routine doesn’t currently have permission to use AI.";case"capability_unavailable":return"AI is unavailable in this execution environment.";case"invalid_input":return"The AI request is invalid. Check its input, instructions and schema.";case"unsupported_file":return"AI couldn’t read this file in the requested format.";case"file_unavailable":return"AI couldn’t read or verify the file.";case"input_too_large":return"The AI input exceeds the size limit for this execution path.";case"output_too_large":return"The AI response exceeds the size limit for this execution path.";case"provider_failure":return"AI couldn’t complete the request. No more specific reason was recorded.";case"invalid_output":return"AI returned an answer OS could not accept.";case"cancelled":return"The AI operation was stopped before it completed."}}var ROUTINE_AI_VALUE_BYTES=256*1024;var ROUTINE_AI_RESULT_BYTES=6*ROUTINE_AI_VALUE_BYTES+1024;var ROUTINE_AI_EVIDENCE_BYTES=4*1024;var ROUTINE_AI_ERROR_CODES=["access_denied","capability_unavailable","invalid_input","unsupported_file","file_unavailable","input_too_large","output_too_large","provider_failure","invalid_output","cancelled"];class AIError extends Error{code;detail;constructor(code,options={}){const detail=parseRoutineAIErrorDetail(code,options.detail);super(routineAIErrorMessage(code,detail));this.code=code;this.name="AIError";if(detail)this.detail=Object.freeze(detail);if(code==="invalid_output"&&typeof options.text==="string"&&new TextEncoder().encode(options.text).byteLength<=ROUTINE_AI_VALUE_BYTES)Object.defineProperty(this,"text",{value:options.text})}}function parseRoutineAIError(value){try{const v=capture(value,"invalid_output","output_too_large",ROUTINE_AI_RESULT_BYTES);assertRoutineFields(v,["code","detail","text"]);if(!ROUTINE_AI_ERROR_CODES.includes(v.code))throw new Error;const detail=parseRoutineAIErrorDetail(v.code,v.detail);if(Object.hasOwn(v,"detail")&&!detail||Object.hasOwn(v,"text")&&(typeof v.text!=="string"||new TextEncoder().encode(v.text).byteLength>ROUTINE_AI_VALUE_BYTES)||v.code!=="invalid_output"&&Object.hasOwn(v,"text"))throw new Error;return new AIError(v.code,{detail,...v.text===undefined?{}:{text:v.text}})}catch{throw new AIError("invalid_output")}}function capture(value,invalid3,oversized,limit=ROUTINE_AI_VALUE_BYTES){try{assertRoutineJson(value);const encoded=JSON.stringify(value);if(new TextEncoder().encode(encoded).byteLength>limit)throw new AIError(oversized);return freezeRoutineMetadata(JSON.parse(encoded))}catch(error){if(error instanceof AIError)throw error;throw new AIError(invalid3)}}function parseRoutineAIRequest(value){const v=capture(value,"invalid_input","input_too_large");try{assertRoutineFields(v,v.kind==="generateObject"?["kind","instructions","input","schema","tools"]:["kind","instructions","input","tools"]);if(!["generateText","generateObject"].includes(v.kind)||typeof v.instructions!=="string"||!v.instructions.trim())throw new Error;const input=typeof v.input==="string"?v.input:parseFileDescriptor(v.input);if(Object.hasOwn(v,"tools")&&typeof v.tools!=="boolean")throw new AIError("invalid_input",{detail:{reason:"invalid_tools"}});if(v.tools===true&&typeof input==="string")throw new AIError("invalid_input",{detail:{reason:"tools_require_file"}});const tools=v.tools===true?{tools:true}:{};if(v.kind==="generateText")return freezeRoutineMetadata({kind:v.kind,instructions:v.instructions,input,...tools});const schema=parseAppRoutineContract({routine:"ai",input:v.schema,steps:[{id:"generate"}]}).input;return freezeRoutineMetadata({kind:v.kind,instructions:v.instructions,input,schema,...tools})}catch(error){if(error instanceof AIError)throw error;throw new AIError("invalid_input")}}function parseRoutineAIResult(request,value){let v;try{v=capture(value,"invalid_output","output_too_large",request.kind==="generateText"?ROUTINE_AI_RESULT_BYTES:ROUTINE_AI_VALUE_BYTES);assertRoutineFields(v,request.kind==="generateText"?["text"]:["object"]);if(request.kind==="generateText"){if(typeof v.text!=="string")throw new Error;return acceptText(request,v.text)}if(!Object.hasOwn(v,"object"))throw new Error}catch(error){if(error instanceof AIError)throw error;throw new AIError("invalid_output",{detail:{reason:"invalid_response"}})}validateObject(request.schema,v.object);return freezeRoutineMetadata({object:v.object})}function validateObject(schema,object3,text2){let detail={reason:"invalid_response"};try{validateRoutineSchemaValue(schema,object3,(issue)=>{detail=issue})}catch{throw new AIError("invalid_output",{...text2===undefined?{}:{text:text2},detail})}}function acceptText(request,text2){if(new TextEncoder().encode(text2).byteLength>ROUTINE_AI_VALUE_BYTES)throw new AIError("output_too_large");if(request.kind==="generateText"){if(!text2.trim())throw new AIError("invalid_output",{text:text2,detail:{reason:"empty_text"}});return freezeRoutineMetadata({text:text2})}let object3;const trimmed=text2.trim();const fenced=/^(`{3,}|~{3,})(?:json)?[ \t]*\r?\n([\s\S]*?)\r?\n\1[ \t]*$/i.exec(trimmed);try{object3=JSON.parse(fenced?fenced[2]:text2)}catch{throw new AIError("invalid_output",{text:text2,detail:{reason:"invalid_json"}})}validateObject(request.schema,object3,text2);return capture({object:object3},"invalid_output","output_too_large")}var LIMIT=256*1024;var invalid3=()=>{throw new AppRoutineContractError("invalid_value")};var invalidContract3=()=>{throw new AppRoutineContractError("invalid_contract")};var empty={type:"object",properties:{},required:[],additionalProperties:false};function captureJson(value,maximum=LIMIT){assertRoutineJson(value);const encoded=JSON.stringify(value);if(maximum!==null&&new TextEncoder().encode(encoded).byteLength>maximum)return invalid3();return freezeRoutineMetadata(JSON.parse(encoded))}function capture2(schema,value){const captured=captureJson(value);validateRoutineSchemaValue(schema,captured);return captured}var schemas=new WeakMap;function nestedSchema(value){const metadata=schemaMetadata(value);if(Object.hasOwn(metadata,"default"))return invalidContract3();return metadata.schema}function schemaMetadata(value){if(!value||typeof value!=="object")return invalidContract3();const registered=schemas.get(value);if(registered)return registered;try{assertRoutineJson(value)}catch{return invalidContract3()}return{schema:parseAppRoutineContract({routine:"definition",input:value,steps:[{id:"inspect"}]}).input}}function declaration(value,defaults){try{assertRoutineJson(value)}catch{return invalidContract3()}const parsed=freezeRoutineMetadata(parseAppRoutineContract({routine:"definition",input:value,steps:[{id:"inspect"}]}).input);const captured=defaults?capture2(parsed,defaults.value):undefined;const builder=Object.defineProperty({...parsed},"default",{value:(value2)=>declaration(parsed,{value:value2})});schemas.set(builder,{schema:parsed,...defaults?{default:captured}:{}});return Object.freeze(builder)}var schema={object(properties){return declaration({type:"object",properties:Object.fromEntries(Object.entries(properties).map(([key,value])=>[key,nestedSchema(value)])),required:Object.keys(properties),additionalProperties:false})},array(items,options={}){assertRoutineFields(options,["maxItems"]);return declaration({type:"array",items:nestedSchema(items),...options})},string(options={}){return declaration({type:"string",...options})},integer(options={}){return declaration({type:"integer",...options})},number(options={}){return declaration({type:"number",...options})},boolean(){return declaration({type:"boolean"})}};var file=(options={})=>{assertRoutineFields(options,["storage","path"]);return declaration({type:"file",...options})};var definitions=new WeakMap;var defineRoutine=(definition)=>{assertRoutineFields(definition,["id","title","input","steps","result","access","responses","run"]);if(!isAppRoutineName(definition.id)||definition.title!==undefined&&!routineTitle(definition.title)||typeof definition.run!=="function")return invalidContract3();const input=definition.input===undefined?{schema:empty,default:{}}:schemaMetadata(definition.input);const result=definition.result===undefined?undefined:schemaMetadata(definition.result).schema;const access=parseRoutineAccess(definition.access);assertRoutineFields(definition.steps??{});const executable=Object.fromEntries(Object.entries(definition.steps??{}).map(([id2,step])=>{assertRoutineFields(step,["title","run"]);if(!routineTitle(step.title)||typeof step.run!=="function")return invalidContract3();return[id2,Object.freeze({title:step.title,run:step.run})]}));const steps=Object.entries(executable).map(([id2,step])=>({id:id2,title:step.title}));parseAppRoutineContract({routine:definition.id,input:input.schema,steps:steps.length?steps.map(({id:id2})=>({id:id2})):[{id:"inspect"}],...result?{result}:{}});const responses=[];const ids=new Set;if(definition.responses!==undefined){if(!Array.isArray(definition.responses)||definition.responses.length>64||Reflect.ownKeys(definition.responses).length!==definition.responses.length+1)return invalidContract3();for(let index=0;index<definition.responses.length;index++){const descriptor=Object.getOwnPropertyDescriptor(definition.responses,String(index));if(!descriptor||!Object.hasOwn(descriptor,"value"))return invalidContract3();const response=descriptor.value;assertRoutineFields(response,["id","results","run"]);if(!isAppRoutineName(response.id)||ids.has(response.id))return invalidContract3();ids.add(response.id);if(response.results!==undefined){try{assertRoutineJson(response.results)}catch{return invalidContract3()}}try{responses.push(defineHandler(response))}catch{return invalidContract3()}}}const contract=freezeRoutineMetadata({id:definition.id,...definition.title===undefined?{}:{title:definition.title},input:input.schema,...Object.hasOwn(input,"default")?{inputDefault:input.default}:{},access,responses:responses.map(({id:id2})=>({id:id2})),steps,...result?{result}:{}});const captured=Object.freeze({...definition,access,steps:Object.freeze(executable),responses:Object.freeze(responses),...definition.input===undefined?{}:{input:declaration(input.schema,Object.hasOwn(input,"default")?{value:input.default}:undefined)},...result===undefined?{}:{result:declaration(result)},run:(input2,os)=>executeRoutineDefinition(captured,input2,os)});definitions.set(captured,{contract,steps:executable,run:definition.run});return captured};function inspectRoutineDefinition(definition){if(!definition||typeof definition!=="object")return invalidContract3();const registered=definitions.get(definition);if(!registered)return invalidContract3();return registered.contract}function captureRoutineInput(definition,input){const contract=inspectRoutineDefinition(definition);return capture2(contract.input,input===undefined&&Object.hasOwn(contract,"inputDefault")?contract.inputDefault:input)}async function executeRoutineDefinition(definition,input,runtime){const captured=captureRoutineInput(definition,input);const{contract,steps,run}=definitions.get(definition);let active=true,accepting=true,broken=false;let work=Promise.resolve();const aiWork=new Set;const generate=(kind,value)=>{const operation=(async()=>{if(!active||broken||contract.access.ai!==true)throw new AIError("access_denied");if(!runtime.ai)throw new AIError("capability_unavailable");let request;try{assertRoutineFields(value,kind==="generateObject"?["instructions","input","schema","tools"]:["instructions","input","tools"]);request=parseRoutineAIRequest({kind,instructions:value.instructions,input:value.input,...kind==="generateObject"?{schema:schemaMetadata(value.schema).schema}:{},...value.tools===undefined?{}:{tools:value.tools}})}catch(error){if(error instanceof AIError)throw error;throw new AIError("invalid_input")}const result2=await runtime.ai[kind](request);if(!active||broken)throw new AIError("access_denied");return parseRoutineAIResult(request,result2)})();aiWork.add(operation);operation.then(()=>aiWork.delete(operation),()=>aiWork.delete(operation));return operation};const called=new Set;const reached=new Set;const guarded=(value,receiver)=>typeof value==="function"?(...args)=>{if(!active||broken)throw new Error("Run authority ended");return guarded(Reflect.apply(value,receiver,args))}:value&&typeof value==="object"&&!(value instanceof Promise)?new Proxy({...value},{get(_target,key){return guarded(Reflect.get(value,key,value),value)}}):value;const validateHandlers=(value)=>{for(const question2 of value.questions??[])if(question2.handler&&!contract.responses.some((handler)=>handler.id===question2.handler.id))return invalid3();return value};let activeStep;const progress=new Map;const os=Object.freeze({...guarded({...runtime,run:freezeRoutineMetadata({id:runtime.run.id,async progress(value){assertRoutineFields(value,["completed","total"]);const{completed,total}=value;const prior=activeStep?progress.get(activeStep):undefined;if(!active||broken||!activeStep||!Number.isSafeInteger(completed)||!Number.isSafeInteger(total)||completed<1||completed>total||prior&&(prior.total!==total||completed<=prior.completed))return invalid3();const accepted=freezeRoutineMetadata({step:activeStep,completed,total});await runtime.run.progress(accepted);progress.set(activeStep,accepted)}}),ai:{generateText:(value)=>generate("generateText",value),generateObject:(value)=>generate("generateObject",value)},connections:{...runtime.connections,get:async(identity)=>{if(!active||broken||!contract.access.connections?.includes(identity))throw new Error("Connection unavailable");const value=await runtime.connections.get(identity);if(!active||broken)throw new Error("Run authority ended");return value}},inbox:{...runtime.inbox,publishAsk:(value,options)=>runtime.inbox.publishAsk(validateHandlers(value),options)}}),step(id2,...input2){let saved;try{if(!active||!accepting||broken||!Object.hasOwn(steps,id2)||called.has(id2)||input2.length>1)return invalid3();if(input2.length)saved=captureJson(input2[0],null);called.add(id2)}catch(error){broken=true;return Promise.reject(error)}const next=work.then(async()=>{if(broken)return invalid3();reached.add(id2);try{await runtime.step(id2,{status:"running"});activeStep=id2;const output=await steps[id2].run(saved,os);assertRoutineFields(output,["summary","data"]);if(!Object.hasOwn(output,"summary")||!Object.hasOwn(output,"data"))return invalid3();const summary=captureJson(output.summary),data=captureJson(output.data);await runtime.step(id2,{status:"completed",summary,data});activeStep=undefined;return freezeRoutineMetadata({summary,data})}catch(error){broken=true;activeStep=undefined;await runtime.step(id2,{status:"failed"});throw error}});work=next.then(()=>{},()=>{broken=true});return next}});let result,failure;try{result=await run(captured,os)}catch(error){failure=error;broken=true}accepting=false;await work;while(aiWork.size)await Promise.allSettled([...aiWork]);active=false;for(const step of contract.steps)if(!reached.has(step.id))await runtime.step(step.id,{status:"skipped"});if(broken)throw failure??new AppRoutineContractError("invalid_value");if(contract.result!==undefined)return capture2(contract.result,result);if(result!==undefined)return invalid3();return}var RECORD_READ_INPUT_LIMIT=1024*1024;var RECORD_CAPTURE_OUTPUT_LIMIT=25*1024*1024;function validRecordRef(value){return typeof value==="string"&&value.length<=512&&/^[_a-zA-Z0-9][a-zA-Z0-9_-]*(\/[_a-zA-Z0-9][a-zA-Z0-9_-]*)+$/.test(value)}var fieldProblems=["unknown","missing","invalid","source_schema"];var reasons={unknown:"unknown_field",missing:"missing_field",invalid:"invalid_value",source_schema:"source_schema_mismatch"};var expectationKinds={string:"a string",integer:"a safe integer",number:"a finite number",boolean:"a boolean",date:"a date in YYYY-MM-DD format",const:"the constant declared in the schema",enum:"one of the choices declared in the schema",link:"a link to an existing record of an allowed type",object:"an object matching the schema",map:"a map matching the schema"};function expectationText(expected){if(!Object.hasOwn(expectationKinds,expected.type)||typeof expected.many!=="boolean"||typeof expected.nullable!=="boolean"||expected.decimalPlaces!==undefined&&(expected.type!=="number"||!Number.isInteger(expected.decimalPlaces)||expected.decimalPlaces<0||expected.decimalPlaces>6)||expected.format!==undefined&&(expected.type!=="date"||expected.format!=="month"))return;const scalar=expected.type==="number"&&expected.decimalPlaces!==undefined?`a finite number with at most ${expected.decimalPlaces} decimal places`:expected.type==="date"&&expected.format==="month"?"a date in YYYY-MM format":expectationKinds[expected.type];return`${expected.many?"Expected a list. Each item must be":"Expected"} ${scalar}.${expected.nullable?" The field may also be null.":""}`}function parseExpectation(text2){if(!text2)return;const parts=/^Expected (a list\. Each item must be )?(.+?)\.( The field may also be null\.)?$/.exec(text2);if(!parts)return;const number=/^a finite number with at most ([0-6]) decimal places$/.exec(parts[2]);const month=parts[2]==="a date in YYYY-MM format";const kind=number?"number":month?"date":Object.keys(expectationKinds).find((kind2)=>expectationKinds[kind2]===parts[2]);if(!kind)return;const expected={type:kind,many:!!parts[1],nullable:!!parts[3],...number?{decimalPlaces:Number(number[1])}:{},...month?{format:"month"}:{}};return expectationText(expected)===text2?expected:undefined}function parseDataValidationDetail(value){if(!value||typeof value!=="object"||Array.isArray(value))return;const v=value;if(Object.keys(v).some((key)=>!["record","field","reason","schemaFile","expected"].includes(key))||typeof v.record!=="string"||typeof v.field!=="string")return;const problem=fieldProblems.find((problem2)=>reasons[problem2]===v.reason);if(!problem||v.schemaFile!==undefined&&typeof v.schemaFile!=="string")return;let expected;if(Object.hasOwn(v,"expected")){if(!v.expected||typeof v.expected!=="object"||Array.isArray(v.expected))return;const e=v.expected;if(Object.keys(e).some((key)=>!["type","many","nullable","decimalPlaces","format"].includes(key)))return;expected={...e};if(!expectationText(expected))return}if(problem==="unknown"&&expected||problem==="source_schema"&&(v.field!=="media_type"||expected?.type!=="string"||expected.many||expected.nullable))return;if(!recordFieldMessage(v.record,v.field,problem,v.schemaFile,expected))return;return{record:v.record,field:v.field,reason:reasons[problem],...typeof v.schemaFile==="string"?{schemaFile:v.schemaFile}:{},...expected?{expected}:{}}}function recordFieldMessage(record2,field,problem,schemaPath,expected){if(!validRecordRef(record2)||!/^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/.test(field))return;if(schemaPath!==undefined&&(schemaPath.length>256||!/^[a-zA-Z0-9_.-]+(?:\/[a-zA-Z0-9_.-]+)*\/_schema\.yaml$/.test(schemaPath)||schemaPath.split("/").some((part)=>[".","..",".git","routines"].includes(part))))return;const prefix=`Record "${record2}" isn't valid.`;const schema2=schemaPath?`"${schemaPath}"`:"the collection schema";if(problem==="source_schema")return field==="media_type"?`${prefix} This repository's Source schema${schemaPath?` ${schema2}`:""} doesn't include "media_type". The OS SDK uses "media_type" for file Sources. Update the Source schema in this repository to include this field.`:undefined;if(problem==="unknown")return`${prefix} The record contains "${field}", but ${schema2} doesn't define that field. Check that the record and ${schemaPath?"that file":"the collection schema"} use the same field name.`;if(problem==="missing")return`${prefix} The record is missing required field "${field}". Add it as defined in ${schema2}.`;const expectation=expected?expectationText(expected):undefined;if(expected&&!expectation)return;return`${prefix} The record has an invalid value for field "${field}".${expectation?` ${expectation}`:""} Check its definition in ${schema2}.`}function safeRecordFieldMessage(value){if(typeof value!=="string"||value.length>1200)return;const parts=/^Record "([^"]+)" isn't valid\. (.+)$/.exec(value);if(!parts)return;const schemaPath=/"([^"]+\/_schema\.yaml)"/.exec(value)?.[1];const field=[...parts[2].matchAll(/"([^"]+)"/g)].map((match)=>match[1]).find((part)=>part!==schemaPath);if(!field)return;const expected=parseExpectation(/\. (Expected .+) Check its definition in /.exec(value)?.[1]);return fieldProblems.map((problem)=>recordFieldMessage(parts[1],field,problem,schemaPath,expected)).find((message)=>message===value)}function dataValidationMessageFacts(error){if(error.code==="invalid_change"){const detail=parseDataValidationDetail(error.detail);if(detail){const problem=fieldProblems.find((problem2)=>reasons[problem2]===detail.reason);return{detail,message:recordFieldMessage(detail.record,detail.field,problem,detail.schemaFile,detail.expected)}}}const message=error.code==="invalid_change"?safeRecordFieldMessage(error.message):undefined;return message?{message}:{}}function explainDataValidation(error,message,detail){Object.assign(error,dataValidationMessageFacts({code:error.code,message:typeof message==="string"?message:"",detail}));return error}var localDataPath=(value,repository)=>typeof value==="string"&&value.length<=1024&&value.startsWith(`${repository}/`)&&!value.includes("\\")&&!/[\x00-\x1f\x7f]/.test(value)&&value.split("/").every((part)=>!!part&&part!=="."&&part!=="..");var localDataFile=(value,repository)=>{if(!value||typeof value!=="object"||Array.isArray(value))return false;const row=value;return Object.keys(row).sort().join(",")==="action,path"&&["created","updated","deleted"].includes(String(row.action))&&localDataPath(row.path,repository)};function parseDataFailureDetail(value){const invalid4=()=>{throw new Error("Invalid local Data failure detail")};if(!value||typeof value!=="object"||Array.isArray(value))return invalid4();const row=value;if(Object.keys(row).sort().join(",")!=="cause,code,files,nextAction,operation,repository"||!["local_data_read_failed","local_data_write_failed","local_data_write_partial"].includes(String(row.code))||!["read","write"].includes(String(row.operation))||typeof row.repository!=="string"||!/^[a-z0-9][a-z0-9._/-]{0,127}$/.test(row.repository)||row.repository.includes("//")||row.repository.includes("..")||!["fix_failed_file_then_rerun","review_resolve_then_rerun"].includes(String(row.nextAction)))return invalid4();const repository=row.repository;if(!row.cause||typeof row.cause!=="object"||Array.isArray(row.cause))return invalid4();const cause=row.cause;if(!["code,message","code,message,path"].includes(Object.keys(cause).sort().join(","))||!["schema_validation_failed","invalid_record","unsafe_record","stale_record","path_conflict","filesystem_unavailable"].includes(String(cause.code))||typeof cause.message!=="string"||!cause.message||cause.message.length>512||/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/.test(cause.message)||cause.path!==undefined&&!localDataPath(cause.path,repository))return invalid4();if(!row.files||typeof row.files!=="object"||Array.isArray(row.files))return invalid4();const files=row.files;if(Object.keys(files).some((key)=>!["state","saved","failed","notAttempted","savedOmitted","notAttemptedOmitted"].includes(key))||!["none","partial"].includes(String(files.state))||!Array.isArray(files.saved)||files.saved.length>128||!files.saved.every((item)=>localDataFile(item,repository))||files.failed!==undefined&&!localDataFile(files.failed,repository)||!Array.isArray(files.notAttempted)||files.notAttempted.length>128||!files.notAttempted.every((item)=>localDataFile(item,repository)))return invalid4();for(const key of["savedOmitted","notAttemptedOmitted"])if(files[key]!==undefined&&(!Number.isSafeInteger(files[key])||Number(files[key])<1||Number(files[key])>1e4))return invalid4();if(row.operation==="read"&&(row.code!=="local_data_read_failed"||files.state!=="none"||files.saved.length||files.failed!==undefined||files.notAttempted.length)||row.operation==="write"&&row.code==="local_data_read_failed"||row.code==="local_data_write_partial"&&(files.state!=="partial"||!files.saved.length)||row.code!=="local_data_write_partial"&&files.state==="partial")return invalid4();return structuredClone(value)}function parseDataOperationDetail(value){const validation=parseDataValidationDetail(value);if(validation)return validation;if(value&&typeof value==="object"&&!Array.isArray(value)&&value.code==="record_limit_exceeded"){const row=value;if(Object.keys(row).sort().join(",")!=="code,collections,maxRecords"||!Number.isSafeInteger(row.maxRecords)||Number(row.maxRecords)<1||!Array.isArray(row.collections)||!row.collections.length||row.collections.length>16||!row.collections.every((name)=>typeof name==="string"&&name.length<=512&&/^[_a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(name))||new Set(row.collections).size!==row.collections.length)throw new Error("Invalid Data operation detail");return structuredClone(value)}return parseDataFailureDetail(value)}function dataRecordLimitMessage(detail){const scope=detail.collections.length===1?` from ${detail.collections[0]}`:` across ${detail.collections.join(", ")}`;return`The routine tried to load more than ${detail.maxRecords.toLocaleString("en-US")} matching Records${scope}. `+"Narrow the query or increase maxRecords."}class DataOperationError extends Error{code;retryable;effect;component;detail;constructor(code,retryable=false,effect,component,detail){const parsed=detail===undefined?undefined:parseDataOperationDetail(detail);if(parsed&&("reason"in parsed?code!=="invalid_change":parsed.code==="record_limit_exceeded"&&code!=="capacity"))throw new Error("Invalid Data operation detail");super(code==="capacity"&&parsed&&"code"in parsed&&parsed.code==="record_limit_exceeded"?dataRecordLimitMessage(parsed):`Data operation failed: ${code}`);this.code=code;this.retryable=retryable;this.effect=effect;this.component=component;this.detail=detail;this.name="DataOperationError";if(parsed!==undefined)this.detail=parsed}}var invalid4=()=>{throw new DataOperationError("invalid_query")};var historyText=(value)=>typeof value==="string"&&!/[\u0000\uD800-\uDFFF]/u.test(value);function historyVersion(value){return historyText(value)&&value.length>0&&new TextEncoder().encode(value).length<=1024&&!/[\u0000-\u001f\u007f-\u009f]/.test(value)&&!/^[0-9a-f]{40}$/i.test(value)}function historyProperties(value){if(!value||typeof value!=="object"||Array.isArray(value)||![Object.prototype,null].includes(Object.getPrototypeOf(value)))return invalid4();const descriptors=Object.getOwnPropertyDescriptors(value);if(Reflect.ownKeys(value).some((key)=>typeof key!=="string"||!descriptors[key]?.enumerable||!Object.hasOwn(descriptors[key],"value")))return invalid4();return descriptors}var historyCollection=(value)=>typeof value==="string"&&value.length<=512&&/^[_a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value);var historyCursor=(value)=>typeof value==="string"&&value.length<=128*1024&&/^history-cursor-v1\.[A-Za-z0-9_-]{1,64}\.[A-Za-z0-9_-]{16}\.[A-Za-z0-9_-]+$/.test(value);function historyArray(value){if(!Array.isArray(value)||Object.getPrototypeOf(value)!==Array.prototype)return invalid4();const descriptors=Object.getOwnPropertyDescriptors(value);if(Reflect.ownKeys(value).length!==value.length+1)return invalid4();const result=[];for(let i=0;i<value.length;i++){const descriptor=descriptors[i];if(!descriptor?.enumerable||!Object.hasOwn(descriptor,"value"))return invalid4();result.push(descriptor.value)}return result}function captureOptions(value,changes){if(value===undefined)return{};const descriptors=historyProperties(value),result={};const allowed=changes?["collections","refs","from","through","limit","after"]:["limit","before"];if(Object.keys(descriptors).some((key)=>!allowed.includes(key)))return invalid4();for(const key of allowed){if(!Object.hasOwn(descriptors,key))continue;const scalar=descriptors[key].value;if(key==="collections"||key==="refs"){const values=historyArray(scalar);if(!values.length||values.length>(key==="collections"?16:100)||!values.every(key==="collections"?historyCollection:validRecordRef)||new Set(values).size!==values.length)return invalid4();result[key]=values}else if(key==="limit"){if(!Number.isInteger(scalar)||scalar<1||scalar>(changes?500:100))return invalid4();result.limit=scalar}else{if(!(key==="after"?historyCursor(scalar):historyVersion(scalar)))return invalid4();result[key]=scalar}}return result}var captureHistoryListOptions=(value)=>captureOptions(value,false);var captureHistoryChangesOptions=(value)=>captureOptions(value,true);function captureHistoryInstant(value){if(!historyText(value)||value.length>1024)return invalid4();const match=/^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2}):(\d{2})(?:\.\d+)?([Zz]|([+-])(\d{2}):(\d{2}))$/.exec(value);if(!match)return invalid4();const[year,month,day,hour,minute,second]=match.slice(1,7).map(Number);const days=new Date(Date.UTC(year,month,0));days.setUTCFullYear(year);if(year<1||month<1||month>12||day<1||day>days.getUTCDate()||hour>23||minute>59||second>59||Number(match[9]??0)>23||Number(match[10]??0)>59)return invalid4();return value}var invalid5=()=>{throw new DataOperationError("invalid_query")};function captureRecordsSearchInput(query,options){if(!historyText(query))return invalid5();const length=[...query.trim()].length;if(length<1||length>256)return invalid5();if(options===undefined)return{query};const descriptors=historyProperties(options);if(Object.keys(descriptors).some((key)=>!["collections","limit"].includes(key)))return invalid5();const captured={};if(Object.hasOwn(descriptors,"collections")){const supplied=descriptors.collections.value;if(!Array.isArray(supplied)||supplied.length<1||supplied.length>16||Reflect.ownKeys(supplied).length!==supplied.length+1)return invalid5();const collections=[];for(let index=0;index<supplied.length;index++){const descriptor=Object.getOwnPropertyDescriptor(supplied,String(index));if(!descriptor?.enumerable||!Object.hasOwn(descriptor,"value")||!historyText(descriptor.value))return invalid5();collections.push(descriptor.value)}if(new Set(collections).size!==collections.length)return invalid5();captured.collections=collections}if(Object.hasOwn(descriptors,"limit")){const supplied=descriptors.limit.value;if(!Number.isInteger(supplied)||supplied<1||supplied>100)return invalid5();captured.limit=supplied}return{query,options:captured}}function captureRecordsReadRefs(value){if(!Array.isArray(value)||value.length<1||value.length>100)throw new DataOperationError("invalid_query");const refs=historyArray(value);if(!refs.every((ref)=>validRecordRef(ref)&&!/[\r\n]/.test(ref))||new Set(refs).size!==refs.length)throw new DataOperationError("invalid_query");return refs}function captureRecordsReadOptions(value){if(value===undefined)return{};let row;try{row=Object.fromEntries(Object.entries(historyProperties(value)).map(([key,descriptor])=>[key,descriptor.value]))}catch{throw new DataOperationError("invalid_query")}if(!value||typeof value!=="object"||Array.isArray(value)||![Object.prototype,null].includes(Object.getPrototypeOf(value))||Reflect.ownKeys(value).some((key)=>key!=="body"||!Object.hasOwn(Object.getOwnPropertyDescriptor(value,key),"value"))||Object.hasOwn(row,"body")&&typeof row.body!=="boolean")throw new DataOperationError("invalid_query");return Object.hasOwn(row,"body")?{body:row.body}:{}}function validRecordBody(value){return typeof value==="string"&&value===new TextDecoder("utf-8",{ignoreBOM:true}).decode(new TextEncoder().encode(value))}var RECORD_BODY_READ_BYTES=8*1024*1024;var DATA_REQUEST_LIMIT=256*1024;var LOCAL_DATA_CHANGE_REQUEST_LIMIT=32*1024*1024;var invalidChange=()=>{throw new DataOperationError("invalid_change",false,"unapplied")};function mapping(value){try{historyProperties(value);return value}catch{return invalidChange()}}function captureValue(value,ancestors=new Set,depth=0){if(value===null||typeof value==="string"||typeof value==="boolean"||typeof value==="number"&&Number.isFinite(value))return value;if(!value||typeof value!=="object"||ancestors.has(value)||depth>32)return invalidChange();ancestors.add(value);try{if(Array.isArray(value)){if(value.length>1e5||Object.keys(value).length!==value.length||Object.getOwnPropertySymbols(value).length)return invalidChange();return Array.from(value,(item)=>captureValue(item,ancestors,depth+1))}return Object.fromEntries(Object.entries(mapping(value)).map(([key,item])=>{if(["__proto__","constructor","prototype"].includes(key))return invalidChange();return[key,captureValue(item,ancestors,depth+1)]}))}finally{ancestors.delete(value)}}function captureDataDelete(record2){const identity=mapping(record2);if(!validRecordRef(identity.$ref)||typeof identity.$version!=="string"||!identity.$version.length||identity.$version.length>512)return invalidChange();return{ref:identity.$ref,expectedVersion:identity.$version}}function captureDataUpdate(record2,set){const identity=captureDataDelete(record2),input=mapping(set);const{$body,...fields3}=input;const body=Object.hasOwn(input,"$body");if(body&&!validRecordBody($body)||!Object.keys(fields3).length&&!body||Object.keys(fields3).some((key)=>key.startsWith("$")||["id","type"].includes(key)))return invalidChange();return{...identity,set:captureValue(fields3),...body?{body:$body}:{}}}function captureIdentities(value,update,allowEmpty=true){if(!Array.isArray(value)||!allowEmpty&&!value.length||value.length>1e4)return invalidChange();const captured=value.map((item)=>{const row=mapping(item);if(Object.keys(row).filter((key)=>!update||key!=="body").sort().join(",")!==(update?"expectedVersion,ref,set":"expectedVersion,ref"))return invalidChange();const identity={$ref:row.ref,$version:row.expectedVersion};if(update&&Object.keys(mapping(row.set)).some((key)=>key.startsWith("$")))return invalidChange();return update?captureDataUpdate(identity,{...mapping(row.set),...Object.hasOwn(row,"body")?{$body:row.body}:{}}):captureDataDelete(identity)});if(new Set(captured.map((item)=>item.ref)).size!==captured.length)return invalidChange();return captured}function captureDataUpdates(value,allowEmpty=false){return captureIdentities(value,true,allowEmpty)}function captureDataCreate(value){const row=mapping(value);if(!validRecordRef(row.$ref)||Object.keys(row).some((key)=>key.startsWith("$")&&!["$ref","$filing","$body"].includes(key)))return invalidChange();const{$ref:ref,$filing,$body,...fields3}=row;const body=Object.hasOwn(row,"$body");if(body&&!validRecordBody($body))return invalidChange();let filing;if($filing!==undefined){const components=mapping($filing);if(Object.entries(components).some(([name,value2])=>!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)||["constructor","prototype"].includes(name)||typeof value2!=="string"||!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value2)))return invalidChange();filing={...components}}return{ref,fields:captureValue(fields3),...filing?{filing}:{},...body?{body:$body}:{}}}function captureDataChanges(updatesValue,createsValue=[],deletesValue=[]){const updates=captureDataUpdates(updatesValue,true);if(!Array.isArray(createsValue)||createsValue.length>1e4)return invalidChange();const creates=createsValue.map((item)=>{const row=mapping(item);if(Object.keys(row).some((key)=>!["ref","fields","filing","body"].includes(key))||!Object.hasOwn(row,"ref")||!Object.hasOwn(row,"fields"))return invalidChange();const fields3=mapping(row.fields);if(Object.keys(fields3).some((key)=>key.startsWith("$")))return invalidChange();return captureDataCreate({...fields3,$ref:row.ref,...Object.hasOwn(row,"filing")?{$filing:row.filing}:{},...Object.hasOwn(row,"body")?{$body:row.body}:{}})});const deletes=captureIdentities(deletesValue,false);const refs=[...updates,...creates,...deletes].map((item)=>item.ref);if(!refs.length||refs.length>1e4||new Set(refs).size!==refs.length)return invalidChange();return{updates,creates,deletes}}function checkDataRequestSize(input,limit=DATA_REQUEST_LIMIT){if(new TextEncoder().encode(JSON.stringify(input)).byteLength>limit)throw new DataOperationError("request_too_large",false,"unapplied")}function dataTransportError(status,value){const failures={400:["invalid_query","invalid_change"],401:["unauthenticated"],403:["access_denied"],409:["conflict","apply_pending"],413:["request_too_large"],429:["capacity"],503:["unavailable","apply_pending"]};const error=value&&typeof value==="object"&&"error"in value?value.error:undefined;const row=error&&typeof error==="object"?error:undefined;const code=failures[status]?.find((allowed)=>allowed===row?.code)??"unavailable";const effect=["unapplied","uncertain","applied"].includes(String(row?.effect))?row.effect:undefined;let detail;try{detail=row?.detail===undefined?undefined:parseDataOperationDetail(row.detail)}catch{}if(detail&&"reason"in detail&&code!=="invalid_change")detail=undefined;return explainDataValidation(new DataOperationError(code,typeof row?.retryable==="boolean"?row.retryable:["capacity","unavailable","apply_pending"].includes(code),code==="conflict"?"unapplied":effect,code==="invalid_change"&&typeof row?.component==="string"&&/^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/.test(row.component)?row.component:undefined,detail),row?.message,row?.detail)}var AUTH_ORIGIN="https://auth.oddington.ai";function oddingtonOrigin(environment=process.env){const value=environment.OS_ORIGIN??AUTH_ORIGIN;const url=new URL(value);if(url.protocol!=="https:"&&url.hostname!=="127.0.0.1")throw new Error("OS_ORIGIN must use HTTPS");return url.origin}var nodeRequest;var nodeReadable;if(typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__){({request:nodeRequest}=await import("node:http"));({Readable:nodeReadable}=await import("node:stream"))}function privateRoutineRequest(environment=typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__?{}:typeof process==="undefined"?{}:process.env){if(typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__)return;const prepared=["OS_ROUTINE_LOCAL","OS_ROUTINE_LOCAL_SOCKET","OS_ROUTINE_LOCAL_TOKEN"].some((key)=>environment[key]!==undefined);const managed=["OS_FILES_SOCKET","OS_FILES_TOKEN"].some((key)=>environment[key]!==undefined);if(!prepared&&!managed)return;const socket=prepared?environment.OS_ROUTINE_LOCAL_SOCKET:environment.OS_FILES_SOCKET;const token=prepared?environment.OS_ROUTINE_LOCAL_TOKEN:environment.OS_FILES_TOKEN;const request=localRoutineRequest(prepared?environment:{OS_ROUTINE_LOCAL:"1",OS_ROUTINE_LOCAL_SOCKET:socket,OS_ROUTINE_LOCAL_TOKEN:token});const isCurrent=()=>prepared?environment.OS_ROUTINE_LOCAL==="1"&&environment.OS_ROUTINE_LOCAL_SOCKET===socket&&environment.OS_ROUTINE_LOCAL_TOKEN===token:environment.OS_FILES_SOCKET===socket&&environment.OS_FILES_TOKEN===token;if(!nodeRequest||!nodeReadable)throw new Error("Files transport unavailable");const httpRequest=nodeRequest,Readable=nodeReadable;const files=async(suffix,init,signal)=>{if(!isCurrent())throw new FileOperationError("unsupported_context",400);const tcp=/^tcp:\/\/127\.0\.0\.1:([1-9][0-9]{0,4})$/.exec(socket);const endpoint=tcp?{hostname:"127.0.0.1",port:Number(tcp[1])}:{socketPath:socket};const id2=crypto.randomUUID();if(init.body instanceof ReadableStream||suffix===""&&init.method==="POST"){await new Promise((resolve,reject)=>{const check=httpRequest({...endpoint,path:"/files/check-create",method:"POST",timeout:30000,signal,agent:false,headers:{...Object.fromEntries(new Headers(init.headers)),authorization:`Bearer ${token}`,"x-os-files-suffix":encodeURIComponent(suffix),"x-os-files-method":init.method??"GET"}},(response)=>{const bytes=Buffer.alloc(16384);let size=0;response.on("data",(chunk)=>{size+=chunk.length;if(size>16384)response.destroy(new Error("File operation start response exceeded 16 KiB."));else bytes.set(chunk,size-chunk.length)});response.once("error",reject);response.once("end",()=>{if(response.statusCode===204){resolve();return}try{const value=JSON.parse(bytes.subarray(0,size).toString());const code=value?.error?.code;const status=response.statusCode??503;if(["invalid_input","request_too_large","unsupported_context","access_denied","capacity","unavailable"].includes(code))reject(new FileOperationError(code,status,code==="capacity"||code==="unavailable",parseFileErrorDetail(value?.error?.detail)));else reject(new FileOperationError("unavailable",503,true))}catch{reject(new FileOperationError("unavailable",503,true))}})});check.once("error",()=>reject(new FileOperationError("unavailable",503,true)));check.once("timeout",()=>check.destroy(new Error("The file create check did not finish in time.")));check.end()});if(!isCurrent())throw new FileOperationError("unsupported_context",400)}let cancellation;const cancelCall=()=>cancellation??=new Promise((resolve,reject)=>{const cancel=httpRequest({...endpoint,path:"/files/cancel",method:"POST",timeout:30000,headers:{authorization:`Bearer ${token}`,"x-os-files-call":id2}},(response)=>{response.resume();response.once("end",resolve);response.once("error",reject)});cancel.once("error",reject);cancel.once("timeout",()=>cancel.destroy(new Error("Files cancellation stalled")));cancel.end()});let pumping=Promise.resolve();let sourceReader;const result=new Promise((resolve,reject)=>{const call=httpRequest({...endpoint,path:"/files/stream",method:"POST",headers:{...Object.fromEntries(new Headers(init.headers)),authorization:`Bearer ${token}`,"x-os-files-call":id2,"x-os-files-suffix":encodeURIComponent(suffix),"x-os-files-method":init.method??"GET"},signal,timeout:30000,agent:false},async(response)=>{try{call.setTimeout(0);if((response.statusCode??503)>=400){await sourceReader?.cancel().catch(()=>{});call.end()}await pumping;if(!isCurrent()){response.destroy();reject(new FileOperationError("unsupported_context",400));return}const headers=new Headers;for(const[key,value]of Object.entries(response.headers))if(value!==undefined)headers.set(key,Array.isArray(value)?value.join(", "):value);const source=Readable.toWeb(response,{strategy:{highWaterMark:65536,size:(chunk)=>chunk.byteLength}});const reader=source.getReader();if(response.statusCode===204){const timer=setTimeout(()=>response.destroy(new Error("Files completion stalled")),30000);try{if(!(await reader.read()).done)throw new FileOperationError("unavailable",503,true);if(!isCurrent())throw new FileOperationError("unsupported_context",400);resolve(new Response(null,{status:204,headers}))}finally{clearTimeout(timer);reader.releaseLock()}return}let closed=false;const body=new ReadableStream({async pull(controller){let timer;try{if(!isCurrent())throw new FileOperationError("unsupported_context",400);timer=setTimeout(()=>response.destroy(new Error("Files delivery stalled")),30000);const next=await reader.read();if(closed)return;if(next.done){closed=true;reader.releaseLock();controller.close()}else controller.enqueue(next.value)}catch(error){closed=true;controller.error(error);await cancelCall().catch(()=>{});response.socket?.destroy();response.destroy();await reader.cancel(error).catch(()=>{});reader.releaseLock()}finally{clearTimeout(timer)}},async cancel(reason){closed=true;await cancelCall().catch(()=>{});response.socket?.destroy();response.destroy();call.destroy();await reader.cancel(reason).catch(()=>{});reader.releaseLock()}},{highWaterMark:0});resolve(new Response(body,{status:response.statusCode??503,headers}))}catch(error){response.destroy();reject(error instanceof FileOperationError?error:new FileOperationError("unavailable",503,true))}});call.on("error",(error)=>{cancelCall().catch(()=>{});reject(error instanceof FileOperationError?error:new FileOperationError("unavailable",503,true))});call.on("timeout",()=>call.destroy(new Error("Files I/O stalled")));call.on("information",()=>call.setTimeout(30000));if(init.body instanceof ReadableStream){call.flushHeaders();const reader=sourceReader=init.body.getReader();const abort=()=>{reader.cancel(signal.reason).catch(()=>{})};signal.addEventListener("abort",abort,{once:true});call.once("close",abort);pumping=(async()=>{try{for(;;){const next=await reader.read();if(next.done)break;if(!(next.value instanceof Uint8Array))throw new FileOperationError("invalid_input",400);if(!isCurrent())throw new FileOperationError("unsupported_context",400);for(let offset=0;offset<next.value.byteLength;offset+=262144){if(call.destroyed)throw new Error("Files parent disconnected");await new Promise((done,fail2)=>{const closed=()=>fail2(new Error("Files parent disconnected"));call.once("close",closed);call.write(next.value.subarray(offset,offset+262144),(error)=>{call.removeListener("close",closed);error?fail2(error):done()})})}}call.end()}catch(error){call.destroy(error instanceof Error?error:new Error("Files transport failed"))}finally{await reader.cancel().catch(()=>{});signal.removeEventListener("abort",abort);call.removeListener("close",abort);reader.releaseLock()}})()}else call.end(init.body===undefined?undefined:Buffer.from(init.body))});try{return await result}finally{await pumping}};return{request,files,isCurrent,identity:`private:${socket}`}}function localRoutineRequest(environment=typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__?{}:typeof process==="undefined"?{}:process.env){if(typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__){const{OS_ROUTINE_LOCAL:mode,OS_ROUTINE_LOCAL_SOCKET:socket,OS_ROUTINE_LOCAL_TOKEN:token}=environment;if(mode===undefined&&socket===undefined&&token===undefined)return;if(mode!=="1"||!socket||!token||!/^[0-9a-f]{64}$/.test(token))throw new Error("Preparation transport unavailable; nothing can publish");const tcp=/^tcp:\/\/127\.0\.0\.1:([1-9][0-9]{0,4})$/.exec(socket);const endpoint=tcp&&tcp[0]===socket&&Number(tcp[1])<=65535?{hostname:"127.0.0.1",port:Number(tcp[1])}:socket.startsWith("/")&&!socket.startsWith("//")&&!socket.includes("\x00")?{socketPath:socket}:undefined;if(!endpoint)throw new Error("Preparation transport unavailable; nothing can publish");return async(operation,input)=>{const{request}=await import("node:http");return await new Promise((resolve,reject)=>{const call=request({...endpoint,path:`/${operation}`,method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${token}`},timeout:operation==="ai/generate"?125000:120000},(response)=>{const limit=operation==="ai/generate"?ROUTINE_AI_RESULT_BYTES:33554432;const bytes=Buffer.alloc(limit);let size=0;response.on("data",(chunk)=>{size+=chunk.length;if(size>limit){response.destroy();reject(operation==="ai/generate"?new AIError("output_too_large"):new Error("Local result exceeds supported size"))}else bytes.set(chunk,size-chunk.length)});response.on("error",(error)=>reject(operation==="ai/generate"?new AIError("capability_unavailable"):error));response.on("end",()=>{try{const result=JSON.parse(bytes.subarray(0,size).toString());if(response.statusCode!==200){if(operation==="ai/generate")throw parseRoutineAIError(result.error);if(operation==="files/request"){const error=result.error;const status=response.statusCode??503;const codes=["invalid_input","unsupported_context","unauthenticated","access_denied","not_found","request_too_large","conflict","local_only","integrity","unavailable","capacity","method_not_allowed"];if(error?.code&&codes.includes(error.code))throw new FileOperationError(error.code,status,error.code==="capacity"||error.code==="unavailable",parseFileErrorDetail(error.detail));throw new FileOperationError("unavailable",503,true)}if(operation==="data/query"){throw dataTransportError(response.statusCode??0,result)}throw new Error(typeof result.error==="string"?result.error:"Preparation failed")}resolve(result)}catch(error){reject(operation==="ai/generate"&&!(error instanceof AIError)?new AIError("invalid_output"):error)}})});call.on("error",()=>reject(operation==="ai/generate"?new AIError("capability_unavailable"):operation==="data/query"?dataTransportError(503,{error:{code:"unavailable"}}):new Error("Preparation transport unavailable; nothing was published")));call.on("timeout",()=>call.destroy(new Error("Preparation timed out")));call.end(JSON.stringify(input))})}}}var installed;var ended=false;function routineTransport(){if(ended||installed&&!installed.isCurrent())throw new Error("Routine authority ended");return installed}var memberContext;var retainedContext;function installMemberContext(resolve,retained=resolve){memberContext=resolve;retainedContext=retained;return()=>{if(memberContext===resolve){memberContext=undefined;retainedContext=undefined}}}async function resolveAppContext(retained=false){const host=memberContext;if(!host)throw new Error("App context unavailable.");const context=await(retained?retainedContext:host)();if(host!==memberContext||!context.isCurrent()||context.expiresAt<=Date.now()||context.kind!=="local"&&(typeof context.accessToken!=="string"||!/^[^\s]{1,8192}$/.test(context.accessToken))){throw new Error("App context unavailable.")}return context}async function resolveDataContext(){try{if(typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__){const installed2=routineTransport();if(installed2)return{local:installed2.request};const local=localRoutineRequest();if(local)return{local};const managed=privateRoutineRequest();if(managed)return{local:managed.request}}const host=memberContext;if(host!==undefined){const context=await host();if(host!==memberContext||!context.isCurrent()||context.expiresAt<=Date.now())throw new Error;if(context.kind==="local")return{local:context.requestData};if(!context||!Number.isFinite(context.expiresAt)||context.expiresAt<=Date.now()||typeof context.accessToken!=="string"||!/^[^\s]{1,8192}$/.test(context.accessToken))throw new Error;return checked(context.workspace,context.endpoint,{authorization:`Bearer ${context.accessToken}`})}if(typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__){const environment=typeof process==="undefined"?undefined:process.env;if(!environment||!/^[0-9a-f]{64}$/.test(environment.OS_ROUTINE_RUN??""))throw new Error;return checked(environment.OS_ROUTINE_WORKSPACE,oddingtonOrigin(environment),{"x-os-run":environment.OS_ROUTINE_RUN})}throw new Error}catch{throw new DataOperationError("context_unavailable")}}async function resolveFilesContext(){try{const environment=typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__?{}:typeof process==="undefined"?{}:process.env;if(typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__){const installed2=routineTransport();if(installed2)return{url:"private:installed",headers:{},isCurrent:installed2.isCurrent,local:installed2.request,localFiles:installed2.files,signal:undefined};const local=privateRoutineRequest(environment);if(local)return{url:local.identity,headers:{},isCurrent:local.isCurrent,local:local.request,localFiles:local.files,signal:undefined}}const host=memberContext;if(host){const context=await host();if(host!==memberContext||!context.isCurrent()||context.expiresAt<=Date.now())throw new Error;if(context.kind==="local")return{url:`private:app:${context.workspace}/${context.memberId}`,headers:{},isCurrent:context.isCurrent,signal:context.signal,local:undefined,localFiles:context.requestFiles};if(!Number.isFinite(context.expiresAt)||context.expiresAt<=Date.now()||typeof context.accessToken!=="string"||!/^[^\s]{1,8192}$/.test(context.accessToken))throw new Error;return{...filesContext(context.workspace,context.endpoint,{authorization:`Bearer ${context.accessToken}`}),isCurrent:context.isCurrent,local:undefined,localFiles:undefined,signal:undefined}}if(typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__){if(!/^[0-9a-f]{64}$/.test(environment.OS_ROUTINE_RUN??""))throw new Error;const workspace=environment.OS_ROUTINE_WORKSPACE;return{...filesContext(workspace,`https://${workspace}.oddington.ai`,{"x-os-run":environment.OS_ROUTINE_RUN}),local:undefined,localFiles:undefined,signal:undefined}}throw new Error}catch{throw new FileOperationError("unsupported_context",400)}}function filesContext(workspace,endpoint,headers){if(!workspace||!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(workspace)||workspace.length>63||["auth","www","api","os"].includes(workspace)||endpoint!==`https://${workspace}.oddington.ai`)throw new Error;return{url:`${endpoint}/api/files`,headers:{...headers,"x-os-workspace":workspace},isCurrent:()=>true}}function checked(workspace,endpoint,headers){if(!workspace||!/^[a-z0-9][a-z0-9-]{0,127}$/.test(workspace))throw new Error;const origin=new URL(endpoint);if(origin.protocol!=="https:"||origin.username||origin.password||origin.search||origin.hash||origin.pathname!=="/")throw new Error;return{url:`${origin.origin}/api/data`,headers:{...headers,"x-os-workspace":workspace}}}var invalid6=()=>{throw new DataOperationError("invalid_query")};var unavailable=()=>{throw new DataOperationError("unavailable")};var text2=(value)=>typeof value==="string"&&value.length>0;function capture3(value,ancestors=new Set,depth=0){if(value===null||typeof value==="string"||typeof value==="boolean"||typeof value==="number"&&Number.isFinite(value))return value;if(!value||typeof value!=="object"||ancestors.has(value)||depth>32)return invalid6();ancestors.add(value);try{if(Array.isArray(value))return historyArray(value).map((item)=>capture3(item,ancestors,depth+1));return Object.fromEntries(Object.entries(historyProperties(value)).map(([key,descriptor])=>[key,capture3(descriptor.value,ancestors,depth+1)]))}finally{ancestors.delete(value)}}function recordPagination(queryRecords){function pages(query){const captured=capture3(query);const names=Object.keys(historyProperties(captured));for(const name of names){const selection2=historyProperties(captured[name]);if(Object.hasOwn(selection2,"$")){const options=historyProperties(selection2.$.value);if(Object.hasOwn(options,"after"))return invalid6()}}return iterate();async function*iterate(){const state=new Map(names.map((name)=>[name,{seen:new Set,total:0,count:undefined,next:undefined}]));let active=names,version;do{const request=Object.fromEntries(active.map((name)=>{const selection2=captured[name];const next=state.get(name).next;return[name,next===undefined?selection2:{...selection2,$:{...selection2.$,after:next}}]}));const response=await queryRecords(request);let page;try{page=capture3(response);const keys2=Object.keys(historyProperties(page));if(keys2.length!==active.length+1||keys2.some((key)=>key!=="$meta"&&!active.includes(key)))unavailable();const meta=page.$meta;if(Object.keys(historyProperties(meta)).sort().join(",")!=="collections,version"||!text2(meta.version)||version!==undefined&&version!==meta.version)unavailable();version=meta.version;const collectionKeys=Object.keys(historyProperties(meta.collections));if(collectionKeys.some((key)=>!active.includes(key)))unavailable();for(const name of active){const records=historyArray(page[name]);const metadata=Object.hasOwn(meta.collections,name)?meta.collections[name]:{};if(Object.keys(historyProperties(metadata)).some((key)=>key!=="count"&&key!=="next")||Object.hasOwn(metadata,"next")&&!text2(metadata.next))unavailable();for(const record2 of records){historyProperties(record2);const row=record2;if(!validRecordRef(row.$ref)||!text2(row.$version))unavailable()}const current=state.get(name);if(captured[name].$?.count===true){if(!Number.isSafeInteger(metadata.count)||metadata.count<0||current.count!==undefined&¤t.count!==metadata.count)unavailable();current.count=metadata.count}else if(Object.hasOwn(metadata,"count"))unavailable();current.total+=records.length;if(!Number.isSafeInteger(current.total)||current.count!==undefined&&(current.total>current.count||metadata.next===undefined&¤t.total!==current.count))unavailable();if(metadata.next!==undefined){if(current.seen.has(metadata.next))unavailable();current.seen.add(metadata.next)}current.next=metadata.next}}catch{return unavailable()}const collections=Object.fromEntries(names.map((name)=>{const current=state.get(name);return[name,{...current.count===undefined?{}:{count:current.count},...current.next===undefined?{}:{next:current.next}}]}));const output=Object.fromEntries(names.map((name)=>[name,active.includes(name)?page[name]:[]]));active=active.filter((name)=>state.get(name).next!==undefined);yield{...output,$meta:{version,collections}}}while(active.length)}}async function all(query,options){const properties=historyProperties(options);const maxRecords=properties.maxRecords?.value;if(Object.keys(properties).join(",")!=="maxRecords"||!Number.isSafeInteger(maxRecords)||maxRecords<1)invalid6();const captured=capture3(query);const names=Object.keys(historyProperties(captured));if(names.length===1){const name=names[0],selection2=historyProperties(captured[name]);const selectionNames=Object.keys(selection2);const authored=selection2.$?historyProperties(selection2.$.value):{};if(selectionNames.every((key)=>key==="$")&&!Object.hasOwn(authored,"limit"))captured[name]={...captured[name],$:{...captured[name].$,limit:Math.min(500,maxRecords)}}}let result,total=0;for await(const page of pages(captured)){const names2=Object.keys(page.$meta.collections);const size=names2.reduce((sum,name)=>sum+page[name].length,0);if(size>maxRecords-total)throw new DataOperationError("capacity",false,undefined,undefined,{code:"record_limit_exceeded",maxRecords,collections:names2});total+=size;result??={...Object.fromEntries(names2.map((name)=>[name,[]])),$meta:page.$meta};for(const name of names2){const target=result[name];for(const record2 of page[name])target.push(record2)}result.$meta=page.$meta}return result}return{pages,all}}var genericData={repository(repository){async function send(input){const context=await resolveDataContext();const envelope={repository,...input};const changing="operation"in input&&["changes.validate","changes.apply"].includes(String(input.operation));checkDataRequestSize(envelope,"local"in context&&changing?LOCAL_DATA_CHANGE_REQUEST_LIMIT:DATA_REQUEST_LIMIT);if("local"in context)return await context.local("data/query",envelope);try{const response=await fetch(context.url,{method:"POST",redirect:"error",cache:"no-store",headers:{"content-type":"application/json",...context.headers},body:JSON.stringify(envelope)});const result=await response.json();if(!response.ok){throw dataTransportError(response.status,result)}return result}catch(error){if(error instanceof DataOperationError)throw error;throw new DataOperationError("unavailable",true)}}async function read(input,options){const refs=captureRecordsReadRefs(typeof input==="string"?[input]:input);const captured=captureRecordsReadOptions(options);const result=await send({operation:"records.read",refs,...options===undefined?{}:{options:captured}});return typeof input==="string"?result.records[0]:result}const queryRecords=(query)=>send({operation:"records.query",query});return{collections:{list:()=>send({operation:"collections.list"}),schema:(name)=>send({operation:"collections.schema",name})},records:{read,query:queryRecords,...recordPagination(queryRecords),search:async(query,options)=>send({operation:"records.search",...captureRecordsSearchInput(query,options)})},history:{list:async(options)=>send({operation:"history.list",options:captureHistoryListOptions(options)}),at:async(instant)=>send({operation:"history.at",instant:captureHistoryInstant(instant)}),changes:async(options)=>send({operation:"history.changes",options:captureHistoryChangesOptions(options)})},changes(){let updates=[],creates=[],deletes=[],applyId;let pending,confirmed;const assertMutable=()=>{if(applyId)throw new DataOperationError("invalid_change",false,"unapplied")};const snapshot=(nextUpdates=updates,nextCreates=creates,nextDeletes=deletes)=>{const{updates:updates2,creates:creates2,deletes:deletes2}=captureDataChanges(nextUpdates,nextCreates,nextDeletes);const input={updates:updates2,...creates2.length?{creates:creates2}:{},...deletes2.length?{deletes:deletes2}:{}};checkDataRequestSize({repository,operation:"changes.apply",...input,applyId:applyId??"00000000-0000-4000-8000-000000000000"},LOCAL_DATA_CHANGE_REQUEST_LIMIT);return input};return{create(record2){assertMutable();const next=[...creates,captureDataCreate(record2)];snapshot(updates,next,deletes);creates=next},update(record2,set){assertMutable();const next=[...updates,captureDataUpdate(record2,set)];snapshot(next,creates,deletes);updates=next},delete(record2){assertMutable();const next=[...deletes,captureDataDelete(record2)];snapshot(updates,creates,next);deletes=next},async validate(){await send({operation:"changes.validate",...snapshot()})},apply(){if(confirmed)return Promise.resolve(structuredClone(confirmed));if(!pending){let captured;try{captured=snapshot()}catch(error){return Promise.reject(error)}applyId??=routineTransport()?.key("data")??crypto.randomUUID();pending=send({operation:"changes.apply",...captured,applyId}).then((result)=>{confirmed=structuredClone(result);return result}).catch((error)=>{if(error instanceof DataOperationError)throw explainDataValidation(new DataOperationError(error.code,error.retryable,error.effect??(["unavailable","apply_pending"].includes(error.code)?"uncertain":"unapplied"),error.component,error.detail),error.message,error.detail);throw new DataOperationError("unavailable",true,"uncertain")}).finally(()=>{pending=undefined})}return pending.then((result)=>structuredClone(result))}}}}}};var data=genericData;async function hostedContent(url,init,parent,upstream=fetch,check=async()=>{},failure){const delivery=new AbortController;const abort=()=>delivery.abort(parent.reason);parent.addEventListener("abort",abort,{once:true});if(parent.aborted)abort();const detach=()=>parent.removeEventListener("abort",abort);try{const response=await upstream(url,{...init,signal:delivery.signal});try{await check();if(delivery.signal.aborted)throw failure?.()??new FileOperationError("unavailable",503,true)}catch(error){response.body?.cancel().catch(()=>{});throw error}if(!response.body){detach();return response}const source=response.body;let reader;let settled=false;let output;const cancel=async(reason)=>{if(settled)return;settled=true;detach();delivery.signal.removeEventListener("abort",stop);delivery.abort(reason);try{await(reader?reader.cancel(reason):source.cancel(reason))}catch(error){if(error!==delivery.signal.reason&&!(error instanceof Error&&error.name==="AbortError"))throw error}finally{reader?.releaseLock()}};const stop=()=>{if(settled)return;const error=failure?.()??delivery.signal.reason;cancel(error).catch(()=>{});output.error(error)};const body=new ReadableStream({start(controller){output=controller;delivery.signal.addEventListener("abort",stop,{once:true});if(delivery.signal.aborted)stop()},async pull(controller){try{await check();if(settled)return;reader??=source.getReader();const{done,value}=await reader.read();await check();if(settled)return;if(done){settled=true;detach();delivery.signal.removeEventListener("abort",stop);reader.releaseLock();controller.close()}else controller.enqueue(value)}catch(error){if(settled)return;controller.error(failure?.()??error);await cancel(error).catch(()=>{})}},cancel},{highWaterMark:0});const wrapped=new Response(body,{status:response.status,statusText:response.statusText,headers:response.headers});for(const key of["url","redirected","type"])Object.defineProperty(wrapped,key,{value:response[key]});return wrapped}catch(error){detach();delivery.abort(error);throw error}}var MAX_BYTES=16*1024*1024;var PART_BYTES=8*1024*1024;var METADATA_BYTES=4096;var RESULT_BYTES=16*1024;var CONTROL_RESULT_BYTES=128*1024;var TIMEOUT_MS=30000;var MAX_ACTIVE=4;var ATTEMPTS=2;var active=0;var waiters=[];var invalid7=()=>new FileOperationError("invalid_input",400);var unavailable2=()=>new FileOperationError("unavailable",503,true);var failures={400:["invalid_input","unsupported_context"],401:["unauthenticated"],403:["access_denied"],404:["not_found"],405:["method_not_allowed"],409:["conflict","local_only"],413:["request_too_large"],429:["capacity"],503:["integrity","unavailable"]};function heldSlot(){let held=true;return()=>{if(!held)return;held=false;for(;;){const waiter=waiters.shift();if(!waiter){active--;return}if(!waiter.waiting)continue;waiter.waiting=false;waiter.signal?.removeEventListener("abort",waiter.abort);waiter.resolve(heldSlot());return}}}async function acquireSlot(signal){if(signal?.aborted)throw unavailable2();if(active<MAX_ACTIVE){active++;return heldSlot()}return new Promise((resolve,reject)=>{const waiter={signal,waiting:true,resolve,reject,abort(){if(!waiter.waiting)return;waiter.waiting=false;const index=waiters.indexOf(waiter);if(index!==-1)waiters.splice(index,1);reject(unavailable2())}};waiters.push(waiter);signal?.addEventListener("abort",waiter.abort,{once:true});if(signal?.aborted)waiter.abort()})}async function boundedBytes(stream,limit,signal){if(!stream)return new Uint8Array;const reader=stream.getReader();const bytes=new Uint8Array(limit);let size=0;const cancel=()=>{reader.cancel().catch(()=>{})};signal?.addEventListener("abort",cancel,{once:true});if(signal?.aborted)cancel();try{for(;;){const{done,value}=await reader.read();if(signal?.aborted)throw unavailable2();if(done)break;if(!(value instanceof Uint8Array))throw new FileOperationError("invalid_input",400,false,{reason:"invalid_bytes"});size+=value.byteLength;if(size>limit)throw new FileOperationError("request_too_large",413,false,{reason:"size_limit",limitBytes:limit,receivedBytes:size,receivedAtLeast:true});bytes.set(value,size-value.byteLength)}}catch(error){cancel();throw error}finally{signal?.removeEventListener("abort",cancel);reader.releaseLock()}return bytes.slice(0,size)}async function timed(work,parent,timeout=TIMEOUT_MS){const controller=new AbortController;let timer;let abort;const expiry=new Promise((_,reject)=>{abort=()=>{controller.abort();reject(unavailable2())};timer=setTimeout(abort,timeout);parent?.addEventListener("abort",abort,{once:true});if(parent?.aborted)abort()});try{return await Promise.race([work(controller.signal),expiry])}finally{clearTimeout(timer);parent?.removeEventListener("abort",abort)}}async function result(response,maximum=RESULT_BYTES){try{const bytes=await boundedBytes(response.body,maximum);return JSON.parse(new TextDecoder("utf-8",{fatal:true}).decode(bytes))}catch{throw unavailable2()}}async function send(suffix,init,descriptor,initial,parent){const original=initial;const checkCurrent=(context=original)=>{if(parent?.aborted)throw unavailable2();if(!original.isCurrent()||context.url!==original.url)throw new FileOperationError("unsupported_context",400)};for(let attempt=0;attempt<ATTEMPTS;attempt++){checkCurrent();const context=await resolveFilesContext();checkCurrent(context);try{const response=context.localFiles?await context.localFiles(suffix,init,parent):await(async()=>{const url=`${context.url}${suffix}`;const request={...init,signal:parent,headers:{...context.headers,...init.headers},redirect:"error",cache:"no-store"};return descriptor?fetch(url,request):hostedContent(url,request,parent)})();if(!response.ok){const value2=await result(response);const error=value2&&typeof value2==="object"&&"error"in value2?value2.error:undefined;const received=error&&typeof error==="object"&&"code"in error?error.code:undefined;const code=failures[response.status]?.find((code2)=>code2===received);throw code?new FileOperationError(code,response.status,code==="capacity"||code==="unavailable",parseFileErrorDetail(error?.detail)):unavailable2()}if(response.status!==200){response.body?.cancel().catch(()=>{});throw unavailable2()}try{checkCurrent()}catch(error){response.body?.cancel().catch(()=>{});throw error}if(!descriptor)return response;const value=await result(response,descriptor==="control"?CONTROL_RESULT_BYTES:RESULT_BYTES);if(descriptor==="control"){checkCurrent();return value}let parsed;if(descriptor==="enrichment"){if(!value||typeof value!=="object"||Array.isArray(value))throw unavailable2();const{name,...metadata}=value;if(!safeEnrichmentName(name))throw unavailable2();parsed={name,...parseEnrichmentDescriptor(metadata)}}else parsed=parseFileDescriptor(value);checkCurrent();return parsed}catch(error){const failure=error instanceof FileOperationError?error:unavailable2();if(init.body instanceof ReadableStream||!failure.retryable||attempt+1===ATTEMPTS)throw failure}}throw unavailable2()}function idPath(id2){if(typeof id2!=="string"||!FILE_ID_PATTERN.test(id2))throw invalid7();return`/${id2}`}async function multipartCreate(input,metadata,exchange,release,upload,expectedSha256){const route=upload?`${idPath(upload.file.id)}/upload/multipart`:"/multipart";let ticket;let reader;let chunk,offset=0;const receipts=[];const pending=new Set;const request=(work,timeout=TIMEOUT_MS)=>timed((signal)=>{const task=work(signal);pending.add(task);task.then(()=>pending.delete(task),()=>pending.delete(task));return task},undefined,timeout);const control=(body)=>({method:"POST",headers:{"content-type":"application/json",...ticket?{"x-os-transfer":ticket}:{}},body:JSON.stringify(body)});try{const startRequest=control(upload?.file??metadata);if(expectedSha256)startRequest.headers["x-os-original-sha256"]=expectedSha256;const start=await request((signal)=>exchange(`${route}/start`,startRequest,"control",signal));if(!start||typeof start!=="object"||Array.isArray(start))throw unavailable2();const session=start;if(Object.keys(session).sort().join(",")!=="partBytes,ticket"||session.partBytes!==PART_BYTES||typeof session.ticket!=="string"||!session.ticket||session.ticket.length>64*1024)throw unavailable2();ticket=session.ticket;if(input.file instanceof ReadableStream)reader=input.file.getReader();let lastProgress=Date.now();const next=async()=>{try{if(Date.now()-lastProgress>=TIMEOUT_MS)throw unavailable2();const value=await request(()=>reader.read(),Math.max(1,TIMEOUT_MS-(Date.now()-lastProgress)));if(value.value?.byteLength)lastProgress=Date.now();return value}catch(error){await reader.cancel(error).catch(()=>{});throw error}};for(let sent=0,partNumber=1;sent<metadata.size||metadata.size===0&&partNumber===1;partNumber++){const length=Math.min(PART_BYTES,metadata.size-sent);let part;if(input.file instanceof Uint8Array)part=new Uint8Array(input.file.subarray(sent,sent+length));else if(input.file instanceof Blob){const slice=input.file.slice(sent,sent+length);part=new Uint8Array(await request(()=>slice.arrayBuffer()))}else{part=new Uint8Array(length);let filled=0;while(filled<length){if(!chunk||offset===chunk.byteLength){chunk=undefined;offset=0;const value2=await next();if(value2.done)throw invalid7();if(!(value2.value instanceof Uint8Array))throw invalid7();chunk=value2.value;if(chunk.byteLength>metadata.size-sent-filled)throw invalid7()}const take=Math.min(length-filled,chunk.byteLength-offset);part.set(chunk.subarray(offset,offset+take),filled);filled+=take;offset+=take;if(offset===chunk.byteLength){chunk=undefined;offset=0}}}if(part.byteLength!==length)throw invalid7();if(reader&&sent+length===metadata.size){lastProgress=Date.now();for(;;){const value2=await next();if(value2.done)break;if(!(value2.value instanceof Uint8Array)||value2.value.byteLength)throw invalid7()}}const value=await request((signal)=>exchange(`${route}/part`,{method:"POST",headers:{"content-type":"application/octet-stream","x-os-transfer":ticket,"x-os-part":String(partNumber)},body:part.buffer},"control",signal));part=undefined;const receipt=value;if(!receipt||typeof receipt!=="object"||Object.keys(receipt).sort().join(",")!=="etag,partNumber"||receipt.partNumber!==partNumber||typeof receipt.etag!=="string"||!receipt.etag||receipt.etag.length>256||/[\u0000-\u001f\u007f]/.test(receipt.etag))throw unavailable2();receipts.push({partNumber,etag:receipt.etag});sent+=length;lastProgress=Date.now()}if(upload)for(const name of Object.keys(upload.file.enrichments)){const bytes=await request(()=>upload.enrichment(name));if(bytes.byteLength!==upload.file.enrichments[name].size||bytes.byteLength>MAX_BYTES)throw invalid7();await request((signal)=>exchange(`${route}/enrichments/${encodeURIComponent(name)}`,{method:"POST",headers:{"content-type":"application/octet-stream","x-os-transfer":ticket},body:bytes.buffer.slice(bytes.byteOffset,bytes.byteOffset+bytes.byteLength)},"control",signal))}await upload?.beforeComplete();const completion=control({parts:receipts});if(new TextEncoder().encode(completion.body).byteLength>128*1024)throw unavailable2();const completed=parseFileDescriptor(await request((signal)=>exchange(`${route}/complete`,completion,true,signal),TIMEOUT_MS+Math.ceil(metadata.size/(1024*1024))*1000));if(!upload){const acknowledged=await request((signal)=>exchange(`${route}/acknowledge`,control(completed),"control",signal));if(!acknowledged||typeof acknowledged!=="object"||Object.keys(acknowledged).join(",")!=="acknowledged"||acknowledged.acknowledged!==true)throw unavailable2()}return completed}catch(error){if(reader)await reader.cancel(error).catch(()=>{});if(ticket)await request((signal)=>exchange(`${route}/abort`,control({}),"control",signal)).catch(()=>{});throw error instanceof FileOperationError?error:unavailable2()}finally{chunk=undefined;reader?.releaseLock();if(pending.size)Promise.allSettled([...pending]).then(release);else release()}}async function operation(work,initial,parent){const context=initial??await resolveFilesContext();const signal=context.signal&&parent?AbortSignal.any([context.signal,parent]):context.signal??parent;const release=await acquireSlot(signal);const execute=async(signal2)=>{try{return await work(context,signal2)}finally{release()}};if(context.localFiles)return execute(signal??new AbortController().signal);return timed(execute,signal).catch((error)=>{throw error instanceof FileOperationError?error:unavailable2()})}function contentPath(id2,name){const path=idPath(id2);if(name===undefined)return`${path}/content`;if(!safeEnrichmentName(name))throw invalid7();return`${path}/enrichments/${encodeURIComponent(name)}/content`}async function read(id2,names){const context=await resolveFilesContext();idPath(id2);if(names===undefined||typeof names==="string"){const path=contentPath(id2,names);return operation((context2,signal)=>send(path,{method:"GET"},false,context2,signal),context)}if(!Array.isArray(names))throw invalid7();const distinct=[];const seen=new Set;for(const name of names){if(typeof name!=="string"||!safeEnrichmentName(name))throw invalid7();if(seen.has(name))continue;if(seen.size===16)throw invalid7();seen.add(name);distinct.push(name)}const paths=distinct.map((name)=>contentPath(id2,name));return timed(async(parent)=>{const responses={};try{for(let i=0;i<paths.length;i++){const response=await operation((context2,signal)=>send(paths[i],{method:"GET"},false,context2,signal),context,parent);Object.defineProperty(responses,distinct[i],{value:response,enumerable:true})}if(!context.isCurrent())throw new FileOperationError("unsupported_context",400);return responses}catch(error){for(const response of Object.values(responses))response.body?.cancel().catch(()=>{});throw error}})}var files={async upload(id2){return operation(async(context,signal)=>{const file2=await send(`${idPath(id2)}/upload`,{method:"POST"},true,context,signal);if(file2.id!==id2)throw unavailable2();return file2})},async create(input,options){const context=await resolveFilesContext();if(!input||typeof input!=="object"||Array.isArray(input)||Object.keys(input).some((key)=>!["file","size","path","name","storage","mediaType"].includes(key))||options!==undefined&&(!options||typeof options!=="object"||Array.isArray(options)||Object.keys(options).some((key)=>key!=="requestKey")))throw invalid7();const blob=input.file instanceof Blob;const array2=input.file instanceof Uint8Array;const stream=input.file instanceof ReadableStream;if(!blob&&!array2&&!stream)throw invalid7();const intrinsic=blob?input.file.size:array2?input.file.byteLength:undefined;if(intrinsic!==undefined&&input.size!==undefined&&input.size!==intrinsic){if(!Number.isSafeInteger(input.size)||input.size<0)throw new FileOperationError("invalid_input",400,false,{reason:"invalid_size"});throw new FileOperationError("invalid_input",400,false,{reason:"size_mismatch",expectedBytes:input.size,receivedBytes:intrinsic})}let name=input.name;if(name===undefined&&blob&&"name"in input.file&&typeof input.file.name==="string"){name=typeof globalThis.File!=="undefined"&&input.file instanceof globalThis.File?input.file.name:input.file.name.split(/[\\/]/).at(-1)}const mediaType=declaredOriginalMediaType(input.mediaType===undefined?blob&&input.file.type?input.file.type:"application/octet-stream":input.mediaType);const metadata=parseFileCreateMetadata({name,size:intrinsic??input.size,path:input.path,storage:input.storage,mediaType,requestKey:options?.requestKey===undefined?routineTransport()?.key("files")??crypto.randomUUID():options.requestKey},FILE_ORIGINAL_MAX_BYTES);if(!context.local&&!context.localFiles&&metadata.storage==="local")throw new FileOperationError("unsupported_context",400);const header=encodeURIComponent(JSON.stringify(metadata));if(new TextEncoder().encode(header).byteLength>METADATA_BYTES)throw invalid7();const release=await acquireSlot(context.signal);if(context.localFiles&&!routineTransport()&&metadata.size>MAX_BYTES){try{const signal=context.signal??new AbortController().signal;const file2=input.file;let offset=0;const body=file2 instanceof Blob?context.signal?file2:file2.stream():file2 instanceof ReadableStream?file2:new ReadableStream({pull(controller){if(offset===file2.byteLength){controller.close();return}const end=Math.min(offset+256*1024,file2.byteLength);controller.enqueue(file2.subarray(offset,end));offset=end}},{highWaterMark:0});return await send("",{method:"POST",headers:{"content-type":"application/octet-stream","x-os-file":header},body},true,context,signal)}finally{release()}}if(metadata.size>MAX_BYTES)return multipartCreate(input,metadata,(suffix,init,kind,signal)=>kind===true?send(suffix,init,true,context,signal):send(suffix,init,"control",context,signal),release);return timed(async(signal)=>{try{const bytes=array2?new Uint8Array(input.file):await boundedBytes(blob?input.file.stream():input.file,metadata.size,signal);if(bytes.byteLength!==metadata.size)throw new FileOperationError("invalid_input",400,false,{reason:"size_mismatch",expectedBytes:metadata.size,receivedBytes:bytes.byteLength});if(signal.aborted)throw unavailable2();return await send("",{method:"POST",headers:{"content-type":"application/octet-stream","x-os-file":header},body:bytes.buffer},true,context,signal)}finally{release()}},context.signal).catch((error)=>{throw error instanceof FileOperationError?error:unavailable2()})},async enrich(input){const context=await resolveFilesContext();if(!input||typeof input!=="object"||Array.isArray(input)||Object.keys(input).some((key)=>!["file","name","content","mediaType","replace"].includes(key))||typeof input.content!=="string"&&!(input.content instanceof Uint8Array))throw invalid7();const path=`${idPath(input.file)}/enrichments`;if(typeof input.content==="string"?input.content.length>MAX_BYTES:input.content.byteLength>MAX_BYTES)throw new FileOperationError("request_too_large",413);return operation(async(context2,signal)=>{let bytes;if(typeof input.content==="string"){const buffer=new Uint8Array(Math.min(MAX_BYTES,input.content.length*3));const encoded=new TextEncoder().encodeInto(input.content,buffer);if(encoded.read!==input.content.length)throw new FileOperationError("request_too_large",413);bytes=buffer.slice(0,encoded.written)}else bytes=new Uint8Array(input.content);const metadata=parseFileEnrichMetadata({name:input.name,size:bytes.byteLength,...input.mediaType===undefined?{}:{mediaType:input.mediaType},...input.replace===undefined?{}:{replace:input.replace}},MAX_BYTES);const header=encodeURIComponent(JSON.stringify(metadata));if(new TextEncoder().encode(header).byteLength>METADATA_BYTES)throw invalid7();const result2=await send(path,{method:"POST",headers:{"content-type":"application/octet-stream","x-os-enrichment":header},body:bytes.buffer},"enrichment",context2,signal);if(result2.name!==metadata.name)throw unavailable2();return result2},context)},async get(id2){return operation((context,signal)=>send(idPath(id2),{method:"GET"},true,context,signal))},read};function validDropboxRootPath(value){return typeof value==="string"&&value.length<=2048&&value.startsWith("/")&&!/[\\\x00-\x1f\x7f]/.test(value)&&value.slice(1).split("/").every((segment)=>segment.length>0&&segment.trim()===segment&&segment!=="."&&segment!=="..")}function validMicrosoftId(value){return typeof value==="string"&&/^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i.test(value)}function validMicrosoftMailbox(value){return typeof value==="string"&&value.length<=254&&/^[^\s@/?#\\\x00-\x1f\x7f]+@[^\s@/?#\\\x00-\x1f\x7f]+\.[^\s@/?#\\\x00-\x1f\x7f]+$/.test(value)}function sharePointHost(value){return/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.sharepoint\.com$/.test(value)}function canonicalSharePointSiteUrl(value){if(typeof value!=="string"||value.length>2048||/[\s\\?#\x00-\x1f\x7f]/.test(value)||!/^https:\/\/[^/:@]+(?:\/|$)/i.test(value))return;try{const url=new URL(value);if(url.protocol!=="https:"||!sharePointHost(url.hostname)||url.username||url.password||url.port)return;const rawPath=value.replace(/^https:\/\/[^/]+/i,"")||"/";const path=rawPath.endsWith("/")?rawPath.slice(0,-1):rawPath;const segments=path.slice(1).split("/");if(path&&segments.some((segment)=>!segment))return;const encoded=path?segments.map((segment)=>{const decoded=decodeURIComponent(segment);if(decoded==="."||decoded===".."||/[/%\\?#\x00-\x1f\x7f]/.test(decoded))throw new Error;return encodeURIComponent(decoded)}).join("/"):"";const canonical=`https://${url.hostname}/${encoded}`;return canonical.length<=2048?canonical:undefined}catch{return}}function validSharePointSiteId(value,siteUrl){if(typeof value!=="string"||value.length>512)return false;const[host,collection,site,extra]=value.split(",");return extra===undefined&&host===new URL(siteUrl).hostname&&validMicrosoftId(collection)&&validMicrosoftId(site)}function validGoogleScopes(value){return Array.isArray(value)&&value.length>0&&value.length<=32&&value.every((scope)=>typeof scope==="string"&&scope.length<=256&&/^(https:\/\/www\.googleapis\.com\/auth\/[A-Za-z0-9._-]+|https:\/\/mail\.google\.com\/|openid|email|profile)$/.test(scope))&&new Set(value).size===value.length}var DROPBOX_FILE_SCOPES=["account_info.read","files.metadata.read","files.content.read","files.content.write"];function validDropboxFileScopes(value){return Array.isArray(value)&&value.length===DROPBOX_FILE_SCOPES.length&&new Set(value).size===value.length&&DROPBOX_FILE_SCOPES.every((scope)=>value.includes(scope))}var ROUTINE_CONNECTION_CREDENTIALS_ENV="OS_ROUTINE_CONNECTION_CREDENTIALS";function parseRoutineConnectionNames(value){if(!Array.isArray(value)||value.some((name)=>typeof name!=="string"||!/^(gmail|airtable|dropbox|outlook|sharepoint)\/[a-z0-9][a-z0-9-]{0,62}$/.test(name))||new Set(value).size!==value.length)throw new Error("Invalid routine connections");return value}var connectionUuid=(v)=>typeof v==="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(v);function runtimeConnection(lease){switch(lease.provider){case"outlook":return{id:`outlook/${lease.name}`,provider:lease.provider,name:lease.name,mailboxEmail:lease.mailboxEmail,accessToken:lease.accessToken,expiresAt:lease.expiresAt};case"sharepoint":return{id:`sharepoint/${lease.name}`,provider:lease.provider,name:lease.name,siteId:lease.siteId,siteUrl:lease.siteUrl,accessToken:lease.accessToken,expiresAt:lease.expiresAt};case"gmail":return{id:`gmail/${lease.name}`,provider:lease.provider,name:lease.name,accountEmail:lease.accountEmail,scopes:[...lease.scopes],accessToken:lease.accessToken,expiresAt:lease.expiresAt};case"airtable":return{id:`airtable/${lease.name}`,provider:lease.provider,name:lease.name,baseId:lease.baseId,accessToken:lease.accessToken,runExpiresAt:lease.runExpiresAt};case"dropbox":return{id:`dropbox/${lease.name}`,provider:lease.provider,name:lease.name,accountId:lease.accountId,access:lease.access,rootPath:lease.rootPath,scopes:[...lease.scopes],accessToken:lease.accessToken,expiresAt:lease.expiresAt}}}function parseConnectionLease(raw,now=Date.now()){const v=raw;if(!v||typeof v!=="object"||Array.isArray(v)||!connectionUuid(v.connectionId)||!connectionUuid(v.runId)||typeof v.name!=="string"||!/^[a-z0-9][a-z0-9-]{0,62}$/.test(v.name)||typeof v.accessToken!=="string"||!/^[A-Za-z0-9._~+/-]{1,8192}={0,2}$/.test(v.accessToken))throw new Error("Invalid connection credential");if(v.provider==="outlook"||v.provider==="sharepoint"){const targetValid=v.provider==="outlook"?Object.keys(v).sort().join(",")==="accessToken,connectionId,expiresAt,mailboxEmail,name,provider,runId"&&validMicrosoftMailbox(v.mailboxEmail):Object.keys(v).sort().join(",")==="accessToken,connectionId,expiresAt,name,provider,runId,siteId,siteUrl"&&typeof v.siteUrl==="string"&&canonicalSharePointSiteUrl(v.siteUrl)===v.siteUrl&&validSharePointSiteId(v.siteId,v.siteUrl);if(!targetValid||typeof v.expiresAt!=="string"||!Number.isFinite(Date.parse(v.expiresAt))||Date.parse(v.expiresAt)<=now||Date.parse(v.expiresAt)>now+3600000)throw new Error("Invalid connection credential");return v}if(v.provider==="gmail"){if(Object.keys(v).sort().join(",")!=="accessToken,accountEmail,connectionId,expiresAt,name,provider,runId,scopes"||typeof v.accountEmail!=="string"||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v.accountEmail)||!validGoogleScopes(v.scopes)||typeof v.expiresAt!=="string"||!Number.isFinite(Date.parse(v.expiresAt))||Date.parse(v.expiresAt)<=now||Date.parse(v.expiresAt)>now+3600000)throw new Error("Invalid connection credential");return v}if(v.provider==="airtable"&&Object.keys(v).sort().join(",")==="accessToken,baseId,connectionId,name,provider,runExpiresAt,runId"&&typeof v.baseId==="string"&&/^app[A-Za-z0-9]+$/.test(v.baseId)&&typeof v.runExpiresAt==="string"&&Number.isFinite(Date.parse(v.runExpiresAt))&&Date.parse(v.runExpiresAt)>now&&Date.parse(v.runExpiresAt)<=now+15*60000)return v;if(v.provider==="dropbox"&&Object.keys(v).sort().join(",")==="access,accessToken,accountId,connectionId,expiresAt,name,provider,rootPath,runId,scopes"&&typeof v.accountId==="string"&&/^dbid:[A-Za-z0-9_-]{1,128}$/.test(v.accountId)&&v.access==="full_dropbox"&&validDropboxRootPath(v.rootPath)&&validDropboxFileScopes(v.scopes)&&typeof v.expiresAt==="string"&&Number.isFinite(Date.parse(v.expiresAt))&&Date.parse(v.expiresAt)>now&&Date.parse(v.expiresAt)<=now+14400000)return v;throw new Error("Invalid connection credential")}class AirtableOperationError extends Error{effect;receipts;constructor(message,effect="unapplied",receipts=[]){super(message);this.effect=effect;this.receipts=receipts;this.name="AirtableOperationError"}}var recordId=(v)=>typeof v==="string"&&/^rec[A-Za-z0-9]+$/.test(v);var tableId=(v)=>typeof v==="string"&&/^tbl[A-Za-z0-9]+$/.test(v);function fail2(message){throw new AirtableOperationError(message)}function object3(v){if(!v||typeof v!=="object"||Array.isArray(v)||![null,Object.prototype].includes(Object.getPrototypeOf(v)))fail2("Invalid Airtable data");return v}function keys2(v,allowed,required=allowed){if(Object.keys(v).some((k)=>!allowed.includes(k))||required.some((k)=>!Object.hasOwn(v,k)))fail2("Invalid Airtable input")}function text3(v){return typeof v==="string"&&v.length>0&&v.length<=1024}function fields3(v,nonempty=false){const result2=object3(v);if(nonempty&&!Object.keys(result2).length||Object.keys(result2).some((k)=>!text3(k)))fail2("Invalid Airtable fields");try{return serializable(result2)}catch{return fail2("Invalid Airtable fields")}}function record2(v){const r=object3(v);if(!recordId(r.id)||r.createdTime!==undefined&&(typeof r.createdTime!=="string"||!Number.isFinite(Date.parse(r.createdTime))))fail2("Malformed Airtable record");return{id:r.id,...r.createdTime===undefined?{}:{createdTime:r.createdTime},fields:fields3(r.fields)}}function equal(a,b){if(a===b)return true;if(!a||!b||typeof a!=="object"||typeof b!=="object"||Array.isArray(a)!==Array.isArray(b))return false;const left=Object.keys(a),right=Object.keys(b);return left.length===right.length&&left.every((k)=>Object.hasOwn(b,k)&&equal(a[k],b[k]))}function createConnections(transport){return{async get(){throw new Error("Connection unavailable")},airtable(name){if(typeof name!=="string"||!/^[a-z0-9][a-z0-9-]{0,62}$/.test(name))fail2("Invalid Airtable connection name");const call=(operation2,input)=>transport(name,operation2,input);return{tables:{list:async()=>await call("tables.list",{})},records:{list:async(input)=>await call("records.list",input),get:async(input)=>await call("records.get",input),create:async(input)=>await call("records.create",input),update:async(input)=>await call("records.update",input),delete:async(input)=>await call("records.delete",input)}}}}}async function executeAirtableOperation(authority,operation2,raw,options={}){const{name,baseId,accessToken}=authority;if(!/^[a-z0-9][a-z0-9-]{0,62}$/.test(name)||!/^app[A-Za-z0-9]+$/.test(baseId)||!/^[A-Za-z0-9._~+/-]{1,8192}={0,2}$/.test(accessToken))fail2("Airtable connection unavailable");let input;try{input=object3(serializable(raw))}catch{return fail2("Invalid Airtable input")}const mutation=["records.create","records.update","records.delete"].includes(operation2);const receipt=(ids2)=>({provider:"airtable",connection:`airtable/${name}`,baseId,table:input.table,operation:operation2.slice(8),records:ids2.map((id2)=>({id:id2}))});async function request(path2,init={},write=false){let response;try{response=await(options.fetch??fetch)(`https://api.airtable.com/v0/${path2}`,{...init,headers:{authorization:`Bearer ${accessToken}`,"content-type":"application/json"},redirect:"manual",signal:options.signal?AbortSignal.any([options.signal,AbortSignal.timeout(15000)]):AbortSignal.timeout(15000)})}catch{throw new AirtableOperationError("Airtable request acknowledgment unavailable",write?"uncertain":"unapplied")}if(!response.ok){await response.body?.cancel().catch(()=>{});throw new AirtableOperationError("Airtable request rejected",write&&(response.status>=500||response.status===408||response.status<400)?"uncertain":"unapplied")}try{if(!response.headers.get("content-type")?.toLowerCase().includes("application/json"))throw new Error;const value=object3(await response.json());const safe=serializable(value);if(Object.hasOwn(value,"error")||JSON.stringify(safe).includes(accessToken))throw new Error;return value}catch{throw new AirtableOperationError("Malformed Airtable acknowledgment",write?"uncertain":"unapplied")}}if(operation2==="tables.list"){keys2(input,[]);const tables=[],seen=new Set;let offset;do{const query2=new URLSearchParams(offset?{offset}:{});const page=await request(`meta/bases/${baseId}/tables?${query2}`);if(!Array.isArray(page.tables))fail2("Malformed Airtable tables");for(const value of page.tables){const t=object3(value);if(!tableId(t.id)||!text3(t.name)||!text3(t.primaryFieldId)||!Array.isArray(t.fields)||tables.some((existing)=>existing.id===t.id))fail2("Malformed Airtable table");const metadata=t.fields.map((value2)=>{const f=object3(value2);if(typeof f.id!=="string"||!/^fld[A-Za-z0-9]+$/.test(f.id)||!text3(f.name)||!text3(f.type))fail2("Malformed Airtable field");return{id:f.id,name:f.name,type:f.type,...f.options===undefined?{}:{options:serializable(f.options)}}});if(!metadata.some((f)=>f.id===t.primaryFieldId)||new Set(metadata.map((f)=>f.id)).size!==metadata.length)fail2("Malformed Airtable fields");tables.push({id:t.id,name:t.name,primaryFieldId:t.primaryFieldId,fields:metadata})}offset=nextOffset(page.offset,seen)}while(offset);return tables}if(!text3(input.table)||input.table==="."||input.table==="..")fail2("Invalid Airtable table");if(mutation&&!tableId(input.table))fail2("Airtable writes require a stable table ID");const path=`${baseId}/${encodeURIComponent(input.table)}`;if(operation2==="records.get"){keys2(input,["table","id"]);if(!recordId(input.id))fail2("Invalid Airtable record ID");const result3=record2(await request(`${path}/${input.id}`));if(result3.id!==input.id)fail2("Malformed Airtable record");return result3}if(operation2==="records.list"){keys2(input,["table","fields"],["table"]);if(input.fields!==undefined&&(!Array.isArray(input.fields)||!input.fields.length||input.fields.some((f)=>!text3(f))||new Set(input.fields).size!==input.fields.length))fail2("Invalid Airtable field selection");const records2=[],ids2=new Set,seen=new Set;let offset;do{const query2=new URLSearchParams;for(const field of input.fields??[])query2.append("fields[]",field);if(offset)query2.set("offset",offset);const page=await request(`${path}?${query2}`);if(!Array.isArray(page.records))fail2("Malformed Airtable records");for(const value of page.records){const r=record2(value);if(ids2.has(r.id))fail2("Malformed Airtable pagination");ids2.add(r.id);records2.push(r)}offset=nextOffset(page.offset,seen)}while(offset);return records2}if(!mutation)fail2("Unsupported Airtable operation");keys2(input,["table","records"]);if(!Array.isArray(input.records)||!input.records.length||input.records.length>10)fail2("Invalid Airtable batch");const kind=operation2.slice(8),ids=new Set;const records=input.records.map((value)=>{const r=object3(value);keys2(r,kind==="create"?["fields"]:kind==="update"?["id","expected","set"]:["id","expected"]);if(kind==="create")return{fields:fields3(r.fields,true)};if(!recordId(r.id)||ids.has(r.id))fail2("Invalid Airtable batch record ID");ids.add(r.id);const set=kind==="update"?fields3(r.set,true):undefined;if(set&&Object.values(set).some((value2)=>value2===null))fail2("Airtable guard null cannot be an update value");return{id:r.id,expected:fields3(r.expected),...set?{set}:{}}});for(const r of records){if(!("id"in r))continue;const current=record2(await request(`${path}/${r.id}`));if(current.id!==r.id)fail2("Malformed Airtable record");for(const[key,value]of Object.entries(r.expected)){if(value===null?Object.hasOwn(current.fields,key):!Object.hasOwn(current.fields,key)||!equal(current.fields[key],value))fail2("Airtable reviewed values are stale")}}await options.beforeMutation?.();const query=new URLSearchParams;if(kind==="delete")for(const id2 of ids)query.append("records[]",id2);const result2=await request(`${path}${kind==="delete"?`?${query}`:""}`,{method:kind==="create"?"POST":kind==="update"?"PATCH":"DELETE",...kind==="delete"?{}:{body:JSON.stringify({records:records.map((r)=>("id"in r)?{id:r.id,fields:r.set}:r)})}},true);const acknowledged=[],returned=[];try{if(!Array.isArray(result2.records))throw new Error;for(const value of result2.records){const r=object3(value);if(!recordId(r.id)||acknowledged.includes(r.id)||kind!=="create"&&!ids.has(r.id)||kind==="delete"&&r.deleted!==true)throw new Error;acknowledged.push(r.id);if(kind!=="delete")returned.push(record2(r))}if(acknowledged.length!==records.length)throw new Error}catch{throw new AirtableOperationError("Incomplete Airtable mutation acknowledgment",acknowledged.length?"partial":"uncertain",acknowledged.length?[receipt(acknowledged)]:[])}return{receipt:receipt(acknowledged),...kind==="delete"?{}:{records:returned}}}function nextOffset(value,seen){if(value===undefined)return;if(!text3(value)||seen.has(value))fail2("Malformed Airtable pagination");seen.add(value);return value}var MANAGED_CONNECTION_CAPABILITY_ENV="OS_MANAGED_CONNECTION_CAPABILITY";function managedConnections(capability){const endpoint=new URL(capability.endpoint);if(endpoint.protocol!=="http:"||endpoint.hostname!=="127.0.0.1"||!endpoint.port||endpoint.pathname!=="/"||endpoint.search||endpoint.hash||endpoint.username||endpoint.password||!/^[0-9a-f-]{36}$/.test(capability.token))throw new AirtableOperationError("Airtable capability unavailable");const transport=async(name,operation2,input)=>{let safeInput;try{safeInput=serializable(input)}catch{safeInput=null}try{const response=await fetch(new URL("airtable",endpoint),{method:"POST",redirect:"error",headers:{authorization:`Bearer ${capability.token}`,"content-type":"application/json"},body:JSON.stringify({name,operation:operation2,input:safeInput}),signal:AbortSignal.timeout(125000)});const value=await response.json();if(!response.ok)throw new AirtableOperationError("Airtable operation failed; the execution retains its evidence",value.effect==="partial"||value.effect==="uncertain"?value.effect:"unapplied",value.receipts??[]);return value}catch(error){if(error instanceof AirtableOperationError)throw error;throw new AirtableOperationError("Airtable parent acknowledgment unavailable",["records.create","records.update","records.delete"].includes(operation2)?"uncertain":"unapplied")}};return createConnections(transport)}var observer;function observeLocalRoutineEffects(value){observer=value}async function reportLocalRoutineEffect(value){await observer?.(value)}var identityPattern=/^(gmail|airtable|dropbox|outlook|sharepoint)\/([a-z0-9][a-z0-9-]{0,62})$/;var workspacePattern=/^[a-z0-9][a-z0-9-]{0,62}$/;var providerNames={gmail:"Gmail",airtable:"Airtable",dropbox:"Dropbox",outlook:"Outlook",sharepoint:"SharePoint"};function parseConnectionFailureDetail(value){if(!value||typeof value!=="object"||Array.isArray(value))throw new Error("Invalid Connection failure");const detail=value;if(!["identity","identity,workspace"].includes(Object.keys(detail).sort().join(","))||typeof detail.identity!=="string"||!identityPattern.test(detail.identity)||detail.workspace!==undefined&&(typeof detail.workspace!=="string"||!workspacePattern.test(detail.workspace)))throw new Error("Invalid Connection failure");return{identity:detail.identity,...detail.workspace===undefined?{}:{workspace:detail.workspace}}}function connectionFailureMessage(value){const detail=parseConnectionFailureDetail(value);const[,provider,name]=identityPattern.exec(detail.identity);const first=`Couldn’t use ${providerNames[provider]??provider} connection ${name}.`;return detail.workspace?`${first}
|
|
37
37
|
|
|
38
38
|
Check it with:
|
|
39
39
|
os connection test --workspace ${detail.workspace} --connection ${detail.identity}`:`${first}
|
|
40
40
|
|
|
41
|
-
Check or reconnect this Connection, then try again.`}class ConnectionOperationError extends Error{code="unavailable";detail;constructor(identity,workspace){const detail=parseConnectionFailureDetail({identity,...workspace===undefined?{}:{workspace}});super(connectionFailureMessage(detail));this.name="ConnectionOperationError";this.detail=detail}}var local;function installLocalRoutineConnections(runId,declared,raw,acquire){if(local||!Array.isArray(raw))throw new Error("Connection unavailable");const names=parseRoutineConnectionNames([...declared]);const leases=raw.map((value)=>parseConnectionLease(value));if(!acquire&&leases.length!==names.length||new Set(leases.map((lease)=>`${lease.provider}/${lease.name}`)).size!==leases.length||leases.some((lease)=>lease.runId!==runId||!names.includes(`${lease.provider}/${lease.name}`)))throw new Error("Connection unavailable");const current={runId,declared:names,leases,acquiring:new Map,acquire};local=current;return()=>{if(local===current)local=undefined;current.leases.length=0;current.acquiring.clear()}}async function localLease(identity){const current=local;if(!current||!current.declared.includes(identity))throw new Error("Connection unavailable");let lease=current.leases.find((value)=>`${value.provider}/${value.name}`===identity);if(lease){try{return parseConnectionLease(lease)}catch{const index=current.leases.indexOf(lease);if(index!==-1)current.leases.splice(index,1);if(!current.acquire)throw new Error("Connection unavailable");lease=undefined}}if(!lease&¤t.acquire){let acquiring=current.acquiring.get(identity);if(!acquiring){acquiring=(async()=>{const acquired=parseConnectionLease(await current.acquire(identity));if(local!==current||acquired.runId!==current.runId||`${acquired.provider}/${acquired.name}`!==identity)throw new Error("Connection unavailable");current.leases.push(acquired);return acquired})();current.acquiring.set(identity,acquiring);acquiring.finally(()=>{if(current.acquiring.get(identity)===acquiring)current.acquiring.delete(identity)}).catch(()=>{})}lease=await acquiring}if(local!==current||!lease||lease.runId!==current.runId||`${lease.provider}/${lease.name}`!==identity)throw new Error("Connection unavailable");return parseConnectionLease(lease)}function connectionFailure(identity){const workspace=typeof process==="undefined"?undefined:process.env.OS_ROUTINE_WORKSPACE;try{return new ConnectionOperationError(identity,workspace)}catch{return new Error("Connection unavailable")}}var airtable=createConnections(async(name,operation2,input)=>{if(typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__)throw new AirtableOperationError("Airtable connection unavailable");try{const installed2=routineTransport();if(installed2)return await installed2.request("airtable",{name,operation:operation2,input:serializable(input)});const managed=process.env[MANAGED_CONNECTION_CAPABILITY_ENV];if(managed){const client=managedConnections(JSON.parse(managed)).airtable(name);if(operation2==="tables.list")return await client.tables.list();return await client.records[operation2.slice(8)](input)}const raw=local?[await localLease(`airtable/${name}`)]:JSON.parse(process.env[ROUTINE_CONNECTION_CREDENTIALS_ENV]??"[]");if(!Array.isArray(raw))throw new Error;const leases=raw.map((value)=>parseConnectionLease(value));if(new Set(leases.map((lease2)=>`${lease2.provider}/${lease2.name}`)).size!==leases.length)throw new Error;const lease=leases.find((lease2)=>lease2.provider==="airtable"&&lease2.name===name);if(!lease||lease.provider!=="airtable")throw new Error;const writing=["records.create","records.update","records.delete"].includes(operation2);const captured=serializable(input);let result2;try{result2=await executeAirtableOperation(lease,operation2,captured)}catch(error){if(writing&&error instanceof AirtableOperationError)await reportLocalRoutineEffect({type:"effect",connection:`airtable/${name}`,operation:operation2,input:captured,effect:error.effect,receipts:error.receipts});throw error}if(writing)await reportLocalRoutineEffect({type:"effect",connection:`airtable/${name}`,operation:operation2,input:captured,effect:"confirmed",receipts:[result2.receipt]});return result2}catch(error){if(error instanceof AirtableOperationError)throw error;throw new AirtableOperationError("Airtable connection unavailable")}});function runtimeConnections(){return{...airtable,async get(identity){if(typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__)throw connectionFailure(identity);try{parseRoutineConnectionNames([identity]);const installed2=routineTransport();if(installed2)return await installed2.request("connections/get",{identity});const managed=process.env[MANAGED_CONNECTION_CAPABILITY_ENV];if(managed){const capability=JSON.parse(managed);const response=await fetch(new URL("connections/get",capability.endpoint),{method:"POST",redirect:"error",headers:{authorization:`Bearer ${capability.token}`,"content-type":"application/json"},body:JSON.stringify({identity})});if(!response.ok)throw new Error;return await response.json()}return runtimeConnection(await localLease(identity))}catch{throw connectionFailure(identity)}}}}var connections=runtimeConnections();var LOCAL_ROUTINE_VALUE_BYTES=256*1024;var codes={FileOperationError:["invalid_input","unsupported_context","unauthenticated","access_denied","request_too_large","conflict","local_only","integrity","unavailable","capacity","method_not_allowed"],DataOperationError:["context_unavailable","unauthenticated","access_denied","invalid_query","request_too_large","capacity","unavailable","invalid_change","conflict","apply_pending"],RoutineAIError:ROUTINE_AI_ERROR_CODES,ConnectionOperationError:["unavailable"],AppRoutineContractError:["invalid_contract","invalid_value"],Error:[],TypeError:[],RangeError:[],SyntaxError:[]};function parseLocalRoutineFailure(value){const invalid8=()=>{throw new Error("Invalid local routine failure")};if(!value||typeof value!=="object"||Array.isArray(value))return invalid8();const v=value;if(Object.keys(v).some((key)=>!["kind","code","status","retryable","detail","message"].includes(key))||typeof v.kind!=="string"||!Object.hasOwn(codes,v.kind))return invalid8();const kind=v.kind,allowed=codes[kind];if(allowed.length?typeof v.code!=="string"||!allowed.includes(v.code):Object.hasOwn(v,"code"))return invalid8();if(Object.hasOwn(v,"status")&&(kind!=="FileOperationError"||!Number.isSafeInteger(v.status)||v.status<400||v.status>599))return invalid8();if(Object.hasOwn(v,"retryable")&&(!["FileOperationError","DataOperationError"].includes(kind)||typeof v.retryable!=="boolean"))return invalid8();const detail=kind==="FileOperationError"?fileErrorDetailForCode(v.code,v.detail):kind==="RoutineAIError"?parseRoutineAIErrorDetail(v.code,v.detail):undefined;const dataDetail=kind==="DataOperationError"&&v.detail!==undefined?parseDataOperationDetail(v.detail):undefined;const connectionDetail=kind==="ConnectionOperationError"&&v.detail!==undefined?parseConnectionFailureDetail(v.detail):undefined;if(dataDetail&&("reason"in dataDetail?v.code!=="invalid_change":dataDetail.code==="record_limit_exceeded"&&v.code!=="capacity"))return invalid8();const message=kind==="DataOperationError"&&v.code==="invalid_change"?dataDetail&&"reason"in dataDetail?dataValidationMessageFacts({code:"invalid_change",message:"",detail:dataDetail}).message:safeRecordFieldMessage(v.message):undefined;if(Object.hasOwn(v,"message")&&(!message||v.message!==message))return invalid8();if(Object.hasOwn(v,"detail")&&!detail&&!dataDetail&&!connectionDetail)return invalid8();return{kind,...allowed.length?{code:v.code}:{},...Object.hasOwn(v,"status")?{status:v.status}:{},...Object.hasOwn(v,"retryable")?{retryable:v.retryable}:{},...connectionDetail??dataDetail??detail?{detail:connectionDetail??dataDetail??detail}:{},...message?{message}:{}}}function captureLocalRoutineFailure(error){try{if(error instanceof FileOperationError)return parseLocalRoutineFailure({kind:"FileOperationError",code:error.code,status:error.status,retryable:error.retryable,...error.detail?{detail:error.detail}:{}});if(error instanceof DataOperationError)return parseLocalRoutineFailure({kind:"DataOperationError",code:error.code,retryable:error.retryable,...dataValidationMessageFacts(error),...error.detail?{detail:error.detail}:{}});if(error instanceof AIError)return parseLocalRoutineFailure({kind:"RoutineAIError",code:error.code,...error.detail?{detail:error.detail}:{}});if(error instanceof ConnectionOperationError)return parseLocalRoutineFailure({kind:"ConnectionOperationError",code:error.code,detail:error.detail});if(error instanceof AppRoutineContractError)return parseLocalRoutineFailure({kind:"AppRoutineContractError",code:error.code});return{kind:error instanceof TypeError?"TypeError":error instanceof RangeError?"RangeError":error instanceof SyntaxError?"SyntaxError":"Error"}}catch{return{kind:"Error"}}}function captureLocalRoutineErrorDetail(error){const detail=[],seen=new Set;try{for(let value=error;value!==undefined&&!seen.has(value)&&detail.length<4;){seen.add(value);if(!(value instanceof Error)){detail.push({name:"Error",message:typeof value==="string"?value.slice(0,2048):"A non-Error value was thrown."});break}detail.push({name:String(value.name).slice(0,128),message:String(value.message).slice(0,2048),...typeof value.stack==="string"?{stack:value.stack.slice(0,8192)}:{}});value=value.cause}}catch{}return detail}if((typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__)&&typeof process!=="undefined"&&process.env.OS_LOCAL_ROUTINE_HOST==="1"){Object.defineProperty(globalThis,Symbol.for("oddington.private.local-routine-host"),{value:async()=>{const{readSync,closeSync}=await import("node:fs");const{Socket}=await import("node:net");const{pathToFileURL}=await import("node:url");const chunks=[];let size=0;for(;;){const chunk=Buffer.alloc(4096),count=readSync(4,chunk,0,chunk.length,null);if(!count)break;if((size+=count)>524288)throw new Error("Invalid routine bootstrap");chunks.push(chunk.subarray(0,count))}closeSync(4);const bootstrap=JSON.parse(new TextDecoder("utf-8",{fatal:true}).decode(Buffer.concat(chunks)));const channel=new Socket({fd:3,readable:true,writable:true});let sequence=0,broken=false,settled=false;let pending;let buffer="";const fail3=()=>{broken=true;pending?.reject();pending=undefined;channel.destroy();if(!settled){if(process.platform!=="win32"){try{process.kill(-process.pid,"SIGKILL")}catch{}}process.exit(1)}};channel.on("error",fail3);channel.on("end",fail3);channel.on("close",fail3);channel.on("data",(bytes)=>{buffer+=bytes.toString("utf8");if(Buffer.byteLength(buffer)>1024)return fail3();const end=buffer.indexOf(`
|
|
41
|
+
Check or reconnect this Connection, then try again.`}class ConnectionOperationError extends Error{code="unavailable";detail;constructor(identity,workspace){const detail=parseConnectionFailureDetail({identity,...workspace===undefined?{}:{workspace}});super(connectionFailureMessage(detail));this.name="ConnectionOperationError";this.detail=detail}}var local;function installLocalRoutineConnections(runId,declared,raw,acquire){if(local||!Array.isArray(raw))throw new Error("Connection unavailable");const names=parseRoutineConnectionNames([...declared]);const leases=raw.map((value)=>parseConnectionLease(value));if(!acquire&&leases.length!==names.length||new Set(leases.map((lease)=>`${lease.provider}/${lease.name}`)).size!==leases.length||leases.some((lease)=>lease.runId!==runId||!names.includes(`${lease.provider}/${lease.name}`)))throw new Error("Connection unavailable");const current={runId,declared:names,leases,acquiring:new Map,acquire};local=current;return()=>{if(local===current)local=undefined;current.leases.length=0;current.acquiring.clear()}}async function localLease(identity){const current=local;if(!current||!current.declared.includes(identity))throw new Error("Connection unavailable");let lease=current.leases.find((value)=>`${value.provider}/${value.name}`===identity);if(lease){try{return parseConnectionLease(lease)}catch{const index=current.leases.indexOf(lease);if(index!==-1)current.leases.splice(index,1);if(!current.acquire)throw new Error("Connection unavailable");lease=undefined}}if(!lease&¤t.acquire){let acquiring=current.acquiring.get(identity);if(!acquiring){acquiring=(async()=>{const acquired=parseConnectionLease(await current.acquire(identity));if(local!==current||acquired.runId!==current.runId||`${acquired.provider}/${acquired.name}`!==identity)throw new Error("Connection unavailable");current.leases.push(acquired);return acquired})();current.acquiring.set(identity,acquiring);acquiring.finally(()=>{if(current.acquiring.get(identity)===acquiring)current.acquiring.delete(identity)}).catch(()=>{})}lease=await acquiring}if(local!==current||!lease||lease.runId!==current.runId||`${lease.provider}/${lease.name}`!==identity)throw new Error("Connection unavailable");return parseConnectionLease(lease)}function connectionFailure(identity){const workspace=typeof process==="undefined"?undefined:process.env.OS_ROUTINE_WORKSPACE;try{return new ConnectionOperationError(identity,workspace)}catch{return new Error("Connection unavailable")}}var airtable=createConnections(async(name,operation2,input)=>{if(typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__)throw new AirtableOperationError("Airtable connection unavailable");try{const installed2=routineTransport();if(installed2)return await installed2.request("airtable",{name,operation:operation2,input:serializable(input)});const managed=process.env[MANAGED_CONNECTION_CAPABILITY_ENV];if(managed){const client=managedConnections(JSON.parse(managed)).airtable(name);if(operation2==="tables.list")return await client.tables.list();return await client.records[operation2.slice(8)](input)}const raw=local?[await localLease(`airtable/${name}`)]:JSON.parse(process.env[ROUTINE_CONNECTION_CREDENTIALS_ENV]??"[]");if(!Array.isArray(raw))throw new Error;const leases=raw.map((value)=>parseConnectionLease(value));if(new Set(leases.map((lease2)=>`${lease2.provider}/${lease2.name}`)).size!==leases.length)throw new Error;const lease=leases.find((lease2)=>lease2.provider==="airtable"&&lease2.name===name);if(!lease||lease.provider!=="airtable")throw new Error;const writing=["records.create","records.update","records.delete"].includes(operation2);const captured=serializable(input);let result2;try{result2=await executeAirtableOperation(lease,operation2,captured)}catch(error){if(writing&&error instanceof AirtableOperationError)await reportLocalRoutineEffect({type:"effect",connection:`airtable/${name}`,operation:operation2,input:captured,effect:error.effect,receipts:error.receipts});throw error}if(writing)await reportLocalRoutineEffect({type:"effect",connection:`airtable/${name}`,operation:operation2,input:captured,effect:"confirmed",receipts:[result2.receipt]});return result2}catch(error){if(error instanceof AirtableOperationError)throw error;throw new AirtableOperationError("Airtable connection unavailable")}});function runtimeConnections(){return{...airtable,async get(identity){if(typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__)throw connectionFailure(identity);try{parseRoutineConnectionNames([identity]);const installed2=routineTransport();if(installed2)return await installed2.request("connections/get",{identity});const managed=process.env[MANAGED_CONNECTION_CAPABILITY_ENV];if(managed){const capability=JSON.parse(managed);const response=await fetch(new URL("connections/get",capability.endpoint),{method:"POST",redirect:"error",headers:{authorization:`Bearer ${capability.token}`,"content-type":"application/json"},body:JSON.stringify({identity})});if(!response.ok)throw new Error;return await response.json()}return runtimeConnection(await localLease(identity))}catch{throw connectionFailure(identity)}}}}var connections=runtimeConnections();var LOCAL_ROUTINE_VALUE_BYTES=256*1024;var codes={FileOperationError:["invalid_input","unsupported_context","unauthenticated","access_denied","not_found","request_too_large","conflict","local_only","integrity","unavailable","capacity","method_not_allowed"],DataOperationError:["context_unavailable","unauthenticated","access_denied","invalid_query","request_too_large","capacity","unavailable","invalid_change","conflict","apply_pending"],RoutineAIError:ROUTINE_AI_ERROR_CODES,ConnectionOperationError:["unavailable"],AppRoutineContractError:["invalid_contract","invalid_value"],Error:[],TypeError:[],RangeError:[],SyntaxError:[]};function parseLocalRoutineFailure(value){const invalid8=()=>{throw new Error("Invalid local routine failure")};if(!value||typeof value!=="object"||Array.isArray(value))return invalid8();const v=value;if(Object.keys(v).some((key)=>!["kind","code","status","retryable","detail","message"].includes(key))||typeof v.kind!=="string"||!Object.hasOwn(codes,v.kind))return invalid8();const kind=v.kind,allowed=codes[kind];if(allowed.length?typeof v.code!=="string"||!allowed.includes(v.code):Object.hasOwn(v,"code"))return invalid8();if(Object.hasOwn(v,"status")&&(kind!=="FileOperationError"||!Number.isSafeInteger(v.status)||v.status<400||v.status>599))return invalid8();if(Object.hasOwn(v,"retryable")&&(!["FileOperationError","DataOperationError"].includes(kind)||typeof v.retryable!=="boolean"))return invalid8();const detail=kind==="FileOperationError"?fileErrorDetailForCode(v.code,v.detail):kind==="RoutineAIError"?parseRoutineAIErrorDetail(v.code,v.detail):undefined;const dataDetail=kind==="DataOperationError"&&v.detail!==undefined?parseDataOperationDetail(v.detail):undefined;const connectionDetail=kind==="ConnectionOperationError"&&v.detail!==undefined?parseConnectionFailureDetail(v.detail):undefined;if(dataDetail&&("reason"in dataDetail?v.code!=="invalid_change":dataDetail.code==="record_limit_exceeded"&&v.code!=="capacity"))return invalid8();const message=kind==="DataOperationError"&&v.code==="invalid_change"?dataDetail&&"reason"in dataDetail?dataValidationMessageFacts({code:"invalid_change",message:"",detail:dataDetail}).message:safeRecordFieldMessage(v.message):undefined;if(Object.hasOwn(v,"message")&&(!message||v.message!==message))return invalid8();if(Object.hasOwn(v,"detail")&&!detail&&!dataDetail&&!connectionDetail)return invalid8();return{kind,...allowed.length?{code:v.code}:{},...Object.hasOwn(v,"status")?{status:v.status}:{},...Object.hasOwn(v,"retryable")?{retryable:v.retryable}:{},...connectionDetail??dataDetail??detail?{detail:connectionDetail??dataDetail??detail}:{},...message?{message}:{}}}function captureLocalRoutineFailure(error){try{if(error instanceof FileOperationError)return parseLocalRoutineFailure({kind:"FileOperationError",code:error.code,status:error.status,retryable:error.retryable,...error.detail?{detail:error.detail}:{}});if(error instanceof DataOperationError)return parseLocalRoutineFailure({kind:"DataOperationError",code:error.code,retryable:error.retryable,...dataValidationMessageFacts(error),...error.detail?{detail:error.detail}:{}});if(error instanceof AIError)return parseLocalRoutineFailure({kind:"RoutineAIError",code:error.code,...error.detail?{detail:error.detail}:{}});if(error instanceof ConnectionOperationError)return parseLocalRoutineFailure({kind:"ConnectionOperationError",code:error.code,detail:error.detail});if(error instanceof AppRoutineContractError)return parseLocalRoutineFailure({kind:"AppRoutineContractError",code:error.code});return{kind:error instanceof TypeError?"TypeError":error instanceof RangeError?"RangeError":error instanceof SyntaxError?"SyntaxError":"Error"}}catch{return{kind:"Error"}}}function captureLocalRoutineErrorDetail(error){const detail=[],seen=new Set;try{for(let value=error;value!==undefined&&!seen.has(value)&&detail.length<4;){seen.add(value);if(!(value instanceof Error)){detail.push({name:"Error",message:typeof value==="string"?value.slice(0,2048):"A non-Error value was thrown."});break}detail.push({name:String(value.name).slice(0,128),message:String(value.message).slice(0,2048),...typeof value.stack==="string"?{stack:value.stack.slice(0,8192)}:{}});value=value.cause}}catch{}return detail}if((typeof __OS_BROWSER__==="undefined"||!__OS_BROWSER__)&&typeof process!=="undefined"&&process.env.OS_LOCAL_ROUTINE_HOST==="1"){Object.defineProperty(globalThis,Symbol.for("oddington.private.local-routine-host"),{value:async()=>{const{readSync,closeSync}=await import("node:fs");const{Socket}=await import("node:net");const{pathToFileURL}=await import("node:url");const chunks=[];let size=0;for(;;){const chunk=Buffer.alloc(4096),count=readSync(4,chunk,0,chunk.length,null);if(!count)break;if((size+=count)>524288)throw new Error("Invalid routine bootstrap");chunks.push(chunk.subarray(0,count))}closeSync(4);const bootstrap=JSON.parse(new TextDecoder("utf-8",{fatal:true}).decode(Buffer.concat(chunks)));const channel=new Socket({fd:3,readable:true,writable:true});let sequence=0,broken=false,settled=false;let pending;let buffer="";const fail3=()=>{broken=true;pending?.reject();pending=undefined;channel.destroy();if(!settled){if(process.platform!=="win32"){try{process.kill(-process.pid,"SIGKILL")}catch{}}process.exit(1)}};channel.on("error",fail3);channel.on("end",fail3);channel.on("close",fail3);channel.on("data",(bytes)=>{buffer+=bytes.toString("utf8");if(Buffer.byteLength(buffer)>1024)return fail3();const end=buffer.indexOf(`
|
|
42
42
|
`);if(end<0)return;try{const ack=JSON.parse(buffer.slice(0,end));if(end!==buffer.length-1||!pending||Object.keys(ack).sort().join(",")!=="accepted,sequence"||ack.sequence!==pending.sequence||ack.accepted!==true)return fail3();buffer="";pending.resolve();pending=undefined}catch{fail3()}});const sendReport=async(value)=>{if(broken||pending)throw new Error("Routine reporting unavailable");const frame=JSON.stringify({...value,sequence:++sequence});if(Buffer.byteLength(frame)>LOCAL_ROUTINE_VALUE_BYTES+65536)throw new Error("Routine reporting unavailable");await new Promise((resolve,reject)=>{const timeout=setTimeout(fail3,30000);pending={sequence,resolve(){clearTimeout(timeout);resolve()},reject(){clearTimeout(timeout);reject(new Error("Routine reporting unavailable"))}};channel.write(`${frame}
|
|
43
43
|
`,(error)=>{if(error)fail3()})})};let reporting=Promise.resolve();const report=(value)=>{const captured=structuredClone(value);const next=reporting.then(()=>sendReport(captured));reporting=next;return next};const flush=(stream)=>new Promise((resolve)=>{let timer,settled2=false;const complete=()=>{if(settled2)return;settled2=true;if(timer)clearTimeout(timer);resolve()};timer=setTimeout(complete,1000);if(stream.destroyed||stream.writableEnded)complete();else stream.write("",complete)});let exitCode=0;let releaseConnections;try{const definition=(await import(pathToFileURL(bootstrap.entry).href)).default;const contract=inspectRoutineDefinition(definition);if(bootstrap.mode==="inspect")await report({type:"contract",contract});else if(bootstrap.mode==="execute"&&typeof bootstrap.runId==="string"){const input=captureRoutineInput(definition,bootstrap.input);if(JSON.stringify(contract)!==JSON.stringify(bootstrap.contract))throw new Error("Routine definition changed");const privateRequest=localRoutineRequest();releaseConnections=installLocalRoutineConnections(bootstrap.runId,contract.access.connections??[],[],async(identity)=>{if(!privateRequest)throw new Error("Connection unavailable");return privateRequest("connections/get",{identity})});delete bootstrap.connectionLeases;observeLocalRoutineEffects(report);const generate=async(request)=>{if(!privateRequest)throw new AIError("capability_unavailable");return await privateRequest("ai/generate",request)};const result2=await executeRoutineDefinition(definition,input,{run:{id:bootstrap.runId,progress:async(value)=>report({type:"progress",...value})},data,files,connections,ai:{generateText:generate,generateObject:generate},inbox:routinePublicationClient(),step:async(id2,fact)=>report({type:"step",id:id2,...fact})});await report({type:"finish",...result2===undefined?{}:{result:result2}})}else throw new Error("Invalid routine bootstrap")}catch(error){exitCode=1;if(bootstrap.mode==="execute"){await report({type:"failure",diagnostic:captureLocalRoutineFailure(error),detail:captureLocalRoutineErrorDetail(error)}).catch(()=>{})}}finally{settled=true;observeLocalRoutineEffects(undefined);releaseConnections?.();if(exitCode===0)channel.end();else channel.destroy();await Promise.allSettled([flush(process.stdout),flush(process.stderr)]);process.exit(exitCode)}}})}function locationIdentity(location){const coordinates=location.provider==="os"?[location.file]:location.provider==="gmail"?[location.connection,location.message,location.attachment]:location.provider==="dropbox"?[location.connection,location.file]:location.provider==="outlook"?[location.connection,location.message,...location.attachment===undefined?[]:[location.attachment]]:location.provider==="sharepoint"?[location.connection,location.site,location.drive,location.item,...location.version===undefined?[]:[location.version]]:undefined;if(coordinates?.every((value)=>typeof value==="string"&&value.length>0))return JSON.stringify([location.provider,...coordinates])}var source={file(input){return{$ref:input.$ref,type:"source",kind:"file",filename:input.file.name,media_type:input.file.mediaType,size_bytes:input.file.size,sha256:input.file.sha256,locations:input.locations.map((location)=>({...location}))}},location:{os(file2){return{provider:"os",file:file2.id}},gmail(input){return{provider:"gmail",connection:input.connection,message:input.message,attachment:input.attachment,...input.url===undefined?{}:{url:input.url}}},dropbox(input){return{provider:"dropbox",connection:input.connection,file:input.file,...input.revision===undefined?{}:{revision:input.revision},...input.path===undefined?{}:{path:input.path},...input.url===undefined?{}:{url:input.url}}},outlook(input){return{provider:"outlook",connection:input.connection,message:input.message,...input.attachment===undefined?{}:{attachment:input.attachment},...input.url===undefined?{}:{url:input.url}}},sharepoint(input){return{provider:"sharepoint",connection:input.connection,site:input.site,drive:input.drive,item:input.item,...input.version===undefined?{}:{version:input.version},...input.path===undefined?{}:{path:input.path},...input.url===undefined?{}:{url:input.url}}}},locations:{merge(existing,incoming){const merged=existing.map((location)=>({...location}));for(const location of incoming){const identity=locationIdentity(location);const index=identity===undefined?-1:merged.findIndex((value)=>locationIdentity(value)===identity);if(index<0)merged.push({...location});else merged[index]={...location}}return merged}},csv:{row(baseRef,row){if(!validRecordRef(baseRef))throw new TypeError("CSV row links require a base Record ref");if(!Number.isSafeInteger(row)||row<1)throw new RangeError("CSV row must be a positive safe integer");return`${baseRef}#row=${row}`}}};class InboxOperationError extends Error{status;reason;constructor(status,reason){super(reason==="conflict"?"This question already has an accepted answer":reason==="unavailable"?"Inbox request unavailable. Retry the same action.":reason==="invalid_input"?"Invalid Inbox request":"Inbox access unavailable");this.status=status;this.reason=reason}}var INBOX_RESULT_BYTES=8*1024*1024;var INBOX_INPUT_BYTES=8192;var INBOX_LOCAL_INPUT_BYTES=256*1024;var INBOX_UUID=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function isAppQuestionOperation(operation2){return operation2==="questions.list"||operation2==="questions.answer"||operation2==="questions.searchRecords"}var operations={current:[],"items.list":[],"questions.list":[],"items.read":["itemId"],"items.see":["itemId"],"items.markDigestRead":["itemId"],"items.rename":["itemId","revision","title"],"items.setLifecycle":["itemId","revision","lifecycle"],"items.listRecipientCandidates":["itemId"],"items.addRecipient":["itemId","personId"],"questions.answer":["itemId","revision","questionId","response"],"questions.searchRecords":["itemId","revision","questionId","query"]};function assert(value){if(!value)throw new Error("Invalid Inbox result")}function object4(value){assert(value&&typeof value==="object"&&!Array.isArray(value)&&[Object.prototype,null].includes(Object.getPrototypeOf(value))&&Reflect.ownKeys(value).every((key)=>{const descriptor=typeof key==="string"?Object.getOwnPropertyDescriptor(value,key):undefined;return!!descriptor?.enumerable&&"value"in descriptor}));return value}function keys3(value,allowed,required=allowed){assert(Object.keys(value).every((key)=>allowed.includes(key))&&required.every((key)=>Object.hasOwn(value,key)))}function text4(value,empty2=false){return typeof value==="string"&&(empty2||!!value.trim())}function id2(value){return typeof value==="string"&&INBOX_UUID.test(value)}function integer(value,minimum=1){return Number.isSafeInteger(value)&&Number(value)>=minimum}function date(value){return text4(value)&&Number.isFinite(Date.parse(value))}function optionalDate(value){return value===null||date(value)}function array2(value){assert(Array.isArray(value)&&Object.getPrototypeOf(value)===Array.prototype&&Reflect.ownKeys(value).length===value.length+1&&value.every((_entry,index)=>{const descriptor=Object.getOwnPropertyDescriptor(value,String(index));return!!descriptor?.enumerable&&"value"in descriptor}));return value}function json(value,ancestors=new Set){if(value===null||typeof value==="boolean"||typeof value==="string"||typeof value==="number"&&Number.isFinite(value))return value;assert(value&&typeof value==="object"&&!ancestors.has(value));ancestors.add(value);try{if(Array.isArray(value))return array2(value).map((entry)=>json(entry,ancestors));return Object.fromEntries(Object.entries(object4(value)).map(([key,entry])=>[key,json(entry,ancestors)]))}finally{ancestors.delete(value)}}function recordReference(value){const record3=object4(value);keys3(record3,["repository","ref"]);assert(text4(record3.repository)&&record3.repository===record3.repository.trim()&&/^[a-z0-9][a-z0-9._/-]{0,127}$/.test(record3.repository)&&!/\.\.|\/\//.test(record3.repository)&&text4(record3.ref)&&record3.ref===record3.ref.trim()&&record3.ref.length<=512&&/^[_a-zA-Z0-9][a-zA-Z0-9_-]*(\/[_a-zA-Z0-9][a-zA-Z0-9_-]*)+$/.test(record3.ref));return record3}function responseDefinition(value){const definition=object4(value);keys3(definition,["type","source"]);assert(definition.type==="selection");const source2=object4(definition.source);if(source2.type==="authored"){keys3(source2,["type","options","suggestions","search"],["type","options"]);const options=array2(source2.options);assert(options.length>0);const values=options.map((value2)=>{const option=object4(value2);keys3(option,["value","label","description","note"],["value","label"]);assert(text4(option.value)&&option.value===option.value.trim()&&text4(option.label));if("description"in option)assert(text4(option.description));if("note"in option){const note=object4(option.note);keys3(note,["placeholder"]);assert(text4(note.placeholder))}return option.value});assert(new Set(values).size===values.length);if("search"in source2||"suggestions"in source2){const search=object4(source2.search);keys3(search,["triggerLabel","placeholder","emptyLabel"]);assert(text4(search.triggerLabel)&&text4(search.placeholder)&&text4(search.emptyLabel));const suggestions2=array2(source2.suggestions);assert(suggestions2.length<=8&&suggestions2.every((value2)=>text4(value2)&&values.includes(value2))&&new Set(suggestions2).size===suggestions2.length)}else assert(options.length<=9);return}assert(source2.type==="records");keys3(source2,["type","collection","refPrefix","where","display","suggestions"],["type","collection","display"]);const collection=object4(source2.collection);keys3(collection,["repository","name"]);recordReference({repository:collection.repository,ref:"records/example"});assert(text4(collection.name)&&/^[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_-]+)*$/.test(collection.name));if("refPrefix"in source2)assert(text4(source2.refPrefix)&&source2.refPrefix.length<=512&&/^[_a-zA-Z0-9][a-zA-Z0-9_-]*(\/[_a-zA-Z0-9][a-zA-Z0-9_-]*)*\/$/.test(source2.refPrefix));const where=object4(source2.where??{});assert(Object.entries(where).every(([name,value2])=>/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)&&!["constructor","prototype"].includes(name)&&(value2===null||typeof value2==="string"||typeof value2==="boolean"||typeof value2==="number"&&Number.isFinite(value2))));const display=object4(source2.display);keys3(display,["labelFields"]);const labels=array2(display.labelFields);assert(labels.length>0&&labels.length<=2&&new Set(labels).size===labels.length&&labels.every((value2)=>text4(value2)&&/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(value2)));const suggestions=array2(source2.suggestions??[]);const refs=suggestions.map((value2)=>{const suggestion=object4(value2);keys3(suggestion,["record","reason"],["record"]);const record3=recordReference(suggestion.record);assert(record3.repository===collection.repository);if("reason"in suggestion)assert(text4(suggestion.reason));return record3.ref});assert(suggestions.length<=8&&new Set(refs).size===refs.length)}function inboxFile(value){validateInboxFile(value)}function fields4(value){const labels=array2(value).map((value2)=>{const field=object4(value2);keys3(field,["label","value"]);assert(text4(field.label)&&text4(field.value));return field.label});assert(new Set(labels).size===labels.length)}function block(value){const entry=object4(value);if(entry.kind==="rich-text"){keys3(entry,["kind","markdown"]);assert(text4(entry.markdown));return}if(entry.kind==="asks"){keys3(entry,["kind","problem","asks"]);const asks=array2(entry.asks);assert(text4(entry.problem)&&asks.length>0&&asks.every(id2)&&new Set(asks).size===asks.length);return}assert(["record","records","files"].includes(String(entry.kind)));keys3(entry,["kind","label","initiallyExpanded",...entry.kind==="record"?["record","view"]:entry.kind==="records"?["records","view"]:["files"]],["kind","label",entry.kind==="record"?"record":entry.kind==="records"?"records":"files"]);assert(text4(entry.label)&&(!("initiallyExpanded"in entry)||typeof entry.initiallyExpanded==="boolean")&&(!("view"in entry)||text4(entry.view)&&entry.view===entry.view.trim()));if(entry.kind==="record"){const record3=object4(entry.record);keys3(record3,["ref","title","fields"]);assert(text4(record3.ref)&&record3.ref===record3.ref.trim()&&text4(record3.title));fields4(record3.fields);return}if(entry.kind==="records"){const records=array2(entry.records);const refs=records.map((value2)=>{const record3=object4(value2);keys3(record3,["ref","title","description","facts","view"],["ref","title"]);assert(text4(record3.ref)&&record3.ref===record3.ref.trim()&&text4(record3.title));if("description"in record3)assert(text4(record3.description));if("facts"in record3)fields4(record3.facts);if("view"in record3)assert(text4(record3.view)&&record3.view===record3.view.trim());return record3.ref});assert(records.length>0&&new Set(refs).size===refs.length);return}const files2=array2(entry.files);files2.forEach(inboxFile);assert(files2.length>0&&new Set(files2.map((value2)=>object4(value2).id)).size===files2.length)}function response(value){const answer=object4(value);assert(Object.keys(answer).every((key)=>["selection","note"].includes(key)));if(typeof answer.selection==="string")assert(text4(answer.selection)&&answer.selection===answer.selection.trim());else recordReference(answer.selection);if(Object.hasOwn(answer,"note"))assert(text4(answer.note));return answer}function parseInboxRequest(value){try{const envelope=object4(value);assert(Object.keys(envelope).sort().join(",")==="input,operation");assert(typeof envelope.operation==="string"&&Object.hasOwn(operations,envelope.operation));const operation2=envelope.operation;const input={...object4(envelope.input)};const required=operations[operation2];assert(required.every((key)=>Object.hasOwn(input,key))&&Object.keys(input).every((key)=>required.includes(key)||operation2==="questions.searchRecords"&&key==="selected"||(operation2==="items.list"||operation2==="questions.list")&&key==="beforeNumber"||operation2==="questions.list"&&key==="routines"));if(operation2==="questions.list"){assert(Object.hasOwn(input,"routines"));assert(array2(input.routines).every(isAppRoutineName))}for(const key of["itemId","personId","fileId"])if(key in input)assert(id2(input[key]));if("revision"in input)assert(integer(input.revision));if("beforeNumber"in input)assert(integer(input.beforeNumber));if("questionId"in input)assert(text4(input.questionId)&&input.questionId===input.questionId.trim());if("title"in input)assert(text4(input.title));if("lifecycle"in input)assert(input.lifecycle==="open"||input.lifecycle==="closed");if("query"in input)assert(text4(input.query,true)&&input.query.length<=256);if("selected"in input)recordReference(input.selected);if("response"in input)response(input.response);assert(new TextEncoder().encode(JSON.stringify(envelope)).byteLength<=INBOX_INPUT_BYTES);if("routines"in input)input.routines=[...new Set(input.routines)];return{operation:operation2,input}}catch{throw new InboxOperationError(400,"invalid_input")}}function parseInboxCurrent(value){const current=object4(value),workspace=object4(current.workspace),viewer=object4(current.viewer);assert(id2(workspace.id)&&text4(workspace.slug)&&/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(workspace.slug)&&text4(workspace.name)&&text4(workspace.locale)&&text4(workspace.timezone));assert(id2(viewer.id)&&text4(viewer.name)&&text4(viewer.email));return{workspace:{id:workspace.id,slug:workspace.slug,name:workspace.name,locale:workspace.locale,timezone:workspace.timezone},viewer:{id:viewer.id,name:viewer.name,email:viewer.email}}}function parseInboxItem(value){const item=object4(json(value));assert(id2(item.id)&&id2(item.workspaceId)&&integer(item.number)&&integer(item.revision)&&integer(item.activityVersion,0)&&["ask","digest"].includes(String(item.kind))&&["open","closed"].includes(String(item.lifecycle))&&text4(item.title)&&text4(item.description,true)&&text4(item.author)&&date(item.publishedAt)&&optionalDate(item.seenAt)&&optionalDate(item.digestReadAt));if(item.outcome!==null)assert(text4(object4(item.outcome).outcome));if("canonicalRoutineId"in item)assert(item.canonicalRoutineId===null||isAppRoutineName(item.canonicalRoutineId));if(item.kind==="ask")askMetadata(item);else assert(!("tags"in item)&&!("recordRefs"in item));array2(item.body).forEach(block);array2(item.views).forEach((value2)=>{const view=object4(value2);assert(text4(view.id)&&text4(view.view)&&text4(view.implementation));json(view.input)});array2(item.people).forEach((value2)=>{const person=object4(value2);assert(id2(person.id)&&text4(person.name))});array2(item.questions).forEach((value2)=>{const question2=object4(value2);assert(text4(question2.id)&&id2(question2.to)&&text4(question2.prompt)&&(question2.instructions===null||text4(question2.instructions,true))&&typeof question2.available==="boolean");responseDefinition(question2.response);assert(array2(question2.allowedResponders).every(id2));if(question2.acceptedResponse!==null){const accepted=object4(question2.acceptedResponse);assert(id2(accepted.id)&&id2(accepted.userId)&&date(accepted.acceptedAt));response(accepted.response);if(accepted.label===null)delete accepted.label;else if("label"in accepted)assert(text4(accepted.label));if("acceptanceOrder"in accepted)assert(integer(accepted.acceptanceOrder))}if(question2.execution!==null){const execution=object4(question2.execution);assert(id2(execution.id)&&["pending","running","completed","failed"].includes(String(execution.state))&&integer(execution.attempt,0));if("consequence"in execution){const consequence=object4(execution.consequence);assert(["pending","running","applied","no-write","stopped","partial","uncertain"].includes(String(consequence.state))&&(consequence.phase===null||["loading","invoking","committing"].includes(String(consequence.phase)))&&date(consequence.updatedAt)&&typeof consequence.needsReconciliation==="boolean"&&(consequence.reason===null||text4(consequence.reason,true)));array2(consequence.evidence).forEach((value3)=>{const receipt=object4(value3);assert(text4(receipt.repository)&&text4(receipt.commit)&&text4(receipt.diff,true))})}}});array2(item.linkedAsks).forEach((value2)=>{const linked=object4(value2);assert(id2(linked.id));if(linked.state==="unavailable")assert(typeof linked.done==="boolean");else{assert(["yours","done","open","theirs"].includes(String(linked.state))&&text4(linked.title));if(linked.state==="theirs"){const assignee=object4(linked.assignee);assert(id2(assignee.id)&&text4(assignee.name))}}});array2(item.activity).forEach((value2)=>{const event=object4(value2);assert(integer(event.id)&&text4(event.type)&&(event.actorId===null||id2(event.actorId))&&(event.questionId===null||text4(event.questionId))&&integer(event.revision)&&date(event.createdAt));object4(event.data)});array2(item.work).forEach((value2)=>{const work=object4(value2);assert(id2(work.id)&&text4(work.questionId)&&text4(work.reason)&&optionalDate(work.settledAt))});return item}function parseAnswerableQuestion(value){const entry=object4(json(value));keys3(entry,["itemId","number","revision","title","inboxUrl","questionId","routine","prompt","response","answerable","tags","recordRefs","instructions"],["itemId","number","revision","title","inboxUrl","questionId","routine","prompt","response","answerable"]);assert(id2(entry.itemId)&&integer(entry.number)&&integer(entry.revision)&&text4(entry.title)&&text4(entry.inboxUrl));const link=new URL(entry.inboxUrl);const slug=link.hostname.slice(0,-".oddington.ai".length);assert(link.hostname.endsWith(".oddington.ai")&&slug.length<=63&&/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug)&&!["auth","www","api","os"].includes(slug)&&entry.inboxUrl===`https://${slug}.oddington.ai/inbox/${entry.itemId}`);assert(isAppRoutineName(entry.routine)&&text4(entry.questionId)&&entry.questionId===entry.questionId.trim()&&text4(entry.prompt)&&(!("instructions"in entry)||text4(entry.instructions,true))&&typeof entry.answerable==="boolean");responseDefinition(entry.response);askMetadata(entry);return entry}function askMetadata(entry){const tags=array2(entry.tags===undefined?[]:entry.tags);assert(tags.length<=32&&tags.every((tag)=>text4(tag)&&new TextEncoder().encode(tag).byteLength<=64));assert(new Set(tags).size===tags.length);const refs=array2(entry.recordRefs===undefined?[]:entry.recordRefs);refs.forEach((value)=>{const ref=object4(value);keys3(ref,["repository","id"]);recordReference({repository:ref.repository,ref:ref.id})});assert(new Set(refs.map((value)=>{const ref=object4(value);return JSON.stringify([ref.repository,ref.id])})).size===refs.length);entry.tags=tags;entry.recordRefs=refs}function parseInboxAcceptance(value){const accepted=object4(value);assert(id2(accepted.responseId)&&date(accepted.acceptedAt));if("executionId"in accepted)assert(id2(accepted.executionId));if("acceptanceOrder"in accepted)assert(integer(accepted.acceptanceOrder));if("label"in accepted)assert(text4(accepted.label));return accepted}function parseInboxResult(operation2,value){if(operation2==="current")return parseInboxCurrent(value);if(operation2==="questions.list"){const page=object4(value);keys3(page,["questions","nextBeforeNumber"]);const questions=array2(page.questions).map(parseAnswerableQuestion);assert(page.nextBeforeNumber===null||integer(page.nextBeforeNumber));return{questions,nextBeforeNumber:page.nextBeforeNumber}}if(operation2==="items.read")return parseInboxItem(value);if(operation2==="items.list"){const page=object4(value);const items=array2(page.items).map(parseInboxItem);assert(items.length<=100&&(page.nextBeforeNumber===null||integer(page.nextBeforeNumber)));return{items,nextBeforeNumber:page.nextBeforeNumber}}if(operation2==="items.see"){assert(date(value));return}if(operation2==="items.markDigestRead"){const read2=object4(value);assert(integer(read2.activityId)&&date(read2.readAt));return read2}if(operation2==="items.rename"||operation2==="items.setLifecycle"){const update=object4(value);const item=parseInboxItem(update.item);assert((update.activityId===null||integer(update.activityId))&&optionalDate(update.changedAt));return{...update,item}}if(operation2==="items.listRecipientCandidates"){const candidates=array2(value);candidates.forEach((value2)=>{const person=object4(value2);assert(id2(person.id)&&text4(person.name)&&text4(person.email))});assert(new Set(candidates.map((value2)=>object4(value2).id)).size===candidates.length);return candidates}if(operation2==="items.addRecipient"){const addition=object4(value);const item=parseInboxItem(addition.item);assert(id2(addition.addedPersonId)&&item.people.some((person)=>person.id===addition.addedPersonId));return{...addition,item}}if(operation2==="questions.answer")return parseInboxAcceptance(value);if(operation2==="questions.searchRecords"){const result2=object4(value);assert(text4(result2.recordType)&&integer(result2.eligibleCount,0)&&integer(result2.matchCount,0)&&Number(result2.matchCount)<=Number(result2.eligibleCount));const labeled=(value2)=>{const record3=object4(value2);recordReference({repository:record3.repository,ref:record3.ref});assert(text4(record3.label));if("reason"in record3)assert(text4(record3.reason))};array2(result2.matches).forEach(labeled);array2(result2.suggestions).forEach(labeled);if("selected"in result2)labeled(result2.selected);return result2}throw new Error("File content is not a JSON result")}async function limitedBody(request,limit,timeoutMs){if(!request.body)return new Uint8Array;const reader=request.body.getReader();let expired=false;const timer=timeoutMs===undefined?undefined:setTimeout(()=>{expired=true;reader.cancel().catch(()=>{})},timeoutMs);const chunks=[];let length=0;try{while(true){const{done,value}=await reader.read();if(done)break;length+=value.byteLength;if(length>limit){await reader.cancel();return}chunks.push(value)}if(expired)return;const contents=new Uint8Array(length);let offset=0;for(const chunk of chunks){contents.set(chunk,offset);offset+=chunk.byteLength}return contents}finally{if(timer!==undefined)clearTimeout(timer)}}var UUID=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function parseInboxHostContext(value){if(!value||typeof value!=="object"||Array.isArray(value))throw new Error("Inbox context unavailable");const v=value;if(v.kind!=="inbox"&&v.kind!=="focused"||Object.keys(v).sort().join(",")!==(v.kind==="inbox"?"generation,kind,memberId,workspaceId":"appId,generation,kind,memberId,workspaceId")||typeof v.workspaceId!=="string"||!UUID.test(v.workspaceId)||typeof v.memberId!=="string"||!UUID.test(v.memberId)||typeof v.generation!=="string"||!UUID.test(v.generation)||v.kind==="focused"&&(typeof v.appId!=="string"||!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(v.appId)))throw new Error("Inbox context unavailable");const base={workspaceId:v.workspaceId,memberId:v.memberId,generation:v.generation};return Object.freeze(v.kind==="inbox"?{...base,kind:"inbox"}:{...base,kind:"focused",appId:v.appId})}class InboxContextError extends Error{status;constructor(status){super("Inbox context unavailable");this.status=status}}var contexts=new WeakMap;function resolveHostedInboxContext(host){if(!host.binding||!host.memberId)throw new Error("Inbox context unavailable");let resolve=contexts.get(host.binding);if(!resolve){resolve=hostedInboxContext();contexts.set(host.binding,resolve)}return resolve({...host,memberId:host.memberId})}function hostedInboxContext(){let installed2;let revision=0,issued=0,settled=0;return async(host)=>{const started=++issued;const check=()=>{if(!host.isCurrent()||host.expiresAt<=Date.now())throw new Error("Inbox context unavailable")};check();const response2=await fetch(`${host.endpoint}/api/inbox/context`,{method:"GET",headers:{authorization:`Bearer ${host.accessToken}`},credentials:"omit",redirect:"error",cache:"no-store",signal:AbortSignal.timeout(15000)});try{check();if(response2.status===401||response2.status===403){installed2=undefined;revision++;settled=Math.max(settled,started)}if(!response2.ok||response2.status!==200)throw new InboxContextError(response2.status);const bytes=await limitedBody(response2,4096);check();if(!bytes)throw new Error("Inbox context unavailable");const context=parseInboxHostContext(JSON.parse(new TextDecoder("utf-8",{fatal:true}).decode(bytes)));if(context.memberId!==host.memberId)throw new Error("Inbox context unavailable");if(JSON.stringify(installed2)!==JSON.stringify(context)){if(started<settled)throw new Error("Inbox context unavailable");installed2=context;revision++}settled=Math.max(settled,started);const current=revision;return Object.freeze({context,isCurrent:()=>host.isCurrent()&&host.expiresAt>Date.now()&¤t===revision})}finally{response2.body?.cancel().catch(()=>{})}}}var sessionKey="_os.app.session";var responseChecks=new WeakMap;class AppResponseReadError extends Error{}class AppContextDenied extends Error{}class AppRenewalUnavailable extends Error{}async function untilAborted(work,signal){if(signal.aborted){work.catch(()=>{});throw new AppRenewalUnavailable}let abort;const cancelled=new Promise((_resolve,reject)=>{abort=()=>reject(new AppRenewalUnavailable);signal.addEventListener("abort",abort,{once:true})});try{return await Promise.race([work,cancelled])}finally{signal.removeEventListener("abort",abort)}}async function appResponse(response2,maximum,signal){if(signal.aborted||!response2.body||response2.headers.get("content-type")?.split(";")[0]?.trim().toLowerCase()!=="application/json")throw new Error;const reader=response2.body.getReader();const abort=()=>{reader.cancel().catch(()=>{})};signal.addEventListener("abort",abort,{once:true});let bytes=0,text5="";const decoder=new TextDecoder("utf-8",{fatal:true});try{while(true){let chunk;try{chunk=await reader.read()}catch{throw new AppResponseReadError}if(signal.aborted)throw new Error;if(chunk.done){const value=JSON.parse(text5+decoder.decode());await responseChecks.get(response2)?.(value);if(signal.aborted)throw new Error;return value}bytes+=chunk.value.byteLength;if(bytes>maximum){abort();throw new Error}text5+=decoder.decode(chunk.value,{stream:true})}}finally{signal.removeEventListener("abort",abort);reader.releaseLock()}}function isAppOrigin(value){try{const url=new URL(value);return url.protocol==="http:"&&url.hostname==="127.0.0.1"&&Boolean(url.port)&&url.port!=="0"&&url.origin===value}catch{return false}}function appContext(origin,active2){let binding;let credential;let pair;let serialized;let denied=false;const controller=new AbortController;let access=new AbortController;let expiry;let startup;let renewalTimer;let renewal;let observation;let resolution2;let disposed=false;const stored=()=>globalThis.localStorage.getItem(sessionKey);const alive=()=>{try{return!denied&&!disposed&&active2()&&globalThis.location.origin===origin}catch{return false}};const cancel=()=>{controller.abort();access.abort();clearTimeout(expiry);clearTimeout(startup);clearTimeout(renewalTimer);clearInterval(monitor);globalThis.removeEventListener?.("storage",storageChanged);for(const event of["pageshow","focus","visibilitychange"])globalThis.removeEventListener?.(event,wake)};const invalidate=()=>{denied=true;cancel();try{if(!disposed&&active2()&&globalThis.location.origin===origin&&(!serialized||globalThis.localStorage.getItem(sessionKey)===serialized)){globalThis.localStorage.removeItem(sessionKey)}}catch{}};const current=()=>{try{return alive()&&!!binding&&binding.expiresAt>Date.now()&&stored()===serialized}catch{return false}};const sameSession=(value)=>!binding||["appId","memberId","workspace","sessionId"].every((key)=>value[key]===binding[key]);const bounded=(value)=>validBinding(value)&&value.expiresAt>Date.now()&&value.expiresAt<=Date.now()+600000&&sameSession(value);const readPair=(candidate)=>{const value=JSON.parse(candidate??"null");if(!validPair(value)||value.context.expiresAt>Date.now()+600000||!sameSession(value.context))throw new Error;return value};const expireAccess=()=>{if(binding&&binding.expiresAt<=Date.now())access.abort()};async function send2(path,candidate,signal,init={}){const url=`${origin}/_os/app/${path}`;let response2;try{response2=await fetch(url,{...init,credentials:"omit",redirect:"error",cache:"no-store",...init.body instanceof ReadableStream?{duplex:"half"}:{},referrerPolicy:"no-referrer",signal,headers:{...init.body===undefined?{}:{"content-type":"application/json"},...Object.fromEntries(new Headers(init.headers)),authorization:`Bearer ${candidate}`}})}catch{throw new AppRenewalUnavailable}if(response2.redirected||response2.url&&response2.url!==url)throw new Error;return response2}async function proof(candidate,signal=controller.signal){if(!alive()||!validProof(candidate))throw new Error;const response2=await send2("context",candidate,signal);if(response2.status===401||response2.status===403)throw new AppContextDenied;if(response2.status>=500)throw new AppRenewalUnavailable;if(!response2.ok)throw new Error;const value=await appResponse(response2,4096,signal);if(!alive()||!bounded(value))throw new Error;return value}function install(value,candidate,raw){expireAccess();if(access.signal.aborted)access=new AbortController;binding={...value};pair=candidate;credential=candidate.credential;serialized=raw;clearTimeout(expiry);clearTimeout(renewalTimer);const remaining=binding.expiresAt-Date.now();expiry=setTimeout(expireAccess,remaining);renewalTimer=setTimeout(()=>{renew().catch(()=>{})},remaining-Math.min(60000,remaining/5))}async function synchronize(signal=controller.signal){if(!alive())throw new Error;if(signal.aborted)throw new AppRenewalUnavailable;if(!credential)return;if(stored()===serialized)return;if(!binding)throw new Error;if(observation)return untilAborted(observation,signal);observation=(async()=>{while(alive()){const candidate=stored();if(!candidate)throw new Error;let value;let replacement;try{replacement=readPair(candidate);value=await proof(replacement.credential,signal)}catch(error){if(stored()!==candidate)continue;throw error}if(stored()!==candidate)continue;if(value.expiresAt!==replacement.context.expiresAt)throw new Error;install(value,replacement,candidate);return}throw new Error})();const observed=observation;try{await untilAborted(observed,signal)}catch(error){if(!(error instanceof AppRenewalUnavailable||error instanceof AppResponseReadError))invalidate();throw error}finally{if(observation===observed)observation=undefined}}async function renew(){if(renewal)return renewal;if(!binding||!pair||!alive())throw new Error;renewal=(async()=>{const requestController=new AbortController;const abort=()=>requestController.abort();controller.signal.addEventListener("abort",abort,{once:true});const timeout=setTimeout(abort,20000);const previous=serialized;try{await synchronize(requestController.signal);if(serialized!==previous)return;const response2=await send2("renew",pair.renewalCredential,requestController.signal,{method:"POST"});const value=await appResponse(response2,4096,requestController.signal);if(response2.status===503&&value&&typeof value==="object"&&!Array.isArray(value)&&Object.keys(value).join(",")==="error"&&"error"in value&&value.error==="renewal_unavailable")throw new AppRenewalUnavailable;if(response2.status===403&&value&&typeof value==="object"&&!Array.isArray(value)&&Object.keys(value).join(",")==="error"&&"error"in value&&value.error==="renewal_conflict"){while(alive()&&stored()===previous&&!requestController.signal.aborted){await new Promise((resolve2,reject)=>{const abortWait=()=>{clearTimeout(timer);reject(new Error)};const timer=setTimeout(()=>{requestController.signal.removeEventListener("abort",abortWait);resolve2()},100);requestController.signal.addEventListener("abort",abortWait,{once:true})})}if(requestController.signal.aborted)throw new Error;await synchronize(requestController.signal);return}if(!response2.ok)throw new Error;if(!alive()||!validPair(value)||!bounded(value.context)||new Set([value.credential,value.renewalCredential,pair.credential,pair.renewalCredential]).size!==4)throw new Error;if(stored()!==previous){await synchronize(requestController.signal);return}const raw=JSON.stringify(value);globalThis.localStorage.setItem(sessionKey,raw);install(value.context,value,raw)}catch(error){try{if(alive()&&stored()&&stored()!==previous){await synchronize(requestController.signal);return}}catch{}if((error instanceof AppRenewalUnavailable||error instanceof AppResponseReadError||requestController.signal.aborted)&&alive()){if(current())renewalTimer=setTimeout(()=>{renew().catch(()=>{})},Math.min(5000,(binding.expiresAt-Date.now())/5))}else invalidate();throw new AppRenewalUnavailable}finally{clearTimeout(timeout);controller.signal.removeEventListener("abort",abort)}})();try{await renewal}finally{renewal=undefined}}const storageChanged=()=>{if(!credential)return;if(!alive()){invalidate();return}expireAccess();synchronize().catch(()=>{})};const monitor=setInterval(()=>{storageChanged()},100);globalThis.addEventListener?.("storage",storageChanged);const wake=()=>{if(alive())resolve().catch(()=>{})};for(const event of["pageshow","focus","visibilitychange"])globalThis.addEventListener?.(event,wake);const dispose=()=>{disposed=true;cancel()};async function settledAccess(signal){await synchronize();while(alive()&&stored()!==serialized)await synchronize();if(signal.aborted||!current())throw new Error}async function requestData(operation2,input){try{if(operation2!=="data/query"||!current())throw new Error;const admitted=credential;const signal=access.signal;const response2=await send2("data",credential,signal,{method:"POST",body:JSON.stringify(input)});await settledAccess(signal);if(response2.status===401||response2.status===403){if(admitted===credential&¤t())invalidate();throw new DataOperationError("access_denied")}const result2=await appResponse(response2,Number.MAX_SAFE_INTEGER,signal);await settledAccess(signal);if(!response2.ok)throw dataTransportError(response2.status,result2);return result2}catch(error){if(error instanceof DataOperationError)throw error;if(!current()||controller.signal.aborted)throw new DataOperationError("context_unavailable");throw new DataOperationError("unavailable",true)}}async function requestInbox(operation2,input){if(!["questions.list","questions.answer","questions.searchRecords"].includes(operation2))throw new Error("Inbox operation unavailable");return requestChecked("inbox",{method:"POST",body:JSON.stringify({operation:operation2,input})},true)}async function requestRoutine(key,suffix,init={}){return requestChecked(`routines/${encodeURIComponent(key)}/${suffix}`,init)}async function requestRetainedRoutine(key,suffix){return requestChecked(`routines/${encodeURIComponent(key)}/${suffix}`,{},false,true)}async function requestFiles(suffix,init,parent){const unavailable3=()=>new FileOperationError("unsupported_context",400);if(!current()||!/^(?:|\/[0-9a-f-]{36}(?:\/(?:content|upload|enrichments(?:\/[^/?#]+\/content)?))?)$/i.test(suffix))throw unavailable3();const admitted=credential;const signal=parent?AbortSignal.any([access.signal,parent]):access.signal;const failure=()=>current()&&!signal.aborted?new FileOperationError("unavailable",503,true):unavailable3();try{return await hostedContent("",init,signal,(_url,request)=>untilAborted(send2(`files${suffix}`,admitted,signal,request).then((value)=>{if(signal.aborted){value.body?.cancel().catch(()=>{});throw unavailable3()}return value}),signal),()=>settledAccess(signal),failure)}catch{throw failure()}}async function requestChecked(path,init,inbox=false,retained2=false){if(!current())throw new Error("Local app context unavailable.");const admitted=credential;const signal=access.signal;const response2=await send2(path,credential,signal,init);const check=async()=>{if(retained2){if(signal.aborted||!current())throw new Error("Local app context unavailable.")}else await settledAccess(signal)};await check();if((response2.status===401||!inbox&&response2.status===403)&&admitted===credential&¤t())invalidate();responseChecks.set(response2,async(value)=>{await check();if(admitted===credential&¤t()&&value&&typeof value==="object"&&"error"in value&&value.error==="authority_unavailable")invalidate()});return response2}function context(){const issued=credential;const signal=access.signal;return{kind:"local",...binding,get expiresAt(){return binding.expiresAt},isCurrent:()=>!signal.aborted&¤t(),signal,invalidate:()=>{if(issued===credential&¤t())invalidate()},requestRoutine,requestRetainedRoutine,requestData,requestInbox,requestFiles,requestAvailability:(key)=>requestRoutine(key,"availability",{method:"GET"})}}const resolveOnce=async()=>{let attempted;try{if(!alive())throw new Error;if(!pair){const candidate2=stored();const retained3=readPair(candidate2);pair=retained3;binding={...retained3.context};credential=retained3.credential;serialized=candidate2}expireAccess();if(binding.expiresAt<=Date.now()){await renew();if(!current())throw new AppRenewalUnavailable;return context()}await synchronize();const candidate=stored();const retained2=readPair(candidate);attempted=candidate??undefined;if(!current())throw new AppRenewalUnavailable;const value=await proof(retained2.credential);if(stored()!==candidate||serialized!==candidate){await synchronize();return context()}if(!current())throw new Error;if(expiry&&binding&&value.expiresAt>binding.expiresAt)throw new Error;if(!expiry||value.expiresAt!==binding.expiresAt)install(value,retained2,candidate);return context()}catch(error){if(alive()&&error instanceof AppRenewalUnavailable)throw new Error;try{if(binding&¤t()&&attempted&&attempted!==serialized)return context();if(binding&&alive()&&stored()&&stored()!==serialized){await synchronize();return context()}}catch{}if(error instanceof AppContextDenied&&binding&&alive()&&renewal)throw new Error;if(alive()&&(error instanceof AppResponseReadError||pair&&stored()===serialized&&!current()))throw new Error;invalidate();throw new Error}};const resolve=()=>{if(resolution2)return resolution2;resolution2=resolveOnce().finally(()=>{resolution2=undefined});return resolution2};const start=()=>{startup=setTimeout(()=>{if(alive()&&!resolution2&&!binding)resolve().catch(()=>{})},0)};const retained=async()=>{if(!expiry&&alive()){if(binding?current()&&resolution2:readPair(stored()).context.expiresAt>Date.now())return resolve()}if(!expiry||!current())throw new Error("Local app context unavailable.");return context()};return{resolve,retained,start,invalidate,dispose}}function validProof(value){return typeof value==="string"&&/^[A-Za-z0-9_-]{43}$/.test(value)}function validBinding(value){if(!value||typeof value!=="object"||Array.isArray(value)||Object.keys(value).sort().join(",")!=="appId,expiresAt,memberId,sessionId,workspace")return false;const binding=value;return typeof binding.appId==="string"&&/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(binding.appId)&&typeof binding.workspace==="string"&&/^[a-z0-9][a-z0-9-]{0,62}$/.test(binding.workspace)&&typeof binding.memberId==="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(binding.memberId)&&validProof(binding.sessionId)&&typeof binding.expiresAt==="number"&&Number.isFinite(binding.expiresAt)}function validPair(value){if(!value||typeof value!=="object"||Array.isArray(value)||Object.keys(value).sort().join(",")!=="context,credential,renewalCredential")return false;const pair=value;return validProof(pair.credential)&&validProof(pair.renewalCredential)&&pair.credential!==pair.renewalCredential&&validBinding(pair.context)}class WorkspaceAccessError extends Error{status;constructor(status){super("Workspace access is unavailable.");this.status=status}}var unavailable3=()=>new InboxOperationError(503,"unavailable");var stale=()=>new InboxOperationError(401,"authority_unavailable");var contextFailure=(error)=>error instanceof WorkspaceAccessError?new InboxOperationError(error.status,error.status===401?"authority_unavailable":error.status===403?"access_denied":"unavailable"):stale();function hostFailure(error,context){if(!context.isCurrent()||context.expiresAt<=Date.now()||error instanceof InboxContextError&&error.status===401)return stale();return error instanceof InboxContextError&&error.status===403?new InboxOperationError(403,"access_denied"):unavailable3()}async function send2(operation2,input,resolved){const envelope=parseInboxRequest({operation:operation2,input});let context;try{context=resolved??await resolveAppContext()}catch(error){throw contextFailure(error)}if(context.kind==="local"){if(!isAppQuestionOperation(operation2))throw new InboxOperationError(403,"access_denied");const check2=()=>{if(!context.isCurrent()||context.signal.aborted||context.expiresAt<=Date.now())throw stale()};try{const response2=await context.requestInbox(operation2,envelope.input);const value=await appResponse(response2,INBOX_RESULT_BYTES,context.signal);check2();if(!response2.ok)throw new InboxOperationError([400,401,403,409].includes(response2.status)?response2.status:503,response2.status===400?"invalid_input":response2.status===401?"authority_unavailable":response2.status===403?"access_denied":response2.status===409?"conflict":"unavailable");if(response2.status!==200)throw unavailable3();const parsed=parseInboxResult(operation2,value);check2();if(operation2==="questions.answer"&&typeof envelope.input.response.selection==="object"&&!parsed.label?.trim())throw unavailable3();return parsed}catch(error){check2();throw error instanceof InboxOperationError?error:unavailable3()}}if(context.endpoint!==`https://${context.workspace}.oddington.ai`||["auth","www","api","os"].includes(context.workspace))throw stale();let host;if(!isAppQuestionOperation(operation2)){try{host=await resolveHostedInboxContext(context)}catch(error){throw hostFailure(error,context)}if(!host)throw unavailable3()}const check=()=>{if(!context.isCurrent()||host&&!host.isCurrent()||!Number.isFinite(context.expiresAt)||context.expiresAt<=Date.now())throw stale()};check();if(host?.context.kind==="focused")throw new InboxOperationError(403,"access_denied");try{const response2=await fetch(`${context.endpoint}/api/inbox`,{method:"POST",headers:{authorization:`Bearer ${context.accessToken}`,"content-type":"application/json"},body:JSON.stringify(envelope),redirect:"error",cache:"no-store",signal:AbortSignal.timeout(30000)});try{check()}catch(error){response2.body?.cancel().catch(()=>{});throw error}if(!response2.ok){response2.body?.cancel().catch(()=>{});throw new InboxOperationError([400,401,403,409].includes(response2.status)?response2.status:503,response2.status===400?"invalid_input":response2.status===401?"authority_unavailable":response2.status===403?"access_denied":response2.status===409?"conflict":"unavailable")}if(response2.status!==200){response2.body?.cancel().catch(()=>{});throw unavailable3()}const bytes=await limitedBody(response2,INBOX_RESULT_BYTES);check();if(!bytes)throw unavailable3();const value=JSON.parse(new TextDecoder("utf-8",{fatal:true}).decode(bytes));const parsed=parseInboxResult(operation2,value);check();if(operation2==="current"&&parsed.workspace.slug!==context.workspace)throw unavailable3();if("itemId"in envelope.input){const item=operation2==="items.read"?parsed:operation2==="items.rename"||operation2==="items.setLifecycle"||operation2==="items.addRecipient"?parsed.item:undefined;if(item&&(item.id!==envelope.input.itemId||("revision"in envelope.input)&&item.revision!==envelope.input.revision))throw unavailable3();if(operation2==="items.addRecipient"&&parsed.addedPersonId!==envelope.input.personId)throw unavailable3();if(operation2==="questions.answer"&&typeof envelope.input.response.selection==="object"&&!parsed.label?.trim())throw unavailable3()}return parsed}catch(error){check();throw error instanceof InboxOperationError?error:unavailable3()}}var inbox={current:async()=>await send2("current",{}),items:{async list(){const items=[];let beforeNumber;let initial;try{initial=await resolveAppContext()}catch(error){throw contextFailure(error)}let host;try{host=initial.kind!=="local"&&await resolveHostedInboxContext(initial)}catch(error){throw hostFailure(error,initial)}if(initial.kind==="local")throw new InboxOperationError(403,"access_denied");if(!host)throw unavailable3();const check=()=>{if(!initial.isCurrent()||!host.isCurrent()||initial.expiresAt<=Date.now())throw stale()};do{check();const page=await send2("items.list",beforeNumber===undefined?{}:{beforeNumber});check();if(beforeNumber!==undefined&&(page.items.some((item)=>item.number>=beforeNumber)||page.nextBeforeNumber!==null&&page.nextBeforeNumber>=beforeNumber))throw unavailable3();items.push(...page.items);if(page.nextBeforeNumber===null)return items;beforeNumber=page.nextBeforeNumber}while(true)},read:async(itemId)=>await send2("items.read",{itemId}),see:async(itemId)=>{await send2("items.see",{itemId})},markDigestRead:async(itemId)=>await send2("items.markDigestRead",{itemId}),rename:async(input)=>await send2("items.rename",input),setLifecycle:async(input)=>await send2("items.setLifecycle",input),listRecipientCandidates:async(itemId)=>await send2("items.listRecipientCandidates",{itemId}),addRecipient:async(input)=>await send2("items.addRecipient",input)},questions:{async list(input){const supplied=parseInboxRequest({operation:"questions.list",input}).input;if(Object.hasOwn(supplied,"beforeNumber"))throw new InboxOperationError(400,"invalid_input");const routines=Object.freeze(supplied.routines);const questions=[];let beforeNumber;let initial;try{initial=await resolveAppContext()}catch(error){throw contextFailure(error)}const check=()=>{if(!initial.isCurrent()||initial.expiresAt<=Date.now())throw stale()};do{check();const page=await send2("questions.list",{routines,...beforeNumber===undefined?{}:{beforeNumber}},initial);check();if(page.questions.some((question2)=>question2.inboxUrl!==`https://${initial.workspace}.oddington.ai/inbox/${question2.itemId}`||!routines.includes(question2.routine))||beforeNumber!==undefined&&page.nextBeforeNumber!==null&&page.nextBeforeNumber>=beforeNumber)throw unavailable3();questions.push(...page.questions);if(page.nextBeforeNumber===null)return questions;beforeNumber=page.nextBeforeNumber}while(true)},answer:async(input)=>await send2("questions.answer",input),searchRecords:async(input)=>await send2("questions.searchRecords",input)}};var sources=new WeakMap;function registerBrowserAuth(handle,source2){sources.set(handle,source2)}function browserAuthSource(handle){return sources.get(handle)}var installedDispose;function init({auth:input}){installedDispose?.();const registered=browserAuthSource(input);const auth=registered??input;if(!registered&&input&&"getState"in input||typeof auth?.getSession!=="function"||typeof auth?.onAuthStateChange!=="function"){installedDispose=installMemberContext(async()=>{throw new Error("Hosted Data context unavailable.")});return}let endpoint;let workspace;let localOrigin;try{const url=new URL(globalThis.location.origin);if(isAppOrigin(globalThis.location.origin))localOrigin=url.origin;const slug=url.hostname.endsWith(".oddington.ai")?url.hostname.slice(0,-".oddington.ai".length):"";if(url.protocol==="https:"&&!url.port&&!url.username&&!url.password&&!url.search&&!url.hash&&url.pathname==="/"&&/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(slug)&&slug!=="auth"){endpoint=url.origin;workspace=slug}}catch{}let active2=true;let revision=0;let person;let token;const binding={};const local2=localOrigin?appContext(localOrigin,()=>active2):undefined;let subscription;let stopDisposal;const resolve=async()=>{if(local2)return local2.resolve();if(registered)await registered.ready();if(!active2||!endpoint||!workspace||globalThis.location.origin!==endpoint)throw new Error("Hosted Data context unavailable.");const started=revision;const{data:{session},error}=await auth.getSession();if(!active2||globalThis.location.origin!==endpoint||started!==revision||error||!session||person!==undefined&&person!==session.user.id){throw new Error("Hosted Data context unavailable.")}const expiresAt=(session.expires_at??0)*1000;if(!Number.isFinite(expiresAt)||expiresAt<=Date.now()||!session.user.id){throw new Error("Hosted Data context unavailable.")}person=session.user.id;if(registered)await registered.checkWorkspaceAccess();if(!active2||globalThis.location.origin!==endpoint||started!==revision||person!==session.user.id)throw new Error("Hosted Data context unavailable.");const isCurrent=()=>active2&&globalThis.location.origin===endpoint&&revision===started&&person===session.user.id;return{workspace,endpoint,accessToken:session.access_token,expiresAt,isCurrent,memberId:session.user.id,binding}};const uninstall=installMemberContext(resolve,local2?local2.retained:resolve);const dispose=()=>{if(!active2)return;active2=false;local2?.dispose();revision++;subscription?.unsubscribe();stopDisposal?.();uninstall();if(installedDispose===dispose)installedDispose=undefined};installedDispose=dispose;stopDisposal=registered?.onDispose(dispose);if(!active2)return;subscription=auth.onAuthStateChange((event,session)=>{const next=session?.user.id??null;if(event==="SIGNED_OUT"||person!==undefined&&next!==person||person!==undefined&&event==="SIGNED_IN"&&token!==session?.access_token){revision++;local2?.invalidate()}person=next;token=session?.access_token}).data.subscription;local2?.start()}var os={init};var CLI_CALLBACK="http://127.0.0.1:53682/oauth/callback";function authorizationConfiguration(value){const setup=value;if(!setup||typeof setup.clientId!=="string"||!/^[A-Za-z0-9_-]{1,128}$/.test(setup.clientId)||setup.redirectUri!==CLI_CALLBACK||!Array.isArray(setup.scopes)||setup.scopes.length!==1||setup.scopes[0]!=="email")throw new Error("Unavailable");return{clientId:setup.clientId,redirectUri:CLI_CALLBACK,scopes:["email"]}}function authorizationDetails(value,id3,setup,userId,account){const details=value;if(!details||details.authorization_id!==id3||details.redirect_uri!==setup.redirectUri||details.client?.id!==setup.clientId||typeof details.client.name!=="string"||!details.client.name.trim()||details.client.name.length>128||/[\x00-\x1f\x7f]/.test(details.client.name)||details.user?.id!==userId||details.user.email!==account.email||typeof details.scope!=="string"||details.scope.trim()!=="email")return Object.freeze({status:"invalid"});return Object.freeze({status:"consent",clientName:details.client.name.trim(),account,scopes:Object.freeze([...setup.scopes]),callbackAddress:new URL(setup.redirectUri).host})}function authorizationReturn(value,decision){const returnUrl=value?.redirect_url;if(typeof returnUrl!=="string"||returnUrl.length>8192||!returnUrl.startsWith(`${CLI_CALLBACK}?`)||/[\x00-\x20\x7f]/.test(returnUrl))return Object.freeze({status:"invalid"});try{const url=new URL(returnUrl);if(url.origin+url.pathname!==CLI_CALLBACK||url.username||url.password||url.hash)return Object.freeze({status:"invalid"});const parameters=url.searchParams;const allowed=["code","state","error","error_description","error_uri"];for(const key of parameters.keys()){if(!allowed.includes(key)||parameters.getAll(key).length!==1)return Object.freeze({status:"invalid"})}const code=parameters.get("code");const error=parameters.get("error");if(!parameters.get("state")||Boolean(code)===Boolean(error)||decision==="deny"&&!error||decision==="approve"&&!code||parameters.has("code")&&!code||parameters.has("error")&&!error||code&&(parameters.has("error_description")||parameters.has("error_uri")))return Object.freeze({status:"invalid"});return Object.freeze({status:"return",returnUrl})}catch{return Object.freeze({status:"invalid"})}}function authorizationFailure(error){const status=error?.status;return Object.freeze({status:status===404||status===410||status===400?"expired":status===401?"signed_out":status===403||status===422?"invalid":"unavailable"})}function createBrowserAuth(runtime){const coordinators=new Map;function publish(c,state){c.state=Object.freeze(state);for(const listener of c.listeners){try{listener(c.state)}catch{}}}function notify(c,event){for(const listener of c.sessions){try{listener(event,event==="SIGNED_OUT"?null:c.session)}catch{}}}function expire(c){if(!c.active||!c.session&&c.state.status==="expired")return;c.revision++;if(c.timer)clearTimeout(c.timer);c.session=null;publish(c,{status:"expired"});notify(c,"SIGNED_OUT")}function accept(c,event,session){if(!c.active)return;if(event==="INITIAL_SESSION"&&c.state.status!=="initializing")return;if(event==="TOKEN_REFRESHED"&&!c.session&&c.state.status!=="initializing")return;const replaced=c.session?.user?.id!==session?.user?.id||event==="SIGNED_OUT"||!!(event==="SIGNED_IN"&&c.session&&session?.access_token!==c.session.access_token);if(replaced)c.revision++;if(c.timer)clearTimeout(c.timer);const pending=c.state.pending;if(!session){c.session=null;publish(c,{status:c.state.status==="expired"?"expired":"signed_out",...pending?{pending}:{}});notify(c,"SIGNED_OUT");return}if(!validSession(session)){c.session=session;expire(c);return}c.session=session;const email=typeof session.user.email==="string"?session.user.email.trim():"";const metadata=session.user.user_metadata;const displayName=["name","full_name","first_name"].map((key)=>metadata?.[key]).find((value)=>typeof value==="string"&&value.trim());const name=displayName?.trim()||email;const account=!replaced&&c.state.account?.email===email&&c.state.account.displayName===name?c.state.account:Object.freeze({email,displayName:name});notify(c,event);publish(c,{status:"signed_in",account,...pending?{pending}:{}});const checkExpiry=()=>{if(!c.active||!c.session)return;const remaining=c.session.expires_at*1000-Date.now();if(remaining<=0)expire(c);else c.timer=setTimeout(checkExpiry,Math.min(remaining,2147483647))};checkExpiry()}function validSession(session){return typeof session.access_token==="string"&&/^[^\s]{1,8192}$/.test(session.access_token)&&typeof session.user?.id==="string"&&!!session.user.id&&Number.isFinite(session.expires_at)&&session.expires_at*1000>Date.now()}function createCoordinator(origin){const c={state:Object.freeze({status:"initializing"}),session:null,revision:0,active:true,refs:0,listeners:new Set,sessions:new Set,ready:Promise.resolve()};c.ready=(async()=>{const revision=c.revision;try{if(!allowedOrigin(origin))throw runtime.failure("unavailable");const response2=await fetch(`${origin}/api/auth`,{method:"GET",credentials:"same-origin",redirect:"error",cache:"no-store"});if(!response2.ok)throw runtime.failure("unavailable");const configuration=validateConfiguration(await response2.json());if(configuration.authorization&&origin!=="https://auth.oddington.ai"&&origin!=="http://127.0.0.1:5176")throw runtime.failure("unavailable");c.authorization=configuration.authorization;if(!c.active||globalThis.location?.origin!==origin)return;c.provider=await runtime.provider(configuration,{revision:()=>c.revision,current:(revision2)=>current(c,origin,revision2),canPersistSession:()=>c.active&&(c.state.status==="initializing"||!!c.session||c.state.pending==="verify_code"),canAuthorize:(accessToken)=>current(c,origin,c.revision)&&!!c.session&&c.session.access_token===accessToken&&c.state.pending!=="sign_out"});if(!c.active||globalThis.location?.origin!==origin){c.provider.dispose();return}const subscription=c.provider.onAuthStateChange((event,session)=>{if(c.state.status==="initializing"&&c.state.pending==="sign_out")return;accept(c,event,session)}).data.subscription;c.unsubscribe=()=>subscription.unsubscribe();const started=c.revision;const{data:data2,error}=await c.provider.getSession();if(!current(c,origin,started))return;if(error){if(terminalSessionFailure(error))expire(c);else if(!c.session||!validSession(c.session))publish(c,{status:"unavailable",error:"unavailable"})}else if(c.state.pending!=="sign_out")accept(c,"INITIAL_SESSION",data2.session)}catch{if(current(c,origin,revision))publish(c,{status:"unavailable",error:"unavailable"})}})();return c}function current(c,origin,revision){if(c.session&&!validSession(c.session))expire(c);return c.active&&c.revision===revision&&globalThis.location?.origin===origin}async function checkWorkspaceAccess(c,origin){if(origin==="https://auth.oddington.ai"||origin==="http://127.0.0.1:5176")return;const revision=c.revision;if(!current(c,origin,revision)||!c.session||c.state.pending==="sign_out")throw runtime.failure("stale");if(c.workspaceAccess?.revision!==revision){const token=c.session.access_token;const result2=(async()=>{let status;try{const response2=await fetch(`${origin}/api/auth`,{method:"POST",headers:{authorization:`Bearer ${token}`},credentials:"same-origin",redirect:"error",cache:"no-store",signal:AbortSignal.timeout(15000)});status=response2.status;const value=status===200?await response2.json():null;if(status===200&&value?.allowed!==true)status=503;if(status!==200)response2.body?.cancel().catch(()=>{})}catch{status=503}if(!current(c,origin,revision)||c.state.pending==="sign_out")throw runtime.failure("stale");if(status!==200)throw new WorkspaceAccessError(status===401?401:status===403?403:503)})();c.workspaceAccess={revision,result:result2}}await c.workspaceAccess.result;if(!current(c,origin,revision))throw runtime.failure("stale")}return{create(){const origin=globalThis.location?.origin??"";let c=coordinators.get(origin);if(!c){c=createCoordinator(origin);coordinators.set(origin,c)}const coordinator=c;coordinator.refs++;let active2=true;let ownedAction;let authorizationId;let authorizationGeneration=0;let inspected;const observers=new Set;const sessionObservers=new Set;const disposalObservers=new Set;let lastState=coordinator.state;const observation=(state)=>{lastState=state;for(const listener of observers){try{listener(state)}catch{}}};coordinator.listeners.add(observation);const assertActive=()=>{if(!active2)throw runtime.failure("disposed")};async function action(kind,work){assertActive();if(coordinator.action&&kind!=="sign_out")throw runtime.failure("busy");if(kind==="sign_out"&&coordinator.state.pending==="sign_out")throw runtime.failure("busy");if(kind==="sign_out"){coordinator.revision++;notify(coordinator,"SIGNED_OUT")}const marker={};coordinator.action=marker;ownedAction=marker;const revision=coordinator.revision;publish(coordinator,{...coordinator.state,error:undefined,pending:kind});try{await coordinator.ready;assertActive();if(!coordinator.provider||!coordinator.active||globalThis.location?.origin!==origin)throw runtime.failure("unavailable");if(!current(coordinator,origin,revision))throw runtime.failure("stale");if(coordinator.action!==marker)throw runtime.failure("stale");await work(coordinator.provider);assertActive();if(coordinator.action!==marker)throw runtime.failure("stale");if(!current(coordinator,origin,revision)&&kind!=="verify_code"&&kind!=="sign_out")throw runtime.failure("stale")}catch(error){const reason=!active2?"disposed":!current(coordinator,origin,revision)?"stale":safeReason(error)??"unavailable";if(active2&¤t(coordinator,origin,revision))publish(coordinator,{...coordinator.state,error:reason});throw runtime.failure(reason)}finally{if(coordinator.action===marker){coordinator.action=undefined;if(coordinator.active){publish(coordinator,{...coordinator.state,pending:undefined});if(kind==="sign_out"&&coordinator.session)notify(coordinator,"TOKEN_REFRESHED")}}if(ownedAction===marker)ownedAction=undefined}}async function authorize(kind,id3){if(!active2)return Object.freeze({status:"disposed"});if(id3!==authorizationId){authorizationId=id3;authorizationGeneration++;inspected=undefined}if(!id3)return Object.freeze({status:"missing"});if(typeof id3!=="string"||!/^[A-Za-z0-9_-]{1,128}$/.test(id3))return Object.freeze({status:"invalid"});const generation=authorizationGeneration;await coordinator.ready;if(!active2)return Object.freeze({status:"disposed"});if(generation!==authorizationGeneration)return Object.freeze({status:"stale"});const revision=coordinator.revision;if(!current(coordinator,origin,revision))return Object.freeze({status:"stale"});if(!coordinator.session||coordinator.state.pending==="sign_out")return Object.freeze({status:coordinator.state.status==="expired"?"expired":coordinator.state.status==="unavailable"?"unavailable":"signed_out"});if(!coordinator.authorization||!coordinator.provider)return Object.freeze({status:"unavailable"});if(coordinator.action)return Object.freeze({status:"busy"});if(kind!=="get"&&(!inspected||inspected.id!==id3||inspected.revision!==revision))return Object.freeze({status:"stale"});if(kind!=="get"&&inspected?.result.status!=="consent")return inspected.result;const marker={};coordinator.action=marker;ownedAction=marker;const requestCurrent=()=>active2&&generation===authorizationGeneration&¤t(coordinator,origin,revision)&&coordinator.action===marker&&!!coordinator.session&&coordinator.state.pending!=="sign_out";const stale2=()=>Object.freeze({status:active2?"stale":"disposed"});try{const provider=coordinator.provider;const response2=await provider.authorization.get(id3,requestCurrent);if(!requestCurrent())return stale2();if(response2.error){inspected=undefined;const failure=authorizationFailure(response2.error);if(failure.status==="signed_out")expire(coordinator);return failure}const account=coordinator.state.account;const result2=response2.data&&typeof response2.data==="object"&&"redirect_url"in response2.data?authorizationReturn(response2.data):authorizationDetails(response2.data,id3,coordinator.authorization,coordinator.session.user.id,account);inspected={id:id3,revision,result:result2};if(kind==="get"||result2.status!=="consent")return result2;if(!requestCurrent())return stale2();const decision=await provider.authorization[kind](id3,requestCurrent);if(!requestCurrent())return stale2();const returned=decision.error?authorizationFailure(decision.error):authorizationReturn(decision.data,kind);if(returned.status==="signed_out")expire(coordinator);inspected={id:id3,revision,result:returned};return returned}catch(error){if(!requestCurrent())return stale2();inspected=undefined;if(safeReason(error)==="stale")return stale2();return Object.freeze({status:"unavailable"})}finally{if(coordinator.action===marker)coordinator.action=undefined;if(ownedAction===marker)ownedAction=undefined}}const handle=Object.freeze({authorization:Object.freeze({get:(id3)=>authorize("get",id3),approve:(id3)=>authorize("approve",id3),deny:(id3)=>authorize("deny",id3)}),getState(){if(active2&&coordinator.session&&!validSession(coordinator.session))expire(coordinator);return lastState},subscribe(listener){assertActive();observers.add(listener);return()=>{observers.delete(listener)}},async sendCode(email){assertActive();if(!validEmail(email))throw runtime.failure("invalid_input");await action("send_code",async(provider)=>{const{error}=await provider.signInWithOtp({email:email.trim(),options:{shouldCreateUser:origin!=="https://auth.oddington.ai"&&origin!=="http://127.0.0.1:5176"}});if(error&&!accountRefusal(error))throw runtime.failure("unavailable")})},async verifyCode(email,code){assertActive();if(!validEmail(email)||typeof code!=="string"||!/^\d{6}$/.test(code))throw runtime.failure("invalid_input");await action("verify_code",async(provider)=>{const revision=coordinator.revision;const{data:data2,error}=await provider.verifyOtp({email:email.trim(),token:code,type:"email"});if(error)throw runtime.failure(accountRefusal(error)?"invalid_code":"unavailable");if(!data2.session||!validSession(data2.session))throw runtime.failure("invalid_code");if(!current(coordinator,origin,revision)&&(coordinator.session?.access_token!==data2.session.access_token||coordinator.revision!==revision+1||coordinator.state.pending!=="verify_code"))throw runtime.failure("stale");accept(coordinator,"SIGNED_IN",data2.session);try{await checkWorkspaceAccess(coordinator,origin)}catch(error2){if(!(error2 instanceof WorkspaceAccessError))throw error2}})},async signOut(){assertActive();await action("sign_out",async(provider)=>{const revision=coordinator.revision;const{error}=await provider.signOut({scope:"local"});if(error)throw runtime.failure("unavailable");if(!current(coordinator,origin,revision)&&coordinator.session)throw runtime.failure("stale");accept(coordinator,"SIGNED_OUT",null)})},dispose(){if(!active2)return;active2=false;authorizationGeneration++;inspected=undefined;if(ownedAction&&coordinator.action===ownedAction)coordinator.revision++;observers.clear();coordinator.listeners.delete(observation);for(const listener of disposalObservers){try{listener()}catch{}}disposalObservers.clear();for(const listener of sessionObservers)coordinator.sessions.delete(listener);sessionObservers.clear();if(--coordinator.refs===0){coordinator.active=false;coordinator.revision++;if(coordinator.timer)clearTimeout(coordinator.timer);coordinator.unsubscribe?.();coordinator.provider?.dispose();coordinator.provider=undefined;coordinator.session=null;coordinator.listeners.clear();coordinator.sessions.clear();coordinators.delete(origin)}}});registerBrowserAuth(handle,{async ready(){assertActive();await coordinator.ready;assertActive()},async checkWorkspaceAccess(){assertActive();await checkWorkspaceAccess(coordinator,origin);assertActive()},onDispose(callback){if(!active2){callback();return()=>{}}disposalObservers.add(callback);return()=>{disposalObservers.delete(callback)}},async getSession(){assertActive();await coordinator.ready;assertActive();const revision=coordinator.revision;if(!current(coordinator,origin,revision)||!coordinator.provider||!coordinator.session||coordinator.state.pending==="sign_out")return{data:{session:null},error:null};let result2;try{result2=await coordinator.provider.getSession()}catch{result2={data:{session:null},error:runtime.failure("unavailable")}}if(!active2||!current(coordinator,origin,revision))return{data:{session:null},error:runtime.failure("stale")};if(result2.error){if(!terminalSessionFailure(result2.error)&&coordinator.session&&validSession(coordinator.session))return{data:{session:coordinator.session},error:null};expire(coordinator);return{data:{session:null},error:runtime.failure("unavailable")}}accept(coordinator,"TOKEN_REFRESHED",result2.data.session);return{data:{session:coordinator.session},error:null}},onAuthStateChange(callback){if(!active2){callback("SIGNED_OUT",null);return{data:{subscription:{unsubscribe(){}}}}}const listener=(event,session)=>callback(event,session);coordinator.sessions.add(listener);sessionObservers.add(listener);callback("INITIAL_SESSION",coordinator.session);return{data:{subscription:{unsubscribe(){coordinator.sessions.delete(listener);sessionObservers.delete(listener)}}}}}});return handle}}}function safeReason(error){const reason=error?.reason;return["invalid_input","invalid_code","unavailable","busy","stale","disposed"].includes(reason)?reason:undefined}function accountRefusal(error){return[400,401,403,404,422].includes(error?.status??0)}function terminalSessionFailure(error){return[400,401,403,404,422].includes(error?.status??0)}function validEmail(email){return typeof email==="string"&&email.length<=320&&/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim())}function allowedOrigin(origin){if(origin==="http://127.0.0.1:5176"||origin==="https://auth.oddington.ai")return true;try{const url=new URL(origin);const slug=url.hostname.endsWith(".oddington.ai")?url.hostname.slice(0,-".oddington.ai".length):"";return slug.length<=63&&/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug)&&!["auth","api","os","www"].includes(slug)&&origin===`https://${slug}.oddington.ai`}catch{return false}}function validateConfiguration(value){const configuration=value;if(!configuration||typeof configuration.providerUrl!=="string"||typeof configuration.publishableKey!=="string")throw new Error("Unavailable");const url=new URL(configuration.providerUrl);if(url.origin!==configuration.providerUrl||url.protocol!=="https:"||url.username||url.password||url.port||!configuration.publishableKey)throw new Error("Unavailable");return{providerUrl:url.origin,publishableKey:configuration.publishableKey,...configuration.authorization===undefined?{}:{authorization:authorizationConfiguration(configuration.authorization)}}}class BrowserAuthError extends Error{reason;constructor(reason){super(`Browser authentication failed: ${reason}`);this.reason=reason;this.name="BrowserAuthError"}}async function provider(configuration,guard){const{AuthClient:AuthClient2}=await Promise.resolve().then(() => (init_auth_provider(),exports_auth_provider));if(!guard.current(guard.revision()))throw new BrowserAuthError("stale");const provenance=new Map;let removalRevision;let authorizationRequest;let authorizationQueue=Promise.resolve();const storage=globalThis.localStorage;const client=new AuthClient2({url:`${configuration.providerUrl}/auth/v1`,headers:{apikey:configuration.publishableKey,Authorization:`Bearer ${configuration.publishableKey}`},storageKey:`sb-${new URL(configuration.providerUrl).hostname.split(".")[0]}-auth-token`,persistSession:true,autoRefreshToken:true,detectSessionInUrl:false,storage:{getItem:(key)=>storage.getItem(key),removeItem(key){if(!guard.current(removalRevision??guard.revision()))throw new BrowserAuthError("stale");storage.removeItem(key)},setItem(key,value){const token=JSON.parse(value).access_token;const revision=token?provenance.get(token):undefined;if(!guard.current(revision??guard.revision())||token&&!guard.canPersistSession())throw new BrowserAuthError("stale");storage.setItem(key,value)}},fetch:Object.assign(async(input,init2)=>{const revision=guard.revision();const request=String(input).startsWith(`${configuration.providerUrl}/auth/v1/oauth/authorizations/`)?authorizationRequest:undefined;const rejectStale=()=>{if(request)request.rejected=true;throw new BrowserAuthError("stale")};if(request&&(!request.current()||!guard.canAuthorize(new Headers(init2?.headers).get("authorization")?.replace(/^Bearer /,"")??"")))rejectStale();const response2=await fetch(input,{...init2,redirect:"error"});const body=await response2.arrayBuffer();if(!guard.current(revision)||request&&!request.current())rejectStale();const result2=new Response([204,205,304].includes(response2.status)?null:body,{status:response2.status,statusText:response2.statusText,headers:response2.headers});const json2=result2.json.bind(result2);result2.json=async()=>{const value=await json2();if(!guard.current(revision)||request&&!request.current())rejectStale();if(value&&typeof value.access_token==="string")provenance.set(value.access_token,revision);return value};return result2},{preconnect:fetch.preconnect})});async function authorization(kind,id3,current){const previous=authorizationQueue;let release;authorizationQueue=new Promise((resolve)=>{release=resolve});await previous;const request={current,rejected:false};authorizationRequest=request;try{if(!current())throw new BrowserAuthError("stale");const result2=await(kind==="get"?client.oauth.getAuthorizationDetails(id3):kind==="approve"?client.oauth.approveAuthorization(id3,{skipBrowserRedirect:true}):client.oauth.denyAuthorization(id3,{skipBrowserRedirect:true}));if(request.rejected||!current())throw new BrowserAuthError("stale");return result2}catch(error){if(request.rejected||!current())throw new BrowserAuthError("stale");throw error}finally{authorizationRequest=undefined;release()}}return{authorization:{get:(id3,current)=>authorization("get",id3,current),approve:(id3,current)=>authorization("approve",id3,current),deny:(id3,current)=>authorization("deny",id3,current)},getSession:()=>client.getSession(),onAuthStateChange:(callback)=>client.onAuthStateChange((event,session)=>{const revision=session?provenance.get(session.access_token):undefined;if(revision!==undefined&&!guard.current(revision))return;callback(event,session);if(session)provenance.delete(session.access_token)}),signInWithOtp:(input)=>client.signInWithOtp(input),verifyOtp:(input)=>client.verifyOtp(input),async signOut(input){removalRevision=guard.revision();try{return await client.signOut(input)}finally{removalRevision=undefined}},dispose(){provenance.clear();client.dispose()}}}var auth=createBrowserAuth({provider,failure:(reason)=>new BrowserAuthError(reason)});function routineRunHandle(operations2){return Object.freeze({current:operations2.current,step:operations2.step,async*watch(){let previous;for(;;){const state=await operations2.current(),encoded=JSON.stringify(state);if(encoded!==previous){previous=encoded;yield state}if(state.status==="succeeded"||state.status==="failed")return;await(operations2.wait?.()??new Promise((resolve)=>setTimeout(resolve,100)))}}})}var name=/^[a-z0-9][a-z0-9-]{0,62}$/;var uuid=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;var invalid8=()=>{throw new Error("Run state unavailable")};var record3=(value)=>value&&typeof value==="object"&&!Array.isArray(value)?value:invalid8();function time(value){if(typeof value!=="string"||value.length>40||!Number.isFinite(Date.parse(value)))return invalid8();return value}function times(value){return{...value.startedAt===undefined?{}:{startedAt:time(value.startedAt)},...value.finishedAt===undefined?{}:{finishedAt:time(value.finishedAt)}}}function bounded(value){assertRoutineJson(value);if(new TextEncoder().encode(JSON.stringify(value)).byteLength>256*1024)return invalid8();return value}function progress(value){if(value===undefined)return{};const v=record3(value);if(Object.keys(v).sort().join(",")!=="completed,total"||!Number.isSafeInteger(v.completed)||!Number.isSafeInteger(v.total)||v.completed<1||v.completed>v.total)return invalid8();return{progress:{completed:v.completed,total:v.total}}}function parseRunStep(value,expected){const v=record3(value);if(typeof v.id!=="string"||!name.test(v.id)||expected!==undefined&&v.id!==expected||typeof v.title!=="string"||!v.title.trim()||v.title.length>256||!["pending","running","completed","failed","skipped"].includes(v.status))return invalid8();return{id:v.id,title:v.title,status:v.status,...times(v),...progress(v.progress),...Object.hasOwn(v,"summary")?{summary:bounded(v.summary)}:{},...Object.hasOwn(v,"data")?{data:bounded(v.data)}:{}}}function parseRemoteRun(value,expected={}){const v=record3(value);if(typeof v.id!=="string"||!uuid.test(v.id)||expected.id!==undefined&&v.id!==expected.id||typeof v.routine!=="string"||!name.test(v.routine)||expected.routine!==undefined&&v.routine!==expected.routine||v.placement!=="remote"||!["queued","running","succeeded","failed"].includes(v.status)||!Array.isArray(v.steps)||v.steps.length>64)return invalid8();const steps=v.steps.map((value2)=>{const step=record3(value2);if(typeof step.detailAvailable!=="boolean"||Object.hasOwn(step,"data"))return invalid8();return{...parseRunStep(step),detailAvailable:step.detailAvailable}});if(new Set(steps.map((step)=>step.id)).size!==steps.length)return invalid8();let failure;if(v.failure!==undefined){const f=record3(v.failure);if(v.status!=="failed"||typeof f.message!=="string"||!f.message||f.message.length>512)return invalid8();failure={message:f.message}}if(Object.hasOwn(v,"result")&&v.status!=="succeeded")return invalid8();return{id:v.id,routine:v.routine,placement:"remote",status:v.status,createdAt:time(v.createdAt),...times(v),steps,...Object.hasOwn(v,"result")?{result:bounded(v.result)}:{},...failure?{failure}:{}}}var identifier=/^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/;var uuid2=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}(?![\s\S])/i;var dataErrorCodes=new Set(["context_unavailable","unauthenticated","access_denied","invalid_query","request_too_large","capacity","unavailable","invalid_change","conflict","apply_pending"]);var SUMMARY_BYTES=17*1024*1024;class AppRoutineError extends Error{reason;constructor(reason){super(reason);this.reason=reason;this.name="AppRoutineError"}}var fail3=(reason)=>{throw new AppRoutineError(reason)};function current(context){if(!context.isCurrent()||context.kind==="local"&&context.signal.aborted)fail3("authority_unavailable")}function appDescriptors(){const value=globalThis[Symbol.for("oddington.app.descriptor")];return value?.routines??[]}async function authority(retained=false){const context=await resolveAppContext(retained).catch(()=>fail3("authority_unavailable"));current(context);if(context.kind!=="local"&&(!context.binding||!context.memberId||!identifier.test(context.workspace)||context.workspace.length>63||["auth","api","os","www"].includes(context.workspace)||context.endpoint!==`https://${context.workspace}.oddington.ai`))fail3("authority_unavailable");return context}async function live(context,read2){current(context);if(context.kind==="local")return context;const resolved=await authority(read2);current(context);if(resolved.kind==="local"||resolved.binding!==context.binding||resolved.memberId!==context.memberId||resolved.workspace!==context.workspace||resolved.endpoint!==context.endpoint)fail3("authority_unavailable");return resolved}async function request(key,suffix,init2,maximum=SUMMARY_BYTES,retained,read2=false){if(!identifier.test(key)||!appDescriptors().some((item)=>item.id===key))fail3("authority_unavailable");const context=retained?await live(retained,read2):await authority(read2);current(context);const deadline=new AbortController;const timeout=context.kind==="local"?undefined:setTimeout(()=>deadline.abort(),20000);try{const response2=await(context.kind==="local"?read2?context.requestRetainedRoutine(key,suffix):context.requestRoutine(key,suffix,init2):fetch(`${context.endpoint}/api/routines/${key}/${suffix}`,{...init2,credentials:"omit",redirect:"error",signal:deadline.signal,headers:{authorization:`Bearer ${context.accessToken}`,...init2?.body?{"content-type":"application/json"}:{}}}));if(response2.redirected)fail3("execution_unavailable");const value=await appResponse(response2,maximum,context.kind==="local"?context.signal:deadline.signal);current(context);if(context.kind!=="local")await live(context,read2);if(!response2.ok){if(context.kind!=="local"){const code=value?.code;if(code==="authentication_required"||code==="access_denied")fail3("authority_unavailable");if(code==="input_invalid"||code==="file_not_remote")fail3("invalid_input");if(suffix==="describe"&&(code==="current_deployment_unavailable"||code==="capability_unavailable"))return unavailable4(key,code==="current_deployment_unavailable"?"not_deployed":"capability_unavailable");fail3("execution_unavailable")}const reason=value?.error;if(reason==="authority_unavailable"){if(context.kind==="local")context.invalidate();fail3(reason)}if(reason==="invalid_input"||reason==="execution_unavailable")fail3(reason);fail3("execution_unavailable")}return value}catch(error){current(context);if(error instanceof AppRoutineError)throw error;fail3("execution_unavailable")}finally{clearTimeout(timeout)}}function summary(value,key,context,id3){if(context.kind!=="local"){try{if(!only(value,"id,routine,placement,status,createdAt,startedAt,finishedAt,steps,result,failure")||!Array.isArray(value.steps)||value.steps.some((step)=>!only(step,"id,title,status,startedAt,finishedAt,progress,summary,detailAvailable"))||value.failure!==undefined&&!only(value.failure,"message"))fail3("execution_unavailable");return parseRemoteRun(value,{routine:key,id:id3})}catch{return fail3("execution_unavailable")}}const run=value;if(!only(run,"id,routine,placement,status,createdAt,startedAt,finishedAt,steps,result,failure,local")||typeof run.id!=="string"||!uuid2.test(run.id)||id3!==undefined&&run.id!==id3||run.routine!==key||run.placement!=="local"||!["queued","running","succeeded","failed"].includes(run.status)||!timestamp(run.createdAt)||!optionalTimes(run)||!Array.isArray(run.steps)||run.steps.length>64||run.steps.some((step)=>!only(step,"id,title,status,startedAt,finishedAt,progress,summary,detailAvailable")||typeof step.detailAvailable!=="boolean"||!validStep(step))||new Set(run.steps.map((step)=>step.id)).size!==run.steps.length||Object.hasOwn(run,"result")&&(run.status!=="succeeded"||!bounded2(run.result))||run.failure!==undefined&&(run.status!=="failed"||!only(run.failure,"message")||!message(run.failure.message))||run.local!==undefined&&!validLocalActivity(run.local))fail3("execution_unavailable");return run}function only(value,allowed){return!!value&&typeof value==="object"&&!Array.isArray(value)&&Object.keys(value).every((key)=>allowed.split(",").includes(key))}var timestamp=(value)=>typeof value==="string"&&value.length<=32&&Number.isFinite(Date.parse(value));var message=(value)=>typeof value==="string"&&value.length>0&&value.length<=512;var bounded2=(value)=>new TextEncoder().encode(JSON.stringify(value)).byteLength<=256*1024;function optionalTimes(value){return(value.startedAt===undefined||timestamp(value.startedAt))&&(value.finishedAt===undefined||timestamp(value.finishedAt))}function validStep(step){return typeof step.id==="string"&&identifier.test(step.id)&&typeof step.title==="string"&&step.title.length>0&&step.title.length<=256&&["pending","running","completed","failed","skipped"].includes(step.status)&&optionalTimes(step)&&(step.progress===undefined||only(step.progress,"completed,total")&&Number.isSafeInteger(step.progress.completed)&&Number.isSafeInteger(step.progress.total)&&step.progress.completed>0&&step.progress.completed<=step.progress.total)&&(!Object.hasOwn(step,"summary")||bounded2(step.summary))&&(!Object.hasOwn(step,"data")||bounded2(step.data))}function validLocalActivity(value){const paths=(value2)=>Array.isArray(value2)&&value2.every((path)=>typeof path==="string"&&path.length>0&&path.length<=4096&&!path.startsWith("/")&&!path.includes("\\")&&!path.split("/").some((part)=>!part||part==="."||part==="..")&&!/[\x00-\x1f\x7f]/.test(path));return value&&only(value,"data,effects,git")&&bounded2(value)&&Array.isArray(value.data)&&Array.isArray(value.effects)&&value.data.every((item)=>only(item,"repository,created,updated,deleted,failures,failure")&&typeof item.repository==="string"&&identifier.test(item.repository)&&paths(item.created)&&paths(item.updated)&&paths(item.deleted)&&(item.failures===undefined||Array.isArray(item.failures)&&item.failures.every((code)=>typeof code==="string"&&dataErrorCodes.has(code)))&&(item.failure===undefined||(()=>{try{parseDataFailureDetail(item.failure);return true}catch{return false}})()))&&value.effects.every((item)=>only(item,"capability,operation,status,durationMs,reference,summary")&&["files","inbox","ai"].includes(item.capability)&&typeof item.operation==="string"&&/^[a-zA-Z][a-zA-Z0-9-]{0,62}$/.test(item.operation)&&["completed","failed"].includes(item.status)&&(item.durationMs===undefined||typeof item.durationMs==="number"&&Number.isFinite(item.durationMs)&&item.durationMs>=0)&&(item.reference===undefined||typeof item.reference==="string"&&uuid2.test(item.reference))&&(!Object.hasOwn(item,"summary")||bounded2(item.summary)))&&(value.git===undefined||only(value.git,"branch,commit,dirty")&&typeof value.git.dirty==="boolean"&&(value.git.branch===undefined||typeof value.git.branch==="string"&&value.git.branch.length<=256&&!/[\x00-\x1f\x7f]/.test(value.git.branch))&&(value.git.commit===undefined||typeof value.git.commit==="string"&&/^[0-9a-f]{40}$/.test(value.git.commit)))}function jsonInput(value,ancestors=new Set){if(value===null||typeof value==="string"||typeof value==="boolean"||typeof value==="number"&&Number.isFinite(value))return;if(!value||typeof value!=="object"||ancestors.has(value))return fail3("invalid_input");const array3=Array.isArray(value),keys4=Reflect.ownKeys(value);if(!array3&&![Object.prototype,null].includes(Object.getPrototypeOf(value))||array3&&(keys4.length!==value.length+1||!Array.from({length:value.length},(_,index)=>Object.hasOwn(value,index)).every(Boolean)))return fail3("invalid_input");ancestors.add(value);for(const key of keys4){if(array3&&key==="length")continue;const descriptor=Object.getOwnPropertyDescriptor(value,key);if(typeof key!=="string"||!descriptor.enumerable||!Object.hasOwn(descriptor,"value"))return fail3("invalid_input");jsonInput(descriptor.value,ancestors)}ancestors.delete(value)}function structure(value){return JSON.stringify(value,(_key,item)=>item&&typeof item==="object"&&!Array.isArray(item)?Object.fromEntries(Object.keys(item).sort().map((key)=>[key,item[key]])):item)}function handle(key,id3,context){if(!identifier.test(key)||!appDescriptors().some((item)=>item.id===key))fail3("authority_unavailable");if(typeof id3!=="string"||!uuid2.test(id3))fail3("invalid_input");const read2=async()=>summary(await request(key,`runs/${id3}`,undefined,SUMMARY_BYTES,context,true),key,context,id3);return routineRunHandle({async current(){current(context);return read2()},async step(step){if(typeof step!=="string"||!identifier.test(step))fail3("invalid_input");const value=await request(key,`runs/${id3}/steps/${step}`,undefined,514*1024,context,true);if(context.kind!=="local"){try{if(!only(value,"id,title,status,startedAt,finishedAt,progress,summary,data"))fail3("execution_unavailable");return parseRunStep(value,step)}catch{return fail3("execution_unavailable")}}if(!only(value,"id,title,status,startedAt,finishedAt,progress,summary,data")||value.id!==step||!validStep(value))fail3("execution_unavailable");return value}})}function unavailable4(key,reason){const descriptor=appDescriptors().find((item)=>item.id===key);return{...structuredClone(descriptor),connections:descriptor.connections.map((connection)=>({...connection,available:false})),readiness:{state:"unavailable",reason,message:reason==="not_deployed"?"Routine is not deployed.":"Routine capability unavailable."}}}function deployedDescription(value,key){if(!only(value,"id,title,input,connections,steps,readiness")||value.id!==key||value.title!==undefined&&(typeof value.title!=="string"||!value.title.trim()||value.title.length>256)||!only(value.input,"type,properties,required,additionalProperties,items,maxItems,maxLength,minimum,maximum,storage,path,default")||!Array.isArray(value.steps)||value.steps.length>64||value.steps.some((step)=>!only(step,"id,title")||typeof step.title!=="string"||!step.title.trim()||step.title.length>256)||!Array.isArray(value.connections)||value.connections.length>64||value.connections.some((item)=>!only(item,"id,provider,name,available")||typeof item.available!=="boolean"||typeof item.provider!=="string"||!identifier.test(item.provider)||typeof item.name!=="string"||!identifier.test(item.name)||item.id!==`${item.provider}/${item.name}`)||new Set(value.connections.map((item)=>item.id)).size!==value.connections.length)fail3("execution_unavailable");const{default:inputDefault,...input}=value.input;const contract=parseAppRoutineContract({routine:key,input,steps:value.steps.length?value.steps.map(({id:id3})=>({id:id3})):[{id:"inspect"}]});if(Object.hasOwn(value.input,"default"))validateRoutineSchemaValue(contract.input,inputDefault)}async function describeAppRoutine(key){const descriptor=appDescriptors().find((item)=>item.id===key);if(!descriptor)return fail3("authority_unavailable");try{const context=await authority();const value=await request(key,"describe",undefined,1024*1024,context);if(context.kind!=="local")deployedDescription(value,key);if(!only(value,"id,title,input,connections,steps,readiness")||!value.readiness||!Array.isArray(value.connections)||context.kind==="local"&&structure({...value,readiness:undefined,connections:value.connections.map(({available,...item})=>item)})!==structure(descriptor)||value.connections.some((item)=>typeof item.available!=="boolean")||!(value.readiness.state==="ready"&&only(value.readiness,"state,placement")&&value.readiness.placement===(context.kind==="local"?"local":"remote")||value.readiness.state==="unavailable"&&only(value.readiness,"state,reason,message")&&["not_deployed","definition_invalid","capability_unavailable"].includes(value.readiness.reason)&&message(value.readiness.message)))fail3("execution_unavailable");return value}catch{return unavailable4(key,"capability_unavailable")}}function appRoutineBinding(key){if(typeof key!=="string"||!identifier.test(key)||!appDescriptors().some((item)=>item.id===key))fail3("authority_unavailable");return Object.freeze({describe:()=>describeAppRoutine(key),async run(...args){if(args.length>1)fail3("invalid_input");let encoded;try{if(args[0]===undefined)encoded="{}";else{jsonInput(args[0]);const input=JSON.stringify(args[0]);if(new TextEncoder().encode(input).byteLength>256*1024)fail3("invalid_input");encoded=`{"input":${input}}`}}catch{return fail3("invalid_input")}const context=await authority();if(context.kind!=="local")encoded=JSON.stringify({...JSON.parse(encoded),startKey:crypto.randomUUID()});const run=summary(await request(key,"runs",{method:"POST",body:encoded},SUMMARY_BYTES,context),key,context);return handle(key,run.id,context)},runs:Object.freeze({async list(){const context=await authority(true);const value=await request(key,"runs",undefined,20*SUMMARY_BYTES,context,true);if(!Array.isArray(value)||value.length>20)return fail3("execution_unavailable");const runs=value.map((run)=>summary(run,key,context));if(new Set(runs.map((run)=>run.id)).size!==runs.length)fail3("execution_unavailable");return runs},async get(id3){if(typeof id3!=="string"||!uuid2.test(id3))fail3("invalid_input");if(!identifier.test(key)||!appDescriptors().some((item)=>item.id===key))fail3("authority_unavailable");return handle(key,id3,await authority(true))}})})}var app=Object.freeze({listRoutines:()=>Promise.all(appDescriptors().map(({id:id3})=>describeAppRoutine(id3))),routine:appRoutineBinding,routines:new Proxy(Object.create(null),{get(_target,key){if(typeof key!=="string"||!appDescriptors().some((item)=>item.id===key))return;return appRoutineBinding(key)},set:()=>false,defineProperty:()=>false,deleteProperty:()=>false})});async function requestInboxPublication(operation2,request2,caller){const attempt=()=>{if(caller?.aborted)throw caller.reason;const timeout=AbortSignal.timeout(30000);return request2(caller?AbortSignal.any([caller,timeout]):timeout)};if(operation2!=="publish")return attempt();try{const response2=await attempt();if(response2.status!==408&&response2.status!==429&&response2.status<500)return response2;await response2.body?.cancel()}catch(error){if(caller?.aborted)throw error}if(caller?.aborted)throw caller.reason;return attempt()}function routinePublicationClient(options={}){const environment=typeof __OS_BROWSER__!=="undefined"&&__OS_BROWSER__?{}:typeof process==="undefined"?{}:process.env;const installed2=options.request?undefined:routineTransport();const local2=options.request?undefined:installed2?.request??localRoutineRequest(environment);const workspace=installed2?"installed":options.workspace??environment.OS_ROUTINE_WORKSPACE;const capability=options.capability??(options.request?undefined:environment.OS_ROUTINE_RUN);if(!workspace||!/^[a-z0-9][a-z0-9-]*$/.test(workspace)||capability!==undefined&&!/^[0-9a-f]{64}$/.test(capability))throw new Error("A workspace and valid optional routine capability are required");const headers=capability?{"x-os-run":capability}:{};const request2=options.request??(capability?async(path,init2)=>{const origin=`https://${workspace}.oddington.ai`;const target=new URL(path,`${origin}/`);if(workspace.length>63||["auth","www","api","os"].includes(workspace)||target.origin!==origin||target.search||target.hash||target.username||target.password||!/^\/api\/inbox\/(check|publish|resolve)$/.test(path)||init2?.method!=="POST")throw new Error("Invalid routine endpoint");return fetch(target,{...init2,redirect:"error"})}:async()=>{throw new Error("Member publication requires a host-supplied request")});async function send3(operation2,body){if(local2)return await local2(operation2,body);const response2=await requestInboxPublication(operation2,(signal)=>request2(`/api/inbox/${operation2}`,{method:"POST",headers:{"content-type":"application/json",...headers},body:JSON.stringify(body),signal}));const result2=await response2.json();if(!response2.ok)throw new Error(result2.error??"Could not confirm routine publication");return result2}const transport={async publish(body){return await send3("publish",body)},async resolve(body){await send3("resolve",body)}};return{...createInboxPublisher(transport),async check(body){await send3("check",{requestKey:body.requestKey,item:enforcePublicationSize(validatePublication(body.item))})}}}export{source,selection,schema,routinePublicationClient,richTextBlock,respond,resolveAsk,recordsBlock,recordBlock,question,os,inbox,files,fileBlock,file,defineRoutine,defineHandler,data,continueAsk,connections,auth,asksBlock,app,AIError as RoutineAIError,InboxOperationError,InboxContractError,FileOperationError,DataOperationError,BrowserAuthError,AppRoutineError,AirtableOperationError,AIError};
|