@dyrected/core 2.5.59 → 2.5.61
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-9hs8DRED.d.cts +1718 -0
- package/dist/app-config-9hs8DRED.d.ts +1718 -0
- package/dist/app-config-C0twGIaF.d.cts +1597 -0
- package/dist/app-config-C0twGIaF.d.ts +1597 -0
- package/dist/app-config-C0uxEU7Q.d.cts +1874 -0
- package/dist/app-config-C0uxEU7Q.d.ts +1874 -0
- package/dist/app-config-CBOn8IyZ.d.cts +1838 -0
- package/dist/app-config-CBOn8IyZ.d.ts +1838 -0
- package/dist/app-config-CstocO9M.d.cts +1580 -0
- package/dist/app-config-CstocO9M.d.ts +1580 -0
- package/dist/app-config-CwaU1de2.d.cts +1868 -0
- package/dist/app-config-CwaU1de2.d.ts +1868 -0
- package/dist/app-config-DIwvzbpe.d.cts +1555 -0
- package/dist/app-config-DIwvzbpe.d.ts +1555 -0
- package/dist/app-config-DVdSospO.d.cts +1842 -0
- package/dist/app-config-DVdSospO.d.ts +1842 -0
- package/dist/app-config-Dkndq5ni.d.cts +1580 -0
- package/dist/app-config-Dkndq5ni.d.ts +1580 -0
- package/dist/app-config-P-SF5nnR.d.cts +1568 -0
- package/dist/app-config-P-SF5nnR.d.ts +1568 -0
- package/dist/app-config-ouBRb6Bf.d.cts +1716 -0
- package/dist/app-config-ouBRb6Bf.d.ts +1716 -0
- package/dist/chunk-2WODKOUB.js +1627 -0
- package/dist/chunk-35NM2WPO.js +1658 -0
- package/dist/chunk-3CMG2BH2.js +1618 -0
- package/dist/chunk-CUOPCOU2.js +1644 -0
- package/dist/chunk-DCY7QHRB.js +1637 -0
- package/dist/chunk-EOW4YMAV.js +1637 -0
- package/dist/chunk-JFA22YFB.js +1625 -0
- package/dist/chunk-WF5A6PDJ.js +1618 -0
- package/dist/index.cjs +209 -47
- package/dist/index.d.cts +79 -4
- package/dist/index.d.ts +79 -4
- package/dist/index.js +42 -4
- package/dist/server.cjs +388 -56
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +224 -13
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,7 @@ __export(index_exports, {
|
|
|
24
24
|
LIFECYCLE_EVENT_NAMES: () => LIFECYCLE_EVENT_NAMES,
|
|
25
25
|
WORKFLOW_HISTORY_COLLECTION: () => WORKFLOW_HISTORY_COLLECTION,
|
|
26
26
|
availableWorkflowTransitions: () => availableWorkflowTransitions,
|
|
27
|
+
buildSqlOrderBy: () => buildSqlOrderBy,
|
|
27
28
|
canViewWorkflowDraft: () => canViewWorkflowDraft,
|
|
28
29
|
createLifecycleEvent: () => createLifecycleEvent,
|
|
29
30
|
createWorkflowDocument: () => createWorkflowDocument,
|
|
@@ -50,6 +51,7 @@ __export(index_exports, {
|
|
|
50
51
|
defineRichTextField: () => defineRichTextField,
|
|
51
52
|
defineRowField: () => defineRowField,
|
|
52
53
|
defineSelectField: () => defineSelectField,
|
|
54
|
+
defineTab: () => defineTab,
|
|
53
55
|
defineTextField: () => defineTextField,
|
|
54
56
|
defineTextareaField: () => defineTextareaField,
|
|
55
57
|
defineTimeField: () => defineTimeField,
|
|
@@ -64,6 +66,7 @@ __export(index_exports, {
|
|
|
64
66
|
initializeWorkflowDocument: () => initializeWorkflowDocument,
|
|
65
67
|
materializeWorkflowDocument: () => materializeWorkflowDocument,
|
|
66
68
|
normalizeConfig: () => normalizeConfig,
|
|
69
|
+
numericFieldNames: () => numericFieldNames,
|
|
67
70
|
parseMongoWhere: () => parseMongoWhere,
|
|
68
71
|
parseSort: () => parseSort,
|
|
69
72
|
parseSqlWhere: () => parseSqlWhere,
|
|
@@ -71,6 +74,7 @@ __export(index_exports, {
|
|
|
71
74
|
resolveAdminAuthCollection: () => resolveAdminAuthCollection,
|
|
72
75
|
runCollectionHooks: () => runCollectionHooks,
|
|
73
76
|
saveWorkflowDraft: () => saveWorkflowDraft,
|
|
77
|
+
simplePublishingWorkflow: () => simplePublishingWorkflow,
|
|
74
78
|
transitionWorkflow: () => transitionWorkflow,
|
|
75
79
|
workflowCapabilities: () => workflowCapabilities
|
|
76
80
|
});
|
|
@@ -109,6 +113,20 @@ function publishingWorkflow() {
|
|
|
109
113
|
]
|
|
110
114
|
};
|
|
111
115
|
}
|
|
116
|
+
function simplePublishingWorkflow() {
|
|
117
|
+
return {
|
|
118
|
+
initialState: "draft",
|
|
119
|
+
draftState: "draft",
|
|
120
|
+
states: [
|
|
121
|
+
{ name: "draft", label: "Draft", color: "neutral" },
|
|
122
|
+
{ name: "published", label: "Published", color: "success", published: true }
|
|
123
|
+
],
|
|
124
|
+
transitions: [
|
|
125
|
+
{ name: "publish", label: "Publish", from: "draft", to: "published" },
|
|
126
|
+
{ name: "unpublish", label: "Unpublish", from: "published", to: "draft", unpublish: true }
|
|
127
|
+
]
|
|
128
|
+
};
|
|
129
|
+
}
|
|
112
130
|
function publicMetadata(meta) {
|
|
113
131
|
const { availableTransitions: _availableTransitions, ...safe } = meta;
|
|
114
132
|
return safe;
|
|
@@ -142,9 +160,23 @@ function initializeWorkflowDocument(data, workflow) {
|
|
|
142
160
|
__workflow: { state: workflow.initialState, revision: 1 }
|
|
143
161
|
};
|
|
144
162
|
}
|
|
163
|
+
function publishedStateName(workflow) {
|
|
164
|
+
return workflow.states.find((state) => state.published)?.name ?? workflow.states[workflow.states.length - 1]?.name ?? workflow.initialState;
|
|
165
|
+
}
|
|
145
166
|
function materializeWorkflowDocument(doc, workflow, user) {
|
|
146
167
|
const meta = doc.__workflow;
|
|
147
|
-
if (!meta)
|
|
168
|
+
if (!meta) {
|
|
169
|
+
const { __published: _legacyPublished, __workflow: _legacyWorkflow, ...working2 } = doc;
|
|
170
|
+
const state = publishedStateName(workflow);
|
|
171
|
+
return {
|
|
172
|
+
...working2,
|
|
173
|
+
_workflow: {
|
|
174
|
+
state,
|
|
175
|
+
revision: 1,
|
|
176
|
+
availableTransitions: availableWorkflowTransitions(workflow, state, user).map((item) => item.name)
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
148
180
|
const { __published, __workflow, ...working } = doc;
|
|
149
181
|
if (!canViewWorkflowDraft(workflow, user)) {
|
|
150
182
|
if (!__published || typeof __published !== "object") return null;
|
|
@@ -419,6 +451,7 @@ var AUDIT_COLLECTION = {
|
|
|
419
451
|
{ name: "timestamp", type: "date", label: "Timestamp", required: true },
|
|
420
452
|
{ name: "changes", type: "json", label: "Changes" }
|
|
421
453
|
],
|
|
454
|
+
access: { read: () => false, create: () => false, update: () => false, delete: () => false },
|
|
422
455
|
admin: { hidden: true }
|
|
423
456
|
};
|
|
424
457
|
var WORKFLOW_HISTORY_COLLECTION_CONFIG = {
|
|
@@ -461,7 +494,7 @@ function normalizeConfig(config) {
|
|
|
461
494
|
const collections = config?.collections || [];
|
|
462
495
|
const globals = config?.globals || [];
|
|
463
496
|
const needsAudit = collections.some((col) => col.audit);
|
|
464
|
-
const needsWorkflow = collections.some((col) => col.workflow);
|
|
497
|
+
const needsWorkflow = collections.some((col) => col.workflow || col.drafts);
|
|
465
498
|
const adminAuthCollectionSlug = getAdminAuthCollection({
|
|
466
499
|
collections,
|
|
467
500
|
adminAuth: config.adminAuth
|
|
@@ -523,6 +556,12 @@ function normalizeConfig(config) {
|
|
|
523
556
|
if (field.name === "email") {
|
|
524
557
|
return {
|
|
525
558
|
...field,
|
|
559
|
+
// Email is the login identifier. Keep the integrity constraints
|
|
560
|
+
// auth relies on even when the field is explicitly redefined, so a
|
|
561
|
+
// custom `email` field can never silently drop uniqueness.
|
|
562
|
+
required: true,
|
|
563
|
+
unique: true,
|
|
564
|
+
promoted: true,
|
|
526
565
|
access: {
|
|
527
566
|
...field.access || {},
|
|
528
567
|
update: "!id"
|
|
@@ -532,6 +571,9 @@ function normalizeConfig(config) {
|
|
|
532
571
|
if (field.name === "password") {
|
|
533
572
|
return {
|
|
534
573
|
...field,
|
|
574
|
+
// Password is required to authenticate; enforce it regardless of
|
|
575
|
+
// how the field was declared.
|
|
576
|
+
required: true,
|
|
535
577
|
admin: { ...field.admin || {} },
|
|
536
578
|
access: {
|
|
537
579
|
...field.access || {},
|
|
@@ -587,8 +629,10 @@ function normalizeConfig(config) {
|
|
|
587
629
|
}
|
|
588
630
|
const updatedFieldNames = new Set(fields.map((f) => f.name));
|
|
589
631
|
const fieldsToInject = SYSTEM_FIELDS.filter((f) => !updatedFieldNames.has(f.name));
|
|
632
|
+
const workflow = col.workflow || (col.drafts ? simplePublishingWorkflow() : void 0);
|
|
590
633
|
return {
|
|
591
634
|
...col,
|
|
635
|
+
workflow,
|
|
592
636
|
fields: [...fields, ...fieldsToInject]
|
|
593
637
|
};
|
|
594
638
|
});
|
|
@@ -612,7 +656,7 @@ function normalizeConfig(config) {
|
|
|
612
656
|
function assertNever(op, context) {
|
|
613
657
|
throw new Error(`[dyrected/core] Unhandled where operator "${op}" in ${context}`);
|
|
614
658
|
}
|
|
615
|
-
function parseSqlWhere(where, getJsonField, placeholder = "?") {
|
|
659
|
+
function parseSqlWhere(where, getJsonField, placeholder = "?", likeOperator = "LIKE") {
|
|
616
660
|
const params = [];
|
|
617
661
|
let pgIndex = 1;
|
|
618
662
|
function next() {
|
|
@@ -674,10 +718,10 @@ function parseSqlWhere(where, getJsonField, placeholder = "?") {
|
|
|
674
718
|
return `${c} <= ${next()}`;
|
|
675
719
|
case "contains":
|
|
676
720
|
params.push(`%${operand}%`);
|
|
677
|
-
return `${c}
|
|
721
|
+
return `${c} ${likeOperator} ${next()}`;
|
|
678
722
|
case "starts_with":
|
|
679
723
|
params.push(`${operand}%`);
|
|
680
|
-
return `${c}
|
|
724
|
+
return `${c} ${likeOperator} ${next()}`;
|
|
681
725
|
case "exists":
|
|
682
726
|
return operand ? `${c} IS NOT NULL` : `${c} IS NULL`;
|
|
683
727
|
default:
|
|
@@ -782,6 +826,33 @@ function parseSort(sort, fallback = { field: "createdAt", direction: "DESC" }) {
|
|
|
782
826
|
}).filter((clause) => Boolean(clause));
|
|
783
827
|
return clauses.length > 0 ? clauses : [fallback];
|
|
784
828
|
}
|
|
829
|
+
function numericFieldNames(fields) {
|
|
830
|
+
const names = /* @__PURE__ */ new Set();
|
|
831
|
+
for (const field of fields ?? []) {
|
|
832
|
+
if (field.type === "number" && "name" in field && field.name) {
|
|
833
|
+
names.add(field.name);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
return names;
|
|
837
|
+
}
|
|
838
|
+
var TIMESTAMP_COLUMNS = {
|
|
839
|
+
createdat: "created_at",
|
|
840
|
+
created_at: "created_at",
|
|
841
|
+
updatedat: "updated_at",
|
|
842
|
+
updated_at: "updated_at"
|
|
843
|
+
};
|
|
844
|
+
function buildSqlOrderBy(sort, existingColumns, numericFields, dialect) {
|
|
845
|
+
return parseSort(sort).map(({ field, direction }) => {
|
|
846
|
+
const timestamp = TIMESTAMP_COLUMNS[field.toLowerCase()];
|
|
847
|
+
if (timestamp) return `${dialect.quoteIdent(timestamp)} ${direction}`;
|
|
848
|
+
if (existingColumns.includes(field) && field !== "id" && field !== "data") {
|
|
849
|
+
return `${dialect.quoteIdent(field)} ${direction}`;
|
|
850
|
+
}
|
|
851
|
+
const extracted = dialect.jsonExtract(field);
|
|
852
|
+
const expr = numericFields.has(field) ? dialect.castNumeric(extracted) : extracted;
|
|
853
|
+
return `${expr} ${direction}`;
|
|
854
|
+
}).join(", ");
|
|
855
|
+
}
|
|
785
856
|
|
|
786
857
|
// src/utils/hooks.ts
|
|
787
858
|
async function runCollectionHooks(hooks, args, options = {}) {
|
|
@@ -947,6 +1018,15 @@ async function executeFieldAfterRead(fields, doc, user, db) {
|
|
|
947
1018
|
}
|
|
948
1019
|
|
|
949
1020
|
// src/utils/openapi.ts
|
|
1021
|
+
function getCollectionLabels(collection) {
|
|
1022
|
+
return collection.labels || { singular: collection.slug, plural: collection.slug };
|
|
1023
|
+
}
|
|
1024
|
+
function getCollectionTag(collection) {
|
|
1025
|
+
return `Collection: ${getCollectionLabels(collection).plural}`;
|
|
1026
|
+
}
|
|
1027
|
+
function getGlobalTag(global) {
|
|
1028
|
+
return `Global: ${global.label || global.slug}`;
|
|
1029
|
+
}
|
|
950
1030
|
function generateOpenApi(config) {
|
|
951
1031
|
const spec = {
|
|
952
1032
|
openapi: "3.0.0",
|
|
@@ -978,15 +1058,7 @@ function generateOpenApi(config) {
|
|
|
978
1058
|
},
|
|
979
1059
|
WorkflowHistoryEntry: {
|
|
980
1060
|
type: "object",
|
|
981
|
-
required: [
|
|
982
|
-
"collection",
|
|
983
|
-
"documentId",
|
|
984
|
-
"transition",
|
|
985
|
-
"from",
|
|
986
|
-
"to",
|
|
987
|
-
"revision",
|
|
988
|
-
"createdAt"
|
|
989
|
-
],
|
|
1061
|
+
required: ["collection", "documentId", "transition", "from", "to", "revision", "createdAt"],
|
|
990
1062
|
properties: {
|
|
991
1063
|
id: { type: "string" },
|
|
992
1064
|
collection: { type: "string" },
|
|
@@ -1000,6 +1072,21 @@ function generateOpenApi(config) {
|
|
|
1000
1072
|
createdAt: { type: "string", format: "date-time" }
|
|
1001
1073
|
}
|
|
1002
1074
|
},
|
|
1075
|
+
AuditEntry: {
|
|
1076
|
+
type: "object",
|
|
1077
|
+
required: ["collection", "operation", "timestamp"],
|
|
1078
|
+
properties: {
|
|
1079
|
+
id: { type: "string" },
|
|
1080
|
+
collection: { type: "string" },
|
|
1081
|
+
documentId: { type: "string", nullable: true },
|
|
1082
|
+
operation: { type: "string" },
|
|
1083
|
+
user: { type: "string", nullable: true },
|
|
1084
|
+
timestamp: { type: "string", format: "date-time" },
|
|
1085
|
+
changes: {
|
|
1086
|
+
oneOf: [{ type: "string" }, { type: "object", additionalProperties: true }, { type: "null" }]
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
1003
1090
|
Error: {
|
|
1004
1091
|
type: "object",
|
|
1005
1092
|
properties: {
|
|
@@ -1088,17 +1175,13 @@ function generateOpenApi(config) {
|
|
|
1088
1175
|
get: {
|
|
1089
1176
|
tags: ["Preferences"],
|
|
1090
1177
|
summary: "Get an authenticated user preference",
|
|
1091
|
-
parameters: [
|
|
1092
|
-
{ name: "key", in: "path", required: true, schema: { type: "string" } }
|
|
1093
|
-
],
|
|
1178
|
+
parameters: [{ name: "key", in: "path", required: true, schema: { type: "string" } }],
|
|
1094
1179
|
responses: { 200: { description: "Preference value" } }
|
|
1095
1180
|
},
|
|
1096
1181
|
put: {
|
|
1097
1182
|
tags: ["Preferences"],
|
|
1098
1183
|
summary: "Set an authenticated user preference",
|
|
1099
|
-
parameters: [
|
|
1100
|
-
{ name: "key", in: "path", required: true, schema: { type: "string" } }
|
|
1101
|
-
],
|
|
1184
|
+
parameters: [{ name: "key", in: "path", required: true, schema: { type: "string" } }],
|
|
1102
1185
|
requestBody: {
|
|
1103
1186
|
required: true,
|
|
1104
1187
|
content: { "application/json": { schema: { type: "object" } } }
|
|
@@ -1129,6 +1212,39 @@ function generateOpenApi(config) {
|
|
|
1129
1212
|
responses: { 200: { description: "Preview document data" } }
|
|
1130
1213
|
}
|
|
1131
1214
|
};
|
|
1215
|
+
spec.paths["/api/audit"] = {
|
|
1216
|
+
get: {
|
|
1217
|
+
tags: ["Audit"],
|
|
1218
|
+
summary: "Get audit entries across all readable audited collections",
|
|
1219
|
+
parameters: [
|
|
1220
|
+
{ name: "limit", in: "query", schema: { type: "integer", default: 50, maximum: 100 } },
|
|
1221
|
+
{ name: "page", in: "query", schema: { type: "integer", default: 1 } },
|
|
1222
|
+
{ name: "where", in: "query", schema: { type: "string" }, description: "JSON filter" },
|
|
1223
|
+
{ name: "sort", in: "query", schema: { type: "string", default: "-timestamp" } }
|
|
1224
|
+
],
|
|
1225
|
+
responses: {
|
|
1226
|
+
200: {
|
|
1227
|
+
description: "Audit entries",
|
|
1228
|
+
content: {
|
|
1229
|
+
"application/json": {
|
|
1230
|
+
schema: {
|
|
1231
|
+
type: "object",
|
|
1232
|
+
properties: {
|
|
1233
|
+
docs: {
|
|
1234
|
+
type: "array",
|
|
1235
|
+
items: { $ref: "#/components/schemas/AuditEntry" }
|
|
1236
|
+
},
|
|
1237
|
+
total: { type: "integer" },
|
|
1238
|
+
limit: { type: "integer" },
|
|
1239
|
+
page: { type: "integer" }
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1132
1248
|
for (const collection of config.collections) {
|
|
1133
1249
|
spec.components.schemas[collection.slug] = collectionToSchema(collection);
|
|
1134
1250
|
}
|
|
@@ -1138,10 +1254,11 @@ function generateOpenApi(config) {
|
|
|
1138
1254
|
for (const collection of config.collections) {
|
|
1139
1255
|
const slug = collection.slug;
|
|
1140
1256
|
const path = `/api/collections/${slug}`;
|
|
1141
|
-
const labels = collection
|
|
1257
|
+
const labels = getCollectionLabels(collection);
|
|
1258
|
+
const collectionTag = getCollectionTag(collection);
|
|
1142
1259
|
spec.paths[path] = {
|
|
1143
1260
|
get: {
|
|
1144
|
-
tags: [
|
|
1261
|
+
tags: [collectionTag],
|
|
1145
1262
|
summary: `Find ${labels.plural}`,
|
|
1146
1263
|
parameters: [
|
|
1147
1264
|
{
|
|
@@ -1190,7 +1307,7 @@ function generateOpenApi(config) {
|
|
|
1190
1307
|
}
|
|
1191
1308
|
},
|
|
1192
1309
|
post: {
|
|
1193
|
-
tags: [
|
|
1310
|
+
tags: [collectionTag],
|
|
1194
1311
|
summary: `Create ${labels.singular}`,
|
|
1195
1312
|
requestBody: {
|
|
1196
1313
|
required: true,
|
|
@@ -1214,7 +1331,7 @@ function generateOpenApi(config) {
|
|
|
1214
1331
|
};
|
|
1215
1332
|
spec.paths[`${path}/{id}`] = {
|
|
1216
1333
|
get: {
|
|
1217
|
-
tags: [
|
|
1334
|
+
tags: [collectionTag],
|
|
1218
1335
|
summary: `Get a single ${labels.singular}`,
|
|
1219
1336
|
parameters: [
|
|
1220
1337
|
{
|
|
@@ -1236,7 +1353,7 @@ function generateOpenApi(config) {
|
|
|
1236
1353
|
}
|
|
1237
1354
|
},
|
|
1238
1355
|
patch: {
|
|
1239
|
-
tags: [
|
|
1356
|
+
tags: [collectionTag],
|
|
1240
1357
|
summary: `Update ${labels.singular}`,
|
|
1241
1358
|
parameters: [
|
|
1242
1359
|
{
|
|
@@ -1266,7 +1383,7 @@ function generateOpenApi(config) {
|
|
|
1266
1383
|
}
|
|
1267
1384
|
},
|
|
1268
1385
|
delete: {
|
|
1269
|
-
tags: [
|
|
1386
|
+
tags: [collectionTag],
|
|
1270
1387
|
summary: `Delete ${labels.singular}`,
|
|
1271
1388
|
parameters: [
|
|
1272
1389
|
{
|
|
@@ -1283,7 +1400,7 @@ function generateOpenApi(config) {
|
|
|
1283
1400
|
};
|
|
1284
1401
|
spec.paths[`${path}/delete-many`] = {
|
|
1285
1402
|
delete: {
|
|
1286
|
-
tags: [
|
|
1403
|
+
tags: [collectionTag],
|
|
1287
1404
|
summary: `Delete multiple ${labels.plural}`,
|
|
1288
1405
|
requestBody: {
|
|
1289
1406
|
required: true,
|
|
@@ -1302,9 +1419,46 @@ function generateOpenApi(config) {
|
|
|
1302
1419
|
responses: { 200: { description: "Deleted and failed document IDs" } }
|
|
1303
1420
|
}
|
|
1304
1421
|
};
|
|
1422
|
+
if (collection.audit) {
|
|
1423
|
+
spec.paths[`${path}/__audit`] = {
|
|
1424
|
+
get: {
|
|
1425
|
+
tags: [collectionTag],
|
|
1426
|
+
summary: `Get ${labels.singular} audit entries`,
|
|
1427
|
+
parameters: [
|
|
1428
|
+
{ name: "limit", in: "query", schema: { type: "integer", default: 50, maximum: 100 } },
|
|
1429
|
+
{ name: "page", in: "query", schema: { type: "integer", default: 1 } },
|
|
1430
|
+
{ name: "where", in: "query", schema: { type: "string" }, description: "JSON filter" },
|
|
1431
|
+
{ name: "sort", in: "query", schema: { type: "string", default: "-timestamp" } }
|
|
1432
|
+
],
|
|
1433
|
+
responses: {
|
|
1434
|
+
200: {
|
|
1435
|
+
description: "Audit entries for this collection",
|
|
1436
|
+
content: {
|
|
1437
|
+
"application/json": {
|
|
1438
|
+
schema: {
|
|
1439
|
+
type: "object",
|
|
1440
|
+
properties: {
|
|
1441
|
+
docs: {
|
|
1442
|
+
type: "array",
|
|
1443
|
+
items: { $ref: "#/components/schemas/AuditEntry" }
|
|
1444
|
+
},
|
|
1445
|
+
total: { type: "integer" },
|
|
1446
|
+
limit: { type: "integer" },
|
|
1447
|
+
page: { type: "integer" }
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
},
|
|
1453
|
+
403: { description: "Collection read access denied" },
|
|
1454
|
+
404: { description: "Audit is not enabled for this collection" }
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
};
|
|
1458
|
+
}
|
|
1305
1459
|
spec.paths[`${path}/seed`] = {
|
|
1306
1460
|
post: {
|
|
1307
|
-
tags: [
|
|
1461
|
+
tags: [collectionTag],
|
|
1308
1462
|
summary: `Seed initial ${labels.plural}`,
|
|
1309
1463
|
responses: { 200: { description: "Seeded documents" } }
|
|
1310
1464
|
}
|
|
@@ -1312,12 +1466,12 @@ function generateOpenApi(config) {
|
|
|
1312
1466
|
if (collection.upload) {
|
|
1313
1467
|
spec.paths[`${path}/media`] = {
|
|
1314
1468
|
get: {
|
|
1315
|
-
tags: [
|
|
1469
|
+
tags: [collectionTag],
|
|
1316
1470
|
summary: `List ${labels.plural}`,
|
|
1317
1471
|
responses: { 200: { description: "Paginated media documents" } }
|
|
1318
1472
|
},
|
|
1319
1473
|
post: {
|
|
1320
|
-
tags: [
|
|
1474
|
+
tags: [collectionTag],
|
|
1321
1475
|
summary: `Upload ${labels.singular}`,
|
|
1322
1476
|
requestBody: {
|
|
1323
1477
|
required: true,
|
|
@@ -1336,7 +1490,7 @@ function generateOpenApi(config) {
|
|
|
1336
1490
|
};
|
|
1337
1491
|
spec.paths[`${path}/media/{filename}`] = {
|
|
1338
1492
|
get: {
|
|
1339
|
-
tags: [
|
|
1493
|
+
tags: [collectionTag],
|
|
1340
1494
|
summary: `Serve ${labels.singular} bytes`,
|
|
1341
1495
|
parameters: [
|
|
1342
1496
|
{
|
|
@@ -1356,7 +1510,7 @@ function generateOpenApi(config) {
|
|
|
1356
1510
|
}
|
|
1357
1511
|
if (collection.auth) {
|
|
1358
1512
|
const publicAuthPost = (summary) => ({
|
|
1359
|
-
tags: [
|
|
1513
|
+
tags: [collectionTag],
|
|
1360
1514
|
summary,
|
|
1361
1515
|
security: [],
|
|
1362
1516
|
requestBody: {
|
|
@@ -1398,14 +1552,14 @@ function generateOpenApi(config) {
|
|
|
1398
1552
|
};
|
|
1399
1553
|
spec.paths[`${path}/logout`] = {
|
|
1400
1554
|
post: {
|
|
1401
|
-
tags: [
|
|
1555
|
+
tags: [collectionTag],
|
|
1402
1556
|
summary: `Log out of ${labels.plural}`,
|
|
1403
1557
|
responses: { 200: { description: "Logged out" } }
|
|
1404
1558
|
}
|
|
1405
1559
|
};
|
|
1406
1560
|
spec.paths[`${path}/init`] = {
|
|
1407
1561
|
get: {
|
|
1408
|
-
tags: [
|
|
1562
|
+
tags: [collectionTag],
|
|
1409
1563
|
summary: `Get ${labels.plural} initialization state`,
|
|
1410
1564
|
security: [],
|
|
1411
1565
|
responses: { 200: { description: "Initialization state" } }
|
|
@@ -1416,14 +1570,14 @@ function generateOpenApi(config) {
|
|
|
1416
1570
|
};
|
|
1417
1571
|
spec.paths[`${path}/me`] = {
|
|
1418
1572
|
get: {
|
|
1419
|
-
tags: [
|
|
1573
|
+
tags: [collectionTag],
|
|
1420
1574
|
summary: `Get the current ${labels.singular}`,
|
|
1421
1575
|
responses: { 200: { description: "Authenticated user" } }
|
|
1422
1576
|
}
|
|
1423
1577
|
};
|
|
1424
1578
|
spec.paths[`${path}/refresh-token`] = {
|
|
1425
1579
|
post: {
|
|
1426
|
-
tags: [
|
|
1580
|
+
tags: [collectionTag],
|
|
1427
1581
|
summary: "Refresh an authentication token",
|
|
1428
1582
|
responses: { 200: { description: "Refreshed token" } }
|
|
1429
1583
|
}
|
|
@@ -1436,7 +1590,7 @@ function generateOpenApi(config) {
|
|
|
1436
1590
|
};
|
|
1437
1591
|
spec.paths[`${path}/invite`] = {
|
|
1438
1592
|
post: {
|
|
1439
|
-
tags: [
|
|
1593
|
+
tags: [collectionTag],
|
|
1440
1594
|
summary: `Invite a ${labels.singular}`,
|
|
1441
1595
|
responses: { 200: { description: "Invitation sent" } }
|
|
1442
1596
|
}
|
|
@@ -1446,7 +1600,7 @@ function generateOpenApi(config) {
|
|
|
1446
1600
|
};
|
|
1447
1601
|
spec.paths[`${path}/{id}/change-password`] = {
|
|
1448
1602
|
post: {
|
|
1449
|
-
tags: [
|
|
1603
|
+
tags: [collectionTag],
|
|
1450
1604
|
summary: `Change a ${labels.singular} password`,
|
|
1451
1605
|
parameters: [
|
|
1452
1606
|
{
|
|
@@ -1463,7 +1617,7 @@ function generateOpenApi(config) {
|
|
|
1463
1617
|
if (collection.workflow) {
|
|
1464
1618
|
spec.paths[`${path}/{id}/transitions/{transition}`] = {
|
|
1465
1619
|
post: {
|
|
1466
|
-
tags: [
|
|
1620
|
+
tags: [collectionTag],
|
|
1467
1621
|
summary: `Transition ${labels.singular} workflow`,
|
|
1468
1622
|
parameters: [
|
|
1469
1623
|
{
|
|
@@ -1508,7 +1662,7 @@ function generateOpenApi(config) {
|
|
|
1508
1662
|
};
|
|
1509
1663
|
spec.paths[`${path}/{id}/workflow-history`] = {
|
|
1510
1664
|
get: {
|
|
1511
|
-
tags: [
|
|
1665
|
+
tags: [collectionTag],
|
|
1512
1666
|
summary: `Get ${labels.singular} workflow history`,
|
|
1513
1667
|
parameters: [
|
|
1514
1668
|
{
|
|
@@ -1554,9 +1708,10 @@ function generateOpenApi(config) {
|
|
|
1554
1708
|
for (const global of config.globals) {
|
|
1555
1709
|
const slug = global.slug;
|
|
1556
1710
|
const path = `/api/globals/${slug}`;
|
|
1711
|
+
const globalTag = getGlobalTag(global);
|
|
1557
1712
|
spec.paths[path] = {
|
|
1558
1713
|
get: {
|
|
1559
|
-
tags: [
|
|
1714
|
+
tags: [globalTag],
|
|
1560
1715
|
summary: `Get ${global.label || slug}`,
|
|
1561
1716
|
responses: {
|
|
1562
1717
|
200: {
|
|
@@ -1570,7 +1725,7 @@ function generateOpenApi(config) {
|
|
|
1570
1725
|
}
|
|
1571
1726
|
},
|
|
1572
1727
|
patch: {
|
|
1573
|
-
tags: [
|
|
1728
|
+
tags: [globalTag],
|
|
1574
1729
|
summary: `Update ${global.label || slug}`,
|
|
1575
1730
|
requestBody: {
|
|
1576
1731
|
required: true,
|
|
@@ -1594,7 +1749,7 @@ function generateOpenApi(config) {
|
|
|
1594
1749
|
};
|
|
1595
1750
|
spec.paths[`${path}/seed`] = {
|
|
1596
1751
|
post: {
|
|
1597
|
-
tags: [
|
|
1752
|
+
tags: [globalTag],
|
|
1598
1753
|
summary: `Seed ${global.label || slug}`,
|
|
1599
1754
|
responses: { 200: { description: "Seeded global" } }
|
|
1600
1755
|
}
|
|
@@ -1673,10 +1828,7 @@ function fieldToSchema(field) {
|
|
|
1673
1828
|
break;
|
|
1674
1829
|
case "url":
|
|
1675
1830
|
schema = {
|
|
1676
|
-
oneOf: [
|
|
1677
|
-
{ type: "string" },
|
|
1678
|
-
{ type: "object", additionalProperties: true }
|
|
1679
|
-
]
|
|
1831
|
+
oneOf: [{ type: "string" }, { type: "object", additionalProperties: true }]
|
|
1680
1832
|
};
|
|
1681
1833
|
break;
|
|
1682
1834
|
case "icon":
|
|
@@ -1812,12 +1964,19 @@ var defineUrlField = createFieldDefiner("url");
|
|
|
1812
1964
|
var defineIconField = createFieldDefiner("icon");
|
|
1813
1965
|
var defineJoinField = createFieldDefiner("join");
|
|
1814
1966
|
var defineRowField = createFieldDefiner("row");
|
|
1967
|
+
function defineTab(args) {
|
|
1968
|
+
return args.fields.map((field) => ({
|
|
1969
|
+
...field,
|
|
1970
|
+
admin: { ...field.admin ?? {}, tab: args.label }
|
|
1971
|
+
}));
|
|
1972
|
+
}
|
|
1815
1973
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1816
1974
|
0 && (module.exports = {
|
|
1817
1975
|
LIFECYCLE_EVENTS_COLLECTION,
|
|
1818
1976
|
LIFECYCLE_EVENT_NAMES,
|
|
1819
1977
|
WORKFLOW_HISTORY_COLLECTION,
|
|
1820
1978
|
availableWorkflowTransitions,
|
|
1979
|
+
buildSqlOrderBy,
|
|
1821
1980
|
canViewWorkflowDraft,
|
|
1822
1981
|
createLifecycleEvent,
|
|
1823
1982
|
createWorkflowDocument,
|
|
@@ -1844,6 +2003,7 @@ var defineRowField = createFieldDefiner("row");
|
|
|
1844
2003
|
defineRichTextField,
|
|
1845
2004
|
defineRowField,
|
|
1846
2005
|
defineSelectField,
|
|
2006
|
+
defineTab,
|
|
1847
2007
|
defineTextField,
|
|
1848
2008
|
defineTextareaField,
|
|
1849
2009
|
defineTimeField,
|
|
@@ -1858,6 +2018,7 @@ var defineRowField = createFieldDefiner("row");
|
|
|
1858
2018
|
initializeWorkflowDocument,
|
|
1859
2019
|
materializeWorkflowDocument,
|
|
1860
2020
|
normalizeConfig,
|
|
2021
|
+
numericFieldNames,
|
|
1861
2022
|
parseMongoWhere,
|
|
1862
2023
|
parseSort,
|
|
1863
2024
|
parseSqlWhere,
|
|
@@ -1865,6 +2026,7 @@ var defineRowField = createFieldDefiner("row");
|
|
|
1865
2026
|
resolveAdminAuthCollection,
|
|
1866
2027
|
runCollectionHooks,
|
|
1867
2028
|
saveWorkflowDraft,
|
|
2029
|
+
simplePublishingWorkflow,
|
|
1868
2030
|
transitionWorkflow,
|
|
1869
2031
|
workflowCapabilities
|
|
1870
2032
|
});
|