firebase
Version:
Firebase JavaScript library for web and Node.js
4 lines (2 loc) • 17.6 kB
JavaScript
import{_removeServiceInstance as e,getApp as t,_getProvider,_registerComponent as r,registerVersion as n,_isFirebaseServerApp as o,SDK_VERSION as i}from"https://www.gstatic.com/firebasejs/11.6.0/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}`,o=this.errors[e],i=o?function replaceTemplate(e,t){return e.replace(s,((e,r)=>{const n=t[r];return null!=n?String(n):`<${r}?>`}))}(o,r):"Error",a=`${this.serviceName}: ${i} (${n}).`;return new FirebaseError(n,a,r)}}const s=/\{\$([^}]+)}/g;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(),o=l[t];if(!o)throw new Error(`Attempted to log a message with an invalid logType (value: ${t})`);console[o](`[${n}] ${e.name}:`,...r)};const u="@firebase/data-connect",p="0.3.3";let d="";class AppCheckTokenProvider{constructor(e,t){this.appCheckProvider=t,o(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",_="already-initialized",f="invalid-argument",C="partial-error",k="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(C,e),this.name="DataConnectOperationError",this.response=t}}const v=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){v.setLogLevel(e)}function logDebug(e){v.debug(`DataConnect (${d}): ${e}`)}function logError(e){v.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 m="query",E="mutation",T="SERVER",b="CACHE";let y;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){y=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:m},o=y(n),i={ref:n,subscriptions:[],currentCache:r||null,lastError:null};return function setIfNotExists(e,t,r){e.has(t)||e.set(t,r)}(this._queries,o,i),this._queries.get(o)}addSubscription(e,t,r,n){const o=y({name:e.name,variables:e.variables,refType:m}),i=this._queries.get(o),s={userCallback:t,errCallback:r},unsubscribe=()=>{const e=this._queries.get(o);e.subscriptions=e.subscriptions.filter((e=>e!==s))};if(n&&i.currentCache!==n&&(logDebug("Initial cache found. Comparing dates."),(!i.currentCache||i.currentCache&&function compareDates(e,t){const r=new Date(e),n=new Date(t);return r.getTime()<n.getTime()}(i.currentCache.fetchTime,n.fetchTime))&&(i.currentCache=n)),null!==i.currentCache){t({data:i.currentCache.data,source:b,ref:e,toJSON:getRefSerializer(e,i.currentCache.data,b),fetchTime:i.currentCache.fetchTime}),null!==i.lastError&&r&&r(void 0)}if(i.subscriptions.push({userCallback:t,errCallback:r,unsubscribe:unsubscribe}),!i.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!==m)throw new DataConnectError(f,"ExecuteQuery can only execute query operation");const t=y({name:e.name,variables:e.variables,refType:m}),r=this._queries.get(t);return this.transport.invokeQuery(e.name,e.variables).then((t=>{const n=(new Date).toString(),o=Object.assign(Object.assign({},t),{source:T,ref:e,toJSON:getRefSerializer(e,t.data,T),fetchTime:n});return r.subscriptions.forEach((e=>{e.userCallback(o)})),r.currentCache={data:t.data,source:b,fetchTime:n},o}),(e=>{throw r.lastError=e,r.subscriptions.forEach((t=>{t.errCallback&&t.errCallback(e)})),e}))}enableEmulator(e,t){this.transport.useEmulator(e,t)}}const w={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 O=globalThis.fetch;function getGoogApiClientValue(e,t){let r="gl-js/ fire/"+d;return t!==w.Base&&t!==w.Generated?r+=" js/"+t.toLowerCase():(e||t===w.Generated)&&(r+=" js/gen"),r}function dcFetch(e,t,{signal:r},n,o,i,s,a){if(!O)throw new DataConnectError(g,"No Fetch Implementation detected!");const c={"Content-Type":"application/json","X-Goog-Api-Client":getGoogApiClientValue(s,a)};o&&(c["X-Firebase-Auth-Token"]=o),n&&(c["x-firebase-gmpid"]=n),i&&(c["X-Firebase-AppCheck"]=i);const h=JSON.stringify(t);return logDebug(`Making request out to ${e} with body: ${h}`),O(e,{body:h,method:"POST",headers:c,signal:r}).catch((e=>{throw new DataConnectError(g,"Failed to fetch: "+JSON.stringify(e))})).then((async e=>{let t=null;try{t=await e.json()}catch(e){throw new DataConnectError(g,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(k,r);throw new DataConnectError(g,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,o,i,s=!1,a=w.Base){var c,h;this.apiKey=t,this.appId=r,this.authProvider=n,this.appCheckProvider=o,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.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.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)))},i&&("number"==typeof i.port&&(this._port=i.port),void 0!==i.sslEnabled&&(this._secure=i.sslEnabled),this._host=i.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(f,"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:o,service:i}=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(f,"Incorrect type for port passed in!");return`${h}/v1/projects/${o}/locations/${n}/services/${i}/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,"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===k&&!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:E,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:T,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,[o,i]=r.split(":");return{host:o,port:Number(i),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=w.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(_,"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){e.enableEmulator({host:t,port:r,sslEnabled:n})}function getDataConnect(e,r){let n,o;"location"in e?(o=e,n=t()):(o=r,n=e),n&&0!==Object.keys(n).length||(n=t());const i=_getProvider(n,"data-connect"),s=JSON.stringify(o);if(i.isInitialized(s)){const e=i.getImmediate({identifier:s}),t=i.getOptions(s);if(Object.keys(t).length>0)return logDebug("Re-using cached instance"),e}return validateDCOptions(o),logDebug("Creating new DataConnect instance"),i.initialize({instanceIdentifier:s,options:o})}function validateDCOptions(e){if(!e)throw new DataConnectError(f,"DC Option Required");return["connector","location","service"].forEach((t=>{if(null===e[t]||void 0===e[t])throw new DataConnectError(f,`${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:m,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 o,i;if(t&&"enableEmulator"in t?(o=t,i=r):(o=getDataConnect(e),i=t),!o||!i&&n)throw new DataConnectError(f,"Variables required.");return{dc:o,vars:i}}function subscribe(e,t,r,n){let o,i,s;if("refInfo"in e){const t=e,{data:r,source:n,fetchTime:s}=t;i={data:r,source:n,fetchTime:s},o=toQueryRef(t)}else o=e;if("function"==typeof t?s=t:(s=t.onNext,r=t.onErr,t.onComplete),!s)throw new DataConnectError(f,"Must provide onNext");return o.dataConnect._queryManager.addSubscription(o,s,r,i)}!function registerDataConnect(e){!function setSDKVersion(e){d=e}(i),r(new Component("data-connect",((e,{instanceIdentifier:t,options:r})=>{const n=e.getProvider("app").getImmediate(),o=e.getProvider("auth-internal"),i=e.getProvider("app-check-internal");let s=r;if(t&&(s=JSON.parse(t)),!n.options.projectId)throw new DataConnectError(f,"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}),o,i)}),"PUBLIC").setMultipleInstances(!0)),n(u,p,e),n(u,p,"esm2017")}();export{w as CallerSdkTypeEnum,DataConnect,DataConnectError,DataConnectOperationError,E as MUTATION_STR,MutationManager,m as QUERY_STR,b as SOURCE_CACHE,T as SOURCE_SERVER,areTransportOptionsEqual,connectDataConnectEmulator,executeMutation,executeQuery,getDataConnect,mutationRef,parseOptions,queryRef,setLogLevel,subscribe,terminate,toQueryRef,validateArgs,validateDCOptions};
//# sourceMappingURL=firebase-data-connect.js.map