@m1212e/rumble 0.16.41 → 0.16.47
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/client.cjs +3 -3
- package/out/client.cjs.map +1 -1
- package/out/client.mjs +3 -3
- package/out/client.mjs.map +1 -1
- package/out/index.cjs +206 -5
- package/out/index.cjs.map +1 -1
- package/out/index.d.cts +21 -78
- package/out/index.d.cts.map +1 -1
- package/out/index.d.mts +21 -78
- package/out/index.d.mts.map +1 -1
- package/out/index.mjs +206 -5
- package/out/index.mjs.map +1 -1
- package/package.json +16 -16
package/out/index.cjs
CHANGED
|
@@ -209,7 +209,7 @@ function mapNullFieldsToUndefined(obj) {
|
|
|
209
209
|
}
|
|
210
210
|
//#endregion
|
|
211
211
|
//#region package.json
|
|
212
|
-
var version = "0.16.
|
|
212
|
+
var version = "0.16.47";
|
|
213
213
|
//#endregion
|
|
214
214
|
//#region lib/helpers/mergeFilters.ts
|
|
215
215
|
function mergeFilters(filterA, filterB) {
|
|
@@ -375,6 +375,9 @@ const createAbilityBuilder = ({ db, actions, defaultLimit, otel }) => {
|
|
|
375
375
|
const runtimeFilters = /* @__PURE__ */ new Map();
|
|
376
376
|
for (const action of actions) if (!runtimeFilters.has(action)) runtimeFilters.set(action, []);
|
|
377
377
|
return {
|
|
378
|
+
/**
|
|
379
|
+
* Allows to perform a specific action on a specific entity
|
|
380
|
+
*/
|
|
378
381
|
allow: (action) => {
|
|
379
382
|
if (hasBeenBuilt) throw new RumbleError("You can't call allow() after the ability builder has been built. Please ensure that you register all abilities before accessing them.");
|
|
380
383
|
const actions = Array.isArray(action) ? action : [action];
|
|
@@ -385,24 +388,58 @@ const createAbilityBuilder = ({ db, actions, defaultLimit, otel }) => {
|
|
|
385
388
|
queryFilters.set(action, filters);
|
|
386
389
|
}
|
|
387
390
|
}
|
|
388
|
-
return {
|
|
391
|
+
return {
|
|
392
|
+
/**
|
|
393
|
+
* Restricts the allowed actions to a filter
|
|
394
|
+
* @example
|
|
395
|
+
* ```ts
|
|
396
|
+
* abilityBuilder.users.allow(["read", "update", "delete"]).when(({ userId }) => ({
|
|
397
|
+
* where: {
|
|
398
|
+
* id: userId,
|
|
399
|
+
* },
|
|
400
|
+
* }));
|
|
401
|
+
* ```
|
|
402
|
+
*/
|
|
403
|
+
when: (queryFilter) => {
|
|
389
404
|
for (const action of actions) {
|
|
390
405
|
if (queryFilters.get(action) === "unrestricted") queryFilters.set(action, []);
|
|
391
406
|
queryFilters.get(action).push(queryFilter);
|
|
392
407
|
}
|
|
393
408
|
} };
|
|
394
409
|
},
|
|
410
|
+
/**
|
|
411
|
+
* Allows to register an application level filter to restrict some results
|
|
412
|
+
* which were returned by a query
|
|
413
|
+
*/
|
|
395
414
|
filter: (action) => {
|
|
396
415
|
const actions = Array.isArray(action) ? action : [action];
|
|
397
416
|
return {
|
|
417
|
+
/**
|
|
418
|
+
* Allows to register an application level prefetch to fetch some data
|
|
419
|
+
* which could be useful for later filtering the results. The prefetch
|
|
420
|
+
* function will be called with the user context but unlike the actual
|
|
421
|
+
* filter function, it will not have access to the result of the query
|
|
422
|
+
* and therefore can be run in parallel with underlying query resolver.
|
|
423
|
+
* A typical use case is to fetch some data which is not directly
|
|
424
|
+
* related to the query but to the context only. So e.g. fetching the
|
|
425
|
+
* user's permissions from an external system and then later applying
|
|
426
|
+
* the filter based on those permissions.
|
|
427
|
+
*/
|
|
398
428
|
prefetch: (prefetch) => {
|
|
399
|
-
return {
|
|
429
|
+
return {
|
|
430
|
+
/**
|
|
431
|
+
* The actual filter function to apply. Returns the allowed values
|
|
432
|
+
*/
|
|
433
|
+
by: (explicitFilter) => {
|
|
400
434
|
for (const action of actions) runtimeFilters.get(action).push({
|
|
401
435
|
filter: explicitFilter,
|
|
402
436
|
prefetch
|
|
403
437
|
});
|
|
404
438
|
} };
|
|
405
439
|
},
|
|
440
|
+
/**
|
|
441
|
+
* The actual filter function to apply. Returns the allowed values
|
|
442
|
+
*/
|
|
406
443
|
by: (explicitFilter) => {
|
|
407
444
|
for (const action of actions) runtimeFilters.get(action).push({ filter: explicitFilter });
|
|
408
445
|
}
|
|
@@ -417,6 +454,10 @@ const createAbilityBuilder = ({ db, actions, defaultLimit, otel }) => {
|
|
|
417
454
|
const buildersPerTable = Object.fromEntries(Object.keys(db.query).map((tableName) => [tableName, createBuilderForTable()]));
|
|
418
455
|
return {
|
|
419
456
|
...buildersPerTable,
|
|
457
|
+
/**
|
|
458
|
+
* @internal
|
|
459
|
+
* @ignore
|
|
460
|
+
*/
|
|
420
461
|
_: {
|
|
421
462
|
registeredFilters({ action, table }) {
|
|
422
463
|
return buildersPerTable[table]._.runtimeFilters.get(action);
|
|
@@ -461,12 +502,27 @@ const createAbilityBuilder = ({ db, actions, defaultLimit, otel }) => {
|
|
|
461
502
|
return filters?.where ? (0, drizzle_orm.relationsFilterToSQL)(tableSchema.foundRelation.table, filters.where, tableSchema.relations, db._.relations, casing) : void 0;
|
|
462
503
|
});
|
|
463
504
|
if (filters?.columns) return {
|
|
505
|
+
/**
|
|
506
|
+
* Query filters for the drizzle query API.
|
|
507
|
+
* @example
|
|
508
|
+
* ```ts
|
|
509
|
+
* author: t.relation("author", {
|
|
510
|
+
* query: (_args, ctx) => ctx.abilities.users.filter("read").query.single,
|
|
511
|
+
* }),
|
|
512
|
+
* ´´´
|
|
513
|
+
*/
|
|
464
514
|
query: {
|
|
515
|
+
/**
|
|
516
|
+
* For find first calls
|
|
517
|
+
*/
|
|
465
518
|
single: {
|
|
466
519
|
extras: filters?.extras,
|
|
467
520
|
where: filters?.where,
|
|
468
521
|
columns: filters?.columns
|
|
469
522
|
},
|
|
523
|
+
/**
|
|
524
|
+
* For find many calls
|
|
525
|
+
*/
|
|
470
526
|
many: {
|
|
471
527
|
extras: filters?.extras,
|
|
472
528
|
where: filters?.where,
|
|
@@ -476,16 +532,50 @@ const createAbilityBuilder = ({ db, actions, defaultLimit, otel }) => {
|
|
|
476
532
|
}
|
|
477
533
|
}
|
|
478
534
|
},
|
|
535
|
+
/**
|
|
536
|
+
* Query filters for the drizzle SQL API as used in e.g. updates.
|
|
537
|
+
* @example
|
|
538
|
+
*
|
|
539
|
+
* ```ts
|
|
540
|
+
* await db
|
|
541
|
+
* .update(schema.users)
|
|
542
|
+
* .set({
|
|
543
|
+
* name: args.newName,
|
|
544
|
+
* })
|
|
545
|
+
* .where(
|
|
546
|
+
* and(
|
|
547
|
+
* eq(schema.users.id, args.userId),
|
|
548
|
+
* ctx.abilities.users.filter("update").sql.where,
|
|
549
|
+
* ),
|
|
550
|
+
* );
|
|
551
|
+
* ```
|
|
552
|
+
*
|
|
553
|
+
*/
|
|
479
554
|
sql: { get where() {
|
|
480
555
|
return sqlTransformedWhere();
|
|
481
556
|
} }
|
|
482
557
|
};
|
|
483
558
|
else return {
|
|
559
|
+
/**
|
|
560
|
+
* Query filters for the drizzle query API.
|
|
561
|
+
* @example
|
|
562
|
+
* ```ts
|
|
563
|
+
* author: t.relation("author", {
|
|
564
|
+
* query: (_args, ctx) => ctx.abilities.users.filter("read").query.single,
|
|
565
|
+
* }),
|
|
566
|
+
* ´´´
|
|
567
|
+
*/
|
|
484
568
|
query: {
|
|
569
|
+
/**
|
|
570
|
+
* For find first calls
|
|
571
|
+
*/
|
|
485
572
|
single: {
|
|
486
573
|
extras: filters?.extras,
|
|
487
574
|
where: filters?.where
|
|
488
575
|
},
|
|
576
|
+
/**
|
|
577
|
+
* For find many calls
|
|
578
|
+
*/
|
|
489
579
|
many: {
|
|
490
580
|
extras: filters?.extras,
|
|
491
581
|
where: filters?.where,
|
|
@@ -494,6 +584,25 @@ const createAbilityBuilder = ({ db, actions, defaultLimit, otel }) => {
|
|
|
494
584
|
}
|
|
495
585
|
}
|
|
496
586
|
},
|
|
587
|
+
/**
|
|
588
|
+
* Query filters for the drizzle SQL API as used in e.g. updates.
|
|
589
|
+
* @example
|
|
590
|
+
*
|
|
591
|
+
* ```ts
|
|
592
|
+
* await db
|
|
593
|
+
* .update(schema.users)
|
|
594
|
+
* .set({
|
|
595
|
+
* name: args.newName,
|
|
596
|
+
* })
|
|
597
|
+
* .where(
|
|
598
|
+
* and(
|
|
599
|
+
* eq(schema.users.id, args.userId),
|
|
600
|
+
* ctx.abilities.users.filter("update").sql.where,
|
|
601
|
+
* ),
|
|
602
|
+
* );
|
|
603
|
+
* ```
|
|
604
|
+
*
|
|
605
|
+
*/
|
|
497
606
|
sql: { get where() {
|
|
498
607
|
return sqlTransformedWhere();
|
|
499
608
|
} }
|
|
@@ -737,7 +846,7 @@ const createWhereArgImplementer = ({ db, schemaBuilder, enumImplementer }) => {
|
|
|
737
846
|
//#region lib/client/client.ts
|
|
738
847
|
const clientCreatorImplementer = ({ builtSchema }) => {
|
|
739
848
|
const clientCreator = async ({ apiUrl, outputPath, rumbleImportPath, useExternalUrqlClient, removeExisting, forceReactivity, autoIncludeIdField = false }) => {
|
|
740
|
-
if (process.env.NODE_ENV !== "development") console.warn(`Running rumble client generation in non development mode. Are you sure this is correct? Called
|
|
849
|
+
if (process.env.NODE_ENV !== "development") console.warn(`Running rumble client generation in non development mode. Are you sure this is correct? Called with arguments: ${JSON.stringify({
|
|
741
850
|
outputPath,
|
|
742
851
|
apiUrl,
|
|
743
852
|
rumbleImportPath,
|
|
@@ -1201,6 +1310,9 @@ const createPubSubInstance = ({ subscriptions }) => {
|
|
|
1201
1310
|
return `${SUBSCRIPTION_NOTIFIER_RUMBLE_PREFIX}/${tableName}${primaryKeyValue ? `/${primaryKeyValue}` : ""}/${actionKey}`;
|
|
1202
1311
|
}
|
|
1203
1312
|
return {
|
|
1313
|
+
/**
|
|
1314
|
+
* Call this when you want to register a subscription on an instance to this table
|
|
1315
|
+
*/
|
|
1204
1316
|
registerOnInstance({ instance, action, primaryKeyValue }) {
|
|
1205
1317
|
const key = makePubSubKey({
|
|
1206
1318
|
tableName: table.toString(),
|
|
@@ -1209,6 +1321,9 @@ const createPubSubInstance = ({ subscriptions }) => {
|
|
|
1209
1321
|
});
|
|
1210
1322
|
instance.register(key);
|
|
1211
1323
|
},
|
|
1324
|
+
/**
|
|
1325
|
+
* Call this when you created an entity of this table
|
|
1326
|
+
*/
|
|
1212
1327
|
created() {
|
|
1213
1328
|
const key = makePubSubKey({
|
|
1214
1329
|
tableName: table.toString(),
|
|
@@ -1216,6 +1331,9 @@ const createPubSubInstance = ({ subscriptions }) => {
|
|
|
1216
1331
|
});
|
|
1217
1332
|
return pubsub.publish(key);
|
|
1218
1333
|
},
|
|
1334
|
+
/**
|
|
1335
|
+
* Call this when you removed one or more entities of this table
|
|
1336
|
+
*/
|
|
1219
1337
|
removed() {
|
|
1220
1338
|
const key = makePubSubKey({
|
|
1221
1339
|
tableName: table.toString(),
|
|
@@ -1223,6 +1341,9 @@ const createPubSubInstance = ({ subscriptions }) => {
|
|
|
1223
1341
|
});
|
|
1224
1342
|
return pubsub.publish(key);
|
|
1225
1343
|
},
|
|
1344
|
+
/**
|
|
1345
|
+
* Call this when you updated one or more entities of this table
|
|
1346
|
+
*/
|
|
1226
1347
|
updated(primaryKeyValue) {
|
|
1227
1348
|
const keys = (Array.isArray(primaryKeyValue) ? primaryKeyValue : [primaryKeyValue]).map((primaryKeyValue) => makePubSubKey({
|
|
1228
1349
|
tableName: table.toString(),
|
|
@@ -1682,21 +1803,101 @@ export const db = drizzle(
|
|
|
1682
1803
|
});
|
|
1683
1804
|
};
|
|
1684
1805
|
return {
|
|
1806
|
+
/**
|
|
1807
|
+
* The ability builder. Use it to declare whats allowed for each entity in your DB.
|
|
1808
|
+
*
|
|
1809
|
+
* @example
|
|
1810
|
+
*
|
|
1811
|
+
* ```ts
|
|
1812
|
+
* // users can edit themselves
|
|
1813
|
+
abilityBuilder.users
|
|
1814
|
+
.allow(["read", "update", "delete"])
|
|
1815
|
+
.when(({ userId }) => ({ where: eq(schema.users.id, userId) }));
|
|
1816
|
+
|
|
1817
|
+
// everyone can read posts
|
|
1818
|
+
abilityBuilder.posts.allow("read");
|
|
1819
|
+
*
|
|
1820
|
+
* ```
|
|
1821
|
+
*/
|
|
1685
1822
|
abilityBuilder,
|
|
1823
|
+
/**
|
|
1824
|
+
* The pothos schema builder. See https://pothos-graphql.dev/docs/plugins/drizzle
|
|
1825
|
+
*/
|
|
1686
1826
|
schemaBuilder,
|
|
1827
|
+
/**
|
|
1828
|
+
* Creates the native yoga instance. Can be used to run an actual HTTP server.
|
|
1829
|
+
*
|
|
1830
|
+
* @example
|
|
1831
|
+
*
|
|
1832
|
+
* ```ts
|
|
1833
|
+
* import { createServer } from "node:http";
|
|
1834
|
+
* const server = createServer(createYoga());
|
|
1835
|
+
* server.listen(3000, () => {
|
|
1836
|
+
* console.info("Visit http://localhost:3000/graphql");
|
|
1837
|
+
* });
|
|
1838
|
+
* ```
|
|
1839
|
+
* https://the-guild.dev/graphql/yoga-server/docs#server
|
|
1840
|
+
*/
|
|
1687
1841
|
createYoga,
|
|
1842
|
+
/**
|
|
1843
|
+
* Creates a sofa instance to offer a REST API.
|
|
1844
|
+
*
|
|
1845
|
+
* ```ts
|
|
1846
|
+
* import express from "express";
|
|
1847
|
+
*
|
|
1848
|
+
* const app = express();
|
|
1849
|
+
* const sofa = createSofa(...);
|
|
1850
|
+
*
|
|
1851
|
+
* app.use("/api", useSofa({ schema }));
|
|
1852
|
+
* ```
|
|
1853
|
+
* https://the-guild.dev/graphql/sofa-api/docs#usage
|
|
1854
|
+
*/
|
|
1688
1855
|
createSofa,
|
|
1856
|
+
/**
|
|
1857
|
+
* A function for creating default objects for your schema
|
|
1858
|
+
*/
|
|
1689
1859
|
object,
|
|
1860
|
+
/**
|
|
1861
|
+
* A function for creating where args to filter entities
|
|
1862
|
+
*/
|
|
1690
1863
|
whereArg,
|
|
1864
|
+
/**
|
|
1865
|
+
* A function for creating order args to sort entities
|
|
1866
|
+
*/
|
|
1691
1867
|
orderArg,
|
|
1868
|
+
/**
|
|
1869
|
+
* A function for creating default READ queries.
|
|
1870
|
+
* Make sure the objects for the table you are creating the queries for are implemented
|
|
1871
|
+
*/
|
|
1692
1872
|
query,
|
|
1873
|
+
/**
|
|
1874
|
+
* A function for creating a pubsub instance for a table. Use this to publish or subscribe events
|
|
1875
|
+
*/
|
|
1693
1876
|
pubsub: makePubSubInstance,
|
|
1877
|
+
/**
|
|
1878
|
+
* A function to implement enums for graphql usage.
|
|
1879
|
+
* The other helpers use this helper internally so in most cases you do not have to
|
|
1880
|
+
* call this helper directly, unless you need the reference to an enum type
|
|
1881
|
+
*/
|
|
1694
1882
|
enum_,
|
|
1883
|
+
/**
|
|
1884
|
+
* Create a client to consume a rumble graphql api at the specified location.
|
|
1885
|
+
* Requires GraphQL, does not work with the SOFA REST API.
|
|
1886
|
+
*/
|
|
1695
1887
|
clientCreator: clientCreatorImplementer({
|
|
1696
1888
|
...rumbleInput,
|
|
1697
1889
|
builtSchema
|
|
1698
1890
|
}),
|
|
1699
|
-
|
|
1891
|
+
/**
|
|
1892
|
+
* A function for creating count queries for your tables
|
|
1893
|
+
*/
|
|
1894
|
+
countQuery,
|
|
1895
|
+
/**
|
|
1896
|
+
* The generated GraphQL schema. You can use this for example to create a GraphQL server with a different library than Yoga or to generate types with codegen.
|
|
1897
|
+
* When calling this function, the schema will be built for the first time and cached for later usage. So you can call this function multiple times without performance issues.
|
|
1898
|
+
* After calling, you cannot adjust the schema via the schema builder
|
|
1899
|
+
*/
|
|
1900
|
+
buildSchema: builtSchema
|
|
1700
1901
|
};
|
|
1701
1902
|
};
|
|
1702
1903
|
//#endregion
|