@taruvi/refine-providers 1.0.8 → 1.0.10
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/dist/index.cjs +212 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -49
- package/dist/index.d.ts +19 -49
- package/dist/index.js +209 -68
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var sdk = require('@taruvi/sdk');
|
|
4
|
+
var DataLoader = require('dataloader');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var DataLoader__default = /*#__PURE__*/_interopDefault(DataLoader);
|
|
4
9
|
|
|
5
10
|
// src/dataProvider.ts
|
|
6
11
|
var REFINE_TO_SDK_OPERATOR = {
|
|
@@ -43,7 +48,7 @@ function applyFilters(query, filters) {
|
|
|
43
48
|
}
|
|
44
49
|
let sdkValue;
|
|
45
50
|
if (operator === "in" || operator === "nin") {
|
|
46
|
-
sdkValue = Array.isArray(value) ? value
|
|
51
|
+
sdkValue = Array.isArray(value) ? value : [value];
|
|
47
52
|
} else if (operator === "null" || operator === "nnull") {
|
|
48
53
|
sdkValue = true;
|
|
49
54
|
} else if (typeof value === "boolean" || typeof value === "number") {
|
|
@@ -114,7 +119,7 @@ function dataProvider(client) {
|
|
|
114
119
|
const tableName = getTableName(resource, taruviMeta);
|
|
115
120
|
const idColumn = getIdColumn(taruviMeta);
|
|
116
121
|
let query = new sdk.Database(client).from(tableName);
|
|
117
|
-
query = query.filter(idColumn, "in", ids.map(String)
|
|
122
|
+
query = query.filter(idColumn, "in", ids.map(String));
|
|
118
123
|
query = applyPopulate(query, taruviMeta);
|
|
119
124
|
const response = await query.execute();
|
|
120
125
|
return { data: response.data };
|
|
@@ -426,43 +431,119 @@ function functionsDataProvider(client) {
|
|
|
426
431
|
const baseApiUrl = `${config.baseUrl}/api/apps/${config.appSlug}`;
|
|
427
432
|
const functions = new sdk.Functions(client);
|
|
428
433
|
return {
|
|
429
|
-
|
|
430
|
-
|
|
434
|
+
/**
|
|
435
|
+
* Execute an edge function.
|
|
436
|
+
*
|
|
437
|
+
* @param resource - The function slug to execute
|
|
438
|
+
* @param variables - Parameters to pass to the function
|
|
439
|
+
* @param meta.async - Whether to execute asynchronously (default: false)
|
|
440
|
+
*/
|
|
441
|
+
create: async ({
|
|
442
|
+
resource,
|
|
443
|
+
variables,
|
|
444
|
+
meta
|
|
445
|
+
}) => {
|
|
431
446
|
const functionMeta = meta;
|
|
432
|
-
const response = await functions.execute(
|
|
447
|
+
const response = await functions.execute(resource, {
|
|
433
448
|
async: functionMeta?.async ?? false,
|
|
434
|
-
params:
|
|
449
|
+
params: variables
|
|
435
450
|
});
|
|
436
451
|
return { data: response.data };
|
|
437
452
|
},
|
|
438
453
|
getApiUrl: () => baseApiUrl,
|
|
439
|
-
// Edge functions don't support
|
|
454
|
+
// Edge functions don't support custom method - use create() instead
|
|
455
|
+
custom: async () => {
|
|
456
|
+
throw new Error(
|
|
457
|
+
"custom is not supported for edge functions. Use useCreate to execute functions."
|
|
458
|
+
);
|
|
459
|
+
},
|
|
460
|
+
// Edge functions don't support other CRUD operations
|
|
440
461
|
getList: async () => {
|
|
441
|
-
throw new Error(
|
|
462
|
+
throw new Error(
|
|
463
|
+
"getList is not supported for edge functions. Use useCreate to execute functions."
|
|
464
|
+
);
|
|
465
|
+
},
|
|
466
|
+
getOne: async () => {
|
|
467
|
+
throw new Error(
|
|
468
|
+
"getOne is not supported for edge functions. Use useCreate to execute functions."
|
|
469
|
+
);
|
|
470
|
+
},
|
|
471
|
+
getMany: async () => {
|
|
472
|
+
throw new Error(
|
|
473
|
+
"getMany is not supported for edge functions. Use useCreate to execute functions."
|
|
474
|
+
);
|
|
475
|
+
},
|
|
476
|
+
createMany: async () => {
|
|
477
|
+
throw new Error(
|
|
478
|
+
"createMany is not supported for edge functions. Use useCreate to execute functions."
|
|
479
|
+
);
|
|
480
|
+
},
|
|
481
|
+
update: async () => {
|
|
482
|
+
throw new Error(
|
|
483
|
+
"update is not supported for edge functions. Use useCreate to execute functions."
|
|
484
|
+
);
|
|
485
|
+
},
|
|
486
|
+
updateMany: async () => {
|
|
487
|
+
throw new Error(
|
|
488
|
+
"updateMany is not supported for edge functions. Use useCreate to execute functions."
|
|
489
|
+
);
|
|
490
|
+
},
|
|
491
|
+
deleteOne: async () => {
|
|
492
|
+
throw new Error(
|
|
493
|
+
"deleteOne is not supported for edge functions. Use useCreate to execute functions."
|
|
494
|
+
);
|
|
495
|
+
},
|
|
496
|
+
deleteMany: async () => {
|
|
497
|
+
throw new Error(
|
|
498
|
+
"deleteMany is not supported for edge functions. Use useCreate to execute functions."
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
function appDataProvider(client) {
|
|
504
|
+
const config = client.getConfig();
|
|
505
|
+
const baseApiUrl = `${config.baseUrl}/api/apps/${config.appSlug}`;
|
|
506
|
+
return {
|
|
507
|
+
getList: async (params) => {
|
|
508
|
+
const { resource } = params;
|
|
509
|
+
if (resource === "roles") {
|
|
510
|
+
const app = new sdk.App(client);
|
|
511
|
+
const response = await app.roles().execute();
|
|
512
|
+
return {
|
|
513
|
+
data: response.data || response,
|
|
514
|
+
total: response.total ?? (Array.isArray(response) ? response.length : response.data?.length ?? 0)
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
throw new Error(`Unknown app resource: ${resource}. Supported resources: roles`);
|
|
442
518
|
},
|
|
519
|
+
getApiUrl: () => baseApiUrl,
|
|
520
|
+
// App resources are read-only
|
|
443
521
|
getOne: async () => {
|
|
444
|
-
throw new Error("getOne is not supported for
|
|
522
|
+
throw new Error("getOne is not supported for app resources");
|
|
445
523
|
},
|
|
446
524
|
getMany: async () => {
|
|
447
|
-
throw new Error("getMany is not supported for
|
|
525
|
+
throw new Error("getMany is not supported for app resources");
|
|
448
526
|
},
|
|
449
527
|
create: async () => {
|
|
450
|
-
throw new Error("create is not supported for
|
|
528
|
+
throw new Error("create is not supported for app resources");
|
|
451
529
|
},
|
|
452
530
|
createMany: async () => {
|
|
453
|
-
throw new Error("createMany is not supported for
|
|
531
|
+
throw new Error("createMany is not supported for app resources");
|
|
454
532
|
},
|
|
455
533
|
update: async () => {
|
|
456
|
-
throw new Error("update is not supported for
|
|
534
|
+
throw new Error("update is not supported for app resources");
|
|
457
535
|
},
|
|
458
536
|
updateMany: async () => {
|
|
459
|
-
throw new Error("updateMany is not supported for
|
|
537
|
+
throw new Error("updateMany is not supported for app resources");
|
|
460
538
|
},
|
|
461
539
|
deleteOne: async () => {
|
|
462
|
-
throw new Error("deleteOne is not supported for
|
|
540
|
+
throw new Error("deleteOne is not supported for app resources");
|
|
463
541
|
},
|
|
464
542
|
deleteMany: async () => {
|
|
465
|
-
throw new Error("deleteMany is not supported for
|
|
543
|
+
throw new Error("deleteMany is not supported for app resources");
|
|
544
|
+
},
|
|
545
|
+
custom: async () => {
|
|
546
|
+
throw new Error("custom is not supported for app resources");
|
|
466
547
|
}
|
|
467
548
|
};
|
|
468
549
|
}
|
|
@@ -526,41 +607,68 @@ function analyticsDataProvider(client) {
|
|
|
526
607
|
const baseApiUrl = `${config.baseUrl}/api/apps/${config.appSlug}`;
|
|
527
608
|
const analytics = new sdk.Analytics(client);
|
|
528
609
|
return {
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
610
|
+
/**
|
|
611
|
+
* Execute an analytics query.
|
|
612
|
+
*
|
|
613
|
+
* @param resource - The query slug to execute
|
|
614
|
+
* @param variables - Parameters to pass to the query
|
|
615
|
+
*/
|
|
616
|
+
create: async ({
|
|
617
|
+
resource,
|
|
618
|
+
variables
|
|
619
|
+
}) => {
|
|
620
|
+
const response = await analytics.execute(resource, {
|
|
621
|
+
params: variables
|
|
533
622
|
});
|
|
534
623
|
return { data: response.data };
|
|
535
624
|
},
|
|
536
625
|
getApiUrl: () => baseApiUrl,
|
|
537
|
-
// Analytics
|
|
626
|
+
// Analytics don't support custom method - use create() instead
|
|
627
|
+
custom: async () => {
|
|
628
|
+
throw new Error(
|
|
629
|
+
"custom is not supported for analytics. Use useCreate to execute queries."
|
|
630
|
+
);
|
|
631
|
+
},
|
|
632
|
+
// Analytics queries don't support other CRUD operations
|
|
538
633
|
getList: async () => {
|
|
539
|
-
throw new Error(
|
|
634
|
+
throw new Error(
|
|
635
|
+
"getList is not supported for analytics. Use useCreate to execute queries."
|
|
636
|
+
);
|
|
540
637
|
},
|
|
541
638
|
getOne: async () => {
|
|
542
|
-
throw new Error(
|
|
639
|
+
throw new Error(
|
|
640
|
+
"getOne is not supported for analytics. Use useCreate to execute queries."
|
|
641
|
+
);
|
|
543
642
|
},
|
|
544
643
|
getMany: async () => {
|
|
545
|
-
throw new Error(
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
throw new Error("create is not supported for analytics. Use custom() to execute queries");
|
|
644
|
+
throw new Error(
|
|
645
|
+
"getMany is not supported for analytics. Use useCreate to execute queries."
|
|
646
|
+
);
|
|
549
647
|
},
|
|
550
648
|
createMany: async () => {
|
|
551
|
-
throw new Error(
|
|
649
|
+
throw new Error(
|
|
650
|
+
"createMany is not supported for analytics. Use useCreate to execute queries."
|
|
651
|
+
);
|
|
552
652
|
},
|
|
553
653
|
update: async () => {
|
|
554
|
-
throw new Error(
|
|
654
|
+
throw new Error(
|
|
655
|
+
"update is not supported for analytics. Use useCreate to execute queries."
|
|
656
|
+
);
|
|
555
657
|
},
|
|
556
658
|
updateMany: async () => {
|
|
557
|
-
throw new Error(
|
|
659
|
+
throw new Error(
|
|
660
|
+
"updateMany is not supported for analytics. Use useCreate to execute queries."
|
|
661
|
+
);
|
|
558
662
|
},
|
|
559
663
|
deleteOne: async () => {
|
|
560
|
-
throw new Error(
|
|
664
|
+
throw new Error(
|
|
665
|
+
"deleteOne is not supported for analytics. Use useCreate to execute queries."
|
|
666
|
+
);
|
|
561
667
|
},
|
|
562
668
|
deleteMany: async () => {
|
|
563
|
-
throw new Error(
|
|
669
|
+
throw new Error(
|
|
670
|
+
"deleteMany is not supported for analytics. Use useCreate to execute queries."
|
|
671
|
+
);
|
|
564
672
|
}
|
|
565
673
|
};
|
|
566
674
|
}
|
|
@@ -682,60 +790,97 @@ function authProvider(client) {
|
|
|
682
790
|
}
|
|
683
791
|
};
|
|
684
792
|
}
|
|
685
|
-
function accessControlProvider(client) {
|
|
793
|
+
function accessControlProvider(client, options) {
|
|
686
794
|
const policy = new sdk.Policy(client);
|
|
687
795
|
const auth = new sdk.Auth(client);
|
|
688
|
-
|
|
689
|
-
|
|
796
|
+
const { batchDelayMs = 50 } = options ?? {};
|
|
797
|
+
const permissionLoader = new DataLoader__default.default(
|
|
798
|
+
async (checks) => {
|
|
690
799
|
const user = auth.getCurrentUser();
|
|
691
800
|
if (!user) {
|
|
692
|
-
return {
|
|
801
|
+
return checks.map(() => ({
|
|
693
802
|
can: false,
|
|
694
803
|
reason: "User not authenticated"
|
|
695
|
-
};
|
|
804
|
+
}));
|
|
696
805
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
806
|
+
const uniqueResources = /* @__PURE__ */ new Map();
|
|
807
|
+
for (const check of checks) {
|
|
808
|
+
const recordId = check.params?.id ? String(check.params.id) : "*";
|
|
809
|
+
const key = `${check.resource}:${recordId}`;
|
|
810
|
+
if (!uniqueResources.has(key)) {
|
|
811
|
+
uniqueResources.set(key, {
|
|
812
|
+
entityType: check.entityType,
|
|
813
|
+
tableName: check.resource,
|
|
814
|
+
recordId,
|
|
815
|
+
attributes: check.params || {},
|
|
816
|
+
actions: /* @__PURE__ */ new Set()
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
uniqueResources.get(key).actions.add(check.action);
|
|
702
820
|
}
|
|
821
|
+
const batchPayload = Array.from(uniqueResources.values()).map((entry) => ({
|
|
822
|
+
entityType: entry.entityType ?? entry.tableName,
|
|
823
|
+
// Default to tableName if entityType not specified
|
|
824
|
+
tableName: entry.tableName,
|
|
825
|
+
recordId: entry.recordId,
|
|
826
|
+
attributes: entry.attributes,
|
|
827
|
+
actions: Array.from(entry.actions)
|
|
828
|
+
}));
|
|
703
829
|
try {
|
|
704
|
-
const
|
|
705
|
-
const
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
const actionResult = result.results?.[0]?.actions?.[action];
|
|
717
|
-
const allowed = actionResult === "EFFECT_ALLOW" || result.allowed === true;
|
|
830
|
+
const result = await policy.checkResource(batchPayload);
|
|
831
|
+
const resultsByResource = /* @__PURE__ */ new Map();
|
|
832
|
+
result?.results?.forEach((r, index) => {
|
|
833
|
+
const payload = batchPayload[index];
|
|
834
|
+
const key = `${payload.tableName}:${payload.recordId}`;
|
|
835
|
+
resultsByResource.set(key, r.actions || {});
|
|
836
|
+
});
|
|
837
|
+
return checks.map((check) => {
|
|
838
|
+
const recordId = check.params?.id ? String(check.params.id) : "*";
|
|
839
|
+
const key = `${check.resource}:${recordId}`;
|
|
840
|
+
const actions = resultsByResource.get(key) || {};
|
|
841
|
+
const allowed = actions[check.action] === "EFFECT_ALLOW";
|
|
718
842
|
return {
|
|
719
843
|
can: allowed,
|
|
720
|
-
reason:
|
|
844
|
+
reason: allowed ? void 0 : "Permission denied by policy"
|
|
721
845
|
};
|
|
722
|
-
}
|
|
723
|
-
return {
|
|
724
|
-
can: false,
|
|
725
|
-
reason: "Invalid policy response"
|
|
726
|
-
};
|
|
846
|
+
});
|
|
727
847
|
} catch (error) {
|
|
728
|
-
console.error("
|
|
729
|
-
return {
|
|
848
|
+
console.error("Batch permission check failed:", error);
|
|
849
|
+
return checks.map(() => ({
|
|
730
850
|
can: false,
|
|
731
851
|
reason: error instanceof Error ? error.message : "Permission check failed"
|
|
732
|
-
};
|
|
852
|
+
}));
|
|
853
|
+
}
|
|
854
|
+
},
|
|
855
|
+
{
|
|
856
|
+
batchScheduleFn: (callback) => setTimeout(callback, batchDelayMs),
|
|
857
|
+
cache: false
|
|
858
|
+
// TanStack Query handles caching
|
|
859
|
+
}
|
|
860
|
+
);
|
|
861
|
+
return {
|
|
862
|
+
can: async ({ resource, action, params }) => {
|
|
863
|
+
if (!resource) {
|
|
864
|
+
return { can: false, reason: "Resource not specified" };
|
|
733
865
|
}
|
|
866
|
+
const entityType = params?.resource?.meta?.entityType;
|
|
867
|
+
return permissionLoader.load({
|
|
868
|
+
resource,
|
|
869
|
+
action,
|
|
870
|
+
params,
|
|
871
|
+
entityType
|
|
872
|
+
});
|
|
734
873
|
},
|
|
735
874
|
options: {
|
|
736
875
|
buttons: {
|
|
737
876
|
enableAccessControl: true,
|
|
738
|
-
hideIfUnauthorized:
|
|
877
|
+
hideIfUnauthorized: true
|
|
878
|
+
},
|
|
879
|
+
queryOptions: {
|
|
880
|
+
staleTime: 5 * 60 * 1e3,
|
|
881
|
+
// 5 minutes
|
|
882
|
+
gcTime: 10 * 60 * 1e3
|
|
883
|
+
// 10 minutes
|
|
739
884
|
}
|
|
740
885
|
}
|
|
741
886
|
};
|
|
@@ -772,6 +917,7 @@ Object.defineProperty(exports, "User", {
|
|
|
772
917
|
exports.REFINE_OPERATOR_MAP = REFINE_OPERATOR_MAP;
|
|
773
918
|
exports.accessControlProvider = accessControlProvider;
|
|
774
919
|
exports.analyticsDataProvider = analyticsDataProvider;
|
|
920
|
+
exports.appDataProvider = appDataProvider;
|
|
775
921
|
exports.authProvider = authProvider;
|
|
776
922
|
exports.buildQueryString = buildQueryString;
|
|
777
923
|
exports.buildRefineQueryParams = buildRefineQueryParams;
|