@m1212e/rumble 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -22
- package/index.cjs +6 -6
- package/index.cjs.map +1 -1
- package/index.d.cts +180 -133
- package/index.d.ts +180 -133
- package/index.js +6 -6
- package/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
@@ -49,7 +49,7 @@ Condition object abilities allow a thing under a certain, fixed condition which
|
|
49
49
|
```ts
|
50
50
|
// everyone can read published posts
|
51
51
|
abilityBuilder.posts.allow("read").when({
|
52
|
-
where:
|
52
|
+
where: { published: true },
|
53
53
|
});
|
54
54
|
```
|
55
55
|
|
@@ -59,7 +59,7 @@ Condition functions are functions that return condition objects. They are called
|
|
59
59
|
// only the author can update posts
|
60
60
|
abilityBuilder.posts
|
61
61
|
.allow(["update", "delete"])
|
62
|
-
.when(({ userId }) => ({ where:
|
62
|
+
.when(({ userId }) => ({ where: { authorId: userId } }));
|
63
63
|
|
64
64
|
```
|
65
65
|
|
@@ -74,7 +74,7 @@ abilityBuilder.users.filter("read").by(({ context, entities }) => {
|
|
74
74
|
return entities;
|
75
75
|
});
|
76
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.
|
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. If you need to apply a filter to a manually implemented object, please use the `applyFilters` config field as shown in the example project.
|
78
78
|
|
79
79
|
|
80
80
|
### Applying abilities
|
@@ -87,7 +87,7 @@ schemaBuilder.queryFields((t) => {
|
|
87
87
|
resolve: (query, root, args, ctx, info) => {
|
88
88
|
return db.query.posts.findMany(
|
89
89
|
// here we apply our filter
|
90
|
-
query(ctx.abilities.posts.filter("read").many),
|
90
|
+
query(ctx.abilities.posts.filter("read").query.many),
|
91
91
|
);
|
92
92
|
},
|
93
93
|
}),
|
@@ -95,6 +95,8 @@ schemaBuilder.queryFields((t) => {
|
|
95
95
|
});
|
96
96
|
```
|
97
97
|
|
98
|
+
> The `filter()` call returns an object with `query` and `sql` fields. Depending on if you are using the drizzle query or and SQL based API (like update or delete), you need to apply different filters. Same goes for the `query.many` and `query.single` fields.
|
99
|
+
|
98
100
|
#### Applying filters
|
99
101
|
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
102
|
```ts
|
@@ -120,7 +122,7 @@ rumble({
|
|
120
122
|
},
|
121
123
|
});
|
122
124
|
```
|
123
|
-
`rumble` offers more config options, use intellisense or take a look at [the rumble input type](lib/types/rumbleInput.ts) if you want to know more.
|
125
|
+
> `rumble` offers more config options, use intellisense or take a look at [the rumble input type](lib/types/rumbleInput.ts) if you want to know more.
|
124
126
|
|
125
127
|
## Helpers
|
126
128
|
Rumble offers various helpers to make it easy and fast to implement your api. Ofcourse you can write your api by hand using the provided `schemaBuilder` from the rumble initiator, but since this might get repetitive, the provided helpers automate a lot of this work for you while also automatically applying the concepts of rumble directly into your api.
|
@@ -128,11 +130,8 @@ Rumble offers various helpers to make it easy and fast to implement your api. Of
|
|
128
130
|
### arg
|
129
131
|
`arg` is a helper to implement query arguments for filtering the results of a query for certain results. In many cases you would implement arguments for a query with something as `matchUsername: t.arg.string()` which is supposed to restrict the query to users which have that username. The arg helper implements such a filter tailored to the specific entity which you then can directly pass on to the database query.
|
130
132
|
```ts
|
131
|
-
const {
|
132
|
-
|
133
|
-
transformArgumentToQueryCondition,
|
134
|
-
} = arg({
|
135
|
-
tableName: "posts",
|
133
|
+
const WhereArgs = arg({
|
134
|
+
table: "posts",
|
136
135
|
});
|
137
136
|
|
138
137
|
schemaBuilder.queryFields((t) => {
|
@@ -141,19 +140,18 @@ schemaBuilder.queryFields((t) => {
|
|
141
140
|
type: [PostRef],
|
142
141
|
args: {
|
143
142
|
// here we set our generated type as type for the where argument
|
144
|
-
where: t.arg({ type:
|
143
|
+
where: t.arg({ type: WhereArgs }),
|
145
144
|
},
|
146
145
|
resolve: (query, root, args, ctx, info) => {
|
147
146
|
return db.query.posts.findMany(
|
148
147
|
query(
|
149
|
-
|
148
|
+
// here we apply the ability filter
|
150
149
|
ctx.abilities.users.filter("read", {
|
151
|
-
|
150
|
+
// we can inject one time filters into the permission filter
|
152
151
|
inject: {
|
153
|
-
|
154
|
-
where: transformArgumentToQueryCondition(args.where),
|
152
|
+
where: args.where,
|
155
153
|
},
|
156
|
-
}).many,
|
154
|
+
}).query.many,
|
157
155
|
),
|
158
156
|
);
|
159
157
|
},
|
@@ -166,7 +164,7 @@ schemaBuilder.queryFields((t) => {
|
|
166
164
|
`object` is a helper to implement an object with relations. Don't worry about abilities, they are automatically applied. The helper returns the object reference which you can use in the rest of your api, for an example on how to use a type, see the above code snippet (`type: [PostRef],`).
|
167
165
|
```ts
|
168
166
|
const UserRef = object({
|
169
|
-
|
167
|
+
table: "users",
|
170
168
|
});
|
171
169
|
```
|
172
170
|
|
@@ -174,7 +172,7 @@ const UserRef = object({
|
|
174
172
|
The `query` helper is even simpler. It implements a `findFirst` and `findMany` query for the specified entity.
|
175
173
|
```ts
|
176
174
|
query({
|
177
|
-
|
175
|
+
table: "users",
|
178
176
|
});
|
179
177
|
|
180
178
|
```
|
@@ -183,7 +181,7 @@ query({
|
|
183
181
|
In case you want to use subscriptions, `rumble` has got you covered! The rumble helpers all use the `smart subscriptions plugin` from `pothos`. The `pubsub` helper lets you easily hook into the subscription notification logic.
|
184
182
|
```ts
|
185
183
|
const { updated, created, removed } = pubsub({
|
186
|
-
|
184
|
+
table: "users",
|
187
185
|
});
|
188
186
|
```
|
189
187
|
Now just call the functions whenever your application does the respective action and your subscriptions will get notified:
|
@@ -205,13 +203,13 @@ All `query` and `object` helper implementations will automatically update and wo
|
|
205
203
|
> The rumble initiator lets you configure the subscription notifiers in case you want to use an external service like redis for your pubsub notifications instead of the internal default one
|
206
204
|
|
207
205
|
### enum_
|
208
|
-
The `enum_` helper is a little different to the others, as it will get called internally automatically if another
|
206
|
+
The `enum_` helper is a little different to the others, as it will get called internally automatically if another helpers like `object` or `arg` detects an enum field. In most cases you should be good without calling it manually but in case you would like to have a reference to an enum object, you can get it from this helper.
|
209
207
|
```ts
|
210
208
|
const enumRef = enum_({
|
211
|
-
|
209
|
+
tsName: "moodEnum",
|
212
210
|
});
|
213
211
|
```
|
214
|
-
> The enum parameter allows
|
212
|
+
> The enum parameter allows other fields to be used to reference an enum. This is largely due to how this is used internally. Because of the way how drizzle handles enums, we are not able to provide type safety with enums. In case you actually need to use it, the above way is the recommended approach.
|
215
213
|
|
216
214
|
## Running the server
|
217
215
|
In case you directly want to run a server from your rumble instance, you can do so by using the `createYoga` function. It returns a graphql `yoga` instance which can be used to provide a graphql api in [a multitude of ways](https://the-guild.dev/graphql/yoga-server/docs/integrations/z-other-environments).
|
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'),pgCore=require('drizzle-orm/pg-core'),Ee=require('@pothos/core'),Ae=require('@pothos/plugin-drizzle'),ve=require('@pothos/plugin-smart-subscriptions'),graphqlScalars=require('graphql-scalars');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Ee__default=/*#__PURE__*/_interopDefault(Ee);var Ae__default=/*#__PURE__*/_interopDefault(Ae);var ve__default=/*#__PURE__*/_interopDefault(ve);function N(e){let t,m=false;return ()=>(m||(t=e(),m=true),t)}function _(e){return typeof e=="object"&&e!==null}function V(e,t){throw new Error("Unexpected invariant triggered.")}var pe=/\r\n|[\n\r]/g;function z(e,t){let m=0,u=1;for(let n of e.body.matchAll(pe)){if(typeof n.index=="number"||V(),n.index>=t)break;m=n.index+n[0].length,u+=1;}return {line:u,column:t+1-m}}function $(e){return k(e.source,z(e.source,e.start))}function k(e,t){let m=e.locationOffset.column-1,u="".padStart(m)+e.body,n=t.line-1,a=e.locationOffset.line-1,i=t.line+a,l=t.line===1?m:0,o=t.column+l,p=`${e.name}:${i}:${o}
|
2
|
+
`,r=u.split(/\r\n|[\n\r]/g),f=r[n];if(f.length>120){let s=Math.floor(o/80),d=o%80,c=[];for(let b=0;b<f.length;b+=80)c.push(f.slice(b,b+80));return p+M([[`${i} |`,c[0]],...c.slice(1,s+1).map(b=>["|",b]),["|","^".padStart(d)],["|",c[s+1]]])}return p+M([[`${i-1} |`,r[n-1]],[`${i} |`,f],["|","^".padStart(o)],[`${i+1} |`,r[n+1]]])}function M(e){let t=e.filter(([u,n])=>n!==void 0),m=Math.max(...t.map(([u])=>u.length));return t.map(([u,n])=>u.padStart(m)+(n?" "+n:"")).join(`
|
3
|
+
`)}function me(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 v=class e extends Error{constructor(t,...m){var u,n,a;let{nodes:i,source:l,positions:o,path:p,originalError:r,extensions:f}=me(m);super(t),this.name="GraphQLError",this.path=p??void 0,this.originalError=r??void 0,this.nodes=H(Array.isArray(i)?i:i?[i]:void 0);let s=H((u=this.nodes)===null||u===void 0?void 0:u.map(c=>c.loc).filter(c=>c!=null));this.source=l??(s==null||(n=s[0])===null||n===void 0?void 0:n.source),this.positions=o??s?.map(c=>c.start),this.locations=o&&l?o.map(c=>z(l,c)):s?.map(c=>z(c.source,c.start));let d=_(r?.extensions)?r?.extensions:void 0;this.extensions=(a=f??d)!==null&&a!==void 0?a: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}}),r!=null&&r.stack?Object.defineProperty(this,"stack",{value:r.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 m of this.nodes)m.loc&&(t+=`
|
4
4
|
|
5
|
-
|
5
|
+
`+$(m.loc));else if(this.source&&this.locations)for(let m of this.locations)t+=`
|
6
6
|
|
7
|
-
`+q(this.source,l);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 _(e){return e===void 0||e.length===0?void 0:e}var R=class extends Error{constructor(t){super(t),this.name="RumbleError";}},A=class extends B{};var U=(e,t)=>new R(`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 U(e,"Distinct")}function me(e){return typeof e!="function"}function ce(e){return typeof e=="function"&&e.constructor.name!=="AsyncFunction"}var M=({db:e,actions:t,defaultLimit:l})=>{let p=e._.schema,n={},d={},i={},y=r=>{for(let s of t)i[r]||(i[r]={}),i[r][s]||(i[r][s]=[]);return {allow:s=>{let o=d[r];o||(o={},d[r]=o);let f=Array.isArray(s)?s:[s];for(let a of f){let c=o[a];c||(c="wildcard",o[a]=c);}return {when:a=>{for(let c of f)o[c]==="wildcard"&&(o[c]=[]),o[c].push(a);}}},filter:s=>{let o=Array.isArray(s)?s:[s];return {by:f=>{for(let a of o)i[r][a].push(f);}}}}};for(let r of Object.keys(e.query))n[r]=y(r);return {...n,registeredConditions:d,registeredFilters:i,buildWithUserContext:r=>{let s={},o=f=>({filter:(a,c)=>{let m=d[f];m||(m={});let x=m[a];if(x==="wildcard")return {single:{where:c?.inject?.where,columns:c?.inject?.columns},many:{where:c?.inject?.where,columns:c?.inject?.columns,limit:c?.inject?.limit??l??void 0}};let C=()=>{let b=p[f].primaryKey.at(0);if(!b)throw new R(`No primary key found for entity ${f.toString()}`);let N=K(b.getSQLType());return {where:drizzleOrm.and(drizzleOrm.eq(b,N.value1),drizzleOrm.eq(b,N.value2))}};(!m||!x)&&(x=[C()]);let T=x.filter(me),u=x.filter(ce).map(b=>b(r)),g=u.some(b=>b==="allow"),h=[...T,...u];h.filter(b=>b!==void 0).length===0&&h.push(C());let S;for(let b of h)b!=="allow"&&b?.limit&&(S===void 0||b.limit>S)&&(S=b.limit);c?.inject?.limit&&S&&S<c.inject.limit&&(S=c.inject.limit);let D;for(let b of [...h,c?.inject??{}])b!=="allow"&&b?.columns&&(D===void 0?D=b.columns:D={...D,...b.columns});let v=g?[]:h.filter(b=>b!=="allow"&&b?.where).map(b=>b?.where),P=v.length>0?drizzleOrm.or(...v):void 0;return c?.inject?.where&&(P=P?drizzleOrm.and(P,c.inject.where):c.inject.where),{single:{where:P,columns:D},many:{where:P,columns:D,limit:S??l??void 0}}},explicitFilters:a=>i[f][a]});for(let f of Object.keys(e.query))s[f]=o(f);return s}}};var W=({context:e,abilityBuilder:t})=>async l=>{let p=e?await e(l):{};return {...p,abilities:t.buildWithUserContext(p)}};function E(e){return String(e).charAt(0).toUpperCase()+String(e).slice(1)}function L(e){let t=I(e);return t.enumValues!==void 0&&t.enumName!==void 0&&typeof t.enumName=="string"&&Array.isArray(t.enumValues)}function I(e){return e.enum??e}var J=({db:e,schemaBuilder:t})=>{let l=new Map;return ({enumVariableName:n,name:d,enumName:i})=>{let y=e._.fullSchema,r;if(n?r=y[n]:i&&(r=Object.values(y).filter(L).map(I).find(a=>a.enumName===i)),!r)throw new R(`Could not determine enum structure! (${String(n)}, ${enumValuesParam}, ${i})`);let s=d??`${E(casing.toCamelCase(r.enumName.toString()))}Enum`,o=l.get(s);return o||(o=t.enumType(s,{values:r.enumValues}),l.set(s,o),o)}};function w(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 de="RUMBLE_SUBSCRIPTION_NOTIFICATION",fe="REMOVED",he="UPDATED",ge="CREATED",H=({subscriptions:e,db:t})=>{let l=e?graphqlYoga.createPubSub(...e):graphqlYoga.createPubSub();return {pubsub:l,makePubSubInstance:({tableName:n})=>{function d({action:i,tableName:y,primaryKeyValue:r}){let s;switch(i){case "created":s=ge;break;case "removed":s=fe;break;case "updated":s=he;break;default:throw new Error(`Unknown action: ${i}`)}return `${de}/${y}${r?`/${r}`:""}/${s}`}return {registerOnInstance({instance:i,action:y,primaryKeyValue:r}){let s=d({tableName:n.toString(),action:y,primaryKeyValue:r});i.register(s);},created(){let i=d({tableName:n.toString(),action:"created"});return l.publish(i)},removed(i){let y=d({tableName:n.toString(),action:"removed"});return l.publish(y)},updated(i){let r=(Array.isArray(i)?i:[i]).map(o=>d({tableName:n.toString(),action:"updated",primaryKeyValue:o})),s=Array.from(new Set(r));for(let o of s)l.publish(o);}}}}};var X=({db:e,schemaBuilder:t,makePubSubInstance:l,argImplementer:p,enumImplementer:n,abilityBuilder:d})=>({tableName:i,name:y,readAction:r="read"})=>{let s=e._.schema[i];if(!s)throw new R(`Could not find schema for ${i.toString()} (object)`);let o=s.primaryKey.at(0)?.name;o||console.warn(`Could not find primary key for ${i.toString()}. Cannot register subscriptions!`);let{registerOnInstance:f}=l({tableName:i});return t.drizzleObject(i,{name:y??E(i.toString()),subscribe:(a,c,m)=>{if(!o)return;let x=c[o];if(!x){console.warn(`Could not find primary key value for ${JSON.stringify(c)}. Cannot register subscription!`);return}f({instance:a,action:"updated",primaryKeyValue:x});},applyFilters:d?.registeredFilters?.[i]?.[r],fields:a=>{let c=(C,T,u)=>{let g=w(C);switch(g){case "Int":return a.exposeInt(T,{nullable:u});case "String":return a.exposeString(T,{nullable:u});case "Boolean":return a.exposeBoolean(T,{nullable:u});case "Date":return a.field({type:"Date",resolve:h=>h[T],nullable:u});case "DateTime":return a.field({type:"DateTime",resolve:h=>h[T],nullable:u});case "Float":return a.exposeFloat(T,{nullable:u});case "ID":return a.exposeID(T,{nullable:u});case "JSON":return a.field({type:"JSON",resolve:h=>h[T],nullable:u});default:throw new R(`Unsupported object type ${g} for column ${T}`)}},m=Object.entries(s.columns).reduce((C,[T,u])=>{if(L(u)){let g=I(u),h=n({enumName:g.enumName});C[T]=a.field({type:h,resolve:S=>S[T],nullable:!u.notNull});}else C[T]=c(u.getSQLType(),T,!u.notNull);return C},{}),x=Object.entries(s.relations).reduce((C,[T,u])=>{let {inputType:g,transformArgumentToQueryCondition:h}=p({tableName:u.referencedTableName,nativeTableName:u.referencedTableName}),S=false,v="many";return u instanceof drizzleOrm.One&&(S=!u.isNullable,v="single"),C[T]=a.relation(T,{args:{where:a.arg({type:g,required:false})},nullable:S,query:(P,b)=>{let N=Object.entries(e._.schema).find(([qe,ie])=>ie.dbName===u.referencedTableName)?.at(0);if(!N)throw new R(`Could not find table ${u.referencedTableName} in schema object`);return b.abilities[N].filter(r,{inject:{where:h(P.where)}})[v]}}),C},{});return {...m,...x}}})};var O=e=>{if(!e)throw new A("Value not found but required (findFirst)");return e},xe=e=>{let t=e.at(0);if(!t)throw new A("Value not found but required (firstEntry)");return t},Z=async({filters:e,entities:t,context:l})=>(await Promise.all(e.map(p=>p({context:l,entities:t})))).reduce((p,n)=>(p.push(...n),p),[]);var ee=({db:e,schemaBuilder:t,argImplementer:l,makePubSubInstance:p})=>({tableName:n,readAction:d="read",listAction:i="read"})=>{let y=e._.schema[n];if(!y)throw new R(`Could not find schema for ${n.toString()} (query)`);y.primaryKey.at(0)?.name||console.warn(`Could not find primary key for ${n.toString()}. Cannot register subscriptions!`);let{inputType:s,transformArgumentToQueryCondition:o}=l({tableName:n}),{registerOnInstance:f}=p({tableName:n});return t.queryFields(a=>({[`findMany${E(n.toString())}`]:a.drizzleField({type:[n],nullable:false,smartSubscription:true,subscribe:(c,m,x,C,T)=>{f({instance:c,action:"created"}),f({instance:c,action:"removed"});},args:{where:a.arg({type:s,required:false})},resolve:(c,m,x,C,T)=>{let u=C.abilities[n].filter(i,{inject:{where:o(x.where)}}).many,g=c(u);return u.columns&&(g.columns=u.columns),e.query[n].findMany(g)}}),[`findFirst${E(n.toString())}`]:a.drizzleField({type:n,nullable:false,smartSubscription:true,args:{where:a.arg({type:s,required:false})},resolve:(c,m,x,C,T)=>{let u=C.abilities[n].filter(d,{inject:{where:o(x.where)}}).single,g=c(u);return u.columns&&(g.columns=u.columns),e.query[n].findFirst(g).then(O)}})}))};var te="ManualFiltersPlugin",ne=te,Se="applyFilters",z=class extends Te.BasePlugin{wrapResolve(t,l){return async(p,n,d,i)=>{let y=(l?.type).type?.ref.currentConfig.pothosOptions[Se];if(!y||!Array.isArray(y)||y.length===0)return t(p,n,d,i);let r=await t(p,n,d,i),s=Array.isArray(r)?r:[r],o=Array.isArray(y)?y:[y],f=await Z({filters:o,entities:s,context:d});return Array.isArray(r)?f:f[0]??null}}};Te__default.default.registerPlugin(te,z);var re=({db:e,disableDefaultObjects:t,pubsub:l,pothosConfig:p})=>{let n=new Te__default.default({plugins:[ne,De__default.default,Ee__default.default,...p?.plugins??[]],...p,drizzle:{client:e},smartSubscriptions:{...Ee.subscribeOptionsFromIterator((d,i)=>l.subscribe(d))}});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 Le=e=>`${E(casing.toCamelCase(e.toString()))}WhereInputArgument`,oe=({db:e,schemaBuilder:t,enumImplementer:l})=>{let p=new Map,n=({tableName:d,name:i,nativeTableName:y})=>{let r=e._.schema[d];if(y){let a=Object.values(e._.schema).find(c=>c.dbName===y);a&&(r=a);}if(!r)throw new R(`Could not find schema for ${d.toString()} (whereArg)`);let s=i??Le(r.dbName),o=p.get(s);return o||(o={inputType:t.inputType(s,{fields:m=>{let x=u=>{let g=w(u);switch(g){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 R(`Unsupported argument type ${g} for column ${u}`)}},C=Object.entries(r.columns).reduce((u,[g,h])=>{if(L(h)){let S=I(h),D=l({enumName:S.enumName});u[g]=m.field({type:D,required:false});}else u[g]=x(h.getSQLType());return u},{}),T=Object.entries(r.relations).reduce((u,[g,h])=>{let S=n({tableName:h.referencedTableName,nativeTableName:h.referencedTableName});return u[g]=m.field({type:S.inputType,required:false}),u},{});return {...C,...T}}}),transformArgumentToQueryCondition:m=>{if(!m)return;let x=u=>{let g=r.columns[u],h=m[u];if(h)return drizzleOrm.eq(g,h)},C=u=>{let g=r.relations[u],h=m[u];if(!h)return;let S=n({tableName:g.referencedTableName,nativeTableName:g.referencedTableName}).transformArgumentToQueryCondition;return S(h)},T=[...Object.keys(r.columns).map(x),...Object.keys(r.relations).map(C)];return drizzleOrm.and(...T)}},p.set(s,o),o)};return n};var we=e=>{e.actions||(e.actions=["read","update","delete"]),e.defaultLimit===void 0&&(e.defaultLimit=100);let t=M(e),l=W({...e,abilityBuilder:t}),{makePubSubInstance:p,pubsub:n}=H({...e}),{schemaBuilder:d}=re({...e,pubsub:n}),i=J({...e,schemaBuilder:d}),y=oe({...e,schemaBuilder:d,enumImplementer:i}),r=X({...e,schemaBuilder:d,makePubSubInstance:p,argImplementer:y,enumImplementer:i,abilityBuilder:t}),s=ee({...e,schemaBuilder:d,argImplementer:y,makePubSubInstance:p});return {abilityBuilder:t,schemaBuilder:d,createYoga:f=>graphqlYoga.createYoga({...f,schema:d.toSchema(),context:l}),object:r,arg:y,query:s,pubsub:p,enum_:i}};
|
8
|
-
exports.RumbleError=
|
7
|
+
`+k(this.source,m);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 H(e){return e===void 0||e.length===0?void 0:e}var C=class extends Error{constructor(t){super(t),this.name="RumbleError";}},F=class extends v{};var O=(e,t)=>new C(`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 O(e,"Distinct")}var G=Symbol.for("drizzle:Name"),W=Symbol.for("drizzle:Columns");function E({dbName:e,tsName:t,table:m,db:u}){let n=m;if(t&&(n=u._.relations.schema[t]),e&&(n=Object.values(u._.relations.schema).find(a=>a[G]===e)),!n)throw new C(`Could not find schema for ${JSON.stringify({tsName:t,dbName:e,table:m?.[G]}).toString()}`);return {tableSchema:n,columns:n[W],get primaryColumns(){return Object.entries(n[W]).filter(([a,i])=>i.primary).reduce((a,[i,l])=>(a[i]=l,a),{})},relations:u._.relations.config[t],dbName:n[G],get tsName(){return Object.entries(u._.relations.schema).find(([a,i])=>i===n).at(0)}}}function fe(e){return typeof e!="function"}function Te(e){return typeof e=="function"&&e.constructor.name!=="AsyncFunction"}var Y=({db:e,actions:t,defaultLimit:m})=>{let u={},n={},a={},i=l=>{for(let o of t)a[l]||(a[l]={}),a[l][o]||(a[l][o]=[]);return {allow:o=>{let p=n[l];p||(p={},n[l]=p);let r=Array.isArray(o)?o:[o];for(let f of r){let s=p[f];s||(s="unspecified",p[f]=s);}return {when:f=>{for(let s of r)p[s]==="unspecified"&&(p[s]=[]),p[s].push(f);}}},filter:o=>{let p=Array.isArray(o)?o:[o];return {by:r=>{for(let f of p)a[l][f].push(r);}}}}};for(let l of Object.keys(e.query))u[l]=i(l);return {...u,registeredQueryFilters:n,registeredFilters:a,buildWithUserContext:l=>{let o={},p=r=>({filter:(f,s)=>{let d=y=>{let B=N(()=>{if(!(!y?.where&&!s?.inject?.where))return s?.inject?.where?{AND:[y?.where,s?.inject?.where]}:y?.where}),A=N(()=>{let P=B();if(!P)return;let ue=E({tsName:r,db:e});return drizzleOrm.relationsFilterToSQL(ue.tableSchema,P)}),q=N(()=>{let P=y?.limit??m;return s?.inject?.limit&&(!P||P>s.inject.limit)&&(P=s.inject.limit),y?.limit&&(!P||y.limit>P)&&(P=y.limit),P??void 0}),w=N(()=>{if(!(!y?.columns&&!s?.inject?.columns))return {...y?.columns,...s?.inject?.columns}});return {query:{single:{get where(){return B()},get columns(){return w()}},many:{get where(){return B()},get columns(){return w()},get limit(){return q()}}},sql:{get where(){return A()},get columns(){return w()},get limit(){return q()}}}},c=()=>{let y=E({db:e,tsName:r});if(Object.keys(y.primaryColumns).length===0)throw new C(`No primary key found for entity ${r.toString()}`);let B=Object.values(y.primaryColumns)[0],A=J(B.getSQLType());return {where:{AND:[{[B.name]:A.value1},{[B.name]:A.value2}]}}},b=n?.[r]?.[f];if(b==="unspecified")return d();b||(b=[c()]);let x=b.filter(fe),D=b.filter(Te).map(y=>y(l)),h=D.some(y=>y==="allow"),T=[...x,...D].filter(y=>y!==void 0).filter(y=>y!=="allow");!h&&T.length===0&&(T=[c()]);let g;for(let y of T)y?.limit&&(g===void 0||y.limit>g)&&(g=y.limit);let S;for(let y of [...T,s?.inject])y?.columns&&(S===void 0?S=y.columns:S={...S,...y.columns});let R=h?[]:T.filter(y=>y?.where).map(y=>y.where),L=R.length>0?{OR:R}:void 0;return d({where:L,columns:S,limit:g})},explicitFilters:f=>a[r][f]});for(let r of Object.keys(e.query))o[r]=p(r);return o}}};var X=({context:e,abilityBuilder:t})=>async m=>{let u=e?await e(m):{};return {...u,abilities:t.buildWithUserContext(u)}};function I(e){return String(e).charAt(0).toUpperCase()+String(e).slice(1)}function U(e){return e instanceof pgCore.PgEnumColumn}var Z=({db:e,schemaBuilder:t})=>{let m=new Map;return ({tsName:n,enumColumn:a,refName:i})=>{let l,o;if(n){let s=E({db:e,tsName:n});l=n.toString();let d=Object.values(e._.relations.schema).filter(c=>typeof c=="object").map(c=>Object.values(c[Symbol.for("drizzle:Columns")])).flat(2).find(c=>c.config?.enum===s);if(!d)throw new C(`Could not find applied enum column for ${n.toString()}.
|
8
|
+
Please ensure that you use the enum at least once as a column of a table!`);o=d.enumValues;}else if(a){let s=Object.entries(e._.relations.schema).find(([d,c])=>c===a.config.enum);if(!s)throw new C(`Could not find enum in schema for ${a.name}!`);l=s[0],o=a.enumValues;}if(!l||!o)throw new C("Could not determine enum structure!");let p=i??`${I(casing.toCamelCase(l))}Enum`,r=m.get(p);return r||(r=t.enumType(p,{values:o}),m.set(p,r),r)}};function Q(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 O(e,"SQL to GQL")}var ee=({db:e,schemaBuilder:t,makePubSubInstance:m,argImplementer:u,enumImplementer:n,abilityBuilder:a})=>({table:i,refName:l,readAction:o="read",extend:p})=>{let r=E({db:e,tsName:i});Object.keys(r.primaryColumns).length===0&&console.warn(`Could not find primary key for ${i.toString()}. Cannot register subscriptions!`);let f=Object.values(r.primaryColumns)[0],{registerOnInstance:s}=m({table:i});return t.drizzleObject(i,{name:l??I(i.toString()),subscribe:(d,c,b)=>{if(!f)return;let x=c[f.name];if(!x){console.warn(`Could not find primary key value for ${JSON.stringify(c)}. Cannot register subscription!`);return}s({instance:d,action:"updated",primaryKeyValue:x});},applyFilters:a?.registeredFilters?.[i]?.[o],fields:d=>{let c=r.columns,b=(h,T,g)=>{let S=Q(h);switch(S){case "Int":return d.exposeInt(T,{nullable:g});case "String":return d.exposeString(T,{nullable:g});case "Boolean":return d.exposeBoolean(T,{nullable:g});case "Date":return d.field({type:"Date",resolve:R=>R[T],nullable:g});case "DateTime":return d.field({type:"DateTime",resolve:R=>R[T],nullable:g});case "Float":return d.exposeFloat(T,{nullable:g});case "ID":return d.exposeID(T,{nullable:g});case "JSON":return d.field({type:"JSON",resolve:R=>R[T],nullable:g});default:throw new C(`Unsupported object type ${S} for column ${T}`)}},x=Object.entries(c).reduce((h,[T,g])=>{if(U(g)){let S=n({enumColumn:g});h[T]=d.field({type:S,resolve:R=>R[T],nullable:!g.notNull});}else h[T]=b(g.getSQLType(),T,!g.notNull);return h},{}),D=Object.entries(r.relations).reduce((h,[T,g])=>{let S=E({db:e,table:g.targetTable}),R=u({dbName:S.dbName}),L=false,B="many";return g instanceof drizzleOrm.One&&(L=g.optional,B="single"),h[T]=d.relation(T,{args:{where:d.arg({type:R,required:false})},nullable:L,query:(A,q)=>q.abilities[S.tsName].filter(o,{inject:{where:A.where}}).query[B]}),h},{});return p?{...x,...D,...p(d)??{}}:{...x,...D}}})};var he="RUMBLE_SUBSCRIPTION_NOTIFICATION",Ce="REMOVED",De="UPDATED",Se="CREATED",ne=({subscriptions:e,db:t})=>{let m=e?graphqlYoga.createPubSub(...e):graphqlYoga.createPubSub();return {pubsub:m,makePubSubInstance:({table:n})=>{function a({action:i,tableName:l,primaryKeyValue:o}){let p;switch(i){case "created":p=Se;break;case "removed":p=Ce;break;case "updated":p=De;break;default:throw new Error(`Unknown action: ${i}`)}return `${he}/${l}${o?`/${o}`:""}/${p}`}return {registerOnInstance({instance:i,action:l,primaryKeyValue:o}){let p=a({tableName:n.toString(),action:l,primaryKeyValue:o});i.register(p);},created(){let i=a({tableName:n.toString(),action:"created"});return m.publish(i)},removed(i){let l=a({tableName:n.toString(),action:"removed"});return m.publish(l)},updated(i){let o=(Array.isArray(i)?i:[i]).map(r=>a({tableName:n.toString(),action:"updated",primaryKeyValue:r})),p=Array.from(new Set(o));for(let r of p)m.publish(r);}}}}};var j=e=>{if(!e)throw new F("Value not found but required (findFirst)");return e},Re=e=>{let t=e.at(0);if(!t)throw new F("Value not found but required (firstEntry)");return t},re=async({filters:e,entities:t,context:m})=>(await Promise.all(e.map(u=>u({context:m,entities:t})))).reduce((u,n)=>(u.push(...n),u),[]);var ie=({db:e,schemaBuilder:t,argImplementer:m,makePubSubInstance:u})=>({table:n,readAction:a="read",listAction:i="read"})=>{let l=m({table:n}),{registerOnInstance:o}=u({table:n});return t.queryFields(p=>({[`findMany${I(n.toString())}`]:p.drizzleField({type:[n],nullable:false,smartSubscription:true,subscribe:(r,f,s,d,c)=>{o({instance:r,action:"created"}),o({instance:r,action:"removed"});},args:{where:p.arg({type:l,required:false})},resolve:(r,f,s,d,c)=>{let b=d.abilities[n].filter(i,{inject:{where:s.where}}).query.many,x=r(b);return b.columns&&(x.columns=b.columns),e.query[n].findMany(x)}}),[`findFirst${I(n.toString())}`]:p.drizzleField({type:n,nullable:false,smartSubscription:true,args:{where:p.arg({type:l,required:false})},resolve:(r,f,s,d,c)=>{let b=d.abilities[n].filter(a,{inject:{where:s.where}}).query.single,x=r(b);return b.columns&&(x.columns=b.columns),e.query[n].findFirst(x).then(j)}})}))};var oe="ManualFiltersPlugin",se=oe,Pe="applyFilters",K=class extends Ee.BasePlugin{wrapResolve(t,m){return async(u,n,a,i)=>{let l=(m?.type).type?.ref.currentConfig.pothosOptions[Pe];if(!l||!Array.isArray(l)||l.length===0)return t(u,n,a,i);let o=await t(u,n,a,i),p=Array.isArray(o)?o:[o],r=Array.isArray(l)?l:[l],f=await re({filters:r,entities:p,context:a});return Array.isArray(o)?f:f[0]??null}}};Ee__default.default.registerPlugin(oe,K);var ae=({db:e,disableDefaultObjects:t,pubsub:m,pothosConfig:u})=>{let n=new Ee__default.default({plugins:[se,Ae__default.default,ve__default.default,...u?.plugins??[]],...u,drizzle:{client:e,relations:e._.relations,getTableConfig(a){return {columns:Object.values(a[Symbol.for("drizzle:Columns")]),primaryKeys:Object.values(a[Symbol.for("drizzle:Columns")]).filter(i=>i.primary)}}},smartSubscriptions:{...ve.subscribeOptionsFromIterator((a,i)=>m.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 Oe=e=>`${I(casing.toCamelCase(e.toString()))}WhereInputArgument`,le=({db:e,schemaBuilder:t,enumImplementer:m})=>{let u=new Map,n=({table:a,refName:i,dbName:l})=>{let o=E({db:e,dbName:l,tsName:a}),p=i??Oe(o.tsName),r=u.get(p);return r||(r=t.inputType(p,{fields:s=>{let d=x=>{let D=Q(x);switch(D){case "Int":return s.int({required:false});case "String":return s.string({required:false});case "Boolean":return s.boolean({required:false});case "Date":return s.field({type:"Date",required:false});case "DateTime":return s.field({type:"DateTime",required:false});case "Float":return s.float({required:false});case "ID":return s.id({required:false});case "JSON":return s.field({type:"JSON",required:false});default:throw new C(`Unsupported argument type ${D} for column ${x}`)}},c=Object.entries(o.columns).reduce((x,[D,h])=>{if(U(h)){let T=m({enumColumn:h});x[D]=s.field({type:T,required:false});}else x[D]=d(h.getSQLType());return x},{}),b=Object.entries(o.relations).reduce((x,[D,h])=>{let T=E({db:e,table:h.targetTable}),g=n({dbName:T.dbName});return x[D]=s.field({type:g,required:false}),x},{});return {...c,...b}}}),u.set(p,r),r)};return n};var Qe=e=>{e.actions||(e.actions=["read","update","delete"]),e.defaultLimit===void 0&&(e.defaultLimit=100);let t=Y(e),m=X({...e,abilityBuilder:t}),{makePubSubInstance:u,pubsub:n}=ne({...e}),{schemaBuilder:a}=ae({...e,pubsub:n}),i=Z({...e,schemaBuilder:a}),l=le({...e,schemaBuilder:a,enumImplementer:i}),o=ee({...e,schemaBuilder:a,makePubSubInstance:u,argImplementer:l,enumImplementer:i,abilityBuilder:t}),p=ie({...e,schemaBuilder:a,argImplementer:l,makePubSubInstance:u});return {abilityBuilder:t,schemaBuilder:a,createYoga:f=>graphqlYoga.createYoga({...f,schema:a.toSchema(),context:m}),object:o,arg:l,query:p,pubsub:u,enum_:i}};exports.RumbleError=C;exports.RumbleErrorSafe=F;exports.assertFindFirstExists=j;exports.assertFirstEntryExists=Re;exports.rumble=Qe;//# sourceMappingURL=index.cjs.map
|
9
9
|
//# sourceMappingURL=index.cjs.map
|