@m1212e/rumble 0.3.12 → 0.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,8 +21,8 @@ import * as schema from "./db/schema";
21
21
  import { rumble } from "@m1212e/rumble";
22
22
 
23
23
  export const db = drizzle(
24
- "postgres://postgres:postgres@localhost:5432/postgres",
25
- { schema }
24
+ "postgres://postgres:postgres@localhost:5432/postgres",
25
+ { schema }
26
26
  );
27
27
 
28
28
  const { abilityBuilder } = rumble({ db });
@@ -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: eq(schema.posts.published, true),
52
+ where: eq(schema.posts.published, true),
53
53
  });
54
54
  ```
55
55
 
@@ -58,8 +58,8 @@ Condition functions are functions that return condition objects. They are called
58
58
  ```ts
59
59
  // only the author can update posts
60
60
  abilityBuilder.posts
61
- .allow(["update", "delete"])
62
- .when(({ userId }) => ({ where: eq(schema.posts.authorId, userId) }));
61
+ .allow(["update", "delete"])
62
+ .when(({ userId }) => ({ where: eq(schema.posts.authorId, userId) }));
63
63
 
64
64
  ```
65
65
 
@@ -67,17 +67,17 @@ abilityBuilder.posts
67
67
  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
68
  ```ts
69
69
  schemaBuilder.queryFields((t) => {
70
- return {
71
- findManyPosts: t.drizzleField({
72
- type: [PostRef],
73
- resolve: (query, root, args, ctx, info) => {
74
- return db.query.posts.findMany(
75
- // here we apply our filter
76
- query(ctx.abilities.posts.filter("read")),
77
- );
78
- },
79
- }),
80
- };
70
+ return {
71
+ findManyPosts: t.drizzleField({
72
+ type: [PostRef],
73
+ resolve: (query, root, args, ctx, info) => {
74
+ return db.query.posts.findMany(
75
+ // here we apply our filter
76
+ query(ctx.abilities.posts.filter("read")),
77
+ );
78
+ },
79
+ }),
80
+ };
81
81
  });
82
82
  ```
83
83
 
@@ -85,15 +85,16 @@ schemaBuilder.queryFields((t) => {
85
85
  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
86
  ```ts
87
87
  rumble({
88
- db,
89
- context(request) {
90
- return {
91
- // here you could instead read some cookies or HTTP headers to retrieve an actual userId
92
- userId: 2,
93
- };
94
- },
88
+ db,
89
+ context(request) {
90
+ return {
91
+ // here you could instead read some cookies or HTTP headers to retrieve an actual userId
92
+ userId: 2,
93
+ };
94
+ },
95
95
  });
96
96
  ```
97
+ `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.
97
98
 
98
99
  ## Helpers
99
100
  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.
@@ -102,36 +103,36 @@ Rumble offers various helpers to make it easy and fast to implement your api. Of
102
103
  `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.
103
104
  ```ts
104
105
  const {
105
- inputType,
106
- transformArgumentToQueryCondition,
106
+ inputType,
107
+ transformArgumentToQueryCondition,
107
108
  } = arg({
108
- tableName: "posts",
109
+ tableName: "posts",
109
110
  });
110
111
 
111
112
  schemaBuilder.queryFields((t) => {
112
- return {
113
- findManyPostsFiltered: t.drizzleField({
114
- type: [PostRef],
115
- args: {
116
- // here we set our generated type as type for the where argument
117
- where: t.arg({ type: inputType }),
118
- },
119
- resolve: (query, root, args, ctx, info) => {
120
- return db.query.posts.findMany(
121
- query(
113
+ return {
114
+ findManyPostsFiltered: t.drizzleField({
115
+ type: [PostRef],
116
+ args: {
117
+ // here we set our generated type as type for the where argument
118
+ where: t.arg({ type: inputType }),
119
+ },
120
+ resolve: (query, root, args, ctx, info) => {
121
+ return db.query.posts.findMany(
122
+ query(
122
123
  // here we apply the ability filter
123
- ctx.abilities.users.filter("read", {
124
+ ctx.abilities.users.filter("read", {
124
125
  // we can inject one time filters into the permission filter
125
- inject: {
126
+ inject: {
126
127
  // here we transform the args into a drizzle filter
127
- where: transformArgumentToQueryCondition(args.where),
128
- },
129
- }),
130
- ),
131
- );
132
- },
133
- }),
134
- };
128
+ where: transformArgumentToQueryCondition(args.where),
129
+ },
130
+ }),
131
+ ),
132
+ );
133
+ },
134
+ }),
135
+ };
135
136
  });
136
137
  ```
137
138
 
@@ -139,7 +140,7 @@ schemaBuilder.queryFields((t) => {
139
140
  `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],`).
140
141
  ```ts
141
142
  const UserRef = object({
142
- tableName: "users",
143
+ tableName: "users",
143
144
  });
144
145
  ```
145
146
 
@@ -147,7 +148,7 @@ const UserRef = object({
147
148
  The `query` helper is even simpler. It implements a `findFirst` and `findMany` query for the specified entity.
148
149
  ```ts
149
150
  query({
150
- tableName: "users",
151
+ tableName: "users",
151
152
  });
152
153
 
153
154
  ```
@@ -156,7 +157,7 @@ query({
156
157
  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.
157
158
  ```ts
158
159
  const { updated, created, removed } = pubsub({
159
- tableName: "users",
160
+ tableName: "users",
160
161
  });
161
162
  ```
162
163
  Now just call the functions whenever your application does the respective action and your subscriptions will get notified:
@@ -181,7 +182,7 @@ All `query` and `object` helper implementations will automatically update and wo
181
182
  The `enum_` helper is a little different to the others, as it will get called internally automatically if another helper 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.
182
183
  ```ts
183
184
  const enumRef = enum_({
184
- enumVariableName: "moodEnum",
185
+ enumVariableName: "moodEnum",
185
186
  });
186
187
  ```
187
188
  > The enum parameter allows for various other fields to use 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 one to use it.
@@ -192,7 +193,7 @@ In case you directly want to run a server from your rumble instance, you can do
192
193
  import { createServer } from "node:http";
193
194
  const server = createServer(createYoga());
194
195
  server.listen(3000, () => {
195
- console.info("Visit http://localhost:3000/graphql");
196
+ console.info("Visit http://localhost:3000/graphql");
196
197
  });
197
198
 
198
199
  ```
package/index.cjs CHANGED
@@ -1,3 +1,9 @@
1
- 'use strict';var graphqlYoga=require('graphql-yoga'),drizzleOrm=require('drizzle-orm'),casing=require('drizzle-orm/casing'),ee=require('@pothos/core'),te=require('@pothos/plugin-drizzle'),ne=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 te__default=/*#__PURE__*/_interopDefault(te);var ne__default=/*#__PURE__*/_interopDefault(ne);var T=class extends Error{constructor(t){super(t),this.name="RumbleError";}};var I=(e,t)=>new T(`RumbleError: Unknown SQL type '${e}'. Please open an issue (https://github.com/m1212e/rumble/issues) so it can be added. (${t})`);function q(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 I(e,"Distinct")}function K(e){return typeof e!="function"}function V(e){return typeof e=="function"&&e.constructor.name!=="AsyncFunction"}var N=({db:e})=>{let t=e._.schema,x={},r={},o=i=>({allow:d=>{let m=r[i];m||(m={},r[i]=m);let p=Array.isArray(d)?d:[d];for(let l of p){let s=m[l];s||(s="wildcard",m[l]=s);}return {when:l=>{for(let s of p)m[s]==="wildcard"&&(m[s]=[]),m[s].push(l);}}}});for(let i of Object.keys(e.query))x[i]=o(i);return {...x,registeredConditions:r,buildWithUserContext:i=>{let d={},m=p=>({filter:(l,s)=>{let a=r[p];a||(a={});let D=a[l];if(D==="wildcard")return {where:void 0,columns:void 0,limit:void 0,...s?.inject};let g=()=>{let b=t[p].primaryKey.at(0);if(!b)throw new T(`No primary key found for entity ${p.toString()}`);let U=q(b.getSQLType());return {where:drizzleOrm.and(drizzleOrm.eq(b,U.value1),drizzleOrm.eq(b,U.value2))}};(!a||!D)&&(D=[g()]);let f=D.filter(K),S=D.filter(V).map(b=>b(i)),u=[...f,...S];u.filter(b=>b!==void 0).length===0&&u.push(g());let n;for(let b of u)b?.limit&&(n===void 0||b.limit>n)&&(n=b.limit);s?.inject?.limit&&n<s.inject.limit&&(n=s.inject.limit);let c;for(let b of [...u,s?.inject??{}])b?.columns&&(c===void 0?c=b.columns:c={...c,...b.columns});let y=u.filter(b=>b?.where).map(b=>b?.where),R=y.length>0?drizzleOrm.or(...y):void 0;return s?.inject?.where&&(R=R?drizzleOrm.and(R,s.inject.where):s.inject.where),{where:R,columns:c,limit:n}}});for(let p of Object.keys(e.query))d[p]=m(p);return d}}};var Q=({context:e,abilityBuilder:t})=>async x=>{let r=e?await e(x):{};return {...r,abilities:t.buildWithUserContext(r)}};function C(e){return String(e).charAt(0).toUpperCase()+String(e).slice(1)}function E(e){let t=B(e);return t.enumValues!==void 0&&t.enumName!==void 0&&typeof t.enumName=="string"&&Array.isArray(t.enumValues)}function B(e){return e.enum??e}var O=({db:e,schemaBuilder:t})=>{let x=new Map;return ({enumVariableName:o,name:i,enumValues:d,enumName:m})=>{let p=e._.fullSchema,l;if(o?l=p[o]:d?l=Object.values(p).filter(E).map(B).find(g=>g.enumValues===d):m&&(l=Object.values(p).filter(E).map(B).find(g=>g.enumName===m)),!l)throw new T(`Could not determine enum structure! (${String(o)}, ${d}, ${m})`);let s=i??`${C(casing.toCamelCase(l.enumName.toString()))}Enum`,a=x.get(s);return a||(a=t.enumType(s,{values:l.enumValues}),x.set(s,a),a)}};function A(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 I(e,"SQL to GQL")}var J="RUMBLE_SUBSCRIPTION_NOTIFICATION",W="REMOVED",Y="UPDATED",X="CREATED";function v({action:e,tableName:t,primaryKeyValue:x}){let r;switch(e){case "created":r=X;break;case "removed":r=W;break;case "updated":r=Y;break;default:throw new Error(`Unknown action: ${e}`)}return `${J}/${t}${x?`/${x}`:""}/${r}`}var F=({subscriptions:e})=>{let t=e?graphqlYoga.createPubSub(...e):graphqlYoga.createPubSub();return {pubsub:t,makePubSubInstance:({tableName:r})=>({registerOnInstance({instance:o,action:i,primaryKeyValue:d}){let m=v({tableName:r.toString(),action:i,primaryKeyValue:d});o.register(m);},created(){let o=v({tableName:r.toString(),action:"created"});return t.publish(o)},removed(o){let i=v({tableName:r.toString(),action:"removed"});return t.publish(i)},updated(o){let i=v({tableName:r.toString(),action:"updated",primaryKeyValue:o});return t.publish(i)}})}};var L=({db:e,schemaBuilder:t,makePubSubInstance:x,argImplementer:r,enumImplementer:o})=>({tableName:i,name:d,readAction:m="read"})=>{let p=e._.schema[i];if(!p)throw new T(`Could not find schema for ${i.toString()} (object)`);let l=p.primaryKey.at(0)?.name;l||console.warn(`Could not find primary key for ${i.toString()}. Cannot register subscriptions!`);let{registerOnInstance:s}=x({tableName:i});return t.drizzleObject(i,{name:d??C(i.toString()),subscribe:(a,D,g)=>{if(!l)return;let f=D[l];if(!f){console.warn(`Could not find primary key value for ${JSON.stringify(D)}. Cannot register subscription!`);return}s({instance:a,action:"updated",primaryKeyValue:f});},fields:a=>{let D=(S,u,n)=>{let c=A(S);switch(c){case "Int":return a.exposeInt(u,{nullable:n});case "String":return a.exposeString(u,{nullable:n});case "Boolean":return a.exposeBoolean(u,{nullable:n});case "Date":return a.field({type:"Date",resolve:y=>y[u],nullable:n});case "DateTime":return a.field({type:"DateTime",resolve:y=>y[u],nullable:n});case "Float":return a.exposeFloat(u,{nullable:n});case "ID":return a.exposeID(u,{nullable:n});case "JSON":return a.field({type:"JSON",resolve:y=>y[u],nullable:n});default:throw new T(`Unsupported object type ${c} for column ${u}`)}},g=Object.entries(p.columns).reduce((S,[u,n])=>{if(E(n)){let c=B(n),y=o({enumName:c.enumName});S[u]=a.field({type:y,resolve:R=>R[u],nullable:!n.notNull});}else S[u]=D(n.getSQLType(),u,!n.notNull);return S},{}),f=Object.entries(p.relations).reduce((S,[u,n])=>{let{inputType:c,transformArgumentToQueryCondition:y}=r({tableName:n.referencedTableName,nativeTableName:n.referencedTableName}),R=false;return n instanceof drizzleOrm.One&&(R=!n.isNullable),S[u]=a.relation(u,{args:{where:a.arg({type:c,required:false})},nullable:R,query:(h,b)=>b.abilities[n.referencedTableName].filter(m,{inject:{where:y(h.where)}})}),S},{});return {...g,...f}}})};var z=e=>{if(!e)throw new T("Value not found but required (findFirst)");return e},Z=e=>{let t=e.at(0);if(!t)throw new T("Value not found but required (firstEntry)");return t};var j=({db:e,schemaBuilder:t,argImplementer:x,makePubSubInstance:r})=>({tableName:o,readAction:i="read",listAction:d="read"})=>{let m=e._.schema[o];if(!m)throw new T(`Could not find schema for ${o.toString()} (query)`);m.primaryKey.at(0)?.name||console.warn(`Could not find primary key for ${o.toString()}. Cannot register subscriptions!`);let{inputType:l,transformArgumentToQueryCondition:s}=x({tableName:o}),{registerOnInstance:a}=r({tableName:o});return t.queryFields(D=>({[`findMany${C(o.toString())}`]:D.drizzleField({type:[o],nullable:false,smartSubscription:true,subscribe:(g,f,S,u,n)=>{a({instance:g,action:"created"}),a({instance:g,action:"removed"});},args:{where:D.arg({type:l,required:false})},resolve:(g,f,S,u,n)=>{let c=u.abilities[o].filter(d,{inject:{where:s(S.where)}}),y=g(c);return c.columns&&(y.columns=c.columns),e.query[o].findMany(y)}}),[`findFirst${C(o.toString())}`]:D.drizzleField({type:o,nullable:false,smartSubscription:true,args:{where:D.arg({type:l,required:false})},resolve:(g,f,S,u,n)=>{let c=u.abilities[o].filter(i,{inject:{where:s(S.where)}}),y=g(c);return c.columns&&(y.columns=c.columns),e.query[o].findFirst(y).then(z)}})}))};var G=({db:e,disableDefaultObjects:t,pubsub:x})=>{let r=new ee__default.default({plugins:[te__default.default,ne__default.default],drizzle:{client:e},smartSubscriptions:{...ne.subscribeOptionsFromIterator((o,i)=>x.subscribe(o))}});return r.addScalarType("JSON",graphqlScalars.JSONResolver),r.addScalarType("Date",graphqlScalars.DateResolver),r.addScalarType("DateTime",graphqlScalars.DateTimeISOResolver),t?.query||r.queryType({}),t?.subscription||r.subscriptionType({}),t?.mutation||r.mutationType({}),{schemaBuilder:r}};var _=({db:e,schemaBuilder:t,enumImplementer:x})=>{let r=new Map;return ({tableName:i,name:d,nativeTableName:m})=>{let p=e._.schema[i];if(m){let D=Object.values(e._.schema).find(g=>g.dbName===m);D&&(p=D);}if(!p)throw new T(`Could not find schema for ${i.toString()} (whereArg)`);let l=d??`${C(casing.toCamelCase(i.toString()))}WhereInputArgument`,s=r.get(l);return s||(s={inputType:t.inputType(l,{fields:f=>{let S=n=>{let c=A(n);switch(c){case "Int":return f.int({required:false});case "String":return f.string({required:false});case "Boolean":return f.boolean({required:false});case "Date":return f.field({type:"Date",required:false});case "DateTime":return f.field({type:"DateTime",required:false});case "Float":return f.float({required:false});case "ID":return f.id({required:false});case "JSON":return f.field({type:"JSON",required:false});default:throw new T(`Unsupported argument type ${c} for column ${n}`)}};return {...Object.entries(p.columns).reduce((n,[c,y])=>{if(E(y)){let R=B(y),h=x({enumName:R.enumName});n[c]=f.field({type:h,required:false});}else n[c]=S(y.getSQLType());return n},{})}}}),transformArgumentToQueryCondition:f=>{if(!f)return;let S=n=>{let c=p.columns[n],y=f[n];if(y)return drizzleOrm.eq(c,y)},u=Object.keys(p.columns).map(S);return drizzleOrm.and(...u)}},r.set(l,s),s)}};var pe=e=>{let t=N(e),x=Q({...e,abilityBuilder:t}),{makePubSubInstance:r,pubsub:o}=F({...e}),{schemaBuilder:i}=G({...e,pubsub:o}),d=O({...e,schemaBuilder:i}),m=_({...e,schemaBuilder:i,enumImplementer:d}),p=L({...e,schemaBuilder:i,makePubSubInstance:r,argImplementer:m,enumImplementer:d}),l=j({...e,schemaBuilder:i,argImplementer:m,makePubSubInstance:r});return {abilityBuilder:t,schemaBuilder:i,createYoga:a=>graphqlYoga.createYoga({...a,schema:i.toSchema(),context:x}),object:p,arg:m,query:l,pubsub:r,enum_:d}};
2
- exports.RumbleError=T;exports.assertFindFirstExists=z;exports.assertFirstEntryExists=Z;exports.rumble=pe;//# sourceMappingURL=index.cjs.map
1
+ 'use strict';var graphqlYoga=require('graphql-yoga'),drizzleOrm=require('drizzle-orm'),casing=require('drizzle-orm/casing'),de=require('@pothos/core'),ye=require('@pothos/plugin-drizzle'),fe=require('@pothos/plugin-smart-subscriptions'),graphqlScalars=require('graphql-scalars');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var de__default=/*#__PURE__*/_interopDefault(de);var ye__default=/*#__PURE__*/_interopDefault(ye);var fe__default=/*#__PURE__*/_interopDefault(fe);function O(e){return typeof e=="object"&&e!==null}function Q(e,t){throw new Error("Unexpected invariant triggered.")}var Z=/\r\n|[\n\r]/g;function v(e,t){let m=0,o=1;for(let n of e.body.matchAll(Z)){if(typeof n.index=="number"||Q(),n.index>=t)break;m=n.index+n[0].length,o+=1;}return {line:o,column:t+1-m}}function k(e){return L(e.source,v(e.source,e.start))}function L(e,t){let m=e.locationOffset.column-1,o="".padStart(m)+e.body,n=t.line-1,i=e.locationOffset.line-1,p=t.line+i,l=t.line===1?m:0,s=t.column+l,y=`${e.name}:${p}:${s}
2
+ `,r=o.split(/\r\n|[\n\r]/g),a=r[n];if(a.length>120){let f=Math.floor(s/80),C=s%80,u=[];for(let g=0;g<a.length;g+=80)u.push(a.slice(g,g+80));return y+w([[`${p} |`,u[0]],...u.slice(1,f+1).map(g=>["|",g]),["|","^".padStart(C)],["|",u[f+1]]])}return y+w([[`${p-1} |`,r[n-1]],[`${p} |`,a],["|","^".padStart(s)],[`${p+1} |`,r[n+1]]])}function w(e){let t=e.filter(([o,n])=>n!==void 0),m=Math.max(...t.map(([o])=>o.length));return t.map(([o,n])=>o.padStart(m)+(n?" "+n:"")).join(`
3
+ `)}function ee(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 B=class e extends Error{constructor(t,...m){var o,n,i;let{nodes:p,source:l,positions:s,path:y,originalError:r,extensions:a}=ee(m);super(t),this.name="GraphQLError",this.path=y??void 0,this.originalError=r??void 0,this.nodes=F(Array.isArray(p)?p:p?[p]:void 0);let f=F((o=this.nodes)===null||o===void 0?void 0:o.map(u=>u.loc).filter(u=>u!=null));this.source=l??(f==null||(n=f[0])===null||n===void 0?void 0:n.source),this.positions=s??f?.map(u=>u.start),this.locations=s&&l?s.map(u=>v(l,u)):f?.map(u=>v(u.source,u.start));let C=O(r?.extensions)?r?.extensions:void 0;this.extensions=(i=a??C)!==null&&i!==void 0?i: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
+
5
+ `+k(m.loc));else if(this.source&&this.locations)for(let m of this.locations)t+=`
6
+
7
+ `+L(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 F(e){return e===void 0||e.length===0?void 0:e}var S=class extends Error{constructor(t){super(t),this.name="RumbleError";}},P=class extends B{};var A=(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 A(e,"Distinct")}function oe(e){return typeof e!="function"}function ie(e){return typeof e=="function"&&e.constructor.name!=="AsyncFunction"}var V=({db:e})=>{let t=e._.schema,m={},o={},n=i=>({allow:p=>{let l=o[i];l||(l={},o[i]=l);let s=Array.isArray(p)?p:[p];for(let y of s){let r=l[y];r||(r="wildcard",l[y]=r);}return {when:y=>{for(let r of s)l[r]==="wildcard"&&(l[r]=[]),l[r].push(y);}}}});for(let i of Object.keys(e.query))m[i]=n(i);return {...m,registeredConditions:o,buildWithUserContext:i=>{let p={},l=s=>({filter:(y,r)=>{let a=o[s];a||(a={});let f=a[y];if(f==="wildcard")return {where:r?.inject?.where,columns:r?.inject?.columns,limit:r?.inject?.limit};let C=()=>{let x=t[s].primaryKey.at(0);if(!x)throw new S(`No primary key found for entity ${s.toString()}`);let z=j(x.getSQLType());return {where:drizzleOrm.and(drizzleOrm.eq(x,z.value1),drizzleOrm.eq(x,z.value2))}};(!a||!f)&&(f=[C()]);let u=f.filter(oe),g=f.filter(ie).map(x=>x(i)),h=[...u,...g];h.filter(x=>x!==void 0).length===0&&h.push(C());let d;for(let x of h)x?.limit&&(d===void 0||x.limit>d)&&(d=x.limit);r?.inject?.limit&&d<r.inject.limit&&(d=r.inject.limit);let c;for(let x of [...h,r?.inject??{}])x?.columns&&(c===void 0?c=x.columns:c={...c,...x.columns});let b=h.filter(x=>x?.where).map(x=>x?.where),T=b.length>0?drizzleOrm.or(...b):void 0;return r?.inject?.where&&(T=T?drizzleOrm.and(T,r.inject.where):r.inject.where),{where:T,columns:c,limit:d}}});for(let s of Object.keys(e.query))p[s]=l(s);return p}}};var $=({context:e,abilityBuilder:t})=>async m=>{let o=e?await e(m):{};return {...o,abilities:t.buildWithUserContext(o)}};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 K=({db:e,schemaBuilder:t})=>{let m=new Map;return ({enumVariableName:n,name:i,enumValues:p,enumName:l})=>{let s=e._.fullSchema,y;if(n?y=s[n]:p?y=Object.values(s).filter(I).map(E).find(C=>C.enumValues===p):l&&(y=Object.values(s).filter(I).map(E).find(C=>C.enumName===l)),!y)throw new S(`Could not determine enum structure! (${String(n)}, ${p}, ${l})`);let r=i??`${R(casing.toCamelCase(y.enumName.toString()))}Enum`,a=m.get(r);return a||(a=t.enumType(r,{values:y.enumValues}),m.set(r,a),a)}};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 A(e,"SQL to GQL")}var ae="RUMBLE_SUBSCRIPTION_NOTIFICATION",ue="REMOVED",me="UPDATED",le="CREATED";function U({action:e,tableName:t,primaryKeyValue:m}){let o;switch(e){case "created":o=le;break;case "removed":o=ue;break;case "updated":o=me;break;default:throw new Error(`Unknown action: ${e}`)}return `${ae}/${t}${m?`/${m}`:""}/${o}`}var W=({subscriptions:e})=>{let t=e?graphqlYoga.createPubSub(...e):graphqlYoga.createPubSub();return {pubsub:t,makePubSubInstance:({tableName:o})=>({registerOnInstance({instance:n,action:i,primaryKeyValue:p}){let l=U({tableName:o.toString(),action:i,primaryKeyValue:p});n.register(l);},created(){let n=U({tableName:o.toString(),action:"created"});return t.publish(n)},removed(n){let i=U({tableName:o.toString(),action:"removed"});return t.publish(i)},updated(n){let i=U({tableName:o.toString(),action:"updated",primaryKeyValue:n});return t.publish(i)}})}};var J=({db:e,schemaBuilder:t,makePubSubInstance:m,argImplementer:o,enumImplementer:n})=>({tableName:i,name:p,readAction:l="read"})=>{let s=e._.schema[i];if(!s)throw new S(`Could not find schema for ${i.toString()} (object)`);let y=s.primaryKey.at(0)?.name;y||console.warn(`Could not find primary key for ${i.toString()}. Cannot register subscriptions!`);let{registerOnInstance:r}=m({tableName:i});return t.drizzleObject(i,{name:p??R(i.toString()),subscribe:(a,f,C)=>{if(!y)return;let u=f[y];if(!u){console.warn(`Could not find primary key value for ${JSON.stringify(f)}. Cannot register subscription!`);return}r({instance:a,action:"updated",primaryKeyValue:u});},fields:a=>{let f=(g,h,d)=>{let c=N(g);switch(c){case "Int":return a.exposeInt(h,{nullable:d});case "String":return a.exposeString(h,{nullable:d});case "Boolean":return a.exposeBoolean(h,{nullable:d});case "Date":return a.field({type:"Date",resolve:b=>b[h],nullable:d});case "DateTime":return a.field({type:"DateTime",resolve:b=>b[h],nullable:d});case "Float":return a.exposeFloat(h,{nullable:d});case "ID":return a.exposeID(h,{nullable:d});case "JSON":return a.field({type:"JSON",resolve:b=>b[h],nullable:d});default:throw new S(`Unsupported object type ${c} for column ${h}`)}},C=Object.entries(s.columns).reduce((g,[h,d])=>{if(I(d)){let c=E(d),b=n({enumName:c.enumName});g[h]=a.field({type:b,resolve:T=>T[h],nullable:!d.notNull});}else g[h]=f(d.getSQLType(),h,!d.notNull);return g},{}),u=Object.entries(s.relations).reduce((g,[h,d])=>{let{inputType:c,transformArgumentToQueryCondition:b}=o({tableName:d.referencedTableName,nativeTableName:d.referencedTableName}),T=false;return d instanceof drizzleOrm.One&&(T=!d.isNullable),g[h]=a.relation(h,{args:{where:a.arg({type:c,required:false})},nullable:T,query:(D,x)=>x.abilities[d.referencedTableName].filter(l,{inject:{where:b(D.where)}})}),g},{});return {...C,...u}}})};var q=e=>{if(!e)throw new P("Value not found but required (findFirst)");return e},pe=e=>{let t=e.at(0);if(!t)throw new P("Value not found but required (firstEntry)");return t};var Y=({db:e,schemaBuilder:t,argImplementer:m,makePubSubInstance:o})=>({tableName:n,readAction:i="read",listAction:p="read"})=>{let l=e._.schema[n];if(!l)throw new S(`Could not find schema for ${n.toString()} (query)`);l.primaryKey.at(0)?.name||console.warn(`Could not find primary key for ${n.toString()}. Cannot register subscriptions!`);let{inputType:y,transformArgumentToQueryCondition:r}=m({tableName:n}),{registerOnInstance:a}=o({tableName:n});return t.queryFields(f=>({[`findMany${R(n.toString())}`]:f.drizzleField({type:[n],nullable:false,smartSubscription:true,subscribe:(C,u,g,h,d)=>{a({instance:C,action:"created"}),a({instance:C,action:"removed"});},args:{where:f.arg({type:y,required:false})},resolve:(C,u,g,h,d)=>{let c=h.abilities[n].filter(p,{inject:{where:r(g.where)}}),b=C(c);return c.columns&&(b.columns=c.columns),e.query[n].findMany(b)}}),[`findFirst${R(n.toString())}`]:f.drizzleField({type:n,nullable:false,smartSubscription:true,args:{where:f.arg({type:y,required:false})},resolve:(C,u,g,h,d)=>{let c=h.abilities[n].filter(i,{inject:{where:r(g.where)}}),b=C(c);return c.columns&&(b.columns=c.columns),e.query[n].findFirst(b).then(q)}})}))};var H=({db:e,disableDefaultObjects:t,pubsub:m,pothosConfig:o})=>{let n=new de__default.default({plugins:[ye__default.default,fe__default.default,...o?.plugins??[]],...o,drizzle:{client:e},smartSubscriptions:{...fe.subscribeOptionsFromIterator((i,p)=>m.subscribe(i))}});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`,X=({db:e,schemaBuilder:t,enumImplementer:m})=>{let o=new Map,n=({tableName:i,name:p,nativeTableName:l})=>{let s=e._.schema[i];if(l){let f=Object.values(e._.schema).find(C=>C.dbName===l);f&&(s=f);}if(!s)throw new S(`Could not find schema for ${i.toString()} (whereArg)`);let y=p??Re(s.dbName),r=o.get(y);return r||(r={inputType:t.inputType(y,{fields:u=>{let g=c=>{let b=N(c);switch(b){case "Int":return u.int({required:false});case "String":return u.string({required:false});case "Boolean":return u.boolean({required:false});case "Date":return u.field({type:"Date",required:false});case "DateTime":return u.field({type:"DateTime",required:false});case "Float":return u.float({required:false});case "ID":return u.id({required:false});case "JSON":return u.field({type:"JSON",required:false});default:throw new S(`Unsupported argument type ${b} for column ${c}`)}},h=Object.entries(s.columns).reduce((c,[b,T])=>{if(I(T)){let D=E(T),x=m({enumName:D.enumName});c[b]=u.field({type:x,required:false});}else c[b]=g(T.getSQLType());return c},{}),d=Object.entries(s.relations).reduce((c,[b,T])=>{let D=n({tableName:T.referencedTableName,nativeTableName:T.referencedTableName});return c[b]=u.field({type:D.inputType,required:false}),c},{});return {...h,...d}}}),transformArgumentToQueryCondition:u=>{if(!u)return;let g=c=>{let b=s.columns[c],T=u[c];if(T)return drizzleOrm.eq(b,T)},h=c=>{let b=s.relations[c],T=u[c];if(!T)return;let D=n({tableName:b.referencedTableName,nativeTableName:b.referencedTableName}).transformArgumentToQueryCondition;return D(T)},d=[...Object.keys(s.columns).map(g),...Object.keys(s.relations).map(h)];return drizzleOrm.and(...d)}},o.set(y,r),r)};return n};var Ee=e=>{let t=V(e),m=$({...e,abilityBuilder:t}),{makePubSubInstance:o,pubsub:n}=W({...e}),{schemaBuilder:i}=H({...e,pubsub:n}),p=K({...e,schemaBuilder:i}),l=X({...e,schemaBuilder:i,enumImplementer:p}),s=J({...e,schemaBuilder:i,makePubSubInstance:o,argImplementer:l,enumImplementer:p}),y=Y({...e,schemaBuilder:i,argImplementer:l,makePubSubInstance:o});return {abilityBuilder:t,schemaBuilder:i,createYoga:a=>graphqlYoga.createYoga({...a,schema:i.toSchema(),context:m}),object:s,arg:l,query:y,pubsub:o,enum_:p}};
8
+ exports.RumbleError=S;exports.RumbleErrorSafe=P;exports.assertFindFirstExists=q;exports.assertFirstEntryExists=pe;exports.rumble=Ee;//# sourceMappingURL=index.cjs.map
3
9
  //# sourceMappingURL=index.cjs.map