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