@basmilius/http-client 3.9.0 → 3.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +1 -1
- package/package.json +5 -4
- package/src/adapter/HttpAdapter.ts +17 -17
- package/src/decorator/dto/clone.ts +7 -6
- package/src/decorator/dto/{constant.ts → const.ts} +3 -0
- package/src/decorator/dto/helper/areEqual.ts +3 -5
- package/src/decorator/dto/helper/circularProtect.ts +18 -9
- package/src/decorator/dto/helper/markDtoClean.ts +1 -1
- package/src/decorator/dto/helper/markDtoDirty.ts +1 -1
- package/src/decorator/dto/helper/relateValueTo.ts +6 -4
- package/src/decorator/dto/helper/trackDto.ts +1 -1
- package/src/decorator/dto/helper/triggerDto.ts +1 -1
- package/src/decorator/dto/helper/unrelateDtoFrom.ts +4 -1
- package/src/decorator/dto/helper/unrelateValueFrom.ts +4 -4
- package/src/decorator/dto/index.ts +1 -1
- package/src/decorator/dto/instanceProxy.ts +1 -1
- package/src/decorator/dto/serialize/deserializeDto.ts +1 -1
- package/src/decorator/dto/serialize/isSerializedDateTime.ts +2 -1
- package/src/decorator/dto/serialize/isSerializedDto.ts +2 -1
- package/src/decorator/dto/serialize/serializeDateTime.ts +2 -1
- package/src/decorator/dto/serialize/serializeDto.ts +2 -1
- package/src/decorator/dto/serialize/types.ts +4 -2
- package/src/decorator/dto/toJSON.ts +12 -10
- package/src/dto/ValidationError.ts +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -42,15 +42,15 @@ declare class ValidationError {
|
|
|
42
42
|
get errorDescription(): string;
|
|
43
43
|
get errors(): Record<string, ValidationError>;
|
|
44
44
|
get params(): Record<string, string | number | boolean>;
|
|
45
|
-
constructor(code: number, error: string, errorDescription: string, errors
|
|
45
|
+
constructor(code: number, error: string, errorDescription: string, errors: Record<string, ValidationError>, params: Record<string, string | number | boolean>);
|
|
46
46
|
}
|
|
47
47
|
//#endregion
|
|
48
48
|
//#region src/adapter/HttpAdapter.d.ts
|
|
49
49
|
declare class HttpAdapter {
|
|
50
|
-
static parsePaginatedAdapter<T>(
|
|
50
|
+
static parsePaginatedAdapter<T>(data: ForeignData, adapterMethod: (item: object) => T): Paginated<T>;
|
|
51
51
|
static parseFileNameFromContentDispositionHeader(header: string): string;
|
|
52
|
-
static parseRequestError(
|
|
53
|
-
static parseValidationError(
|
|
52
|
+
static parseRequestError(data: ForeignData, statusCode: HttpStatusCode): RequestError;
|
|
53
|
+
static parseValidationError(data: ForeignData): ValidationError;
|
|
54
54
|
}
|
|
55
55
|
//#endregion
|
|
56
56
|
//#region src/decorator/adapter.d.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DateTime as e}from"luxon";import{debounce as t,getPrototypeChain as n,setObjectMethod as r,setObjectValue as i}from"@basmilius/utils";import{customRef as a,markRaw as o,toRaw as s}from"vue";function c(e){return class extends e{constructor(...e){throw Error(`@adapter: cannot create instance of class.`)}}}function ee(){return(e,t)=>{e[t]=e[t].bind(e)}}function te(e){return(n,r,i)=>{i.value=t(i.value,e,n)}}const l=Symbol(),u=Symbol(),d=Symbol(),f=Symbol(),p=Symbol(),m=Symbol(),h=Symbol(),g=Symbol(),_=Symbol(),v=Symbol(),y=Symbol();function b(e){return e&&typeof e==`object`&&!!e[p]}function ne(e,t){return!b(e)||!b(t)?e===t:JSON.stringify(e)===JSON.stringify(t)}function x(e){if(!b(e))throw Error(`@dto assert given object is not a class decorated with @Dto.`)}const S=Symbol();function C(e,t=0,n){return function(...r){let i=S in e,a=e[S]??=new WeakMap,o=r[t],s=n===void 0?`self`:r[n];if(typeof o!=`object`)return e.call(this,...r);if(a.has(o)||a.set(o,[]),a.get(o).includes(s))return;a.get(o).push(s);let c=e.call(this,...r);return!i&&delete e[S],c}}function re(e){return x(e),e.clone()}function w(e){return x(e),e[f]}const T=C(function(e,t,n,r){let i=e[y];i(e,t,n,r),e[m]&&T(e[m],e[h],e[m][e[h]])},0,1),E=C(function(e){x(e),e[f]&&(e[f]=!1,T(e,f,!1,!0)),!(!e[u]||e[u].length===0)&&e[u].filter(w).forEach(E)});async function ie(e,t){!b(e)||!w(e)||(await t(e),E(e))}function ae(e){return x(e),!e[f]}const D=C(function(e,t){x(e),e[f]||(e[f]=!0,T(e,f,!0,!1)),e[m]&&D(e[m],e[h])});function O(e,t,n){t[u]??=[],!t[u].includes(e)&&t[u].push(e),e[m]!==t&&(e[m]=t),e[h]!==n&&(e[h]=n)}function oe(e,t,n){b(n)?O(n,e,t):Array.isArray(n)&&(n.some(b)&&n.filter(b).forEach(n=>O(n,e,t)),n[m]=e,n[h]=t)}function se(e,t){let n=e[v];n(e,t)}function ce(e,t){if(u in t){let n=t[u].indexOf(e);t[u].splice(n,1)}e[m]=void 0,e[h]=void 0}function le(e,t){b(t)?ce(t,e):Array.isArray(t)&&(t.some(b)&&t.filter(b).forEach(t=>ce(t,e)),t[m]=void 0,t[h]=void 0)}const k={};var ue={deleteProperty(e,t){if(Reflect.deleteProperty(e,t),A(e,t))return!0;let n=e[m];return n&&T(n,e[h],n[e[h]]),n&&D(n,e[h]),!0},get(e,t,n){if(t===_)return!0;if(A(e,t))return Reflect.get(e,t,n);let r=e[m];return r&&se(r,e[h]),Reflect.get(e,t)},set(e,t,n,r){if(A(e,t))return Reflect.set(e,t,n,r);let i=e[m];return i&&T(i,e[h],i[e[h]]),i&&D(i,e[h]),Reflect.set(e,t,n)}};function A(e,t){return typeof t==`symbol`||typeof e[t]==`function`||t===`length`}var de={get(e,t,n){if(t===_)return!0;if(typeof t==`symbol`)return Reflect.get(e,t,n);let r=e[d][t];if(!r||!r.get)return Reflect.get(e,t,n);let i=r.get.call(e);return se(e,t),oe(e,t,i),i},getOwnPropertyDescriptor(e,t){return e[d][t]},ownKeys(e){return e[g]},set(e,t,n,r){if(typeof t==`symbol`)return Reflect.set(e,t,n,r);let i=e[d][t];if(!i||!i.set)return Reflect.set(e,t,n,r);let a=i.get?.call(e)??void 0;return ne(n,a)?!0:(le(e,a),Array.isArray(n)&&!n[_]&&(n=new Proxy(n,ue)),i.set.call(e,n),oe(e,t,n),D(e,t),T(e,t,n,a),!0)}},fe={get(e,t,n){return t===`__v_isRef`?!1:t===_?!0:t in e?Reflect.get(e,t,n):Reflect.get(e.value,t)},getOwnPropertyDescriptor(e,t){return Reflect.getOwnPropertyDescriptor(e.value,t)},ownKeys(e){return Reflect.ownKeys(e.value)},set(e,t,n,r){return t in e?Reflect.set(e,t,n,r):Reflect.set(e.value,t,n)}},pe={construct(e,t,n){t=t.map(e=>Array.isArray(e)?new Proxy(e,ue):e);let r=a((r,i)=>{let a=o(Reflect.construct(e,t,n));a[l]=t,a[f]=!1,a[v]=r,a[y]=i;let s=new Proxy(a,de);return{get:()=>(r(),s),set:()=>void 0}});return new Proxy(r,fe)}};function me(){let e=this;x(e);let t=k[e[p]],n=new t(...e[l]);return Object.entries(this[d]).filter(([,e])=>!!e.set).map(([e])=>e).forEach(e=>n[e]=b(this[e])?this[e].clone():this[e]),n}function he(e){for(let t in e){let n=this[d][t];b(this[t])&&typeof e[t]==`object`?this[t].fill(e[t]):n&&n.set&&(this[t]=e[t])}}function ge(){return Object.fromEntries(this[g].map(e=>{let t=Reflect.get.call(this,this,e,this);return b(t)&&(t=t.toJSON()),[e,t]}))}function j(e){ve(e);let t=Object.freeze(n(e)),a=Object.keys(t);return i(e.prototype,d,t),i(e.prototype,p,e.name),i(e.prototype,g,a),i(e,Symbol.hasInstance,t=>typeof t==`object`&&t?.[p]===e.name),r(e,`clone`,me),r(e,`fill`,he),r(e,`toJSON`,ge),_e(e)}function _e(e){let t=new Proxy(e,pe);return k[e.name]=t,t}function ve(e){let t=Object.getPrototypeOf(e.prototype);if(p in t)throw Error(`⛔️ @dto ${e.name} cannot extend parent class which is also decorated with @dto ${t[p]}.`)}function M(e){return e.map(F)}function ye([,t]){return e.fromISO(t)}function N(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,F(t)]).filter(([,e])=>e!==void 0))}const P={};function be([,e,t,n,r]){if(!(t in k))throw Error(`Cannot restore @dto. Dto ${t} was not found.`);if(e in P)return P[e];let i=k[t],a=new i(...M(r));return a.fill(N(n)),P[e]=a,a}function xe(e){return Array.isArray(e)&&e[0]===3058}function Se(e){return Array.isArray(e)&&e[0]===3057}function F(e){switch(!0){case e===null:return null;case Array.isArray(e):switch(!0){case xe(e):return ye(e);case Se(e):return be(e);default:return M(e)}case typeof e==`object`:return N(e);default:return e}}function Ce(e){return F(JSON.parse(e))}function I(e){return[3058,e.toISO({extendedZone:!0,includeOffset:!0})]}function L(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,B(t)]).filter(([,e])=>e!==void 0))}function we(){return`10000000-1000-4000-8000-100000000000`.replace(/[018]/g,e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16))}function R(e){e=s(e);let t=e.toJSON();return[3057,we(),e[p],L(t),z(e[l])]}function z(t){switch(!0){case t.every(b):return t.map(R);case t.every(e.isDateTime):return t.map(I);default:return t.map(B)}}function B(t){switch(!0){case t===null:return null;case Array.isArray(t):return z(t);case b(t):return R(t);case e.isDateTime(t):return I(t);case typeof t==`object`:return L(t);case typeof t==`boolean`:case typeof t==`number`:case typeof t==`string`:return t;default:return}}function Te(e){return JSON.stringify(B(e))}function V(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}let H=class{get blob(){return this.#e}get name(){return this.#t}#e;#t;constructor(e,t){this.#e=e,this.#t=t}};H=V([j],H);var Ee=H;let U=class{get items(){return this.#e}get page(){return this.#t}get pageSize(){return this.#n}get pages(){return this.#r}get total(){return this.#i}#e;#t;#n;#r;#i;constructor(e,t,n,r,i){this.#e=e,this.#t=t,this.#n=n,this.#r=r,this.#i=i}};U=V([j],U);var De=U;let W=class{get code(){return this.#e}get error(){return this.#t}get errorDescription(){return this.#n}get statusCode(){return this.#r}#e;#t;#n;#r;constructor(e,t,n,r){this.#e=e,this.#t=t,this.#n=n,this.#r=r}};W=V([j],W);var G=W;let K=class{get code(){return this.#e}get error(){return this.#t}get errorDescription(){return this.#n}get errors(){return this.#r}get params(){return this.#i}#e;#t;#n;#r;#i;constructor(e,t,n,r,i){this.#e=e,this.#t=t,this.#n=n,this.#r=r,this.#i=i}};K=V([j],K);var q=K,J;let Y=J=class{static parsePaginatedAdapter(e,t){return new De(e.items.map(t),e.page,e.page_size,e.pages,e.total)}static parseFileNameFromContentDispositionHeader(t){let n=`download-${e.now().toFormat(`yyyy-MM-dd HH-mm-ss`)}`;if(!t.startsWith(`attachment`))return n;let r=/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(t);return(r?.length||0)<2?n:r[1].replaceAll(`'`,``).replaceAll(`"`,``).replaceAll(`/`,`-`).replaceAll(`:`,`-`)}static parseRequestError(e,t){return new G(e.code,e.error,e.error_description,t)}static parseValidationError(e){let t;return e.errors&&(t={},Object.entries(e.errors).forEach(([e,n])=>{t[e]=J.parseValidationError(n)})),new q(e.code,e.error,e.error_description,t,e.params)}};Y=J=V([c],Y);var X=class{get data(){return this.#e}get headers(){return this.#t.headers}get ok(){return this.statusCode>=200&&this.statusCode<300}get response(){return this.#t}get statusCode(){return this.#t.status}#e;#t;constructor(e,t){this.#e=e,this.#t=t}},Oe=class e{get authToken(){return this.#e}set authToken(e){this.#e=e}get baseUrl(){return this.#t}get dataField(){return this.#n}#e;#t;#n;constructor(e,t,n=!1){this.#e=e,this.#t=t,this.#n=n}static get instance(){if(e.#r===null)throw Error(`There is currently no HttpClient instance registered. Register one using the HttpClient.register() function.`);return e.#r}static#r=null;static register(t){e.#r=t}},Z=class extends Error{};const Q={};var $=class t{get client(){return this.#e}get options(){return this.#r}get path(){return this.#n}set path(e){this.#n=e}get query(){return this.#i}set query(e){this.#i=e}#e;#t=null;#n;#r={};#i=null;constructor(e,t){this.#e=t??Oe.instance,this.#r.cache=`no-cache`,this.#r.method=`GET`,this.#n=e}autoCancel(e){return this.#t=e,this}bearerToken(e){return e??=this.#e.authToken,e?this.header(`Authorization`,`Bearer ${e}`):(this.#r.headers&&`Authorization`in this.#r.headers&&delete this.#r.headers.Authorization,this)}body(e,t=`application/octet-stream`){return e instanceof FormData?t=null:(Array.isArray(e)||typeof e==`object`)&&(e=JSON.stringify(e),t=`application/json`),this.#r.body=e,t===null?this:this.header(`Content-Type`,t)}header(e,t){return this.#r.headers=this.#r.headers||{},this.#r.headers[e]=t,this}method(e){return this.#r.method=e.toUpperCase(),this}queryString(e){return this.#i=e,this}signal(e=null){return this.#r.signal=e,this}async fetch(){return this.#a().then(e=>e.json())}async fetchBlob(){let t=await this.#a();if(t.status!==200){let e=await t.json();throw`code`in e&&`error`in e&&`error_description`in e?new G(e.code,e.error,e.error_description,t.status):new G(-1,`failed_without_info`,`Request failed without any information from the backend.`,t.status)}let n=t.headers.has(`content-disposition`)?Y.parseFileNameFromContentDispositionHeader(t.headers.get(`content-disposition`)):`download-${e.now().toFormat(`yyyy-MM-dd HH-mm-ss`)}`;return new Ee(await t.blob(),n)}async run(){let{data:e,response:t}=await this.#o();return new X(e,t)}async runAdapter(e){let{data:t,response:n}=await this.#o();return new X(e(t),n)}async runArrayAdapter(e){return this.runAdapter(t=>t.map(e))}async runEmpty(){return await this.#o()}async runPaginatedAdapter(e){return this.runAdapter(t=>Y.parsePaginatedAdapter(t,e))}async runData(){return await this.#o()}async runDataKey(e){let{data:t,response:n}=await this.#o();return new X(t[e],n)}async runStatusCode(){return(await this.#o()).statusCode}async#a(){if(this.#t!==null){this.#t in Q&&Q[this.#t].abort(new Z);let e=new AbortController;Q[this.#t]=e,this.signal(e.signal)}let e=this.path;return this.query!==null&&(e+=`?${this.query.build()}`),await fetch(this.client.baseUrl+e,this.options)}async#o(){return await this.#a().then(e=>t.#s(e,this.client.dataField))}static async#s(e,t){if(e.status===204)return new X(null,e);if(e.headers.has(`content-type`)&&e.headers.get(`content-type`).startsWith(`application/json`)){let n=await e.json();if(n&&typeof n==`object`&&`code`in n&&`error`in n&&`error_description`in n)throw`errors`in n?Y.parseValidationError(n):Y.parseRequestError(n,e.status);return t&&`data`in n?new X(n.data,e):new X(n,e)}if(e.status===401||e.status===403||(await e.text()).length===0&&e.status>=200&&e.status<300)return new X(null,e);throw new G(-1,`not_a_json_response`,`The response was not a JSON response.`,e.status)}},ke=class{request(e,t){return new $(e,t)}},Ae=class e{#e;constructor(){this.#e=new URLSearchParams}build(){return this.#e.toString()}append(e,t){return this.#t(this.#e.append.bind(this.#e),e,t)}appendArray(e,t){return t?.forEach(t=>this.append(e,t)),this}delete(e){return this.#e.delete(e),this}get(e){return this.#e.get(e)}getAll(e){return this.#e.getAll(e)}has(e){return this.#e.has(e)}set(e,t){return this.#t(this.#e.set.bind(this.#e),e,t)}#t(e,t,n){if(!n&&n!==!1)return this;switch(typeof n){case`boolean`:e(t,n?`true`:`false`);break;case`number`:e(t,n.toString(10));break;case`string`:e(t,n);break}return this}static builder(){return new e}};function je(e){return e instanceof Z}function Me(e){return e instanceof G}function Ne(e){return e instanceof G&&(e=e.statusCode),e===403||e===401}function Pe(e){return e instanceof q}export{X as BaseResponse,ke as BaseService,Ee as BlobResponse,Y as HttpAdapter,Oe as HttpClient,De as Paginated,Ae as QueryString,Z as RequestAbortedError,$ as RequestBuilder,G as RequestError,q as ValidationError,c as adapter,x as assertDto,ee as bound,re as cloneDto,te as debounce,Ce as deserialize,j as dto,ie as executeIfDtoDirtyAndMarkClean,b as isDto,ae as isDtoClean,w as isDtoDirty,je as isRequestAborted,Me as isRequestError,Ne as isUnsanctionedRequest,Pe as isValidationError,E as markDtoClean,D as markDtoDirty,Te as serialize};
|
|
1
|
+
import{DateTime as e}from"luxon";import{debounce as t,getPrototypeChain as n,setObjectMethod as r,setObjectValue as i}from"@basmilius/utils";import{customRef as a,markRaw as o,toRaw as s}from"vue";function c(e){return class extends e{constructor(...e){throw Error(`@adapter: cannot create instance of class.`)}}}function ee(){return(e,t)=>{e[t]=e[t].bind(e)}}function te(e){return(n,r,i)=>{i.value=t(i.value,e,n)}}function ne(e,t){return e===t?!0:e===t}const l=Symbol(),u=Symbol(),d=Symbol(),f=Symbol(),p=Symbol(),m=Symbol(),h=Symbol(),g=Symbol(),_=Symbol(),v=Symbol(),re=Symbol();function y(e){return e&&typeof e==`object`&&!!e[p]}function b(e){if(!y(e))throw Error(`@dto assert given object is not a class decorated with @Dto.`)}const ie=Symbol();function x(e,t=0,n){return function(...r){let i=e[ie]??=new WeakMap,a=r[t],o=n===void 0?`self`:r[n];if(typeof a!=`object`||!a)return e.call(this,...r);i.has(a)||i.set(a,[]);let s=i.get(a);if(!s.includes(o)){s.push(o);try{return e.call(this,...r)}finally{let e=s.lastIndexOf(o);e!==-1&&s.splice(e,1),s.length===0&&i.delete(a)}}}}function ae(e){return b(e),e.clone()}function S(e){return b(e),e[f]}const C=x(function(e,t,n,r){let i=e[re];i(e,t,n,r),e[m]&&C(e[m],e[h],e[m][e[h]])},0,1),w=x(function(e){b(e),e[f]&&(e[f]=!1,C(e,f,!1,!0)),!(!e[u]||e[u].length===0)&&e[u].filter(S).forEach(w)});async function oe(e,t){!y(e)||!S(e)||(await t(e),w(e))}function se(e){return b(e),!e[f]}const T=x(function(e,t){b(e),e[f]||(e[f]=!0,C(e,f,!0,!1)),e[m]&&T(e[m],e[h])});function E(e,t,n){t[u]??=[],!t[u].includes(e)&&t[u].push(e),e[m]!==t&&(e[m]=t),e[h]!==n&&(e[h]=n)}function D(e,t,n){if(y(n))E(n,e,t);else if(Array.isArray(n)){for(let r of n)y(r)&&E(r,e,t);n[m]=e,n[h]=t}}function O(e,t){let n=e[v];n(e,t)}function ce(e,t){if(u in t){let n=t[u].indexOf(e);n!==-1&&t[u].splice(n,1)}e[m]=void 0,e[h]=void 0}function le(e,t){if(y(t))ce(t,e);else if(Array.isArray(t)){for(let n of t)y(n)&&ce(n,e);t[m]=void 0,t[h]=void 0}}const k={};var ue={deleteProperty(e,t){if(Reflect.deleteProperty(e,t),A(e,t))return!0;let n=e[m];return n&&C(n,e[h],n[e[h]]),n&&T(n,e[h]),!0},get(e,t,n){if(t===_)return!0;if(A(e,t))return Reflect.get(e,t,n);let r=e[m];return r&&O(r,e[h]),Reflect.get(e,t)},set(e,t,n,r){if(A(e,t))return Reflect.set(e,t,n,r);let i=e[m];return i&&C(i,e[h],i[e[h]]),i&&T(i,e[h]),Reflect.set(e,t,n)}};function A(e,t){return typeof t==`symbol`||typeof e[t]==`function`||t===`length`}var de={get(e,t,n){if(t===_)return!0;if(typeof t==`symbol`)return Reflect.get(e,t,n);let r=e[d][t];if(!r||!r.get)return Reflect.get(e,t,n);let i=r.get.call(e);return O(e,t),D(e,t,i),i},getOwnPropertyDescriptor(e,t){return e[d][t]},ownKeys(e){return e[g]},set(e,t,n,r){if(typeof t==`symbol`)return Reflect.set(e,t,n,r);let i=e[d][t];if(!i||!i.set)return Reflect.set(e,t,n,r);let a=i.get?.call(e)??void 0;return ne(n,a)?!0:(le(e,a),Array.isArray(n)&&!n[_]&&(n=new Proxy(n,ue)),i.set.call(e,n),D(e,t,n),T(e,t),C(e,t,n,a),!0)}},fe={get(e,t,n){return t===`__v_isRef`?!1:t===_?!0:t in e?Reflect.get(e,t,n):Reflect.get(e.value,t)},getOwnPropertyDescriptor(e,t){return Reflect.getOwnPropertyDescriptor(e.value,t)},ownKeys(e){return Reflect.ownKeys(e.value)},set(e,t,n,r){return t in e?Reflect.set(e,t,n,r):Reflect.set(e.value,t,n)}},pe={construct(e,t,n){t=t.map(e=>Array.isArray(e)?new Proxy(e,ue):e);let r=a((r,i)=>{let a=o(Reflect.construct(e,t,n));a[l]=t,a[f]=!1,a[v]=r,a[re]=i;let s=new Proxy(a,de);return{get:()=>(r(),s),set:()=>void 0}});return new Proxy(r,fe)}};function me(){let e=this;b(e);let t=k[e[p]],n=new t(...e[l]);for(let[e,t]of Object.entries(this[d]))t.set&&(n[e]=y(this[e])?this[e].clone():this[e]);return n}function he(e){for(let t in e){let n=this[d][t];y(this[t])&&typeof e[t]==`object`?this[t].fill(e[t]):n&&n.set&&(this[t]=e[t])}}function ge(){let e={};for(let t of this[g]){let n=this[t];y(n)&&(n=n.toJSON()),e[t]=n}return e}function j(e){ve(e);let t=Object.freeze(n(e)),a=Object.keys(t);return i(e.prototype,d,t),i(e.prototype,p,e.name),i(e.prototype,g,a),i(e,Symbol.hasInstance,t=>typeof t==`object`&&t?.[p]===e.name),r(e,`clone`,me),r(e,`fill`,he),r(e,`toJSON`,ge),_e(e)}function _e(e){let t=new Proxy(e,pe);return k[e.name]=t,t}function ve(e){let t=Object.getPrototypeOf(e.prototype);if(p in t)throw Error(`⛔️ @dto ${e.name} cannot extend parent class which is also decorated with @dto ${t[p]}.`)}function M(e){return e.map(F)}function ye([,t]){return e.fromISO(t)}function N(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,F(t)]).filter(([,e])=>e!==void 0))}const P={};function be([,e,t,n,r]){if(!(t in k))throw Error(`Cannot restore @dto. Dto ${t} was not found.`);if(e in P)return P[e];let i=k[t],a=new i(...M(r));return a.fill(N(n)),P[e]=a,a}function xe(e){return Array.isArray(e)&&e[0]===3058}function Se(e){return Array.isArray(e)&&e[0]===3057}function F(e){switch(!0){case e===null:return null;case Array.isArray(e):switch(!0){case xe(e):return ye(e);case Se(e):return be(e);default:return M(e)}case typeof e==`object`:return N(e);default:return e}}function Ce(e){return F(JSON.parse(e))}function I(e){return[3058,e.toISO({extendedZone:!0,includeOffset:!0})]}function L(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,B(t)]).filter(([,e])=>e!==void 0))}function we(){return`10000000-1000-4000-8000-100000000000`.replace(/[018]/g,e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16))}function R(e){e=s(e);let t=e.toJSON();return[3057,we(),e[p],L(t),z(e[l])]}function z(t){switch(!0){case t.every(y):return t.map(R);case t.every(e.isDateTime):return t.map(I);default:return t.map(B)}}function B(t){switch(!0){case t===null:return null;case Array.isArray(t):return z(t);case y(t):return R(t);case e.isDateTime(t):return I(t);case typeof t==`object`:return L(t);case typeof t==`boolean`:case typeof t==`number`:case typeof t==`string`:return t;default:return}}function Te(e){return JSON.stringify(B(e))}function V(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}let H=class{get blob(){return this.#e}get name(){return this.#t}#e;#t;constructor(e,t){this.#e=e,this.#t=t}};H=V([j],H);var Ee=H;let U=class{get items(){return this.#e}get page(){return this.#t}get pageSize(){return this.#n}get pages(){return this.#r}get total(){return this.#i}#e;#t;#n;#r;#i;constructor(e,t,n,r,i){this.#e=e,this.#t=t,this.#n=n,this.#r=r,this.#i=i}};U=V([j],U);var De=U;let W=class{get code(){return this.#e}get error(){return this.#t}get errorDescription(){return this.#n}get statusCode(){return this.#r}#e;#t;#n;#r;constructor(e,t,n,r){this.#e=e,this.#t=t,this.#n=n,this.#r=r}};W=V([j],W);var G=W;let K=class{get code(){return this.#e}get error(){return this.#t}get errorDescription(){return this.#n}get errors(){return this.#r}get params(){return this.#i}#e;#t;#n;#r;#i;constructor(e,t,n,r,i){this.#e=e,this.#t=t,this.#n=n,this.#r=r,this.#i=i}};K=V([j],K);var q=K,J;let Y=J=class{static parsePaginatedAdapter(e,t){return new De(e.items.map(t),e.page,e.page_size,e.pages,e.total)}static parseFileNameFromContentDispositionHeader(t){let n=`download-${e.now().toFormat(`yyyy-MM-dd HH-mm-ss`)}`;if(!t.startsWith(`attachment`))return n;let r=/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(t);return(r?.length||0)<2?n:r[1].replaceAll(`'`,``).replaceAll(`"`,``).replaceAll(`/`,`-`).replaceAll(`:`,`-`)}static parseRequestError(e,t){return new G(e.code,e.error,e.error_description,t)}static parseValidationError(e){let t;return e.errors&&(t={},Object.entries(e.errors).forEach(([e,n])=>{t[e]=J.parseValidationError(n)})),new q(e.code,e.error,e.error_description,t,e.params)}};Y=J=V([c],Y);var X=class{get data(){return this.#e}get headers(){return this.#t.headers}get ok(){return this.statusCode>=200&&this.statusCode<300}get response(){return this.#t}get statusCode(){return this.#t.status}#e;#t;constructor(e,t){this.#e=e,this.#t=t}},Oe=class e{get authToken(){return this.#e}set authToken(e){this.#e=e}get baseUrl(){return this.#t}get dataField(){return this.#n}#e;#t;#n;constructor(e,t,n=!1){this.#e=e,this.#t=t,this.#n=n}static get instance(){if(e.#r===null)throw Error(`There is currently no HttpClient instance registered. Register one using the HttpClient.register() function.`);return e.#r}static#r=null;static register(t){e.#r=t}},Z=class extends Error{};const Q={};var $=class t{get client(){return this.#e}get options(){return this.#r}get path(){return this.#n}set path(e){this.#n=e}get query(){return this.#i}set query(e){this.#i=e}#e;#t=null;#n;#r={};#i=null;constructor(e,t){this.#e=t??Oe.instance,this.#r.cache=`no-cache`,this.#r.method=`GET`,this.#n=e}autoCancel(e){return this.#t=e,this}bearerToken(e){return e??=this.#e.authToken,e?this.header(`Authorization`,`Bearer ${e}`):(this.#r.headers&&`Authorization`in this.#r.headers&&delete this.#r.headers.Authorization,this)}body(e,t=`application/octet-stream`){return e instanceof FormData?t=null:(Array.isArray(e)||typeof e==`object`)&&(e=JSON.stringify(e),t=`application/json`),this.#r.body=e,t===null?this:this.header(`Content-Type`,t)}header(e,t){return this.#r.headers=this.#r.headers||{},this.#r.headers[e]=t,this}method(e){return this.#r.method=e.toUpperCase(),this}queryString(e){return this.#i=e,this}signal(e=null){return this.#r.signal=e,this}async fetch(){return this.#a().then(e=>e.json())}async fetchBlob(){let t=await this.#a();if(t.status!==200){let e=await t.json();throw`code`in e&&`error`in e&&`error_description`in e?new G(e.code,e.error,e.error_description,t.status):new G(-1,`failed_without_info`,`Request failed without any information from the backend.`,t.status)}let n=t.headers.has(`content-disposition`)?Y.parseFileNameFromContentDispositionHeader(t.headers.get(`content-disposition`)):`download-${e.now().toFormat(`yyyy-MM-dd HH-mm-ss`)}`;return new Ee(await t.blob(),n)}async run(){let{data:e,response:t}=await this.#o();return new X(e,t)}async runAdapter(e){let{data:t,response:n}=await this.#o();return new X(e(t),n)}async runArrayAdapter(e){return this.runAdapter(t=>t.map(e))}async runEmpty(){return await this.#o()}async runPaginatedAdapter(e){return this.runAdapter(t=>Y.parsePaginatedAdapter(t,e))}async runData(){return await this.#o()}async runDataKey(e){let{data:t,response:n}=await this.#o();return new X(t[e],n)}async runStatusCode(){return(await this.#o()).statusCode}async#a(){if(this.#t!==null){this.#t in Q&&Q[this.#t].abort(new Z);let e=new AbortController;Q[this.#t]=e,this.signal(e.signal)}let e=this.path;return this.query!==null&&(e+=`?${this.query.build()}`),await fetch(this.client.baseUrl+e,this.options)}async#o(){return await this.#a().then(e=>t.#s(e,this.client.dataField))}static async#s(e,t){if(e.status===204)return new X(null,e);if(e.headers.has(`content-type`)&&e.headers.get(`content-type`).startsWith(`application/json`)){let n=await e.json();if(n&&typeof n==`object`&&`code`in n&&`error`in n&&`error_description`in n)throw`errors`in n?Y.parseValidationError(n):Y.parseRequestError(n,e.status);return t&&`data`in n?new X(n.data,e):new X(n,e)}if(e.status===401||e.status===403||(await e.text()).length===0&&e.status>=200&&e.status<300)return new X(null,e);throw new G(-1,`not_a_json_response`,`The response was not a JSON response.`,e.status)}},ke=class{request(e,t){return new $(e,t)}},Ae=class e{#e;constructor(){this.#e=new URLSearchParams}build(){return this.#e.toString()}append(e,t){return this.#t(this.#e.append.bind(this.#e),e,t)}appendArray(e,t){return t?.forEach(t=>this.append(e,t)),this}delete(e){return this.#e.delete(e),this}get(e){return this.#e.get(e)}getAll(e){return this.#e.getAll(e)}has(e){return this.#e.has(e)}set(e,t){return this.#t(this.#e.set.bind(this.#e),e,t)}#t(e,t,n){if(!n&&n!==!1)return this;switch(typeof n){case`boolean`:e(t,n?`true`:`false`);break;case`number`:e(t,n.toString(10));break;case`string`:e(t,n);break}return this}static builder(){return new e}};function je(e){return e instanceof Z}function Me(e){return e instanceof G}function Ne(e){return e instanceof G&&(e=e.statusCode),e===403||e===401}function Pe(e){return e instanceof q}export{X as BaseResponse,ke as BaseService,Ee as BlobResponse,Y as HttpAdapter,Oe as HttpClient,De as Paginated,Ae as QueryString,Z as RequestAbortedError,$ as RequestBuilder,G as RequestError,q as ValidationError,c as adapter,b as assertDto,ee as bound,ae as cloneDto,te as debounce,Ce as deserialize,j as dto,oe as executeIfDtoDirtyAndMarkClean,y as isDto,se as isDtoClean,S as isDtoDirty,je as isRequestAborted,Me as isRequestError,Ne as isUnsanctionedRequest,Pe as isValidationError,w as markDtoClean,T as markDtoDirty,Te as serialize};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basmilius/http-client",
|
|
3
3
|
"description": "Http client for Vue projects.",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.11.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"funding": "https://github.com/sponsors/basmilius",
|
|
7
7
|
"homepage": "https://github.com/basmilius/packages",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"vue 3"
|
|
20
20
|
],
|
|
21
21
|
"scripts": {
|
|
22
|
-
"build": "tsgo --noEmit && tsdown"
|
|
22
|
+
"build": "tsgo --noEmit && tsdown",
|
|
23
|
+
"dev": "tsdown --watch"
|
|
23
24
|
},
|
|
24
25
|
"engines": {
|
|
25
26
|
"node": ">=23"
|
|
@@ -45,12 +46,12 @@
|
|
|
45
46
|
"provenance": true
|
|
46
47
|
},
|
|
47
48
|
"dependencies": {
|
|
48
|
-
"@basmilius/utils": "3.
|
|
49
|
+
"@basmilius/utils": "3.11.0",
|
|
49
50
|
"luxon": "^3.7.2",
|
|
50
51
|
"vue": "^3.6.0-beta.7"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@types/luxon": "^3.7.1",
|
|
54
|
-
"tsdown": "^0.21.0
|
|
55
|
+
"tsdown": "^0.21.0"
|
|
55
56
|
}
|
|
56
57
|
}
|
|
@@ -5,13 +5,13 @@ import type { ForeignData, HttpStatusCode } from '../type';
|
|
|
5
5
|
|
|
6
6
|
@adapter
|
|
7
7
|
export class HttpAdapter {
|
|
8
|
-
public static parsePaginatedAdapter<T>(
|
|
8
|
+
public static parsePaginatedAdapter<T>(data: ForeignData, adapterMethod: (item: object) => T): Paginated<T> {
|
|
9
9
|
return new Paginated<T>(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
data.items.map(adapterMethod),
|
|
11
|
+
data.page,
|
|
12
|
+
data.page_size,
|
|
13
|
+
data.pages,
|
|
14
|
+
data.total
|
|
15
15
|
);
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -36,32 +36,32 @@ export class HttpAdapter {
|
|
|
36
36
|
.replaceAll('\:', '-');
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
public static parseRequestError(
|
|
39
|
+
public static parseRequestError(data: ForeignData, statusCode: HttpStatusCode): RequestError {
|
|
40
40
|
return new RequestError(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
data.code,
|
|
42
|
+
data.error,
|
|
43
|
+
data.error_description,
|
|
44
44
|
statusCode
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
public static parseValidationError(
|
|
48
|
+
public static parseValidationError(data: ForeignData): ValidationError {
|
|
49
49
|
let errors: Record<string, ValidationError>;
|
|
50
50
|
|
|
51
|
-
if (
|
|
51
|
+
if (data.errors) {
|
|
52
52
|
errors = {};
|
|
53
53
|
|
|
54
|
-
Object.entries(
|
|
54
|
+
Object.entries(data.errors).forEach(([key, value]) => {
|
|
55
55
|
errors[key] = HttpAdapter.parseValidationError(value as object);
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
return new ValidationError(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
data.code,
|
|
61
|
+
data.error,
|
|
62
|
+
data.error_description,
|
|
63
63
|
errors,
|
|
64
|
-
|
|
64
|
+
data.params
|
|
65
65
|
);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
@@ -13,12 +13,13 @@ export default function <T>(this: DtoInstance<T>): DtoInstance<T> {
|
|
|
13
13
|
const clazz = DTO_CLASS_MAP[instance[NAME]];
|
|
14
14
|
const clone = new clazz(...instance[ARGS]);
|
|
15
15
|
|
|
16
|
-
Object.entries(this[DESCRIPTORS])
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
for (const [key, descriptor] of Object.entries(this[DESCRIPTORS])) {
|
|
17
|
+
if (!descriptor.set) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
clone[key] = isDto(this[key]) ? this[key].clone() : this[key];
|
|
22
|
+
}
|
|
22
23
|
|
|
23
24
|
return clone as DtoInstance<T>;
|
|
24
25
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import isDto from './isDto';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Checks if the two given values are equal. When both values are a
|
|
5
3
|
* dto, the check is done by firstly converthing them to JSON.
|
|
6
4
|
*/
|
|
7
5
|
export default function (a: unknown, b: unknown): boolean {
|
|
8
|
-
if (
|
|
9
|
-
return
|
|
6
|
+
if (a === b) {
|
|
7
|
+
return true;
|
|
10
8
|
}
|
|
11
9
|
|
|
12
|
-
return
|
|
10
|
+
return a === b;
|
|
13
11
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ENABLE_CIRCULAR_LOGGING } from '../
|
|
1
|
+
import { ENABLE_CIRCULAR_LOGGING } from '../const';
|
|
2
2
|
import type DtoInstance from '../instance';
|
|
3
3
|
|
|
4
4
|
type CircularMap = WeakMap<DtoInstance<unknown>, (string | symbol)[]>;
|
|
@@ -6,12 +6,11 @@ const CIRCULAR_MAP = Symbol();
|
|
|
6
6
|
|
|
7
7
|
export default function <T extends (...args: any[]) => unknown>(fn: T, arg1: number = 0, arg2?: number): T {
|
|
8
8
|
return function (...args: any[]): unknown {
|
|
9
|
-
const hasMap = CIRCULAR_MAP in fn;
|
|
10
9
|
const map: CircularMap = fn[CIRCULAR_MAP] ??= new WeakMap();
|
|
11
10
|
const primary = args[arg1];
|
|
12
11
|
const secondary = arg2 !== undefined ? args[arg2] : 'self';
|
|
13
12
|
|
|
14
|
-
if (typeof primary !== 'object') {
|
|
13
|
+
if (typeof primary !== 'object' || primary === null) {
|
|
15
14
|
return fn.call(this, ...args);
|
|
16
15
|
}
|
|
17
16
|
|
|
@@ -19,17 +18,27 @@ export default function <T extends (...args: any[]) => unknown>(fn: T, arg1: num
|
|
|
19
18
|
map.set(primary, []);
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
const visited = map.get(primary)!;
|
|
22
|
+
|
|
23
|
+
if (visited.includes(secondary)) {
|
|
24
|
+
ENABLE_CIRCULAR_LOGGING && console.log('%c@dto %ccircular protect %cdetected a circular reference', 'color: #0891b2', 'color: #059669', 'color: #1d4ed8', {fn, primary, secondary});
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
visited.push(secondary);
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
try {
|
|
31
|
+
return fn.call(this, ...args);
|
|
32
|
+
} finally {
|
|
33
|
+
const index = visited.lastIndexOf(secondary);
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
if (index !== -1) {
|
|
36
|
+
visited.splice(index, 1);
|
|
37
|
+
}
|
|
32
38
|
|
|
33
|
-
|
|
39
|
+
if (visited.length === 0) {
|
|
40
|
+
map.delete(primary);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
34
43
|
} as T;
|
|
35
44
|
}
|
|
@@ -10,10 +10,12 @@ export default function (dto: DtoInstance<unknown>, key: string, value: unknown)
|
|
|
10
10
|
if (isDto(value)) {
|
|
11
11
|
relateDtoTo(value, dto, key);
|
|
12
12
|
} else if (Array.isArray(value)) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
for (const item of value) {
|
|
14
|
+
if (!isDto(item)) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
relateDtoTo(item, dto, key);
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
value[PARENT] = dto;
|
|
@@ -7,7 +7,10 @@ import type DtoInstance from '../instance';
|
|
|
7
7
|
export default function (dto: DtoInstance<unknown>, parent: DtoInstance<unknown>): void {
|
|
8
8
|
if (CHILDREN in parent) {
|
|
9
9
|
const index = parent[CHILDREN].indexOf(dto);
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
if (index !== -1) {
|
|
12
|
+
parent[CHILDREN].splice(index, 1);
|
|
13
|
+
}
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
dto[PARENT] = undefined;
|
|
@@ -10,10 +10,10 @@ export default function (dto: DtoInstance<unknown>, value: unknown): void {
|
|
|
10
10
|
if (isDto(value)) {
|
|
11
11
|
unrelateDtoFrom(value, dto);
|
|
12
12
|
} else if (Array.isArray(value)) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
for (const item of value) {
|
|
14
|
+
if (isDto(item)) {
|
|
15
|
+
unrelateDtoFrom(item, dto);
|
|
16
|
+
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
value[PARENT] = undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Constructor, getPrototypeChain, setObjectMethod, setObjectValue } from '@basmilius/utils';
|
|
2
|
-
import { OVERRIDE_CONSOLE_LOG } from './
|
|
2
|
+
import { OVERRIDE_CONSOLE_LOG } from './const';
|
|
3
3
|
import { instance, isDto } from './helper';
|
|
4
4
|
import { DTO_CLASS_MAP } from './map';
|
|
5
5
|
import { DESCRIPTORS, NAME, PROPERTIES } from './symbols';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ENABLE_GET_LOGGING, ENABLE_SET_LOGGING } from './
|
|
1
|
+
import { ENABLE_GET_LOGGING, ENABLE_SET_LOGGING } from './const';
|
|
2
2
|
import { areEqual, markDtoDirty, relateValueTo, trackDto, triggerDto, unrelateValueFrom } from './helper';
|
|
3
3
|
import { DESCRIPTORS, NAME, PROPERTIES, PROXY } from './symbols';
|
|
4
4
|
import arrayProxy from './arrayProxy';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { SERIALIZED_DATETIME } from '../const';
|
|
1
2
|
import type { SerializedDateTime } from './types';
|
|
2
3
|
|
|
3
4
|
export default function (obj: unknown): obj is SerializedDateTime {
|
|
4
|
-
return Array.isArray(obj) && obj[0] ===
|
|
5
|
+
return Array.isArray(obj) && obj[0] === SERIALIZED_DATETIME;
|
|
5
6
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { SERIALIZED_DTO } from '../const';
|
|
1
2
|
import type { SerializedDto } from './types';
|
|
2
3
|
|
|
3
4
|
export default function (obj: unknown): obj is SerializedDto {
|
|
4
|
-
return Array.isArray(obj) && obj[0] ===
|
|
5
|
+
return Array.isArray(obj) && obj[0] === SERIALIZED_DTO;
|
|
5
6
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { DateTime } from 'luxon';
|
|
2
|
+
import { SERIALIZED_DATETIME } from '../const';
|
|
2
3
|
import type { SerializedDateTime } from './types';
|
|
3
4
|
|
|
4
5
|
export default function (obj: DateTime): SerializedDateTime {
|
|
5
|
-
return [
|
|
6
|
+
return [SERIALIZED_DATETIME, obj.toISO({
|
|
6
7
|
extendedZone: true,
|
|
7
8
|
includeOffset: true
|
|
8
9
|
})];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { toRaw } from 'vue';
|
|
2
|
+
import { SERIALIZED_DTO } from '../const';
|
|
2
3
|
import { ARGS, NAME } from '../symbols';
|
|
3
4
|
import type { SerializedDto } from './types';
|
|
4
5
|
import type DtoInstance from '../instance';
|
|
@@ -12,7 +13,7 @@ export default function (obj: DtoInstance<unknown>): SerializedDto {
|
|
|
12
13
|
const json = obj.toJSON();
|
|
13
14
|
|
|
14
15
|
return [
|
|
15
|
-
|
|
16
|
+
SERIALIZED_DTO,
|
|
16
17
|
uuid(),
|
|
17
18
|
obj[NAME],
|
|
18
19
|
serializeObject(json),
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import type { SERIALIZED_DATETIME, SERIALIZED_DTO } from '../const';
|
|
2
|
+
|
|
3
|
+
export type SerializedDateTime = [typeof SERIALIZED_DATETIME, string];
|
|
4
|
+
export type SerializedDto = [typeof SERIALIZED_DTO, string, string, Record<string, unknown>, any[]];
|
|
3
5
|
export type Serialized = boolean | number | string | Record<string, unknown> | SerializedDateTime | SerializedDto | Serialized[];
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import { isDto } from './helper';
|
|
2
|
-
import { PROPERTIES } from './symbols';
|
|
3
2
|
import type DtoInstance from './instance';
|
|
3
|
+
import { PROPERTIES } from './symbols';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Returns the json object representation of the dto.
|
|
7
7
|
*/
|
|
8
8
|
export default function (this: DtoInstance<unknown>): Record<string, unknown> {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const result: Record<string, unknown> = {};
|
|
10
|
+
|
|
11
|
+
for (const property of this[PROPERTIES]) {
|
|
12
|
+
let value: unknown = this[property];
|
|
13
|
+
|
|
14
|
+
if (isDto(value)) {
|
|
15
|
+
value = value.toJSON();
|
|
16
|
+
}
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
18
|
+
result[property] = value;
|
|
19
|
+
}
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
})
|
|
19
|
-
);
|
|
21
|
+
return result;
|
|
20
22
|
}
|
|
@@ -28,7 +28,7 @@ export default class ValidationError {
|
|
|
28
28
|
readonly #errors: Record<string, ValidationError>;
|
|
29
29
|
readonly #params: Record<string, string | number | boolean>;
|
|
30
30
|
|
|
31
|
-
constructor(code: number, error: string, errorDescription: string, errors
|
|
31
|
+
constructor(code: number, error: string, errorDescription: string, errors: Record<string, ValidationError>, params: Record<string, string | number | boolean>) {
|
|
32
32
|
this.#code = code;
|
|
33
33
|
this.#error = error;
|
|
34
34
|
this.#errorDescription = errorDescription;
|