@dyrected/core 2.5.43 → 2.5.44
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/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.cjs +86 -95
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +16 -10
- package/dist/server.cjs +483 -310
- package/dist/server.d.cts +34 -1
- package/dist/server.d.ts +34 -1
- package/dist/server.js +411 -231
- package/dist/where-sanitizer-7Q4JXMX6.js +57 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -51,7 +51,7 @@ __export(index_exports, {
|
|
|
51
51
|
});
|
|
52
52
|
module.exports = __toCommonJS(index_exports);
|
|
53
53
|
|
|
54
|
-
// src/types/workflows.
|
|
54
|
+
// src/types/workflows.js
|
|
55
55
|
var LIFECYCLE_EVENT_NAMES = [
|
|
56
56
|
"revision.created",
|
|
57
57
|
"workflow.transitioned",
|
|
@@ -59,7 +59,7 @@ var LIFECYCLE_EVENT_NAMES = [
|
|
|
59
59
|
"entry.unpublished"
|
|
60
60
|
];
|
|
61
61
|
|
|
62
|
-
// src/workflows.
|
|
62
|
+
// src/workflows.js
|
|
63
63
|
var WORKFLOW_HISTORY_COLLECTION = "__workflow_history";
|
|
64
64
|
var LIFECYCLE_EVENTS_COLLECTION = "__lifecycle_events";
|
|
65
65
|
function publishingWorkflow() {
|
|
@@ -92,17 +92,18 @@ function workflowCapabilities(workflow, user) {
|
|
|
92
92
|
const capabilities = new Set(Array.isArray(user?.capabilities) ? user.capabilities : []);
|
|
93
93
|
const roles = Array.isArray(user?.roles) ? user.roles : [];
|
|
94
94
|
for (const mapping of workflow.roles ?? []) {
|
|
95
|
-
if (roles.includes(mapping.role))
|
|
95
|
+
if (roles.includes(mapping.role))
|
|
96
|
+
mapping.capabilities.forEach((capability) => capabilities.add(capability));
|
|
96
97
|
}
|
|
97
98
|
return capabilities;
|
|
98
99
|
}
|
|
99
100
|
function canViewWorkflowDraft(workflow, user) {
|
|
100
|
-
if (!user)
|
|
101
|
+
if (!user)
|
|
102
|
+
return false;
|
|
101
103
|
const capabilities = workflowCapabilities(workflow, user);
|
|
102
|
-
if (capabilities.has("entry.edit"))
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
);
|
|
104
|
+
if (capabilities.has("entry.edit"))
|
|
105
|
+
return true;
|
|
106
|
+
return workflow.transitions.some((transition) => (transition.requiredCapabilities ?? []).some((capability) => capabilities.has(capability)));
|
|
106
107
|
}
|
|
107
108
|
function availableWorkflowTransitions(workflow, state, user) {
|
|
108
109
|
const capabilities = workflowCapabilities(workflow, user);
|
|
@@ -119,10 +120,12 @@ function initializeWorkflowDocument(data, workflow) {
|
|
|
119
120
|
}
|
|
120
121
|
function materializeWorkflowDocument(doc, workflow, user) {
|
|
121
122
|
const meta = doc.__workflow;
|
|
122
|
-
if (!meta)
|
|
123
|
+
if (!meta)
|
|
124
|
+
return doc;
|
|
123
125
|
const { __published, __workflow, ...working } = doc;
|
|
124
126
|
if (!canViewWorkflowDraft(workflow, user)) {
|
|
125
|
-
if (!__published || typeof __published !== "object")
|
|
127
|
+
if (!__published || typeof __published !== "object")
|
|
128
|
+
return null;
|
|
126
129
|
return { id: doc.id, ...__published, _workflow: publicMetadata(meta) };
|
|
127
130
|
}
|
|
128
131
|
return {
|
|
@@ -154,13 +157,15 @@ async function persistEvent(db, event) {
|
|
|
154
157
|
}
|
|
155
158
|
async function dispatchLifecycleEvent(config, event) {
|
|
156
159
|
const db = config.db;
|
|
157
|
-
if (!db || !config.events?.handlers.length)
|
|
160
|
+
if (!db || !config.events?.handlers.length)
|
|
161
|
+
return;
|
|
158
162
|
const maxAttempts = config.events.maxAttempts ?? 8;
|
|
159
163
|
const retryDelayMs = config.events.retryDelayMs ?? 1e3;
|
|
160
164
|
const attempts = event.attempts + 1;
|
|
161
165
|
try {
|
|
162
166
|
await db.update({ collection: LIFECYCLE_EVENTS_COLLECTION, id: event.id, data: { status: "processing", attempts } });
|
|
163
|
-
for (const handler of config.events.handlers)
|
|
167
|
+
for (const handler of config.events.handlers)
|
|
168
|
+
await handler({ ...event, status: "processing", attempts });
|
|
164
169
|
await db.update({
|
|
165
170
|
collection: LIFECYCLE_EVENTS_COLLECTION,
|
|
166
171
|
id: event.id,
|
|
@@ -181,7 +186,8 @@ async function dispatchLifecycleEvent(config, event) {
|
|
|
181
186
|
}
|
|
182
187
|
}
|
|
183
188
|
async function dispatchPendingLifecycleEvents(config, limit = 50) {
|
|
184
|
-
if (!config.db || !config.events?.handlers.length)
|
|
189
|
+
if (!config.db || !config.events?.handlers.length)
|
|
190
|
+
return 0;
|
|
185
191
|
const maxAttempts = config.events.maxAttempts ?? 8;
|
|
186
192
|
const result = await config.db.find({
|
|
187
193
|
collection: LIFECYCLE_EVENTS_COLLECTION,
|
|
@@ -190,17 +196,17 @@ async function dispatchPendingLifecycleEvents(config, limit = 50) {
|
|
|
190
196
|
limit
|
|
191
197
|
});
|
|
192
198
|
const now = Date.now();
|
|
193
|
-
const due = result.docs.filter(
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
for (const event of due) await dispatchLifecycleEvent(config, event);
|
|
199
|
+
const due = result.docs.filter((doc) => Number(doc.attempts ?? 0) < maxAttempts && (!doc.nextAttemptAt || new Date(doc.nextAttemptAt).getTime() <= now));
|
|
200
|
+
for (const event of due)
|
|
201
|
+
await dispatchLifecycleEvent(config, event);
|
|
197
202
|
return due.length;
|
|
198
203
|
}
|
|
199
204
|
async function saveWorkflowDraft(args) {
|
|
200
205
|
const { config, collection, id, originalDoc, data, user } = args;
|
|
201
206
|
const db = config.db;
|
|
202
207
|
const workflow = collection.workflow;
|
|
203
|
-
if (!db.transaction)
|
|
208
|
+
if (!db.transaction)
|
|
209
|
+
throw new Error(`The configured database adapter does not support workflow transactions.`);
|
|
204
210
|
const previous = originalDoc.__workflow;
|
|
205
211
|
const event = createLifecycleEvent({
|
|
206
212
|
name: "revision.created",
|
|
@@ -225,7 +231,8 @@ async function saveWorkflowDraft(args) {
|
|
|
225
231
|
async function createWorkflowDocument(args) {
|
|
226
232
|
const { config, collection, data, user } = args;
|
|
227
233
|
const db = config.db;
|
|
228
|
-
if (!db.transaction)
|
|
234
|
+
if (!db.transaction)
|
|
235
|
+
throw new Error(`The configured database adapter does not support workflow transactions.`);
|
|
229
236
|
let event;
|
|
230
237
|
const doc = await db.transaction(async (tx) => {
|
|
231
238
|
const created = await tx.create({ collection: collection.slug, data });
|
|
@@ -246,11 +253,14 @@ async function transitionWorkflow(args) {
|
|
|
246
253
|
const { config, collection, id, transitionName, expectedRevision, comment, user, req } = args;
|
|
247
254
|
const db = config.db;
|
|
248
255
|
const workflow = collection.workflow;
|
|
249
|
-
if (!db.transaction)
|
|
256
|
+
if (!db.transaction)
|
|
257
|
+
throw new Error(`The configured database adapter does not support workflow transactions.`);
|
|
250
258
|
const original = await db.findOne({ collection: collection.slug, id });
|
|
251
|
-
if (!original)
|
|
259
|
+
if (!original)
|
|
260
|
+
throw Object.assign(new Error("Not Found"), { statusCode: 404 });
|
|
252
261
|
const meta = original.__workflow;
|
|
253
|
-
if (!meta)
|
|
262
|
+
if (!meta)
|
|
263
|
+
throw Object.assign(new Error("Entry has no workflow metadata"), { statusCode: 409 });
|
|
254
264
|
if (expectedRevision !== void 0 && expectedRevision !== meta.revision) {
|
|
255
265
|
throw Object.assign(new Error("This entry changed since it was loaded. Refresh before transitioning it."), { statusCode: 409 });
|
|
256
266
|
}
|
|
@@ -266,7 +276,8 @@ async function transitionWorkflow(args) {
|
|
|
266
276
|
throw Object.assign(new Error(`A comment is required for "${transition.label}".`), { statusCode: 400 });
|
|
267
277
|
}
|
|
268
278
|
const hookContext = { transition, from: meta.state, to: transition.to, doc: original, user, comment, req, db };
|
|
269
|
-
for (const hook of workflow.hooks?.beforeTransition ?? [])
|
|
279
|
+
for (const hook of workflow.hooks?.beforeTransition ?? [])
|
|
280
|
+
await hook(hookContext);
|
|
270
281
|
const events = [createLifecycleEvent({
|
|
271
282
|
name: "workflow.transitioned",
|
|
272
283
|
collection: collection.slug,
|
|
@@ -282,7 +293,8 @@ async function transitionWorkflow(args) {
|
|
|
282
293
|
}
|
|
283
294
|
const updated = await db.transaction(async (tx) => {
|
|
284
295
|
const locked = await tx.findOne({ collection: collection.slug, id });
|
|
285
|
-
if (!locked)
|
|
296
|
+
if (!locked)
|
|
297
|
+
throw Object.assign(new Error("Not Found"), { statusCode: 404 });
|
|
286
298
|
const lockedMeta = locked.__workflow;
|
|
287
299
|
if (lockedMeta.revision !== meta.revision || lockedMeta.state !== meta.state || expectedRevision !== void 0 && lockedMeta.revision !== expectedRevision) {
|
|
288
300
|
throw Object.assign(new Error("This entry changed since it was loaded. Refresh before transitioning it."), { statusCode: 409 });
|
|
@@ -296,20 +308,24 @@ async function transitionWorkflow(args) {
|
|
|
296
308
|
...transition.unpublish ? { publishedRevision: void 0, publishedAt: void 0, publishedBy: void 0 } : {}
|
|
297
309
|
};
|
|
298
310
|
const data = { __workflow: nextMeta };
|
|
299
|
-
if (targetState.published)
|
|
300
|
-
|
|
311
|
+
if (targetState.published)
|
|
312
|
+
data.__published = working;
|
|
313
|
+
if (transition.unpublish)
|
|
314
|
+
data.__published = null;
|
|
301
315
|
const next = await tx.update({ collection: collection.slug, id, data });
|
|
302
316
|
await tx.create({
|
|
303
317
|
collection: WORKFLOW_HISTORY_COLLECTION,
|
|
304
318
|
data: { collection: collection.slug, documentId: id, transition: transition.name, from: lockedMeta.state, to: transition.to, revision: lockedMeta.revision, comment: comment ?? null, actorId: user?.sub ?? null, createdAt: now }
|
|
305
319
|
});
|
|
306
|
-
for (const event of events)
|
|
320
|
+
for (const event of events)
|
|
321
|
+
await persistEvent(tx, event);
|
|
307
322
|
if (collection.audit) {
|
|
308
323
|
await tx.create({ collection: "__audit", data: { collection: collection.slug, documentId: id, operation: "workflow.transition", user: user?.sub ?? null, timestamp: now, changes: JSON.stringify({ transition: transition.name, from: lockedMeta.state, to: transition.to, revision: lockedMeta.revision }) } });
|
|
309
324
|
}
|
|
310
325
|
return next;
|
|
311
326
|
});
|
|
312
|
-
for (const event of events)
|
|
327
|
+
for (const event of events)
|
|
328
|
+
void dispatchLifecycleEvent(config, event);
|
|
313
329
|
for (const hook of workflow.hooks?.afterTransition ?? []) {
|
|
314
330
|
try {
|
|
315
331
|
await hook({ ...hookContext, doc: updated, event: events[0] });
|
|
@@ -320,7 +336,7 @@ async function transitionWorkflow(args) {
|
|
|
320
336
|
return updated;
|
|
321
337
|
}
|
|
322
338
|
|
|
323
|
-
// src/utils/admin-auth.
|
|
339
|
+
// src/utils/admin-auth.js
|
|
324
340
|
function getAdminAuthCollection(config) {
|
|
325
341
|
const requestedSlug = config.adminAuth?.collectionSlug;
|
|
326
342
|
if (requestedSlug) {
|
|
@@ -344,11 +360,12 @@ function getPublicAdminAuthConfig(adminAuth) {
|
|
|
344
360
|
}
|
|
345
361
|
function humanizeProviderName(id, type) {
|
|
346
362
|
const cleaned = id.replace(/[-_]+/g, " ").trim();
|
|
347
|
-
if (!cleaned)
|
|
363
|
+
if (!cleaned)
|
|
364
|
+
return type.toUpperCase();
|
|
348
365
|
return cleaned.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
349
366
|
}
|
|
350
367
|
|
|
351
|
-
// src/utils/config.
|
|
368
|
+
// src/utils/config.js
|
|
352
369
|
var AUDIT_COLLECTION_SLUG = "__audit";
|
|
353
370
|
var SYSTEM_FIELDS = [
|
|
354
371
|
{
|
|
@@ -562,7 +579,8 @@ function normalizeConfig(config) {
|
|
|
562
579
|
});
|
|
563
580
|
const hasAuditCollection = normalizedCollections.some((col) => col.slug === AUDIT_COLLECTION_SLUG);
|
|
564
581
|
const systemCollections = [];
|
|
565
|
-
if (needsAudit && !hasAuditCollection)
|
|
582
|
+
if (needsAudit && !hasAuditCollection)
|
|
583
|
+
systemCollections.push(AUDIT_COLLECTION);
|
|
566
584
|
if (needsWorkflow && !normalizedCollections.some((col) => col.slug === WORKFLOW_HISTORY_COLLECTION)) {
|
|
567
585
|
systemCollections.push(WORKFLOW_HISTORY_COLLECTION_CONFIG);
|
|
568
586
|
}
|
|
@@ -576,7 +594,7 @@ function normalizeConfig(config) {
|
|
|
576
594
|
};
|
|
577
595
|
}
|
|
578
596
|
|
|
579
|
-
// src/utils/parse-where.
|
|
597
|
+
// src/utils/parse-where.js
|
|
580
598
|
function assertNever(op, context) {
|
|
581
599
|
throw new Error(`[dyrected/core] Unhandled where operator "${op}" in ${context}`);
|
|
582
600
|
}
|
|
@@ -612,7 +630,8 @@ function parseSqlWhere(where, getJsonField, placeholder = "?") {
|
|
|
612
630
|
return `${c} != ${next()}`;
|
|
613
631
|
case "in": {
|
|
614
632
|
const vals = Array.isArray(operand) ? operand : [operand];
|
|
615
|
-
if (vals.length === 0)
|
|
633
|
+
if (vals.length === 0)
|
|
634
|
+
return "1=0";
|
|
616
635
|
const placeholders = vals.map((v) => {
|
|
617
636
|
params.push(v);
|
|
618
637
|
return next();
|
|
@@ -621,7 +640,8 @@ function parseSqlWhere(where, getJsonField, placeholder = "?") {
|
|
|
621
640
|
}
|
|
622
641
|
case "not_in": {
|
|
623
642
|
const vals = Array.isArray(operand) ? operand : [operand];
|
|
624
|
-
if (vals.length === 0)
|
|
643
|
+
if (vals.length === 0)
|
|
644
|
+
return "1=1";
|
|
625
645
|
const placeholders = vals.map((v) => {
|
|
626
646
|
params.push(v);
|
|
627
647
|
return next();
|
|
@@ -727,22 +747,26 @@ function parseMongoWhere(where) {
|
|
|
727
747
|
conditions.push(buildOperator(field, value));
|
|
728
748
|
}
|
|
729
749
|
}
|
|
730
|
-
if (conditions.length === 0)
|
|
731
|
-
|
|
750
|
+
if (conditions.length === 0)
|
|
751
|
+
return {};
|
|
752
|
+
if (conditions.length === 1)
|
|
753
|
+
return conditions[0];
|
|
732
754
|
return { $and: conditions };
|
|
733
755
|
}
|
|
734
756
|
return buildClause(where);
|
|
735
757
|
}
|
|
736
758
|
|
|
737
|
-
// src/utils/parse-sort.
|
|
759
|
+
// src/utils/parse-sort.js
|
|
738
760
|
var SORT_FIELD_PATTERN = /^([A-Za-z_][A-Za-z0-9_]*)(?:\s+(ASC|DESC))?$/i;
|
|
739
761
|
function parseSort(sort, fallback = { field: "createdAt", direction: "DESC" }) {
|
|
740
|
-
if (!sort)
|
|
762
|
+
if (!sort)
|
|
763
|
+
return [fallback];
|
|
741
764
|
const clauses = sort.split(",").map((part) => part.trim()).filter(Boolean).map((part) => {
|
|
742
765
|
const descByPrefix = part.startsWith("-");
|
|
743
766
|
const withoutPrefix = descByPrefix ? part.slice(1).trim() : part;
|
|
744
767
|
const match = withoutPrefix.match(SORT_FIELD_PATTERN);
|
|
745
|
-
if (!match)
|
|
768
|
+
if (!match)
|
|
769
|
+
return null;
|
|
746
770
|
return {
|
|
747
771
|
field: match[1],
|
|
748
772
|
direction: descByPrefix || match[2]?.toUpperCase() === "DESC" ? "DESC" : "ASC"
|
|
@@ -751,7 +775,7 @@ function parseSort(sort, fallback = { field: "createdAt", direction: "DESC" }) {
|
|
|
751
775
|
return clauses.length > 0 ? clauses : [fallback];
|
|
752
776
|
}
|
|
753
777
|
|
|
754
|
-
// src/utils/hooks.
|
|
778
|
+
// src/utils/hooks.js
|
|
755
779
|
async function runCollectionHooks(hooks, args, options = {}) {
|
|
756
780
|
if (!hooks || hooks.length === 0) {
|
|
757
781
|
return args.data ?? args.doc ?? void 0;
|
|
@@ -778,10 +802,12 @@ async function runCollectionHooks(hooks, args, options = {}) {
|
|
|
778
802
|
return currentPayload;
|
|
779
803
|
}
|
|
780
804
|
async function executeFieldBeforeChange(fields, data, originalDoc, user, db) {
|
|
781
|
-
if (!data || typeof data !== "object")
|
|
805
|
+
if (!data || typeof data !== "object")
|
|
806
|
+
return data;
|
|
782
807
|
const result = { ...data };
|
|
783
808
|
for (const field of fields) {
|
|
784
|
-
if (!field.name)
|
|
809
|
+
if (!field.name)
|
|
810
|
+
continue;
|
|
785
811
|
const value = result[field.name];
|
|
786
812
|
const origValue = originalDoc?.[field.name];
|
|
787
813
|
let updatedValue = value;
|
|
@@ -801,21 +827,13 @@ async function executeFieldBeforeChange(fields, data, originalDoc, user, db) {
|
|
|
801
827
|
}
|
|
802
828
|
if (updatedValue !== void 0 && updatedValue !== null) {
|
|
803
829
|
if (field.type === "object" && field.fields) {
|
|
804
|
-
result[field.name] = await executeFieldBeforeChange(
|
|
805
|
-
field.fields,
|
|
806
|
-
updatedValue,
|
|
807
|
-
origValue,
|
|
808
|
-
user,
|
|
809
|
-
db
|
|
810
|
-
);
|
|
830
|
+
result[field.name] = await executeFieldBeforeChange(field.fields, updatedValue, origValue, user, db);
|
|
811
831
|
} else if (field.type === "array" && field.fields && Array.isArray(updatedValue)) {
|
|
812
832
|
const arrayResult = [];
|
|
813
833
|
for (let i = 0; i < updatedValue.length; i++) {
|
|
814
834
|
const item = updatedValue[i];
|
|
815
835
|
const origItem = Array.isArray(origValue) ? origValue[i] : null;
|
|
816
|
-
arrayResult.push(
|
|
817
|
-
await executeFieldBeforeChange(field.fields, item, origItem, user, db)
|
|
818
|
-
);
|
|
836
|
+
arrayResult.push(await executeFieldBeforeChange(field.fields, item, origItem, user, db));
|
|
819
837
|
}
|
|
820
838
|
result[field.name] = arrayResult;
|
|
821
839
|
} else if (field.type === "blocks" && field.blocks && Array.isArray(updatedValue)) {
|
|
@@ -823,19 +841,9 @@ async function executeFieldBeforeChange(fields, data, originalDoc, user, db) {
|
|
|
823
841
|
for (let i = 0; i < updatedValue.length; i++) {
|
|
824
842
|
const blockData = updatedValue[i];
|
|
825
843
|
const origBlock = Array.isArray(origValue) ? origValue[i] : null;
|
|
826
|
-
const blockConfig = field.blocks.find(
|
|
827
|
-
(b) => b.slug === blockData.blockType
|
|
828
|
-
);
|
|
844
|
+
const blockConfig = field.blocks.find((b) => b.slug === blockData.blockType);
|
|
829
845
|
if (blockConfig) {
|
|
830
|
-
blocksResult.push(
|
|
831
|
-
await executeFieldBeforeChange(
|
|
832
|
-
blockConfig.fields,
|
|
833
|
-
blockData,
|
|
834
|
-
origBlock,
|
|
835
|
-
user,
|
|
836
|
-
db
|
|
837
|
-
)
|
|
838
|
-
);
|
|
846
|
+
blocksResult.push(await executeFieldBeforeChange(blockConfig.fields, blockData, origBlock, user, db));
|
|
839
847
|
} else {
|
|
840
848
|
blocksResult.push(blockData);
|
|
841
849
|
}
|
|
@@ -847,10 +855,12 @@ async function executeFieldBeforeChange(fields, data, originalDoc, user, db) {
|
|
|
847
855
|
return result;
|
|
848
856
|
}
|
|
849
857
|
async function executeFieldAfterRead(fields, doc, user, db) {
|
|
850
|
-
if (!doc || typeof doc !== "object")
|
|
858
|
+
if (!doc || typeof doc !== "object")
|
|
859
|
+
return doc;
|
|
851
860
|
const result = { ...doc };
|
|
852
861
|
for (const field of fields) {
|
|
853
|
-
if (!field.name)
|
|
862
|
+
if (!field.name)
|
|
863
|
+
continue;
|
|
854
864
|
const value = result[field.name];
|
|
855
865
|
let updatedValue = value;
|
|
856
866
|
if (field.hooks?.afterRead) {
|
|
@@ -868,41 +878,20 @@ async function executeFieldAfterRead(fields, doc, user, db) {
|
|
|
868
878
|
}
|
|
869
879
|
if (updatedValue !== void 0 && updatedValue !== null) {
|
|
870
880
|
if (field.type === "object" && field.fields) {
|
|
871
|
-
result[field.name] = await executeFieldAfterRead(
|
|
872
|
-
field.fields,
|
|
873
|
-
updatedValue,
|
|
874
|
-
user,
|
|
875
|
-
db
|
|
876
|
-
);
|
|
881
|
+
result[field.name] = await executeFieldAfterRead(field.fields, updatedValue, user, db);
|
|
877
882
|
} else if (field.type === "array" && field.fields && Array.isArray(updatedValue)) {
|
|
878
883
|
const arrayResult = [];
|
|
879
884
|
for (const item of updatedValue) {
|
|
880
|
-
arrayResult.push(
|
|
881
|
-
await executeFieldAfterRead(
|
|
882
|
-
field.fields,
|
|
883
|
-
item,
|
|
884
|
-
user,
|
|
885
|
-
db
|
|
886
|
-
)
|
|
887
|
-
);
|
|
885
|
+
arrayResult.push(await executeFieldAfterRead(field.fields, item, user, db));
|
|
888
886
|
}
|
|
889
887
|
result[field.name] = arrayResult;
|
|
890
888
|
} else if (field.type === "blocks" && field.blocks && Array.isArray(updatedValue)) {
|
|
891
889
|
const blocksResult = [];
|
|
892
890
|
for (const blockData of updatedValue) {
|
|
893
891
|
const typedBlock = blockData;
|
|
894
|
-
const blockConfig = field.blocks.find(
|
|
895
|
-
(b) => b.slug === typedBlock.blockType
|
|
896
|
-
);
|
|
892
|
+
const blockConfig = field.blocks.find((b) => b.slug === typedBlock.blockType);
|
|
897
893
|
if (blockConfig) {
|
|
898
|
-
blocksResult.push(
|
|
899
|
-
await executeFieldAfterRead(
|
|
900
|
-
blockConfig.fields,
|
|
901
|
-
typedBlock,
|
|
902
|
-
user,
|
|
903
|
-
db
|
|
904
|
-
)
|
|
905
|
-
);
|
|
894
|
+
blocksResult.push(await executeFieldAfterRead(blockConfig.fields, typedBlock, user, db));
|
|
906
895
|
} else {
|
|
907
896
|
blocksResult.push(blockData);
|
|
908
897
|
}
|
|
@@ -914,7 +903,7 @@ async function executeFieldAfterRead(fields, doc, user, db) {
|
|
|
914
903
|
return result;
|
|
915
904
|
}
|
|
916
905
|
|
|
917
|
-
// src/utils/openapi.
|
|
906
|
+
// src/utils/openapi.js
|
|
918
907
|
function generateOpenApi(config) {
|
|
919
908
|
const spec = {
|
|
920
909
|
openapi: "3.0.0",
|
|
@@ -1623,7 +1612,8 @@ function fieldsToProperties(fields) {
|
|
|
1623
1612
|
required.push(...nested.required);
|
|
1624
1613
|
continue;
|
|
1625
1614
|
}
|
|
1626
|
-
if (!field.name)
|
|
1615
|
+
if (!field.name)
|
|
1616
|
+
continue;
|
|
1627
1617
|
props[field.name] = fieldToSchema(field);
|
|
1628
1618
|
if (field.required) {
|
|
1629
1619
|
required.push(field.name);
|
|
@@ -1735,7 +1725,8 @@ function fieldToSchema(field) {
|
|
|
1735
1725
|
default:
|
|
1736
1726
|
schema = { type: "string" };
|
|
1737
1727
|
}
|
|
1738
|
-
if (field.label)
|
|
1728
|
+
if (field.label)
|
|
1729
|
+
schema.description = field.label;
|
|
1739
1730
|
return schema;
|
|
1740
1731
|
}
|
|
1741
1732
|
|
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/index.js
CHANGED
|
@@ -20,9 +20,9 @@ import {
|
|
|
20
20
|
saveWorkflowDraft,
|
|
21
21
|
transitionWorkflow,
|
|
22
22
|
workflowCapabilities
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-44O2LDPT.js";
|
|
24
24
|
|
|
25
|
-
// src/types/workflows.
|
|
25
|
+
// src/types/workflows.js
|
|
26
26
|
var LIFECYCLE_EVENT_NAMES = [
|
|
27
27
|
"revision.created",
|
|
28
28
|
"workflow.transitioned",
|
|
@@ -30,7 +30,7 @@ var LIFECYCLE_EVENT_NAMES = [
|
|
|
30
30
|
"entry.unpublished"
|
|
31
31
|
];
|
|
32
32
|
|
|
33
|
-
// src/utils/parse-where.
|
|
33
|
+
// src/utils/parse-where.js
|
|
34
34
|
function assertNever(op, context) {
|
|
35
35
|
throw new Error(`[dyrected/core] Unhandled where operator "${op}" in ${context}`);
|
|
36
36
|
}
|
|
@@ -66,7 +66,8 @@ function parseSqlWhere(where, getJsonField, placeholder = "?") {
|
|
|
66
66
|
return `${c} != ${next()}`;
|
|
67
67
|
case "in": {
|
|
68
68
|
const vals = Array.isArray(operand) ? operand : [operand];
|
|
69
|
-
if (vals.length === 0)
|
|
69
|
+
if (vals.length === 0)
|
|
70
|
+
return "1=0";
|
|
70
71
|
const placeholders = vals.map((v) => {
|
|
71
72
|
params.push(v);
|
|
72
73
|
return next();
|
|
@@ -75,7 +76,8 @@ function parseSqlWhere(where, getJsonField, placeholder = "?") {
|
|
|
75
76
|
}
|
|
76
77
|
case "not_in": {
|
|
77
78
|
const vals = Array.isArray(operand) ? operand : [operand];
|
|
78
|
-
if (vals.length === 0)
|
|
79
|
+
if (vals.length === 0)
|
|
80
|
+
return "1=1";
|
|
79
81
|
const placeholders = vals.map((v) => {
|
|
80
82
|
params.push(v);
|
|
81
83
|
return next();
|
|
@@ -181,22 +183,26 @@ function parseMongoWhere(where) {
|
|
|
181
183
|
conditions.push(buildOperator(field, value));
|
|
182
184
|
}
|
|
183
185
|
}
|
|
184
|
-
if (conditions.length === 0)
|
|
185
|
-
|
|
186
|
+
if (conditions.length === 0)
|
|
187
|
+
return {};
|
|
188
|
+
if (conditions.length === 1)
|
|
189
|
+
return conditions[0];
|
|
186
190
|
return { $and: conditions };
|
|
187
191
|
}
|
|
188
192
|
return buildClause(where);
|
|
189
193
|
}
|
|
190
194
|
|
|
191
|
-
// src/utils/parse-sort.
|
|
195
|
+
// src/utils/parse-sort.js
|
|
192
196
|
var SORT_FIELD_PATTERN = /^([A-Za-z_][A-Za-z0-9_]*)(?:\s+(ASC|DESC))?$/i;
|
|
193
197
|
function parseSort(sort, fallback = { field: "createdAt", direction: "DESC" }) {
|
|
194
|
-
if (!sort)
|
|
198
|
+
if (!sort)
|
|
199
|
+
return [fallback];
|
|
195
200
|
const clauses = sort.split(",").map((part) => part.trim()).filter(Boolean).map((part) => {
|
|
196
201
|
const descByPrefix = part.startsWith("-");
|
|
197
202
|
const withoutPrefix = descByPrefix ? part.slice(1).trim() : part;
|
|
198
203
|
const match = withoutPrefix.match(SORT_FIELD_PATTERN);
|
|
199
|
-
if (!match)
|
|
204
|
+
if (!match)
|
|
205
|
+
return null;
|
|
200
206
|
return {
|
|
201
207
|
field: match[1],
|
|
202
208
|
direction: descByPrefix || match[2]?.toUpperCase() === "DESC" ? "DESC" : "ASC"
|