@dyrected/core 2.5.43 → 2.5.45
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/LICENSE.md +1 -1
- package/dist/app-config-3XBnu9Xz.d.cts +1379 -0
- package/dist/app-config-3XBnu9Xz.d.ts +1379 -0
- package/dist/chunk-44O2LDPT.js +1513 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/server.cjs +133 -32
- package/dist/server.d.cts +34 -1
- package/dist/server.d.ts +34 -1
- package/dist/server.js +105 -2
- package/dist/where-sanitizer-7Q4JXMX6.js +57 -0
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as Field, B as Block, D as DyrectedConfig, C as CollectionConfig, A as AdminAuthConfig, P as PublicAdminAuthConfig, W as WorkflowConfig, a as AuthenticatedUser, b as WorkflowTransition, L as LifecycleEventName, c as LifecycleEvent, d as BaseDocument, H as HookRequestContext, G as GlobalConfig } from './app-config-
|
|
2
|
-
export { e as AccessFunction, f as AdminAuthAccessResolution, g as AdminAuthClaimMapping, h as
|
|
1
|
+
import { F as Field, B as Block, D as DyrectedConfig, C as CollectionConfig, A as AdminAuthConfig, P as PublicAdminAuthConfig, W as WorkflowConfig, a as AuthenticatedUser, b as WorkflowTransition, L as LifecycleEventName, c as LifecycleEvent, d as BaseDocument, H as HookRequestContext, G as GlobalConfig } from './app-config-3XBnu9Xz.cjs';
|
|
2
|
+
export { e as AccessFunction, f as AdminAuthAccessResolution, g as AdminAuthClaimMapping, h as AdminAuthMember, i as AdminAuthProvider, j as AdminAuthProviderMembersConfig, k as AdminAuthProvisioningMode, l as AdminAuthResolveAccessArgs, m as AdminAuthResolvedIdentity, n as AdminConfig, o as AdminDashboardComponentSlots, p as AdminIconName, q as ArrayField, r as BaseAdminAuthProvider, s as BlocksField, t as BooleanField, u as CharacterLimitFieldConfig, v as CollectionAfterChangeHook, w as CollectionAfterDeleteHook, x as CollectionAfterReadHook, y as CollectionAfterTransitionHook, z as CollectionBeforeChangeHook, E as CollectionBeforeDeleteHook, I as CollectionBeforeReadHook, J as CollectionBeforeTransitionHook, K as CollectionListComponentSlots, M as CustomAdminAuthProvider, N as DatabaseAdapter, O as DateField, Q as DateTimeField, R as DynamicOptionItem, S as DynamicOptionsConfig, T as DynamicOptionsResolver, U as DynamicOptionsResolverArgs, V as EmailField, X as FieldAdminOnChangeHook, Y as FieldAdminOnChangeHookArgs, Z as FieldAdminOptionsHook, _ as FieldAdminOptionsHookArgs, $ as FieldAdminOptionsHookResult, a0 as FieldAfterReadHook, a1 as FieldAfterReadHookArgs, a2 as FieldBeforeChangeHook, a3 as FieldBeforeChangeHookArgs, a4 as FieldHook, a5 as FieldType, a6 as FileData, a7 as GlobalAfterChangeHook, a8 as GlobalAfterReadHook, a9 as GlobalBeforeChangeHook, aa as GlobalBeforeReadHook, ab as HookFunction, ac as IconField, ad as ImageField, ae as ImageService, af as JoinField, ag as JsonField, ah as LIFECYCLE_EVENT_NAMES, ai as LifecycleEventHandler, aj as MultiSelectField, ak as NumberField, al as OIDCAdminAuthProvider, am as ObjectField, an as PaginatedResult, ao as PublicAdminAuthProvider, ap as RadioField, aq as ReadonlyDatabaseAdapter, ar as RelationshipField, as as RichTextField, at as RowField, au as SelectField, av as StorageAdapter, aw as TextField, ax as TextareaField, ay as TimeField, az as UploadConfig, aA as UrlField, aB as WordLimitFieldConfig, aC as WorkflowMetadata, aD as WorkflowRole, aE as WorkflowState, aF as WorkflowTransitionContext } from './app-config-3XBnu9Xz.cjs';
|
|
3
3
|
import 'lucide-react';
|
|
4
4
|
|
|
5
5
|
type Prettify<T> = {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as Field, B as Block, D as DyrectedConfig, C as CollectionConfig, A as AdminAuthConfig, P as PublicAdminAuthConfig, W as WorkflowConfig, a as AuthenticatedUser, b as WorkflowTransition, L as LifecycleEventName, c as LifecycleEvent, d as BaseDocument, H as HookRequestContext, G as GlobalConfig } from './app-config-
|
|
2
|
-
export { e as AccessFunction, f as AdminAuthAccessResolution, g as AdminAuthClaimMapping, h as
|
|
1
|
+
import { F as Field, B as Block, D as DyrectedConfig, C as CollectionConfig, A as AdminAuthConfig, P as PublicAdminAuthConfig, W as WorkflowConfig, a as AuthenticatedUser, b as WorkflowTransition, L as LifecycleEventName, c as LifecycleEvent, d as BaseDocument, H as HookRequestContext, G as GlobalConfig } from './app-config-3XBnu9Xz.js';
|
|
2
|
+
export { e as AccessFunction, f as AdminAuthAccessResolution, g as AdminAuthClaimMapping, h as AdminAuthMember, i as AdminAuthProvider, j as AdminAuthProviderMembersConfig, k as AdminAuthProvisioningMode, l as AdminAuthResolveAccessArgs, m as AdminAuthResolvedIdentity, n as AdminConfig, o as AdminDashboardComponentSlots, p as AdminIconName, q as ArrayField, r as BaseAdminAuthProvider, s as BlocksField, t as BooleanField, u as CharacterLimitFieldConfig, v as CollectionAfterChangeHook, w as CollectionAfterDeleteHook, x as CollectionAfterReadHook, y as CollectionAfterTransitionHook, z as CollectionBeforeChangeHook, E as CollectionBeforeDeleteHook, I as CollectionBeforeReadHook, J as CollectionBeforeTransitionHook, K as CollectionListComponentSlots, M as CustomAdminAuthProvider, N as DatabaseAdapter, O as DateField, Q as DateTimeField, R as DynamicOptionItem, S as DynamicOptionsConfig, T as DynamicOptionsResolver, U as DynamicOptionsResolverArgs, V as EmailField, X as FieldAdminOnChangeHook, Y as FieldAdminOnChangeHookArgs, Z as FieldAdminOptionsHook, _ as FieldAdminOptionsHookArgs, $ as FieldAdminOptionsHookResult, a0 as FieldAfterReadHook, a1 as FieldAfterReadHookArgs, a2 as FieldBeforeChangeHook, a3 as FieldBeforeChangeHookArgs, a4 as FieldHook, a5 as FieldType, a6 as FileData, a7 as GlobalAfterChangeHook, a8 as GlobalAfterReadHook, a9 as GlobalBeforeChangeHook, aa as GlobalBeforeReadHook, ab as HookFunction, ac as IconField, ad as ImageField, ae as ImageService, af as JoinField, ag as JsonField, ah as LIFECYCLE_EVENT_NAMES, ai as LifecycleEventHandler, aj as MultiSelectField, ak as NumberField, al as OIDCAdminAuthProvider, am as ObjectField, an as PaginatedResult, ao as PublicAdminAuthProvider, ap as RadioField, aq as ReadonlyDatabaseAdapter, ar as RelationshipField, as as RichTextField, at as RowField, au as SelectField, av as StorageAdapter, aw as TextField, ax as TextareaField, ay as TimeField, az as UploadConfig, aA as UrlField, aB as WordLimitFieldConfig, aC as WorkflowMetadata, aD as WorkflowRole, aE as WorkflowState, aF as WorkflowTransitionContext } from './app-config-3XBnu9Xz.js';
|
|
3
3
|
import 'lucide-react';
|
|
4
4
|
|
|
5
5
|
type Prettify<T> = {
|
package/dist/server.cjs
CHANGED
|
@@ -553,6 +553,34 @@ async function evaluateAccess(expression, context) {
|
|
|
553
553
|
}
|
|
554
554
|
}
|
|
555
555
|
|
|
556
|
+
// src/utils/admin-auth.ts
|
|
557
|
+
function getAdminAuthCollection(config) {
|
|
558
|
+
const requestedSlug = config.adminAuth?.collectionSlug;
|
|
559
|
+
if (requestedSlug) {
|
|
560
|
+
return config.collections.find((collection) => collection.slug === requestedSlug) ?? null;
|
|
561
|
+
}
|
|
562
|
+
return config.collections.find((collection) => collection.slug === "__admins") ?? config.collections.find((collection) => collection.auth) ?? null;
|
|
563
|
+
}
|
|
564
|
+
function getPublicAdminAuthConfig(adminAuth) {
|
|
565
|
+
const providers = (adminAuth?.providers ?? []).map((provider) => ({
|
|
566
|
+
id: provider.id,
|
|
567
|
+
type: provider.type,
|
|
568
|
+
displayName: provider.displayName || humanizeProviderName(provider.id, provider.type),
|
|
569
|
+
autoRedirect: provider.autoRedirect
|
|
570
|
+
}));
|
|
571
|
+
return {
|
|
572
|
+
mode: adminAuth?.mode ?? "local",
|
|
573
|
+
collectionSlug: adminAuth?.collectionSlug,
|
|
574
|
+
provisioningMode: adminAuth?.provisioningMode,
|
|
575
|
+
providers
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
function humanizeProviderName(id, type) {
|
|
579
|
+
const cleaned = id.replace(/[-_]+/g, " ").trim();
|
|
580
|
+
if (!cleaned) return type.toUpperCase();
|
|
581
|
+
return cleaned.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
582
|
+
}
|
|
583
|
+
|
|
556
584
|
// src/workflows.ts
|
|
557
585
|
var WORKFLOW_HISTORY_COLLECTION = "__workflow_history";
|
|
558
586
|
var LIFECYCLE_EVENTS_COLLECTION = "__lifecycle_events";
|
|
@@ -782,10 +810,54 @@ var CollectionController = class {
|
|
|
782
810
|
constructor(collection) {
|
|
783
811
|
this.collection = collection;
|
|
784
812
|
}
|
|
813
|
+
getDelegatedProvider(c) {
|
|
814
|
+
const config = c.get("config");
|
|
815
|
+
const authCollection = getAdminAuthCollection(config);
|
|
816
|
+
if (!authCollection || this.collection.slug !== authCollection.slug) {
|
|
817
|
+
return null;
|
|
818
|
+
}
|
|
819
|
+
return config.adminAuth?.providers?.find((p) => p.members) || null;
|
|
820
|
+
}
|
|
785
821
|
async find(c) {
|
|
786
822
|
const config = c.get("config");
|
|
787
823
|
const db = config.db;
|
|
788
824
|
if (!db) return c.json({ message: "Database not configured" }, 500);
|
|
825
|
+
const provider = this.getDelegatedProvider(c);
|
|
826
|
+
if (provider && provider.members?.list) {
|
|
827
|
+
const limit2 = Number(c.req.query("limit")) || 10;
|
|
828
|
+
const page2 = Number(c.req.query("page")) || 1;
|
|
829
|
+
const sort2 = c.req.query("sort") || void 0;
|
|
830
|
+
let where2 = void 0;
|
|
831
|
+
const whereRaw2 = c.req.query("where");
|
|
832
|
+
if (whereRaw2) {
|
|
833
|
+
try {
|
|
834
|
+
where2 = JSON.parse(decodeURIComponent(whereRaw2));
|
|
835
|
+
} catch {
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
const paginatedResult = await provider.members.list({ limit: limit2, page: page2, sort: sort2, where: where2, req: c.req });
|
|
839
|
+
const mappedDocs = [];
|
|
840
|
+
for (const m of paginatedResult.docs) {
|
|
841
|
+
let localId = m.id;
|
|
842
|
+
const localDoc = await db.find({
|
|
843
|
+
collection: this.collection.slug,
|
|
844
|
+
where: m.id ? { externalSubject: { equals: m.id } } : { email: { equals: m.email } },
|
|
845
|
+
limit: 1
|
|
846
|
+
});
|
|
847
|
+
if (localDoc.docs[0]) {
|
|
848
|
+
localId = localDoc.docs[0].id;
|
|
849
|
+
}
|
|
850
|
+
mappedDocs.push({
|
|
851
|
+
...m,
|
|
852
|
+
id: localId,
|
|
853
|
+
externalSubject: m.id
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
return c.json({
|
|
857
|
+
...paginatedResult,
|
|
858
|
+
docs: mappedDocs
|
|
859
|
+
});
|
|
860
|
+
}
|
|
789
861
|
const readonlyDb = createReadonlyDb(db);
|
|
790
862
|
const limit = Number(c.req.query("limit")) || 10;
|
|
791
863
|
const page = Number(c.req.query("page")) || 1;
|
|
@@ -843,11 +915,13 @@ var CollectionController = class {
|
|
|
843
915
|
where
|
|
844
916
|
});
|
|
845
917
|
}
|
|
846
|
-
result.docs = result.docs.map((doc) => this.collection.workflow ? materializeWorkflowDocument(doc, this.collection.workflow, user) : doc).filter((doc) => doc !== null)
|
|
918
|
+
result.docs = result.docs.map((doc) => this.collection.workflow ? materializeWorkflowDocument(doc, this.collection.workflow, user) : doc).filter((doc) => doc !== null);
|
|
847
919
|
const processedDocs = [];
|
|
920
|
+
const readonlyDbForHooks = createReadonlyDb(db);
|
|
848
921
|
for (const doc of result.docs) {
|
|
922
|
+
const docWithDefaults = DefaultsService.apply(this.collection.fields, doc);
|
|
849
923
|
const docWithCollectionHooks = await runCollectionHooks(this.collection.hooks?.afterRead, {
|
|
850
|
-
doc,
|
|
924
|
+
doc: docWithDefaults,
|
|
851
925
|
req: c.req,
|
|
852
926
|
user,
|
|
853
927
|
db: readonlyDb
|
|
@@ -866,6 +940,26 @@ var CollectionController = class {
|
|
|
866
940
|
const config = c.get("config");
|
|
867
941
|
const db = config.db;
|
|
868
942
|
if (!db) return c.json({ message: "Database not configured" }, 500);
|
|
943
|
+
const provider = this.getDelegatedProvider(c);
|
|
944
|
+
if (provider && (provider.members?.get || provider.members?.list)) {
|
|
945
|
+
const id2 = c.req.param("id");
|
|
946
|
+
if (!id2) return c.json({ message: "Missing ID" }, 400);
|
|
947
|
+
const localDoc = await db.findOne({ collection: this.collection.slug, id: id2 });
|
|
948
|
+
const externalSubject = localDoc?.externalSubject || id2;
|
|
949
|
+
let member = null;
|
|
950
|
+
if (provider.members.get) {
|
|
951
|
+
member = await provider.members.get({ externalSubject, req: c.req });
|
|
952
|
+
} else if (provider.members.list) {
|
|
953
|
+
const listResult = await provider.members.list({ req: c.req });
|
|
954
|
+
member = listResult.docs.find((m) => m.id === externalSubject) || null;
|
|
955
|
+
}
|
|
956
|
+
if (!member) return c.json({ message: "Not Found" }, 404);
|
|
957
|
+
return c.json({
|
|
958
|
+
...member,
|
|
959
|
+
id: localDoc ? localDoc.id : member.id,
|
|
960
|
+
externalSubject: member.id
|
|
961
|
+
});
|
|
962
|
+
}
|
|
869
963
|
const readonlyDb = createReadonlyDb(db);
|
|
870
964
|
const id = c.req.param("id");
|
|
871
965
|
const depth = c.req.query("depth") !== void 0 ? Number(c.req.query("depth")) : 10;
|
|
@@ -901,6 +995,20 @@ var CollectionController = class {
|
|
|
901
995
|
const config = c.get("config");
|
|
902
996
|
const db = config.db;
|
|
903
997
|
if (!db) return c.json({ message: "Database not configured" }, 500);
|
|
998
|
+
const provider = this.getDelegatedProvider(c);
|
|
999
|
+
if (provider && provider.members?.create) {
|
|
1000
|
+
const contentType2 = c.req.header("Content-Type") || "";
|
|
1001
|
+
if (contentType2.toLowerCase().includes("multipart/form-data")) {
|
|
1002
|
+
return this.upload(c);
|
|
1003
|
+
}
|
|
1004
|
+
const body2 = await c.req.json();
|
|
1005
|
+
const member = await provider.members.create({ data: body2, req: c.req });
|
|
1006
|
+
return c.json({
|
|
1007
|
+
...member,
|
|
1008
|
+
id: member.id,
|
|
1009
|
+
externalSubject: member.id
|
|
1010
|
+
}, 201);
|
|
1011
|
+
}
|
|
904
1012
|
const readonlyDb = createReadonlyDb(db);
|
|
905
1013
|
const contentType = c.req.header("Content-Type") || "";
|
|
906
1014
|
if (contentType.toLowerCase().includes("multipart/form-data")) {
|
|
@@ -1027,6 +1135,20 @@ var CollectionController = class {
|
|
|
1027
1135
|
const config = c.get("config");
|
|
1028
1136
|
const db = config.db;
|
|
1029
1137
|
if (!db) return c.json({ message: "Database not configured" }, 500);
|
|
1138
|
+
const provider = this.getDelegatedProvider(c);
|
|
1139
|
+
if (provider && provider.members?.update) {
|
|
1140
|
+
const id2 = c.req.param("id");
|
|
1141
|
+
if (!id2) return c.json({ message: "Missing ID" }, 400);
|
|
1142
|
+
const body2 = await c.req.json();
|
|
1143
|
+
const localDoc = await db.findOne({ collection: this.collection.slug, id: id2 });
|
|
1144
|
+
const externalSubject = localDoc?.externalSubject || id2;
|
|
1145
|
+
const member = await provider.members.update({ externalSubject, data: body2, req: c.req });
|
|
1146
|
+
return c.json({
|
|
1147
|
+
...member,
|
|
1148
|
+
id: localDoc ? localDoc.id : member.id,
|
|
1149
|
+
externalSubject: member.id
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1030
1152
|
const readonlyDb = createReadonlyDb(db);
|
|
1031
1153
|
const id = c.req.param("id");
|
|
1032
1154
|
if (!id) return c.json({ message: "Missing ID" }, 400);
|
|
@@ -1215,6 +1337,15 @@ var CollectionController = class {
|
|
|
1215
1337
|
const config = c.get("config");
|
|
1216
1338
|
const db = config.db;
|
|
1217
1339
|
if (!db) return c.json({ message: "Database not configured" }, 500);
|
|
1340
|
+
const provider = this.getDelegatedProvider(c);
|
|
1341
|
+
if (provider && provider.members?.delete) {
|
|
1342
|
+
const id2 = c.req.param("id");
|
|
1343
|
+
if (!id2) return c.json({ message: "Missing ID" }, 400);
|
|
1344
|
+
const localDoc = await db.findOne({ collection: this.collection.slug, id: id2 });
|
|
1345
|
+
const externalSubject = localDoc?.externalSubject || id2;
|
|
1346
|
+
await provider.members.delete({ externalSubject, req: c.req });
|
|
1347
|
+
return c.json({ message: "Deleted" });
|
|
1348
|
+
}
|
|
1218
1349
|
const readonlyDb = createReadonlyDb(db);
|
|
1219
1350
|
const id = c.req.param("id");
|
|
1220
1351
|
if (!id) return c.json({ message: "Missing ID" }, 400);
|
|
@@ -2098,36 +2229,6 @@ var AuthController = class {
|
|
|
2098
2229
|
var import_node_crypto2 = require("crypto");
|
|
2099
2230
|
var import_node_util3 = require("util");
|
|
2100
2231
|
var import_jose2 = require("jose");
|
|
2101
|
-
|
|
2102
|
-
// src/utils/admin-auth.ts
|
|
2103
|
-
function getAdminAuthCollection(config) {
|
|
2104
|
-
const requestedSlug = config.adminAuth?.collectionSlug;
|
|
2105
|
-
if (requestedSlug) {
|
|
2106
|
-
return config.collections.find((collection) => collection.slug === requestedSlug) ?? null;
|
|
2107
|
-
}
|
|
2108
|
-
return config.collections.find((collection) => collection.slug === "__admins") ?? config.collections.find((collection) => collection.auth) ?? null;
|
|
2109
|
-
}
|
|
2110
|
-
function getPublicAdminAuthConfig(adminAuth) {
|
|
2111
|
-
const providers = (adminAuth?.providers ?? []).map((provider) => ({
|
|
2112
|
-
id: provider.id,
|
|
2113
|
-
type: provider.type,
|
|
2114
|
-
displayName: provider.displayName || humanizeProviderName(provider.id, provider.type),
|
|
2115
|
-
autoRedirect: provider.autoRedirect
|
|
2116
|
-
}));
|
|
2117
|
-
return {
|
|
2118
|
-
mode: adminAuth?.mode ?? "local",
|
|
2119
|
-
collectionSlug: adminAuth?.collectionSlug,
|
|
2120
|
-
provisioningMode: adminAuth?.provisioningMode,
|
|
2121
|
-
providers
|
|
2122
|
-
};
|
|
2123
|
-
}
|
|
2124
|
-
function humanizeProviderName(id, type) {
|
|
2125
|
-
const cleaned = id.replace(/[-_]+/g, " ").trim();
|
|
2126
|
-
if (!cleaned) return type.toUpperCase();
|
|
2127
|
-
return cleaned.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
2128
|
-
}
|
|
2129
|
-
|
|
2130
|
-
// src/controllers/admin-auth.controller.ts
|
|
2131
2232
|
var AdminAuthController = class {
|
|
2132
2233
|
constructor(config) {
|
|
2133
2234
|
this.config = config;
|
package/dist/server.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as hono_types from 'hono/types';
|
|
2
2
|
import * as hono from 'hono';
|
|
3
3
|
import { Hono, Context } from 'hono';
|
|
4
|
-
import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-
|
|
4
|
+
import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-3XBnu9Xz.cjs';
|
|
5
5
|
import * as hono_utils_http_status from 'hono/utils/http-status';
|
|
6
6
|
import * as hono_utils_types from 'hono/utils/types';
|
|
7
7
|
import 'lucide-react';
|
|
@@ -155,9 +155,26 @@ declare class AuthController {
|
|
|
155
155
|
declare class CollectionController {
|
|
156
156
|
private collection;
|
|
157
157
|
constructor(collection: CollectionConfig);
|
|
158
|
+
private getDelegatedProvider;
|
|
158
159
|
find(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
|
|
159
160
|
message: string;
|
|
160
161
|
}, 500, "json">) | (Response & hono.TypedResponse<{
|
|
162
|
+
docs: {
|
|
163
|
+
id: string;
|
|
164
|
+
externalSubject: string;
|
|
165
|
+
email: string;
|
|
166
|
+
name?: string | undefined;
|
|
167
|
+
roles: string[];
|
|
168
|
+
siteAccess?: string[] | undefined;
|
|
169
|
+
status?: "active" | "pending" | undefined;
|
|
170
|
+
}[];
|
|
171
|
+
totalDocs: number;
|
|
172
|
+
limit: number;
|
|
173
|
+
page: number;
|
|
174
|
+
totalPages: number;
|
|
175
|
+
hasNextPage: boolean;
|
|
176
|
+
hasPrevPage: boolean;
|
|
177
|
+
}, hono_utils_http_status.ContentfulStatusCode, "json">) | (Response & hono.TypedResponse<{
|
|
161
178
|
docs: {
|
|
162
179
|
[x: string]: any;
|
|
163
180
|
}[];
|
|
@@ -175,6 +192,14 @@ declare class CollectionController {
|
|
|
175
192
|
message: string;
|
|
176
193
|
}, 400, "json">) | (Response & hono.TypedResponse<{
|
|
177
194
|
[x: string]: hono_utils_types.JSONValue;
|
|
195
|
+
}, 201, "json">) | (Response & hono.TypedResponse<{
|
|
196
|
+
id: string;
|
|
197
|
+
externalSubject: string;
|
|
198
|
+
email: string;
|
|
199
|
+
name?: string | undefined;
|
|
200
|
+
roles: string[];
|
|
201
|
+
siteAccess?: string[] | undefined;
|
|
202
|
+
status?: "active" | "pending" | undefined;
|
|
178
203
|
}, 201, "json">)>;
|
|
179
204
|
upload(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
|
|
180
205
|
message: string;
|
|
@@ -190,6 +215,14 @@ declare class CollectionController {
|
|
|
190
215
|
}, 500, "json">) | (Response & hono.TypedResponse<{
|
|
191
216
|
message: string;
|
|
192
217
|
}, 400, "json">) | (Response & hono.TypedResponse<{
|
|
218
|
+
id: string;
|
|
219
|
+
externalSubject: string;
|
|
220
|
+
email: string;
|
|
221
|
+
name?: string | undefined;
|
|
222
|
+
roles: string[];
|
|
223
|
+
siteAccess?: string[] | undefined;
|
|
224
|
+
status?: "active" | "pending" | undefined;
|
|
225
|
+
}, hono_utils_http_status.ContentfulStatusCode, "json">) | (Response & hono.TypedResponse<{
|
|
193
226
|
message: string;
|
|
194
227
|
}, 404, "json">)>;
|
|
195
228
|
transition(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
|
package/dist/server.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as hono_types from 'hono/types';
|
|
2
2
|
import * as hono from 'hono';
|
|
3
3
|
import { Hono, Context } from 'hono';
|
|
4
|
-
import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-
|
|
4
|
+
import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-3XBnu9Xz.js';
|
|
5
5
|
import * as hono_utils_http_status from 'hono/utils/http-status';
|
|
6
6
|
import * as hono_utils_types from 'hono/utils/types';
|
|
7
7
|
import 'lucide-react';
|
|
@@ -155,9 +155,26 @@ declare class AuthController {
|
|
|
155
155
|
declare class CollectionController {
|
|
156
156
|
private collection;
|
|
157
157
|
constructor(collection: CollectionConfig);
|
|
158
|
+
private getDelegatedProvider;
|
|
158
159
|
find(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
|
|
159
160
|
message: string;
|
|
160
161
|
}, 500, "json">) | (Response & hono.TypedResponse<{
|
|
162
|
+
docs: {
|
|
163
|
+
id: string;
|
|
164
|
+
externalSubject: string;
|
|
165
|
+
email: string;
|
|
166
|
+
name?: string | undefined;
|
|
167
|
+
roles: string[];
|
|
168
|
+
siteAccess?: string[] | undefined;
|
|
169
|
+
status?: "active" | "pending" | undefined;
|
|
170
|
+
}[];
|
|
171
|
+
totalDocs: number;
|
|
172
|
+
limit: number;
|
|
173
|
+
page: number;
|
|
174
|
+
totalPages: number;
|
|
175
|
+
hasNextPage: boolean;
|
|
176
|
+
hasPrevPage: boolean;
|
|
177
|
+
}, hono_utils_http_status.ContentfulStatusCode, "json">) | (Response & hono.TypedResponse<{
|
|
161
178
|
docs: {
|
|
162
179
|
[x: string]: any;
|
|
163
180
|
}[];
|
|
@@ -175,6 +192,14 @@ declare class CollectionController {
|
|
|
175
192
|
message: string;
|
|
176
193
|
}, 400, "json">) | (Response & hono.TypedResponse<{
|
|
177
194
|
[x: string]: hono_utils_types.JSONValue;
|
|
195
|
+
}, 201, "json">) | (Response & hono.TypedResponse<{
|
|
196
|
+
id: string;
|
|
197
|
+
externalSubject: string;
|
|
198
|
+
email: string;
|
|
199
|
+
name?: string | undefined;
|
|
200
|
+
roles: string[];
|
|
201
|
+
siteAccess?: string[] | undefined;
|
|
202
|
+
status?: "active" | "pending" | undefined;
|
|
178
203
|
}, 201, "json">)>;
|
|
179
204
|
upload(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
|
|
180
205
|
message: string;
|
|
@@ -190,6 +215,14 @@ declare class CollectionController {
|
|
|
190
215
|
}, 500, "json">) | (Response & hono.TypedResponse<{
|
|
191
216
|
message: string;
|
|
192
217
|
}, 400, "json">) | (Response & hono.TypedResponse<{
|
|
218
|
+
id: string;
|
|
219
|
+
externalSubject: string;
|
|
220
|
+
email: string;
|
|
221
|
+
name?: string | undefined;
|
|
222
|
+
roles: string[];
|
|
223
|
+
siteAccess?: string[] | undefined;
|
|
224
|
+
status?: "active" | "pending" | undefined;
|
|
225
|
+
}, hono_utils_http_status.ContentfulStatusCode, "json">) | (Response & hono.TypedResponse<{
|
|
193
226
|
message: string;
|
|
194
227
|
}, 404, "json">)>;
|
|
195
228
|
transition(c: Context<DyrectedContext>): Promise<(Response & hono.TypedResponse<{
|
package/dist/server.js
CHANGED
|
@@ -306,10 +306,54 @@ var CollectionController = class {
|
|
|
306
306
|
constructor(collection) {
|
|
307
307
|
this.collection = collection;
|
|
308
308
|
}
|
|
309
|
+
getDelegatedProvider(c) {
|
|
310
|
+
const config = c.get("config");
|
|
311
|
+
const authCollection = getAdminAuthCollection(config);
|
|
312
|
+
if (!authCollection || this.collection.slug !== authCollection.slug) {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
return config.adminAuth?.providers?.find((p) => p.members) || null;
|
|
316
|
+
}
|
|
309
317
|
async find(c) {
|
|
310
318
|
const config = c.get("config");
|
|
311
319
|
const db = config.db;
|
|
312
320
|
if (!db) return c.json({ message: "Database not configured" }, 500);
|
|
321
|
+
const provider = this.getDelegatedProvider(c);
|
|
322
|
+
if (provider && provider.members?.list) {
|
|
323
|
+
const limit2 = Number(c.req.query("limit")) || 10;
|
|
324
|
+
const page2 = Number(c.req.query("page")) || 1;
|
|
325
|
+
const sort2 = c.req.query("sort") || void 0;
|
|
326
|
+
let where2 = void 0;
|
|
327
|
+
const whereRaw2 = c.req.query("where");
|
|
328
|
+
if (whereRaw2) {
|
|
329
|
+
try {
|
|
330
|
+
where2 = JSON.parse(decodeURIComponent(whereRaw2));
|
|
331
|
+
} catch {
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
const paginatedResult = await provider.members.list({ limit: limit2, page: page2, sort: sort2, where: where2, req: c.req });
|
|
335
|
+
const mappedDocs = [];
|
|
336
|
+
for (const m of paginatedResult.docs) {
|
|
337
|
+
let localId = m.id;
|
|
338
|
+
const localDoc = await db.find({
|
|
339
|
+
collection: this.collection.slug,
|
|
340
|
+
where: m.id ? { externalSubject: { equals: m.id } } : { email: { equals: m.email } },
|
|
341
|
+
limit: 1
|
|
342
|
+
});
|
|
343
|
+
if (localDoc.docs[0]) {
|
|
344
|
+
localId = localDoc.docs[0].id;
|
|
345
|
+
}
|
|
346
|
+
mappedDocs.push({
|
|
347
|
+
...m,
|
|
348
|
+
id: localId,
|
|
349
|
+
externalSubject: m.id
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
return c.json({
|
|
353
|
+
...paginatedResult,
|
|
354
|
+
docs: mappedDocs
|
|
355
|
+
});
|
|
356
|
+
}
|
|
313
357
|
const readonlyDb = createReadonlyDb(db);
|
|
314
358
|
const limit = Number(c.req.query("limit")) || 10;
|
|
315
359
|
const page = Number(c.req.query("page")) || 1;
|
|
@@ -367,11 +411,13 @@ var CollectionController = class {
|
|
|
367
411
|
where
|
|
368
412
|
});
|
|
369
413
|
}
|
|
370
|
-
result.docs = result.docs.map((doc) => this.collection.workflow ? materializeWorkflowDocument(doc, this.collection.workflow, user) : doc).filter((doc) => doc !== null)
|
|
414
|
+
result.docs = result.docs.map((doc) => this.collection.workflow ? materializeWorkflowDocument(doc, this.collection.workflow, user) : doc).filter((doc) => doc !== null);
|
|
371
415
|
const processedDocs = [];
|
|
416
|
+
const readonlyDbForHooks = createReadonlyDb(db);
|
|
372
417
|
for (const doc of result.docs) {
|
|
418
|
+
const docWithDefaults = DefaultsService.apply(this.collection.fields, doc);
|
|
373
419
|
const docWithCollectionHooks = await runCollectionHooks(this.collection.hooks?.afterRead, {
|
|
374
|
-
doc,
|
|
420
|
+
doc: docWithDefaults,
|
|
375
421
|
req: c.req,
|
|
376
422
|
user,
|
|
377
423
|
db: readonlyDb
|
|
@@ -390,6 +436,26 @@ var CollectionController = class {
|
|
|
390
436
|
const config = c.get("config");
|
|
391
437
|
const db = config.db;
|
|
392
438
|
if (!db) return c.json({ message: "Database not configured" }, 500);
|
|
439
|
+
const provider = this.getDelegatedProvider(c);
|
|
440
|
+
if (provider && (provider.members?.get || provider.members?.list)) {
|
|
441
|
+
const id2 = c.req.param("id");
|
|
442
|
+
if (!id2) return c.json({ message: "Missing ID" }, 400);
|
|
443
|
+
const localDoc = await db.findOne({ collection: this.collection.slug, id: id2 });
|
|
444
|
+
const externalSubject = localDoc?.externalSubject || id2;
|
|
445
|
+
let member = null;
|
|
446
|
+
if (provider.members.get) {
|
|
447
|
+
member = await provider.members.get({ externalSubject, req: c.req });
|
|
448
|
+
} else if (provider.members.list) {
|
|
449
|
+
const listResult = await provider.members.list({ req: c.req });
|
|
450
|
+
member = listResult.docs.find((m) => m.id === externalSubject) || null;
|
|
451
|
+
}
|
|
452
|
+
if (!member) return c.json({ message: "Not Found" }, 404);
|
|
453
|
+
return c.json({
|
|
454
|
+
...member,
|
|
455
|
+
id: localDoc ? localDoc.id : member.id,
|
|
456
|
+
externalSubject: member.id
|
|
457
|
+
});
|
|
458
|
+
}
|
|
393
459
|
const readonlyDb = createReadonlyDb(db);
|
|
394
460
|
const id = c.req.param("id");
|
|
395
461
|
const depth = c.req.query("depth") !== void 0 ? Number(c.req.query("depth")) : 10;
|
|
@@ -425,6 +491,20 @@ var CollectionController = class {
|
|
|
425
491
|
const config = c.get("config");
|
|
426
492
|
const db = config.db;
|
|
427
493
|
if (!db) return c.json({ message: "Database not configured" }, 500);
|
|
494
|
+
const provider = this.getDelegatedProvider(c);
|
|
495
|
+
if (provider && provider.members?.create) {
|
|
496
|
+
const contentType2 = c.req.header("Content-Type") || "";
|
|
497
|
+
if (contentType2.toLowerCase().includes("multipart/form-data")) {
|
|
498
|
+
return this.upload(c);
|
|
499
|
+
}
|
|
500
|
+
const body2 = await c.req.json();
|
|
501
|
+
const member = await provider.members.create({ data: body2, req: c.req });
|
|
502
|
+
return c.json({
|
|
503
|
+
...member,
|
|
504
|
+
id: member.id,
|
|
505
|
+
externalSubject: member.id
|
|
506
|
+
}, 201);
|
|
507
|
+
}
|
|
428
508
|
const readonlyDb = createReadonlyDb(db);
|
|
429
509
|
const contentType = c.req.header("Content-Type") || "";
|
|
430
510
|
if (contentType.toLowerCase().includes("multipart/form-data")) {
|
|
@@ -551,6 +631,20 @@ var CollectionController = class {
|
|
|
551
631
|
const config = c.get("config");
|
|
552
632
|
const db = config.db;
|
|
553
633
|
if (!db) return c.json({ message: "Database not configured" }, 500);
|
|
634
|
+
const provider = this.getDelegatedProvider(c);
|
|
635
|
+
if (provider && provider.members?.update) {
|
|
636
|
+
const id2 = c.req.param("id");
|
|
637
|
+
if (!id2) return c.json({ message: "Missing ID" }, 400);
|
|
638
|
+
const body2 = await c.req.json();
|
|
639
|
+
const localDoc = await db.findOne({ collection: this.collection.slug, id: id2 });
|
|
640
|
+
const externalSubject = localDoc?.externalSubject || id2;
|
|
641
|
+
const member = await provider.members.update({ externalSubject, data: body2, req: c.req });
|
|
642
|
+
return c.json({
|
|
643
|
+
...member,
|
|
644
|
+
id: localDoc ? localDoc.id : member.id,
|
|
645
|
+
externalSubject: member.id
|
|
646
|
+
});
|
|
647
|
+
}
|
|
554
648
|
const readonlyDb = createReadonlyDb(db);
|
|
555
649
|
const id = c.req.param("id");
|
|
556
650
|
if (!id) return c.json({ message: "Missing ID" }, 400);
|
|
@@ -739,6 +833,15 @@ var CollectionController = class {
|
|
|
739
833
|
const config = c.get("config");
|
|
740
834
|
const db = config.db;
|
|
741
835
|
if (!db) return c.json({ message: "Database not configured" }, 500);
|
|
836
|
+
const provider = this.getDelegatedProvider(c);
|
|
837
|
+
if (provider && provider.members?.delete) {
|
|
838
|
+
const id2 = c.req.param("id");
|
|
839
|
+
if (!id2) return c.json({ message: "Missing ID" }, 400);
|
|
840
|
+
const localDoc = await db.findOne({ collection: this.collection.slug, id: id2 });
|
|
841
|
+
const externalSubject = localDoc?.externalSubject || id2;
|
|
842
|
+
await provider.members.delete({ externalSubject, req: c.req });
|
|
843
|
+
return c.json({ message: "Deleted" });
|
|
844
|
+
}
|
|
742
845
|
const readonlyDb = createReadonlyDb(db);
|
|
743
846
|
const id = c.req.param("id");
|
|
744
847
|
if (!id) return c.json({ message: "Missing ID" }, 400);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// src/utils/where-sanitizer.js
|
|
2
|
+
var NEVER_FILTERABLE_TYPES = [
|
|
3
|
+
"password",
|
|
4
|
+
"richText",
|
|
5
|
+
"json",
|
|
6
|
+
"file",
|
|
7
|
+
"image",
|
|
8
|
+
"join",
|
|
9
|
+
"collapsible"
|
|
10
|
+
];
|
|
11
|
+
function sanitizeWhereClause(where, fields) {
|
|
12
|
+
const fieldMap = /* @__PURE__ */ new Map();
|
|
13
|
+
function addFieldsToMap(fList, prefix = "") {
|
|
14
|
+
for (const f of fList) {
|
|
15
|
+
if ("name" in f && f.name) {
|
|
16
|
+
fieldMap.set(prefix + f.name, f);
|
|
17
|
+
}
|
|
18
|
+
if (f.type === "object" || f.type === "row" || f.type === "array") {
|
|
19
|
+
if ("fields" in f && Array.isArray(f.fields)) {
|
|
20
|
+
addFieldsToMap(f.fields, f.type === "object" || f.type === "array" ? `${prefix}${f.name}.` : prefix);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
addFieldsToMap(fields);
|
|
26
|
+
function walk(node) {
|
|
27
|
+
const result = {};
|
|
28
|
+
for (const [key, value] of Object.entries(node)) {
|
|
29
|
+
if (key === "AND" || key === "OR") {
|
|
30
|
+
if (Array.isArray(value)) {
|
|
31
|
+
const processed = value.map((v) => walk(v)).filter((v) => Object.keys(v).length > 0);
|
|
32
|
+
if (processed.length > 0) {
|
|
33
|
+
result[key] = processed;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (key === "id") {
|
|
39
|
+
result[key] = value;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const fieldDef = fieldMap.get(key);
|
|
43
|
+
if (!fieldDef)
|
|
44
|
+
continue;
|
|
45
|
+
if (fieldDef.admin?.filterable === false)
|
|
46
|
+
continue;
|
|
47
|
+
if (NEVER_FILTERABLE_TYPES.includes(fieldDef.type))
|
|
48
|
+
continue;
|
|
49
|
+
result[key] = value;
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
return walk(where);
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
sanitizeWhereClause
|
|
57
|
+
};
|