resora 0.2.8 → 0.2.9

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/README.md CHANGED
@@ -52,7 +52,7 @@ import { Resource } from 'resora';
52
52
 
53
53
  class UserResource extends Resource {
54
54
  data() {
55
- return this.toArray();
55
+ return this.toObject();
56
56
  }
57
57
  }
58
58
  ```
@@ -88,7 +88,7 @@ class UserCollection<R extends User[]> extends ResourceCollection<R> {
88
88
  collects = UserResource;
89
89
 
90
90
  data() {
91
- return this.toArray();
91
+ return this.toObject();
92
92
  }
93
93
  }
94
94
  ```
package/dist/index.cjs CHANGED
@@ -22,4 +22,4 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.
22
22
  | _ // _ \/ __|/ _ \| '__/ _, |
23
23
  | | \ \ __/\__ \ (_) | | | (_| |
24
24
  |_| \_\___||___/\___/|_| \__,_|
25
- `;var Q=class{_status=200;headers={};constructor(e,t){this.response=e,this.body=t}setStatusCode(e){return this._status=e,`status`in this.response&&typeof this.response.status==`function`?this.response.status(e):`status`in this.response&&(this.response.status=e),this}status(){return this._status}statusText(){if(`statusMessage`in this.response)return this.response.statusMessage;if(`statusText`in this.response)return this.response.statusText}setCookie(e,t,n){return this.#e(`Set-Cookie`,`${e}=${t}; ${Object.entries(n||{}).map(([e,t])=>`${e}=${t}`).join(`; `)}`),this}setHeaders(e){for(let[t,n]of Object.entries(e))this.#e(t,n);return this}header(e,t){return this.#e(e,t),this}#e(e,t){this.headers[e]=t,`headers`in this.response?this.response.headers.set(e,t):`setHeader`in this.response&&this.response.setHeader(e,t)}then(e,t){let n=Promise.resolve(this.body).then(e,t);return`send`in this.response&&this.response.send(this.body),n}catch(e){return this.then(void 0,e)}finally(e){return this.then(e,e)}},$=class{static preferredCase;static responseStructure;static config;instanceConfig;additionalMeta;called={};when(e,t){return V(e,t)}whenNotNull(e){return H(e)}mergeWhen(e,t){return U(e,t)}with(e){if(this.called.with=!0,e===void 0)return this.additionalMeta||{};let t=typeof e==`function`?e(this.getResourceForMeta()):e;return this.additionalMeta=j(this.additionalMeta,t),this.called.json&&this.applyMetaToBody(t,this.resolveCurrentRootKey()),this}withMeta(e){return this.with(e),this}resolveMergedMeta(e){return j(z(this,e),this.additionalMeta)}runResponse(e){this.called.toResponse=!0,e.ensureJson();let t=e.body(),n=e.createServerResponse(e.rawResponse,t);return this.called.withResponse=!0,e.callWithResponse(n,e.rawResponse),n}runThen(e){this.called.then=!0,e.ensureJson();let t=e.body();if(e.rawResponse!==void 0){let n=e.createServerResponse(e.rawResponse,t);this.called.withResponse=!0,e.callWithResponse(n,e.rawResponse)}else this.called.withResponse=!0,e.callWithResponse();let n=e.body(),r=Promise.resolve(n).then(e.onfulfilled,e.onrejected);return e.rawResponse!==void 0&&e.sendRawResponse&&e.sendRawResponse(e.rawResponse,n),r}config(e){return e===void 0?this.instanceConfig||{}:(this.instanceConfig={...this.instanceConfig||{},...e,responseStructure:{...this.instanceConfig?.responseStructure||{},...e.responseStructure||{}}},this)}resolveSerializerConfig(e,t){let n=typeof e.config==`function`?e.config():{};return{preferredCase:this.instanceConfig?.preferredCase??n?.preferredCase,responseStructure:{...n?.responseStructure||{},...this.instanceConfig?.responseStructure||{}}}}resolveSerializerCaseStyle(e,t){return this.resolveSerializerConfig(e,t).preferredCase??e.preferredCase??t?.preferredCase??S()}resolveSerializerResponseStructure(e,t){let n=this.resolveSerializerConfig(e,t),r=w();return{wrap:n.responseStructure?.wrap??e.responseStructure?.wrap??t?.responseStructure?.wrap??r?.wrap??!0,rootKey:n.responseStructure?.rootKey??e.responseStructure?.rootKey??t?.responseStructure?.rootKey??r?.rootKey??`data`,factory:n.responseStructure?.factory??e.responseStructure?.factory??t?.responseStructure?.factory??r?.factory}}},ke=class e extends ${body={data:{}};resource;collects;withResponseContext;constructor(e,t){super(),this.res=t,this.resource=e;let n=!!this.resource&&typeof this.resource==`object`&&`data`in this.resource,r=n?this.resource.data:void 0,i=!!r&&!Array.isArray(r),a=n?r:this.resource;if(a&&typeof a==`object`&&!Array.isArray(a)&&!N(a)){let e=M(a)?Object.keys(a.toObject()):Object.keys(a);for(let t of e)t in this||Object.defineProperty(this,t,{enumerable:!0,configurable:!0,get:()=>M(a)&&typeof a.getAttribute==`function`?a.getAttribute(t):i?r[t]:this.resource[t],set:e=>{if(M(a)&&typeof a.setAttribute==`function`){a.setAttribute(t,e);return}if(i){r[t]=e;return}this.resource[t]=e}})}}data(){return this.resource}getBody(){return this.json(),this.body}setBody(e){return this.body=e,this}resolveCollectsConfig(){let e=this.collects;if(!e)return;let t=typeof e.config==`function`?e.config():{};return{preferredCase:t.preferredCase??e.preferredCase,responseStructure:{...e.responseStructure||{},...t.responseStructure||{}}}}resolveResponseStructure(){return this.resolveSerializerResponseStructure(this.constructor,this.resolveCollectsConfig())}resolveCurrentRootKey(){return this.resolveResponseStructure().rootKey}applyMetaToBody(e,t){this.body=A(this.body,e,t)}getResourceForMeta(){return this.resource}getPayloadKey(){let{wrap:e,rootKey:t,factory:n}=this.resolveResponseStructure();return n||!e?void 0:t}json(){if(!this.called.json){this.called.json=!0;let t=P(this.data());Array.isArray(t)&&this.collects&&(t=t.map(e=>new this.collects(e).data())),!Array.isArray(t)&&t&&t.data!==void 0&&(t=t.data),t=W(t);let n=L(this.resource),{metaKey:r}=F(),i=r?n[r]:void 0;r&&delete n[r];let a=this.resolveSerializerCaseStyle(this.constructor,this.resolveCollectsConfig());if(a){let e=K(a);t=q(t,e)}let o=this.resolveMergedMeta(e.prototype.with),{wrap:s,rootKey:c,factory:l}=this.resolveResponseStructure();this.body=R({payload:t,meta:i,metaKey:r,wrap:s,rootKey:c,factory:l,context:{type:`generic`,resource:this.resource}}),this.body=A(this.body,{...n,...o||{}},c)}return this}toArray(){this.called.toArray=!0,this.json();let e=P(this.resource);return!Array.isArray(e)&&e&&e.data!==void 0&&(e=e.data),e}additional(e){this.called.additional=!0,this.json();let t=e.data;delete e.data,delete e.pagination;let n=this.getPayloadKey();return t&&n&&this.body[n]!==void 0&&(this.body[n]=Array.isArray(this.body[n])?[...this.body[n],...t]:{...this.body[n],...t}),this.body={...this.body,...e},this}response(e){let t=e??this.res;return this.runResponse({ensureJson:()=>this.json(),rawResponse:t,body:()=>this.body,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)}})}withResponse(e,t){return this}then(e,t){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:t})}catch(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onrejected:e})}finally(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:e})}},Ae=class e extends ${body={data:[]};resource;collects;withResponseContext;isPaginatedCollectible(e){if(!e||typeof e!=`object`)return!1;let t=e;return t.pagination&&Array.isArray(t.data)?!0:t.meta&&typeof t.meta==`object`&&`currentPage`in t.meta?Array.isArray(t.data)||N(t.data):!1}constructor(e,t){super(),this.res=t,this.resource=e}data(){return this.toArray()}getBody(){return this.json(),this.body}setBody(e){return this.body=e,this}resolveCollectsConfig(){let e=this.collects;if(!e)return;let t=typeof e.config==`function`?e.config():{};return{preferredCase:t.preferredCase??e.preferredCase,responseStructure:{...e.responseStructure||{},...t.responseStructure||{}}}}resolveResponseStructure(){return this.resolveSerializerResponseStructure(this.constructor,this.resolveCollectsConfig())}resolveCurrentRootKey(){return this.resolveResponseStructure().rootKey}applyMetaToBody(e,t){this.body=A(this.body,e,t)}getResourceForMeta(){return this.resource}getPayloadKey(){let{wrap:e,rootKey:t,factory:n}=this.resolveResponseStructure();return n||!e?void 0:t}json(){if(!this.called.json){this.called.json=!0;let t=this.data();this.collects&&(t=t.map(e=>new this.collects(e).data())),t=P(t),t=W(t);let n=Array.isArray(this.resource)?{}:L(this.resource),{metaKey:r}=F(),i=r?n[r]:void 0;r&&delete n[r];let a=this.resolveSerializerCaseStyle(this.constructor,this.resolveCollectsConfig());if(a){let e=K(a);t=q(t,e)}let o=this.resolveMergedMeta(e.prototype.with),{wrap:s,rootKey:c,factory:l}=this.resolveResponseStructure();this.body=R({payload:t,meta:i,metaKey:r,wrap:s,rootKey:c,factory:l,context:{type:`collection`,resource:this.resource}}),this.body=A(this.body,{...n,...o||{}},c)}return this}toArray(){return this.called.toArray=!0,this.json(),P(Array.isArray(this.resource)?this.resource:N(this.resource)?this.resource.all():this.resource.data)}additional(e){this.called.additional=!0,this.json(),delete e.cursor,delete e.pagination;let t=this.getPayloadKey();return e.data&&t&&Array.isArray(this.body[t])&&(this.body[t]=[...this.body[t],...e.data]),this.body={...this.body,...e},this}response(e){let t=e??this.res;return this.runResponse({ensureJson:()=>this.json(),rawResponse:t,body:()=>this.body,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)}})}withResponse(e,t){return this}setCollects(e){return this.collects=e,this}then(e,t){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:t})}catch(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onrejected:e})}finally(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:e})}},je=class e extends ${body={data:{}};resource;withResponseContext;constructor(e,t){super(),this.res=t,this.resource=e;let n=this.resource.data??this.resource;if(!Array.isArray(n)){let e=M(n)?Object.keys(n.toObject()):Object.keys(n);for(let t of e)t in this||Object.defineProperty(this,t,{enumerable:!0,configurable:!0,get:()=>M(n)&&typeof n.getAttribute==`function`?n.getAttribute(t):this.resource.data?.[t]??this.resource[t],set:e=>{if(M(n)&&typeof n.setAttribute==`function`){n.setAttribute(t,e);return}this.resource.data&&this.resource.data[t]?this.resource.data[t]=e:this.resource[t]=e}})}}static collection(e){return new Ae(e).setCollects(this)}data(){return this.toArray()}getBody(){return this.json(),this.body}setBody(e){return this.body=e,this}resolveResponseStructure(){return this.resolveSerializerResponseStructure(this.constructor)}resolveCurrentRootKey(){return this.resolveResponseStructure().rootKey}applyMetaToBody(e,t){this.body=A(this.body,e,t)}getResourceForMeta(){return this.resource}getPayloadKey(){let{wrap:e,rootKey:t,factory:n}=this.resolveResponseStructure();return n||!e?void 0:t}json(){if(!this.called.json){this.called.json=!0;let t=P(this.data());!Array.isArray(t)&&t&&t.data!==void 0&&(t=t.data),t=W(t);let n=this.resolveSerializerCaseStyle(this.constructor);if(n){let e=K(n);t=q(t,e)}let r=this.resolveMergedMeta(e.prototype.with),{wrap:i,rootKey:a,factory:o}=this.resolveResponseStructure();this.body=R({payload:t,wrap:i,rootKey:a,factory:o,context:{type:`resource`,resource:this.resource}}),this.body=A(this.body,r,a)}return this}toArray(){this.called.toArray=!0,this.json();let e=P(this.resource);return!Array.isArray(e)&&e&&e.data!==void 0&&(e=e.data),e}additional(e){this.called.additional=!0,this.json();let t=this.getPayloadKey();return e.data&&t&&this.body[t]!==void 0&&(this.body[t]=Array.isArray(this.body[t])?[...this.body[t],...e.data]:{...this.body[t],...e.data}),this.body={...this.body,...e},this}response(e){let t=e??this.res;return this.runResponse({ensureJson:()=>this.json(),rawResponse:t,body:()=>this.body,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)}})}withResponse(e,t){return this}then(e,t){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:t})}catch(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onrejected:e})}finally(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:e})}};exports.ApiResource=ee,exports.CONDITIONAL_ATTRIBUTE_MISSING=B,exports.CliApp=Ee,exports.GenericResource=ke,exports.InitCommand=De,exports.MakeResource=Oe,exports.Resource=je,exports.ResourceCollection=Ae,exports.ServerResponse=Q,exports.appendRootProperties=A,exports.applyRuntimeConfig=xe,exports.buildPaginationExtras=L,exports.buildResponseEnvelope=R,exports.defineConfig=Y,exports.getCaseTransformer=K,exports.getDefaultConfig=ye,exports.getGlobalBaseUrl=fe,exports.getGlobalCase=S,exports.getGlobalCursorMeta=O,exports.getGlobalPageName=me,exports.getGlobalPaginatedExtras=ce,exports.getGlobalPaginatedLinks=ue,exports.getGlobalPaginatedMeta=E,exports.getGlobalResponseFactory=oe,exports.getGlobalResponseRootKey=ie,exports.getGlobalResponseStructure=w,exports.getGlobalResponseWrap=re,exports.getPaginationExtraKeys=F,exports.isArkormLikeCollection=N,exports.isArkormLikeModel=M,exports.isPlainObject=k,exports.loadRuntimeConfig=Te,exports.mergeMetadata=j,exports.normalizeSerializableData=P,exports.resetRuntimeConfigForTests=be,exports.resolveMergeWhen=U,exports.resolveWhen=V,exports.resolveWhenNotNull=H,exports.resolveWithHookMetadata=z,exports.sanitizeConditionalAttributes=W,exports.setGlobalBaseUrl=de,exports.setGlobalCase=x,exports.setGlobalCursorMeta=D,exports.setGlobalPageName=pe,exports.setGlobalPaginatedExtras=se,exports.setGlobalPaginatedLinks=le,exports.setGlobalPaginatedMeta=T,exports.setGlobalResponseFactory=ae,exports.setGlobalResponseRootKey=te,exports.setGlobalResponseStructure=C,exports.setGlobalResponseWrap=ne,exports.splitWords=G,exports.toCamelCase=he,exports.toKebabCase=ve,exports.toPascalCase=_e,exports.toSnakeCase=ge,exports.transformKeys=q;
25
+ `;var Q=class{_status=200;headers={};constructor(e,t){this.response=e,this.body=t}setStatusCode(e){return this._status=e,`status`in this.response&&typeof this.response.status==`function`?this.response.status(e):`status`in this.response&&(this.response.status=e),this}status(){return this._status}statusText(){if(`statusMessage`in this.response)return this.response.statusMessage;if(`statusText`in this.response)return this.response.statusText}setCookie(e,t,n){return this.#e(`Set-Cookie`,`${e}=${t}; ${Object.entries(n||{}).map(([e,t])=>`${e}=${t}`).join(`; `)}`),this}setHeaders(e){for(let[t,n]of Object.entries(e))this.#e(t,n);return this}header(e,t){return this.#e(e,t),this}#e(e,t){this.headers[e]=t,`headers`in this.response?this.response.headers.set(e,t):`setHeader`in this.response&&this.response.setHeader(e,t)}then(e,t){let n=Promise.resolve(this.body).then(e,t);return`send`in this.response&&this.response.send(this.body),n}catch(e){return this.then(void 0,e)}finally(e){return this.then(e,e)}},$=class{static preferredCase;static responseStructure;static config;instanceConfig;additionalMeta;called={};when(e,t){return V(e,t)}whenNotNull(e){return H(e)}mergeWhen(e,t){return U(e,t)}with(e){if(this.called.with=!0,e===void 0)return this.additionalMeta||{};let t=typeof e==`function`?e(this.getResourceForMeta()):e;return this.additionalMeta=j(this.additionalMeta,t),this.called.json&&this.applyMetaToBody(t,this.resolveCurrentRootKey()),this}withMeta(e){return this.with(e),this}resolveMergedMeta(e){return j(z(this,e),this.additionalMeta)}runResponse(e){this.called.toResponse=!0,e.ensureJson();let t=e.body(),n=e.createServerResponse(e.rawResponse,t);return this.called.withResponse=!0,e.callWithResponse(n,e.rawResponse),n}runThen(e){this.called.then=!0,e.ensureJson();let t=e.body();if(e.rawResponse!==void 0){let n=e.createServerResponse(e.rawResponse,t);this.called.withResponse=!0,e.callWithResponse(n,e.rawResponse)}else this.called.withResponse=!0,e.callWithResponse();let n=e.body(),r=Promise.resolve(n).then(e.onfulfilled,e.onrejected);return e.rawResponse!==void 0&&e.sendRawResponse&&e.sendRawResponse(e.rawResponse,n),r}config(e){return e===void 0?this.instanceConfig||{}:(this.instanceConfig={...this.instanceConfig||{},...e,responseStructure:{...this.instanceConfig?.responseStructure||{},...e.responseStructure||{}}},this)}resolveSerializerConfig(e,t){let n=typeof e.config==`function`?e.config():{};return{preferredCase:this.instanceConfig?.preferredCase??n?.preferredCase,responseStructure:{...n?.responseStructure||{},...this.instanceConfig?.responseStructure||{}}}}resolveSerializerCaseStyle(e,t){return this.resolveSerializerConfig(e,t).preferredCase??e.preferredCase??t?.preferredCase??S()}resolveSerializerResponseStructure(e,t){let n=this.resolveSerializerConfig(e,t),r=w();return{wrap:n.responseStructure?.wrap??e.responseStructure?.wrap??t?.responseStructure?.wrap??r?.wrap??!0,rootKey:n.responseStructure?.rootKey??e.responseStructure?.rootKey??t?.responseStructure?.rootKey??r?.rootKey??`data`,factory:n.responseStructure?.factory??e.responseStructure?.factory??t?.responseStructure?.factory??r?.factory}}},ke=class e extends ${body={data:{}};resource;collects;withResponseContext;constructor(e,t){super(),this.res=t,this.resource=e;let n=!!this.resource&&typeof this.resource==`object`&&`data`in this.resource,r=n?this.resource.data:void 0,i=!!r&&!Array.isArray(r),a=n?r:this.resource;if(a&&typeof a==`object`&&!Array.isArray(a)&&!N(a)){let e=M(a)?Object.keys(a.toObject()):Object.keys(a);for(let t of e)t in this||Object.defineProperty(this,t,{enumerable:!0,configurable:!0,get:()=>M(a)&&typeof a.getAttribute==`function`?a.getAttribute(t):i?r[t]:this.resource[t],set:e=>{if(M(a)&&typeof a.setAttribute==`function`){a.setAttribute(t,e);return}if(i){r[t]=e;return}this.resource[t]=e}})}}data(){return this.resource}getBody(){return this.json(),this.body}setBody(e){return this.body=e,this}resolveCollectsConfig(){let e=this.collects;if(!e)return;let t=typeof e.config==`function`?e.config():{};return{preferredCase:t.preferredCase??e.preferredCase,responseStructure:{...e.responseStructure||{},...t.responseStructure||{}}}}resolveResponseStructure(){return this.resolveSerializerResponseStructure(this.constructor,this.resolveCollectsConfig())}resolveCurrentRootKey(){return this.resolveResponseStructure().rootKey}applyMetaToBody(e,t){this.body=A(this.body,e,t)}getResourceForMeta(){return this.resource}getPayloadKey(){let{wrap:e,rootKey:t,factory:n}=this.resolveResponseStructure();return n||!e?void 0:t}json(){if(!this.called.json){this.called.json=!0;let t=P(this.data());Array.isArray(t)&&this.collects&&(t=t.map(e=>new this.collects(e).data())),!Array.isArray(t)&&t&&t.data!==void 0&&(t=t.data),t=W(t);let n=L(this.resource),{metaKey:r}=F(),i=r?n[r]:void 0;r&&delete n[r];let a=this.resolveSerializerCaseStyle(this.constructor,this.resolveCollectsConfig());if(a){let e=K(a);t=q(t,e)}let o=this.resolveMergedMeta(e.prototype.with),{wrap:s,rootKey:c,factory:l}=this.resolveResponseStructure();this.body=R({payload:t,meta:i,metaKey:r,wrap:s,rootKey:c,factory:l,context:{type:`generic`,resource:this.resource}}),this.body=A(this.body,{...n,...o||{}},c)}return this}toObject(){this.called.toObject=!0,this.json();let e=P(this.resource);return!Array.isArray(e)&&e&&e.data!==void 0&&(e=e.data),e}toArray(){return this.called.toArray=!0,this.toObject()}additional(e){this.called.additional=!0,this.json();let t=e.data;delete e.data,delete e.pagination;let n=this.getPayloadKey();return t&&n&&this.body[n]!==void 0&&(this.body[n]=Array.isArray(this.body[n])?[...this.body[n],...t]:{...this.body[n],...t}),this.body={...this.body,...e},this}response(e){let t=e??this.res;return this.runResponse({ensureJson:()=>this.json(),rawResponse:t,body:()=>this.body,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)}})}withResponse(e,t){return this}then(e,t){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:t})}catch(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onrejected:e})}finally(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:e})}},Ae=class e extends ${body={data:[]};resource;collects;withResponseContext;isPaginatedCollectible(e){if(!e||typeof e!=`object`)return!1;let t=e;return t.pagination&&Array.isArray(t.data)?!0:t.meta&&typeof t.meta==`object`&&`currentPage`in t.meta?Array.isArray(t.data)||N(t.data):!1}constructor(e,t){super(),this.res=t,this.resource=e}data(){return this.toObject()}getBody(){return this.json(),this.body}setBody(e){return this.body=e,this}resolveCollectsConfig(){let e=this.collects;if(!e)return;let t=typeof e.config==`function`?e.config():{};return{preferredCase:t.preferredCase??e.preferredCase,responseStructure:{...e.responseStructure||{},...t.responseStructure||{}}}}resolveResponseStructure(){return this.resolveSerializerResponseStructure(this.constructor,this.resolveCollectsConfig())}resolveCurrentRootKey(){return this.resolveResponseStructure().rootKey}applyMetaToBody(e,t){this.body=A(this.body,e,t)}getResourceForMeta(){return this.resource}getPayloadKey(){let{wrap:e,rootKey:t,factory:n}=this.resolveResponseStructure();return n||!e?void 0:t}json(){if(!this.called.json){this.called.json=!0;let t=this.data();this.collects&&(t=t.map(e=>new this.collects(e).data())),t=P(t),t=W(t);let n=Array.isArray(this.resource)?{}:L(this.resource),{metaKey:r}=F(),i=r?n[r]:void 0;r&&delete n[r];let a=this.resolveSerializerCaseStyle(this.constructor,this.resolveCollectsConfig());if(a){let e=K(a);t=q(t,e)}let o=this.resolveMergedMeta(e.prototype.with),{wrap:s,rootKey:c,factory:l}=this.resolveResponseStructure();this.body=R({payload:t,meta:i,metaKey:r,wrap:s,rootKey:c,factory:l,context:{type:`collection`,resource:this.resource}}),this.body=A(this.body,{...n,...o||{}},c)}return this}toObject(){return this.called.toObject=!0,this.json(),P(Array.isArray(this.resource)?this.resource:N(this.resource)?this.resource.all():this.resource.data)}toArray(){return this.called.toArray=!0,this.toObject()}additional(e){this.called.additional=!0,this.json(),delete e.cursor,delete e.pagination;let t=this.getPayloadKey();return e.data&&t&&Array.isArray(this.body[t])&&(this.body[t]=[...this.body[t],...e.data]),this.body={...this.body,...e},this}response(e){let t=e??this.res;return this.runResponse({ensureJson:()=>this.json(),rawResponse:t,body:()=>this.body,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)}})}withResponse(e,t){return this}setCollects(e){return this.collects=e,this}then(e,t){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:t})}catch(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onrejected:e})}finally(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:e})}},je=class e extends ${body={data:{}};resource;withResponseContext;constructor(e,t){super(),this.res=t,this.resource=e;let n=this.resource.data??this.resource;if(!Array.isArray(n)){let e=M(n)?Object.keys(n.toObject()):Object.keys(n);for(let t of e)t in this||Object.defineProperty(this,t,{enumerable:!0,configurable:!0,get:()=>M(n)&&typeof n.getAttribute==`function`?n.getAttribute(t):this.resource.data?.[t]??this.resource[t],set:e=>{if(M(n)&&typeof n.setAttribute==`function`){n.setAttribute(t,e);return}this.resource.data&&this.resource.data[t]?this.resource.data[t]=e:this.resource[t]=e}})}}static collection(e){return new Ae(e).setCollects(this)}data(){return this.toObject()}getBody(){return this.json(),this.body}setBody(e){return this.body=e,this}resolveResponseStructure(){return this.resolveSerializerResponseStructure(this.constructor)}resolveCurrentRootKey(){return this.resolveResponseStructure().rootKey}applyMetaToBody(e,t){this.body=A(this.body,e,t)}getResourceForMeta(){return this.resource}getPayloadKey(){let{wrap:e,rootKey:t,factory:n}=this.resolveResponseStructure();return n||!e?void 0:t}json(){if(!this.called.json){this.called.json=!0;let t=P(this.data());!Array.isArray(t)&&t&&t.data!==void 0&&(t=t.data),t=W(t);let n=this.resolveSerializerCaseStyle(this.constructor);if(n){let e=K(n);t=q(t,e)}let r=this.resolveMergedMeta(e.prototype.with),{wrap:i,rootKey:a,factory:o}=this.resolveResponseStructure();this.body=R({payload:t,wrap:i,rootKey:a,factory:o,context:{type:`resource`,resource:this.resource}}),this.body=A(this.body,r,a)}return this}toObject(){this.called.toObject=!0,this.json();let e=P(this.resource);return!Array.isArray(e)&&e&&e.data!==void 0&&(e=e.data),e}toArray(){return this.called.toArray=!0,this.toObject()}additional(e){this.called.additional=!0,this.json();let t=this.getPayloadKey();return e.data&&t&&this.body[t]!==void 0&&(this.body[t]=Array.isArray(this.body[t])?[...this.body[t],...e.data]:{...this.body[t],...e.data}),this.body={...this.body,...e},this}response(e){let t=e??this.res;return this.runResponse({ensureJson:()=>this.json(),rawResponse:t,body:()=>this.body,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)}})}withResponse(e,t){return this}then(e,t){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:t})}catch(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onrejected:e})}finally(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:e})}};exports.ApiResource=ee,exports.CONDITIONAL_ATTRIBUTE_MISSING=B,exports.CliApp=Ee,exports.GenericResource=ke,exports.InitCommand=De,exports.MakeResource=Oe,exports.Resource=je,exports.ResourceCollection=Ae,exports.ServerResponse=Q,exports.appendRootProperties=A,exports.applyRuntimeConfig=xe,exports.buildPaginationExtras=L,exports.buildResponseEnvelope=R,exports.defineConfig=Y,exports.getCaseTransformer=K,exports.getDefaultConfig=ye,exports.getGlobalBaseUrl=fe,exports.getGlobalCase=S,exports.getGlobalCursorMeta=O,exports.getGlobalPageName=me,exports.getGlobalPaginatedExtras=ce,exports.getGlobalPaginatedLinks=ue,exports.getGlobalPaginatedMeta=E,exports.getGlobalResponseFactory=oe,exports.getGlobalResponseRootKey=ie,exports.getGlobalResponseStructure=w,exports.getGlobalResponseWrap=re,exports.getPaginationExtraKeys=F,exports.isArkormLikeCollection=N,exports.isArkormLikeModel=M,exports.isPlainObject=k,exports.loadRuntimeConfig=Te,exports.mergeMetadata=j,exports.normalizeSerializableData=P,exports.resetRuntimeConfigForTests=be,exports.resolveMergeWhen=U,exports.resolveWhen=V,exports.resolveWhenNotNull=H,exports.resolveWithHookMetadata=z,exports.sanitizeConditionalAttributes=W,exports.setGlobalBaseUrl=de,exports.setGlobalCase=x,exports.setGlobalCursorMeta=D,exports.setGlobalPageName=pe,exports.setGlobalPaginatedExtras=se,exports.setGlobalPaginatedLinks=le,exports.setGlobalPaginatedMeta=T,exports.setGlobalResponseFactory=ae,exports.setGlobalResponseRootKey=te,exports.setGlobalResponseStructure=C,exports.setGlobalResponseWrap=ne,exports.splitWords=G,exports.toCamelCase=he,exports.toKebabCase=ve,exports.toPascalCase=_e,exports.toSnakeCase=ge,exports.transformKeys=q;
package/dist/index.d.cts CHANGED
@@ -81,10 +81,6 @@ interface Cursor {
81
81
  }
82
82
  //#endregion
83
83
  //#region src/types/resource.d.ts
84
- interface ResourceLevelConfig {
85
- preferredCase?: CaseStyle | undefined;
86
- responseStructure?: ResponseStructureConfig | undefined;
87
- }
88
84
  interface MetaData {
89
85
  [key: string]: any;
90
86
  }
@@ -242,6 +238,27 @@ interface Config {
242
238
  */
243
239
  extraCommands?: typeof Command<any>[];
244
240
  }
241
+ /**
242
+ * @description A type that represents the configuration options that can be set at the resource level, allowing for customization of case style, response structure, and additional data included in paginated responses on a per-resource basis.
243
+ */
244
+ interface ResourceLevelConfig {
245
+ /**
246
+ * @description The preferred case style for resource keys in the response.
247
+ * Can be set to a preset string ('camel', 'snake', 'pascal', 'kebab') or a custom transformer function.
248
+ * @default 'camel'
249
+ */
250
+ preferredCase?: CaseStyle | undefined;
251
+ /**
252
+ * @description An object specifying the structure of the response body for resources. It includes a rootKey property that defines the key under which the resource data will be nested in the response. The rootKey is a string that represents the name of this key in the response body.
253
+ */
254
+ responseStructure?: ResponseStructureConfig | undefined;
255
+ /**
256
+ * @description An array or object specifying which additional data to include in paginated responses.
257
+ * Can include 'meta', 'links', and/or 'cursor'. If an object is provided, the keys can be customized to specify the property names for each type of extra data in the response.
258
+ * @default ['meta', 'links']
259
+ */
260
+ paginatedExtras?: Config['paginatedExtras'] | undefined;
261
+ }
245
262
  interface ResoraConfig extends Partial<Omit<Config, 'stubs' | 'cursorMeta' | 'paginatedMeta' | 'paginatedLinks' | 'responseStructure'>> {
246
263
  /**
247
264
  * @description The file names of the various stub templates used for generating resources and configuration.
@@ -341,6 +358,13 @@ declare class MakeResource extends Command<CliApp> {
341
358
  }
342
359
  //#endregion
343
360
  //#region src/ServerResponse.d.ts
361
+ /**
362
+ * ServerResponse class to handle HTTP response construction and sending, compatible
363
+ * with both Express and H3 response objects.
364
+ *
365
+ * @author Legacy (3m1n3nc3)
366
+ * @since 0.1.0
367
+ */
344
368
  declare class ServerResponse<R extends NonCollectible | Collectible | ResourceData[] | ResourceData = any> {
345
369
  #private;
346
370
  private response;
@@ -422,6 +446,16 @@ interface SerializerConstructor {
422
446
  responseStructure?: ResponseStructureConfig;
423
447
  config?: () => ResourceLevelConfig;
424
448
  }
449
+ /**
450
+ * @description BaseSerializer is an abstract class that provides common functionality for
451
+ * serializing resources. It handles configuration, metadata management, and response
452
+ * structure resolution. Concrete serializers should extend this class and implement
453
+ * the abstract methods to define how resources are transformed and how metadata is
454
+ * applied to the response body.
455
+ *
456
+ * @author Legacy (3m1n3nc3)
457
+ * @since 0.2.8
458
+ */
425
459
  declare abstract class BaseSerializer<TResource = any> {
426
460
  static preferredCase?: CaseStyle;
427
461
  static responseStructure?: ResponseStructureConfig;
@@ -431,6 +465,7 @@ declare abstract class BaseSerializer<TResource = any> {
431
465
  protected called: {
432
466
  json?: boolean;
433
467
  data?: boolean;
468
+ toObject?: boolean;
434
469
  toArray?: boolean;
435
470
  additional?: boolean;
436
471
  with?: boolean;
@@ -439,15 +474,63 @@ declare abstract class BaseSerializer<TResource = any> {
439
474
  then?: boolean;
440
475
  toResponse?: boolean;
441
476
  };
477
+ /**
478
+ * Helper method to conditionally resolve a value based on a condition.
479
+ *
480
+ * @param condition
481
+ * @param value
482
+ * @returns
483
+ */
442
484
  when<T>(condition: any, value: T | (() => T)): T | undefined;
485
+ /**
486
+ * Helper method to conditionally resolve a value only if it's not null or undefined.
487
+ *
488
+ * @param value
489
+ * @returns
490
+ */
443
491
  whenNotNull<T>(value: T | null | undefined): T | undefined;
492
+ /**
493
+ * Helper method to conditionally merge values into the response based on a condition.
494
+ *
495
+ * @param condition
496
+ * @param value
497
+ * @returns
498
+ */
444
499
  mergeWhen<T extends Record<string, any>>(condition: any, value: T | (() => T)): Partial<T>;
500
+ /**
501
+ * Resolve the current root key for the response structure.
502
+ */
445
503
  protected abstract resolveCurrentRootKey(): string;
446
504
  protected abstract applyMetaToBody(meta: MetaData, rootKey: string): void;
447
505
  protected abstract getResourceForMeta(): TResource;
506
+ /**
507
+ * Add additional metadata to the response. If called without arguments.
508
+ *
509
+ * @param meta
510
+ * @returns
511
+ */
448
512
  with(meta?: any): any;
513
+ /**
514
+ * Add additional metadata to the response, ensuring it is merged with any existing metadata.
515
+ *
516
+ * @param meta
517
+ * @returns
518
+ */
449
519
  withMeta<M extends MetaData>(meta: M | ((resource: TResource) => M)): this;
520
+ /**
521
+ * Resolve the merged metadata for the current response, combining any metadata
522
+ * defined in hooks with additional metadata added via with() or withMeta().
523
+ *
524
+ * @param withMethod
525
+ * @returns
526
+ */
450
527
  protected resolveMergedMeta(withMethod: (meta?: any) => any): Record<string, any> | undefined;
528
+ /**
529
+ * Run the response generation process, ensuring that the response is properly structured.
530
+ *
531
+ * @param input
532
+ * @returns
533
+ */
451
534
  protected runResponse<TBody, TRawResponse, TServerResponse>(input: {
452
535
  ensureJson: () => void;
453
536
  rawResponse: TRawResponse;
@@ -455,6 +538,13 @@ declare abstract class BaseSerializer<TResource = any> {
455
538
  createServerResponse: (raw: TRawResponse, body: TBody) => TServerResponse;
456
539
  callWithResponse: (response: TServerResponse, raw: TRawResponse) => void;
457
540
  }): TServerResponse;
541
+ /**
542
+ * Run the thenable process for the resource, allowing for async handling and
543
+ * response generation.
544
+ *
545
+ * @param input
546
+ * @returns
547
+ */
458
548
  protected runThen<TBody, TRawResponse, TServerResponse, TResult1, TResult2>(input: {
459
549
  ensureJson: () => void;
460
550
  body: () => TBody;
@@ -465,8 +555,24 @@ declare abstract class BaseSerializer<TResource = any> {
465
555
  onfulfilled?: ((value: TBody) => TResult1 | PromiseLike<TResult1>) | null;
466
556
  onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null;
467
557
  }): Promise<TResult1 | TResult2>;
558
+ /**
559
+ * Get or set the resource-level configuration for this serializer instance.
560
+ */
468
561
  config(): ResourceLevelConfig;
562
+ /**
563
+ * Set the resource-level configuration for this serializer instance.
564
+ *
565
+ * @param config The configuration object to set for this serializer instance.
566
+ */
469
567
  config(config: ResourceLevelConfig): this;
568
+ /**
569
+ * Resolve the effective serializer configuration for this instance, combining
570
+ * class-level and instance-level configurations.
571
+ *
572
+ * @param localConstructor
573
+ * @param _fallbackConfig
574
+ * @returns
575
+ */
470
576
  protected resolveSerializerConfig(localConstructor: SerializerConstructor, _fallbackConfig?: ResourceLevelConfig): {
471
577
  preferredCase: CaseStyle | undefined;
472
578
  responseStructure: {
@@ -475,7 +581,22 @@ declare abstract class BaseSerializer<TResource = any> {
475
581
  factory?: ResponseFactory | undefined;
476
582
  };
477
583
  };
584
+ /**
585
+ * Resolve the preferred case style for this serializer instance, considering
586
+ * instance-level configuration, class-level configuration, and global defaults.
587
+ *
588
+ * @param localConstructor The constructor of the serializer class.
589
+ * @param fallbackConfig The fallback configuration to use if no other configuration is found.
590
+ * @returns The resolved case style for this serializer instance.
591
+ */
478
592
  protected resolveSerializerCaseStyle(localConstructor: SerializerConstructor, fallbackConfig?: ResourceLevelConfig): CaseStyle | undefined;
593
+ /**
594
+ * Resolve the response structure configuration for this serializer instance, considering
595
+ *
596
+ * @param localConstructor
597
+ * @param fallbackConfig
598
+ * @returns
599
+ */
479
600
  protected resolveSerializerResponseStructure(localConstructor: SerializerConstructor, fallbackConfig?: ResourceLevelConfig): {
480
601
  wrap: boolean;
481
602
  rootKey: string;
@@ -485,7 +606,12 @@ declare abstract class BaseSerializer<TResource = any> {
485
606
  //#endregion
486
607
  //#region src/ResourceCollection.d.ts
487
608
  /**
488
- * ResourceCollection class to handle API resource transformation and response building for collections
609
+ * ResourceCollection class to handle API resource transformation and response building
610
+ * for collections
611
+ *
612
+ * @author Legacy (3m1n3nc3)
613
+ * @since 0.1.0
614
+ * @see BaseSerializer for shared serialization logic and configuration handling
489
615
  */
490
616
  declare class ResourceCollection<R extends ResourceData[] | Collectible | CollectionLike | PaginatorLike = ResourceData[] | Collectible | CollectionLike | PaginatorLike, T extends ResourceData = any> extends BaseSerializer<R> {
491
617
  private res?;
@@ -497,7 +623,13 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
497
623
  response: ServerResponse<CollectionBody<R>>;
498
624
  raw: Response | H3Event['res'];
499
625
  };
500
- private isPaginatedCollectible;
626
+ /**
627
+ * Type guard to determine if the provided value is a Collectible with pagination information.
628
+ *
629
+ * @param value The value to check.
630
+ * @returns True if the value is a Collectible with pagination information, false otherwise.
631
+ */
632
+ isPaginatedCollectible(value: unknown): value is Collectible;
501
633
  constructor(rsc: R);
502
634
  constructor(rsc: R, res: Response);
503
635
  /**
@@ -514,9 +646,33 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
514
646
  protected setBody(body: CollectionBody<R>): this;
515
647
  private resolveCollectsConfig;
516
648
  private resolveResponseStructure;
649
+ /**
650
+ * Resolve the current root key for the response structure, based on configuration and defaults.
651
+ *
652
+ * @returns
653
+ */
517
654
  protected resolveCurrentRootKey(): string;
655
+ /**
656
+ * Apply metadata properties to the response body, ensuring they are merged with
657
+ * any existing properties and respecting the configured root key.
658
+ *
659
+ * @param meta
660
+ * @param rootKey
661
+ */
518
662
  protected applyMetaToBody(meta: MetaData, rootKey: string): void;
663
+ /**
664
+ * Get the resource data to be used for generating metadata, allowing for
665
+ * customization in subclasses.
666
+ *
667
+ * @returns
668
+ */
519
669
  protected getResourceForMeta(): R;
670
+ /**
671
+ * Get the appropriate key for the response payload based on the current response
672
+ * structure configuration.
673
+ *
674
+ * @returns The key to use for the response payload, or undefined if no key is needed.
675
+ */
520
676
  private getPayloadKey;
521
677
  /**
522
678
  * Convert resource to JSON response format
@@ -525,10 +681,18 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
525
681
  */
526
682
  json(): this;
527
683
  /**
528
- * Flatten resource to return original data
684
+ * Convert resource to object format and return original data.
529
685
  *
530
686
  * @returns
531
687
  */
688
+ toObject(): (R extends Collectible ? R['data'][number] : R extends PaginatorLike<infer TPaginatorData> ? TPaginatorData : R extends CollectionLike<infer TCollectionData> ? TCollectionData : R extends ResourceData[] ? R[number] : never)[];
689
+ /**
690
+ * Convert resource to object format and return original data.
691
+ *
692
+ * @deprecated Use toObject() instead.
693
+ * @alias toArray
694
+ * @since 0.2.9
695
+ */
532
696
  toArray(): (R extends Collectible ? R['data'][number] : R extends PaginatorLike<infer TPaginatorData> ? TPaginatorData : R extends CollectionLike<infer TCollectionData> ? TCollectionData : R extends ResourceData[] ? R[number] : never)[];
533
697
  /**
534
698
  * Add additional properties to the response body
@@ -573,6 +737,11 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
573
737
  //#region src/Resource.d.ts
574
738
  /**
575
739
  * Resource class to handle API resource transformation and response building
740
+ *
741
+ *
742
+ * @author Legacy (3m1n3nc3)
743
+ * @since 0.1.0
744
+ * @see BaseSerializer for shared serialization logic and configuration handling
576
745
  */
577
746
  declare class Resource<R extends ResourceData | NonCollectible = ResourceData> extends BaseSerializer<R> {
578
747
  private res?;
@@ -604,6 +773,11 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
604
773
  */
605
774
  protected setBody(body: ResourceBody<R>): this;
606
775
  private resolveResponseStructure;
776
+ /**
777
+ * Resolve the current root key for the response body based on configuration and defaults.
778
+ *
779
+ * @returns
780
+ */
607
781
  protected resolveCurrentRootKey(): string;
608
782
  protected applyMetaToBody(meta: MetaData, rootKey: string): void;
609
783
  protected getResourceForMeta(): R;
@@ -615,10 +789,18 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
615
789
  */
616
790
  json(): this;
617
791
  /**
618
- * Flatten resource to array format (for collections) or return original data for single resources
792
+ * Convert resource to object format (for collections) or return original data for single resources.
619
793
  *
620
794
  * @returns
621
795
  */
796
+ toObject(): R extends NonCollectible ? R['data'] : R;
797
+ /**
798
+ * Convert resource to object format and return original data.
799
+ *
800
+ * @deprecated Use toObject() instead.
801
+ * @alias toArray
802
+ * @since 0.2.9
803
+ */
622
804
  toArray(): R extends NonCollectible ? R['data'] : R;
623
805
  /**
624
806
  * Add additional properties to the response body
@@ -627,7 +809,14 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
627
809
  * @returns
628
810
  */
629
811
  additional<X extends Record<string, any>>(extra: X): this;
812
+ /**
813
+ * Build a response object, optionally accepting a raw response to mutate in withResponse.
814
+ */
630
815
  response(): ServerResponse<ResourceBody<R>>;
816
+ /**
817
+ * Build a response object, optionally accepting a raw response to mutate in withResponse.
818
+ * @param res Optional raw response object (e.g. Express Response or H3Event res)
819
+ */
631
820
  response(res: H3Event['res']): ServerResponse<ResourceBody<R>>;
632
821
  /**
633
822
  * Customize the outgoing transport response right before dispatch.
@@ -662,6 +851,10 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
662
851
  //#region src/GenericResource.d.ts
663
852
  /**
664
853
  * GenericResource class to handle API resource transformation and response building
854
+ *
855
+ * @author Legacy (3m1n3nc3)
856
+ * @since 0.1.0
857
+ * @see BaseSerializer for shared serialization logic and configuration handling
665
858
  */
666
859
  declare class GenericResource<R extends NonCollectible | Collectible | CollectionLike | PaginatorLike | ResourceData = ResourceData, T extends ResourceData = any> extends BaseSerializer<R> {
667
860
  private res?;
@@ -688,8 +881,24 @@ declare class GenericResource<R extends NonCollectible | Collectible | Collectio
688
881
  protected setBody(body: GenericBody<R>): this;
689
882
  private resolveCollectsConfig;
690
883
  private resolveResponseStructure;
884
+ /**
885
+ * Resolve the current root key for the response structure, based on configuration and defaults.
886
+ *
887
+ * @returns
888
+ */
691
889
  protected resolveCurrentRootKey(): string;
890
+ /**
891
+ * Apply metadata properties to the response body, ensuring they are merged with.
892
+ *
893
+ * @param meta
894
+ * @param rootKey
895
+ */
692
896
  protected applyMetaToBody(meta: MetaData, rootKey: string): void;
897
+ /**
898
+ * Get the resource data to be used for generating metadata.
899
+ *
900
+ * @returns
901
+ */
693
902
  protected getResourceForMeta(): R;
694
903
  private getPayloadKey;
695
904
  /**
@@ -699,10 +908,18 @@ declare class GenericResource<R extends NonCollectible | Collectible | Collectio
699
908
  */
700
909
  json(): this;
701
910
  /**
702
- * Convert resource to array format (for collections)
911
+ * Convert resource to object format (for collections).
703
912
  *
704
913
  * @returns
705
914
  */
915
+ toObject(): any;
916
+ /**
917
+ * Convert resource to object format and return original data.
918
+ *
919
+ * @deprecated Use toObject() instead.
920
+ * @alias toArray
921
+ * @since 0.2.9
922
+ */
706
923
  toArray(): any;
707
924
  /**
708
925
  * Add additional properties to the response body
@@ -711,7 +928,15 @@ declare class GenericResource<R extends NonCollectible | Collectible | Collectio
711
928
  * @returns
712
929
  */
713
930
  additional<X extends Record<string, any>>(extra: X): this;
931
+ /**
932
+ * Build a response object, optionally accepting a raw response to write to directly.
933
+ */
714
934
  response(): ServerResponse<GenericBody<R>>;
935
+ /**
936
+ * Build a response object, writing to the provided raw response if possible.
937
+ *
938
+ * @param res
939
+ */
715
940
  response(res: H3Event['res']): ServerResponse<GenericBody<R>>;
716
941
  /**
717
942
  * Customize the outgoing transport response right before dispatch.
@@ -832,6 +1057,11 @@ declare const resolveMergeWhen: <T extends Record<string, any>>(condition: any,
832
1057
  declare const sanitizeConditionalAttributes: (value: any) => any;
833
1058
  //#endregion
834
1059
  //#region src/utilities/config.d.ts
1060
+ /**
1061
+ * Get the default configuration for the application
1062
+ *
1063
+ * @returns
1064
+ */
835
1065
  declare const getDefaultConfig: () => Config;
836
1066
  /**
837
1067
  * Defines the configuration for the application by merging the provided configuration with the default configuration. This function takes a partial configuration object as input and returns a complete configuration object that includes all required properties, using default values for any properties that are not specified in the input.
@@ -851,8 +1081,29 @@ type ArkormLikeModel = {
851
1081
  type ArkormLikeCollection = {
852
1082
  all: () => unknown;
853
1083
  };
1084
+ /**
1085
+ * Type guard to check if a value is an Arkorm-like model, which is defined as an object
1086
+ * that has a toObject method and optionally getRawAttributes, getAttribute, and
1087
+ * setAttribute methods.
1088
+ *
1089
+ * @param value The value to check
1090
+ * @returns True if the value is an Arkorm-like model, false otherwise
1091
+ */
854
1092
  declare const isArkormLikeModel: (value: unknown) => value is ArkormLikeModel;
1093
+ /**
1094
+ * Type guard to check if a value is an Arkorm-like collection, which is defined as an object
1095
+ *
1096
+ * @param value
1097
+ * @returns
1098
+ */
855
1099
  declare const isArkormLikeCollection: (value: unknown) => value is ArkormLikeCollection;
1100
+ /**
1101
+ * Normalize a value for serialization by recursively converting Arkorm-like models and
1102
+ * collections to plain objects, while preserving the structure of arrays and plain objects.
1103
+ *
1104
+ * @param value The value to normalize
1105
+ * @returns The normalized value, ready for serialization
1106
+ */
856
1107
  declare const normalizeSerializableData: (value: unknown) => unknown;
857
1108
  //#endregion
858
1109
  //#region src/utilities/metadata.d.ts
package/dist/index.d.mts CHANGED
@@ -81,10 +81,6 @@ interface Cursor {
81
81
  }
82
82
  //#endregion
83
83
  //#region src/types/resource.d.ts
84
- interface ResourceLevelConfig {
85
- preferredCase?: CaseStyle | undefined;
86
- responseStructure?: ResponseStructureConfig | undefined;
87
- }
88
84
  interface MetaData {
89
85
  [key: string]: any;
90
86
  }
@@ -242,6 +238,27 @@ interface Config {
242
238
  */
243
239
  extraCommands?: typeof Command<any>[];
244
240
  }
241
+ /**
242
+ * @description A type that represents the configuration options that can be set at the resource level, allowing for customization of case style, response structure, and additional data included in paginated responses on a per-resource basis.
243
+ */
244
+ interface ResourceLevelConfig {
245
+ /**
246
+ * @description The preferred case style for resource keys in the response.
247
+ * Can be set to a preset string ('camel', 'snake', 'pascal', 'kebab') or a custom transformer function.
248
+ * @default 'camel'
249
+ */
250
+ preferredCase?: CaseStyle | undefined;
251
+ /**
252
+ * @description An object specifying the structure of the response body for resources. It includes a rootKey property that defines the key under which the resource data will be nested in the response. The rootKey is a string that represents the name of this key in the response body.
253
+ */
254
+ responseStructure?: ResponseStructureConfig | undefined;
255
+ /**
256
+ * @description An array or object specifying which additional data to include in paginated responses.
257
+ * Can include 'meta', 'links', and/or 'cursor'. If an object is provided, the keys can be customized to specify the property names for each type of extra data in the response.
258
+ * @default ['meta', 'links']
259
+ */
260
+ paginatedExtras?: Config['paginatedExtras'] | undefined;
261
+ }
245
262
  interface ResoraConfig extends Partial<Omit<Config, 'stubs' | 'cursorMeta' | 'paginatedMeta' | 'paginatedLinks' | 'responseStructure'>> {
246
263
  /**
247
264
  * @description The file names of the various stub templates used for generating resources and configuration.
@@ -341,6 +358,13 @@ declare class MakeResource extends Command<CliApp> {
341
358
  }
342
359
  //#endregion
343
360
  //#region src/ServerResponse.d.ts
361
+ /**
362
+ * ServerResponse class to handle HTTP response construction and sending, compatible
363
+ * with both Express and H3 response objects.
364
+ *
365
+ * @author Legacy (3m1n3nc3)
366
+ * @since 0.1.0
367
+ */
344
368
  declare class ServerResponse<R extends NonCollectible | Collectible | ResourceData[] | ResourceData = any> {
345
369
  #private;
346
370
  private response;
@@ -422,6 +446,16 @@ interface SerializerConstructor {
422
446
  responseStructure?: ResponseStructureConfig;
423
447
  config?: () => ResourceLevelConfig;
424
448
  }
449
+ /**
450
+ * @description BaseSerializer is an abstract class that provides common functionality for
451
+ * serializing resources. It handles configuration, metadata management, and response
452
+ * structure resolution. Concrete serializers should extend this class and implement
453
+ * the abstract methods to define how resources are transformed and how metadata is
454
+ * applied to the response body.
455
+ *
456
+ * @author Legacy (3m1n3nc3)
457
+ * @since 0.2.8
458
+ */
425
459
  declare abstract class BaseSerializer<TResource = any> {
426
460
  static preferredCase?: CaseStyle;
427
461
  static responseStructure?: ResponseStructureConfig;
@@ -431,6 +465,7 @@ declare abstract class BaseSerializer<TResource = any> {
431
465
  protected called: {
432
466
  json?: boolean;
433
467
  data?: boolean;
468
+ toObject?: boolean;
434
469
  toArray?: boolean;
435
470
  additional?: boolean;
436
471
  with?: boolean;
@@ -439,15 +474,63 @@ declare abstract class BaseSerializer<TResource = any> {
439
474
  then?: boolean;
440
475
  toResponse?: boolean;
441
476
  };
477
+ /**
478
+ * Helper method to conditionally resolve a value based on a condition.
479
+ *
480
+ * @param condition
481
+ * @param value
482
+ * @returns
483
+ */
442
484
  when<T>(condition: any, value: T | (() => T)): T | undefined;
485
+ /**
486
+ * Helper method to conditionally resolve a value only if it's not null or undefined.
487
+ *
488
+ * @param value
489
+ * @returns
490
+ */
443
491
  whenNotNull<T>(value: T | null | undefined): T | undefined;
492
+ /**
493
+ * Helper method to conditionally merge values into the response based on a condition.
494
+ *
495
+ * @param condition
496
+ * @param value
497
+ * @returns
498
+ */
444
499
  mergeWhen<T extends Record<string, any>>(condition: any, value: T | (() => T)): Partial<T>;
500
+ /**
501
+ * Resolve the current root key for the response structure.
502
+ */
445
503
  protected abstract resolveCurrentRootKey(): string;
446
504
  protected abstract applyMetaToBody(meta: MetaData, rootKey: string): void;
447
505
  protected abstract getResourceForMeta(): TResource;
506
+ /**
507
+ * Add additional metadata to the response. If called without arguments.
508
+ *
509
+ * @param meta
510
+ * @returns
511
+ */
448
512
  with(meta?: any): any;
513
+ /**
514
+ * Add additional metadata to the response, ensuring it is merged with any existing metadata.
515
+ *
516
+ * @param meta
517
+ * @returns
518
+ */
449
519
  withMeta<M extends MetaData>(meta: M | ((resource: TResource) => M)): this;
520
+ /**
521
+ * Resolve the merged metadata for the current response, combining any metadata
522
+ * defined in hooks with additional metadata added via with() or withMeta().
523
+ *
524
+ * @param withMethod
525
+ * @returns
526
+ */
450
527
  protected resolveMergedMeta(withMethod: (meta?: any) => any): Record<string, any> | undefined;
528
+ /**
529
+ * Run the response generation process, ensuring that the response is properly structured.
530
+ *
531
+ * @param input
532
+ * @returns
533
+ */
451
534
  protected runResponse<TBody, TRawResponse, TServerResponse>(input: {
452
535
  ensureJson: () => void;
453
536
  rawResponse: TRawResponse;
@@ -455,6 +538,13 @@ declare abstract class BaseSerializer<TResource = any> {
455
538
  createServerResponse: (raw: TRawResponse, body: TBody) => TServerResponse;
456
539
  callWithResponse: (response: TServerResponse, raw: TRawResponse) => void;
457
540
  }): TServerResponse;
541
+ /**
542
+ * Run the thenable process for the resource, allowing for async handling and
543
+ * response generation.
544
+ *
545
+ * @param input
546
+ * @returns
547
+ */
458
548
  protected runThen<TBody, TRawResponse, TServerResponse, TResult1, TResult2>(input: {
459
549
  ensureJson: () => void;
460
550
  body: () => TBody;
@@ -465,8 +555,24 @@ declare abstract class BaseSerializer<TResource = any> {
465
555
  onfulfilled?: ((value: TBody) => TResult1 | PromiseLike<TResult1>) | null;
466
556
  onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null;
467
557
  }): Promise<TResult1 | TResult2>;
558
+ /**
559
+ * Get or set the resource-level configuration for this serializer instance.
560
+ */
468
561
  config(): ResourceLevelConfig;
562
+ /**
563
+ * Set the resource-level configuration for this serializer instance.
564
+ *
565
+ * @param config The configuration object to set for this serializer instance.
566
+ */
469
567
  config(config: ResourceLevelConfig): this;
568
+ /**
569
+ * Resolve the effective serializer configuration for this instance, combining
570
+ * class-level and instance-level configurations.
571
+ *
572
+ * @param localConstructor
573
+ * @param _fallbackConfig
574
+ * @returns
575
+ */
470
576
  protected resolveSerializerConfig(localConstructor: SerializerConstructor, _fallbackConfig?: ResourceLevelConfig): {
471
577
  preferredCase: CaseStyle | undefined;
472
578
  responseStructure: {
@@ -475,7 +581,22 @@ declare abstract class BaseSerializer<TResource = any> {
475
581
  factory?: ResponseFactory | undefined;
476
582
  };
477
583
  };
584
+ /**
585
+ * Resolve the preferred case style for this serializer instance, considering
586
+ * instance-level configuration, class-level configuration, and global defaults.
587
+ *
588
+ * @param localConstructor The constructor of the serializer class.
589
+ * @param fallbackConfig The fallback configuration to use if no other configuration is found.
590
+ * @returns The resolved case style for this serializer instance.
591
+ */
478
592
  protected resolveSerializerCaseStyle(localConstructor: SerializerConstructor, fallbackConfig?: ResourceLevelConfig): CaseStyle | undefined;
593
+ /**
594
+ * Resolve the response structure configuration for this serializer instance, considering
595
+ *
596
+ * @param localConstructor
597
+ * @param fallbackConfig
598
+ * @returns
599
+ */
479
600
  protected resolveSerializerResponseStructure(localConstructor: SerializerConstructor, fallbackConfig?: ResourceLevelConfig): {
480
601
  wrap: boolean;
481
602
  rootKey: string;
@@ -485,7 +606,12 @@ declare abstract class BaseSerializer<TResource = any> {
485
606
  //#endregion
486
607
  //#region src/ResourceCollection.d.ts
487
608
  /**
488
- * ResourceCollection class to handle API resource transformation and response building for collections
609
+ * ResourceCollection class to handle API resource transformation and response building
610
+ * for collections
611
+ *
612
+ * @author Legacy (3m1n3nc3)
613
+ * @since 0.1.0
614
+ * @see BaseSerializer for shared serialization logic and configuration handling
489
615
  */
490
616
  declare class ResourceCollection<R extends ResourceData[] | Collectible | CollectionLike | PaginatorLike = ResourceData[] | Collectible | CollectionLike | PaginatorLike, T extends ResourceData = any> extends BaseSerializer<R> {
491
617
  private res?;
@@ -497,7 +623,13 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
497
623
  response: ServerResponse<CollectionBody<R>>;
498
624
  raw: Response | H3Event['res'];
499
625
  };
500
- private isPaginatedCollectible;
626
+ /**
627
+ * Type guard to determine if the provided value is a Collectible with pagination information.
628
+ *
629
+ * @param value The value to check.
630
+ * @returns True if the value is a Collectible with pagination information, false otherwise.
631
+ */
632
+ isPaginatedCollectible(value: unknown): value is Collectible;
501
633
  constructor(rsc: R);
502
634
  constructor(rsc: R, res: Response);
503
635
  /**
@@ -514,9 +646,33 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
514
646
  protected setBody(body: CollectionBody<R>): this;
515
647
  private resolveCollectsConfig;
516
648
  private resolveResponseStructure;
649
+ /**
650
+ * Resolve the current root key for the response structure, based on configuration and defaults.
651
+ *
652
+ * @returns
653
+ */
517
654
  protected resolveCurrentRootKey(): string;
655
+ /**
656
+ * Apply metadata properties to the response body, ensuring they are merged with
657
+ * any existing properties and respecting the configured root key.
658
+ *
659
+ * @param meta
660
+ * @param rootKey
661
+ */
518
662
  protected applyMetaToBody(meta: MetaData, rootKey: string): void;
663
+ /**
664
+ * Get the resource data to be used for generating metadata, allowing for
665
+ * customization in subclasses.
666
+ *
667
+ * @returns
668
+ */
519
669
  protected getResourceForMeta(): R;
670
+ /**
671
+ * Get the appropriate key for the response payload based on the current response
672
+ * structure configuration.
673
+ *
674
+ * @returns The key to use for the response payload, or undefined if no key is needed.
675
+ */
520
676
  private getPayloadKey;
521
677
  /**
522
678
  * Convert resource to JSON response format
@@ -525,10 +681,18 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
525
681
  */
526
682
  json(): this;
527
683
  /**
528
- * Flatten resource to return original data
684
+ * Convert resource to object format and return original data.
529
685
  *
530
686
  * @returns
531
687
  */
688
+ toObject(): (R extends Collectible ? R['data'][number] : R extends PaginatorLike<infer TPaginatorData> ? TPaginatorData : R extends CollectionLike<infer TCollectionData> ? TCollectionData : R extends ResourceData[] ? R[number] : never)[];
689
+ /**
690
+ * Convert resource to object format and return original data.
691
+ *
692
+ * @deprecated Use toObject() instead.
693
+ * @alias toArray
694
+ * @since 0.2.9
695
+ */
532
696
  toArray(): (R extends Collectible ? R['data'][number] : R extends PaginatorLike<infer TPaginatorData> ? TPaginatorData : R extends CollectionLike<infer TCollectionData> ? TCollectionData : R extends ResourceData[] ? R[number] : never)[];
533
697
  /**
534
698
  * Add additional properties to the response body
@@ -573,6 +737,11 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
573
737
  //#region src/Resource.d.ts
574
738
  /**
575
739
  * Resource class to handle API resource transformation and response building
740
+ *
741
+ *
742
+ * @author Legacy (3m1n3nc3)
743
+ * @since 0.1.0
744
+ * @see BaseSerializer for shared serialization logic and configuration handling
576
745
  */
577
746
  declare class Resource<R extends ResourceData | NonCollectible = ResourceData> extends BaseSerializer<R> {
578
747
  private res?;
@@ -604,6 +773,11 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
604
773
  */
605
774
  protected setBody(body: ResourceBody<R>): this;
606
775
  private resolveResponseStructure;
776
+ /**
777
+ * Resolve the current root key for the response body based on configuration and defaults.
778
+ *
779
+ * @returns
780
+ */
607
781
  protected resolveCurrentRootKey(): string;
608
782
  protected applyMetaToBody(meta: MetaData, rootKey: string): void;
609
783
  protected getResourceForMeta(): R;
@@ -615,10 +789,18 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
615
789
  */
616
790
  json(): this;
617
791
  /**
618
- * Flatten resource to array format (for collections) or return original data for single resources
792
+ * Convert resource to object format (for collections) or return original data for single resources.
619
793
  *
620
794
  * @returns
621
795
  */
796
+ toObject(): R extends NonCollectible ? R['data'] : R;
797
+ /**
798
+ * Convert resource to object format and return original data.
799
+ *
800
+ * @deprecated Use toObject() instead.
801
+ * @alias toArray
802
+ * @since 0.2.9
803
+ */
622
804
  toArray(): R extends NonCollectible ? R['data'] : R;
623
805
  /**
624
806
  * Add additional properties to the response body
@@ -627,7 +809,14 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
627
809
  * @returns
628
810
  */
629
811
  additional<X extends Record<string, any>>(extra: X): this;
812
+ /**
813
+ * Build a response object, optionally accepting a raw response to mutate in withResponse.
814
+ */
630
815
  response(): ServerResponse<ResourceBody<R>>;
816
+ /**
817
+ * Build a response object, optionally accepting a raw response to mutate in withResponse.
818
+ * @param res Optional raw response object (e.g. Express Response or H3Event res)
819
+ */
631
820
  response(res: H3Event['res']): ServerResponse<ResourceBody<R>>;
632
821
  /**
633
822
  * Customize the outgoing transport response right before dispatch.
@@ -662,6 +851,10 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
662
851
  //#region src/GenericResource.d.ts
663
852
  /**
664
853
  * GenericResource class to handle API resource transformation and response building
854
+ *
855
+ * @author Legacy (3m1n3nc3)
856
+ * @since 0.1.0
857
+ * @see BaseSerializer for shared serialization logic and configuration handling
665
858
  */
666
859
  declare class GenericResource<R extends NonCollectible | Collectible | CollectionLike | PaginatorLike | ResourceData = ResourceData, T extends ResourceData = any> extends BaseSerializer<R> {
667
860
  private res?;
@@ -688,8 +881,24 @@ declare class GenericResource<R extends NonCollectible | Collectible | Collectio
688
881
  protected setBody(body: GenericBody<R>): this;
689
882
  private resolveCollectsConfig;
690
883
  private resolveResponseStructure;
884
+ /**
885
+ * Resolve the current root key for the response structure, based on configuration and defaults.
886
+ *
887
+ * @returns
888
+ */
691
889
  protected resolveCurrentRootKey(): string;
890
+ /**
891
+ * Apply metadata properties to the response body, ensuring they are merged with.
892
+ *
893
+ * @param meta
894
+ * @param rootKey
895
+ */
692
896
  protected applyMetaToBody(meta: MetaData, rootKey: string): void;
897
+ /**
898
+ * Get the resource data to be used for generating metadata.
899
+ *
900
+ * @returns
901
+ */
693
902
  protected getResourceForMeta(): R;
694
903
  private getPayloadKey;
695
904
  /**
@@ -699,10 +908,18 @@ declare class GenericResource<R extends NonCollectible | Collectible | Collectio
699
908
  */
700
909
  json(): this;
701
910
  /**
702
- * Convert resource to array format (for collections)
911
+ * Convert resource to object format (for collections).
703
912
  *
704
913
  * @returns
705
914
  */
915
+ toObject(): any;
916
+ /**
917
+ * Convert resource to object format and return original data.
918
+ *
919
+ * @deprecated Use toObject() instead.
920
+ * @alias toArray
921
+ * @since 0.2.9
922
+ */
706
923
  toArray(): any;
707
924
  /**
708
925
  * Add additional properties to the response body
@@ -711,7 +928,15 @@ declare class GenericResource<R extends NonCollectible | Collectible | Collectio
711
928
  * @returns
712
929
  */
713
930
  additional<X extends Record<string, any>>(extra: X): this;
931
+ /**
932
+ * Build a response object, optionally accepting a raw response to write to directly.
933
+ */
714
934
  response(): ServerResponse<GenericBody<R>>;
935
+ /**
936
+ * Build a response object, writing to the provided raw response if possible.
937
+ *
938
+ * @param res
939
+ */
715
940
  response(res: H3Event['res']): ServerResponse<GenericBody<R>>;
716
941
  /**
717
942
  * Customize the outgoing transport response right before dispatch.
@@ -832,6 +1057,11 @@ declare const resolveMergeWhen: <T extends Record<string, any>>(condition: any,
832
1057
  declare const sanitizeConditionalAttributes: (value: any) => any;
833
1058
  //#endregion
834
1059
  //#region src/utilities/config.d.ts
1060
+ /**
1061
+ * Get the default configuration for the application
1062
+ *
1063
+ * @returns
1064
+ */
835
1065
  declare const getDefaultConfig: () => Config;
836
1066
  /**
837
1067
  * Defines the configuration for the application by merging the provided configuration with the default configuration. This function takes a partial configuration object as input and returns a complete configuration object that includes all required properties, using default values for any properties that are not specified in the input.
@@ -851,8 +1081,29 @@ type ArkormLikeModel = {
851
1081
  type ArkormLikeCollection = {
852
1082
  all: () => unknown;
853
1083
  };
1084
+ /**
1085
+ * Type guard to check if a value is an Arkorm-like model, which is defined as an object
1086
+ * that has a toObject method and optionally getRawAttributes, getAttribute, and
1087
+ * setAttribute methods.
1088
+ *
1089
+ * @param value The value to check
1090
+ * @returns True if the value is an Arkorm-like model, false otherwise
1091
+ */
854
1092
  declare const isArkormLikeModel: (value: unknown) => value is ArkormLikeModel;
1093
+ /**
1094
+ * Type guard to check if a value is an Arkorm-like collection, which is defined as an object
1095
+ *
1096
+ * @param value
1097
+ * @returns
1098
+ */
855
1099
  declare const isArkormLikeCollection: (value: unknown) => value is ArkormLikeCollection;
1100
+ /**
1101
+ * Normalize a value for serialization by recursively converting Arkorm-like models and
1102
+ * collections to plain objects, while preserving the structure of arrays and plain objects.
1103
+ *
1104
+ * @param value The value to normalize
1105
+ * @returns The normalized value, ready for serialization
1106
+ */
856
1107
  declare const normalizeSerializableData: (value: unknown) => unknown;
857
1108
  //#endregion
858
1109
  //#region src/utilities/metadata.d.ts
package/dist/index.mjs CHANGED
@@ -22,4 +22,4 @@ import{copyFileSync as e,existsSync as t,mkdirSync as n,readFileSync as r,rmSync
22
22
  | _ // _ \/ __|/ _ \| '__/ _, |
23
23
  | | \ \ __/\__ \ (_) | | | (_| |
24
24
  |_| \_\___||___/\___/|_| \__,_|
25
- `;var Q=class{_status=200;headers={};constructor(e,t){this.response=e,this.body=t}setStatusCode(e){return this._status=e,`status`in this.response&&typeof this.response.status==`function`?this.response.status(e):`status`in this.response&&(this.response.status=e),this}status(){return this._status}statusText(){if(`statusMessage`in this.response)return this.response.statusMessage;if(`statusText`in this.response)return this.response.statusText}setCookie(e,t,n){return this.#e(`Set-Cookie`,`${e}=${t}; ${Object.entries(n||{}).map(([e,t])=>`${e}=${t}`).join(`; `)}`),this}setHeaders(e){for(let[t,n]of Object.entries(e))this.#e(t,n);return this}header(e,t){return this.#e(e,t),this}#e(e,t){this.headers[e]=t,`headers`in this.response?this.response.headers.set(e,t):`setHeader`in this.response&&this.response.setHeader(e,t)}then(e,t){let n=Promise.resolve(this.body).then(e,t);return`send`in this.response&&this.response.send(this.body),n}catch(e){return this.then(void 0,e)}finally(e){return this.then(e,e)}},$=class{static preferredCase;static responseStructure;static config;instanceConfig;additionalMeta;called={};when(e,t){return B(e,t)}whenNotNull(e){return V(e)}mergeWhen(e,t){return H(e,t)}with(e){if(this.called.with=!0,e===void 0)return this.additionalMeta||{};let t=typeof e==`function`?e(this.getResourceForMeta()):e;return this.additionalMeta=A(this.additionalMeta,t),this.called.json&&this.applyMetaToBody(t,this.resolveCurrentRootKey()),this}withMeta(e){return this.with(e),this}resolveMergedMeta(e){return A(R(this,e),this.additionalMeta)}runResponse(e){this.called.toResponse=!0,e.ensureJson();let t=e.body(),n=e.createServerResponse(e.rawResponse,t);return this.called.withResponse=!0,e.callWithResponse(n,e.rawResponse),n}runThen(e){this.called.then=!0,e.ensureJson();let t=e.body();if(e.rawResponse!==void 0){let n=e.createServerResponse(e.rawResponse,t);this.called.withResponse=!0,e.callWithResponse(n,e.rawResponse)}else this.called.withResponse=!0,e.callWithResponse();let n=e.body(),r=Promise.resolve(n).then(e.onfulfilled,e.onrejected);return e.rawResponse!==void 0&&e.sendRawResponse&&e.sendRawResponse(e.rawResponse,n),r}config(e){return e===void 0?this.instanceConfig||{}:(this.instanceConfig={...this.instanceConfig||{},...e,responseStructure:{...this.instanceConfig?.responseStructure||{},...e.responseStructure||{}}},this)}resolveSerializerConfig(e,t){let n=typeof e.config==`function`?e.config():{};return{preferredCase:this.instanceConfig?.preferredCase??n?.preferredCase,responseStructure:{...n?.responseStructure||{},...this.instanceConfig?.responseStructure||{}}}}resolveSerializerCaseStyle(e,t){return this.resolveSerializerConfig(e,t).preferredCase??e.preferredCase??t?.preferredCase??x()}resolveSerializerResponseStructure(e,t){let n=this.resolveSerializerConfig(e,t),r=C();return{wrap:n.responseStructure?.wrap??e.responseStructure?.wrap??t?.responseStructure?.wrap??r?.wrap??!0,rootKey:n.responseStructure?.rootKey??e.responseStructure?.rootKey??t?.responseStructure?.rootKey??r?.rootKey??`data`,factory:n.responseStructure?.factory??e.responseStructure?.factory??t?.responseStructure?.factory??r?.factory}}},Oe=class e extends ${body={data:{}};resource;collects;withResponseContext;constructor(e,t){super(),this.res=t,this.resource=e;let n=!!this.resource&&typeof this.resource==`object`&&`data`in this.resource,r=n?this.resource.data:void 0,i=!!r&&!Array.isArray(r),a=n?r:this.resource;if(a&&typeof a==`object`&&!Array.isArray(a)&&!M(a)){let e=j(a)?Object.keys(a.toObject()):Object.keys(a);for(let t of e)t in this||Object.defineProperty(this,t,{enumerable:!0,configurable:!0,get:()=>j(a)&&typeof a.getAttribute==`function`?a.getAttribute(t):i?r[t]:this.resource[t],set:e=>{if(j(a)&&typeof a.setAttribute==`function`){a.setAttribute(t,e);return}if(i){r[t]=e;return}this.resource[t]=e}})}}data(){return this.resource}getBody(){return this.json(),this.body}setBody(e){return this.body=e,this}resolveCollectsConfig(){let e=this.collects;if(!e)return;let t=typeof e.config==`function`?e.config():{};return{preferredCase:t.preferredCase??e.preferredCase,responseStructure:{...e.responseStructure||{},...t.responseStructure||{}}}}resolveResponseStructure(){return this.resolveSerializerResponseStructure(this.constructor,this.resolveCollectsConfig())}resolveCurrentRootKey(){return this.resolveResponseStructure().rootKey}applyMetaToBody(e,t){this.body=k(this.body,e,t)}getResourceForMeta(){return this.resource}getPayloadKey(){let{wrap:e,rootKey:t,factory:n}=this.resolveResponseStructure();return n||!e?void 0:t}json(){if(!this.called.json){this.called.json=!0;let t=N(this.data());Array.isArray(t)&&this.collects&&(t=t.map(e=>new this.collects(e).data())),!Array.isArray(t)&&t&&t.data!==void 0&&(t=t.data),t=U(t);let n=I(this.resource),{metaKey:r}=P(),i=r?n[r]:void 0;r&&delete n[r];let a=this.resolveSerializerCaseStyle(this.constructor,this.resolveCollectsConfig());if(a){let e=K(a);t=q(t,e)}let o=this.resolveMergedMeta(e.prototype.with),{wrap:s,rootKey:c,factory:l}=this.resolveResponseStructure();this.body=L({payload:t,meta:i,metaKey:r,wrap:s,rootKey:c,factory:l,context:{type:`generic`,resource:this.resource}}),this.body=k(this.body,{...n,...o||{}},c)}return this}toArray(){this.called.toArray=!0,this.json();let e=N(this.resource);return!Array.isArray(e)&&e&&e.data!==void 0&&(e=e.data),e}additional(e){this.called.additional=!0,this.json();let t=e.data;delete e.data,delete e.pagination;let n=this.getPayloadKey();return t&&n&&this.body[n]!==void 0&&(this.body[n]=Array.isArray(this.body[n])?[...this.body[n],...t]:{...this.body[n],...t}),this.body={...this.body,...e},this}response(e){let t=e??this.res;return this.runResponse({ensureJson:()=>this.json(),rawResponse:t,body:()=>this.body,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)}})}withResponse(e,t){return this}then(e,t){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:t})}catch(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onrejected:e})}finally(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:e})}},ke=class e extends ${body={data:[]};resource;collects;withResponseContext;isPaginatedCollectible(e){if(!e||typeof e!=`object`)return!1;let t=e;return t.pagination&&Array.isArray(t.data)?!0:t.meta&&typeof t.meta==`object`&&`currentPage`in t.meta?Array.isArray(t.data)||M(t.data):!1}constructor(e,t){super(),this.res=t,this.resource=e}data(){return this.toArray()}getBody(){return this.json(),this.body}setBody(e){return this.body=e,this}resolveCollectsConfig(){let e=this.collects;if(!e)return;let t=typeof e.config==`function`?e.config():{};return{preferredCase:t.preferredCase??e.preferredCase,responseStructure:{...e.responseStructure||{},...t.responseStructure||{}}}}resolveResponseStructure(){return this.resolveSerializerResponseStructure(this.constructor,this.resolveCollectsConfig())}resolveCurrentRootKey(){return this.resolveResponseStructure().rootKey}applyMetaToBody(e,t){this.body=k(this.body,e,t)}getResourceForMeta(){return this.resource}getPayloadKey(){let{wrap:e,rootKey:t,factory:n}=this.resolveResponseStructure();return n||!e?void 0:t}json(){if(!this.called.json){this.called.json=!0;let t=this.data();this.collects&&(t=t.map(e=>new this.collects(e).data())),t=N(t),t=U(t);let n=Array.isArray(this.resource)?{}:I(this.resource),{metaKey:r}=P(),i=r?n[r]:void 0;r&&delete n[r];let a=this.resolveSerializerCaseStyle(this.constructor,this.resolveCollectsConfig());if(a){let e=K(a);t=q(t,e)}let o=this.resolveMergedMeta(e.prototype.with),{wrap:s,rootKey:c,factory:l}=this.resolveResponseStructure();this.body=L({payload:t,meta:i,metaKey:r,wrap:s,rootKey:c,factory:l,context:{type:`collection`,resource:this.resource}}),this.body=k(this.body,{...n,...o||{}},c)}return this}toArray(){return this.called.toArray=!0,this.json(),N(Array.isArray(this.resource)?this.resource:M(this.resource)?this.resource.all():this.resource.data)}additional(e){this.called.additional=!0,this.json(),delete e.cursor,delete e.pagination;let t=this.getPayloadKey();return e.data&&t&&Array.isArray(this.body[t])&&(this.body[t]=[...this.body[t],...e.data]),this.body={...this.body,...e},this}response(e){let t=e??this.res;return this.runResponse({ensureJson:()=>this.json(),rawResponse:t,body:()=>this.body,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)}})}withResponse(e,t){return this}setCollects(e){return this.collects=e,this}then(e,t){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:t})}catch(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onrejected:e})}finally(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:e})}},Ae=class e extends ${body={data:{}};resource;withResponseContext;constructor(e,t){super(),this.res=t,this.resource=e;let n=this.resource.data??this.resource;if(!Array.isArray(n)){let e=j(n)?Object.keys(n.toObject()):Object.keys(n);for(let t of e)t in this||Object.defineProperty(this,t,{enumerable:!0,configurable:!0,get:()=>j(n)&&typeof n.getAttribute==`function`?n.getAttribute(t):this.resource.data?.[t]??this.resource[t],set:e=>{if(j(n)&&typeof n.setAttribute==`function`){n.setAttribute(t,e);return}this.resource.data&&this.resource.data[t]?this.resource.data[t]=e:this.resource[t]=e}})}}static collection(e){return new ke(e).setCollects(this)}data(){return this.toArray()}getBody(){return this.json(),this.body}setBody(e){return this.body=e,this}resolveResponseStructure(){return this.resolveSerializerResponseStructure(this.constructor)}resolveCurrentRootKey(){return this.resolveResponseStructure().rootKey}applyMetaToBody(e,t){this.body=k(this.body,e,t)}getResourceForMeta(){return this.resource}getPayloadKey(){let{wrap:e,rootKey:t,factory:n}=this.resolveResponseStructure();return n||!e?void 0:t}json(){if(!this.called.json){this.called.json=!0;let t=N(this.data());!Array.isArray(t)&&t&&t.data!==void 0&&(t=t.data),t=U(t);let n=this.resolveSerializerCaseStyle(this.constructor);if(n){let e=K(n);t=q(t,e)}let r=this.resolveMergedMeta(e.prototype.with),{wrap:i,rootKey:a,factory:o}=this.resolveResponseStructure();this.body=L({payload:t,wrap:i,rootKey:a,factory:o,context:{type:`resource`,resource:this.resource}}),this.body=k(this.body,r,a)}return this}toArray(){this.called.toArray=!0,this.json();let e=N(this.resource);return!Array.isArray(e)&&e&&e.data!==void 0&&(e=e.data),e}additional(e){this.called.additional=!0,this.json();let t=this.getPayloadKey();return e.data&&t&&this.body[t]!==void 0&&(this.body[t]=Array.isArray(this.body[t])?[...this.body[t],...e.data]:{...this.body[t],...e.data}),this.body={...this.body,...e},this}response(e){let t=e??this.res;return this.runResponse({ensureJson:()=>this.json(),rawResponse:t,body:()=>this.body,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)}})}withResponse(e,t){return this}then(e,t){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:t})}catch(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onrejected:e})}finally(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:e})}};export{f as ApiResource,z as CONDITIONAL_ATTRIBUTE_MISSING,Te as CliApp,Oe as GenericResource,Ee as InitCommand,De as MakeResource,Ae as Resource,ke as ResourceCollection,Q as ServerResponse,k as appendRootProperties,be as applyRuntimeConfig,I as buildPaginationExtras,L as buildResponseEnvelope,Y as defineConfig,K as getCaseTransformer,ve as getDefaultConfig,fe as getGlobalBaseUrl,x as getGlobalCase,D as getGlobalCursorMeta,me as getGlobalPageName,ce as getGlobalPaginatedExtras,ue as getGlobalPaginatedLinks,T as getGlobalPaginatedMeta,oe as getGlobalResponseFactory,ie as getGlobalResponseRootKey,C as getGlobalResponseStructure,re as getGlobalResponseWrap,P as getPaginationExtraKeys,M as isArkormLikeCollection,j as isArkormLikeModel,O as isPlainObject,we as loadRuntimeConfig,A as mergeMetadata,N as normalizeSerializableData,ye as resetRuntimeConfigForTests,H as resolveMergeWhen,B as resolveWhen,V as resolveWhenNotNull,R as resolveWithHookMetadata,U as sanitizeConditionalAttributes,de as setGlobalBaseUrl,b as setGlobalCase,E as setGlobalCursorMeta,pe as setGlobalPageName,se as setGlobalPaginatedExtras,le as setGlobalPaginatedLinks,w as setGlobalPaginatedMeta,ae as setGlobalResponseFactory,te as setGlobalResponseRootKey,S as setGlobalResponseStructure,ne as setGlobalResponseWrap,W as splitWords,G as toCamelCase,_e as toKebabCase,ge as toPascalCase,he as toSnakeCase,q as transformKeys};
25
+ `;var Q=class{_status=200;headers={};constructor(e,t){this.response=e,this.body=t}setStatusCode(e){return this._status=e,`status`in this.response&&typeof this.response.status==`function`?this.response.status(e):`status`in this.response&&(this.response.status=e),this}status(){return this._status}statusText(){if(`statusMessage`in this.response)return this.response.statusMessage;if(`statusText`in this.response)return this.response.statusText}setCookie(e,t,n){return this.#e(`Set-Cookie`,`${e}=${t}; ${Object.entries(n||{}).map(([e,t])=>`${e}=${t}`).join(`; `)}`),this}setHeaders(e){for(let[t,n]of Object.entries(e))this.#e(t,n);return this}header(e,t){return this.#e(e,t),this}#e(e,t){this.headers[e]=t,`headers`in this.response?this.response.headers.set(e,t):`setHeader`in this.response&&this.response.setHeader(e,t)}then(e,t){let n=Promise.resolve(this.body).then(e,t);return`send`in this.response&&this.response.send(this.body),n}catch(e){return this.then(void 0,e)}finally(e){return this.then(e,e)}},$=class{static preferredCase;static responseStructure;static config;instanceConfig;additionalMeta;called={};when(e,t){return B(e,t)}whenNotNull(e){return V(e)}mergeWhen(e,t){return H(e,t)}with(e){if(this.called.with=!0,e===void 0)return this.additionalMeta||{};let t=typeof e==`function`?e(this.getResourceForMeta()):e;return this.additionalMeta=A(this.additionalMeta,t),this.called.json&&this.applyMetaToBody(t,this.resolveCurrentRootKey()),this}withMeta(e){return this.with(e),this}resolveMergedMeta(e){return A(R(this,e),this.additionalMeta)}runResponse(e){this.called.toResponse=!0,e.ensureJson();let t=e.body(),n=e.createServerResponse(e.rawResponse,t);return this.called.withResponse=!0,e.callWithResponse(n,e.rawResponse),n}runThen(e){this.called.then=!0,e.ensureJson();let t=e.body();if(e.rawResponse!==void 0){let n=e.createServerResponse(e.rawResponse,t);this.called.withResponse=!0,e.callWithResponse(n,e.rawResponse)}else this.called.withResponse=!0,e.callWithResponse();let n=e.body(),r=Promise.resolve(n).then(e.onfulfilled,e.onrejected);return e.rawResponse!==void 0&&e.sendRawResponse&&e.sendRawResponse(e.rawResponse,n),r}config(e){return e===void 0?this.instanceConfig||{}:(this.instanceConfig={...this.instanceConfig||{},...e,responseStructure:{...this.instanceConfig?.responseStructure||{},...e.responseStructure||{}}},this)}resolveSerializerConfig(e,t){let n=typeof e.config==`function`?e.config():{};return{preferredCase:this.instanceConfig?.preferredCase??n?.preferredCase,responseStructure:{...n?.responseStructure||{},...this.instanceConfig?.responseStructure||{}}}}resolveSerializerCaseStyle(e,t){return this.resolveSerializerConfig(e,t).preferredCase??e.preferredCase??t?.preferredCase??x()}resolveSerializerResponseStructure(e,t){let n=this.resolveSerializerConfig(e,t),r=C();return{wrap:n.responseStructure?.wrap??e.responseStructure?.wrap??t?.responseStructure?.wrap??r?.wrap??!0,rootKey:n.responseStructure?.rootKey??e.responseStructure?.rootKey??t?.responseStructure?.rootKey??r?.rootKey??`data`,factory:n.responseStructure?.factory??e.responseStructure?.factory??t?.responseStructure?.factory??r?.factory}}},Oe=class e extends ${body={data:{}};resource;collects;withResponseContext;constructor(e,t){super(),this.res=t,this.resource=e;let n=!!this.resource&&typeof this.resource==`object`&&`data`in this.resource,r=n?this.resource.data:void 0,i=!!r&&!Array.isArray(r),a=n?r:this.resource;if(a&&typeof a==`object`&&!Array.isArray(a)&&!M(a)){let e=j(a)?Object.keys(a.toObject()):Object.keys(a);for(let t of e)t in this||Object.defineProperty(this,t,{enumerable:!0,configurable:!0,get:()=>j(a)&&typeof a.getAttribute==`function`?a.getAttribute(t):i?r[t]:this.resource[t],set:e=>{if(j(a)&&typeof a.setAttribute==`function`){a.setAttribute(t,e);return}if(i){r[t]=e;return}this.resource[t]=e}})}}data(){return this.resource}getBody(){return this.json(),this.body}setBody(e){return this.body=e,this}resolveCollectsConfig(){let e=this.collects;if(!e)return;let t=typeof e.config==`function`?e.config():{};return{preferredCase:t.preferredCase??e.preferredCase,responseStructure:{...e.responseStructure||{},...t.responseStructure||{}}}}resolveResponseStructure(){return this.resolveSerializerResponseStructure(this.constructor,this.resolveCollectsConfig())}resolveCurrentRootKey(){return this.resolveResponseStructure().rootKey}applyMetaToBody(e,t){this.body=k(this.body,e,t)}getResourceForMeta(){return this.resource}getPayloadKey(){let{wrap:e,rootKey:t,factory:n}=this.resolveResponseStructure();return n||!e?void 0:t}json(){if(!this.called.json){this.called.json=!0;let t=N(this.data());Array.isArray(t)&&this.collects&&(t=t.map(e=>new this.collects(e).data())),!Array.isArray(t)&&t&&t.data!==void 0&&(t=t.data),t=U(t);let n=I(this.resource),{metaKey:r}=P(),i=r?n[r]:void 0;r&&delete n[r];let a=this.resolveSerializerCaseStyle(this.constructor,this.resolveCollectsConfig());if(a){let e=K(a);t=q(t,e)}let o=this.resolveMergedMeta(e.prototype.with),{wrap:s,rootKey:c,factory:l}=this.resolveResponseStructure();this.body=L({payload:t,meta:i,metaKey:r,wrap:s,rootKey:c,factory:l,context:{type:`generic`,resource:this.resource}}),this.body=k(this.body,{...n,...o||{}},c)}return this}toObject(){this.called.toObject=!0,this.json();let e=N(this.resource);return!Array.isArray(e)&&e&&e.data!==void 0&&(e=e.data),e}toArray(){return this.called.toArray=!0,this.toObject()}additional(e){this.called.additional=!0,this.json();let t=e.data;delete e.data,delete e.pagination;let n=this.getPayloadKey();return t&&n&&this.body[n]!==void 0&&(this.body[n]=Array.isArray(this.body[n])?[...this.body[n],...t]:{...this.body[n],...t}),this.body={...this.body,...e},this}response(e){let t=e??this.res;return this.runResponse({ensureJson:()=>this.json(),rawResponse:t,body:()=>this.body,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)}})}withResponse(e,t){return this}then(e,t){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:t})}catch(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onrejected:e})}finally(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:e})}},ke=class e extends ${body={data:[]};resource;collects;withResponseContext;isPaginatedCollectible(e){if(!e||typeof e!=`object`)return!1;let t=e;return t.pagination&&Array.isArray(t.data)?!0:t.meta&&typeof t.meta==`object`&&`currentPage`in t.meta?Array.isArray(t.data)||M(t.data):!1}constructor(e,t){super(),this.res=t,this.resource=e}data(){return this.toObject()}getBody(){return this.json(),this.body}setBody(e){return this.body=e,this}resolveCollectsConfig(){let e=this.collects;if(!e)return;let t=typeof e.config==`function`?e.config():{};return{preferredCase:t.preferredCase??e.preferredCase,responseStructure:{...e.responseStructure||{},...t.responseStructure||{}}}}resolveResponseStructure(){return this.resolveSerializerResponseStructure(this.constructor,this.resolveCollectsConfig())}resolveCurrentRootKey(){return this.resolveResponseStructure().rootKey}applyMetaToBody(e,t){this.body=k(this.body,e,t)}getResourceForMeta(){return this.resource}getPayloadKey(){let{wrap:e,rootKey:t,factory:n}=this.resolveResponseStructure();return n||!e?void 0:t}json(){if(!this.called.json){this.called.json=!0;let t=this.data();this.collects&&(t=t.map(e=>new this.collects(e).data())),t=N(t),t=U(t);let n=Array.isArray(this.resource)?{}:I(this.resource),{metaKey:r}=P(),i=r?n[r]:void 0;r&&delete n[r];let a=this.resolveSerializerCaseStyle(this.constructor,this.resolveCollectsConfig());if(a){let e=K(a);t=q(t,e)}let o=this.resolveMergedMeta(e.prototype.with),{wrap:s,rootKey:c,factory:l}=this.resolveResponseStructure();this.body=L({payload:t,meta:i,metaKey:r,wrap:s,rootKey:c,factory:l,context:{type:`collection`,resource:this.resource}}),this.body=k(this.body,{...n,...o||{}},c)}return this}toObject(){return this.called.toObject=!0,this.json(),N(Array.isArray(this.resource)?this.resource:M(this.resource)?this.resource.all():this.resource.data)}toArray(){return this.called.toArray=!0,this.toObject()}additional(e){this.called.additional=!0,this.json(),delete e.cursor,delete e.pagination;let t=this.getPayloadKey();return e.data&&t&&Array.isArray(this.body[t])&&(this.body[t]=[...this.body[t],...e.data]),this.body={...this.body,...e},this}response(e){let t=e??this.res;return this.runResponse({ensureJson:()=>this.json(),rawResponse:t,body:()=>this.body,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)}})}withResponse(e,t){return this}setCollects(e){return this.collects=e,this}then(e,t){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:t})}catch(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onrejected:e})}finally(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:e})}},Ae=class e extends ${body={data:{}};resource;withResponseContext;constructor(e,t){super(),this.res=t,this.resource=e;let n=this.resource.data??this.resource;if(!Array.isArray(n)){let e=j(n)?Object.keys(n.toObject()):Object.keys(n);for(let t of e)t in this||Object.defineProperty(this,t,{enumerable:!0,configurable:!0,get:()=>j(n)&&typeof n.getAttribute==`function`?n.getAttribute(t):this.resource.data?.[t]??this.resource[t],set:e=>{if(j(n)&&typeof n.setAttribute==`function`){n.setAttribute(t,e);return}this.resource.data&&this.resource.data[t]?this.resource.data[t]=e:this.resource[t]=e}})}}static collection(e){return new ke(e).setCollects(this)}data(){return this.toObject()}getBody(){return this.json(),this.body}setBody(e){return this.body=e,this}resolveResponseStructure(){return this.resolveSerializerResponseStructure(this.constructor)}resolveCurrentRootKey(){return this.resolveResponseStructure().rootKey}applyMetaToBody(e,t){this.body=k(this.body,e,t)}getResourceForMeta(){return this.resource}getPayloadKey(){let{wrap:e,rootKey:t,factory:n}=this.resolveResponseStructure();return n||!e?void 0:t}json(){if(!this.called.json){this.called.json=!0;let t=N(this.data());!Array.isArray(t)&&t&&t.data!==void 0&&(t=t.data),t=U(t);let n=this.resolveSerializerCaseStyle(this.constructor);if(n){let e=K(n);t=q(t,e)}let r=this.resolveMergedMeta(e.prototype.with),{wrap:i,rootKey:a,factory:o}=this.resolveResponseStructure();this.body=L({payload:t,wrap:i,rootKey:a,factory:o,context:{type:`resource`,resource:this.resource}}),this.body=k(this.body,r,a)}return this}toObject(){this.called.toObject=!0,this.json();let e=N(this.resource);return!Array.isArray(e)&&e&&e.data!==void 0&&(e=e.data),e}toArray(){return this.called.toArray=!0,this.toObject()}additional(e){this.called.additional=!0,this.json();let t=this.getPayloadKey();return e.data&&t&&this.body[t]!==void 0&&(this.body[t]=Array.isArray(this.body[t])?[...this.body[t],...e.data]:{...this.body[t],...e.data}),this.body={...this.body,...e},this}response(e){let t=e??this.res;return this.runResponse({ensureJson:()=>this.json(),rawResponse:t,body:()=>this.body,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)}})}withResponse(e,t){return this}then(e,t){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:t})}catch(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onrejected:e})}finally(e){return this.runThen({ensureJson:()=>this.json(),body:()=>this.body,rawResponse:this.res,createServerResponse:(e,t)=>{let n=new Q(e,t);return this.withResponseContext={response:n,raw:e},n},callWithResponse:(e,t)=>{this.withResponse(e,t)},sendRawResponse:(e,t)=>{e.send(t)},onfulfilled:e,onrejected:e})}};export{f as ApiResource,z as CONDITIONAL_ATTRIBUTE_MISSING,Te as CliApp,Oe as GenericResource,Ee as InitCommand,De as MakeResource,Ae as Resource,ke as ResourceCollection,Q as ServerResponse,k as appendRootProperties,be as applyRuntimeConfig,I as buildPaginationExtras,L as buildResponseEnvelope,Y as defineConfig,K as getCaseTransformer,ve as getDefaultConfig,fe as getGlobalBaseUrl,x as getGlobalCase,D as getGlobalCursorMeta,me as getGlobalPageName,ce as getGlobalPaginatedExtras,ue as getGlobalPaginatedLinks,T as getGlobalPaginatedMeta,oe as getGlobalResponseFactory,ie as getGlobalResponseRootKey,C as getGlobalResponseStructure,re as getGlobalResponseWrap,P as getPaginationExtraKeys,M as isArkormLikeCollection,j as isArkormLikeModel,O as isPlainObject,we as loadRuntimeConfig,A as mergeMetadata,N as normalizeSerializableData,ye as resetRuntimeConfigForTests,H as resolveMergeWhen,B as resolveWhen,V as resolveWhenNotNull,R as resolveWithHookMetadata,U as sanitizeConditionalAttributes,de as setGlobalBaseUrl,b as setGlobalCase,E as setGlobalCursorMeta,pe as setGlobalPageName,se as setGlobalPaginatedExtras,le as setGlobalPaginatedLinks,w as setGlobalPaginatedMeta,ae as setGlobalResponseFactory,te as setGlobalResponseRootKey,S as setGlobalResponseStructure,ne as setGlobalResponseWrap,W as splitWords,G as toCamelCase,_e as toKebabCase,ge as toPascalCase,he as toSnakeCase,q as transformKeys};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "resora",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "A structured API response layer for Node.js and TypeScript with automatic JSON responses, collection support, and pagination handling.",
5
5
  "keywords": [
6
6
  "api",
@@ -52,7 +52,7 @@
52
52
  "@types/node": "^20.10.6",
53
53
  "@types/supertest": "^6.0.3",
54
54
  "@vitest/coverage-v8": "4.0.18",
55
- "arkormx": "^0.1.11",
55
+ "arkormx": "^0.2.5",
56
56
  "barrelize": "^1.7.3",
57
57
  "eslint": "^10.0.0",
58
58
  "express": "^5.1.0",
@@ -11,6 +11,6 @@ export default class {{ResourceName}} extends ResourceCollection {
11
11
  * @memberof {{ResourceName}}
12
12
  */
13
13
  data () {
14
- return this.toArray()
14
+ return this.toObject()
15
15
  }
16
16
  }
@@ -10,6 +10,6 @@ export default class {{ResourceName}} extends Resource {
10
10
  * @memberof {{ResourceName}}
11
11
  */
12
12
  data () {
13
- return this.toArray()
13
+ return this.toObject()
14
14
  }
15
15
  }