@m1212e/rumble 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/index.cjs +6 -6
- package/index.cjs.map +1 -1
- package/index.d.cts +45 -16
- package/index.d.ts +45 -16
- package/index.js +6 -6
- package/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
@@ -63,6 +63,20 @@ abilityBuilder.posts
|
|
63
63
|
|
64
64
|
```
|
65
65
|
|
66
|
+
### Application level filters
|
67
|
+
In some cases you can't implement all your checks via a database query filter. Say, for example, you want to query an external api which handles your authorization, before you return the data to the user. This can be done with application layer filters. They can be set very similar to abilities:
|
68
|
+
```ts
|
69
|
+
abilityBuilder.users.filter("read").by(({ context, entities }) => {
|
70
|
+
// const allowed = await queryExternalAuthorizationService(context.user, entities);
|
71
|
+
|
72
|
+
// we could filter the list to only return the entities the user is allowed to see
|
73
|
+
// event mapping to prevent leakage of certain fields is possible
|
74
|
+
return entities;
|
75
|
+
});
|
76
|
+
```
|
77
|
+
The default implementation helpers automatically respect and call the filters, if you set any. Filters work in addition to abilities. They run on the completed query, which in most cases has had an ability applied, hence abilities have higher priority than filters.
|
78
|
+
|
79
|
+
|
66
80
|
### Applying abilities
|
67
81
|
As you might have noticed, abilities resolve around drizzle query filters. This means, that we can use them to query the database with filters applied that directly restrict what the user is allowed to see, update and retrieve.
|
68
82
|
```ts
|
@@ -81,6 +95,18 @@ schemaBuilder.queryFields((t) => {
|
|
81
95
|
});
|
82
96
|
```
|
83
97
|
|
98
|
+
#### Applying filters
|
99
|
+
Applying filters on objects is done automatically if you use the helpers. If you manually implement an object ref, you can use the `applyFilters` config field to ensure the filters run as expected:
|
100
|
+
```ts
|
101
|
+
const PostRef = schemaBuilder.drizzleObject("posts", {
|
102
|
+
name: "Post",
|
103
|
+
// apply the application level filters
|
104
|
+
applyFilters: abilityBuilder.registeredFilters.posts.read,
|
105
|
+
fields: (t) => ({
|
106
|
+
...
|
107
|
+
```
|
108
|
+
To apply filters in a custom handler implementation, like e.g. your mutations, you can use the `applyFilters` helper exported by rumble to easily filter a list of entities.
|
109
|
+
|
84
110
|
## Context & Configuration
|
85
111
|
The `rumble` initiator offers various configuration options which you can pass. Most importantly, the `context` provider function which creates the request context that is passed to your abilities and resolvers.
|
86
112
|
```ts
|
package/index.cjs
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
'use strict';var graphqlYoga=require('graphql-yoga'),drizzleOrm=require('drizzle-orm'),casing=require('drizzle-orm/casing'),
|
2
|
-
`,
|
3
|
-
`)}function
|
1
|
+
'use strict';var graphqlYoga=require('graphql-yoga'),drizzleOrm=require('drizzle-orm'),casing=require('drizzle-orm/casing'),be=require('@pothos/core'),Se=require('@pothos/plugin-drizzle'),Re=require('@pothos/plugin-smart-subscriptions'),graphqlScalars=require('graphql-scalars');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var be__default=/*#__PURE__*/_interopDefault(be);var Se__default=/*#__PURE__*/_interopDefault(Se);var Re__default=/*#__PURE__*/_interopDefault(Re);function O(e){return typeof e=="object"&&e!==null}function w(e,t){throw new Error("Unexpected invariant triggered.")}var oe=/\r\n|[\n\r]/g;function I(e,t){let c=0,p=1;for(let n of e.body.matchAll(oe)){if(typeof n.index=="number"||w(),n.index>=t)break;c=n.index+n[0].length,p+=1;}return {line:p,column:t+1-c}}function k(e){return L(e.source,I(e.source,e.start))}function L(e,t){let c=e.locationOffset.column-1,p="".padStart(c)+e.body,n=t.line-1,y=e.locationOffset.line-1,u=t.line+y,a=t.line===1?c:0,r=t.column+a,l=`${e.name}:${u}:${r}
|
2
|
+
`,i=p.split(/\r\n|[\n\r]/g),f=i[n];if(f.length>120){let o=Math.floor(r/80),b=r%80,m=[];for(let x=0;x<f.length;x+=80)m.push(f.slice(x,x+80));return l+Q([[`${u} |`,m[0]],...m.slice(1,o+1).map(x=>["|",x]),["|","^".padStart(b)],["|",m[o+1]]])}return l+Q([[`${u-1} |`,i[n-1]],[`${u} |`,f],["|","^".padStart(r)],[`${u+1} |`,i[n+1]]])}function Q(e){let t=e.filter(([p,n])=>n!==void 0),c=Math.max(...t.map(([p])=>p.length));return t.map(([p,n])=>p.padStart(c)+(n?" "+n:"")).join(`
|
3
|
+
`)}function ie(e){let t=e[0];return t==null||"kind"in t||"length"in t?{nodes:t,source:e[1],positions:e[2],path:e[3],originalError:e[4],extensions:e[5]}:t}var P=class e extends Error{constructor(t,...c){var p,n,y;let{nodes:u,source:a,positions:r,path:l,originalError:i,extensions:f}=ie(c);super(t),this.name="GraphQLError",this.path=l??void 0,this.originalError=i??void 0,this.nodes=G(Array.isArray(u)?u:u?[u]:void 0);let o=G((p=this.nodes)===null||p===void 0?void 0:p.map(m=>m.loc).filter(m=>m!=null));this.source=a??(o==null||(n=o[0])===null||n===void 0?void 0:n.source),this.positions=r??o?.map(m=>m.start),this.locations=r&&a?r.map(m=>I(a,m)):o?.map(m=>I(m.source,m.start));let b=O(i?.extensions)?i?.extensions:void 0;this.extensions=(y=f??b)!==null&&y!==void 0?y:Object.create(null),Object.defineProperties(this,{message:{writable:true,enumerable:true},name:{enumerable:false},nodes:{enumerable:false},source:{enumerable:false},positions:{enumerable:false},originalError:{enumerable:false}}),i!=null&&i.stack?Object.defineProperty(this,"stack",{value:i.stack,writable:true,configurable:true}):Error.captureStackTrace?Error.captureStackTrace(this,e):Object.defineProperty(this,"stack",{value:Error().stack,writable:true,configurable:true});}get[Symbol.toStringTag](){return "GraphQLError"}toString(){let t=this.message;if(this.nodes)for(let c of this.nodes)c.loc&&(t+=`
|
4
4
|
|
5
|
-
`+
|
5
|
+
`+k(c.loc));else if(this.source&&this.locations)for(let c of this.locations)t+=`
|
6
6
|
|
7
|
-
`+U(this.source,c);return t}toJSON(){let t={message:this.message};return this.locations!=null&&(t.locations=this.locations),this.path!=null&&(t.path=this.path),this.extensions!=null&&Object.keys(this.extensions).length>0&&(t.extensions=this.extensions),t}};function Q(e){return e===void 0||e.length===0?void 0:e}var S=class extends Error{constructor(t){super(t),this.name="RumbleError";}},B=class extends P{};var v=(e,t)=>new S(`RumbleError: Unknown SQL type '${e}'. Please open an issue (https://github.com/m1212e/rumble/issues) so it can be added. (${t})`);function k(e){if(["serial","int","integer","tinyint","smallint","mediumint"].includes(e))return {value1:1,value2:2};if(["real","decimal","double","float"].includes(e))return {value1:1.1,value2:2.2};if(["string","text","varchar","char","text(256)"].includes(e))return {value1:"a",value2:"b"};if(["uuid"].includes(e))return {value1:"fba31870-5528-42d7-b27e-2e5ee657aea5",value2:"fc65db81-c2d1-483d-8a25-a30e2cf6e02d"};if(["boolean"].includes(e))return {value1:true,value2:false};if(["timestamp","datetime"].includes(e))return {value1:new Date(2022,1,1),value2:new Date(2022,1,2)};if(["date"].includes(e))return {value1:new Date(2022,1,1),value2:new Date(2022,1,2)};if(["json"].includes(e))return {value1:{a:1},value2:{b:2}};throw v(e,"Distinct")}function oe(e){return typeof e!="function"}function ie(e){return typeof e=="function"&&e.constructor.name!=="AsyncFunction"}var G=({db:e})=>{let t=e._.schema,c={},p={},n=a=>({allow:i=>{let u=p[a];u||(u={},p[a]=u);let o=Array.isArray(i)?i:[i];for(let s of o){let r=u[s];r||(r="wildcard",u[s]=r);}return {when:s=>{for(let r of o)u[r]==="wildcard"&&(u[r]=[]),u[r].push(s);}}}});for(let a of Object.keys(e.query))c[a]=n(a);return {...c,registeredConditions:p,buildWithUserContext:a=>{let i={},u=o=>({filter:(s,r)=>{let m=p[o];m||(m={});let f=m[s];if(f==="wildcard")return {single:{where:r?.inject?.where,columns:r?.inject?.columns},many:{where:r?.inject?.where,columns:r?.inject?.columns,limit:r?.inject?.limit}};let T=()=>{let g=t[o].primaryKey.at(0);if(!g)throw new S(`No primary key found for entity ${o.toString()}`);let D=k(g.getSQLType());return {where:drizzleOrm.and(drizzleOrm.eq(g,D.value1),drizzleOrm.eq(g,D.value2))}};(!m||!f)&&(f=[T()]);let l=f.filter(oe),x=f.filter(ie).map(g=>g(a)),h=[...l,...x];h.filter(g=>g!==void 0).length===0&&h.push(T());let y;for(let g of h)g?.limit&&(y===void 0||g.limit>y)&&(y=g.limit);r?.inject?.limit&&y<r.inject.limit&&(y=r.inject.limit);let d;for(let g of [...h,r?.inject??{}])g?.columns&&(d===void 0?d=g.columns:d={...d,...g.columns});let b=h.filter(g=>g?.where).map(g=>g?.where),C=b.length>0?drizzleOrm.or(...b):void 0;return r?.inject?.where&&(C=C?drizzleOrm.and(C,r.inject.where):r.inject.where),{single:{where:C,columns:d},many:{where:C,columns:d,limit:y}}}});for(let o of Object.keys(e.query))i[o]=u(o);return i}}};var _=({context:e,abilityBuilder:t})=>async c=>{let p=e?await e(c):{};return {...p,abilities:t.buildWithUserContext(p)}};function R(e){return String(e).charAt(0).toUpperCase()+String(e).slice(1)}function I(e){let t=E(e);return t.enumValues!==void 0&&t.enumName!==void 0&&typeof t.enumName=="string"&&Array.isArray(t.enumValues)}function E(e){return e.enum??e}var V=({db:e,schemaBuilder:t})=>{let c=new Map;return ({enumVariableName:n,name:a,enumValues:i,enumName:u})=>{let o=e._.fullSchema,s;if(n?s=o[n]:i?s=Object.values(o).filter(I).map(E).find(T=>T.enumValues===i):u&&(s=Object.values(o).filter(I).map(E).find(T=>T.enumName===u)),!s)throw new S(`Could not determine enum structure! (${String(n)}, ${i}, ${u})`);let r=a??`${R(casing.toCamelCase(s.enumName.toString()))}Enum`,m=c.get(r);return m||(m=t.enumType(r,{values:s.enumValues}),c.set(r,m),m)}};function N(e){let t;if(["serial","int","integer","tinyint","smallint","mediumint"].includes(e)&&(t="Int"),["real","decimal","double","float"].includes(e)&&(t="Float"),["string","text","varchar","char","text(256)"].includes(e)&&(t="String"),["uuid"].includes(e)&&(t="ID"),["boolean"].includes(e)&&(t="Boolean"),["timestamp","datetime"].includes(e)&&(t="DateTime"),["date"].includes(e)&&(t="Date"),["json"].includes(e)&&(t="JSON"),t!==void 0)return t;throw v(e,"SQL to GQL")}var ae="RUMBLE_SUBSCRIPTION_NOTIFICATION",ue="REMOVED",me="UPDATED",le="CREATED",$=({subscriptions:e,db:t})=>{let c=e?graphqlYoga.createPubSub(...e):graphqlYoga.createPubSub();return {pubsub:c,makePubSubInstance:({tableName:n})=>{function a({action:i,tableName:u,primaryKeyValue:o}){let s;switch(i){case "created":s=le;break;case "removed":s=ue;break;case "updated":s=me;break;default:throw new Error(`Unknown action: ${i}`)}return `${ae}/${u}${o?`/${o}`:""}/${s}`}return {registerOnInstance({instance:i,action:u,primaryKeyValue:o}){let s=a({tableName:n.toString(),action:u,primaryKeyValue:o});i.register(s);},created(){let i=a({tableName:n.toString(),action:"created"});return c.publish(i)},removed(i){let u=a({tableName:n.toString(),action:"removed"});return c.publish(u)},updated(i){let o=(Array.isArray(i)?i:[i]).map(r=>a({tableName:n.toString(),action:"updated",primaryKeyValue:r})),s=Array.from(new Set(o));for(let r of s)c.publish(r);}}}}};var M=({db:e,schemaBuilder:t,makePubSubInstance:c,argImplementer:p,enumImplementer:n})=>({tableName:a,name:i,readAction:u="read"})=>{let o=e._.schema[a];if(!o)throw new S(`Could not find schema for ${a.toString()} (object)`);let s=o.primaryKey.at(0)?.name;s||console.warn(`Could not find primary key for ${a.toString()}. Cannot register subscriptions!`);let{registerOnInstance:r}=c({tableName:a});return t.drizzleObject(a,{name:i??R(a.toString()),subscribe:(m,f,T)=>{if(!s)return;let l=f[s];if(!l){console.warn(`Could not find primary key value for ${JSON.stringify(f)}. Cannot register subscription!`);return}r({instance:m,action:"updated",primaryKeyValue:l});},fields:m=>{let f=(x,h,y)=>{let d=N(x);switch(d){case "Int":return m.exposeInt(h,{nullable:y});case "String":return m.exposeString(h,{nullable:y});case "Boolean":return m.exposeBoolean(h,{nullable:y});case "Date":return m.field({type:"Date",resolve:b=>b[h],nullable:y});case "DateTime":return m.field({type:"DateTime",resolve:b=>b[h],nullable:y});case "Float":return m.exposeFloat(h,{nullable:y});case "ID":return m.exposeID(h,{nullable:y});case "JSON":return m.field({type:"JSON",resolve:b=>b[h],nullable:y});default:throw new S(`Unsupported object type ${d} for column ${h}`)}},T=Object.entries(o.columns).reduce((x,[h,y])=>{if(I(y)){let d=E(y),b=n({enumName:d.enumName});x[h]=m.field({type:b,resolve:C=>C[h],nullable:!y.notNull});}else x[h]=f(y.getSQLType(),h,!y.notNull);return x},{}),l=Object.entries(o.relations).reduce((x,[h,y])=>{let {inputType:d,transformArgumentToQueryCondition:b}=p({tableName:y.referencedTableName,nativeTableName:y.referencedTableName}),C=false,D="many";return y instanceof drizzleOrm.One&&(C=!y.isNullable,D="single"),x[h]=m.relation(h,{args:{where:m.arg({type:d,required:false})},nullable:C,query:(H,X)=>X.abilities[y.referencedTableName].filter(u,{inject:{where:b(H.where)}})[D]}),x},{});return {...T,...l}}})};var L=e=>{if(!e)throw new B("Value not found but required (findFirst)");return e},pe=e=>{let t=e.at(0);if(!t)throw new B("Value not found but required (firstEntry)");return t};var W=({db:e,schemaBuilder:t,argImplementer:c,makePubSubInstance:p})=>({tableName:n,readAction:a="read",listAction:i="read"})=>{let u=e._.schema[n];if(!u)throw new S(`Could not find schema for ${n.toString()} (query)`);u.primaryKey.at(0)?.name||console.warn(`Could not find primary key for ${n.toString()}. Cannot register subscriptions!`);let{inputType:s,transformArgumentToQueryCondition:r}=c({tableName:n}),{registerOnInstance:m}=p({tableName:n});return t.queryFields(f=>({[`findMany${R(n.toString())}`]:f.drizzleField({type:[n],nullable:false,smartSubscription:true,subscribe:(T,l,x,h,y)=>{m({instance:T,action:"created"}),m({instance:T,action:"removed"});},args:{where:f.arg({type:s,required:false})},resolve:(T,l,x,h,y)=>{let d=h.abilities[n].filter(i,{inject:{where:r(x.where)}}).many,b=T(d);return d.columns&&(b.columns=d.columns),e.query[n].findMany(b)}}),[`findFirst${R(n.toString())}`]:f.drizzleField({type:n,nullable:false,smartSubscription:true,args:{where:f.arg({type:s,required:false})},resolve:(T,l,x,h,y)=>{let d=h.abilities[n].filter(a,{inject:{where:r(x.where)}}).single,b=T(d);return d.columns&&(b.columns=d.columns),e.query[n].findFirst(b).then(L)}})}))};var J=({db:e,disableDefaultObjects:t,pubsub:c,pothosConfig:p})=>{let n=new de__default.default({plugins:[ye__default.default,fe__default.default,...p?.plugins??[]],...p,drizzle:{client:e},smartSubscriptions:{...fe.subscribeOptionsFromIterator((a,i)=>c.subscribe(a))}});return n.addScalarType("JSON",graphqlScalars.JSONResolver),n.addScalarType("Date",graphqlScalars.DateResolver),n.addScalarType("DateTime",graphqlScalars.DateTimeISOResolver),t?.query||n.queryType({}),t?.subscription||n.subscriptionType({}),t?.mutation||n.mutationType({}),{schemaBuilder:n}};var Re=e=>`${R(casing.toCamelCase(e.toString()))}WhereInputArgument`,Y=({db:e,schemaBuilder:t,enumImplementer:c})=>{let p=new Map,n=({tableName:a,name:i,nativeTableName:u})=>{let o=e._.schema[a];if(u){let f=Object.values(e._.schema).find(T=>T.dbName===u);f&&(o=f);}if(!o)throw new S(`Could not find schema for ${a.toString()} (whereArg)`);let s=i??Re(o.dbName),r=p.get(s);return r||(r={inputType:t.inputType(s,{fields:l=>{let x=d=>{let b=N(d);switch(b){case "Int":return l.int({required:false});case "String":return l.string({required:false});case "Boolean":return l.boolean({required:false});case "Date":return l.field({type:"Date",required:false});case "DateTime":return l.field({type:"DateTime",required:false});case "Float":return l.float({required:false});case "ID":return l.id({required:false});case "JSON":return l.field({type:"JSON",required:false});default:throw new S(`Unsupported argument type ${b} for column ${d}`)}},h=Object.entries(o.columns).reduce((d,[b,C])=>{if(I(C)){let g=E(C),D=c({enumName:g.enumName});d[b]=l.field({type:D,required:false});}else d[b]=x(C.getSQLType());return d},{}),y=Object.entries(o.relations).reduce((d,[b,C])=>{let g=n({tableName:C.referencedTableName,nativeTableName:C.referencedTableName});return d[b]=l.field({type:g.inputType,required:false}),d},{});return {...h,...y}}}),transformArgumentToQueryCondition:l=>{if(!l)return;let x=d=>{let b=o.columns[d],C=l[d];if(C)return drizzleOrm.eq(b,C)},h=d=>{let b=o.relations[d],C=l[d];if(!C)return;let g=n({tableName:b.referencedTableName,nativeTableName:b.referencedTableName}).transformArgumentToQueryCondition;return g(C)},y=[...Object.keys(o.columns).map(x),...Object.keys(o.relations).map(h)];return drizzleOrm.and(...y)}},p.set(s,r),r)};return n};var Ee=e=>{let t=G(e),c=_({...e,abilityBuilder:t}),{makePubSubInstance:p,pubsub:n}=$({...e}),{schemaBuilder:a}=J({...e,pubsub:n}),i=V({...e,schemaBuilder:a}),u=Y({...e,schemaBuilder:a,enumImplementer:i}),o=M({...e,schemaBuilder:a,makePubSubInstance:p,argImplementer:u,enumImplementer:i}),s=W({...e,schemaBuilder:a,argImplementer:u,makePubSubInstance:p});return {abilityBuilder:t,schemaBuilder:a,createYoga:m=>graphqlYoga.createYoga({...m,schema:a.toSchema(),context:c}),object:o,arg:u,query:s,pubsub:p,enum_:i}};
|
8
|
-
exports.RumbleError=S;exports.RumbleErrorSafe=B;exports.assertFindFirstExists=
|
7
|
+
`+L(this.source,c);return t}toJSON(){let t={message:this.message};return this.locations!=null&&(t.locations=this.locations),this.path!=null&&(t.path=this.path),this.extensions!=null&&Object.keys(this.extensions).length>0&&(t.extensions=this.extensions),t}};function G(e){return e===void 0||e.length===0?void 0:e}var S=class extends Error{constructor(t){super(t),this.name="RumbleError";}},B=class extends P{};var U=(e,t)=>new S(`RumbleError: Unknown SQL type '${e}'. Please open an issue (https://github.com/m1212e/rumble/issues) so it can be added. (${t})`);function j(e){if(["serial","int","integer","tinyint","smallint","mediumint"].includes(e))return {value1:1,value2:2};if(["real","decimal","double","float"].includes(e))return {value1:1.1,value2:2.2};if(["string","text","varchar","char","text(256)"].includes(e))return {value1:"a",value2:"b"};if(["uuid"].includes(e))return {value1:"fba31870-5528-42d7-b27e-2e5ee657aea5",value2:"fc65db81-c2d1-483d-8a25-a30e2cf6e02d"};if(["boolean"].includes(e))return {value1:true,value2:false};if(["timestamp","datetime"].includes(e))return {value1:new Date(2022,1,1),value2:new Date(2022,1,2)};if(["date"].includes(e))return {value1:new Date(2022,1,1),value2:new Date(2022,1,2)};if(["json"].includes(e))return {value1:{a:1},value2:{b:2}};throw U(e,"Distinct")}function le(e){return typeof e!="function"}function pe(e){return typeof e=="function"&&e.constructor.name!=="AsyncFunction"}var K=({db:e,actions:t})=>{let c=e._.schema,p={},n={},y={},u=a=>{for(let r of t)y[a]||(y[a]={}),y[a][r]||(y[a][r]=[]);return {allow:r=>{let l=n[a];l||(l={},n[a]=l);let i=Array.isArray(r)?r:[r];for(let f of i){let o=l[f];o||(o="wildcard",l[f]=o);}return {when:f=>{for(let o of i)l[o]==="wildcard"&&(l[o]=[]),l[o].push(f);}}},filter:r=>{let l=Array.isArray(r)?r:[r];return {by:i=>{for(let f of l)y[a][f].push(i);}}}}};for(let a of Object.keys(e.query))p[a]=u(a);return {...p,registeredConditions:n,registeredFilters:y,buildWithUserContext:a=>{let r={},l=i=>({filter:(f,o)=>{let b=n[i];b||(b={});let m=b[f];if(m==="wildcard")return {single:{where:o?.inject?.where,columns:o?.inject?.columns},many:{where:o?.inject?.where,columns:o?.inject?.columns,limit:o?.inject?.limit}};let x=()=>{let T=c[i].primaryKey.at(0);if(!T)throw new S(`No primary key found for entity ${i.toString()}`);let N=j(T.getSQLType());return {where:drizzleOrm.and(drizzleOrm.eq(T,N.value1),drizzleOrm.eq(T,N.value2))}};(!b||!m)&&(m=[x()]);let C=m.filter(le),g=m.filter(pe).map(T=>T(a)),s=[...C,...g];s.filter(T=>T!==void 0).length===0&&s.push(x());let d;for(let T of s)T?.limit&&(d===void 0||T.limit>d)&&(d=T.limit);o?.inject?.limit&&d<o.inject.limit&&(d=o.inject.limit);let h;for(let T of [...s,o?.inject??{}])T?.columns&&(h===void 0?h=T.columns:h={...h,...T.columns});let R=s.filter(T=>T?.where).map(T=>T?.where),D=R.length>0?drizzleOrm.or(...R):void 0;return o?.inject?.where&&(D=D?drizzleOrm.and(D,o.inject.where):o.inject.where),{single:{where:D,columns:h},many:{where:D,columns:h,limit:d}}},explicitFilters:f=>y[i][f]});for(let i of Object.keys(e.query))r[i]=l(i);return r}}};var $=({context:e,abilityBuilder:t})=>async c=>{let p=e?await e(c):{};return {...p,abilities:t.buildWithUserContext(p)}};function E(e){return String(e).charAt(0).toUpperCase()+String(e).slice(1)}function v(e){let t=A(e);return t.enumValues!==void 0&&t.enumName!==void 0&&typeof t.enumName=="string"&&Array.isArray(t.enumValues)}function A(e){return e.enum??e}var M=({db:e,schemaBuilder:t})=>{let c=new Map;return ({enumVariableName:n,name:y,enumName:u})=>{let a=e._.fullSchema,r;if(n?r=a[n]:u&&(r=Object.values(a).filter(v).map(A).find(o=>o.enumName===u)),!r)throw new S(`Could not determine enum structure! (${String(n)}, ${enumValuesParam}, ${u})`);let l=y??`${E(casing.toCamelCase(r.enumName.toString()))}Enum`,i=c.get(l);return i||(i=t.enumType(l,{values:r.enumValues}),c.set(l,i),i)}};function F(e){let t;if(["serial","int","integer","tinyint","smallint","mediumint"].includes(e)&&(t="Int"),["real","decimal","double","float"].includes(e)&&(t="Float"),["string","text","varchar","char","text(256)"].includes(e)&&(t="String"),["uuid"].includes(e)&&(t="ID"),["boolean"].includes(e)&&(t="Boolean"),["timestamp","datetime"].includes(e)&&(t="DateTime"),["date"].includes(e)&&(t="Date"),["json"].includes(e)&&(t="JSON"),t!==void 0)return t;throw U(e,"SQL to GQL")}var ce="RUMBLE_SUBSCRIPTION_NOTIFICATION",ye="REMOVED",de="UPDATED",fe="CREATED",J=({subscriptions:e,db:t})=>{let c=e?graphqlYoga.createPubSub(...e):graphqlYoga.createPubSub();return {pubsub:c,makePubSubInstance:({tableName:n})=>{function y({action:u,tableName:a,primaryKeyValue:r}){let l;switch(u){case "created":l=fe;break;case "removed":l=ye;break;case "updated":l=de;break;default:throw new Error(`Unknown action: ${u}`)}return `${ce}/${a}${r?`/${r}`:""}/${l}`}return {registerOnInstance({instance:u,action:a,primaryKeyValue:r}){let l=y({tableName:n.toString(),action:a,primaryKeyValue:r});u.register(l);},created(){let u=y({tableName:n.toString(),action:"created"});return c.publish(u)},removed(u){let a=y({tableName:n.toString(),action:"removed"});return c.publish(a)},updated(u){let r=(Array.isArray(u)?u:[u]).map(i=>y({tableName:n.toString(),action:"updated",primaryKeyValue:i})),l=Array.from(new Set(r));for(let i of l)c.publish(i);}}}}};var Y=({db:e,schemaBuilder:t,makePubSubInstance:c,argImplementer:p,enumImplementer:n,abilityBuilder:y})=>({tableName:u,name:a,readAction:r="read"})=>{let l=e._.schema[u];if(!l)throw new S(`Could not find schema for ${u.toString()} (object)`);let i=l.primaryKey.at(0)?.name;i||console.warn(`Could not find primary key for ${u.toString()}. Cannot register subscriptions!`);let{registerOnInstance:f}=c({tableName:u});return t.drizzleObject(u,{name:a??E(u.toString()),subscribe:(o,b,m)=>{if(!i)return;let x=b[i];if(!x){console.warn(`Could not find primary key value for ${JSON.stringify(b)}. Cannot register subscription!`);return}f({instance:o,action:"updated",primaryKeyValue:x});},applyFilters:y?.registeredFilters?.[u]?.[r],fields:o=>{let b=(C,g,s)=>{let d=F(C);switch(d){case "Int":return o.exposeInt(g,{nullable:s});case "String":return o.exposeString(g,{nullable:s});case "Boolean":return o.exposeBoolean(g,{nullable:s});case "Date":return o.field({type:"Date",resolve:h=>h[g],nullable:s});case "DateTime":return o.field({type:"DateTime",resolve:h=>h[g],nullable:s});case "Float":return o.exposeFloat(g,{nullable:s});case "ID":return o.exposeID(g,{nullable:s});case "JSON":return o.field({type:"JSON",resolve:h=>h[g],nullable:s});default:throw new S(`Unsupported object type ${d} for column ${g}`)}},m=Object.entries(l.columns).reduce((C,[g,s])=>{if(v(s)){let d=A(s),h=n({enumName:d.enumName});C[g]=o.field({type:h,resolve:R=>R[g],nullable:!s.notNull});}else C[g]=b(s.getSQLType(),g,!s.notNull);return C},{}),x=Object.entries(l.relations).reduce((C,[g,s])=>{let {inputType:d,transformArgumentToQueryCondition:h}=p({tableName:s.referencedTableName,nativeTableName:s.referencedTableName}),R=false,T="many";return s instanceof drizzleOrm.One&&(R=!s.isNullable,T="single"),C[g]=o.relation(g,{args:{where:o.arg({type:d,required:false})},nullable:R,query:(N,re)=>re.abilities[s.referencedTableName].filter(r,{inject:{where:h(N.where)}})[T]}),C},{});return {...m,...x}}})};var q=e=>{if(!e)throw new B("Value not found but required (findFirst)");return e},ge=e=>{let t=e.at(0);if(!t)throw new B("Value not found but required (firstEntry)");return t},H=async({filters:e,entities:t,context:c})=>(await Promise.all(e.map(p=>p({context:c,entities:t})))).reduce((p,n)=>(p.push(...n),p),[]);var X=({db:e,schemaBuilder:t,argImplementer:c,makePubSubInstance:p})=>({tableName:n,readAction:y="read",listAction:u="read"})=>{let a=e._.schema[n];if(!a)throw new S(`Could not find schema for ${n.toString()} (query)`);a.primaryKey.at(0)?.name||console.warn(`Could not find primary key for ${n.toString()}. Cannot register subscriptions!`);let{inputType:l,transformArgumentToQueryCondition:i}=c({tableName:n}),{registerOnInstance:f}=p({tableName:n});return t.queryFields(o=>({[`findMany${E(n.toString())}`]:o.drizzleField({type:[n],nullable:false,smartSubscription:true,subscribe:(b,m,x,C,g)=>{f({instance:b,action:"created"}),f({instance:b,action:"removed"});},args:{where:o.arg({type:l,required:false})},resolve:(b,m,x,C,g)=>{let s=C.abilities[n].filter(u,{inject:{where:i(x.where)}}).many,d=b(s);return s.columns&&(d.columns=s.columns),e.query[n].findMany(d)}}),[`findFirst${E(n.toString())}`]:o.drizzleField({type:n,nullable:false,smartSubscription:true,args:{where:o.arg({type:l,required:false})},resolve:(b,m,x,C,g)=>{let s=C.abilities[n].filter(y,{inject:{where:i(x.where)}}).single,d=b(s);return s.columns&&(d.columns=s.columns),e.query[n].findFirst(d).then(q)}})}))};var Z="ManualFiltersPlugin",ee=Z,Te="applyFilters",z=class extends be.BasePlugin{wrapResolve(t,c){return async(p,n,y,u)=>{let a=(c?.type).type?.ref.currentConfig.pothosOptions[Te];if(!a||!Array.isArray(a)||a.length===0)return t(p,n,y,u);let r=await t(p,n,y,u),l=Array.isArray(r)?r:[r],i=Array.isArray(a)?a:[a],f=await H({filters:i,entities:l,context:y});return Array.isArray(r)?f:f[0]??null}}};be__default.default.registerPlugin(Z,z);var te=({db:e,disableDefaultObjects:t,pubsub:c,pothosConfig:p})=>{let n=new be__default.default({plugins:[ee,Se__default.default,Re__default.default,...p?.plugins??[]],...p,drizzle:{client:e},smartSubscriptions:{...Re.subscribeOptionsFromIterator((y,u)=>c.subscribe(y))}});return n.addScalarType("JSON",graphqlScalars.JSONResolver),n.addScalarType("Date",graphqlScalars.DateResolver),n.addScalarType("DateTime",graphqlScalars.DateTimeISOResolver),t?.query||n.queryType({}),t?.subscription||n.subscriptionType({}),t?.mutation||n.mutationType({}),{schemaBuilder:n}};var Ne=e=>`${E(casing.toCamelCase(e.toString()))}WhereInputArgument`,ne=({db:e,schemaBuilder:t,enumImplementer:c})=>{let p=new Map,n=({tableName:y,name:u,nativeTableName:a})=>{let r=e._.schema[y];if(a){let o=Object.values(e._.schema).find(b=>b.dbName===a);o&&(r=o);}if(!r)throw new S(`Could not find schema for ${y.toString()} (whereArg)`);let l=u??Ne(r.dbName),i=p.get(l);return i||(i={inputType:t.inputType(l,{fields:m=>{let x=s=>{let d=F(s);switch(d){case "Int":return m.int({required:false});case "String":return m.string({required:false});case "Boolean":return m.boolean({required:false});case "Date":return m.field({type:"Date",required:false});case "DateTime":return m.field({type:"DateTime",required:false});case "Float":return m.float({required:false});case "ID":return m.id({required:false});case "JSON":return m.field({type:"JSON",required:false});default:throw new S(`Unsupported argument type ${d} for column ${s}`)}},C=Object.entries(r.columns).reduce((s,[d,h])=>{if(v(h)){let R=A(h),D=c({enumName:R.enumName});s[d]=m.field({type:D,required:false});}else s[d]=x(h.getSQLType());return s},{}),g=Object.entries(r.relations).reduce((s,[d,h])=>{let R=n({tableName:h.referencedTableName,nativeTableName:h.referencedTableName});return s[d]=m.field({type:R.inputType,required:false}),s},{});return {...C,...g}}}),transformArgumentToQueryCondition:m=>{if(!m)return;let x=s=>{let d=r.columns[s],h=m[s];if(h)return drizzleOrm.eq(d,h)},C=s=>{let d=r.relations[s],h=m[s];if(!h)return;let R=n({tableName:d.referencedTableName,nativeTableName:d.referencedTableName}).transformArgumentToQueryCondition;return R(h)},g=[...Object.keys(r.columns).map(x),...Object.keys(r.relations).map(C)];return drizzleOrm.and(...g)}},p.set(l,i),i)};return n};var Fe=e=>{e.actions||(e.actions=["read","update","delete"]);let t=K(e),c=$({...e,abilityBuilder:t}),{makePubSubInstance:p,pubsub:n}=J({...e}),{schemaBuilder:y}=te({...e,pubsub:n}),u=M({...e,schemaBuilder:y}),a=ne({...e,schemaBuilder:y,enumImplementer:u}),r=Y({...e,schemaBuilder:y,makePubSubInstance:p,argImplementer:a,enumImplementer:u,abilityBuilder:t}),l=X({...e,schemaBuilder:y,argImplementer:a,makePubSubInstance:p});return {abilityBuilder:t,schemaBuilder:y,createYoga:f=>graphqlYoga.createYoga({...f,schema:y.toSchema(),context:c}),object:r,arg:a,query:l,pubsub:p,enum_:u}};
|
8
|
+
exports.RumbleError=S;exports.RumbleErrorSafe=B;exports.assertFindFirstExists=q;exports.assertFirstEntryExists=ge;exports.rumble=Fe;//# sourceMappingURL=index.cjs.map
|
9
9
|
//# sourceMappingURL=index.cjs.map
|