@m1212e/rumble 0.25.2 → 0.26.1

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/out/index.d.mts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { createRequire } from "node:module";
2
+ import { One, SQL, Table } from "drizzle-orm";
2
3
  import { GraphQLError, GraphQLScalarType, GraphQLSchema } from "graphql";
3
- import { EnvelopArmorPlugin } from "@escape.tech/graphql-armor";
4
4
  import { Tracer } from "@opentelemetry/api";
5
- import { YogaServerOptions, createPubSub } from "graphql-yoga";
6
- import { One, SQL, Table } from "drizzle-orm";
7
5
  import { TracingWrapperOptions } from "@pothos/tracing-opentelemetry";
6
+ import { EnvelopArmorPlugin } from "@escape.tech/graphql-armor";
7
+ import { YogaServerOptions, createPubSub } from "graphql-yoga";
8
8
  import { PgAsyncDatabase } from "drizzle-orm/pg-core";
9
9
  import { MySqlAsyncDatabase } from "drizzle-orm/mysql-core";
10
10
  import { SQLiteAsyncDatabase } from "drizzle-orm/sqlite-core";
@@ -17,140 +17,6 @@ import "@whatwg-node/fetch";
17
17
  import { useSofa } from "@m1212e/sofa-api";
18
18
  import { ServerOptions } from "graphql-ws";
19
19
  //#endregion
20
- //#region lib/helpers/asserts.d.ts
21
- /**
22
- *
23
- * Helper function to map a drizzle findFirst query result,
24
- * which may be optional, to a correct drizzle type.
25
- *
26
- * @throws RumbleError
27
- *
28
- * @example
29
- *
30
- * ```ts
31
- * schemaBuilder.queryFields((t) => {
32
- return {
33
- findFirstUser: t.drizzleField({
34
- type: UserRef,
35
- resolve: (query, root, args, ctx, info) => {
36
- return (
37
- db.query.users
38
- .findFirst({
39
- ...query,
40
- where: (await ctx.abilities.users.filter("read")).single.where,
41
- })
42
- // note that we need to manually raise an error if the value is not found
43
- .then(assertFindFirstExists)
44
- );
45
- },
46
- }),
47
- };
48
- });
49
- * ```
50
- */
51
- export declare const assertFindFirstExists: <T>(value: T | undefined) => T;
52
- /**
53
- *
54
- * Helper function to map a drizzle findFirst query result,
55
- * which may be optional, to a correct drizzle type.
56
- *
57
- * @throws RumbleError
58
- *
59
- * @example
60
- *
61
- * ```ts
62
- schemaBuilder.mutationFields((t) => {
63
- return {
64
- updateUsername: t.drizzleField({
65
- type: UserRef,
66
- args: {
67
- userId: t.arg.int({ required: true }),
68
- newName: t.arg.string({ required: true }),
69
- },
70
- resolve: (query, root, args, ctx, info) => {
71
- return db
72
- .update(schema.users)
73
- .set({
74
- name: args.newName,
75
- })
76
- .where(
77
- and(
78
- eq(schema.users.id, args.userId),
79
- (await ctx.abilities.users.filter("update")).single.where
80
- )
81
- )
82
- .returning({ id: schema.users.id, name: schema.users.name })
83
- // note that we need to manually raise an error if the value is not found
84
- .then(assertFirstEntryExists);
85
- },
86
- }),
87
- };
88
- });
89
- * ```
90
- */
91
- export declare const assertFirstEntryExists: <T>(value: T[]) => T;
92
- //#endregion
93
- //#region lib/helpers/mapNullFieldsToUndefined.d.ts
94
- /**
95
- * Helper to map null fields to undefined
96
- * @param obj The object to map
97
- * @returns The mapped object with all fields of 'null' transformed to 'undefined'
98
- *
99
- * This becomes useful for update mutations where you do not want to pass null (unset value in db)
100
- * but undefined (do not touch value in db) in case of a value not beeing set in the args of said mutation
101
- * @example
102
- * ```ts
103
- * updateUser: t.drizzleField({
104
- type: User,
105
- args: {
106
- id: t.arg.string({ required: true }),
107
- email: t.arg.string(),
108
- lastName: t.arg.string(),
109
- firstName: t.arg.string(),
110
- },
111
- resolve: async (query, root, args, ctx, info) => {
112
- const mappedArgs = mapNullFieldsToUndefined(args);
113
- const user = await db.transaction(async (tx) => {
114
- const user = await tx
115
- .update(schema.user)
116
- .set({
117
-
118
- // email: args.email ?? undefined,
119
- // lastName: args.lastName ?? undefined,
120
- // firstName: args.firstName ?? undefined,
121
-
122
- // becomes this
123
-
124
- email: mappedArgs.email,
125
- lastName: mappedArgs.lastName,
126
- firstName: mappedArgs.firstName,
127
- })
128
- .returning()
129
- .then(assertFirstEntryExists);
130
- return user;
131
- });
132
-
133
- pubsub.updated(user.id);
134
-
135
- return db.query.user
136
- .findFirst(
137
- query(
138
- (await ctx.abilities.user.filter('read')).merge(
139
- {
140
- where: { id: user.id },
141
- }
142
- 1).query.single,
143
- ),
144
- )
145
- .then(assertFindFirstExists);
146
- },
147
- }),
148
- *
149
- *
150
- * ```
151
- */
152
- export declare function mapNullFieldsToUndefined<T extends object>(obj: T): { [K in keyof T]: T[K] extends null ? undefined : Exclude<T[K], null>; };
153
- //#endregion
154
20
  //#region lib/types/drizzleInstanceType.d.ts
155
21
  type DrizzleInstance = PgAsyncDatabase<any, any> | SQLiteAsyncDatabase<any, any, any> | MySqlAsyncDatabase<any, any>;
156
22
  /**
@@ -439,6 +305,151 @@ type AbilityFilterResponse<DB extends DrizzleInstance, TableName extends TableRe
439
305
  merge: (filters: NonNullable<DrizzleQueryFunctionInput<DB, TableName>>) => AbilityFilter<DB, TableName>;
440
306
  };
441
307
  //#endregion
308
+ //#region lib/abilityBuilder/inputGuard.d.ts
309
+ type GuardedInput = {
310
+ where?: unknown;
311
+ orderBy?: unknown;
312
+ };
313
+ /**
314
+ * Restricts client supplied `where` and `orderBy` arguments to what the
315
+ * abilities of the request let the caller read, see `createInputGuard`.
316
+ */
317
+ export declare function guardFilterInput(abilities: object, table: string, action: string, input: GuardedInput): Promise<GuardedInput>;
318
+ //#endregion
319
+ //#region lib/helpers/asserts.d.ts
320
+ /**
321
+ *
322
+ * Helper function to map a drizzle findFirst query result,
323
+ * which may be optional, to a correct drizzle type.
324
+ *
325
+ * @throws RumbleError
326
+ *
327
+ * @example
328
+ *
329
+ * ```ts
330
+ * schemaBuilder.queryFields((t) => {
331
+ return {
332
+ findFirstUser: t.drizzleField({
333
+ type: UserRef,
334
+ resolve: (query, root, args, ctx, info) => {
335
+ return (
336
+ db.query.users
337
+ .findFirst({
338
+ ...query,
339
+ where: (await ctx.abilities.users.filter("read")).single.where,
340
+ })
341
+ // note that we need to manually raise an error if the value is not found
342
+ .then(assertFindFirstExists)
343
+ );
344
+ },
345
+ }),
346
+ };
347
+ });
348
+ * ```
349
+ */
350
+ export declare const assertFindFirstExists: <T>(value: T | undefined) => T;
351
+ /**
352
+ *
353
+ * Helper function to map a drizzle findFirst query result,
354
+ * which may be optional, to a correct drizzle type.
355
+ *
356
+ * @throws RumbleError
357
+ *
358
+ * @example
359
+ *
360
+ * ```ts
361
+ schemaBuilder.mutationFields((t) => {
362
+ return {
363
+ updateUsername: t.drizzleField({
364
+ type: UserRef,
365
+ args: {
366
+ userId: t.arg.int({ required: true }),
367
+ newName: t.arg.string({ required: true }),
368
+ },
369
+ resolve: (query, root, args, ctx, info) => {
370
+ return db
371
+ .update(schema.users)
372
+ .set({
373
+ name: args.newName,
374
+ })
375
+ .where(
376
+ and(
377
+ eq(schema.users.id, args.userId),
378
+ (await ctx.abilities.users.filter("update")).single.where
379
+ )
380
+ )
381
+ .returning({ id: schema.users.id, name: schema.users.name })
382
+ // note that we need to manually raise an error if the value is not found
383
+ .then(assertFirstEntryExists);
384
+ },
385
+ }),
386
+ };
387
+ });
388
+ * ```
389
+ */
390
+ export declare const assertFirstEntryExists: <T>(value: T[]) => T;
391
+ //#endregion
392
+ //#region lib/helpers/mapNullFieldsToUndefined.d.ts
393
+ /**
394
+ * Helper to map null fields to undefined
395
+ * @param obj The object to map
396
+ * @returns The mapped object with all fields of 'null' transformed to 'undefined'
397
+ *
398
+ * This becomes useful for update mutations where you do not want to pass null (unset value in db)
399
+ * but undefined (do not touch value in db) in case of a value not beeing set in the args of said mutation
400
+ * @example
401
+ * ```ts
402
+ * updateUser: t.drizzleField({
403
+ type: User,
404
+ args: {
405
+ id: t.arg.string({ required: true }),
406
+ email: t.arg.string(),
407
+ lastName: t.arg.string(),
408
+ firstName: t.arg.string(),
409
+ },
410
+ resolve: async (query, root, args, ctx, info) => {
411
+ const mappedArgs = mapNullFieldsToUndefined(args);
412
+ const user = await db.transaction(async (tx) => {
413
+ const user = await tx
414
+ .update(schema.user)
415
+ .set({
416
+
417
+ // email: args.email ?? undefined,
418
+ // lastName: args.lastName ?? undefined,
419
+ // firstName: args.firstName ?? undefined,
420
+
421
+ // becomes this
422
+
423
+ email: mappedArgs.email,
424
+ lastName: mappedArgs.lastName,
425
+ firstName: mappedArgs.firstName,
426
+ })
427
+ .returning()
428
+ .then(assertFirstEntryExists);
429
+ return user;
430
+ });
431
+
432
+ pubsub.updated(user.id);
433
+
434
+ return db.query.user
435
+ .findFirst(
436
+ query(
437
+ (await ctx.abilities.user.filter('read')).merge(
438
+ {
439
+ where: { id: user.id },
440
+ }
441
+ 1).query.single,
442
+ ),
443
+ )
444
+ .then(assertFindFirstExists);
445
+ },
446
+ }),
447
+ *
448
+ *
449
+ * ```
450
+ */
451
+ export declare function mapNullFieldsToUndefined<T extends object>(obj: T): { [K in keyof T]: T[K] extends null ? undefined : Exclude<T[K], null>; };
452
+ //#endregion
442
453
  //#region lib/scalars/address.d.ts
443
454
  /**
444
455
  * The shape of a postal address, modeled after the OIDC `address` claim
@@ -4695,6 +4706,7 @@ export declare const rumble: <UserContext extends Record<string, any>, DB extend
4695
4706
  maskColumns: (input: MaskColumnsInput<DB, Action>) => void | Promise<void>;
4696
4707
  maskedActions: (abilities: object, table: TableRelationNames<DB>) => Set<Action>;
4697
4708
  primaryKeyHidden: (abilities: object, row: object) => boolean;
4709
+ columnsHidden: (abilities: object, row: object, columns: string[], primaryKey: string[]) => boolean;
4698
4710
  registerReadAction(table: TableRelationNames<DB>, action: Action): void;
4699
4711
  readActionOf(table: TableRelationNames<DB>): Action;
4700
4712
  registeredFilters({ action, table }: {