UNPKG

firebase

Version:

Firebase JavaScript library for web and Node.js

4 lines (2 loc) • 18.2 kB
import{_removeServiceInstance as e,getApp as t,_getProvider,_registerComponent as r,registerVersion as n,_isFirebaseServerApp as i,SDK_VERSION as o}from"https://www.gstatic.com/firebasejs/11.7.1/firebase-app.js";class FirebaseError extends Error{constructor(e,t,r){super(t),this.code=e,this.customData=r,this.name="FirebaseError",Object.setPrototypeOf(this,FirebaseError.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,ErrorFactory.prototype.create)}}class ErrorFactory{constructor(e,t,r){this.service=e,this.serviceName=t,this.errors=r}create(e,...t){const r=t[0]||{},n=`${this.service}/${e}`,i=this.errors[e],o=i?function replaceTemplate(e,t){return e.replace(s,((e,r)=>{const n=t[r];return null!=n?String(n):`<${r}?>`}))}(i,r):"Error",a=`${this.serviceName}: ${o} (${n}).`;return new FirebaseError(n,a,r)}}const s=/\{\$([^}]+)}/g;function isCloudWorkstation(e){return e.endsWith(".cloudworkstations.dev")}class Component{constructor(e,t,r){this.name=e,this.instanceFactory=t,this.type=r,this.multipleInstances=!1,this.serviceProps={},this.instantiationMode="LAZY",this.onInstanceCreated=null}setInstantiationMode(e){return this.instantiationMode=e,this}setMultipleInstances(e){return this.multipleInstances=e,this}setServiceProps(e){return this.serviceProps=e,this}setInstanceCreatedCallback(e){return this.onInstanceCreated=e,this}}var a;!function(e){e[e.DEBUG=0]="DEBUG",e[e.VERBOSE=1]="VERBOSE",e[e.INFO=2]="INFO",e[e.WARN=3]="WARN",e[e.ERROR=4]="ERROR",e[e.SILENT=5]="SILENT"}(a||(a={}));const c={debug:a.DEBUG,verbose:a.VERBOSE,info:a.INFO,warn:a.WARN,error:a.ERROR,silent:a.SILENT},h=a.INFO,l={[a.DEBUG]:"log",[a.VERBOSE]:"log",[a.INFO]:"info",[a.WARN]:"warn",[a.ERROR]:"error"},defaultLogHandler=(e,t,...r)=>{if(t<e.logLevel)return;const n=(new Date).toISOString(),i=l[t];if(!i)throw new Error(`Attempted to log a message with an invalid logType (value: ${t})`);console[i](`[${n}] ${e.name}:`,...r)};const u="@firebase/data-connect",p="0.3.5";let d="";class AppCheckTokenProvider{constructor(e,t){this.appCheckProvider=t,i(e)&&e.settings.appCheckToken&&(this.serverAppAppCheckToken=e.settings.appCheckToken),this.appCheck=null==t?void 0:t.getImmediate({optional:!0}),this.appCheck||null==t||t.get().then((e=>this.appCheck=e)).catch()}getToken(){return this.serverAppAppCheckToken?Promise.resolve({token:this.serverAppAppCheckToken}):this.appCheck?this.appCheck.getToken():new Promise(((e,t)=>{setTimeout((()=>{this.appCheck?this.getToken().then(e,t):e(null)}),0)}))}addTokenChangeListener(e){var t;null===(t=this.appCheckProvider)||void 0===t||t.get().then((t=>t.addTokenListener(e)))}}const g={OTHER:"other",ALREADY_INITIALIZED:"already-initialized",NOT_INITIALIZED:"not-initialized",NOT_SUPPORTED:"not-supported",INVALID_ARGUMENT:"invalid-argument",PARTIAL_ERROR:"partial-error",UNAUTHORIZED:"unauthorized"};class DataConnectError extends FirebaseError{constructor(e,t){super(e,t),this.name="DataConnectError",Object.setPrototypeOf(this,DataConnectError.prototype)}toString(){return`${this.name}[code=${this.code}]: ${this.message}`}}class DataConnectOperationError extends DataConnectError{constructor(e,t){super(g.PARTIAL_ERROR,e),this.name="DataConnectOperationError",this.response=t}}const _=new class Logger{constructor(e){this.name=e,this._logLevel=h,this._logHandler=defaultLogHandler,this._userLogHandler=null}get logLevel(){return this._logLevel}set logLevel(e){if(!(e in a))throw new TypeError(`Invalid value "${e}" assigned to \`logLevel\``);this._logLevel=e}setLogLevel(e){this._logLevel="string"==typeof e?c[e]:e}get logHandler(){return this._logHandler}set logHandler(e){if("function"!=typeof e)throw new TypeError("Value assigned to `logHandler` must be a function");this._logHandler=e}get userLogHandler(){return this._userLogHandler}set userLogHandler(e){this._userLogHandler=e}debug(...e){this._userLogHandler&&this._userLogHandler(this,a.DEBUG,...e),this._logHandler(this,a.DEBUG,...e)}log(...e){this._userLogHandler&&this._userLogHandler(this,a.VERBOSE,...e),this._logHandler(this,a.VERBOSE,...e)}info(...e){this._userLogHandler&&this._userLogHandler(this,a.INFO,...e),this._logHandler(this,a.INFO,...e)}warn(...e){this._userLogHandler&&this._userLogHandler(this,a.WARN,...e),this._logHandler(this,a.WARN,...e)}error(...e){this._userLogHandler&&this._userLogHandler(this,a.ERROR,...e),this._logHandler(this,a.ERROR,...e)}}("@firebase/data-connect");function setLogLevel(e){_.setLogLevel(e)}function logDebug(e){_.debug(`DataConnect (${d}): ${e}`)}function logError(e){_.error(`DataConnect (${d}): ${e}`)}class FirebaseAuthProvider{constructor(e,t,r){this._appName=e,this._options=t,this._authProvider=r,this._auth=r.getImmediate({optional:!0}),this._auth||r.onInit((e=>this._auth=e))}getToken(e){return this._auth?this._auth.getToken(e).catch((e=>e&&"auth/token-not-initialized"===e.code?(logDebug("Got auth/token-not-initialized error. Treating as null token."),null):(logError("Error received when attempting to retrieve token: "+JSON.stringify(e)),Promise.reject(e)))):new Promise(((t,r)=>{setTimeout((()=>{this._auth?this.getToken(e).then(t,r):t(null)}),0)}))}addTokenChangeListener(e){var t;null===(t=this._auth)||void 0===t||t.addAuthTokenListener(e)}removeTokenChangeListener(e){this._authProvider.get().then((t=>t.removeAuthTokenListener(e))).catch((e=>logError(e)))}}const f="query",C="mutation",E="SERVER",T="CACHE";let k;function getRefSerializer(e,t,r){return function toJSON(){return{data:t,refInfo:{name:e.name,variables:e.variables,connectorConfig:Object.assign({projectId:e.dataConnect.app.options.projectId},e.dataConnect.getSettings())},fetchTime:Date.now().toLocaleString(),source:r}}}!function setEncoder(e){k=e}((e=>JSON.stringify(e)));class QueryManager{constructor(e){this.transport=e,this._queries=new Map}track(e,t,r){const n={name:e,variables:t,refType:f},i=k(n),o={ref:n,subscriptions:[],currentCache:r||null,lastError:null};return function setIfNotExists(e,t,r){e.has(t)||e.set(t,r)}(this._queries,i,o),this._queries.get(i)}addSubscription(e,t,r,n){const i=k({name:e.name,variables:e.variables,refType:f}),o=this._queries.get(i),s={userCallback:t,errCallback:r},unsubscribe=()=>{const e=this._queries.get(i);e.subscriptions=e.subscriptions.filter((e=>e!==s))};if(n&&o.currentCache!==n&&(logDebug("Initial cache found. Comparing dates."),(!o.currentCache||o.currentCache&&function compareDates(e,t){const r=new Date(e),n=new Date(t);return r.getTime()<n.getTime()}(o.currentCache.fetchTime,n.fetchTime))&&(o.currentCache=n)),null!==o.currentCache){t({data:o.currentCache.data,source:T,ref:e,toJSON:getRefSerializer(e,o.currentCache.data,T),fetchTime:o.currentCache.fetchTime}),null!==o.lastError&&r&&r(void 0)}if(o.subscriptions.push({userCallback:t,errCallback:r,unsubscribe:unsubscribe}),!o.currentCache){logDebug(`No cache available for query ${e.name} with variables ${JSON.stringify(e.variables)}. Calling executeQuery.`);this.executeQuery(e).then(void 0,(e=>{}))}return unsubscribe}executeQuery(e){if(e.refType!==f)throw new DataConnectError(g.INVALID_ARGUMENT,"ExecuteQuery can only execute query operation");const t=k({name:e.name,variables:e.variables,refType:f}),r=this._queries.get(t);return this.transport.invokeQuery(e.name,e.variables).then((t=>{const n=(new Date).toString(),i=Object.assign(Object.assign({},t),{source:E,ref:e,toJSON:getRefSerializer(e,t.data,E),fetchTime:n});return r.subscriptions.forEach((e=>{e.userCallback(i)})),r.currentCache={data:t.data,source:T,fetchTime:n},i}),(e=>{throw r.lastError=e,r.subscriptions.forEach((t=>{t.errCallback&&t.errCallback(e)})),e}))}enableEmulator(e,t){this.transport.useEmulator(e,t)}}const v={Base:"Base",Generated:"Generated",TanstackReactCore:"TanstackReactCore",GeneratedReact:"GeneratedReact",TanstackAngularCore:"TanstackAngularCore",GeneratedAngular:"GeneratedAngular"};function addToken(e,t){if(!t)return e;const r=new URL(e);return r.searchParams.append("key",t),r.toString()}let m=globalThis.fetch;function getGoogApiClientValue(e,t){let r="gl-js/ fire/"+d;return t!==v.Base&&t!==v.Generated?r+=" js/"+t.toLowerCase():(e||t===v.Generated)&&(r+=" js/gen"),r}function dcFetch(e,t,{signal:r},n,i,o,s,a,c){if(!m)throw new DataConnectError(g.OTHER,"No Fetch Implementation detected!");const h={"Content-Type":"application/json","X-Goog-Api-Client":getGoogApiClientValue(s,a)};i&&(h["X-Firebase-Auth-Token"]=i),n&&(h["x-firebase-gmpid"]=n),o&&(h["X-Firebase-AppCheck"]=o);const l={body:JSON.stringify(t),method:"POST",headers:h,signal:r};return isCloudWorkstation(e)&&c&&(l.credentials="include"),m(e,l).catch((e=>{throw new DataConnectError(g.OTHER,"Failed to fetch: "+JSON.stringify(e))})).then((async e=>{let t=null;try{t=await e.json()}catch(e){throw new DataConnectError(g.OTHER,JSON.stringify(e))}const r=function getMessage(e){if("message"in e)return e.message;return JSON.stringify(e)}(t);if(e.status>=400){if(logError("Error while performing request: "+JSON.stringify(t)),401===e.status)throw new DataConnectError(g.UNAUTHORIZED,r);throw new DataConnectError(g.OTHER,r)}return t})).then((e=>{if(e.errors&&e.errors.length){const t=JSON.stringify(e.errors),r={errors:e.errors,data:e.data};throw new DataConnectOperationError("DataConnect error while performing request: "+t,r)}return e}))}class RESTTransport{constructor(e,t,r,n,i,o,s=!1,a=v.Base){var c,h;this.apiKey=t,this.appId=r,this.authProvider=n,this.appCheckProvider=i,this._isUsingGen=s,this._callerSdkType=a,this._host="",this._location="l",this._connectorName="",this._secure=!0,this._project="p",this._accessToken=null,this._appCheckToken=null,this._lastToken=null,this._isUsingEmulator=!1,this.invokeQuery=(e,t)=>{const r=new AbortController;return this.withRetry((()=>dcFetch(addToken(`${this.endpointUrl}:executeQuery`,this.apiKey),{name:`projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,operationName:e,variables:t},r,this.appId,this._accessToken,this._appCheckToken,this._isUsingGen,this._callerSdkType,this._isUsingEmulator)))},this.invokeMutation=(e,t)=>{const r=new AbortController;return this.withRetry((()=>dcFetch(addToken(`${this.endpointUrl}:executeMutation`,this.apiKey),{name:`projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,operationName:e,variables:t},r,this.appId,this._accessToken,this._appCheckToken,this._isUsingGen,this._callerSdkType,this._isUsingEmulator)))},o&&("number"==typeof o.port&&(this._port=o.port),void 0!==o.sslEnabled&&(this._secure=o.sslEnabled),this._host=o.host);const{location:l,projectId:u,connector:p,service:d}=e;if(l&&(this._location=l),u&&(this._project=u),this._serviceName=d,!p)throw new DataConnectError(g.INVALID_ARGUMENT,"Connector Name required!");this._connectorName=p,null===(c=this.authProvider)||void 0===c||c.addTokenChangeListener((e=>{logDebug(`New Token Available: ${e}`),this._accessToken=e})),null===(h=this.appCheckProvider)||void 0===h||h.addTokenChangeListener((e=>{const{token:t}=e;logDebug(`New App Check Token Available: ${t}`),this._appCheckToken=t}))}get endpointUrl(){return function urlBuilder(e,t){const{connector:r,location:n,projectId:i,service:o}=e,{host:s,sslEnabled:a,port:c}=t;let h=`${a?"https":"http"}://${s||"firebasedataconnect.googleapis.com"}`;if("number"==typeof c)h+=`:${c}`;else if(void 0!==c)throw logError("Port type is of an invalid type"),new DataConnectError(g.INVALID_ARGUMENT,"Incorrect type for port passed in!");return`${h}/v1/projects/${i}/locations/${n}/services/${o}/connectors/${r}`}({connector:this._connectorName,location:this._location,projectId:this._project,service:this._serviceName},{host:this._host,sslEnabled:this._secure,port:this._port})}useEmulator(e,t,r){this._host=e,this._isUsingEmulator=!0,"number"==typeof t&&(this._port=t),void 0!==r&&(this._secure=r)}onTokenChanged(e){this._accessToken=e}async getWithAuth(e=!1){var t;let r=new Promise((e=>e(this._accessToken)));return this.appCheckProvider&&(this._appCheckToken=null===(t=await this.appCheckProvider.getToken())||void 0===t?void 0:t.token),r=this.authProvider?this.authProvider.getToken(e).then((e=>e?(this._accessToken=e.accessToken,this._accessToken):null)):new Promise((e=>e(""))),r}_setLastToken(e){this._lastToken=e}withRetry(e,t=!1){let r=!1;return this.getWithAuth(t).then((e=>(r=this._lastToken!==e,this._lastToken=e,e))).then(e).catch((n=>{if("code"in n&&n.code===g.UNAUTHORIZED&&!t&&r)return logDebug("Retrying due to unauthorized"),this.withRetry(e,!0);throw n}))}_setCallerSdkType(e){this._callerSdkType=e}}function mutationRef(e,t,r){e.setInitialized();return{dataConnect:e,name:t,refType:C,variables:r}}class MutationManager{constructor(e){this._transport=e,this._inflight=[]}executeMutation(e){const t=this._transport.invokeMutation(e.name,e.variables),r=t.then((t=>Object.assign(Object.assign({},t),{source:E,ref:e,fetchTime:Date.now().toLocaleString()})));this._inflight.push(t);const removePromise=()=>this._inflight=this._inflight.filter((e=>e!==t));return t.then(removePromise,removePromise),r}}function executeMutation(e){return e.dataConnect._mutationManager.executeMutation(e)}function parseOptions(e){const[t,r]=e.split("://"),n="https"===t,[i,o]=r.split(":");return{host:i,port:Number(o),sslEnabled:n}}class DataConnect{constructor(e,t,r,n){if(this.app=e,this.dataConnectOptions=t,this._authProvider=r,this._appCheckProvider=n,this.isEmulator=!1,this._initialized=!1,this._isUsingGeneratedSdk=!1,this._callerSdkType=v.Base,"undefined"!=typeof process&&process.env){const e=process.env.FIREBASE_DATA_CONNECT_EMULATOR_HOST;e&&(logDebug("Found custom host. Using emulator"),this.isEmulator=!0,this._transportOptions=parseOptions(e))}}_useGeneratedSdk(){this._isUsingGeneratedSdk||(this._isUsingGeneratedSdk=!0)}_setCallerSdkType(e){this._callerSdkType=e,this._initialized&&this._transport._setCallerSdkType(e)}_delete(){return e(this.app,"data-connect",JSON.stringify(this.getSettings())),Promise.resolve()}getSettings(){const e=JSON.parse(JSON.stringify(this.dataConnectOptions));return delete e.projectId,e}setInitialized(){this._initialized||(void 0===this._transportClass&&(logDebug("transportClass not provided. Defaulting to RESTTransport."),this._transportClass=RESTTransport),this._authProvider&&(this._authTokenProvider=new FirebaseAuthProvider(this.app.name,this.app.options,this._authProvider)),this._appCheckProvider&&(this._appCheckTokenProvider=new AppCheckTokenProvider(this.app,this._appCheckProvider)),this._initialized=!0,this._transport=new this._transportClass(this.dataConnectOptions,this.app.options.apiKey,this.app.options.appId,this._authTokenProvider,this._appCheckTokenProvider,void 0,this._isUsingGeneratedSdk,this._callerSdkType),this._transportOptions&&this._transport.useEmulator(this._transportOptions.host,this._transportOptions.port,this._transportOptions.sslEnabled),this._queryManager=new QueryManager(this._transport),this._mutationManager=new MutationManager(this._transport))}enableEmulator(e){if(this._initialized&&!areTransportOptionsEqual(this._transportOptions,e))throw logError("enableEmulator called after initialization"),new DataConnectError(g.ALREADY_INITIALIZED,"DataConnect instance already initialized!");this._transportOptions=e,this.isEmulator=!0}}function areTransportOptionsEqual(e,t){return e.host===t.host&&e.port===t.port&&e.sslEnabled===t.sslEnabled}function connectDataConnectEmulator(e,t,r,n=!1){isCloudWorkstation(t)&&async function pingServer(e){return(await fetch(e,{credentials:"include"})).ok}(`https://${t}${r?`:${r}`:""}`),e.enableEmulator({host:t,port:r,sslEnabled:n})}function getDataConnect(e,r){let n,i;"location"in e?(i=e,n=t()):(i=r,n=e),n&&0!==Object.keys(n).length||(n=t());const o=_getProvider(n,"data-connect"),s=JSON.stringify(i);if(o.isInitialized(s)){const e=o.getImmediate({identifier:s}),t=o.getOptions(s);if(Object.keys(t).length>0)return logDebug("Re-using cached instance"),e}return validateDCOptions(i),logDebug("Creating new DataConnect instance"),o.initialize({instanceIdentifier:s,options:i})}function validateDCOptions(e){if(!e)throw new DataConnectError(g.INVALID_ARGUMENT,"DC Option Required");return["connector","location","service"].forEach((t=>{if(null===e[t]||void 0===e[t])throw new DataConnectError(g.INVALID_ARGUMENT,`${t} Required`)})),!0}function terminate(e){return e._delete()}function executeQuery(e){return e.dataConnect._queryManager.executeQuery(e)}function queryRef(e,t,r,n){return e.setInitialized(),e._queryManager.track(t,r,n),{dataConnect:e,refType:f,name:t,variables:r}}function toQueryRef(e){const{refInfo:{name:t,variables:r,connectorConfig:n}}=e;return queryRef(getDataConnect(n),t,r)}function validateArgs(e,t,r,n){let i,o;if(t&&"enableEmulator"in t?(i=t,o=r):(i=getDataConnect(e),o=t),!i||!o&&n)throw new DataConnectError(g.INVALID_ARGUMENT,"Variables required.");return{dc:i,vars:o}}function subscribe(e,t,r,n){let i,o,s;if("refInfo"in e){const t=e,{data:r,source:n,fetchTime:s}=t;o={data:r,source:n,fetchTime:s},i=toQueryRef(t)}else i=e;if("function"==typeof t?s=t:(s=t.onNext,r=t.onErr,t.onComplete),!s)throw new DataConnectError(g.INVALID_ARGUMENT,"Must provide onNext");return i.dataConnect._queryManager.addSubscription(i,s,r,o)}!function registerDataConnect(e){!function setSDKVersion(e){d=e}(o),r(new Component("data-connect",((e,{instanceIdentifier:t,options:r})=>{const n=e.getProvider("app").getImmediate(),i=e.getProvider("auth-internal"),o=e.getProvider("app-check-internal");let s=r;if(t&&(s=JSON.parse(t)),!n.options.projectId)throw new DataConnectError(g.INVALID_ARGUMENT,"Project ID must be provided. Did you pass in a proper projectId to initializeApp?");return new DataConnect(n,Object.assign(Object.assign({},s),{projectId:n.options.projectId}),i,o)}),"PUBLIC").setMultipleInstances(!0)),n(u,p,e),n(u,p,"esm2017")}();export{v as CallerSdkTypeEnum,g as Code,DataConnect,DataConnectError,DataConnectOperationError,C as MUTATION_STR,MutationManager,f as QUERY_STR,T as SOURCE_CACHE,E as SOURCE_SERVER,areTransportOptionsEqual,connectDataConnectEmulator,executeMutation,executeQuery,getDataConnect,mutationRef,parseOptions,queryRef,setLogLevel,subscribe,terminate,toQueryRef,validateArgs,validateDCOptions}; //# sourceMappingURL=firebase-data-connect.js.map