resora 0.2.8 → 0.2.10
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 +2 -2
- package/bin/index.mjs +5 -5
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +261 -9
- package/dist/index.d.mts +261 -9
- package/dist/index.mjs +2 -2
- package/package.json +2 -2
- package/stubs/resource.collection.stub +1 -1
- package/stubs/resource.stub +1 -1
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.
|
|
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.
|
|
91
|
+
return this.toObject();
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
```
|
package/bin/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{copyFileSync as e,existsSync as t,mkdirSync as n,readFileSync as r,rmSync as i,writeFileSync as a}from"fs";import o,{dirname as s,join as c}from"path";import{createRequire as l}from"module";import{pathToFileURL as u}from"url";import{Command as d,Kernel as f}from"@h3ravel/musket";let p={first:`first`,last:`last`,prev:`prev`,next:`next`},m={
|
|
3
|
-
`),u=`import ${s} from './${s}'\n`,d=(!!n?.collection||e.endsWith(`Collection`))&&t(c(this.config.resourcesDir,`${s}.ts`)),f=this.generateFile(o,a,{ResourceName:r,CollectionResourceName:r.replace(/(Resource|Collection)$/,``)+`Resource`,"collects = Resource":d?l:``,"import = Resource":d?u:``},n);return{name:r,path:f}}},
|
|
2
|
+
import{copyFileSync as e,existsSync as t,mkdirSync as n,readFileSync as r,rmSync as i,writeFileSync as a}from"fs";import o,{dirname as s,join as c}from"path";import{createRequire as l}from"module";import{pathToFileURL as u}from"url";import{Command as d,Kernel as f}from"@h3ravel/musket";let p={first:`first`,last:`last`,prev:`prev`,next:`next`},m={previous:`previous`,next:`next`};const h=e=>{p={...p,...e}},g=e=>{m={...m,...e}};let _=o.resolve(process.cwd(),`node_modules/resora/stubs`);t(_)||(_=o.resolve(process.cwd(),`stubs`));const v=()=>({stubsDir:_,preferredCase:`camel`,responseStructure:{wrap:!0,rootKey:`data`},paginatedExtras:[`meta`,`links`],baseUrl:`https://localhost`,pageName:`page`,paginatedLinks:{first:`first`,last:`last`,prev:`prev`,next:`next`},paginatedMeta:{to:`to`,from:`from`,links:`links`,path:`path`,total:`total`,per_page:`per_page`,last_page:`last_page`,current_page:`current_page`},cursorMeta:{previous:`previous`,next:`next`},resourcesDir:`src/resources`,stubs:{config:`resora.config.stub`,resource:`resource.stub`,collection:`resource.collection.stub`}}),y=e=>{let t=v();return Object.assign(t,e,{stubs:Object.assign(t.stubs,e.stubs||{})},{cursorMeta:Object.assign(t.cursorMeta,e.cursorMeta||{})},{paginatedMeta:e.paginatedMeta||t.paginatedMeta},{paginatedLinks:Object.assign(t.paginatedLinks,e.paginatedLinks||{})},{responseStructure:Object.assign(t.responseStructure,e.responseStructure||{})})};let b=!1,x;const S=e=>{e.preferredCase!==`camel`&&e.preferredCase,e.responseStructure,e.paginatedExtras,h(e.paginatedLinks),e.paginatedMeta,g(e.cursorMeta),e.baseUrl,e.pageName},C=async e=>await import(`${u(e).href}?resora_runtime=${Date.now()}`),w=e=>{S(y((e?.default??e)||{})),b=!0},T=()=>{let e=l(import.meta.url),n=[o.join(process.cwd(),`resora.config.cjs`)];for(let r of n)if(t(r))try{return w(e(r)),!0}catch{continue}return!1};(async()=>{if(!b){if(x)return await x;T()||(x=(async()=>{let e=[o.join(process.cwd(),`resora.config.js`),o.join(process.cwd(),`resora.config.ts`)];for(let n of e)if(t(n))try{w(await C(n));return}catch{continue}b=!0})(),await x)}})();var E=class{command;config={};constructor(e={}){this.config=y(e)}async loadConfig(e={}){this.config=y(e);let n=[c(process.cwd(),`resora.config.ts`),c(process.cwd(),`resora.config.js`),c(process.cwd(),`resora.config.cjs`)];for(let e of n)if(t(e))try{let{default:t}=await import(e);Object.assign(this.config,t);break}catch(t){console.error(`Error loading config file at ${e}:`,t)}return this}getConfig(){return this.config}init(){let n=c(process.cwd(),`resora.config.js`),i=c(this.config.stubsDir,this.config.stubs.config);return t(n)&&!this.command.option(`force`)&&(this.command.error(`Error: ${n} already exists.`),process.exit(1)),this.ensureDirectory(n),t(n)&&this.command.option(`force`)&&e(n,n.replace(/\.js$/,`.backup.${Date.now()}.js`)),a(n,r(i,`utf-8`)),{path:n}}ensureDirectory(e){let r=s(e);t(r)||n(r,{recursive:!0})}generateFile(e,n,o,s){t(n)&&!s?.force?(this.command.error(`Error: ${n} already exists.`),process.exit(1)):t(n)&&s?.force&&i(n);let c=r(e,`utf-8`);for(let[e,t]of Object.entries(o))c=c.replace(RegExp(`{{${e}}}`,`g`),t);return this.ensureDirectory(n),a(n,c),n}makeResource(e,n){let r=e;n?.collection&&!e.endsWith(`Collection`)&&!e.endsWith(`Resource`)?r+=`Collection`:!n?.collection&&!e.endsWith(`Resource`)&&!e.endsWith(`Collection`)&&(r+=`Resource`);let i=`${r}.ts`,a=c(this.config.resourcesDir,i),o=c(this.config.stubsDir,n?.collection||e.endsWith(`Collection`)?this.config.stubs.collection:this.config.stubs.resource);t(o)||(this.command.error(`Error: Stub file ${o} not found.`),process.exit(1)),r=r.split(`/`).pop()?.split(`.`).shift();let s=r.replace(/(Resource|Collection)$/,``)+`Resource`,l=[`/**`,` * The resource that this collection collects.`,` */`,`collects = ${s}`].join(`
|
|
3
|
+
`),u=`import ${s} from './${s}'\n`,d=(!!n?.collection||e.endsWith(`Collection`))&&t(c(this.config.resourcesDir,`${s}.ts`)),f=this.generateFile(o,a,{ResourceName:r,CollectionResourceName:r.replace(/(Resource|Collection)$/,``)+`Resource`,"collects = Resource":d?l:``,"import = Resource":d?u:``},n);return{name:r,path:f}}},D=class extends d{signature=`init
|
|
4
4
|
{--force : Force overwrite if config file already exists (existing file will be backed up) }
|
|
5
|
-
`;description=`Initialize Resora`;async handle(){this.app.command=this,this.app.init(),this.success(`Resora initialized`)}},
|
|
5
|
+
`;description=`Initialize Resora`;async handle(){this.app.command=this,this.app.init(),this.success(`Resora initialized`)}},O=class extends d{signature=`#create:
|
|
6
6
|
{resource : Generates a new resource file.
|
|
7
7
|
| {name : Name of the resource to create}
|
|
8
8
|
| {--c|collection : Make a resource collection}
|
|
@@ -16,11 +16,11 @@ import{copyFileSync as e,existsSync as t,mkdirSync as n,readFileSync as r,rmSync
|
|
|
16
16
|
| {prefix : prefix of the resources to create, "Admin" will create AdminResource, AdminCollection}
|
|
17
17
|
| {--force : Create the resource or collection file even if it already exists.}
|
|
18
18
|
}
|
|
19
|
-
`;description=`Create a new resource or resource collection file`;async handle(){this.app.command=this;let e=``,t=this.argument(`name`)||this.argument(`prefix`),n=this.dictionary.name||this.dictionary.baseCommand;if([`resource`,`collection`].includes(n)&&!t)return void this.error(`Error: Name argument is required.`);if(n===`all`&&!t)return void this.error(`Error: Prefix argument is required.`);switch(n){case`resource`:({path:e}=this.app.makeResource(t,this.options()));break;case`collection`:({path:e}=this.app.makeResource(t+`Collection`,this.options()));break;case`all`:{let n=this.app.makeResource(t,{force:this.option(`force`)}),r=this.app.makeResource(t+`Collection`,{collection:!0,force:this.option(`force`)});e=`${n.path}, ${r.path}`;break}default:this.fail(`Unknown action: ${n}`)}this.success(`Created: ${e}`)}},
|
|
19
|
+
`;description=`Create a new resource or resource collection file`;async handle(){this.app.command=this;let e=``,t=this.argument(`name`)||this.argument(`prefix`),n=this.dictionary.name||this.dictionary.baseCommand;if([`resource`,`collection`].includes(n)&&!t)return void this.error(`Error: Name argument is required.`);if(n===`all`&&!t)return void this.error(`Error: Prefix argument is required.`);switch(n){case`resource`:({path:e}=this.app.makeResource(t,this.options()));break;case`collection`:({path:e}=this.app.makeResource(t+`Collection`,this.options()));break;case`all`:{let n=this.app.makeResource(t,{force:this.option(`force`)}),r=this.app.makeResource(t+`Collection`,{collection:!0,force:this.option(`force`)});e=`${n.path}, ${r.path}`;break}default:this.fail(`Unknown action: ${n}`)}this.success(`Created: ${e}`)}},k=String.raw`
|
|
20
20
|
_____
|
|
21
21
|
| __ \
|
|
22
22
|
| |__) |___ ___ ___ _ __ __ _
|
|
23
23
|
| _ // _ \/ __|/ _ \| '__/ _, |
|
|
24
24
|
| | \ \ __/\__ \ (_) | | | (_| |
|
|
25
25
|
|_| \_\___||___/\___/|_| \__,_|
|
|
26
|
-
`;const
|
|
26
|
+
`;const A=new E;await f.init(await A.loadConfig(),{logo:k,name:`Resora CLI`,baseCommands:[O,D,...A.getConfig().extraCommands||[]],exceptionHandler(e){throw e}});export{};
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`fs`),l=require(`path`);l=s(l);let u=require(`module`),d=require(`url`),f=require(`@h3ravel/musket`);function ee(e){return e}let p,m,h=[`meta`,`links`],g={first:`first`,last:`last`,prev:`prev`,next:`next`},_=`https://localhost`,v=`page`,y={to:`to`,from:`from`,links:`links`,path:`path`,total:`total`,per_page:`per_page`,last_page:`last_page`,current_page:`current_page`},b={previous:`previous`,next:`next`};const x=e=>{p=e},S=()=>p,C=e=>{m=e},w=()=>m,te=e=>{m={...m||{},rootKey:e}},ne=e=>{m={...m||{},wrap:e}},re=()=>m?.wrap,ie=()=>m?.rootKey,ae=e=>{m={...m||{},factory:e}},oe=()=>m?.factory,se=e=>{h=e},ce=()=>h,le=e=>{g={...g,...e}},ue=()=>g,de=e=>{_=e},fe=()=>_,pe=e=>{v=e},me=()=>v,T=e=>{y=
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`fs`),l=require(`path`);l=s(l);let u=require(`module`),d=require(`url`),f=require(`@h3ravel/musket`);function ee(e){return e}let p,m,h=[`meta`,`links`],g={first:`first`,last:`last`,prev:`prev`,next:`next`},_=`https://localhost`,v=`page`,y={to:`to`,from:`from`,links:`links`,path:`path`,total:`total`,per_page:`per_page`,last_page:`last_page`,current_page:`current_page`},b={previous:`previous`,next:`next`};const x=e=>{p=e},S=()=>p,C=e=>{m=e},w=()=>m,te=e=>{m={...m||{},rootKey:e}},ne=e=>{m={...m||{},wrap:e}},re=()=>m?.wrap,ie=()=>m?.rootKey,ae=e=>{m={...m||{},factory:e}},oe=()=>m?.factory,se=e=>{h=e},ce=()=>h,le=e=>{g={...g,...e}},ue=()=>g,de=e=>{_=e},fe=()=>_,pe=e=>{v=e},me=()=>v,T=e=>{y=e},E=()=>y,D=e=>{b={...b,...e}},O=()=>b,k=e=>{if(typeof e!=`object`||!e||Array.isArray(e)||e instanceof Date||e instanceof RegExp)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},A=(e,t,n=`data`)=>!t||Object.keys(t).length===0?e:Array.isArray(e)?{[n]:e,...t}:k(e)?{...e,...t}:{[n]:e,...t},j=(e,t)=>{if(!t)return e;if(!e)return t;let n={...e};for(let[e,r]of Object.entries(t)){let t=n[e];k(t)&&k(r)?n[e]=j(t,r):n[e]=r}return n},M=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.toObject==`function`&&typeof t.getRawAttributes==`function`},N=e=>!e||typeof e!=`object`?!1:typeof e.all==`function`,P=e=>{if(Array.isArray(e))return e.map(e=>P(e));if(M(e))return P(e.toObject());if(N(e)){let t=e.all();return Array.isArray(t)?t.map(e=>P(e)):P(t)}return k(e)?Object.entries(e).reduce((e,[t,n])=>(e[t]=P(n),e),{}):e},F=()=>{let e=ce();return Array.isArray(e)?{metaKey:e.includes(`meta`)?`meta`:void 0,linksKey:e.includes(`links`)?`links`:void 0,cursorKey:e.includes(`cursor`)?`cursor`:void 0}:{metaKey:e.meta,linksKey:e.links,cursorKey:e.cursor}},I=(e,t)=>{if(e===void 0)return;let n=t||``,r=fe()||``,i=/^https?:\/\//i.test(n),a=r.replace(/\/$/,``),o=n.replace(/^\//,``),s=i?n:a?o?`${a}/${o}`:a:``;if(!s)return;let c=new URL(s);return c.searchParams.set(me()||`page`,String(e)),c.toString()},L=e=>{let{metaKey:t,linksKey:n,cursorKey:r}=F(),i={},a=!!e&&typeof e==`object`&&!!e.meta&&typeof e.meta==`object`&&(Array.isArray(e.data)||N(e.data)),o=a?{first:typeof e.firstPageUrl==`function`?e.firstPageUrl():void 0,last:typeof e.lastPageUrl==`function`?e.lastPageUrl():void 0,prev:typeof e.previousPageUrl==`function`?e.previousPageUrl():void 0,next:typeof e.nextPageUrl==`function`?e.nextPageUrl():void 0}:void 0,s=o?Object.entries(o).reduce((e,[t,n])=>(n!==void 0&&(e[t]=n),e),{}):void 0,c=e?.pagination||(a?{...e.meta,links:e.links||s}:void 0),l=e?.cursor,u={},d={};if(c){let e={to:c.to,from:c.from,links:c.links,path:c.path,total:c.total,per_page:c.perPage,last_page:c.lastPage,current_page:c.currentPage};for(let[t,n]of Object.entries(E())){if(!n)continue;let r=e[t];r!==void 0&&(u[n]=r)}let t={first:c.links&&Object.prototype.hasOwnProperty.call(c.links,`first`)?c.links.first:I(c.firstPage,c.path),last:c.links&&Object.prototype.hasOwnProperty.call(c.links,`last`)?c.links.last:I(c.lastPage,c.path),prev:c.links&&Object.prototype.hasOwnProperty.call(c.links,`prev`)?c.links.prev:I(c.prevPage,c.path),next:c.links&&Object.prototype.hasOwnProperty.call(c.links,`next`)?c.links.next:I(c.nextPage,c.path)};for(let[e,n]of Object.entries(ue())){if(!n)continue;let r=t[e];r!==void 0&&(d[n]=r)}}if(l){let e={},t={previous:l.previous,next:l.next};for(let[n,r]of Object.entries(O())){if(!r)continue;let i=t[n];i!==void 0&&(e[r]=i)}r&&Object.keys(e).length>0?i[r]=e:Object.keys(e).length>0&&(u.cursor=e)}return t&&Object.keys(u).length>0&&(i[t]=u),n&&Object.keys(d).length>0&&(i[n]=d),i},R=({payload:e,meta:t,metaKey:n=`meta`,wrap:r=!0,rootKey:i=`data`,factory:a,context:o})=>{if(a)return a(e,{...o,rootKey:i,meta:t});if(!r)return t===void 0?e:k(e)?{...e,[n]:t}:{[i]:e,[n]:t};let s={[i]:e};return t!==void 0&&(s[n]=t),s},z=(e,t)=>{let n=e?.with;if(typeof n!=`function`||n===t||n.length>0)return;let r=n.call(e);return k(r)?r:void 0},B=Symbol(`resora.conditional.missing`),V=(e,t)=>e?typeof t==`function`?t():t:B,H=e=>e??B,he=(e,t)=>{if(!e)return{};let n=typeof t==`function`?t():t;return k(n)?n:{}},U=e=>{if(e===B)return B;if(Array.isArray(e))return e.map(e=>U(e)).filter(e=>e!==B);if(k(e)){let t={};for(let[n,r]of Object.entries(e)){let e=U(r);e!==B&&(t[n]=e)}return t}return e},W=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1 $2`).replace(/([A-Z]+)([A-Z][a-z])/g,`$1 $2`).replace(/[-_\s]+/g,` `).trim().toLowerCase().split(` `).filter(Boolean),ge=e=>W(e).map((e,t)=>t===0?e:e.charAt(0).toUpperCase()+e.slice(1)).join(``),_e=e=>W(e).join(`_`),ve=e=>W(e).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``),ye=e=>W(e).join(`-`),G=e=>{if(typeof e==`function`)return e;switch(e){case`camel`:return ge;case`snake`:return _e;case`pascal`:return ve;case`kebab`:return ye}},K=(e,t)=>e==null?e:Array.isArray(e)?e.map(e=>K(e,t)):e instanceof Date||e instanceof RegExp?e:typeof e==`object`?Object.fromEntries(Object.entries(e).map(([e,n])=>[t(e),K(n,t)])):e;let q=l.default.resolve(process.cwd(),`node_modules/resora/stubs`);(0,c.existsSync)(q)||(q=l.default.resolve(process.cwd(),`stubs`));const be=()=>({stubsDir:q,preferredCase:`camel`,responseStructure:{wrap:!0,rootKey:`data`},paginatedExtras:[`meta`,`links`],baseUrl:`https://localhost`,pageName:`page`,paginatedLinks:{first:`first`,last:`last`,prev:`prev`,next:`next`},paginatedMeta:{to:`to`,from:`from`,links:`links`,path:`path`,total:`total`,per_page:`per_page`,last_page:`last_page`,current_page:`current_page`},cursorMeta:{previous:`previous`,next:`next`},resourcesDir:`src/resources`,stubs:{config:`resora.config.stub`,resource:`resource.stub`,collection:`resource.collection.stub`}}),J=e=>{let t=be();return Object.assign(t,e,{stubs:Object.assign(t.stubs,e.stubs||{})},{cursorMeta:Object.assign(t.cursorMeta,e.cursorMeta||{})},{paginatedMeta:e.paginatedMeta||t.paginatedMeta},{paginatedLinks:Object.assign(t.paginatedLinks,e.paginatedLinks||{})},{responseStructure:Object.assign(t.responseStructure,e.responseStructure||{})})};let Y=!1,X;const xe=()=>{Y=!1,X=void 0},Se=e=>{e.preferredCase!==`camel`&&x(e.preferredCase),C(e.responseStructure),se(e.paginatedExtras),le(e.paginatedLinks),T(e.paginatedMeta),D(e.cursorMeta),de(e.baseUrl),pe(e.pageName)},Ce=async e=>await import(`${(0,d.pathToFileURL)(e).href}?resora_runtime=${Date.now()}`),we=e=>{Se(J((e?.default??e)||{})),Y=!0},Te=()=>{let e=(0,u.createRequire)(e(`url`).pathToFileURL(__filename).href),t=[l.default.join(process.cwd(),`resora.config.cjs`)];for(let n of t)if((0,c.existsSync)(n))try{return we(e(n)),!0}catch{continue}return!1},Z=async()=>{if(!Y){if(X)return await X;Te()||(X=(async()=>{let e=[l.default.join(process.cwd(),`resora.config.js`),l.default.join(process.cwd(),`resora.config.ts`)];for(let t of e)if((0,c.existsSync)(t))try{we(await Ce(t));return}catch{continue}Y=!0})(),await X)}};Z();var Ee=class{command;config={};constructor(e={}){this.config=J(e)}async loadConfig(e={}){this.config=J(e);let t=[(0,l.join)(process.cwd(),`resora.config.ts`),(0,l.join)(process.cwd(),`resora.config.js`),(0,l.join)(process.cwd(),`resora.config.cjs`)];for(let e of t)if((0,c.existsSync)(e))try{let{default:t}=await import(e);Object.assign(this.config,t);break}catch(t){console.error(`Error loading config file at ${e}:`,t)}return this}getConfig(){return this.config}init(){let e=(0,l.join)(process.cwd(),`resora.config.js`),t=(0,l.join)(this.config.stubsDir,this.config.stubs.config);return(0,c.existsSync)(e)&&!this.command.option(`force`)&&(this.command.error(`Error: ${e} already exists.`),process.exit(1)),this.ensureDirectory(e),(0,c.existsSync)(e)&&this.command.option(`force`)&&(0,c.copyFileSync)(e,e.replace(/\.js$/,`.backup.${Date.now()}.js`)),(0,c.writeFileSync)(e,(0,c.readFileSync)(t,`utf-8`)),{path:e}}ensureDirectory(e){let t=(0,l.dirname)(e);(0,c.existsSync)(t)||(0,c.mkdirSync)(t,{recursive:!0})}generateFile(e,t,n,r){(0,c.existsSync)(t)&&!r?.force?(this.command.error(`Error: ${t} already exists.`),process.exit(1)):(0,c.existsSync)(t)&&r?.force&&(0,c.rmSync)(t);let i=(0,c.readFileSync)(e,`utf-8`);for(let[e,t]of Object.entries(n))i=i.replace(RegExp(`{{${e}}}`,`g`),t);return this.ensureDirectory(t),(0,c.writeFileSync)(t,i),t}makeResource(e,t){let n=e;t?.collection&&!e.endsWith(`Collection`)&&!e.endsWith(`Resource`)?n+=`Collection`:!t?.collection&&!e.endsWith(`Resource`)&&!e.endsWith(`Collection`)&&(n+=`Resource`);let r=`${n}.ts`,i=(0,l.join)(this.config.resourcesDir,r),a=(0,l.join)(this.config.stubsDir,t?.collection||e.endsWith(`Collection`)?this.config.stubs.collection:this.config.stubs.resource);(0,c.existsSync)(a)||(this.command.error(`Error: Stub file ${a} not found.`),process.exit(1)),n=n.split(`/`).pop()?.split(`.`).shift();let o=n.replace(/(Resource|Collection)$/,``)+`Resource`,s=[`/**`,` * The resource that this collection collects.`,` */`,`collects = ${o}`].join(`
|
|
2
2
|
`),u=`import ${o} from './${o}'\n`,d=(!!t?.collection||e.endsWith(`Collection`))&&(0,c.existsSync)((0,l.join)(this.config.resourcesDir,`${o}.ts`)),f=this.generateFile(a,i,{ResourceName:n,CollectionResourceName:n.replace(/(Resource|Collection)$/,``)+`Resource`,"collects = Resource":d?s:``,"import = Resource":d?u:``},t);return{name:n,path:f}}},De=class extends f.Command{signature=`init
|
|
3
3
|
{--force : Force overwrite if config file already exists (existing file will be backed up) }
|
|
4
4
|
`;description=`Initialize Resora`;async handle(){this.app.command=this,this.app.init(),this.success(`Resora initialized`)}},Oe=class extends f.Command{signature=`#create:
|
|
@@ -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={};constructor(){Z()}when(e,t){return V(e,t)}whenNotNull(e){return H(e)}mergeWhen(e,t){return he(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=U(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=G(a);t=K(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=U(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=G(a);t=K(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=U(t);let n=this.resolveSerializerCaseStyle(this.constructor);if(n){let e=G(n);t=K(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=Se,exports.buildPaginationExtras=L,exports.buildResponseEnvelope=R,exports.defineConfig=J,exports.getCaseTransformer=G,exports.getDefaultConfig=be,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=Z,exports.mergeMetadata=j,exports.normalizeSerializableData=P,exports.resetRuntimeConfigForTests=xe,exports.resolveMergeWhen=he,exports.resolveWhen=V,exports.resolveWhenNotNull=H,exports.resolveWithHookMetadata=z,exports.sanitizeConditionalAttributes=U,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=W,exports.toCamelCase=ge,exports.toKebabCase=ye,exports.toPascalCase=ve,exports.toSnakeCase=_e,exports.transformKeys=K;
|
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,64 @@ declare abstract class BaseSerializer<TResource = any> {
|
|
|
439
474
|
then?: boolean;
|
|
440
475
|
toResponse?: boolean;
|
|
441
476
|
};
|
|
477
|
+
constructor();
|
|
478
|
+
/**
|
|
479
|
+
* Helper method to conditionally resolve a value based on a condition.
|
|
480
|
+
*
|
|
481
|
+
* @param condition
|
|
482
|
+
* @param value
|
|
483
|
+
* @returns
|
|
484
|
+
*/
|
|
442
485
|
when<T>(condition: any, value: T | (() => T)): T | undefined;
|
|
486
|
+
/**
|
|
487
|
+
* Helper method to conditionally resolve a value only if it's not null or undefined.
|
|
488
|
+
*
|
|
489
|
+
* @param value
|
|
490
|
+
* @returns
|
|
491
|
+
*/
|
|
443
492
|
whenNotNull<T>(value: T | null | undefined): T | undefined;
|
|
493
|
+
/**
|
|
494
|
+
* Helper method to conditionally merge values into the response based on a condition.
|
|
495
|
+
*
|
|
496
|
+
* @param condition
|
|
497
|
+
* @param value
|
|
498
|
+
* @returns
|
|
499
|
+
*/
|
|
444
500
|
mergeWhen<T extends Record<string, any>>(condition: any, value: T | (() => T)): Partial<T>;
|
|
501
|
+
/**
|
|
502
|
+
* Resolve the current root key for the response structure.
|
|
503
|
+
*/
|
|
445
504
|
protected abstract resolveCurrentRootKey(): string;
|
|
446
505
|
protected abstract applyMetaToBody(meta: MetaData, rootKey: string): void;
|
|
447
506
|
protected abstract getResourceForMeta(): TResource;
|
|
507
|
+
/**
|
|
508
|
+
* Add additional metadata to the response. If called without arguments.
|
|
509
|
+
*
|
|
510
|
+
* @param meta
|
|
511
|
+
* @returns
|
|
512
|
+
*/
|
|
448
513
|
with(meta?: any): any;
|
|
514
|
+
/**
|
|
515
|
+
* Add additional metadata to the response, ensuring it is merged with any existing metadata.
|
|
516
|
+
*
|
|
517
|
+
* @param meta
|
|
518
|
+
* @returns
|
|
519
|
+
*/
|
|
449
520
|
withMeta<M extends MetaData>(meta: M | ((resource: TResource) => M)): this;
|
|
521
|
+
/**
|
|
522
|
+
* Resolve the merged metadata for the current response, combining any metadata
|
|
523
|
+
* defined in hooks with additional metadata added via with() or withMeta().
|
|
524
|
+
*
|
|
525
|
+
* @param withMethod
|
|
526
|
+
* @returns
|
|
527
|
+
*/
|
|
450
528
|
protected resolveMergedMeta(withMethod: (meta?: any) => any): Record<string, any> | undefined;
|
|
529
|
+
/**
|
|
530
|
+
* Run the response generation process, ensuring that the response is properly structured.
|
|
531
|
+
*
|
|
532
|
+
* @param input
|
|
533
|
+
* @returns
|
|
534
|
+
*/
|
|
451
535
|
protected runResponse<TBody, TRawResponse, TServerResponse>(input: {
|
|
452
536
|
ensureJson: () => void;
|
|
453
537
|
rawResponse: TRawResponse;
|
|
@@ -455,6 +539,13 @@ declare abstract class BaseSerializer<TResource = any> {
|
|
|
455
539
|
createServerResponse: (raw: TRawResponse, body: TBody) => TServerResponse;
|
|
456
540
|
callWithResponse: (response: TServerResponse, raw: TRawResponse) => void;
|
|
457
541
|
}): TServerResponse;
|
|
542
|
+
/**
|
|
543
|
+
* Run the thenable process for the resource, allowing for async handling and
|
|
544
|
+
* response generation.
|
|
545
|
+
*
|
|
546
|
+
* @param input
|
|
547
|
+
* @returns
|
|
548
|
+
*/
|
|
458
549
|
protected runThen<TBody, TRawResponse, TServerResponse, TResult1, TResult2>(input: {
|
|
459
550
|
ensureJson: () => void;
|
|
460
551
|
body: () => TBody;
|
|
@@ -465,8 +556,24 @@ declare abstract class BaseSerializer<TResource = any> {
|
|
|
465
556
|
onfulfilled?: ((value: TBody) => TResult1 | PromiseLike<TResult1>) | null;
|
|
466
557
|
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null;
|
|
467
558
|
}): Promise<TResult1 | TResult2>;
|
|
559
|
+
/**
|
|
560
|
+
* Get or set the resource-level configuration for this serializer instance.
|
|
561
|
+
*/
|
|
468
562
|
config(): ResourceLevelConfig;
|
|
563
|
+
/**
|
|
564
|
+
* Set the resource-level configuration for this serializer instance.
|
|
565
|
+
*
|
|
566
|
+
* @param config The configuration object to set for this serializer instance.
|
|
567
|
+
*/
|
|
469
568
|
config(config: ResourceLevelConfig): this;
|
|
569
|
+
/**
|
|
570
|
+
* Resolve the effective serializer configuration for this instance, combining
|
|
571
|
+
* class-level and instance-level configurations.
|
|
572
|
+
*
|
|
573
|
+
* @param localConstructor
|
|
574
|
+
* @param _fallbackConfig
|
|
575
|
+
* @returns
|
|
576
|
+
*/
|
|
470
577
|
protected resolveSerializerConfig(localConstructor: SerializerConstructor, _fallbackConfig?: ResourceLevelConfig): {
|
|
471
578
|
preferredCase: CaseStyle | undefined;
|
|
472
579
|
responseStructure: {
|
|
@@ -475,7 +582,22 @@ declare abstract class BaseSerializer<TResource = any> {
|
|
|
475
582
|
factory?: ResponseFactory | undefined;
|
|
476
583
|
};
|
|
477
584
|
};
|
|
585
|
+
/**
|
|
586
|
+
* Resolve the preferred case style for this serializer instance, considering
|
|
587
|
+
* instance-level configuration, class-level configuration, and global defaults.
|
|
588
|
+
*
|
|
589
|
+
* @param localConstructor The constructor of the serializer class.
|
|
590
|
+
* @param fallbackConfig The fallback configuration to use if no other configuration is found.
|
|
591
|
+
* @returns The resolved case style for this serializer instance.
|
|
592
|
+
*/
|
|
478
593
|
protected resolveSerializerCaseStyle(localConstructor: SerializerConstructor, fallbackConfig?: ResourceLevelConfig): CaseStyle | undefined;
|
|
594
|
+
/**
|
|
595
|
+
* Resolve the response structure configuration for this serializer instance, considering
|
|
596
|
+
*
|
|
597
|
+
* @param localConstructor
|
|
598
|
+
* @param fallbackConfig
|
|
599
|
+
* @returns
|
|
600
|
+
*/
|
|
479
601
|
protected resolveSerializerResponseStructure(localConstructor: SerializerConstructor, fallbackConfig?: ResourceLevelConfig): {
|
|
480
602
|
wrap: boolean;
|
|
481
603
|
rootKey: string;
|
|
@@ -485,7 +607,12 @@ declare abstract class BaseSerializer<TResource = any> {
|
|
|
485
607
|
//#endregion
|
|
486
608
|
//#region src/ResourceCollection.d.ts
|
|
487
609
|
/**
|
|
488
|
-
* ResourceCollection class to handle API resource transformation and response building
|
|
610
|
+
* ResourceCollection class to handle API resource transformation and response building
|
|
611
|
+
* for collections
|
|
612
|
+
*
|
|
613
|
+
* @author Legacy (3m1n3nc3)
|
|
614
|
+
* @since 0.1.0
|
|
615
|
+
* @see BaseSerializer for shared serialization logic and configuration handling
|
|
489
616
|
*/
|
|
490
617
|
declare class ResourceCollection<R extends ResourceData[] | Collectible | CollectionLike | PaginatorLike = ResourceData[] | Collectible | CollectionLike | PaginatorLike, T extends ResourceData = any> extends BaseSerializer<R> {
|
|
491
618
|
private res?;
|
|
@@ -497,7 +624,13 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
|
|
|
497
624
|
response: ServerResponse<CollectionBody<R>>;
|
|
498
625
|
raw: Response | H3Event['res'];
|
|
499
626
|
};
|
|
500
|
-
|
|
627
|
+
/**
|
|
628
|
+
* Type guard to determine if the provided value is a Collectible with pagination information.
|
|
629
|
+
*
|
|
630
|
+
* @param value The value to check.
|
|
631
|
+
* @returns True if the value is a Collectible with pagination information, false otherwise.
|
|
632
|
+
*/
|
|
633
|
+
isPaginatedCollectible(value: unknown): value is Collectible;
|
|
501
634
|
constructor(rsc: R);
|
|
502
635
|
constructor(rsc: R, res: Response);
|
|
503
636
|
/**
|
|
@@ -514,9 +647,33 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
|
|
|
514
647
|
protected setBody(body: CollectionBody<R>): this;
|
|
515
648
|
private resolveCollectsConfig;
|
|
516
649
|
private resolveResponseStructure;
|
|
650
|
+
/**
|
|
651
|
+
* Resolve the current root key for the response structure, based on configuration and defaults.
|
|
652
|
+
*
|
|
653
|
+
* @returns
|
|
654
|
+
*/
|
|
517
655
|
protected resolveCurrentRootKey(): string;
|
|
656
|
+
/**
|
|
657
|
+
* Apply metadata properties to the response body, ensuring they are merged with
|
|
658
|
+
* any existing properties and respecting the configured root key.
|
|
659
|
+
*
|
|
660
|
+
* @param meta
|
|
661
|
+
* @param rootKey
|
|
662
|
+
*/
|
|
518
663
|
protected applyMetaToBody(meta: MetaData, rootKey: string): void;
|
|
664
|
+
/**
|
|
665
|
+
* Get the resource data to be used for generating metadata, allowing for
|
|
666
|
+
* customization in subclasses.
|
|
667
|
+
*
|
|
668
|
+
* @returns
|
|
669
|
+
*/
|
|
519
670
|
protected getResourceForMeta(): R;
|
|
671
|
+
/**
|
|
672
|
+
* Get the appropriate key for the response payload based on the current response
|
|
673
|
+
* structure configuration.
|
|
674
|
+
*
|
|
675
|
+
* @returns The key to use for the response payload, or undefined if no key is needed.
|
|
676
|
+
*/
|
|
520
677
|
private getPayloadKey;
|
|
521
678
|
/**
|
|
522
679
|
* Convert resource to JSON response format
|
|
@@ -525,10 +682,18 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
|
|
|
525
682
|
*/
|
|
526
683
|
json(): this;
|
|
527
684
|
/**
|
|
528
|
-
*
|
|
685
|
+
* Convert resource to object format and return original data.
|
|
529
686
|
*
|
|
530
687
|
* @returns
|
|
531
688
|
*/
|
|
689
|
+
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)[];
|
|
690
|
+
/**
|
|
691
|
+
* Convert resource to object format and return original data.
|
|
692
|
+
*
|
|
693
|
+
* @deprecated Use toObject() instead.
|
|
694
|
+
* @alias toArray
|
|
695
|
+
* @since 0.2.9
|
|
696
|
+
*/
|
|
532
697
|
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
698
|
/**
|
|
534
699
|
* Add additional properties to the response body
|
|
@@ -573,6 +738,11 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
|
|
|
573
738
|
//#region src/Resource.d.ts
|
|
574
739
|
/**
|
|
575
740
|
* Resource class to handle API resource transformation and response building
|
|
741
|
+
*
|
|
742
|
+
*
|
|
743
|
+
* @author Legacy (3m1n3nc3)
|
|
744
|
+
* @since 0.1.0
|
|
745
|
+
* @see BaseSerializer for shared serialization logic and configuration handling
|
|
576
746
|
*/
|
|
577
747
|
declare class Resource<R extends ResourceData | NonCollectible = ResourceData> extends BaseSerializer<R> {
|
|
578
748
|
private res?;
|
|
@@ -604,6 +774,11 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
|
|
|
604
774
|
*/
|
|
605
775
|
protected setBody(body: ResourceBody<R>): this;
|
|
606
776
|
private resolveResponseStructure;
|
|
777
|
+
/**
|
|
778
|
+
* Resolve the current root key for the response body based on configuration and defaults.
|
|
779
|
+
*
|
|
780
|
+
* @returns
|
|
781
|
+
*/
|
|
607
782
|
protected resolveCurrentRootKey(): string;
|
|
608
783
|
protected applyMetaToBody(meta: MetaData, rootKey: string): void;
|
|
609
784
|
protected getResourceForMeta(): R;
|
|
@@ -615,10 +790,18 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
|
|
|
615
790
|
*/
|
|
616
791
|
json(): this;
|
|
617
792
|
/**
|
|
618
|
-
*
|
|
793
|
+
* Convert resource to object format (for collections) or return original data for single resources.
|
|
619
794
|
*
|
|
620
795
|
* @returns
|
|
621
796
|
*/
|
|
797
|
+
toObject(): R extends NonCollectible ? R['data'] : R;
|
|
798
|
+
/**
|
|
799
|
+
* Convert resource to object format and return original data.
|
|
800
|
+
*
|
|
801
|
+
* @deprecated Use toObject() instead.
|
|
802
|
+
* @alias toArray
|
|
803
|
+
* @since 0.2.9
|
|
804
|
+
*/
|
|
622
805
|
toArray(): R extends NonCollectible ? R['data'] : R;
|
|
623
806
|
/**
|
|
624
807
|
* Add additional properties to the response body
|
|
@@ -627,7 +810,14 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
|
|
|
627
810
|
* @returns
|
|
628
811
|
*/
|
|
629
812
|
additional<X extends Record<string, any>>(extra: X): this;
|
|
813
|
+
/**
|
|
814
|
+
* Build a response object, optionally accepting a raw response to mutate in withResponse.
|
|
815
|
+
*/
|
|
630
816
|
response(): ServerResponse<ResourceBody<R>>;
|
|
817
|
+
/**
|
|
818
|
+
* Build a response object, optionally accepting a raw response to mutate in withResponse.
|
|
819
|
+
* @param res Optional raw response object (e.g. Express Response or H3Event res)
|
|
820
|
+
*/
|
|
631
821
|
response(res: H3Event['res']): ServerResponse<ResourceBody<R>>;
|
|
632
822
|
/**
|
|
633
823
|
* Customize the outgoing transport response right before dispatch.
|
|
@@ -662,6 +852,10 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
|
|
|
662
852
|
//#region src/GenericResource.d.ts
|
|
663
853
|
/**
|
|
664
854
|
* GenericResource class to handle API resource transformation and response building
|
|
855
|
+
*
|
|
856
|
+
* @author Legacy (3m1n3nc3)
|
|
857
|
+
* @since 0.1.0
|
|
858
|
+
* @see BaseSerializer for shared serialization logic and configuration handling
|
|
665
859
|
*/
|
|
666
860
|
declare class GenericResource<R extends NonCollectible | Collectible | CollectionLike | PaginatorLike | ResourceData = ResourceData, T extends ResourceData = any> extends BaseSerializer<R> {
|
|
667
861
|
private res?;
|
|
@@ -688,8 +882,24 @@ declare class GenericResource<R extends NonCollectible | Collectible | Collectio
|
|
|
688
882
|
protected setBody(body: GenericBody<R>): this;
|
|
689
883
|
private resolveCollectsConfig;
|
|
690
884
|
private resolveResponseStructure;
|
|
885
|
+
/**
|
|
886
|
+
* Resolve the current root key for the response structure, based on configuration and defaults.
|
|
887
|
+
*
|
|
888
|
+
* @returns
|
|
889
|
+
*/
|
|
691
890
|
protected resolveCurrentRootKey(): string;
|
|
891
|
+
/**
|
|
892
|
+
* Apply metadata properties to the response body, ensuring they are merged with.
|
|
893
|
+
*
|
|
894
|
+
* @param meta
|
|
895
|
+
* @param rootKey
|
|
896
|
+
*/
|
|
692
897
|
protected applyMetaToBody(meta: MetaData, rootKey: string): void;
|
|
898
|
+
/**
|
|
899
|
+
* Get the resource data to be used for generating metadata.
|
|
900
|
+
*
|
|
901
|
+
* @returns
|
|
902
|
+
*/
|
|
693
903
|
protected getResourceForMeta(): R;
|
|
694
904
|
private getPayloadKey;
|
|
695
905
|
/**
|
|
@@ -699,10 +909,18 @@ declare class GenericResource<R extends NonCollectible | Collectible | Collectio
|
|
|
699
909
|
*/
|
|
700
910
|
json(): this;
|
|
701
911
|
/**
|
|
702
|
-
* Convert resource to
|
|
912
|
+
* Convert resource to object format (for collections).
|
|
703
913
|
*
|
|
704
914
|
* @returns
|
|
705
915
|
*/
|
|
916
|
+
toObject(): any;
|
|
917
|
+
/**
|
|
918
|
+
* Convert resource to object format and return original data.
|
|
919
|
+
*
|
|
920
|
+
* @deprecated Use toObject() instead.
|
|
921
|
+
* @alias toArray
|
|
922
|
+
* @since 0.2.9
|
|
923
|
+
*/
|
|
706
924
|
toArray(): any;
|
|
707
925
|
/**
|
|
708
926
|
* Add additional properties to the response body
|
|
@@ -711,7 +929,15 @@ declare class GenericResource<R extends NonCollectible | Collectible | Collectio
|
|
|
711
929
|
* @returns
|
|
712
930
|
*/
|
|
713
931
|
additional<X extends Record<string, any>>(extra: X): this;
|
|
932
|
+
/**
|
|
933
|
+
* Build a response object, optionally accepting a raw response to write to directly.
|
|
934
|
+
*/
|
|
714
935
|
response(): ServerResponse<GenericBody<R>>;
|
|
936
|
+
/**
|
|
937
|
+
* Build a response object, writing to the provided raw response if possible.
|
|
938
|
+
*
|
|
939
|
+
* @param res
|
|
940
|
+
*/
|
|
715
941
|
response(res: H3Event['res']): ServerResponse<GenericBody<R>>;
|
|
716
942
|
/**
|
|
717
943
|
* Customize the outgoing transport response right before dispatch.
|
|
@@ -832,6 +1058,11 @@ declare const resolveMergeWhen: <T extends Record<string, any>>(condition: any,
|
|
|
832
1058
|
declare const sanitizeConditionalAttributes: (value: any) => any;
|
|
833
1059
|
//#endregion
|
|
834
1060
|
//#region src/utilities/config.d.ts
|
|
1061
|
+
/**
|
|
1062
|
+
* Get the default configuration for the application
|
|
1063
|
+
*
|
|
1064
|
+
* @returns
|
|
1065
|
+
*/
|
|
835
1066
|
declare const getDefaultConfig: () => Config;
|
|
836
1067
|
/**
|
|
837
1068
|
* 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 +1082,29 @@ type ArkormLikeModel = {
|
|
|
851
1082
|
type ArkormLikeCollection = {
|
|
852
1083
|
all: () => unknown;
|
|
853
1084
|
};
|
|
1085
|
+
/**
|
|
1086
|
+
* Type guard to check if a value is an Arkorm-like model, which is defined as an object
|
|
1087
|
+
* that has a toObject method and optionally getRawAttributes, getAttribute, and
|
|
1088
|
+
* setAttribute methods.
|
|
1089
|
+
*
|
|
1090
|
+
* @param value The value to check
|
|
1091
|
+
* @returns True if the value is an Arkorm-like model, false otherwise
|
|
1092
|
+
*/
|
|
854
1093
|
declare const isArkormLikeModel: (value: unknown) => value is ArkormLikeModel;
|
|
1094
|
+
/**
|
|
1095
|
+
* Type guard to check if a value is an Arkorm-like collection, which is defined as an object
|
|
1096
|
+
*
|
|
1097
|
+
* @param value
|
|
1098
|
+
* @returns
|
|
1099
|
+
*/
|
|
855
1100
|
declare const isArkormLikeCollection: (value: unknown) => value is ArkormLikeCollection;
|
|
1101
|
+
/**
|
|
1102
|
+
* Normalize a value for serialization by recursively converting Arkorm-like models and
|
|
1103
|
+
* collections to plain objects, while preserving the structure of arrays and plain objects.
|
|
1104
|
+
*
|
|
1105
|
+
* @param value The value to normalize
|
|
1106
|
+
* @returns The normalized value, ready for serialization
|
|
1107
|
+
*/
|
|
856
1108
|
declare const normalizeSerializableData: (value: unknown) => unknown;
|
|
857
1109
|
//#endregion
|
|
858
1110
|
//#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,64 @@ declare abstract class BaseSerializer<TResource = any> {
|
|
|
439
474
|
then?: boolean;
|
|
440
475
|
toResponse?: boolean;
|
|
441
476
|
};
|
|
477
|
+
constructor();
|
|
478
|
+
/**
|
|
479
|
+
* Helper method to conditionally resolve a value based on a condition.
|
|
480
|
+
*
|
|
481
|
+
* @param condition
|
|
482
|
+
* @param value
|
|
483
|
+
* @returns
|
|
484
|
+
*/
|
|
442
485
|
when<T>(condition: any, value: T | (() => T)): T | undefined;
|
|
486
|
+
/**
|
|
487
|
+
* Helper method to conditionally resolve a value only if it's not null or undefined.
|
|
488
|
+
*
|
|
489
|
+
* @param value
|
|
490
|
+
* @returns
|
|
491
|
+
*/
|
|
443
492
|
whenNotNull<T>(value: T | null | undefined): T | undefined;
|
|
493
|
+
/**
|
|
494
|
+
* Helper method to conditionally merge values into the response based on a condition.
|
|
495
|
+
*
|
|
496
|
+
* @param condition
|
|
497
|
+
* @param value
|
|
498
|
+
* @returns
|
|
499
|
+
*/
|
|
444
500
|
mergeWhen<T extends Record<string, any>>(condition: any, value: T | (() => T)): Partial<T>;
|
|
501
|
+
/**
|
|
502
|
+
* Resolve the current root key for the response structure.
|
|
503
|
+
*/
|
|
445
504
|
protected abstract resolveCurrentRootKey(): string;
|
|
446
505
|
protected abstract applyMetaToBody(meta: MetaData, rootKey: string): void;
|
|
447
506
|
protected abstract getResourceForMeta(): TResource;
|
|
507
|
+
/**
|
|
508
|
+
* Add additional metadata to the response. If called without arguments.
|
|
509
|
+
*
|
|
510
|
+
* @param meta
|
|
511
|
+
* @returns
|
|
512
|
+
*/
|
|
448
513
|
with(meta?: any): any;
|
|
514
|
+
/**
|
|
515
|
+
* Add additional metadata to the response, ensuring it is merged with any existing metadata.
|
|
516
|
+
*
|
|
517
|
+
* @param meta
|
|
518
|
+
* @returns
|
|
519
|
+
*/
|
|
449
520
|
withMeta<M extends MetaData>(meta: M | ((resource: TResource) => M)): this;
|
|
521
|
+
/**
|
|
522
|
+
* Resolve the merged metadata for the current response, combining any metadata
|
|
523
|
+
* defined in hooks with additional metadata added via with() or withMeta().
|
|
524
|
+
*
|
|
525
|
+
* @param withMethod
|
|
526
|
+
* @returns
|
|
527
|
+
*/
|
|
450
528
|
protected resolveMergedMeta(withMethod: (meta?: any) => any): Record<string, any> | undefined;
|
|
529
|
+
/**
|
|
530
|
+
* Run the response generation process, ensuring that the response is properly structured.
|
|
531
|
+
*
|
|
532
|
+
* @param input
|
|
533
|
+
* @returns
|
|
534
|
+
*/
|
|
451
535
|
protected runResponse<TBody, TRawResponse, TServerResponse>(input: {
|
|
452
536
|
ensureJson: () => void;
|
|
453
537
|
rawResponse: TRawResponse;
|
|
@@ -455,6 +539,13 @@ declare abstract class BaseSerializer<TResource = any> {
|
|
|
455
539
|
createServerResponse: (raw: TRawResponse, body: TBody) => TServerResponse;
|
|
456
540
|
callWithResponse: (response: TServerResponse, raw: TRawResponse) => void;
|
|
457
541
|
}): TServerResponse;
|
|
542
|
+
/**
|
|
543
|
+
* Run the thenable process for the resource, allowing for async handling and
|
|
544
|
+
* response generation.
|
|
545
|
+
*
|
|
546
|
+
* @param input
|
|
547
|
+
* @returns
|
|
548
|
+
*/
|
|
458
549
|
protected runThen<TBody, TRawResponse, TServerResponse, TResult1, TResult2>(input: {
|
|
459
550
|
ensureJson: () => void;
|
|
460
551
|
body: () => TBody;
|
|
@@ -465,8 +556,24 @@ declare abstract class BaseSerializer<TResource = any> {
|
|
|
465
556
|
onfulfilled?: ((value: TBody) => TResult1 | PromiseLike<TResult1>) | null;
|
|
466
557
|
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null;
|
|
467
558
|
}): Promise<TResult1 | TResult2>;
|
|
559
|
+
/**
|
|
560
|
+
* Get or set the resource-level configuration for this serializer instance.
|
|
561
|
+
*/
|
|
468
562
|
config(): ResourceLevelConfig;
|
|
563
|
+
/**
|
|
564
|
+
* Set the resource-level configuration for this serializer instance.
|
|
565
|
+
*
|
|
566
|
+
* @param config The configuration object to set for this serializer instance.
|
|
567
|
+
*/
|
|
469
568
|
config(config: ResourceLevelConfig): this;
|
|
569
|
+
/**
|
|
570
|
+
* Resolve the effective serializer configuration for this instance, combining
|
|
571
|
+
* class-level and instance-level configurations.
|
|
572
|
+
*
|
|
573
|
+
* @param localConstructor
|
|
574
|
+
* @param _fallbackConfig
|
|
575
|
+
* @returns
|
|
576
|
+
*/
|
|
470
577
|
protected resolveSerializerConfig(localConstructor: SerializerConstructor, _fallbackConfig?: ResourceLevelConfig): {
|
|
471
578
|
preferredCase: CaseStyle | undefined;
|
|
472
579
|
responseStructure: {
|
|
@@ -475,7 +582,22 @@ declare abstract class BaseSerializer<TResource = any> {
|
|
|
475
582
|
factory?: ResponseFactory | undefined;
|
|
476
583
|
};
|
|
477
584
|
};
|
|
585
|
+
/**
|
|
586
|
+
* Resolve the preferred case style for this serializer instance, considering
|
|
587
|
+
* instance-level configuration, class-level configuration, and global defaults.
|
|
588
|
+
*
|
|
589
|
+
* @param localConstructor The constructor of the serializer class.
|
|
590
|
+
* @param fallbackConfig The fallback configuration to use if no other configuration is found.
|
|
591
|
+
* @returns The resolved case style for this serializer instance.
|
|
592
|
+
*/
|
|
478
593
|
protected resolveSerializerCaseStyle(localConstructor: SerializerConstructor, fallbackConfig?: ResourceLevelConfig): CaseStyle | undefined;
|
|
594
|
+
/**
|
|
595
|
+
* Resolve the response structure configuration for this serializer instance, considering
|
|
596
|
+
*
|
|
597
|
+
* @param localConstructor
|
|
598
|
+
* @param fallbackConfig
|
|
599
|
+
* @returns
|
|
600
|
+
*/
|
|
479
601
|
protected resolveSerializerResponseStructure(localConstructor: SerializerConstructor, fallbackConfig?: ResourceLevelConfig): {
|
|
480
602
|
wrap: boolean;
|
|
481
603
|
rootKey: string;
|
|
@@ -485,7 +607,12 @@ declare abstract class BaseSerializer<TResource = any> {
|
|
|
485
607
|
//#endregion
|
|
486
608
|
//#region src/ResourceCollection.d.ts
|
|
487
609
|
/**
|
|
488
|
-
* ResourceCollection class to handle API resource transformation and response building
|
|
610
|
+
* ResourceCollection class to handle API resource transformation and response building
|
|
611
|
+
* for collections
|
|
612
|
+
*
|
|
613
|
+
* @author Legacy (3m1n3nc3)
|
|
614
|
+
* @since 0.1.0
|
|
615
|
+
* @see BaseSerializer for shared serialization logic and configuration handling
|
|
489
616
|
*/
|
|
490
617
|
declare class ResourceCollection<R extends ResourceData[] | Collectible | CollectionLike | PaginatorLike = ResourceData[] | Collectible | CollectionLike | PaginatorLike, T extends ResourceData = any> extends BaseSerializer<R> {
|
|
491
618
|
private res?;
|
|
@@ -497,7 +624,13 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
|
|
|
497
624
|
response: ServerResponse<CollectionBody<R>>;
|
|
498
625
|
raw: Response | H3Event['res'];
|
|
499
626
|
};
|
|
500
|
-
|
|
627
|
+
/**
|
|
628
|
+
* Type guard to determine if the provided value is a Collectible with pagination information.
|
|
629
|
+
*
|
|
630
|
+
* @param value The value to check.
|
|
631
|
+
* @returns True if the value is a Collectible with pagination information, false otherwise.
|
|
632
|
+
*/
|
|
633
|
+
isPaginatedCollectible(value: unknown): value is Collectible;
|
|
501
634
|
constructor(rsc: R);
|
|
502
635
|
constructor(rsc: R, res: Response);
|
|
503
636
|
/**
|
|
@@ -514,9 +647,33 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
|
|
|
514
647
|
protected setBody(body: CollectionBody<R>): this;
|
|
515
648
|
private resolveCollectsConfig;
|
|
516
649
|
private resolveResponseStructure;
|
|
650
|
+
/**
|
|
651
|
+
* Resolve the current root key for the response structure, based on configuration and defaults.
|
|
652
|
+
*
|
|
653
|
+
* @returns
|
|
654
|
+
*/
|
|
517
655
|
protected resolveCurrentRootKey(): string;
|
|
656
|
+
/**
|
|
657
|
+
* Apply metadata properties to the response body, ensuring they are merged with
|
|
658
|
+
* any existing properties and respecting the configured root key.
|
|
659
|
+
*
|
|
660
|
+
* @param meta
|
|
661
|
+
* @param rootKey
|
|
662
|
+
*/
|
|
518
663
|
protected applyMetaToBody(meta: MetaData, rootKey: string): void;
|
|
664
|
+
/**
|
|
665
|
+
* Get the resource data to be used for generating metadata, allowing for
|
|
666
|
+
* customization in subclasses.
|
|
667
|
+
*
|
|
668
|
+
* @returns
|
|
669
|
+
*/
|
|
519
670
|
protected getResourceForMeta(): R;
|
|
671
|
+
/**
|
|
672
|
+
* Get the appropriate key for the response payload based on the current response
|
|
673
|
+
* structure configuration.
|
|
674
|
+
*
|
|
675
|
+
* @returns The key to use for the response payload, or undefined if no key is needed.
|
|
676
|
+
*/
|
|
520
677
|
private getPayloadKey;
|
|
521
678
|
/**
|
|
522
679
|
* Convert resource to JSON response format
|
|
@@ -525,10 +682,18 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
|
|
|
525
682
|
*/
|
|
526
683
|
json(): this;
|
|
527
684
|
/**
|
|
528
|
-
*
|
|
685
|
+
* Convert resource to object format and return original data.
|
|
529
686
|
*
|
|
530
687
|
* @returns
|
|
531
688
|
*/
|
|
689
|
+
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)[];
|
|
690
|
+
/**
|
|
691
|
+
* Convert resource to object format and return original data.
|
|
692
|
+
*
|
|
693
|
+
* @deprecated Use toObject() instead.
|
|
694
|
+
* @alias toArray
|
|
695
|
+
* @since 0.2.9
|
|
696
|
+
*/
|
|
532
697
|
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
698
|
/**
|
|
534
699
|
* Add additional properties to the response body
|
|
@@ -573,6 +738,11 @@ declare class ResourceCollection<R extends ResourceData[] | Collectible | Collec
|
|
|
573
738
|
//#region src/Resource.d.ts
|
|
574
739
|
/**
|
|
575
740
|
* Resource class to handle API resource transformation and response building
|
|
741
|
+
*
|
|
742
|
+
*
|
|
743
|
+
* @author Legacy (3m1n3nc3)
|
|
744
|
+
* @since 0.1.0
|
|
745
|
+
* @see BaseSerializer for shared serialization logic and configuration handling
|
|
576
746
|
*/
|
|
577
747
|
declare class Resource<R extends ResourceData | NonCollectible = ResourceData> extends BaseSerializer<R> {
|
|
578
748
|
private res?;
|
|
@@ -604,6 +774,11 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
|
|
|
604
774
|
*/
|
|
605
775
|
protected setBody(body: ResourceBody<R>): this;
|
|
606
776
|
private resolveResponseStructure;
|
|
777
|
+
/**
|
|
778
|
+
* Resolve the current root key for the response body based on configuration and defaults.
|
|
779
|
+
*
|
|
780
|
+
* @returns
|
|
781
|
+
*/
|
|
607
782
|
protected resolveCurrentRootKey(): string;
|
|
608
783
|
protected applyMetaToBody(meta: MetaData, rootKey: string): void;
|
|
609
784
|
protected getResourceForMeta(): R;
|
|
@@ -615,10 +790,18 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
|
|
|
615
790
|
*/
|
|
616
791
|
json(): this;
|
|
617
792
|
/**
|
|
618
|
-
*
|
|
793
|
+
* Convert resource to object format (for collections) or return original data for single resources.
|
|
619
794
|
*
|
|
620
795
|
* @returns
|
|
621
796
|
*/
|
|
797
|
+
toObject(): R extends NonCollectible ? R['data'] : R;
|
|
798
|
+
/**
|
|
799
|
+
* Convert resource to object format and return original data.
|
|
800
|
+
*
|
|
801
|
+
* @deprecated Use toObject() instead.
|
|
802
|
+
* @alias toArray
|
|
803
|
+
* @since 0.2.9
|
|
804
|
+
*/
|
|
622
805
|
toArray(): R extends NonCollectible ? R['data'] : R;
|
|
623
806
|
/**
|
|
624
807
|
* Add additional properties to the response body
|
|
@@ -627,7 +810,14 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
|
|
|
627
810
|
* @returns
|
|
628
811
|
*/
|
|
629
812
|
additional<X extends Record<string, any>>(extra: X): this;
|
|
813
|
+
/**
|
|
814
|
+
* Build a response object, optionally accepting a raw response to mutate in withResponse.
|
|
815
|
+
*/
|
|
630
816
|
response(): ServerResponse<ResourceBody<R>>;
|
|
817
|
+
/**
|
|
818
|
+
* Build a response object, optionally accepting a raw response to mutate in withResponse.
|
|
819
|
+
* @param res Optional raw response object (e.g. Express Response or H3Event res)
|
|
820
|
+
*/
|
|
631
821
|
response(res: H3Event['res']): ServerResponse<ResourceBody<R>>;
|
|
632
822
|
/**
|
|
633
823
|
* Customize the outgoing transport response right before dispatch.
|
|
@@ -662,6 +852,10 @@ declare class Resource<R extends ResourceData | NonCollectible = ResourceData> e
|
|
|
662
852
|
//#region src/GenericResource.d.ts
|
|
663
853
|
/**
|
|
664
854
|
* GenericResource class to handle API resource transformation and response building
|
|
855
|
+
*
|
|
856
|
+
* @author Legacy (3m1n3nc3)
|
|
857
|
+
* @since 0.1.0
|
|
858
|
+
* @see BaseSerializer for shared serialization logic and configuration handling
|
|
665
859
|
*/
|
|
666
860
|
declare class GenericResource<R extends NonCollectible | Collectible | CollectionLike | PaginatorLike | ResourceData = ResourceData, T extends ResourceData = any> extends BaseSerializer<R> {
|
|
667
861
|
private res?;
|
|
@@ -688,8 +882,24 @@ declare class GenericResource<R extends NonCollectible | Collectible | Collectio
|
|
|
688
882
|
protected setBody(body: GenericBody<R>): this;
|
|
689
883
|
private resolveCollectsConfig;
|
|
690
884
|
private resolveResponseStructure;
|
|
885
|
+
/**
|
|
886
|
+
* Resolve the current root key for the response structure, based on configuration and defaults.
|
|
887
|
+
*
|
|
888
|
+
* @returns
|
|
889
|
+
*/
|
|
691
890
|
protected resolveCurrentRootKey(): string;
|
|
891
|
+
/**
|
|
892
|
+
* Apply metadata properties to the response body, ensuring they are merged with.
|
|
893
|
+
*
|
|
894
|
+
* @param meta
|
|
895
|
+
* @param rootKey
|
|
896
|
+
*/
|
|
692
897
|
protected applyMetaToBody(meta: MetaData, rootKey: string): void;
|
|
898
|
+
/**
|
|
899
|
+
* Get the resource data to be used for generating metadata.
|
|
900
|
+
*
|
|
901
|
+
* @returns
|
|
902
|
+
*/
|
|
693
903
|
protected getResourceForMeta(): R;
|
|
694
904
|
private getPayloadKey;
|
|
695
905
|
/**
|
|
@@ -699,10 +909,18 @@ declare class GenericResource<R extends NonCollectible | Collectible | Collectio
|
|
|
699
909
|
*/
|
|
700
910
|
json(): this;
|
|
701
911
|
/**
|
|
702
|
-
* Convert resource to
|
|
912
|
+
* Convert resource to object format (for collections).
|
|
703
913
|
*
|
|
704
914
|
* @returns
|
|
705
915
|
*/
|
|
916
|
+
toObject(): any;
|
|
917
|
+
/**
|
|
918
|
+
* Convert resource to object format and return original data.
|
|
919
|
+
*
|
|
920
|
+
* @deprecated Use toObject() instead.
|
|
921
|
+
* @alias toArray
|
|
922
|
+
* @since 0.2.9
|
|
923
|
+
*/
|
|
706
924
|
toArray(): any;
|
|
707
925
|
/**
|
|
708
926
|
* Add additional properties to the response body
|
|
@@ -711,7 +929,15 @@ declare class GenericResource<R extends NonCollectible | Collectible | Collectio
|
|
|
711
929
|
* @returns
|
|
712
930
|
*/
|
|
713
931
|
additional<X extends Record<string, any>>(extra: X): this;
|
|
932
|
+
/**
|
|
933
|
+
* Build a response object, optionally accepting a raw response to write to directly.
|
|
934
|
+
*/
|
|
714
935
|
response(): ServerResponse<GenericBody<R>>;
|
|
936
|
+
/**
|
|
937
|
+
* Build a response object, writing to the provided raw response if possible.
|
|
938
|
+
*
|
|
939
|
+
* @param res
|
|
940
|
+
*/
|
|
715
941
|
response(res: H3Event['res']): ServerResponse<GenericBody<R>>;
|
|
716
942
|
/**
|
|
717
943
|
* Customize the outgoing transport response right before dispatch.
|
|
@@ -832,6 +1058,11 @@ declare const resolveMergeWhen: <T extends Record<string, any>>(condition: any,
|
|
|
832
1058
|
declare const sanitizeConditionalAttributes: (value: any) => any;
|
|
833
1059
|
//#endregion
|
|
834
1060
|
//#region src/utilities/config.d.ts
|
|
1061
|
+
/**
|
|
1062
|
+
* Get the default configuration for the application
|
|
1063
|
+
*
|
|
1064
|
+
* @returns
|
|
1065
|
+
*/
|
|
835
1066
|
declare const getDefaultConfig: () => Config;
|
|
836
1067
|
/**
|
|
837
1068
|
* 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 +1082,29 @@ type ArkormLikeModel = {
|
|
|
851
1082
|
type ArkormLikeCollection = {
|
|
852
1083
|
all: () => unknown;
|
|
853
1084
|
};
|
|
1085
|
+
/**
|
|
1086
|
+
* Type guard to check if a value is an Arkorm-like model, which is defined as an object
|
|
1087
|
+
* that has a toObject method and optionally getRawAttributes, getAttribute, and
|
|
1088
|
+
* setAttribute methods.
|
|
1089
|
+
*
|
|
1090
|
+
* @param value The value to check
|
|
1091
|
+
* @returns True if the value is an Arkorm-like model, false otherwise
|
|
1092
|
+
*/
|
|
854
1093
|
declare const isArkormLikeModel: (value: unknown) => value is ArkormLikeModel;
|
|
1094
|
+
/**
|
|
1095
|
+
* Type guard to check if a value is an Arkorm-like collection, which is defined as an object
|
|
1096
|
+
*
|
|
1097
|
+
* @param value
|
|
1098
|
+
* @returns
|
|
1099
|
+
*/
|
|
855
1100
|
declare const isArkormLikeCollection: (value: unknown) => value is ArkormLikeCollection;
|
|
1101
|
+
/**
|
|
1102
|
+
* Normalize a value for serialization by recursively converting Arkorm-like models and
|
|
1103
|
+
* collections to plain objects, while preserving the structure of arrays and plain objects.
|
|
1104
|
+
*
|
|
1105
|
+
* @param value The value to normalize
|
|
1106
|
+
* @returns The normalized value, ready for serialization
|
|
1107
|
+
*/
|
|
856
1108
|
declare const normalizeSerializableData: (value: unknown) => unknown;
|
|
857
1109
|
//#endregion
|
|
858
1110
|
//#region src/utilities/metadata.d.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{copyFileSync as e,existsSync as t,mkdirSync as n,readFileSync as r,rmSync as i,writeFileSync as a}from"fs";import o,{dirname as s,join as c}from"path";import{createRequire as l}from"module";import{pathToFileURL as u}from"url";import{Command as d}from"@h3ravel/musket";function f(e){return e}let p,m,h=[`meta`,`links`],g={first:`first`,last:`last`,prev:`prev`,next:`next`},_=`https://localhost`,ee=`page`,v={to:`to`,from:`from`,links:`links`,path:`path`,total:`total`,per_page:`per_page`,last_page:`last_page`,current_page:`current_page`},y={previous:`previous`,next:`next`};const b=e=>{p=e},x=()=>p,S=e=>{m=e},C=()=>m,te=e=>{m={...m||{},rootKey:e}},ne=e=>{m={...m||{},wrap:e}},re=()=>m?.wrap,ie=()=>m?.rootKey,ae=e=>{m={...m||{},factory:e}},oe=()=>m?.factory,se=e=>{h=e},ce=()=>h,le=e=>{g={...g,...e}},ue=()=>g,de=e=>{_=e},fe=()=>_,pe=e=>{ee=e},me=()=>ee,w=e=>{v=
|
|
1
|
+
import{copyFileSync as e,existsSync as t,mkdirSync as n,readFileSync as r,rmSync as i,writeFileSync as a}from"fs";import o,{dirname as s,join as c}from"path";import{createRequire as l}from"module";import{pathToFileURL as u}from"url";import{Command as d}from"@h3ravel/musket";function f(e){return e}let p,m,h=[`meta`,`links`],g={first:`first`,last:`last`,prev:`prev`,next:`next`},_=`https://localhost`,ee=`page`,v={to:`to`,from:`from`,links:`links`,path:`path`,total:`total`,per_page:`per_page`,last_page:`last_page`,current_page:`current_page`},y={previous:`previous`,next:`next`};const b=e=>{p=e},x=()=>p,S=e=>{m=e},C=()=>m,te=e=>{m={...m||{},rootKey:e}},ne=e=>{m={...m||{},wrap:e}},re=()=>m?.wrap,ie=()=>m?.rootKey,ae=e=>{m={...m||{},factory:e}},oe=()=>m?.factory,se=e=>{h=e},ce=()=>h,le=e=>{g={...g,...e}},ue=()=>g,de=e=>{_=e},fe=()=>_,pe=e=>{ee=e},me=()=>ee,w=e=>{v=e},T=()=>v,E=e=>{y={...y,...e}},D=()=>y,O=e=>{if(typeof e!=`object`||!e||Array.isArray(e)||e instanceof Date||e instanceof RegExp)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},k=(e,t,n=`data`)=>!t||Object.keys(t).length===0?e:Array.isArray(e)?{[n]:e,...t}:O(e)?{...e,...t}:{[n]:e,...t},A=(e,t)=>{if(!t)return e;if(!e)return t;let n={...e};for(let[e,r]of Object.entries(t)){let t=n[e];O(t)&&O(r)?n[e]=A(t,r):n[e]=r}return n},j=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.toObject==`function`&&typeof t.getRawAttributes==`function`},M=e=>!e||typeof e!=`object`?!1:typeof e.all==`function`,N=e=>{if(Array.isArray(e))return e.map(e=>N(e));if(j(e))return N(e.toObject());if(M(e)){let t=e.all();return Array.isArray(t)?t.map(e=>N(e)):N(t)}return O(e)?Object.entries(e).reduce((e,[t,n])=>(e[t]=N(n),e),{}):e},P=()=>{let e=ce();return Array.isArray(e)?{metaKey:e.includes(`meta`)?`meta`:void 0,linksKey:e.includes(`links`)?`links`:void 0,cursorKey:e.includes(`cursor`)?`cursor`:void 0}:{metaKey:e.meta,linksKey:e.links,cursorKey:e.cursor}},F=(e,t)=>{if(e===void 0)return;let n=t||``,r=fe()||``,i=/^https?:\/\//i.test(n),a=r.replace(/\/$/,``),o=n.replace(/^\//,``),s=i?n:a?o?`${a}/${o}`:a:``;if(!s)return;let c=new URL(s);return c.searchParams.set(me()||`page`,String(e)),c.toString()},I=e=>{let{metaKey:t,linksKey:n,cursorKey:r}=P(),i={},a=!!e&&typeof e==`object`&&!!e.meta&&typeof e.meta==`object`&&(Array.isArray(e.data)||M(e.data)),o=a?{first:typeof e.firstPageUrl==`function`?e.firstPageUrl():void 0,last:typeof e.lastPageUrl==`function`?e.lastPageUrl():void 0,prev:typeof e.previousPageUrl==`function`?e.previousPageUrl():void 0,next:typeof e.nextPageUrl==`function`?e.nextPageUrl():void 0}:void 0,s=o?Object.entries(o).reduce((e,[t,n])=>(n!==void 0&&(e[t]=n),e),{}):void 0,c=e?.pagination||(a?{...e.meta,links:e.links||s}:void 0),l=e?.cursor,u={},d={};if(c){let e={to:c.to,from:c.from,links:c.links,path:c.path,total:c.total,per_page:c.perPage,last_page:c.lastPage,current_page:c.currentPage};for(let[t,n]of Object.entries(T())){if(!n)continue;let r=e[t];r!==void 0&&(u[n]=r)}let t={first:c.links&&Object.prototype.hasOwnProperty.call(c.links,`first`)?c.links.first:F(c.firstPage,c.path),last:c.links&&Object.prototype.hasOwnProperty.call(c.links,`last`)?c.links.last:F(c.lastPage,c.path),prev:c.links&&Object.prototype.hasOwnProperty.call(c.links,`prev`)?c.links.prev:F(c.prevPage,c.path),next:c.links&&Object.prototype.hasOwnProperty.call(c.links,`next`)?c.links.next:F(c.nextPage,c.path)};for(let[e,n]of Object.entries(ue())){if(!n)continue;let r=t[e];r!==void 0&&(d[n]=r)}}if(l){let e={},t={previous:l.previous,next:l.next};for(let[n,r]of Object.entries(D())){if(!r)continue;let i=t[n];i!==void 0&&(e[r]=i)}r&&Object.keys(e).length>0?i[r]=e:Object.keys(e).length>0&&(u.cursor=e)}return t&&Object.keys(u).length>0&&(i[t]=u),n&&Object.keys(d).length>0&&(i[n]=d),i},L=({payload:e,meta:t,metaKey:n=`meta`,wrap:r=!0,rootKey:i=`data`,factory:a,context:o})=>{if(a)return a(e,{...o,rootKey:i,meta:t});if(!r)return t===void 0?e:O(e)?{...e,[n]:t}:{[i]:e,[n]:t};let s={[i]:e};return t!==void 0&&(s[n]=t),s},R=(e,t)=>{let n=e?.with;if(typeof n!=`function`||n===t||n.length>0)return;let r=n.call(e);return O(r)?r:void 0},z=Symbol(`resora.conditional.missing`),B=(e,t)=>e?typeof t==`function`?t():t:z,V=e=>e??z,H=(e,t)=>{if(!e)return{};let n=typeof t==`function`?t():t;return O(n)?n:{}},U=e=>{if(e===z)return z;if(Array.isArray(e))return e.map(e=>U(e)).filter(e=>e!==z);if(O(e)){let t={};for(let[n,r]of Object.entries(e)){let e=U(r);e!==z&&(t[n]=e)}return t}return e},W=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1 $2`).replace(/([A-Z]+)([A-Z][a-z])/g,`$1 $2`).replace(/[-_\s]+/g,` `).trim().toLowerCase().split(` `).filter(Boolean),he=e=>W(e).map((e,t)=>t===0?e:e.charAt(0).toUpperCase()+e.slice(1)).join(``),ge=e=>W(e).join(`_`),_e=e=>W(e).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``),ve=e=>W(e).join(`-`),G=e=>{if(typeof e==`function`)return e;switch(e){case`camel`:return he;case`snake`:return ge;case`pascal`:return _e;case`kebab`:return ve}},K=(e,t)=>e==null?e:Array.isArray(e)?e.map(e=>K(e,t)):e instanceof Date||e instanceof RegExp?e:typeof e==`object`?Object.fromEntries(Object.entries(e).map(([e,n])=>[t(e),K(n,t)])):e;let q=o.resolve(process.cwd(),`node_modules/resora/stubs`);t(q)||(q=o.resolve(process.cwd(),`stubs`));const ye=()=>({stubsDir:q,preferredCase:`camel`,responseStructure:{wrap:!0,rootKey:`data`},paginatedExtras:[`meta`,`links`],baseUrl:`https://localhost`,pageName:`page`,paginatedLinks:{first:`first`,last:`last`,prev:`prev`,next:`next`},paginatedMeta:{to:`to`,from:`from`,links:`links`,path:`path`,total:`total`,per_page:`per_page`,last_page:`last_page`,current_page:`current_page`},cursorMeta:{previous:`previous`,next:`next`},resourcesDir:`src/resources`,stubs:{config:`resora.config.stub`,resource:`resource.stub`,collection:`resource.collection.stub`}}),J=e=>{let t=ye();return Object.assign(t,e,{stubs:Object.assign(t.stubs,e.stubs||{})},{cursorMeta:Object.assign(t.cursorMeta,e.cursorMeta||{})},{paginatedMeta:e.paginatedMeta||t.paginatedMeta},{paginatedLinks:Object.assign(t.paginatedLinks,e.paginatedLinks||{})},{responseStructure:Object.assign(t.responseStructure,e.responseStructure||{})})};let Y=!1,X;const be=()=>{Y=!1,X=void 0},xe=e=>{e.preferredCase!==`camel`&&b(e.preferredCase),S(e.responseStructure),se(e.paginatedExtras),le(e.paginatedLinks),w(e.paginatedMeta),E(e.cursorMeta),de(e.baseUrl),pe(e.pageName)},Se=async e=>await import(`${u(e).href}?resora_runtime=${Date.now()}`),Ce=e=>{xe(J((e?.default??e)||{})),Y=!0},we=()=>{let e=l(import.meta.url),n=[o.join(process.cwd(),`resora.config.cjs`)];for(let r of n)if(t(r))try{return Ce(e(r)),!0}catch{continue}return!1},Z=async()=>{if(!Y){if(X)return await X;we()||(X=(async()=>{let e=[o.join(process.cwd(),`resora.config.js`),o.join(process.cwd(),`resora.config.ts`)];for(let n of e)if(t(n))try{Ce(await Se(n));return}catch{continue}Y=!0})(),await X)}};Z();var Te=class{command;config={};constructor(e={}){this.config=J(e)}async loadConfig(e={}){this.config=J(e);let n=[c(process.cwd(),`resora.config.ts`),c(process.cwd(),`resora.config.js`),c(process.cwd(),`resora.config.cjs`)];for(let e of n)if(t(e))try{let{default:t}=await import(e);Object.assign(this.config,t);break}catch(t){console.error(`Error loading config file at ${e}:`,t)}return this}getConfig(){return this.config}init(){let n=c(process.cwd(),`resora.config.js`),i=c(this.config.stubsDir,this.config.stubs.config);return t(n)&&!this.command.option(`force`)&&(this.command.error(`Error: ${n} already exists.`),process.exit(1)),this.ensureDirectory(n),t(n)&&this.command.option(`force`)&&e(n,n.replace(/\.js$/,`.backup.${Date.now()}.js`)),a(n,r(i,`utf-8`)),{path:n}}ensureDirectory(e){let r=s(e);t(r)||n(r,{recursive:!0})}generateFile(e,n,o,s){t(n)&&!s?.force?(this.command.error(`Error: ${n} already exists.`),process.exit(1)):t(n)&&s?.force&&i(n);let c=r(e,`utf-8`);for(let[e,t]of Object.entries(o))c=c.replace(RegExp(`{{${e}}}`,`g`),t);return this.ensureDirectory(n),a(n,c),n}makeResource(e,n){let r=e;n?.collection&&!e.endsWith(`Collection`)&&!e.endsWith(`Resource`)?r+=`Collection`:!n?.collection&&!e.endsWith(`Resource`)&&!e.endsWith(`Collection`)&&(r+=`Resource`);let i=`${r}.ts`,a=c(this.config.resourcesDir,i),o=c(this.config.stubsDir,n?.collection||e.endsWith(`Collection`)?this.config.stubs.collection:this.config.stubs.resource);t(o)||(this.command.error(`Error: Stub file ${o} not found.`),process.exit(1)),r=r.split(`/`).pop()?.split(`.`).shift();let s=r.replace(/(Resource|Collection)$/,``)+`Resource`,l=[`/**`,` * The resource that this collection collects.`,` */`,`collects = ${s}`].join(`
|
|
2
2
|
`),u=`import ${s} from './${s}'\n`,d=(!!n?.collection||e.endsWith(`Collection`))&&t(c(this.config.resourcesDir,`${s}.ts`)),f=this.generateFile(o,a,{ResourceName:r,CollectionResourceName:r.replace(/(Resource|Collection)$/,``)+`Resource`,"collects = Resource":d?l:``,"import = Resource":d?u:``},n);return{name:r,path:f}}},Ee=class extends d{signature=`init
|
|
3
3
|
{--force : Force overwrite if config file already exists (existing file will be backed up) }
|
|
4
4
|
`;description=`Initialize Resora`;async handle(){this.app.command=this,this.app.init(),this.success(`Resora initialized`)}},De=class extends d{signature=`#create:
|
|
@@ -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={};constructor(){Z()}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=G(a);t=K(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=G(a);t=K(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=G(n);t=K(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,xe as applyRuntimeConfig,I as buildPaginationExtras,L as buildResponseEnvelope,J as defineConfig,G as getCaseTransformer,ye 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,Z as loadRuntimeConfig,A as mergeMetadata,N as normalizeSerializableData,be 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,he as toCamelCase,ve as toKebabCase,_e as toPascalCase,ge as toSnakeCase,K as transformKeys};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "resora",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
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.
|
|
55
|
+
"arkormx": "^0.2.6",
|
|
56
56
|
"barrelize": "^1.7.3",
|
|
57
57
|
"eslint": "^10.0.0",
|
|
58
58
|
"express": "^5.1.0",
|