@opra/client 1.0.0-alpha.1 → 1.0.0-alpha.3

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/browser.js CHANGED
@@ -3,6 +3,6 @@
3
3
  * http://www.panates.com
4
4
  *****************************************/
5
5
 
6
- var K=Object.defineProperty,$=Object.defineProperties;var Q=Object.getOwnPropertyDescriptors;var N=Object.getOwnPropertySymbols;var X=Object.prototype.hasOwnProperty,Y=Object.prototype.propertyIsEnumerable;var G=(o,e,t)=>e in o?K(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,c=(o,e)=>{for(var t in e||(e={}))X.call(e,t)&&G(o,t,e[t]);if(N)for(var t of N(e))Y.call(e,t)&&G(o,t,e[t]);return o},l=(o,e)=>$(o,Q(e)),d=(o,e)=>K(o,"name",{value:e,configurable:!0});var v=class v{constructor(e){this.document=e==null?void 0:e.document}};d(v,"Backend");var g=v;var O=class O extends Error{constructor(e,t){super(e.message),this.cause=t,this.issues=e.issues||[],this.status=e.status,t&&(this.cause=t,t.stack&&(this.stack=t.stack))}};d(O,"ClientError");var w=O;import{Observable as Z}from"rxjs";import{isReadableStreamLike as _}from"rxjs/internal/util/isReadableStreamLike";import H from"@browsery/type-is";import{isBlob as ee,isFormData as te}from"@opra/common";var D=class D extends g{constructor(e,t){super(t);let r=new URL(e);this.serviceUrl=r.toString().split("?")[0].split("#")[0],this.serviceUrl.endsWith("/")||(this.serviceUrl+="/")}};d(D,"HttpBackend");var R=D;var b=class b{constructor(e){this.hasBody=!1,this.headers=(e==null?void 0:e.headers)instanceof Headers?e==null?void 0:e.headers:new Headers(e==null?void 0:e.headers),this.status=(e==null?void 0:e.status)||200,this.statusText=(e==null?void 0:e.statusText)||"OK",this.url=(e==null?void 0:e.url)||null,this.ok=this.status>=200&&this.status<300,this.body=e==null?void 0:e.body,this.hasBody=(e==null?void 0:e.body)!=null||!!(e!=null&&e.hasBody),this.contentType=(this.headers.get("content-type")||"").split(";")[0]}clone(e){return new b(c(c({},this),e))}};d(b,"HttpResponse");var S=b;var m;(function(o){o.Sent="Sent",o.UploadProgress="UploadProgress",o.ResponseHeader="ResponseHeader",o.DownloadProgress="DownloadProgress",o.Response="Response",o.User="User"})(m||(m={}));var I=class I extends R{constructor(e,t){var r,n,s,a,h,x;super(e,t),this.interceptors=Array.from(new Set([...(t==null?void 0:t.interceptors)||[]])),this.defaults=l(c({},t==null?void 0:t.defaults),{headers:((r=t==null?void 0:t.defaults)==null?void 0:r.headers)instanceof Headers?(n=t==null?void 0:t.defaults)==null?void 0:n.headers:new Headers((s=t==null?void 0:t.defaults)==null?void 0:s.headers),params:((a=t==null?void 0:t.defaults)==null?void 0:a.params)instanceof URLSearchParams?(h=t==null?void 0:t.defaults)==null?void 0:h.params:new URLSearchParams((x=t==null?void 0:t.defaults)==null?void 0:x.params)})}handle(e){return new Z(t=>{(async()=>{let r=this.prepareRequest(e);if(r.body&&e.reportProgress){let q=r.body,L=r.headers.get("content-length")||"0",j=parseInt(L,10)||0,y=0,E=new TransformStream({transform(i,C){C.enqueue(i),y+=i.byteLength,t.next({type:m.UploadProgress,request:r,total:j,loaded:y})}});r=new Request(r.url,{cache:r.cache,credentials:r.credentials,headers:r.headers,integrity:r.integrity,keepalive:r.keepalive,method:r.method,mode:r.mode,redirect:r.redirect,referrer:r.referrer,referrerPolicy:r.referrerPolicy,signal:r.signal,body:q.pipeThrough(E),window:e.window,duplex:"half"})}let n=this.send(r);t.next({request:r,type:m.Sent});let s=await n,a=this.createResponse({url:s.url,headers:s.headers,status:s.status,statusText:s.statusText,hasBody:!!s.body});t.next({request:r,type:m.ResponseHeader,response:a});let h;if(s.body)if(e.reportProgress){let q=s.body,L=s.headers.get("content-length")||"0",j=parseInt(L,10)||0,y=0,E=new Response(new ReadableStream({async start(i){let C=q.getReader();for(;;){let{done:W,value:J}=await C.read();if(W)break;y+=J.byteLength,i.enqueue(J),t.next({type:m.DownloadProgress,request:r,total:j,loaded:y})}i.close()}}));h=await this.parseBody(E)}else h=await this.parseBody(s);let x=this.createResponse({url:s.url,headers:s.headers,status:s.status,statusText:s.statusText,body:h});t.next({request:r,type:m.Response,response:x}),t.complete()})().catch(r=>t.error(r))})}send(e){return fetch(e)}prepareRequest(e){let t=e.headers||new Headers,r=l(c({},e),{headers:t});this.defaults.headers.forEach((a,h)=>{t.has(h)||t.set(h,a)});let n=new URL(r.url,this.serviceUrl);this.defaults.params.size&&(this.defaults.params.forEach((a,h)=>{n.searchParams.has(h)||n.searchParams.set(h,a)}),r.url=n.toString());let s=r.body;if(s){let a="";typeof s=="string"||typeof s=="number"||typeof s=="boolean"?(a='text/plain; charset="UTF-8"',r.body=new Blob([String(s)],{type:a}),t.set("Content-Length",String(r.body.size)),delete r.duplex):_(s)?(a="application/octet-stream",r.duplex="half"):Buffer.isBuffer(s)?(a="application/octet-stream",t.set("Content-Length",String(s.length)),delete r.duplex):ee(s)?(a=s.type||"application/octet-stream",t.set("Content-Length",String(s.size)),delete r.duplex):(te(s)||(a='application/json;charset="UTF-8"',r.body=new Blob([JSON.stringify(s)],{type:a}),t.set("Content-Length",String(r.body.size))),delete r.duplex),a&&!t.has("Content-Type")&&t.set("Content-Type",a)}return new Request(n.toString(),r)}createResponse(e){return new S(e)}async parseBody(e){let t,r=e.headers.get("Content-Type")||"";if(H.is(r,["json","application/*+json"]))t=await e.json(),typeof t=="string"&&(t=JSON.parse(t));else if(H.is(r,["text"]))t=await e.text();else if(H.is(r,["multipart"]))t=await e.formData();else{let n=await e.arrayBuffer();n.byteLength&&(t=n)}return t}};d(I,"FetchBackend");var P=I;var re=Symbol.for("kClient"),f=Symbol.for("kBackend"),u=Symbol.for("kContext");import{ApiDocumentFactory as de}from"@opra/common";import{lastValueFrom as M,Observable as ae}from"rxjs";import oe from"@browsery/type-is";import{MimeTypes as ne}from"@opra/common";var p;(function(o){o.ResponseHeader="response-header",o.Response="response",o.Body="body",o.Events="events"})(p||(p={}));var z=class z{constructor(e,t){this.chain=e.reduceRight((r,n)=>(s,a)=>n.intercept(s,{handle:d(h=>r(h,a),"handle")}),se),this.finalHandler=t}handle(e){return this.chain(e,t=>this.finalHandler.handle(t))}};d(z,"HttpInterceptorHandler");var T=z;function se(o,e){return e(o)}d(se,"chainEnd");var U=class U extends ae{constructor(e,t){super(r=>{let n=this[u].observe;new T(e.interceptors||[],this[f]).handle(this[u]).subscribe({next(s){if(n===p.Events){r.next(s);return}if(n===p.ResponseHeader&&s.type===m.ResponseHeader){r.next(s.response),r.complete();return}if(s.type===m.Response){let{response:a}=s;if(n===p.Response){r.next(a),r.complete();return}let h=oe.is(s.response.contentType||"",[ne.opra_response_json]);if(a.status>=400&&a.status<600){r.error(new w({message:a.status+" "+a.statusText,status:a.status,issues:h?a.body.errors:void 0})),r.complete();return}r.next(s.response.body),r.complete()}},error(s){r.error(s)},complete(){r.complete()}})}),Object.defineProperty(this,f,{enumerable:!1,value:e}),Object.defineProperty(this,u,{enumerable:!1,value:l(c({},t),{observe:p.Body,headers:new Headers(t==null?void 0:t.headers)})})}clone(){return new U(this[f],this[u])}options(e){return Object.assign(this[u],e),this}header(e,t){let r=this[u].headers;return typeof e=="object"?((e instanceof Headers?e:new Headers(e)).forEach((s,a)=>{a.toLowerCase()==="set-cookie"?r.append(a,s):r.set(a,s)}),this):(t==null||t===""?r.delete(e):r.append(e,String(t)),this)}param(e,t){t&&typeof t=="object"&&(t=JSON.stringify(t));let r=this[u].url.searchParams;return typeof e=="object"?(typeof e.forEach=="function"?e.forEach((n,s)=>r.set(String(s),String(n))):Object.entries(e).forEach(n=>r.set(String(n[0]),String(n[1]))),this):(t==null?r.delete(e):r.set(e,String(t)),this)}observe(e){if(e===this[u].observe)return this;let t=this.clone();return t[u].observe=e||p.Body,t}getBody(){return M(this.observe(p.Body))}getResponse(){return M(this.observe(p.Response))}};d(U,"HttpRequestObservable");var B=U;var F=class F{constructor(e){Object.defineProperty(this,f,{enumerable:!1,value:e})}get serviceUrl(){return this[f].serviceUrl}async getSchema(){this._schemaRequest||(this._schemaRequest=this.request("$schema",{headers:new Headers({accept:"application/json"})}).getBody().catch(r=>{throw r.message="Error fetching api schema from url ("+this.serviceUrl+`).
7
- `+r.message,r}));let e=await this._schemaRequest,t=await de.createDocument(e).catch(r=>{throw r.message=`Error loading api document.
8
- `+r.message,r});return this[f].document=t,this._schemaRequest=void 0,t}request(e,t){let r=new B(this[f],l(c({},t),{method:(t==null?void 0:t.method)||"GET",url:new URL(e,this.serviceUrl)}));return t!=null&&t.params&&r.param(t.params),r}delete(e,t){return this.request(e,l(c({},t),{method:"DELETE"}))}get(e,t){return this.request(e,l(c({},t),{method:"GET"}))}patch(e,t,r){return this.request(e,l(c({},r),{method:"PATCH",body:t}))}post(e,t,r){return this.request(e,l(c({},r),{method:"POST",body:t}))}put(e,t,r){return this.request(e,l(c({},r),{method:"PUT",body:t}))}};d(F,"HttpClientBase");var k=F;var A=class A extends k{constructor(e,t){super(new P(e,t))}get defaults(){return this[f].defaults}};d(A,"OpraHttpClient");var V=A;function Ze(o,...e){let t="",r;for(r=0;r<o.length;r++)t+=o[0]+encodeURIComponent(e[r]);return t}d(Ze,"urlPath");export{g as Backend,w as ClientError,P as FetchBackend,R as HttpBackend,k as HttpClientBase,m as HttpEventType,p as HttpObserveType,B as HttpRequestObservable,S as HttpResponse,V as OpraHttpClient,f as kBackend,re as kClient,u as kContext,Ze as urlPath};
6
+ var M=Object.defineProperty,$=Object.defineProperties;var Q=Object.getOwnPropertyDescriptors;var N=Object.getOwnPropertySymbols;var X=Object.prototype.hasOwnProperty,Y=Object.prototype.propertyIsEnumerable;var G=(o,e,t)=>e in o?M(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,h=(o,e)=>{for(var t in e||(e={}))X.call(e,t)&&G(o,t,e[t]);if(N)for(var t of N(e))Y.call(e,t)&&G(o,t,e[t]);return o},l=(o,e)=>$(o,Q(e)),d=(o,e)=>M(o,"name",{value:e,configurable:!0});var v=class v{constructor(e){this.document=e==null?void 0:e.document}};d(v,"Backend");var S=v;var D=class D extends Error{constructor(e,t){super(e.message),this.cause=t,this.issues=e.issues||[],this.status=e.status,t&&(this.cause=t,t.stack&&(this.stack=t.stack))}};d(D,"ClientError");var R=D;import{Observable as Z}from"rxjs";import{isReadableStreamLike as _}from"rxjs/internal/util/isReadableStreamLike";import H from"@browsery/type-is";import{isBlob as ee,isFormData as te}from"@opra/common";var O=class O extends S{constructor(e,t){super(t);let r=new URL(e);this.serviceUrl=r.toString().split("?")[0].split("#")[0],this.serviceUrl.endsWith("/")||(this.serviceUrl+="/")}};d(O,"HttpBackend");var P=O;var B=class B{constructor(e){this.hasBody=!1,this.headers=(e==null?void 0:e.headers)instanceof Headers?e==null?void 0:e.headers:new Headers(e==null?void 0:e.headers),this.status=(e==null?void 0:e.status)||200,this.statusText=(e==null?void 0:e.statusText)||"OK",this.url=(e==null?void 0:e.url)||null,this.ok=this.status>=200&&this.status<300,this.body=e==null?void 0:e.body,this.hasBody=(e==null?void 0:e.body)!=null||!!(e!=null&&e.hasBody),this.contentType=(this.headers.get("content-type")||"").split(";")[0]}clone(e){return new B(h(h({},this),e))}};d(B,"HttpResponse");var T=B;var f;(function(o){o.Sent="Sent",o.UploadProgress="UploadProgress",o.ResponseHeader="ResponseHeader",o.DownloadProgress="DownloadProgress",o.Response="Response",o.User="User"})(f||(f={}));var I=class I extends P{constructor(e,t){var r,n,s,a,c,p;super(e,t),this.interceptors=Array.from(new Set([...(t==null?void 0:t.interceptors)||[]])),this.defaults=l(h({},t==null?void 0:t.defaults),{headers:((r=t==null?void 0:t.defaults)==null?void 0:r.headers)instanceof Headers?(n=t==null?void 0:t.defaults)==null?void 0:n.headers:new Headers((s=t==null?void 0:t.defaults)==null?void 0:s.headers),params:((a=t==null?void 0:t.defaults)==null?void 0:a.params)instanceof URLSearchParams?(c=t==null?void 0:t.defaults)==null?void 0:c.params:new URLSearchParams((p=t==null?void 0:t.defaults)==null?void 0:p.params)})}handle(e){return new Z(t=>{(async()=>{let r=this.prepareRequest(e);if(r.body&&e.reportProgress){let x=r.body,i=r.headers.get("content-length")||"0",g=parseInt(i,10)||0,w=0,E=new TransformStream({transform(b,C){C.enqueue(b),w+=b.byteLength,t.next({type:f.UploadProgress,request:r,total:g,loaded:w})}});r=new Request(r.url,{cache:r.cache,credentials:r.credentials,headers:r.headers,integrity:r.integrity,keepalive:r.keepalive,method:r.method,mode:r.mode,redirect:r.redirect,referrer:r.referrer,referrerPolicy:r.referrerPolicy,signal:r.signal,body:x.pipeThrough(E),window:e.window,duplex:"half"})}let n=this.send(r);t.next({request:r,type:f.Sent});let s=await n,a=this.createResponse({url:s.url,headers:s.headers,status:s.status,statusText:s.statusText,hasBody:!!s.body});t.next({request:r,type:f.ResponseHeader,response:a});let c;if(s.body)if(e.reportProgress){let x=s.body,i=s.headers.get("content-length")||"0",g=parseInt(i,10)||0,w=0,E=new Response(new ReadableStream({async start(b){let C=x.getReader();for(;;){let{done:W,value:J}=await C.read();if(W)break;w+=J.byteLength,b.enqueue(J),t.next({type:f.DownloadProgress,request:r,total:g,loaded:w})}b.close()}}));c=await this.parseBody(E)}else c=await this.parseBody(s);let p=this.createResponse({url:s.url,headers:s.headers,status:s.status,statusText:s.statusText,body:c});t.next({request:r,type:f.Response,response:p}),t.complete()})().catch(r=>t.error(r))})}send(e){return fetch(e)}prepareRequest(e){let t=e.headers||new Headers,r=l(h({},e),{headers:t});this.defaults.headers.forEach((a,c)=>{t.has(c)||t.set(c,a)});let n=new URL(r.url,this.serviceUrl);this.defaults.params.size&&(this.defaults.params.forEach((a,c)=>{n.searchParams.has(c)||n.searchParams.set(c,a)}),r.url=n.toString());let s=r.body;if(s){let a="";typeof s=="string"||typeof s=="number"||typeof s=="boolean"?(a='text/plain; charset="UTF-8"',r.body=new Blob([String(s)],{type:a}),t.set("Content-Length",String(r.body.size)),delete r.duplex):_(s)?(a="application/octet-stream",r.duplex="half"):Buffer.isBuffer(s)?(a="application/octet-stream",t.set("Content-Length",String(s.length)),delete r.duplex):ee(s)?(a=s.type||"application/octet-stream",t.set("Content-Length",String(s.size)),delete r.duplex):(te(s)||(a='application/json;charset="UTF-8"',r.body=new Blob([JSON.stringify(s)],{type:a}),t.set("Content-Length",String(r.body.size))),delete r.duplex),a&&!t.has("Content-Type")&&t.set("Content-Type",a)}return new Request(n.toString(),r)}createResponse(e){return new T(e)}async parseBody(e){let t,r=e.headers.get("Content-Type")||"";if(H.is(r,["json","application/*+json"]))t=await e.json(),typeof t=="string"&&(t=JSON.parse(t));else if(H.is(r,["text"]))t=await e.text();else if(H.is(r,["multipart"]))t=await e.formData();else{let n=await e.arrayBuffer();n.byteLength&&(t=n)}return t}};d(I,"FetchBackend");var U=I;var re=Symbol.for("kClient"),u=Symbol.for("kBackend"),m=Symbol.for("kContext");import{ApiDocumentFactory as de}from"@opra/common";import{lastValueFrom as K,Observable as ae}from"rxjs";import oe from"@browsery/type-is";import{MimeTypes as ne}from"@opra/common";var y;(function(o){o.ResponseHeader="response-header",o.Response="response",o.Body="body",o.Events="events"})(y||(y={}));var z=class z{constructor(e,t){this.chain=e.reduceRight((r,n)=>(s,a)=>n.intercept(s,{handle:d(c=>r(c,a),"handle")}),se),this.finalHandler=t}handle(e){return this.chain(e,t=>this.finalHandler.handle(t))}};d(z,"HttpInterceptorHandler");var k=z;function se(o,e){return e(o)}d(se,"chainEnd");var j=class j extends ae{constructor(e,t){super(r=>{let n=this[m].observe;new k(e.interceptors||[],this[u]).handle(this[m]).subscribe({next(s){if(n===y.Events){r.next(s);return}if(n===y.ResponseHeader&&s.type===f.ResponseHeader){r.next(s.response),r.complete();return}if(s.type===f.Response){let{response:a}=s;if(n===y.Response){r.next(a),r.complete();return}let c=oe.is(s.response.contentType||"",[ne.opra_response_json]);if(a.status>=400&&a.status<600){r.error(new R({message:a.status+" "+a.statusText,status:a.status,issues:c?a.body.errors:void 0})),r.complete();return}r.next(s.response.body),r.complete()}},error(s){r.error(s)},complete(){r.complete()}})}),Object.defineProperty(this,u,{enumerable:!1,value:e}),Object.defineProperty(this,m,{enumerable:!1,value:l(h({},t),{observe:y.Body,headers:new Headers(t==null?void 0:t.headers)})})}clone(){return new j(this[u],this[m])}options(e){return Object.assign(this[m],e),this}header(e,t){let r=this[m].headers;return typeof e=="object"?((e instanceof Headers?e:new Headers(e)).forEach((s,a)=>{a.toLowerCase()==="set-cookie"?r.append(a,s):r.set(a,s)}),this):(t==null||t===""?r.delete(e):r.append(e,String(t)),this)}param(e,t){t&&typeof t=="object"&&(t=JSON.stringify(t));let r=this[m].url.searchParams;return typeof e=="object"?(typeof e.forEach=="function"?e.forEach((n,s)=>r.set(String(s),String(n))):Object.entries(e).forEach(n=>r.set(String(n[0]),String(n[1]))),this):(t==null?r.delete(e):r.set(e,String(t)),this)}observe(e){if(e===this[m].observe)return this;let t=this.clone();return t[m].observe=e||y.Body,t}getBody(){return K(this.observe(y.Body))}getResponse(){return K(this.observe(y.Response))}};d(j,"HttpRequestObservable");var L=j;var F=class F{constructor(e){Object.defineProperty(this,u,{enumerable:!1,value:e})}get serviceUrl(){return this[u].serviceUrl}async fetchDocument(e){let t={},r=d(async s=>{let a=this.request("$schema",{headers:new Headers({accept:"application/json"})});s&&a.param("id",s);let c=await a.getBody().catch(p=>{throw p.message="Error fetching api schema from url ("+this.serviceUrl+`).
7
+ `+p.message,p});if(c.references){let p=c.references;c.references={};for(let[x,i]of Object.entries(p)){if(t[i.id]===null)throw new Error("Circular reference detected");t[i.id]=null;let g=await r(i.id);c.references[x]=t[i.id]=g}}return c},"getDocument"),n=await r(e==null?void 0:e.documentId);return await de.createDocument(n).catch(s=>{throw s.message=`Error loading api document.
8
+ `+s.message,s})}request(e,t){let r=new L(this[u],l(h({},t),{method:(t==null?void 0:t.method)||"GET",url:new URL(e,this.serviceUrl)}));return t!=null&&t.params&&r.param(t.params),r}delete(e,t){return this.request(e,l(h({},t),{method:"DELETE"}))}get(e,t){return this.request(e,l(h({},t),{method:"GET"}))}patch(e,t,r){return this.request(e,l(h({},r),{method:"PATCH",body:t}))}post(e,t,r){return this.request(e,l(h({},r),{method:"POST",body:t}))}put(e,t,r){return this.request(e,l(h({},r),{method:"PUT",body:t}))}};d(F,"HttpClientBase");var q=F;var A=class A extends q{constructor(e,t){super(new U(e,t))}get defaults(){return this[u].defaults}};d(A,"OpraHttpClient");var V=A;function Ze(o,...e){let t="",r;for(r=0;r<o.length;r++)t+=o[0]+encodeURIComponent(e[r]);return t}d(Ze,"urlPath");export{S as Backend,R as ClientError,U as FetchBackend,P as HttpBackend,q as HttpClientBase,f as HttpEventType,y as HttpObserveType,L as HttpRequestObservable,T as HttpResponse,V as OpraHttpClient,u as kBackend,re as kClient,m as kContext,Ze as urlPath};
@@ -19,25 +19,36 @@ class HttpClientBase {
19
19
  get serviceUrl() {
20
20
  return this[constants_js_1.kBackend].serviceUrl;
21
21
  }
22
- async getSchema() {
23
- if (!this._schemaRequest) {
24
- this._schemaRequest = this.request('$schema', {
22
+ async fetchDocument(options) {
23
+ const documentMap = {};
24
+ const getDocument = async (documentId) => {
25
+ const req = this.request('$schema', {
25
26
  headers: new Headers({ accept: 'application/json' }),
26
- })
27
- .getBody()
28
- .catch(e => {
27
+ });
28
+ if (documentId)
29
+ req.param('id', documentId);
30
+ const body = await req.getBody().catch(e => {
29
31
  e.message = 'Error fetching api schema from url (' + this.serviceUrl + ').\n' + e.message;
30
32
  throw e;
31
33
  });
32
- }
33
- const body = await this._schemaRequest;
34
- const document = await common_1.ApiDocumentFactory.createDocument(body).catch(e => {
34
+ if (body.references) {
35
+ const oldReferences = body.references;
36
+ body.references = {};
37
+ for (const [ns, obj] of Object.entries(oldReferences)) {
38
+ if (documentMap[obj.id] === null)
39
+ throw new Error('Circular reference detected');
40
+ documentMap[obj.id] = null;
41
+ const x = await getDocument(obj.id);
42
+ body.references[ns] = documentMap[obj.id] = x;
43
+ }
44
+ }
45
+ return body;
46
+ };
47
+ const body = await getDocument(options?.documentId);
48
+ return await common_1.ApiDocumentFactory.createDocument(body).catch(e => {
35
49
  e.message = 'Error loading api document.\n' + e.message;
36
50
  throw e;
37
51
  });
38
- this[constants_js_1.kBackend].document = document;
39
- this._schemaRequest = undefined;
40
- return document;
41
52
  }
42
53
  request(path, options) {
43
54
  const observable = new http_request_observable_js_1.HttpRequestObservable(this[constants_js_1.kBackend], {
@@ -16,25 +16,36 @@ export class HttpClientBase {
16
16
  get serviceUrl() {
17
17
  return this[kBackend].serviceUrl;
18
18
  }
19
- async getSchema() {
20
- if (!this._schemaRequest) {
21
- this._schemaRequest = this.request('$schema', {
19
+ async fetchDocument(options) {
20
+ const documentMap = {};
21
+ const getDocument = async (documentId) => {
22
+ const req = this.request('$schema', {
22
23
  headers: new Headers({ accept: 'application/json' }),
23
- })
24
- .getBody()
25
- .catch(e => {
24
+ });
25
+ if (documentId)
26
+ req.param('id', documentId);
27
+ const body = await req.getBody().catch(e => {
26
28
  e.message = 'Error fetching api schema from url (' + this.serviceUrl + ').\n' + e.message;
27
29
  throw e;
28
30
  });
29
- }
30
- const body = await this._schemaRequest;
31
- const document = await ApiDocumentFactory.createDocument(body).catch(e => {
31
+ if (body.references) {
32
+ const oldReferences = body.references;
33
+ body.references = {};
34
+ for (const [ns, obj] of Object.entries(oldReferences)) {
35
+ if (documentMap[obj.id] === null)
36
+ throw new Error('Circular reference detected');
37
+ documentMap[obj.id] = null;
38
+ const x = await getDocument(obj.id);
39
+ body.references[ns] = documentMap[obj.id] = x;
40
+ }
41
+ }
42
+ return body;
43
+ };
44
+ const body = await getDocument(options?.documentId);
45
+ return await ApiDocumentFactory.createDocument(body).catch(e => {
32
46
  e.message = 'Error loading api document.\n' + e.message;
33
47
  throw e;
34
48
  });
35
- this[kBackend].document = document;
36
- this._schemaRequest = undefined;
37
- return document;
38
49
  }
39
50
  request(path, options) {
40
51
  const observable = new HttpRequestObservable(this[kBackend], {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opra/client",
3
- "version": "1.0.0-alpha.1",
3
+ "version": "1.0.0-alpha.3",
4
4
  "description": "Opra Client package",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
@@ -41,7 +41,7 @@
41
41
  "@browsery/stream": "^4.3.0",
42
42
  "@browsery/type-is": "^1.6.18-r2",
43
43
  "@browsery/util": "^0.12.5",
44
- "@opra/common": "^0.33.13",
44
+ "@opra/common": "^1.0.0-alpha.3",
45
45
  "accepts": "^1.3.8",
46
46
  "buffer": "^6.0.3",
47
47
  "cookie": "^0.6.0",
@@ -1,4 +1,3 @@
1
- import { ApiDocument } from '@opra/common';
2
1
  import { Backend } from '../core/backend.js';
3
2
  import type { HttpHandler } from './interfaces/http-handler.js';
4
3
  import type { HttpInterceptor } from './interfaces/http-interceptor.js';
@@ -9,7 +8,6 @@ import type { HttpInterceptor } from './interfaces/http-interceptor.js';
9
8
  export declare abstract class HttpBackend extends Backend implements HttpHandler {
10
9
  readonly serviceUrl: string;
11
10
  interceptors: HttpInterceptor<any>[];
12
- document?: ApiDocument;
13
11
  protected constructor(serviceUrl: string, options?: HttpBackend.Options);
14
12
  }
15
13
  /**
@@ -22,10 +22,11 @@ export declare namespace OpraClientBase {
22
22
  */
23
23
  export declare abstract class HttpClientBase<TRequestOptions = {}, TResponseExt = {}> {
24
24
  protected [kBackend]: HttpBackend;
25
- protected _schemaRequest?: Promise<any>;
26
25
  protected constructor(backend: HttpBackend);
27
26
  get serviceUrl(): string;
28
- getSchema(): Promise<ApiDocument>;
27
+ fetchDocument(options?: {
28
+ documentId?: string;
29
+ }): Promise<ApiDocument>;
29
30
  request<TBody = any>(path: string, options?: OpraClientBase.RequestOptions): HttpRequestObservable<TBody, TBody, TRequestOptions, TResponseExt>;
30
31
  delete<TBody = any>(path: string, options?: StrictOmit<OpraClientBase.RequestOptions, 'method' | 'body'>): HttpRequestObservable<TBody, TBody, TRequestOptions, TResponseExt>;
31
32
  get<TBody = any>(path: string, options?: StrictOmit<OpraClientBase.RequestOptions, 'method' | 'body'>): HttpRequestObservable<TBody, TBody, TRequestOptions, TResponseExt>;