@visulima/crud 2.0.43 → 2.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,3 +1,1085 @@
1
- import {g,i}from'./chunk-IHNLKSVH.mjs';export{h as RouteType}from'./chunk-IHNLKSVH.mjs';import L from'http-errors';import {createPaginationMetaSchemaObject}from'@visulima/pagination';import {getJSONSchemaProperty,transformDMMF}from'@visulima/prisma-dmmf-transformer';g();g();g();var q=(s,e)=>{let t={};return e.forEach(r=>{t[r]=s[r].plural;}),t},w=q;g();g();var ee=new Set(["boolean","number","string"]),te=s=>ee.has(typeof s),R=te;var re=s=>{let e={};if(Object.keys(s).forEach(t=>{let r=s[t];R(r)&&(e[t]=r);}),Object.keys(e).length!==1)throw new Error("cursor needs to be an object with exactly 1 property with a primitive value");return e},F=re;g();var se={$asc:"asc",$desc:"desc"},ne=s=>{let e={};return Object.keys(s).forEach(t=>{let r=s[t];e[t]=se[r];}),e},k=ne;g();var V=(s,e)=>{let t={};return Object.keys(s).forEach(r=>{t[r]=s[r]===true?true:{[e]:V(s[r],e)};}),t},A=V;g();var C=s=>s instanceof Object,ie={$cont:"contains",$ends:"endsWith",$eq:"equals",$gt:"gt",$gte:"gte",$in:"in",$lt:"lt",$lte:"lte",$neq:"not",$notin:"notIn",$starts:"startsWith"},ae=s=>/^\d{4}-[01]\d-[0-3]\d(?:T[0-2](?:\d:[0-5]){2}\d(?:\.\d+)?(?:Z|[+-][0-2]\d(?::?[0-5]\d)?)?)?$/g.test(s),oe=s=>ae(s)?new Date(s):typeof s=="string"&&s==="$isnull"?null:s,v=(s,e)=>{let t=s.split(".");return t.splice(-1,1),e.includes(t.join("."))},B=s=>{let e=Object.keys(s)[0],t=ie[e];if(t)return {[t]:s[e]}},W=(s,e,t,r)=>{let n=e.split(".").reverse(),a={};n.forEach((m,c)=>{c===0?Q(s,m,a,r):a={[m]:{some:a}};});let i=n.reverse()[0],o=t[i];t[i]={some:{...o?.some,...a[i]?.some}};},T=(s,e)=>{let t={};return Object.keys(s).forEach(r=>{let n=s[r];if(v(r,e))W(n,r,t,e);else if(R(n))t[r]=n;else if(C(n)){let a=B(n);a&&(t[r]=a);}}),t},Q=(s,e,t,r)=>{if(R(s))t[e]=oe(s);else switch(e){case "$and":{C(s)&&(t.AND=T(s,r));break}case "$not":{C(s)&&(t.NOT=T(s,r));break}case "$or":{C(s)&&(t.OR=T(s,r));break}default:{t[e]=B(s);break}}},ce=(s,e)=>{let t={};return Object.keys(s).forEach(r=>{let n=s[r];v(r,e)?W(n,r,t,e):Q(n,r,t,e);}),t},_=ce;var E=class{models;ctorModels;dmmf;manyRelations;primaryKey;prismaClient;constructor({manyRelations:e={},models:t,primaryKey:r="id",prismaClient:n}){this.prismaClient=n,this.primaryKey=r,this.manyRelations=e,this.ctorModels=t;}async connect(){this.prismaClient.$connect();}async create(e,t,r){return await this.getPrismaDelegate(e).create({data:t,include:r.include,select:r.select})}async delete(e,t,r){return await this.getPrismaDelegate(e).delete({include:r.include,select:r.select,where:{[this.primaryKey]:t}})}async disconnect(){await this.prismaClient.$disconnect();}async getAll(e,t){return await this.getPrismaDelegate(e).findMany({cursor:t.cursor,distinct:t.distinct,include:t.include,orderBy:t.orderBy,select:t.select,skip:t.skip,take:t.take,where:t.where})}getModels(){return this.models??[]}async getOne(e,t,r){let n=this.getPrismaDelegate(e);return await(n.findUnique??n.findOne)({include:r.include,select:r.select,where:{[this.primaryKey]:t}})}async getPaginationData(e,t){let r=await this.getPrismaDelegate(e).count({distinct:t.distinct,where:t.where});return {page:Math.ceil((t.skip??0)/(t.take??0))+1,pageCount:Math.ceil(r/(t.take??0)),total:r}}handleError(e){throw console.error(e),e instanceof Error&&e.stack&&console.error(e.stack),e.constructor.name==="PrismaClientKnownRequestError"||e.constructor.name==="PrismaClientValidationError"?L(400,"invalid request, check your server logs for more info"):L(500,"an unknown error occured, check your server logs for more info")}async init(){let e=this.ctorModels,t=await this.getPrismaClientModels();e!==void 0&&e.forEach(r=>{if(!Object.keys(t).includes(r))throw new Error(`Model name ${r} is invalid.`)}),this.models=e??Object.keys(t);}async mapModelsToRouteNames(){return w(await this.getPrismaClientModels(),this.getModels())}parseQuery(e,t){let r={};return t.select&&(r.select=A(t.select,"select")),t.include&&(r.include=A(t.include,"include")),t.originalQuery?.where&&(r.where=_(JSON.parse(t.originalQuery.where),this.manyRelations[e]??[])),t.orderBy&&(r.orderBy=k(t.orderBy)),t.limit!==void 0&&(r.take=t.limit),t.skip!==void 0&&(r.skip=t.skip),t.originalQuery?.cursor&&(r.cursor=F(JSON.parse(t.originalQuery.cursor))),t.distinct&&(r.distinct=t.distinct),r}async update(e,t,r,n){return await this.getPrismaDelegate(e).update({data:r,include:n.include,select:n.select,where:{[this.primaryKey]:t}})}get client(){return this.prismaClient}getPrismaClientModels=async()=>{if(this.prismaClient._dmmf!==void 0)return this.dmmf=this.prismaClient._dmmf,this.dmmf?.mappingsMap;if(this.prismaClient._getDmmf!==void 0)return this.dmmf=await this.prismaClient._getDmmf(),this.dmmf.mappingsMap;throw new Error("Couldn't get prisma client models")};getPrismaDelegate(e){return this.prismaClient[`${e.charAt(0).toLowerCase()}${e.slice(1)}`]}};g();g();g();var pe=s=>`#/components/schemas/${s}`,P=pe;var U=s=>{switch(s){case "BigInt":case "Int":return "integer";case "Boolean":return "boolean";case "Bytes":case "DateTime":case "String":return "string";case "Decimal":case "Float":return "number";case "Json":return "object";case "Null":return "null";default:return ""}},x="PaginationData",ge=[{methodStart:"createOne",schemaNameStart:"Create"},{methodStart:"updateOne",schemaNameStart:"Update"}],$=class{constructor(e){this.dmmf=e;}schemaInputTypes=new Map;formatInputTypeData(e){if(e.kind==="object"){let r=P(e.type.name);return e.isList?{items:{$ref:r},type:"array",xml:{name:e.type.name,wrapped:true}}:{$ref:r}}let t=U(e.type);return e.isList?{items:{type:t},type:"array",xml:{name:e.type.name,wrapped:true}}:{type:t}}getExampleModelsSchemas(e,t){let r=i=>{let o=i.replace("#/components/schemas/",""),m=t[o],c={};return Object.entries(m.properties??{}).forEach(([f,l])=>{let d=l.type;c[f]=d==="array"?[a(l.items)]:d;}),c},n=i=>{let o={};return Object.entries(i).forEach(([m,c])=>{o[m]=c.$ref===void 0?c.type:r(c.$ref);}),o},a=i=>{let o={};return Object.entries(i).forEach(([m,c])=>{c.items.$ref!==void 0?o[m]=[r(c.items.$ref)]:c.type==="array"?o[m]=[a(c.items)]:c.type==="object"?o[m]=n(c.properties):o[m]=c.type;}),o};return e.reduce((i,o)=>{let m={},c=t[o];Object.entries(c.properties).forEach(([d,h])=>{let y=h.type;y==="array"?m[d]=[r(h.items.$ref)]:y==="object"?m[d]=n(h.properties):m[d]=y;});let f=this.getPaginationDataSchema()[x],l={};return Object.entries(f.properties).forEach(([d,h])=>{l[d]=h.type;}),{...i,[`${o}Page`]:{value:{data:[m],meta:l}},[`${o}s`]:{value:[m]},[o]:{value:m}}},{})}getPaginatedModelsSchemas(e){return e.reduce((t,r)=>({...t,[`${r}Page`]:{properties:{data:{items:{$ref:P(r)},type:"array",xml:{name:"data",wrapped:true}},meta:{$ref:P(x)}},type:"object",xml:{name:`${r}Page`}}}),{})}getPaginationDataSchema(){return createPaginationMetaSchemaObject(x)}parseInputTypes(e){let t=e.reduce((r,n)=>(ge.map(i=>({name:`${i.methodStart}${n}`,schemaName:`${i.schemaNameStart}${n}`})).forEach(({name:i,schemaName:o})=>{let m=this.dmmf.mutationType.fieldMap[i].args[0].inputTypes[0].type.fields,c=[],f=m.reduce((l,d)=>{if(d.inputTypes[0].kind==="scalar"){let h=getJSONSchemaProperty(this.dmmf.datamodel,{})({name:d.name,...d.inputTypes[0]}),{type:y}=h[1];y&&Array.isArray(y)?y.includes("null")&&(l[d.name]={...y,nullable:true,type:y.filter(j=>j!=="null")},l[d.name].type.length===1&&(l[d.name]={...l[d.name],type:l[d.name].type[0]})):l[d.name]=h[1];}else {let h=this.parseObjectInputType(d.inputTypes[0]);l[d.name]={...h,nullable:d.isNullable};}return d.isRequired&&c.push(d.name),l},{});r[o]={properties:f,type:"object",xml:{name:o}},c.length>0&&(r[o].required=c);}),r),{});return this.schemaInputTypes.forEach((r,n)=>{t[n]={properties:r,type:"object",xml:{name:n}};}),t}parseModels(){let e=transformDMMF(this.dmmf).definitions;return Object.keys(e).forEach(t=>{let{properties:r}=e[t];Object.keys(r).forEach(n=>{Array.isArray(r[n].type)&&r[n].type.includes("null")&&(r[n].type=r[n].type.filter(a=>a!=="null"),r[n].type.length===1&&(r[n].type=r[n].type[0]),r[n].nullable=true);});}),e}parseObjectInputType(e){return e.kind==="object"?(this.schemaInputTypes.has(e.type.name)||(this.schemaInputTypes.set(e.type.name,{}),e.type.fields.forEach(t=>{let r={};if(t.inputTypes.length>1){let n=false,a=t.inputTypes.map(i=>{let o=this.formatInputTypeData(i);if(o.type==="null"){n=true;return}return o}).filter(Boolean);a.length===1?r=a[0]:r.anyOf=a,n&&(r.nullable=true);}else {let n=t.inputTypes[0];r=this.formatInputTypeData(n);}this.schemaInputTypes.set(e.type.name,{...this.schemaInputTypes.get(e.type.name),[t.name]:r}),t.inputTypes.forEach(n=>{n.kind==="object"&&this.parseObjectInputType(n);});})),{$ref:P(e.type.name)}):{type:U(e.type)}}},H=$;g();var ue=(s,e,t="all")=>s.reduce((r,n)=>e?.[n]?{...r,[n]:i(e[n].only,e[n].exclude,t)}:{...r,[n]:i(void 0,void 0,t)},{}),J=ue;g();g();var O={distinct:{description:"Fields to distinctively retrieve",name:"distinct",schema:{type:"string"}},include:{description:"Include relations, same as select",name:"include",schema:{type:"string"}},limit:{description:"Maximum number of elements to retrieve",name:"limit",schema:{minimum:0,type:"integer"}},orderBy:{description:'Field on which to order by a direction. See <a href="https://next-crud.js.org/query-params#orderBy">the docs</a>',name:"orderBy",schema:{type:"string"}},page:{description:"Page number. Use only for pagination.",name:"page",schema:{minimum:1,type:"integer"}},select:{description:"Fields to select. For nested fields, chain them separated with a dot, eg: user.posts",name:"select",schema:{type:"string"}},skip:{description:"Number of rows to skip",name:"skip",schema:{minimum:0,type:"integer"}},where:{description:'Fields to filter. See <a href="https://next-crud.js.org/query-params#where">the docs</a>',name:"where",schema:{type:"string"}}},G=[O.select,O.include],fe=[...G,O.limit,O.skip,O.where,O.orderBy,O.page,O.distinct],K=(s,e=[])=>s==="READ_ALL"?[...fe,...e].filter(Boolean):[...G,...e].filter(Boolean);g();var he=s=>`#/components/examples/${s}`,b=he;var M=(s,e)=>e?{items:{$ref:P(s)},type:"array"}:{$ref:P(s)},ye=(s,e)=>{if(s==="CREATE")return {content:{content:{"application/json":{example:b(e),schema:M(e)}},description:`${e} created`},statusCode:201};if(s==="DELETE")return {content:{content:{"application/json":{example:b(e),schema:M(e)}},description:`${e} item deleted`},statusCode:200};if(s==="READ_ALL")return {content:{content:{"application/json":{examples:{Default:{$ref:b(`${e}s`)},Pagination:{$ref:b(`${e}Page`)}},schema:{oneOf:[M(e,true),M(`${e}Page`,false)]}}},description:`${e} list retrieved`},statusCode:200};if(s==="READ_ONE")return {content:{content:{"application/json":{example:b(e),schema:M(e)}},description:`${e} item retrieved`},statusCode:200};if(s==="UPDATE")return {content:{content:{"application/json":{example:b(e),schema:M(e)}},description:`${e} item updated`},statusCode:200}},Z=(s,e)=>({content:{"application/json":{schema:{$ref:P(`${s}${e}`)}}}}),Pe=s=>{switch(s){case "CREATE":return "post";case "DELETE":return "delete";case "READ_ALL":case "READ_ONE":return "get";case "UPDATE":return "put";default:throw new TypeError(`Method for route type ${s} was not found.`)}},z=({hasId:s,modelName:e,modelsConfig:t,routeTypes:r,tag:n})=>{let a={};return r.forEach(i=>{if(r.includes(i)){let o=t?.[e]?.routeTypes?.[i]?.response.name??t?.[e]?.type?.name??e,m=Pe(i),c=ye(i,o);if(c===void 0)throw new TypeError(`Route type ${i}; response config was not found.`);a[m]={parameters:K(i).map(f=>({...f,in:"query"})),responses:{[c.statusCode]:c.content,...t?.[e]?.routeTypes?.[i]?.responses},summary:t?.[e]?.routeTypes?.[i]?.summary,tags:[n]},s&&a[m].parameters.push({description:`ID of the ${e}`,in:"path",name:"id",required:true,schema:{type:"string"}}),i==="UPDATE"?a[m].requestBody=Z("Update",o):i==="CREATE"&&(a[m].requestBody=Z("Create",o));}}),a},Oe=({models:s,modelsConfig:e,routes:t,routesMap:r})=>Object.keys(t).reduce((n,a)=>{let i=t[a],o=s?.[a]?.name?s[a].name:r?.[a]??a,m=e?.[a]?.tag.name??a;if(i.includes("CREATE")||i.includes("READ_ALL")){let c=`/${o}`,f=["READ_ALL","CREATE"].filter(l=>i.includes(l));n[c]=z({modelName:a,modelsConfig:e,routeTypes:f,tag:m});}if(i.includes("READ_ONE")||i.includes("UPDATE")||i.includes("DELETE")){let c=`/${o}/{id}`,f=["READ_ONE","UPDATE","DELETE"].filter(l=>i.includes(l));n[c]=z({hasId:true,modelName:a,modelsConfig:e,routeTypes:f,tag:m});}return n},{}),X=Oe;g();var be=(s,e)=>s.map(t=>e?.[t]?.tag?e[t].tag:{name:t}),Y=be;var Me=(s,e)=>(Object.values(s).forEach(t=>{Object.values(t).forEach(r=>{typeof r.responses=="object"&&Object.values(r.responses).forEach(n=>{typeof n.content=="object"&&Object.values(n.content).forEach(a=>{if(typeof a.example=="string"){let i=a.example.replace("#/components/examples/","");e[i]?.value!==void 0&&(a.example=e[i].value);}});});});}),s),Re=async({crud:s={models:{}},defaultExposeStrategy:e="all",models:t,prismaClient:r,swagger:n={allowedMediaTypes:{"application/json":true},models:{}}})=>{let a,i;if(r._dmmf!==void 0?(a=r._dmmf,i=a?.mappingsMap):r._getDmmf!==void 0&&(a=await r._getDmmf(),i=a.mappingsMap),a===void 0)throw new TypeError("Couldn't get prisma client models");let o=new H(a),m=o.parseModels(),c=Object.keys(m),f=JSON.stringify({...m,...o.parseInputTypes(c),...o.getPaginationDataSchema(),...o.getPaginatedModelsSchemas(c)});t!==void 0&&t.forEach(D=>{if(!Object.keys(i).includes(D))throw new Error(`Model name ${D} is invalid.`)});let l=t??Object.keys(i),d=J(l,s.models,e),h=Y(l,n.models),y=X({models:s.models,modelsConfig:n.models,routes:d,routesMap:w(i,l)}),j=JSON.parse(f.replaceAll("#/definitions","#/components/schemas")),I=o.getExampleModelsSchemas(c,j);return {examples:I,paths:Me(y,I),schemas:j,tags:h}},je=Re;
2
- export{E as PrismaAdapter,je as modelsToOpenApi};//# sourceMappingURL=index.mjs.map
1
+ import { init_esm_shims, get_accessible_routes_default } from './chunk-LBXJKEOF.mjs';
2
+ export { RouteType } from './chunk-LBXJKEOF.mjs';
3
+ import createHttpError from 'http-errors';
4
+ import { createPaginationMetaSchemaObject } from '@visulima/pagination';
5
+ import { getJSONSchemaProperty, transformDMMF } from '@visulima/prisma-dmmf-transformer';
6
+
7
+ // src/index.ts
8
+ init_esm_shims();
9
+
10
+ // src/adapter/prisma/index.ts
11
+ init_esm_shims();
12
+
13
+ // src/adapter/prisma/utils/models-to-route-names.ts
14
+ init_esm_shims();
15
+ var modelsToRouteNames = (mappingsMap, models) => {
16
+ const routesMap = {};
17
+ models.forEach((model) => {
18
+ routesMap[model] = mappingsMap[model].plural;
19
+ });
20
+ return routesMap;
21
+ };
22
+ var models_to_route_names_default = modelsToRouteNames;
23
+
24
+ // src/adapter/prisma/utils/parse-cursor.ts
25
+ init_esm_shims();
26
+
27
+ // src/utils/is-primitive.ts
28
+ init_esm_shims();
29
+ var primitiveTypes = /* @__PURE__ */ new Set(["boolean", "number", "string"]);
30
+ var isPrimitive = (value) => primitiveTypes.has(typeof value);
31
+ var is_primitive_default = isPrimitive;
32
+
33
+ // src/adapter/prisma/utils/parse-cursor.ts
34
+ var parsePrismaCursor = (cursor) => {
35
+ const parsed = {};
36
+ Object.keys(cursor).forEach((key) => {
37
+ const value = cursor[key];
38
+ if (is_primitive_default(value)) {
39
+ parsed[key] = value;
40
+ }
41
+ });
42
+ if (Object.keys(parsed).length !== 1) {
43
+ throw new Error("cursor needs to be an object with exactly 1 property with a primitive value");
44
+ }
45
+ return parsed;
46
+ };
47
+ var parse_cursor_default = parsePrismaCursor;
48
+
49
+ // src/adapter/prisma/utils/parse-order-by.ts
50
+ init_esm_shims();
51
+ var operatorsAssociation = {
52
+ $asc: "asc",
53
+ $desc: "desc"
54
+ };
55
+ var parsePrismaOrderBy = (orderBy) => {
56
+ const parsed = {};
57
+ Object.keys(orderBy).forEach((key) => {
58
+ const value = orderBy[key];
59
+ parsed[key] = operatorsAssociation[value];
60
+ });
61
+ return parsed;
62
+ };
63
+ var parse_order_by_default = parsePrismaOrderBy;
64
+
65
+ // src/adapter/prisma/utils/parse-recursive.ts
66
+ init_esm_shims();
67
+ var parsePrismaRecursiveField = (select, fieldName) => {
68
+ const parsed = {};
69
+ Object.keys(select).forEach((field) => {
70
+ parsed[field] = select[field] === true ? true : {
71
+ [fieldName]: parsePrismaRecursiveField(select[field], fieldName)
72
+ };
73
+ });
74
+ return parsed;
75
+ };
76
+ var parse_recursive_default = parsePrismaRecursiveField;
77
+
78
+ // src/adapter/prisma/utils/parse-where.ts
79
+ init_esm_shims();
80
+ var isObject = (a) => a instanceof Object;
81
+ var operatorsAssociation2 = {
82
+ $cont: "contains",
83
+ $ends: "endsWith",
84
+ $eq: "equals",
85
+ $gt: "gt",
86
+ $gte: "gte",
87
+ $in: "in",
88
+ $lt: "lt",
89
+ $lte: "lte",
90
+ $neq: "not",
91
+ $notin: "notIn",
92
+ $starts: "startsWith"
93
+ };
94
+ var isDateString = (value) => /^\d{4}-[01]\d-[0-3]\d(?:T[0-2](?:\d:[0-5]){2}\d(?:\.\d+)?(?:Z|[+-][0-2]\d(?::?[0-5]\d)?)?)?$/g.test(value);
95
+ var getSearchValue = (originalValue) => {
96
+ if (isDateString(originalValue)) {
97
+ return new Date(originalValue);
98
+ }
99
+ if (typeof originalValue === "string" && originalValue === "$isnull") {
100
+ return null;
101
+ }
102
+ return originalValue;
103
+ };
104
+ var isRelation = (key, manyRelations) => {
105
+ const splitKey = key.split(".");
106
+ splitKey.splice(-1, 1);
107
+ return manyRelations.includes(splitKey.join("."));
108
+ };
109
+ var parseSimpleField = (value) => {
110
+ const operator = Object.keys(value)[0];
111
+ const prismaOperator = operatorsAssociation2[operator];
112
+ if (prismaOperator) {
113
+ return {
114
+ [prismaOperator]: value[operator]
115
+ };
116
+ }
117
+ return void 0;
118
+ };
119
+ var parseRelation = (value, key, parsed, manyRelations) => {
120
+ const fields = key.split(".").reverse();
121
+ let formatFields = {};
122
+ fields.forEach((field, index) => {
123
+ if (index === 0) {
124
+ basicParse(value, field, formatFields, manyRelations);
125
+ } else {
126
+ formatFields = {
127
+ [field]: {
128
+ some: formatFields
129
+ }
130
+ };
131
+ }
132
+ });
133
+ const initialFieldKey = fields.reverse()[0];
134
+ const oldParsed = parsed[initialFieldKey];
135
+ parsed[initialFieldKey] = {
136
+ some: {
137
+ ...oldParsed?.some,
138
+ ...formatFields[initialFieldKey]?.some
139
+ }
140
+ };
141
+ };
142
+ var parseObjectCombination = (object, manyRelations) => {
143
+ const parsed = {};
144
+ Object.keys(object).forEach((key) => {
145
+ const value = object[key];
146
+ if (isRelation(key, manyRelations)) {
147
+ parseRelation(value, key, parsed, manyRelations);
148
+ } else if (is_primitive_default(value)) {
149
+ parsed[key] = value;
150
+ } else if (isObject(value)) {
151
+ const fieldResult = parseSimpleField(value);
152
+ if (fieldResult) {
153
+ parsed[key] = fieldResult;
154
+ }
155
+ }
156
+ });
157
+ return parsed;
158
+ };
159
+ var basicParse = (value, key, parsed, manyRelations) => {
160
+ if (is_primitive_default(value)) {
161
+ parsed[key] = getSearchValue(value);
162
+ } else {
163
+ switch (key) {
164
+ case "$and": {
165
+ if (isObject(value)) {
166
+ parsed.AND = parseObjectCombination(value, manyRelations);
167
+ }
168
+ break;
169
+ }
170
+ case "$not": {
171
+ if (isObject(value)) {
172
+ parsed.NOT = parseObjectCombination(value, manyRelations);
173
+ }
174
+ break;
175
+ }
176
+ case "$or": {
177
+ if (isObject(value)) {
178
+ parsed.OR = parseObjectCombination(value, manyRelations);
179
+ }
180
+ break;
181
+ }
182
+ default: {
183
+ parsed[key] = parseSimpleField(value);
184
+ break;
185
+ }
186
+ }
187
+ }
188
+ };
189
+ var parsePrismaWhere = (where, manyRelations) => {
190
+ const parsed = {};
191
+ Object.keys(where).forEach((key) => {
192
+ const value = where[key];
193
+ if (isRelation(key, manyRelations)) {
194
+ parseRelation(value, key, parsed, manyRelations);
195
+ } else {
196
+ basicParse(value, key, parsed, manyRelations);
197
+ }
198
+ });
199
+ return parsed;
200
+ };
201
+ var parse_where_default = parsePrismaWhere;
202
+
203
+ // src/adapter/prisma/index.ts
204
+ var PrismaAdapter = class {
205
+ models;
206
+ ctorModels;
207
+ dmmf;
208
+ manyRelations;
209
+ primaryKey;
210
+ prismaClient;
211
+ constructor({ manyRelations = {}, models, primaryKey = "id", prismaClient }) {
212
+ this.prismaClient = prismaClient;
213
+ this.primaryKey = primaryKey;
214
+ this.manyRelations = manyRelations;
215
+ this.ctorModels = models;
216
+ }
217
+ async connect() {
218
+ this.prismaClient.$connect();
219
+ }
220
+ async create(resourceName, data, query) {
221
+ return await this.getPrismaDelegate(resourceName).create({
222
+ data,
223
+ include: query.include,
224
+ select: query.select
225
+ });
226
+ }
227
+ async delete(resourceName, resourceId, query) {
228
+ return await this.getPrismaDelegate(resourceName).delete({
229
+ include: query.include,
230
+ select: query.select,
231
+ where: {
232
+ [this.primaryKey]: resourceId
233
+ }
234
+ });
235
+ }
236
+ async disconnect() {
237
+ await this.prismaClient.$disconnect();
238
+ }
239
+ async getAll(resourceName, query) {
240
+ return await this.getPrismaDelegate(resourceName).findMany({
241
+ cursor: query.cursor,
242
+ distinct: query.distinct,
243
+ include: query.include,
244
+ orderBy: query.orderBy,
245
+ select: query.select,
246
+ skip: query.skip,
247
+ take: query.take,
248
+ where: query.where
249
+ });
250
+ }
251
+ getModels() {
252
+ return this.models ?? [];
253
+ }
254
+ async getOne(resourceName, resourceId, query) {
255
+ const delegate = this.getPrismaDelegate(resourceName);
256
+ const findFunction = delegate.findUnique ?? delegate.findOne;
257
+ return await findFunction({
258
+ include: query.include,
259
+ select: query.select,
260
+ where: {
261
+ [this.primaryKey]: resourceId
262
+ }
263
+ });
264
+ }
265
+ async getPaginationData(resourceName, query) {
266
+ const total = await this.getPrismaDelegate(resourceName).count({
267
+ distinct: query.distinct,
268
+ where: query.where
269
+ });
270
+ return {
271
+ page: Math.ceil((query.skip ?? 0) / (query.take ?? 0)) + 1,
272
+ pageCount: Math.ceil(total / (query.take ?? 0)),
273
+ total
274
+ };
275
+ }
276
+ // eslint-disable-next-line class-methods-use-this
277
+ handleError(error) {
278
+ console.error(error);
279
+ if (error instanceof Error && error.stack) {
280
+ console.error(error.stack);
281
+ }
282
+ throw error.constructor.name === "PrismaClientKnownRequestError" || error.constructor.name === "PrismaClientValidationError" ? createHttpError(400, "invalid request, check your server logs for more info") : createHttpError(500, "an unknown error occured, check your server logs for more info");
283
+ }
284
+ async init() {
285
+ const models = this.ctorModels;
286
+ const prismaDmmfModels = await this.getPrismaClientModels();
287
+ if (models !== void 0) {
288
+ models.forEach((model) => {
289
+ if (!Object.keys(prismaDmmfModels).includes(model)) {
290
+ throw new Error(`Model name ${model} is invalid.`);
291
+ }
292
+ });
293
+ }
294
+ this.models = models ?? Object.keys(prismaDmmfModels);
295
+ }
296
+ async mapModelsToRouteNames() {
297
+ return models_to_route_names_default(await this.getPrismaClientModels(), this.getModels());
298
+ }
299
+ parseQuery(resourceName, query) {
300
+ const parsed = {};
301
+ if (query.select) {
302
+ parsed.select = parse_recursive_default(query.select, "select");
303
+ }
304
+ if (query.include) {
305
+ parsed.include = parse_recursive_default(query.include, "include");
306
+ }
307
+ if (query.originalQuery?.where) {
308
+ parsed.where = parse_where_default(JSON.parse(query.originalQuery.where), this.manyRelations[resourceName] ?? []);
309
+ }
310
+ if (query.orderBy) {
311
+ parsed.orderBy = parse_order_by_default(query.orderBy);
312
+ }
313
+ if (query.limit !== void 0) {
314
+ parsed.take = query.limit;
315
+ }
316
+ if (query.skip !== void 0) {
317
+ parsed.skip = query.skip;
318
+ }
319
+ if (query.originalQuery?.cursor) {
320
+ parsed.cursor = parse_cursor_default(JSON.parse(query.originalQuery.cursor));
321
+ }
322
+ if (query.distinct) {
323
+ parsed.distinct = query.distinct;
324
+ }
325
+ return parsed;
326
+ }
327
+ async update(resourceName, resourceId, data, query) {
328
+ return await this.getPrismaDelegate(resourceName).update({
329
+ data,
330
+ include: query.include,
331
+ select: query.select,
332
+ where: {
333
+ [this.primaryKey]: resourceId
334
+ }
335
+ });
336
+ }
337
+ get client() {
338
+ return this.prismaClient;
339
+ }
340
+ getPrismaClientModels = async () => {
341
+ if (this.prismaClient._dmmf !== void 0) {
342
+ this.dmmf = this.prismaClient._dmmf;
343
+ return this.dmmf?.mappingsMap;
344
+ }
345
+ if (this.prismaClient._getDmmf !== void 0) {
346
+ this.dmmf = await this.prismaClient._getDmmf();
347
+ return this.dmmf.mappingsMap;
348
+ }
349
+ throw new Error("Couldn't get prisma client models");
350
+ };
351
+ getPrismaDelegate(resourceName) {
352
+ return this.prismaClient[`${resourceName.charAt(0).toLowerCase()}${resourceName.slice(1)}`];
353
+ }
354
+ };
355
+
356
+ // src/swagger/adapter/prisma/index.ts
357
+ init_esm_shims();
358
+
359
+ // src/swagger/json-schema-parser.ts
360
+ init_esm_shims();
361
+
362
+ // src/swagger/utils/format-schema-ref.ts
363
+ init_esm_shims();
364
+ var formatSchemaReference = (schemaName) => `#/components/schemas/${schemaName}`;
365
+ var format_schema_ref_default = formatSchemaReference;
366
+
367
+ // src/swagger/json-schema-parser.ts
368
+ var getJSONSchemaScalar = (fieldType) => {
369
+ switch (fieldType) {
370
+ case "BigInt":
371
+ case "Int": {
372
+ return "integer";
373
+ }
374
+ case "Boolean": {
375
+ return "boolean";
376
+ }
377
+ case "Bytes":
378
+ case "DateTime":
379
+ case "String": {
380
+ return "string";
381
+ }
382
+ case "Decimal":
383
+ case "Float": {
384
+ return "number";
385
+ }
386
+ case "Json": {
387
+ return "object";
388
+ }
389
+ case "Null": {
390
+ return "null";
391
+ }
392
+ default: {
393
+ return "";
394
+ }
395
+ }
396
+ };
397
+ var PAGINATION_SCHEMA_NAME = "PaginationData";
398
+ var methodsNames = [
399
+ { methodStart: "createOne", schemaNameStart: "Create" },
400
+ { methodStart: "updateOne", schemaNameStart: "Update" }
401
+ ];
402
+ var PrismaJsonSchemaParser = class {
403
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
404
+ constructor(dmmf) {
405
+ this.dmmf = dmmf;
406
+ }
407
+ schemaInputTypes = /* @__PURE__ */ new Map();
408
+ // eslint-disable-next-line class-methods-use-this,@typescript-eslint/explicit-module-boundary-types
409
+ formatInputTypeData(inputType) {
410
+ if (inputType.kind === "object") {
411
+ const reference = format_schema_ref_default(inputType.type.name);
412
+ if (inputType.isList) {
413
+ return {
414
+ items: {
415
+ $ref: reference
416
+ },
417
+ type: "array",
418
+ xml: {
419
+ name: inputType.type.name,
420
+ wrapped: true
421
+ }
422
+ };
423
+ }
424
+ return { $ref: reference };
425
+ }
426
+ const type = getJSONSchemaScalar(inputType.type);
427
+ if (inputType.isList) {
428
+ return {
429
+ items: {
430
+ type
431
+ },
432
+ type: "array",
433
+ xml: {
434
+ name: inputType.type.name,
435
+ wrapped: true
436
+ }
437
+ };
438
+ }
439
+ return { type };
440
+ }
441
+ getExampleModelsSchemas(modelNames, schemas) {
442
+ const referenceToSchema = (reference) => {
443
+ const name = reference.replace("#/components/schemas/", "");
444
+ const model = schemas[name];
445
+ const values = {};
446
+ Object.entries(model.properties ?? {}).forEach(([key, v]) => {
447
+ const type = v.type;
448
+ values[key] = type === "array" ? [arrayItemsToSchema(v.items)] : type;
449
+ });
450
+ return values;
451
+ };
452
+ const objectPropertiesToSchema = (objectProperties) => {
453
+ const values = {};
454
+ Object.entries(objectProperties).forEach(([key, value]) => {
455
+ values[key] = value.$ref === void 0 ? value.type : referenceToSchema(value.$ref);
456
+ });
457
+ return values;
458
+ };
459
+ const arrayItemsToSchema = (items) => {
460
+ const values = {};
461
+ Object.entries(items).forEach(([key, value]) => {
462
+ if (value.items.$ref !== void 0) {
463
+ values[key] = [referenceToSchema(value.items.$ref)];
464
+ } else if (value.type === "array") {
465
+ values[key] = [arrayItemsToSchema(value.items)];
466
+ } else if (value.type === "object") {
467
+ values[key] = objectPropertiesToSchema(value.properties);
468
+ } else {
469
+ values[key] = value.type;
470
+ }
471
+ });
472
+ return values;
473
+ };
474
+ return modelNames.reduce((accumulator, modelName) => {
475
+ const value = {};
476
+ const model = schemas[modelName];
477
+ Object.entries(model.properties).forEach(([key, v]) => {
478
+ const type = v.type;
479
+ if (type === "array") {
480
+ value[key] = [referenceToSchema(v.items.$ref)];
481
+ } else if (type === "object") {
482
+ value[key] = objectPropertiesToSchema(v.properties);
483
+ } else {
484
+ value[key] = type;
485
+ }
486
+ });
487
+ const pagination = this.getPaginationDataSchema()[PAGINATION_SCHEMA_NAME];
488
+ const meta = {};
489
+ Object.entries(pagination.properties).forEach(([key, v]) => {
490
+ meta[key] = v.type;
491
+ });
492
+ return {
493
+ ...accumulator,
494
+ [`${modelName}Page`]: {
495
+ value: {
496
+ data: [value],
497
+ meta
498
+ }
499
+ },
500
+ [`${modelName}s`]: {
501
+ value: [value]
502
+ },
503
+ [modelName]: {
504
+ value
505
+ }
506
+ };
507
+ }, {});
508
+ }
509
+ // eslint-disable-next-line class-methods-use-this
510
+ getPaginatedModelsSchemas(modelNames) {
511
+ return modelNames.reduce((accumulator, modelName) => {
512
+ return {
513
+ ...accumulator,
514
+ [`${modelName}Page`]: {
515
+ properties: {
516
+ data: {
517
+ items: {
518
+ $ref: format_schema_ref_default(modelName)
519
+ },
520
+ type: "array",
521
+ xml: {
522
+ name: "data",
523
+ wrapped: true
524
+ }
525
+ },
526
+ meta: {
527
+ $ref: format_schema_ref_default(PAGINATION_SCHEMA_NAME)
528
+ }
529
+ },
530
+ type: "object",
531
+ xml: {
532
+ name: `${modelName}Page`
533
+ }
534
+ }
535
+ };
536
+ }, {});
537
+ }
538
+ // eslint-disable-next-line class-methods-use-this
539
+ getPaginationDataSchema() {
540
+ return createPaginationMetaSchemaObject(PAGINATION_SCHEMA_NAME);
541
+ }
542
+ parseInputTypes(models) {
543
+ const definitions = models.reduce((accumulator, modelName) => {
544
+ const methods = methodsNames.map((method) => {
545
+ return {
546
+ name: `${method.methodStart}${modelName}`,
547
+ schemaName: `${method.schemaNameStart}${modelName}`
548
+ };
549
+ });
550
+ methods.forEach(({ name: method, schemaName }) => {
551
+ const dataFields = this.dmmf.mutationType.fieldMap[method].args[0].inputTypes[0].type.fields;
552
+ const requiredProperties = [];
553
+ const properties = dataFields.reduce((propertiesAccumulator, field) => {
554
+ if (field.inputTypes[0].kind === "scalar") {
555
+ const schema = getJSONSchemaProperty(
556
+ this.dmmf.datamodel,
557
+ {}
558
+ )({
559
+ name: field.name,
560
+ ...field.inputTypes[0]
561
+ });
562
+ const { type: schemaType } = schema[1];
563
+ if (schemaType && Array.isArray(schemaType)) {
564
+ if (schemaType.includes("null")) {
565
+ propertiesAccumulator[field.name] = {
566
+ ...schemaType,
567
+ nullable: true,
568
+ type: schemaType.filter((type) => type !== "null")
569
+ };
570
+ if (propertiesAccumulator[field.name].type.length === 1) {
571
+ propertiesAccumulator[field.name] = {
572
+ ...propertiesAccumulator[field.name],
573
+ type: propertiesAccumulator[field.name].type[0]
574
+ };
575
+ }
576
+ }
577
+ } else {
578
+ propertiesAccumulator[field.name] = schema[1];
579
+ }
580
+ } else {
581
+ const typeName = this.parseObjectInputType(field.inputTypes[0]);
582
+ propertiesAccumulator[field.name] = {
583
+ ...typeName,
584
+ nullable: field.isNullable
585
+ };
586
+ }
587
+ if (field.isRequired) {
588
+ requiredProperties.push(field.name);
589
+ }
590
+ return propertiesAccumulator;
591
+ }, {});
592
+ accumulator[schemaName] = {
593
+ properties,
594
+ type: "object",
595
+ xml: {
596
+ name: schemaName
597
+ }
598
+ };
599
+ if (requiredProperties.length > 0) {
600
+ accumulator[schemaName].required = requiredProperties;
601
+ }
602
+ });
603
+ return accumulator;
604
+ }, {});
605
+ this.schemaInputTypes.forEach((value, key) => {
606
+ definitions[key] = {
607
+ properties: value,
608
+ type: "object",
609
+ xml: {
610
+ name: key
611
+ }
612
+ };
613
+ });
614
+ return definitions;
615
+ }
616
+ parseModels() {
617
+ const modelsDefinitions = transformDMMF(this.dmmf).definitions;
618
+ Object.keys(modelsDefinitions).forEach((definition) => {
619
+ const { properties } = modelsDefinitions[definition];
620
+ Object.keys(properties).forEach((property) => {
621
+ if (Array.isArray(properties[property].type) && properties[property].type.includes("null")) {
622
+ properties[property].type = properties[property].type.filter((type) => type !== "null");
623
+ if (properties[property].type.length === 1) {
624
+ properties[property].type = properties[property].type[0];
625
+ }
626
+ properties[property].nullable = true;
627
+ }
628
+ });
629
+ });
630
+ return modelsDefinitions;
631
+ }
632
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
633
+ parseObjectInputType(fieldType) {
634
+ if (fieldType.kind === "object") {
635
+ if (!this.schemaInputTypes.has(fieldType.type.name)) {
636
+ this.schemaInputTypes.set(fieldType.type.name, {});
637
+ fieldType.type.fields.forEach((field) => {
638
+ let fieldData = {};
639
+ if (field.inputTypes.length > 1) {
640
+ let nullable = false;
641
+ const anyOf = field.inputTypes.map((inputType) => {
642
+ const inputTypeData = this.formatInputTypeData(inputType);
643
+ if (inputTypeData.type === "null") {
644
+ nullable = true;
645
+ return;
646
+ }
647
+ return inputTypeData;
648
+ }).filter(Boolean);
649
+ if (anyOf.length === 1) {
650
+ fieldData = anyOf[0];
651
+ } else {
652
+ fieldData.anyOf = anyOf;
653
+ }
654
+ if (nullable) {
655
+ fieldData.nullable = true;
656
+ }
657
+ } else {
658
+ const inputType = field.inputTypes[0];
659
+ fieldData = this.formatInputTypeData(inputType);
660
+ }
661
+ this.schemaInputTypes.set(fieldType.type.name, {
662
+ ...this.schemaInputTypes.get(fieldType.type.name),
663
+ [field.name]: fieldData
664
+ });
665
+ field.inputTypes.forEach((inputType) => {
666
+ if (inputType.kind === "object") {
667
+ this.parseObjectInputType(inputType);
668
+ }
669
+ });
670
+ });
671
+ }
672
+ return { $ref: format_schema_ref_default(fieldType.type.name) };
673
+ }
674
+ return { type: getJSONSchemaScalar(fieldType.type) };
675
+ }
676
+ };
677
+ var json_schema_parser_default = PrismaJsonSchemaParser;
678
+
679
+ // src/swagger/utils/get-models-accessible-routes.ts
680
+ init_esm_shims();
681
+ var getModelsAccessibleRoutes = (modelNames, models, defaultExposeStrategy = "all") => (
682
+ // eslint-disable-next-line unicorn/no-array-reduce
683
+ modelNames.reduce((accumulator, modelName) => {
684
+ if (models?.[modelName]) {
685
+ return {
686
+ ...accumulator,
687
+ [modelName]: get_accessible_routes_default(models[modelName].only, models[modelName].exclude, defaultExposeStrategy)
688
+ };
689
+ }
690
+ return {
691
+ ...accumulator,
692
+ [modelName]: get_accessible_routes_default(void 0, void 0, defaultExposeStrategy)
693
+ };
694
+ }, {})
695
+ );
696
+ var get_models_accessible_routes_default = getModelsAccessibleRoutes;
697
+
698
+ // src/swagger/utils/get-swagger-paths.ts
699
+ init_esm_shims();
700
+
701
+ // src/swagger/parameters.ts
702
+ init_esm_shims();
703
+ var queryParameters = {
704
+ distinct: {
705
+ description: "Fields to distinctively retrieve",
706
+ name: "distinct",
707
+ schema: {
708
+ type: "string"
709
+ }
710
+ },
711
+ include: {
712
+ description: "Include relations, same as select",
713
+ name: "include",
714
+ schema: {
715
+ type: "string"
716
+ }
717
+ },
718
+ limit: {
719
+ description: "Maximum number of elements to retrieve",
720
+ name: "limit",
721
+ schema: {
722
+ minimum: 0,
723
+ type: "integer"
724
+ }
725
+ },
726
+ orderBy: {
727
+ description: 'Field on which to order by a direction. See <a href="https://next-crud.js.org/query-params#orderBy">the docs</a>',
728
+ name: "orderBy",
729
+ schema: {
730
+ type: "string"
731
+ }
732
+ },
733
+ page: {
734
+ description: "Page number. Use only for pagination.",
735
+ name: "page",
736
+ schema: {
737
+ minimum: 1,
738
+ type: "integer"
739
+ }
740
+ },
741
+ select: {
742
+ description: "Fields to select. For nested fields, chain them separated with a dot, eg: user.posts",
743
+ name: "select",
744
+ schema: {
745
+ type: "string"
746
+ }
747
+ },
748
+ skip: {
749
+ description: "Number of rows to skip",
750
+ name: "skip",
751
+ schema: {
752
+ minimum: 0,
753
+ type: "integer"
754
+ }
755
+ },
756
+ where: {
757
+ description: 'Fields to filter. See <a href="https://next-crud.js.org/query-params#where">the docs</a>',
758
+ name: "where",
759
+ schema: {
760
+ type: "string"
761
+ }
762
+ }
763
+ };
764
+ var commonQueryParameters = [queryParameters.select, queryParameters.include];
765
+ var listQueryParameters = [
766
+ ...commonQueryParameters,
767
+ queryParameters.limit,
768
+ queryParameters.skip,
769
+ queryParameters.where,
770
+ queryParameters.orderBy,
771
+ queryParameters.page,
772
+ queryParameters.distinct
773
+ ];
774
+ var getQueryParameters = (routeType, additionalQueryParameters = []) => {
775
+ if (routeType === "READ_ALL" /* READ_ALL */) {
776
+ return [...listQueryParameters, ...additionalQueryParameters].filter(Boolean);
777
+ }
778
+ return [...commonQueryParameters, ...additionalQueryParameters].filter(Boolean);
779
+ };
780
+
781
+ // src/swagger/utils/format-example-ref.ts
782
+ init_esm_shims();
783
+ var formatExampleReference = (schemaName) => `#/components/examples/${schemaName}`;
784
+ var format_example_ref_default = formatExampleReference;
785
+
786
+ // src/swagger/utils/get-swagger-paths.ts
787
+ var generateContentForSchema = (schemaName, isArray) => {
788
+ if (isArray) {
789
+ return {
790
+ items: {
791
+ $ref: format_schema_ref_default(schemaName)
792
+ },
793
+ type: "array"
794
+ };
795
+ }
796
+ return {
797
+ $ref: format_schema_ref_default(schemaName)
798
+ };
799
+ };
800
+ var generateSwaggerResponse = (routeType, modelName) => {
801
+ if (routeType === "CREATE" /* CREATE */) {
802
+ return {
803
+ content: {
804
+ content: {
805
+ "application/json": {
806
+ example: format_example_ref_default(modelName),
807
+ schema: generateContentForSchema(modelName)
808
+ }
809
+ },
810
+ description: `${modelName} created`
811
+ },
812
+ statusCode: 201
813
+ };
814
+ }
815
+ if (routeType === "DELETE" /* DELETE */) {
816
+ return {
817
+ content: {
818
+ content: {
819
+ "application/json": {
820
+ example: format_example_ref_default(modelName),
821
+ schema: generateContentForSchema(modelName)
822
+ }
823
+ },
824
+ description: `${modelName} item deleted`
825
+ },
826
+ statusCode: 200
827
+ };
828
+ }
829
+ if (routeType === "READ_ALL" /* READ_ALL */) {
830
+ return {
831
+ content: {
832
+ content: {
833
+ "application/json": {
834
+ examples: {
835
+ Default: {
836
+ $ref: format_example_ref_default(`${modelName}s`)
837
+ },
838
+ Pagination: {
839
+ $ref: format_example_ref_default(`${modelName}Page`)
840
+ }
841
+ },
842
+ schema: {
843
+ oneOf: [generateContentForSchema(modelName, true), generateContentForSchema(`${modelName}Page`, false)]
844
+ }
845
+ }
846
+ },
847
+ description: `${modelName} list retrieved`
848
+ },
849
+ statusCode: 200
850
+ };
851
+ }
852
+ if (routeType === "READ_ONE" /* READ_ONE */) {
853
+ return {
854
+ content: {
855
+ content: {
856
+ "application/json": {
857
+ example: format_example_ref_default(modelName),
858
+ schema: generateContentForSchema(modelName)
859
+ }
860
+ },
861
+ description: `${modelName} item retrieved`
862
+ },
863
+ statusCode: 200
864
+ };
865
+ }
866
+ if (routeType === "UPDATE" /* UPDATE */) {
867
+ return {
868
+ content: {
869
+ content: {
870
+ "application/json": {
871
+ example: format_example_ref_default(modelName),
872
+ schema: generateContentForSchema(modelName)
873
+ }
874
+ },
875
+ description: `${modelName} item updated`
876
+ },
877
+ statusCode: 200
878
+ };
879
+ }
880
+ return void 0;
881
+ };
882
+ var generateRequestBody = (schemaStartName, modelName) => {
883
+ return {
884
+ content: {
885
+ "application/json": {
886
+ schema: {
887
+ $ref: format_schema_ref_default(`${schemaStartName}${modelName}`)
888
+ }
889
+ }
890
+ }
891
+ };
892
+ };
893
+ var getRouteTypeMethod = (routeType) => {
894
+ switch (routeType) {
895
+ case "CREATE" /* CREATE */: {
896
+ return "post";
897
+ }
898
+ case "DELETE" /* DELETE */: {
899
+ return "delete";
900
+ }
901
+ case "READ_ALL" /* READ_ALL */:
902
+ case "READ_ONE" /* READ_ONE */: {
903
+ return "get";
904
+ }
905
+ case "UPDATE" /* UPDATE */: {
906
+ return "put";
907
+ }
908
+ default: {
909
+ throw new TypeError(`Method for route type ${routeType} was not found.`);
910
+ }
911
+ }
912
+ };
913
+ var generateSwaggerPathObject = ({
914
+ hasId,
915
+ modelName,
916
+ modelsConfig,
917
+ routeTypes,
918
+ tag
919
+ }) => {
920
+ const methods = {};
921
+ routeTypes.forEach((routeType) => {
922
+ if (routeTypes.includes(routeType)) {
923
+ const returnType = modelsConfig?.[modelName]?.routeTypes?.[routeType]?.response.name ?? modelsConfig?.[modelName]?.type?.name ?? modelName;
924
+ const method = getRouteTypeMethod(routeType);
925
+ const response = generateSwaggerResponse(routeType, returnType);
926
+ if (response === void 0) {
927
+ throw new TypeError(`Route type ${routeType}; response config was not found.`);
928
+ }
929
+ methods[method] = {
930
+ parameters: getQueryParameters(routeType).map((queryParameter) => {
931
+ return { ...queryParameter, in: "query" };
932
+ }),
933
+ responses: {
934
+ [response.statusCode]: response.content,
935
+ ...modelsConfig?.[modelName]?.routeTypes?.[routeType]?.responses
936
+ },
937
+ summary: modelsConfig?.[modelName]?.routeTypes?.[routeType]?.summary,
938
+ tags: [tag]
939
+ };
940
+ if (hasId) {
941
+ methods[method].parameters.push({
942
+ description: `ID of the ${modelName}`,
943
+ in: "path",
944
+ name: "id",
945
+ required: true,
946
+ schema: {
947
+ type: "string"
948
+ }
949
+ });
950
+ }
951
+ if (routeType === "UPDATE" /* UPDATE */) {
952
+ methods[method].requestBody = generateRequestBody("Update", returnType);
953
+ } else if (routeType === "CREATE" /* CREATE */) {
954
+ methods[method].requestBody = generateRequestBody("Create", returnType);
955
+ }
956
+ }
957
+ });
958
+ return methods;
959
+ };
960
+ var getSwaggerPaths = ({ models, modelsConfig, routes, routesMap }) => (
961
+ // eslint-disable-next-line unicorn/no-array-reduce
962
+ Object.keys(routes).reduce((accumulator, value) => {
963
+ const routeTypes = routes[value];
964
+ const resourceName = models?.[value]?.name ? models[value].name : routesMap?.[value] ?? value;
965
+ const tag = modelsConfig?.[value]?.tag.name ?? value;
966
+ if (routeTypes.includes("CREATE" /* CREATE */) || routeTypes.includes("READ_ALL" /* READ_ALL */)) {
967
+ const path = `/${resourceName}`;
968
+ const routeTypesToUse = ["READ_ALL" /* READ_ALL */, "CREATE" /* CREATE */].filter((routeType) => routeTypes.includes(routeType));
969
+ accumulator[path] = generateSwaggerPathObject({
970
+ modelName: value,
971
+ modelsConfig,
972
+ routeTypes: routeTypesToUse,
973
+ tag
974
+ });
975
+ }
976
+ if (routeTypes.includes("READ_ONE" /* READ_ONE */) || routeTypes.includes("UPDATE" /* UPDATE */) || routeTypes.includes("DELETE" /* DELETE */)) {
977
+ const path = `/${resourceName}/{id}`;
978
+ const routeTypesToUse = ["READ_ONE" /* READ_ONE */, "UPDATE" /* UPDATE */, "DELETE" /* DELETE */].filter((routeType) => routeTypes.includes(routeType));
979
+ accumulator[path] = generateSwaggerPathObject({
980
+ hasId: true,
981
+ modelName: value,
982
+ modelsConfig,
983
+ routeTypes: routeTypesToUse,
984
+ tag
985
+ });
986
+ }
987
+ return accumulator;
988
+ }, {})
989
+ );
990
+ var get_swagger_paths_default = getSwaggerPaths;
991
+
992
+ // src/swagger/utils/get-swagger-tags.ts
993
+ init_esm_shims();
994
+ var getSwaggerTags = (modelNames, modelsConfig) => modelNames.map((modelName) => {
995
+ if (modelsConfig?.[modelName]?.tag) {
996
+ return modelsConfig[modelName].tag;
997
+ }
998
+ return {
999
+ name: modelName
1000
+ };
1001
+ });
1002
+ var get_swagger_tags_default = getSwaggerTags;
1003
+
1004
+ // src/swagger/adapter/prisma/index.ts
1005
+ var overwritePathsExampleWithModel = (swaggerPaths, examples) => {
1006
+ Object.values(swaggerPaths).forEach((pathSpec) => {
1007
+ Object.values(pathSpec).forEach((methodSpec) => {
1008
+ if (typeof methodSpec.responses === "object") {
1009
+ Object.values(methodSpec.responses).forEach((responseSpec) => {
1010
+ if (typeof responseSpec.content === "object") {
1011
+ Object.values(responseSpec.content).forEach(
1012
+ (contentSpec) => {
1013
+ if (typeof contentSpec.example === "string") {
1014
+ const example = contentSpec.example.replace("#/components/examples/", "");
1015
+ if (examples[example]?.value !== void 0) {
1016
+ contentSpec.example = examples[example].value;
1017
+ }
1018
+ }
1019
+ }
1020
+ );
1021
+ }
1022
+ });
1023
+ }
1024
+ });
1025
+ });
1026
+ return swaggerPaths;
1027
+ };
1028
+ var modelsToOpenApi = async ({
1029
+ crud = { models: {} },
1030
+ defaultExposeStrategy = "all",
1031
+ models: ctorModels,
1032
+ prismaClient,
1033
+ swagger = { allowedMediaTypes: { "application/json": true }, models: {} }
1034
+ }) => {
1035
+ let dmmf;
1036
+ let prismaDmmfModels;
1037
+ if (prismaClient._dmmf !== void 0) {
1038
+ dmmf = prismaClient._dmmf;
1039
+ prismaDmmfModels = dmmf?.mappingsMap;
1040
+ } else if (prismaClient._getDmmf !== void 0) {
1041
+ dmmf = await prismaClient._getDmmf();
1042
+ prismaDmmfModels = dmmf.mappingsMap;
1043
+ }
1044
+ if (dmmf === void 0) {
1045
+ throw new TypeError("Couldn't get prisma client models");
1046
+ }
1047
+ const parser = new json_schema_parser_default(dmmf);
1048
+ const definitions = parser.parseModels();
1049
+ const dModels = Object.keys(definitions);
1050
+ const schema = JSON.stringify({
1051
+ ...definitions,
1052
+ ...parser.parseInputTypes(dModels),
1053
+ ...parser.getPaginationDataSchema(),
1054
+ ...parser.getPaginatedModelsSchemas(dModels)
1055
+ });
1056
+ if (ctorModels !== void 0) {
1057
+ ctorModels.forEach((model) => {
1058
+ if (!Object.keys(prismaDmmfModels).includes(model)) {
1059
+ throw new Error(`Model name ${model} is invalid.`);
1060
+ }
1061
+ });
1062
+ }
1063
+ const models = ctorModels ?? Object.keys(prismaDmmfModels);
1064
+ const swaggerRoutes = get_models_accessible_routes_default(models, crud.models, defaultExposeStrategy);
1065
+ const swaggerTags = get_swagger_tags_default(models, swagger.models);
1066
+ const swaggerPaths = get_swagger_paths_default({
1067
+ models: crud.models,
1068
+ modelsConfig: swagger.models,
1069
+ routes: swaggerRoutes,
1070
+ routesMap: models_to_route_names_default(prismaDmmfModels, models)
1071
+ });
1072
+ const schemas = JSON.parse(schema.replaceAll("#/definitions", "#/components/schemas"));
1073
+ const examples = parser.getExampleModelsSchemas(dModels, schemas);
1074
+ return {
1075
+ examples,
1076
+ paths: overwritePathsExampleWithModel(swaggerPaths, examples),
1077
+ schemas,
1078
+ tags: swaggerTags
1079
+ };
1080
+ };
1081
+ var prisma_default = modelsToOpenApi;
1082
+
1083
+ export { PrismaAdapter, prisma_default as modelsToOpenApi };
1084
+ //# sourceMappingURL=index.mjs.map
3
1085
  //# sourceMappingURL=index.mjs.map